From d5e05f4d4d2f82e38c08ba66d890f9e223b27ed4 Mon Sep 17 00:00:00 2001 From: Oleksii Bozhenko Date: Wed, 3 May 2023 12:30:38 +0300 Subject: [PATCH] [d3d9] fix opCompositeExtract out of bound Closes: https://github.com/doitsujin/dxvk/issues/3293 Signed-by: Oleksii Bozhenko --- src/d3d9/d3d9_fixed_function.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/d3d9/d3d9_fixed_function.cpp b/src/d3d9/d3d9_fixed_function.cpp index 7b6b379bba47..2673c33e002f 100644 --- a/src/d3d9/d3d9_fixed_function.cpp +++ b/src/d3d9/d3d9_fixed_function.cpp @@ -1102,19 +1102,30 @@ namespace dxvk { m_module.opStore(m_vs.out.NORMAL, outNrm); for (uint32_t i = 0; i < caps::TextureStageCount; i++) { - uint32_t inputIndex = (m_vsKey.Data.Contents.TexcoordIndices >> (i * 3)) & 0b111; - uint32_t inputFlags = (m_vsKey.Data.Contents.TexcoordFlags >> (i * 3)) & 0b111; + uint32_t inputIndex = (m_vsKey.Data.Contents.TexcoordIndices >> (i * 3)) & 0b111; + uint32_t inputFlags = (m_vsKey.Data.Contents.TexcoordFlags >> (i * 3)) & 0b111; + uint32_t texcoordCount = (m_vsKey.Data.Contents.TexcoordDeclMask >> (i * 3)) & 0b111; uint32_t transformed; const uint32_t wIndex = 3; uint32_t flags = (m_vsKey.Data.Contents.TransformFlags >> (i * 3)) & 0b111; - uint32_t count = flags; + uint32_t count; switch (inputFlags) { default: case (DXVK_TSS_TCI_PASSTHRU >> TCIOffset): transformed = m_vs.in.TEXCOORD[inputIndex & 0xFF]; + // flags is actually the number of elements that get passed + // to the rasterizer. + count = flags; + if (texcoordCount) { + // Clamp by the number of elements in the texcoord input. + if (!count || count > texcoordCount) + count = texcoordCount; + } + else + flags = D3DTTFF_DISABLE; break; case (DXVK_TSS_TCI_CAMERASPACENORMAL >> TCIOffset): @@ -1798,10 +1809,9 @@ namespace dxvk { texcoord, texcoord, texcoordCnt, indices.data()); uint32_t projIdx = m_fsKey.Stages[i].Contents.ProjectedCount; - if (projIdx == 0) + if (projIdx == 0 || projIdx > texcoordCnt) projIdx = texcoordCnt; - else - projIdx--; + --projIdx; uint32_t projValue = 0;