1
0
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:
Georg Lehmann 2022-09-26 14:14:37 +02:00 committed by Joshie
parent f1f8d45fcd
commit 7552cfe62a
2 changed files with 40 additions and 94 deletions

View File

@ -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;

View File

@ -664,7 +664,6 @@ namespace dxvk {
void emitTextureDepth(const DxsoInstructionContext& ctx);
uint32_t emitSample(
bool projected,
uint32_t resultType,
DxsoSamplerInfo& samplerInfo,
DxsoRegisterValue coordinates,