From 7552cfe62ad86dda0f48295d6e440096d8c88344 Mon Sep 17 00:00:00 2001 From: Georg Lehmann Date: Mon, 26 Sep 2022 14:14:37 +0200 Subject: [PATCH] [dxso] Always lower projection --- src/dxso/dxso_compiler.cpp | 133 +++++++++++-------------------------- src/dxso/dxso_compiler.h | 1 - 2 files changed, 40 insertions(+), 94 deletions(-) diff --git a/src/dxso/dxso_compiler.cpp b/src/dxso/dxso_compiler.cpp index 0c8a4c6fe..cb1ce67dd 100644 --- a/src/dxso/dxso_compiler.cpp +++ b/src/dxso/dxso_compiler.cpp @@ -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 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 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 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; diff --git a/src/dxso/dxso_compiler.h b/src/dxso/dxso_compiler.h index 9f97fdda6..58b06a03e 100644 --- a/src/dxso/dxso_compiler.h +++ b/src/dxso/dxso_compiler.h @@ -664,7 +664,6 @@ namespace dxvk { void emitTextureDepth(const DxsoInstructionContext& ctx); uint32_t emitSample( - bool projected, uint32_t resultType, DxsoSamplerInfo& samplerInfo, DxsoRegisterValue coordinates,