1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-04 16:24:29 +01:00

[d3d9] FF: Apply transform flags count to generated texture coords

... and fix cases where projection doesn't get applied.
This commit is contained in:
Robin Kertels 2024-05-23 00:18:01 +02:00 committed by Joshie
parent c98152683f
commit 7df8017e46

View File

@ -1139,12 +1139,12 @@ namespace dxvk {
case (DXVK_TSS_TCI_CAMERASPACENORMAL >> TCIOffset): case (DXVK_TSS_TCI_CAMERASPACENORMAL >> TCIOffset):
transformed = outNrm; transformed = outNrm;
count = 4; count = std::min(flags, 4u);
break; break;
case (DXVK_TSS_TCI_CAMERASPACEPOSITION >> TCIOffset): case (DXVK_TSS_TCI_CAMERASPACEPOSITION >> TCIOffset):
transformed = m_module.opCompositeInsert(m_vec4Type, m_module.constf32(1.0f), vtx, 1, &wIndex); transformed = m_module.opCompositeInsert(m_vec4Type, m_module.constf32(1.0f), vtx, 1, &wIndex);
count = 4; count = std::min(flags, 4u);
break; break;
case (DXVK_TSS_TCI_CAMERASPACEREFLECTIONVECTOR >> TCIOffset): { case (DXVK_TSS_TCI_CAMERASPACEREFLECTIONVECTOR >> TCIOffset): {
@ -1159,7 +1159,7 @@ namespace dxvk {
transformIndices[3] = m_module.constf32(1.0f); transformIndices[3] = m_module.constf32(1.0f);
transformed = m_module.opCompositeConstruct(m_vec4Type, transformIndices.size(), transformIndices.data()); transformed = m_module.opCompositeConstruct(m_vec4Type, transformIndices.size(), transformIndices.data());
count = 4; count = std::min(flags, 4u);
break; break;
} }
@ -1183,12 +1183,11 @@ namespace dxvk {
transformIndices[3] = m_module.constf32(1.0f); transformIndices[3] = m_module.constf32(1.0f);
transformed = m_module.opCompositeConstruct(m_vec4Type, transformIndices.size(), transformIndices.data()); transformed = m_module.opCompositeConstruct(m_vec4Type, transformIndices.size(), transformIndices.data());
count = 4; count = std::min(flags, 4u);
break; break;
} }
} }
if (applyTransform || (count != 4 && count != 0)) {
if (applyTransform && !m_vsKey.Data.Contents.HasPositionT) { if (applyTransform && !m_vsKey.Data.Contents.HasPositionT) {
for (uint32_t j = count; j < 4; j++) { for (uint32_t j = count; j < 4; j++) {
// If we're outside the component count of the vertex decl for this texcoord then we pad with zeroes. // If we're outside the component count of the vertex decl for this texcoord then we pad with zeroes.
@ -1205,14 +1204,22 @@ namespace dxvk {
transformed = m_module.opVectorTimesMatrix(m_vec4Type, transformed, m_vs.constants.texcoord[i]); transformed = m_module.opVectorTimesMatrix(m_vec4Type, transformed, m_vs.constants.texcoord[i]);
} }
// Pad the unused section of it with the value for projection. // The projection idx is always based on the flags, even when the input mode is not DXVK_TSS_TCI_PASSTHRU.
uint32_t projIdx = std::max(2u, count - 1); uint32_t projValue;
uint32_t projValue = m_module.opCompositeExtract(m_floatType, transformed, 1, &projIdx); if (count < 3) {
// Not enough components to do projection.
for (uint32_t j = count; j < 4; j++) // Native drivers render normally or garbage with D3DFVF_TEXCOORDSIZE2 or D3DTTFF_COUNT <3
transformed = m_module.opCompositeInsert(m_vec4Type, projValue, transformed, 1, &j); projValue = m_module.constf32(1.0f);
} else {
uint32_t projIdx = count - 1;
projValue = m_module.opCompositeExtract(m_floatType, transformed, 1, &projIdx);
} }
// The w component is only used for projection or unused, so always insert the component that's supposed to be divided by there.
// The fragment shader will then decide whether to project or not.
uint32_t wIdx = 3;
transformed = m_module.opCompositeInsert(m_vec4Type, projValue, transformed, 1, &wIdx);
m_module.opStore(m_vs.out.TEXCOORD[i], transformed); m_module.opStore(m_vs.out.TEXCOORD[i], transformed);
} }