From b56ec10deb2b6b9f03e2c5339143bf3c19938bd0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 16 Sep 2022 15:31:17 +0200 Subject: [PATCH] [d3d9] Add helpers for precise matrix-vector products --- src/d3d9/d3d9_fixed_function.cpp | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index c54bdc422..6a9f5c7c2 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -764,6 +764,9 @@ namespace dxvk { void alphaTestPS(); + uint32_t emitMatrixTimesVector(uint32_t rowCount, uint32_t colCount, uint32_t matrix, uint32_t vector); + uint32_t emitVectorTimesMatrix(uint32_t rowCount, uint32_t colCount, uint32_t vector, uint32_t matrix); + bool isVS() { return m_programType == DxsoProgramType::VertexShader; } bool isPS() { return !isVS(); } @@ -2390,6 +2393,38 @@ namespace dxvk { } + uint32_t D3D9FFShaderCompiler::emitMatrixTimesVector(uint32_t rowCount, uint32_t colCount, uint32_t matrix, uint32_t vector) { + uint32_t f32Type = m_module.defFloatType(32); + uint32_t vecType = m_module.defVectorType(f32Type, rowCount); + uint32_t accum = 0; + + for (uint32_t i = 0; i < colCount; i++) { + std::array indices = { i, i, i, i }; + + uint32_t a = m_module.opVectorShuffle(vecType, vector, vector, rowCount, indices.data()); + uint32_t b = m_module.opCompositeExtract(vecType, matrix, 1, &i); + + accum = accum + ? m_module.opFFma(vecType, a, b, accum) + : m_module.opFMul(vecType, a, b); + + m_module.decorate(accum, spv::DecorationNoContraction); + } + + return accum; + } + + + uint32_t D3D9FFShaderCompiler::emitVectorTimesMatrix(uint32_t rowCount, uint32_t colCount, uint32_t vector, uint32_t matrix) { + uint32_t f32Type = m_module.defFloatType(32); + uint32_t vecType = m_module.defVectorType(f32Type, colCount); + uint32_t matType = m_module.defMatrixType(vecType, rowCount); + + matrix = m_module.opTranspose(matType, matrix); + return emitMatrixTimesVector(colCount, rowCount, matrix, vector); + } + + D3D9FFShader::D3D9FFShader( D3D9DeviceEx* pDevice, const D3D9FFShaderKeyVS& Key) {