mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-06 20:58:37 +01:00
[dxso] Always lower projection
This commit is contained in:
parent
f1f8d45fcd
commit
7552cfe62a
2 changed files with 40 additions and 94 deletions
|
@ -2648,10 +2648,30 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||||
DxsoRegMask vec3Mask(true, true, true, false);
|
DxsoRegMask vec3Mask(true, true, true, false);
|
||||||
DxsoRegMask srcMask (true, true, true, true);
|
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;
|
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) {
|
if (opcode == DxsoOpcode::TexM3x2Tex || opcode == DxsoOpcode::TexM3x3Tex || opcode == DxsoOpcode::TexM3x3Spec || opcode == DxsoOpcode::TexM3x3VSpec) {
|
||||||
|
@ -2711,23 +2731,9 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||||
texcoordVar = m;
|
texcoordVar = m;
|
||||||
samplerIdx = ctx.dst.id.num;
|
samplerIdx = ctx.dst.id.num;
|
||||||
|
|
||||||
uint32_t texcoord_t = getVectorTypeId(texcoordVar.type);
|
|
||||||
|
|
||||||
// The projection (/.w) happens before this...
|
// The projection (/.w) happens before this...
|
||||||
// Of course it does...
|
// Of course it does...
|
||||||
uint32_t bool_t = m_module.defBoolType();
|
texcoordVar.id = DoProjection(texcoordVar, true);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// u' = tc(m).x + [bm00(m) * t(n).x + bm10(m) * t(n).y]
|
// 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]
|
// 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);
|
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;
|
DxsoRegisterValue result;
|
||||||
result.type.ctype = dst.type.ctype;
|
result.type.ctype = dst.type.ctype;
|
||||||
result.type.ccount = depth ? 1 : 4;
|
result.type.ccount = depth ? 1 : 4;
|
||||||
|
@ -2838,12 +2844,10 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||||
imageOperands.sGradY = emitRegisterLoad(ctx.src[3], gradMask).id;
|
imageOperands.sGradY = emitRegisterLoad(ctx.src[3], gradMask).id;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t projDivider = 0;
|
|
||||||
|
|
||||||
if (opcode == DxsoOpcode::Tex
|
if (opcode == DxsoOpcode::Tex
|
||||||
&& m_programInfo.majorVersion() >= 2) {
|
&& m_programInfo.majorVersion() >= 2) {
|
||||||
if (ctx.instruction.specificData.texld == DxsoTexLdMode::Project) {
|
if (ctx.instruction.specificData.texld == DxsoTexLdMode::Project) {
|
||||||
projDivider = GetProjectionValue();
|
texcoordVar.id = DoProjection(texcoordVar, false);
|
||||||
}
|
}
|
||||||
else if (ctx.instruction.specificData.texld == DxsoTexLdMode::Bias) {
|
else if (ctx.instruction.specificData.texld == DxsoTexLdMode::Bias) {
|
||||||
uint32_t w = 3;
|
uint32_t w = 3;
|
||||||
|
@ -2853,15 +2857,9 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool switchProjResult = m_programInfo.majorVersion() < 2 && samplerType != SamplerTypeTextureCube;
|
// We already handled this for TexBem(L)
|
||||||
|
if (m_programInfo.majorVersion() < 2 && samplerType != SamplerTypeTextureCube && opcode != DxsoOpcode::TexBem && opcode != DxsoOpcode::TexBemL) {
|
||||||
if (switchProjResult)
|
texcoordVar.id = DoProjection(texcoordVar, true);
|
||||||
projDivider = GetProjectionValue();
|
|
||||||
|
|
||||||
// We already handled this...
|
|
||||||
if (opcode == DxsoOpcode::TexBem) {
|
|
||||||
switchProjResult = false;
|
|
||||||
projDivider = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t reference = 0;
|
uint32_t reference = 0;
|
||||||
|
@ -2872,13 +2870,6 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||||
m_module.defFloatType(32), texcoordVar.id, 1, &component);
|
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;
|
uint32_t fetch4 = 0;
|
||||||
if (m_programInfo.type() == DxsoProgramType::PixelShader && samplerType != SamplerTypeTexture3D) {
|
if (m_programInfo.type() == DxsoProgramType::PixelShader && samplerType != SamplerTypeTexture3D) {
|
||||||
fetch4 = m_spec.get(m_module, m_specUbo, SpecFetch4, samplerIdx, 1);
|
fetch4 = m_spec.get(m_module, m_specUbo, SpecFetch4, samplerIdx, 1);
|
||||||
|
@ -2892,7 +2883,6 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||||
}
|
}
|
||||||
|
|
||||||
result.id = this->emitSample(
|
result.id = this->emitSample(
|
||||||
projDivider != 0,
|
|
||||||
typeId,
|
typeId,
|
||||||
sampler,
|
sampler,
|
||||||
texcoordVar,
|
texcoordVar,
|
||||||
|
@ -2900,33 +2890,6 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||||
fetch4,
|
fetch4,
|
||||||
imageOperands);
|
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!
|
// If we are sampling depth we've already specc'ed this!
|
||||||
// This path is always size 4 because it only hits on color.
|
// This path is always size 4 because it only hits on color.
|
||||||
if (isNull != 0) {
|
if (isNull != 0) {
|
||||||
|
@ -3118,7 +3081,6 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||||
|
|
||||||
|
|
||||||
uint32_t DxsoCompiler::emitSample(
|
uint32_t DxsoCompiler::emitSample(
|
||||||
bool projected,
|
|
||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
DxsoSamplerInfo& samplerInfo,
|
DxsoSamplerInfo& samplerInfo,
|
||||||
DxsoRegisterValue coordinates,
|
DxsoRegisterValue coordinates,
|
||||||
|
@ -3134,37 +3096,22 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
||||||
|
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
|
|
||||||
// No Fetch 4
|
|
||||||
if (projected) {
|
if (depthCompare) {
|
||||||
if (depthCompare) {
|
if (explicitLod)
|
||||||
if (explicitLod)
|
val = m_module.opImageSampleDrefExplicitLod(resultType, sampledImage, coordinates.id, reference, operands);
|
||||||
val = m_module.opImageSampleProjDrefExplicitLod(resultType, sampledImage, coordinates.id, reference, operands);
|
else
|
||||||
else
|
val = m_module.opImageSampleDrefImplicitLod(resultType, sampledImage, coordinates.id, reference, operands);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (depthCompare) {
|
if (explicitLod)
|
||||||
if (explicitLod)
|
val = m_module.opImageSampleExplicitLod(resultType, sampledImage, coordinates.id, operands);
|
||||||
val = m_module.opImageSampleDrefExplicitLod(resultType, sampledImage, coordinates.id, reference, operands);
|
else
|
||||||
else
|
val = m_module.opImageSampleImplicitLod(resultType, sampledImage, coordinates.id, operands);
|
||||||
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 (fetch4 && !depthCompare) {
|
if (fetch4 && !depthCompare) {
|
||||||
SpirvImageOperands fetch4Operands = operands;
|
SpirvImageOperands fetch4Operands = operands;
|
||||||
fetch4Operands.flags &= ~spv::ImageOperandsLodMask;
|
fetch4Operands.flags &= ~spv::ImageOperandsLodMask;
|
||||||
|
|
|
@ -664,7 +664,6 @@ namespace dxvk {
|
||||||
void emitTextureDepth(const DxsoInstructionContext& ctx);
|
void emitTextureDepth(const DxsoInstructionContext& ctx);
|
||||||
|
|
||||||
uint32_t emitSample(
|
uint32_t emitSample(
|
||||||
bool projected,
|
|
||||||
uint32_t resultType,
|
uint32_t resultType,
|
||||||
DxsoSamplerInfo& samplerInfo,
|
DxsoSamplerInfo& samplerInfo,
|
||||||
DxsoRegisterValue coordinates,
|
DxsoRegisterValue coordinates,
|
||||||
|
|
Loading…
Add table
Reference in a new issue