mirror of
https://github.com/doitsujin/dxvk.git
synced 2024-12-05 01:24:14 +01:00
[dxso] Always lower projection
This commit is contained in:
parent
f1f8d45fcd
commit
7552cfe62a
@ -2648,10 +2648,30 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||
DxsoRegMask vec3Mask(true, true, true, false);
|
||||
DxsoRegMask srcMask (true, true, true, true);
|
||||
|
||||
auto GetProjectionValue = [&]() {
|
||||
auto DoProjection = [&](DxsoRegisterValue coord, bool switchProjRes) {
|
||||
uint32_t bool_t = m_module.defBoolType();
|
||||
uint32_t texcoord_t = getVectorTypeId(coord.type);
|
||||
|
||||
uint32_t w = 3;
|
||||
return m_module.opCompositeExtract(
|
||||
m_module.defFloatType(32), texcoordVar.id, 1, &w);
|
||||
|
||||
uint32_t projScalar = m_module.opCompositeExtract(
|
||||
m_module.defFloatType(32), coord.id, 1, &w);
|
||||
|
||||
projScalar = m_module.opFDiv(m_module.defFloatType(32), m_module.constf32(1.0), projScalar);
|
||||
uint32_t projResult = m_module.opVectorTimesScalar(texcoord_t, coord.id, projScalar);
|
||||
|
||||
if (switchProjRes) {
|
||||
uint32_t shouldProj = m_spec.get(m_module, m_specUbo, SpecProjectionType, samplerIdx, 1);
|
||||
shouldProj = m_module.opINotEqual(bool_t, shouldProj, m_module.constu32(0));
|
||||
|
||||
uint32_t bvec4_t = m_module.defVectorType(bool_t, 4);
|
||||
std::array<uint32_t, 4> indices = { shouldProj, shouldProj, shouldProj, shouldProj };
|
||||
shouldProj = m_module.opCompositeConstruct(bvec4_t, indices.size(), indices.data());
|
||||
|
||||
return m_module.opSelect(texcoord_t, shouldProj, projResult, coord.id);
|
||||
} else {
|
||||
return projResult;
|
||||
}
|
||||
};
|
||||
|
||||
if (opcode == DxsoOpcode::TexM3x2Tex || opcode == DxsoOpcode::TexM3x3Tex || opcode == DxsoOpcode::TexM3x3Spec || opcode == DxsoOpcode::TexM3x3VSpec) {
|
||||
@ -2711,23 +2731,9 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||
texcoordVar = m;
|
||||
samplerIdx = ctx.dst.id.num;
|
||||
|
||||
uint32_t texcoord_t = getVectorTypeId(texcoordVar.type);
|
||||
|
||||
// The projection (/.w) happens before this...
|
||||
// Of course it does...
|
||||
uint32_t bool_t = m_module.defBoolType();
|
||||
|
||||
uint32_t shouldProj = m_spec.get(m_module, m_specUbo, SpecProjectionType, samplerIdx, 1);
|
||||
shouldProj = m_module.opINotEqual(bool_t, shouldProj, m_module.constu32(0));
|
||||
|
||||
uint32_t bvec4_t = m_module.defVectorType(bool_t, 4);
|
||||
std::array<uint32_t, 4> indices = { shouldProj, shouldProj, shouldProj, shouldProj };
|
||||
shouldProj = m_module.opCompositeConstruct(bvec4_t, indices.size(), indices.data());
|
||||
|
||||
uint32_t projScalar = m_module.opFDiv(m_module.defFloatType(32), m_module.constf32(1.0), GetProjectionValue());
|
||||
uint32_t projResult = m_module.opVectorTimesScalar(texcoord_t, texcoordVar.id, projScalar);
|
||||
|
||||
texcoordVar.id = m_module.opSelect(texcoord_t, shouldProj, projResult, texcoordVar.id);
|
||||
texcoordVar.id = DoProjection(texcoordVar, true);
|
||||
|
||||
// u' = tc(m).x + [bm00(m) * t(n).x + bm10(m) * t(n).y]
|
||||
// v' = tc(m).y + [bm01(m) * t(n).x + bm11(m) * t(n).y]
|
||||
@ -2811,7 +2817,7 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||
|
||||
DxsoSampler sampler = m_samplers.at(samplerIdx);
|
||||
|
||||
auto SampleImage = [this, opcode, dst, ctx, samplerIdx, GetProjectionValue](DxsoRegisterValue texcoordVar, DxsoSamplerInfo& sampler, bool depth, DxsoSamplerType samplerType, uint32_t isNull) {
|
||||
auto SampleImage = [this, opcode, dst, ctx, samplerIdx, DoProjection](DxsoRegisterValue texcoordVar, DxsoSamplerInfo& sampler, bool depth, DxsoSamplerType samplerType, uint32_t isNull) {
|
||||
DxsoRegisterValue result;
|
||||
result.type.ctype = dst.type.ctype;
|
||||
result.type.ccount = depth ? 1 : 4;
|
||||
@ -2838,12 +2844,10 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||
imageOperands.sGradY = emitRegisterLoad(ctx.src[3], gradMask).id;
|
||||
}
|
||||
|
||||
uint32_t projDivider = 0;
|
||||
|
||||
if (opcode == DxsoOpcode::Tex
|
||||
&& m_programInfo.majorVersion() >= 2) {
|
||||
if (ctx.instruction.specificData.texld == DxsoTexLdMode::Project) {
|
||||
projDivider = GetProjectionValue();
|
||||
texcoordVar.id = DoProjection(texcoordVar, false);
|
||||
}
|
||||
else if (ctx.instruction.specificData.texld == DxsoTexLdMode::Bias) {
|
||||
uint32_t w = 3;
|
||||
@ -2853,15 +2857,9 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||
}
|
||||
}
|
||||
|
||||
bool switchProjResult = m_programInfo.majorVersion() < 2 && samplerType != SamplerTypeTextureCube;
|
||||
|
||||
if (switchProjResult)
|
||||
projDivider = GetProjectionValue();
|
||||
|
||||
// We already handled this...
|
||||
if (opcode == DxsoOpcode::TexBem) {
|
||||
switchProjResult = false;
|
||||
projDivider = 0;
|
||||
// We already handled this for TexBem(L)
|
||||
if (m_programInfo.majorVersion() < 2 && samplerType != SamplerTypeTextureCube && opcode != DxsoOpcode::TexBem && opcode != DxsoOpcode::TexBemL) {
|
||||
texcoordVar.id = DoProjection(texcoordVar, true);
|
||||
}
|
||||
|
||||
uint32_t reference = 0;
|
||||
@ -2872,13 +2870,6 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||
m_module.defFloatType(32), texcoordVar.id, 1, &component);
|
||||
}
|
||||
|
||||
if (projDivider != 0) {
|
||||
for (uint32_t i = sampler.dimensions; i < 4; i++) {
|
||||
texcoordVar.id = m_module.opCompositeInsert(getVectorTypeId(texcoordVar.type),
|
||||
projDivider, texcoordVar.id, 1, &i);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t fetch4 = 0;
|
||||
if (m_programInfo.type() == DxsoProgramType::PixelShader && samplerType != SamplerTypeTexture3D) {
|
||||
fetch4 = m_spec.get(m_module, m_specUbo, SpecFetch4, samplerIdx, 1);
|
||||
@ -2892,7 +2883,6 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||
}
|
||||
|
||||
result.id = this->emitSample(
|
||||
projDivider != 0,
|
||||
typeId,
|
||||
sampler,
|
||||
texcoordVar,
|
||||
@ -2900,33 +2890,6 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||
fetch4,
|
||||
imageOperands);
|
||||
|
||||
if (switchProjResult) {
|
||||
uint32_t bool_t = m_module.defBoolType();
|
||||
|
||||
uint32_t nonProjResult = this->emitSample(
|
||||
0,
|
||||
typeId,
|
||||
sampler,
|
||||
texcoordVar,
|
||||
reference,
|
||||
fetch4,
|
||||
imageOperands);
|
||||
|
||||
uint32_t shouldProj = m_spec.get(m_module, m_specUbo, SpecProjectionType, samplerIdx, 1);
|
||||
shouldProj = m_module.opINotEqual(m_module.defBoolType(), shouldProj, m_module.constu32(0));
|
||||
|
||||
// Depth -> .x
|
||||
// Colour -> .xyzw
|
||||
// Need to replicate the bool for the opSelect.
|
||||
if (!depth) {
|
||||
uint32_t bvec4_t = m_module.defVectorType(bool_t, 4);
|
||||
std::array<uint32_t, 4> indices = { shouldProj, shouldProj, shouldProj, shouldProj };
|
||||
shouldProj = m_module.opCompositeConstruct(bvec4_t, indices.size(), indices.data());
|
||||
}
|
||||
|
||||
result.id = m_module.opSelect(typeId, shouldProj, result.id, nonProjResult);
|
||||
}
|
||||
|
||||
// If we are sampling depth we've already specc'ed this!
|
||||
// This path is always size 4 because it only hits on color.
|
||||
if (isNull != 0) {
|
||||
@ -3118,7 +3081,6 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||
|
||||
|
||||
uint32_t DxsoCompiler::emitSample(
|
||||
bool projected,
|
||||
uint32_t resultType,
|
||||
DxsoSamplerInfo& samplerInfo,
|
||||
DxsoRegisterValue coordinates,
|
||||
@ -3134,37 +3096,22 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||
|
||||
uint32_t val;
|
||||
|
||||
// No Fetch 4
|
||||
if (projected) {
|
||||
if (depthCompare) {
|
||||
if (explicitLod)
|
||||
val = m_module.opImageSampleProjDrefExplicitLod(resultType, sampledImage, coordinates.id, reference, operands);
|
||||
else
|
||||
val = m_module.opImageSampleProjDrefImplicitLod(resultType, sampledImage, coordinates.id, reference, operands);
|
||||
}
|
||||
else {
|
||||
if (explicitLod)
|
||||
val = m_module.opImageSampleProjExplicitLod(resultType, sampledImage, coordinates.id, operands);
|
||||
else
|
||||
val = m_module.opImageSampleProjImplicitLod(resultType, sampledImage, coordinates.id, operands);
|
||||
}
|
||||
|
||||
if (depthCompare) {
|
||||
if (explicitLod)
|
||||
val = m_module.opImageSampleDrefExplicitLod(resultType, sampledImage, coordinates.id, reference, operands);
|
||||
else
|
||||
val = m_module.opImageSampleDrefImplicitLod(resultType, sampledImage, coordinates.id, reference, operands);
|
||||
}
|
||||
else {
|
||||
if (depthCompare) {
|
||||
if (explicitLod)
|
||||
val = m_module.opImageSampleDrefExplicitLod(resultType, sampledImage, coordinates.id, reference, operands);
|
||||
else
|
||||
val = m_module.opImageSampleDrefImplicitLod(resultType, sampledImage, coordinates.id, reference, operands);
|
||||
}
|
||||
else {
|
||||
if (explicitLod)
|
||||
val = m_module.opImageSampleExplicitLod(resultType, sampledImage, coordinates.id, operands);
|
||||
else
|
||||
val = m_module.opImageSampleImplicitLod(resultType, sampledImage, coordinates.id, operands);
|
||||
}
|
||||
if (explicitLod)
|
||||
val = m_module.opImageSampleExplicitLod(resultType, sampledImage, coordinates.id, operands);
|
||||
else
|
||||
val = m_module.opImageSampleImplicitLod(resultType, sampledImage, coordinates.id, operands);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (fetch4 && !depthCompare) {
|
||||
SpirvImageOperands fetch4Operands = operands;
|
||||
fetch4Operands.flags &= ~spv::ImageOperandsLodMask;
|
||||
|
@ -664,7 +664,6 @@ namespace dxvk {
|
||||
void emitTextureDepth(const DxsoInstructionContext& ctx);
|
||||
|
||||
uint32_t emitSample(
|
||||
bool projected,
|
||||
uint32_t resultType,
|
||||
DxsoSamplerInfo& samplerInfo,
|
||||
DxsoRegisterValue coordinates,
|
||||
|
Loading…
Reference in New Issue
Block a user