From a67c99943ae32dd93f6c39d791de8606f564c887 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Wed, 19 Jul 2023 21:12:30 +0200 Subject: [PATCH] [dxbc] Set output topology for GS and TES correctly --- src/dxbc/dxbc_compiler.cpp | 23 +++++++++++++---------- src/dxbc/dxbc_compiler.h | 2 ++ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 01f715e0..7a97fd57 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -257,6 +257,7 @@ namespace dxvk { info.outputMask = m_outputMask; info.uniformSize = m_immConstData.size(); info.uniformData = m_immConstData.data(); + info.outputTopology = m_outputTopology; if (m_programInfo.type() == DxbcProgramType::HullShader) info.patchVertexCount = m_hs.vertexCountIn; @@ -1294,16 +1295,17 @@ namespace dxvk { // The input primitive topology is stored within in the // control bits of the opcode token. In SPIR-V, we have // to define an execution mode. - const spv::ExecutionMode mode = [&] { + auto mode = [&] { switch (ins.controls.primitiveTopology()) { - case DxbcPrimitiveTopology::PointList: return spv::ExecutionModeOutputPoints; - case DxbcPrimitiveTopology::LineStrip: return spv::ExecutionModeOutputLineStrip; - case DxbcPrimitiveTopology::TriangleStrip: return spv::ExecutionModeOutputTriangleStrip; + case DxbcPrimitiveTopology::PointList: return std::make_pair(VK_PRIMITIVE_TOPOLOGY_POINT_LIST, spv::ExecutionModeOutputPoints); + case DxbcPrimitiveTopology::LineStrip: return std::make_pair(VK_PRIMITIVE_TOPOLOGY_LINE_LIST, spv::ExecutionModeOutputLineStrip); + case DxbcPrimitiveTopology::TriangleStrip: return std::make_pair(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, spv::ExecutionModeOutputTriangleStrip); default: throw DxvkError("DxbcCompiler: Unsupported primitive topology"); } }(); - m_module.setExecutionMode(m_entryPointId, mode); + m_outputTopology = mode.first; + m_module.setExecutionMode(m_entryPointId, mode.second); } @@ -1350,16 +1352,17 @@ namespace dxvk { void DxbcCompiler::emitDclTessDomain(const DxbcShaderInstruction& ins) { - const spv::ExecutionMode executionMode = [&] { + auto mode = [&] { switch (ins.controls.tessDomain()) { - case DxbcTessDomain::Isolines: return spv::ExecutionModeIsolines; - case DxbcTessDomain::Triangles: return spv::ExecutionModeTriangles; - case DxbcTessDomain::Quads: return spv::ExecutionModeQuads; + case DxbcTessDomain::Isolines: return std::make_pair(VK_PRIMITIVE_TOPOLOGY_LINE_LIST, spv::ExecutionModeIsolines); + case DxbcTessDomain::Triangles: return std::make_pair(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, spv::ExecutionModeTriangles); + case DxbcTessDomain::Quads: return std::make_pair(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, spv::ExecutionModeQuads); default: throw DxvkError("Dxbc: Invalid tess domain"); } }(); - m_module.setExecutionMode(m_entryPointId, executionMode); + m_outputTopology = mode.first; + m_module.setExecutionMode(m_entryPointId, mode.second); } diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index 4720066c..7b57358c 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -535,6 +535,8 @@ namespace dxvk { DxbcOpcode m_lastOp = DxbcOpcode::Nop; DxbcOpcode m_currOp = DxbcOpcode::Nop; + VkPrimitiveTopology m_outputTopology = VK_PRIMITIVE_TOPOLOGY_MAX_ENUM; + ///////////////////////////////////////////////////// // Shader interface and metadata declaration methods void emitDcl(