mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 14:52:11 +01:00
[d3d9] Only read point scale push constant in fixed function
Otherwise it doesn't exist and we're reading garbage/non-existant data. Even though this gets spec-constanted away via an opSelect, some drivers don't like this
This commit is contained in:
parent
e4bca7a42f
commit
753fcd5649
@ -254,7 +254,7 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
D3D9PointSizeInfoVS GetPointSizeInfoVS(SpirvModule& spvModule, uint32_t vPos, uint32_t vtx, uint32_t perVertPointSize, uint32_t rsBlock) {
|
D3D9PointSizeInfoVS GetPointSizeInfoVS(SpirvModule& spvModule, uint32_t vPos, uint32_t vtx, uint32_t perVertPointSize, uint32_t rsBlock, bool isFixedFunction) {
|
||||||
uint32_t floatType = spvModule.defFloatType(32);
|
uint32_t floatType = spvModule.defFloatType(32);
|
||||||
uint32_t floatPtr = spvModule.defPointerType(floatType, spv::StorageClassPushConstant);
|
uint32_t floatPtr = spvModule.defPointerType(floatType, spv::StorageClassPushConstant);
|
||||||
uint32_t vec3Type = spvModule.defVectorType(floatType, 3);
|
uint32_t vec3Type = spvModule.defVectorType(floatType, 3);
|
||||||
@ -267,43 +267,44 @@ namespace dxvk {
|
|||||||
return spvModule.opLoad(floatType, spvModule.opAccessChain(floatPtr, rsBlock, 1, &index));
|
return spvModule.opLoad(floatType, spvModule.opAccessChain(floatPtr, rsBlock, 1, &index));
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t pointMode = spvModule.specConst32(uint32Type, 0);
|
uint32_t value = perVertPointSize != 0 ? perVertPointSize : LoadFloat(D3D9RenderStateItem::PointSize);
|
||||||
spvModule.setDebugName(pointMode, "point_mode");
|
|
||||||
spvModule.decorateSpecId(pointMode, getSpecId(D3D9SpecConstantId::PointMode));
|
|
||||||
|
|
||||||
uint32_t scaleBit = spvModule.opBitFieldUExtract(uint32Type, pointMode, spvModule.consti32(0), spvModule.consti32(1));
|
if (isFixedFunction) {
|
||||||
uint32_t isScale = spvModule.opIEqual(boolType, scaleBit, spvModule.constu32(1));
|
uint32_t pointMode = spvModule.specConst32(uint32Type, 0);
|
||||||
|
spvModule.setDebugName(pointMode, "point_mode");
|
||||||
|
spvModule.decorateSpecId(pointMode, getSpecId(D3D9SpecConstantId::PointMode));
|
||||||
|
|
||||||
uint32_t regularValue = perVertPointSize != 0 ? perVertPointSize : LoadFloat(D3D9RenderStateItem::PointSize);
|
uint32_t scaleBit = spvModule.opBitFieldUExtract(uint32Type, pointMode, spvModule.consti32(0), spvModule.consti32(1));
|
||||||
|
uint32_t isScale = spvModule.opIEqual(boolType, scaleBit, spvModule.constu32(1));
|
||||||
|
|
||||||
uint32_t scaleC = LoadFloat(D3D9RenderStateItem::PointScaleC);
|
uint32_t scaleC = LoadFloat(D3D9RenderStateItem::PointScaleC);
|
||||||
uint32_t scaleB = LoadFloat(D3D9RenderStateItem::PointScaleB);
|
uint32_t scaleB = LoadFloat(D3D9RenderStateItem::PointScaleB);
|
||||||
uint32_t scaleA = LoadFloat(D3D9RenderStateItem::PointScaleA);
|
uint32_t scaleA = LoadFloat(D3D9RenderStateItem::PointScaleA);
|
||||||
|
|
||||||
std::array<uint32_t, 4> indices = { 0, 1, 2, 3 };
|
std::array<uint32_t, 4> indices = { 0, 1, 2, 3 };
|
||||||
|
|
||||||
uint32_t vtx3;
|
uint32_t vtx3;
|
||||||
if (vPos != 0) {
|
if (vPos != 0) {
|
||||||
vPos = spvModule.opLoad(vec4Type, vPos);
|
vPos = spvModule.opLoad(vec4Type, vPos);
|
||||||
|
|
||||||
uint32_t rhw = spvModule.opCompositeExtract(floatType, vPos, 1, &indices[3]);
|
uint32_t rhw = spvModule.opCompositeExtract(floatType, vPos, 1, &indices[3]);
|
||||||
rhw = spvModule.opFDiv(floatType, spvModule.constf32(1.0f), rhw);
|
rhw = spvModule.opFDiv(floatType, spvModule.constf32(1.0f), rhw);
|
||||||
uint32_t pos3 = spvModule.opVectorShuffle(vec3Type, vPos, vPos, 3, indices.data());
|
uint32_t pos3 = spvModule.opVectorShuffle(vec3Type, vPos, vPos, 3, indices.data());
|
||||||
vtx3 = spvModule.opVectorTimesScalar(vec3Type, pos3, rhw);
|
vtx3 = spvModule.opVectorTimesScalar(vec3Type, pos3, rhw);
|
||||||
|
} else {
|
||||||
|
vtx3 = spvModule.opVectorShuffle(vec3Type, vtx, vtx, 3, indices.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t DeSqr = spvModule.opDot (floatType, vtx3, vtx3);
|
||||||
|
uint32_t De = spvModule.opSqrt(floatType, DeSqr);
|
||||||
|
uint32_t scaleValue = spvModule.opFMul(floatType, scaleC, DeSqr);
|
||||||
|
scaleValue = spvModule.opFFma(floatType, scaleB, De, scaleValue);
|
||||||
|
scaleValue = spvModule.opFAdd(floatType, scaleA, scaleValue);
|
||||||
|
scaleValue = spvModule.opSqrt(floatType, scaleValue);
|
||||||
|
scaleValue = spvModule.opFDiv(floatType, value, scaleValue);
|
||||||
|
|
||||||
|
value = spvModule.opSelect(floatType, isScale, scaleValue, value);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
vtx3 = spvModule.opVectorShuffle(vec3Type, vtx, vtx, 3, indices.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t DeSqr = spvModule.opDot (floatType, vtx3, vtx3);
|
|
||||||
uint32_t De = spvModule.opSqrt(floatType, DeSqr);
|
|
||||||
uint32_t scaleValue = spvModule.opFMul(floatType, scaleC, DeSqr);
|
|
||||||
scaleValue = spvModule.opFFma(floatType, scaleB, De, scaleValue);
|
|
||||||
scaleValue = spvModule.opFAdd(floatType, scaleA, scaleValue);
|
|
||||||
scaleValue = spvModule.opSqrt(floatType, scaleValue);
|
|
||||||
scaleValue = spvModule.opFDiv(floatType, regularValue, scaleValue);
|
|
||||||
|
|
||||||
uint32_t value = spvModule.opSelect(floatType, isScale, scaleValue, regularValue);
|
|
||||||
|
|
||||||
uint32_t min = LoadFloat(D3D9RenderStateItem::PointSizeMin);
|
uint32_t min = LoadFloat(D3D9RenderStateItem::PointSizeMin);
|
||||||
uint32_t max = LoadFloat(D3D9RenderStateItem::PointSizeMax);
|
uint32_t max = LoadFloat(D3D9RenderStateItem::PointSizeMax);
|
||||||
@ -1171,7 +1172,7 @@ namespace dxvk {
|
|||||||
fogCtx.Specular = m_vs.in.COLOR[1];
|
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, true);
|
||||||
|
|
||||||
uint32_t pointSize = m_module.opFClamp(m_floatType, pointInfo.defaultValue, pointInfo.min, pointInfo.max);
|
uint32_t pointSize = m_module.opFClamp(m_floatType, pointInfo.defaultValue, pointInfo.min, pointInfo.max);
|
||||||
m_module.opStore(m_vs.out.POINTSIZE, pointSize);
|
m_module.opStore(m_vs.out.POINTSIZE, pointSize);
|
||||||
|
@ -56,7 +56,7 @@ namespace dxvk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Default point size and point scale magic!
|
// Default point size and point scale magic!
|
||||||
D3D9PointSizeInfoVS GetPointSizeInfoVS(SpirvModule& spvModule, uint32_t vPos, uint32_t vtx, uint32_t perVertPointSize, uint32_t rsBlock);
|
D3D9PointSizeInfoVS GetPointSizeInfoVS(SpirvModule& spvModule, uint32_t vPos, uint32_t vtx, uint32_t perVertPointSize, uint32_t rsBlock, bool isFixedFunction);
|
||||||
|
|
||||||
struct D3D9PointSizeInfoPS {
|
struct D3D9PointSizeInfoPS {
|
||||||
uint32_t isSprite;
|
uint32_t isSprite;
|
||||||
|
@ -3378,7 +3378,7 @@ void DxsoCompiler::emitControlFlowGenericLoop(
|
|||||||
if (!outputtedColor1)
|
if (!outputtedColor1)
|
||||||
OutputDefault(DxsoSemantic{ DxsoUsage::Color, 1 });
|
OutputDefault(DxsoSemantic{ DxsoUsage::Color, 1 });
|
||||||
|
|
||||||
auto pointInfo = GetPointSizeInfoVS(m_module, m_vs.oPos.id, 0, 0, m_rsBlock);
|
auto pointInfo = GetPointSizeInfoVS(m_module, m_vs.oPos.id, 0, 0, m_rsBlock, false);
|
||||||
|
|
||||||
if (m_vs.oPSize.id == 0) {
|
if (m_vs.oPSize.id == 0) {
|
||||||
m_vs.oPSize = this->emitRegisterPtr(
|
m_vs.oPSize = this->emitRegisterPtr(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user