mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-19 05:52:11 +01:00
[d3d9] Handle specular fog factor for fixed function
Also handle POSITION_T shenanigans Closes #1771
This commit is contained in:
parent
dc392f7cfa
commit
e4bca7a42f
@ -91,74 +91,83 @@ namespace dxvk {
|
|||||||
? fogCtx.vFog
|
? fogCtx.vFog
|
||||||
: spvModule.opFAbs(floatType, z);
|
: spvModule.opFAbs(floatType, z);
|
||||||
}
|
}
|
||||||
|
uint32_t fogFactor;
|
||||||
|
if (!fogCtx.IsPixel && fogCtx.IsFixedFunction && fogCtx.IsPositionT) {
|
||||||
|
fogFactor = fogCtx.HasSpecular
|
||||||
|
? spvModule.opCompositeExtract(floatType, fogCtx.Specular, 1, &wIndex)
|
||||||
|
: spvModule.constf32(1.0f);
|
||||||
|
} else {
|
||||||
|
uint32_t applyFogFactor = spvModule.allocateId();
|
||||||
|
|
||||||
uint32_t applyFogFactor = spvModule.allocateId();
|
std::array<SpirvPhiLabel, 4> fogVariables;
|
||||||
|
|
||||||
std::array<SpirvPhiLabel, 4> fogVariables;
|
std::array<SpirvSwitchCaseLabel, 4> fogCaseLabels = { {
|
||||||
|
{ uint32_t(D3DFOG_NONE), spvModule.allocateId() },
|
||||||
|
{ uint32_t(D3DFOG_EXP), spvModule.allocateId() },
|
||||||
|
{ uint32_t(D3DFOG_EXP2), spvModule.allocateId() },
|
||||||
|
{ uint32_t(D3DFOG_LINEAR), spvModule.allocateId() },
|
||||||
|
} };
|
||||||
|
|
||||||
std::array<SpirvSwitchCaseLabel, 4> fogCaseLabels = { {
|
spvModule.opSelectionMerge(applyFogFactor, spv::SelectionControlMaskNone);
|
||||||
{ uint32_t(D3DFOG_NONE), spvModule.allocateId() },
|
spvModule.opSwitch(fogMode,
|
||||||
{ uint32_t(D3DFOG_EXP), spvModule.allocateId() },
|
fogCaseLabels[D3DFOG_NONE].labelId,
|
||||||
{ uint32_t(D3DFOG_EXP2), spvModule.allocateId() },
|
fogCaseLabels.size(),
|
||||||
{ uint32_t(D3DFOG_LINEAR), spvModule.allocateId() },
|
fogCaseLabels.data());
|
||||||
} };
|
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < fogCaseLabels.size(); i++) {
|
||||||
|
spvModule.opLabel(fogCaseLabels[i].labelId);
|
||||||
|
|
||||||
spvModule.opSelectionMerge(applyFogFactor, spv::SelectionControlMaskNone);
|
fogVariables[i].labelId = fogCaseLabels[i].labelId;
|
||||||
spvModule.opSwitch(fogMode,
|
fogVariables[i].varId = [&] {
|
||||||
fogCaseLabels[D3DFOG_NONE].labelId,
|
auto mode = D3DFOGMODE(fogCaseLabels[i].literal);
|
||||||
fogCaseLabels.size(),
|
switch (mode) {
|
||||||
fogCaseLabels.data());
|
default:
|
||||||
|
// vFog
|
||||||
|
case D3DFOG_NONE: {
|
||||||
|
if (fogCtx.IsPixel)
|
||||||
|
return fogCtx.vFog;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < fogCaseLabels.size(); i++) {
|
if (fogCtx.IsFixedFunction && fogCtx.HasSpecular)
|
||||||
spvModule.opLabel(fogCaseLabels[i].labelId);
|
return spvModule.opCompositeExtract(floatType, fogCtx.Specular, 1, &wIndex);
|
||||||
|
|
||||||
fogVariables[i].labelId = fogCaseLabels[i].labelId;
|
return spvModule.constf32(1.0f);
|
||||||
fogVariables[i].varId = [&] {
|
}
|
||||||
auto mode = D3DFOGMODE(fogCaseLabels[i].literal);
|
|
||||||
switch (mode) {
|
// (end - d) / (end - start)
|
||||||
default:
|
case D3DFOG_LINEAR: {
|
||||||
// vFog
|
uint32_t fogFactor = spvModule.opFSub(floatType, fogEnd, depth);
|
||||||
case D3DFOG_NONE: {
|
fogFactor = spvModule.opFMul(floatType, fogFactor, fogScale);
|
||||||
return fogCtx.IsPixel
|
fogFactor = spvModule.opNClamp(floatType, fogFactor, spvModule.constf32(0.0f), spvModule.constf32(1.0f));
|
||||||
? fogCtx.vFog
|
return fogFactor;
|
||||||
: spvModule.constf32(1.0f);
|
}
|
||||||
|
|
||||||
|
// 1 / (e^[d * density])^2
|
||||||
|
case D3DFOG_EXP2:
|
||||||
|
// 1 / (e^[d * density])
|
||||||
|
case D3DFOG_EXP: {
|
||||||
|
uint32_t fogFactor = spvModule.opFMul(floatType, depth, fogDensity);
|
||||||
|
|
||||||
|
if (mode == D3DFOG_EXP2)
|
||||||
|
fogFactor = spvModule.opFMul(floatType, fogFactor, fogFactor);
|
||||||
|
|
||||||
|
// Provides the rcp.
|
||||||
|
fogFactor = spvModule.opFNegate(floatType, fogFactor);
|
||||||
|
fogFactor = spvModule.opExp(floatType, fogFactor);
|
||||||
|
return fogFactor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}();
|
||||||
|
|
||||||
// (end - d) / (end - start)
|
spvModule.opBranch(applyFogFactor);
|
||||||
case D3DFOG_LINEAR: {
|
}
|
||||||
uint32_t fogFactor = spvModule.opFSub(floatType, fogEnd, depth);
|
|
||||||
fogFactor = spvModule.opFMul(floatType, fogFactor, fogScale);
|
|
||||||
fogFactor = spvModule.opNClamp(floatType, fogFactor, spvModule.constf32(0.0f), spvModule.constf32(1.0f));
|
|
||||||
return fogFactor;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1 / (e^[d * density])^2
|
spvModule.opLabel(applyFogFactor);
|
||||||
case D3DFOG_EXP2:
|
|
||||||
// 1 / (e^[d * density])
|
|
||||||
case D3DFOG_EXP: {
|
|
||||||
uint32_t fogFactor = spvModule.opFMul(floatType, depth, fogDensity);
|
|
||||||
|
|
||||||
if (mode == D3DFOG_EXP2)
|
fogFactor = spvModule.opPhi(floatType,
|
||||||
fogFactor = spvModule.opFMul(floatType, fogFactor, fogFactor);
|
fogVariables.size(),
|
||||||
|
fogVariables.data());
|
||||||
// Provides the rcp.
|
|
||||||
fogFactor = spvModule.opFNegate(floatType, fogFactor);
|
|
||||||
fogFactor = spvModule.opExp(floatType, fogFactor);
|
|
||||||
return fogFactor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}();
|
|
||||||
|
|
||||||
spvModule.opBranch(applyFogFactor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
spvModule.opLabel(applyFogFactor);
|
|
||||||
|
|
||||||
uint32_t fogFactor = spvModule.opPhi(floatType,
|
|
||||||
fogVariables.size(),
|
|
||||||
fogVariables.data());
|
|
||||||
|
|
||||||
uint32_t fogRetValue = 0;
|
uint32_t fogRetValue = 0;
|
||||||
|
|
||||||
// Return the new color if we are doing this in PS
|
// Return the new color if we are doing this in PS
|
||||||
@ -1156,6 +1165,10 @@ namespace dxvk {
|
|||||||
fogCtx.HasFogInput = m_vsKey.Data.Contents.HasFog;
|
fogCtx.HasFogInput = m_vsKey.Data.Contents.HasFog;
|
||||||
fogCtx.vFog = m_vs.in.FOG;
|
fogCtx.vFog = m_vs.in.FOG;
|
||||||
fogCtx.oColor = 0;
|
fogCtx.oColor = 0;
|
||||||
|
fogCtx.IsFixedFunction = true;
|
||||||
|
fogCtx.IsPositionT = m_vsKey.Data.Contents.HasPositionT;
|
||||||
|
fogCtx.HasSpecular = m_vsKey.Data.Contents.HasColor1;
|
||||||
|
fogCtx.Specular = m_vs.in.COLOR[1];
|
||||||
m_module.opStore(m_vs.out.FOG, DoFixedFunctionFog(m_module, fogCtx));
|
m_module.opStore(m_vs.out.FOG, DoFixedFunctionFog(m_module, fogCtx));
|
||||||
|
|
||||||
auto pointInfo = GetPointSizeInfoVS(m_module, 0, vtx, m_vs.in.POINTSIZE, m_rsBlock);
|
auto pointInfo = GetPointSizeInfoVS(m_module, 0, vtx, m_vs.in.POINTSIZE, m_rsBlock);
|
||||||
@ -1942,6 +1955,10 @@ namespace dxvk {
|
|||||||
fogCtx.vPos = m_ps.in.POS;
|
fogCtx.vPos = m_ps.in.POS;
|
||||||
fogCtx.vFog = m_ps.in.FOG;
|
fogCtx.vFog = m_ps.in.FOG;
|
||||||
fogCtx.oColor = current;
|
fogCtx.oColor = current;
|
||||||
|
fogCtx.IsFixedFunction = true;
|
||||||
|
fogCtx.IsPositionT = false;
|
||||||
|
fogCtx.HasSpecular = false;
|
||||||
|
fogCtx.Specular = 0;
|
||||||
current = DoFixedFunctionFog(m_module, fogCtx);
|
current = DoFixedFunctionFog(m_module, fogCtx);
|
||||||
|
|
||||||
m_module.opStore(m_ps.out.COLOR, current);
|
m_module.opStore(m_ps.out.COLOR, current);
|
||||||
|
@ -29,6 +29,11 @@ namespace dxvk {
|
|||||||
uint32_t oColor;
|
uint32_t oColor;
|
||||||
|
|
||||||
bool HasFogInput;
|
bool HasFogInput;
|
||||||
|
|
||||||
|
bool IsFixedFunction;
|
||||||
|
bool IsPositionT;
|
||||||
|
bool HasSpecular;
|
||||||
|
uint32_t Specular;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct D3D9FixedFunctionOptions {
|
struct D3D9FixedFunctionOptions {
|
||||||
|
@ -3521,6 +3521,10 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
|||||||
fogCtx.vPos = m_module.opLoad(getVectorTypeId(vPosPtr.type), vPosPtr.id);
|
fogCtx.vPos = m_module.opLoad(getVectorTypeId(vPosPtr.type), vPosPtr.id);
|
||||||
fogCtx.vFog = m_module.opLoad(getVectorTypeId(vFogPtr.type), vFogPtr.id);
|
fogCtx.vFog = m_module.opLoad(getVectorTypeId(vFogPtr.type), vFogPtr.id);
|
||||||
fogCtx.oColor = m_module.opLoad(getVectorTypeId(oColor0Ptr.type), oColor0Ptr.id);
|
fogCtx.oColor = m_module.opLoad(getVectorTypeId(oColor0Ptr.type), oColor0Ptr.id);
|
||||||
|
fogCtx.IsFixedFunction = false;
|
||||||
|
fogCtx.IsPositionT = false;
|
||||||
|
fogCtx.HasSpecular = false;
|
||||||
|
fogCtx.Specular = 0;
|
||||||
|
|
||||||
m_module.opStore(oColor0Ptr.id, DoFixedFunctionFog(m_module, fogCtx));
|
m_module.opStore(oColor0Ptr.id, DoFixedFunctionFog(m_module, fogCtx));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user