1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-15 07:29:17 +01:00

[d3d9] Use precise matrix-vector operations to compute vertex position

This commit is contained in:
Philip Rebohle 2022-09-16 15:49:27 +02:00 committed by Joshie
parent b56ec10deb
commit 4fb6c200d7

View File

@ -976,8 +976,8 @@ namespace dxvk {
if (!m_vsKey.Data.Contents.HasPositionT) { if (!m_vsKey.Data.Contents.HasPositionT) {
if (m_vsKey.Data.Contents.VertexBlendMode == D3D9FF_VertexBlendMode_Normal) { if (m_vsKey.Data.Contents.VertexBlendMode == D3D9FF_VertexBlendMode_Normal) {
uint32_t blendWeightRemaining = m_module.constf32(1); uint32_t blendWeightRemaining = m_module.constf32(1);
uint32_t vtxSum = m_module.constvec4f32(0, 0, 0, 0); uint32_t vtxSum = 0;
uint32_t nrmSum = m_module.constvec3f32(0, 0, 0); uint32_t nrmSum = 0;
for (uint32_t i = 0; i <= m_vsKey.Data.Contents.VertexBlendCount; i++) { for (uint32_t i = 0; i <= m_vsKey.Data.Contents.VertexBlendCount; i++) {
std::array<uint32_t, 2> arrayIndices; std::array<uint32_t, 2> arrayIndices;
@ -1004,7 +1004,7 @@ namespace dxvk {
} }
nrmMtx = m_module.opCompositeConstruct(m_mat3Type, mtxIndices.size(), mtxIndices.data()); nrmMtx = m_module.opCompositeConstruct(m_mat3Type, mtxIndices.size(), mtxIndices.data());
uint32_t vtxResult = m_module.opVectorTimesMatrix(m_vec4Type, vtx, worldview); uint32_t vtxResult = emitVectorTimesMatrix(4, 4, vtx, worldview);
uint32_t nrmResult = m_module.opVectorTimesMatrix(m_vec3Type, normal, nrmMtx); uint32_t nrmResult = m_module.opVectorTimesMatrix(m_vec3Type, normal, nrmMtx);
uint32_t weight; uint32_t weight;
@ -1015,18 +1015,26 @@ namespace dxvk {
else else
weight = blendWeightRemaining; weight = blendWeightRemaining;
vtxResult = m_module.opVectorTimesScalar(m_vec4Type, vtxResult, weight); std::array<uint32_t, 4> weightIds = { weight, weight, weight, weight };
nrmResult = m_module.opVectorTimesScalar(m_vec3Type, nrmResult, weight); uint32_t weightVec4 = m_module.opCompositeConstruct(m_vec4Type, 4, weightIds.data());
uint32_t weightVec3 = m_module.opCompositeConstruct(m_vec3Type, 3, weightIds.data());
vtxSum = m_module.opFAdd(m_vec4Type, vtxSum, vtxResult); vtxSum = vtxSum
nrmSum = m_module.opFAdd(m_vec3Type, nrmSum, nrmResult); ? m_module.opFFma(m_vec4Type, vtxResult, weightVec4, vtxSum)
: m_module.opFMul(m_vec4Type, vtxResult, weightVec4);
nrmSum = nrmSum
? m_module.opFFma(m_vec3Type, nrmResult, weightVec3, nrmSum)
: m_module.opFMul(m_vec3Type, nrmResult, weightVec3);
m_module.decorate(vtxSum, spv::DecorationNoContraction);
} }
vtx = vtxSum; vtx = vtxSum;
normal = nrmSum; normal = nrmSum;
} }
else { else {
vtx = m_module.opVectorTimesMatrix(m_vec4Type, vtx, m_vs.constants.worldview); vtx = emitVectorTimesMatrix(4, 4, vtx, m_vs.constants.worldview);
uint32_t nrmMtx = m_vs.constants.normal; uint32_t nrmMtx = m_vs.constants.normal;
@ -1054,7 +1062,7 @@ namespace dxvk {
normal = m_module.opSelect(m_vec3Type, isZeroNormal3, m_module.constvec3f32(0.0f, 0.0f, 0.0f), normal); normal = m_module.opSelect(m_vec3Type, isZeroNormal3, m_module.constvec3f32(0.0f, 0.0f, 0.0f), normal);
} }
gl_Position = m_module.opVectorTimesMatrix(m_vec4Type, vtx, m_vs.constants.proj); gl_Position = emitVectorTimesMatrix(4, 4, vtx, m_vs.constants.proj);
} else { } else {
gl_Position = m_module.opFMul(m_vec4Type, gl_Position, m_vs.constants.invExtent); gl_Position = m_module.opFMul(m_vec4Type, gl_Position, m_vs.constants.invExtent);
gl_Position = m_module.opFAdd(m_vec4Type, gl_Position, m_vs.constants.invOffset); gl_Position = m_module.opFAdd(m_vec4Type, gl_Position, m_vs.constants.invOffset);
@ -2304,7 +2312,7 @@ namespace dxvk {
void D3D9FFShaderCompiler::emitVsClipping(uint32_t vtx) { void D3D9FFShaderCompiler::emitVsClipping(uint32_t vtx) {
uint32_t worldPos = m_module.opMatrixTimesVector(m_vec4Type, m_vs.constants.inverseView, vtx); uint32_t worldPos = emitMatrixTimesVector(4, 4, m_vs.constants.inverseView, vtx);
uint32_t clipPlaneCountId = m_module.constu32(caps::MaxClipPlanes); uint32_t clipPlaneCountId = m_module.constu32(caps::MaxClipPlanes);