1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-27 04:54:15 +01:00

[dxvk] Patch geometry shader if input topology does not match pipeline

This commit is contained in:
Philip Rebohle 2025-02-26 16:59:16 +01:00
parent d05abbf8fd
commit 91ac0d2742

View File

@ -9,6 +9,41 @@
namespace dxvk {
VkPrimitiveTopology determineGsInputTopology(
VkPrimitiveTopology shader,
VkPrimitiveTopology state) {
switch (state) {
case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
if (shader == VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY)
return VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY;
[[fallthrough]];
case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
if (shader == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY)
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY;
[[fallthrough]];
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
default:
Logger::err(str::format("Unhandled primitive topology ", state));
return VK_PRIMITIVE_TOPOLOGY_MAX_ENUM;
}
}
DxvkGraphicsPipelineVertexInputState::DxvkGraphicsPipelineVertexInputState() {
}
@ -836,6 +871,13 @@ namespace dxvk {
}
info.undefinedInputs = (providedInputs & consumedInputs) ^ consumedInputs;
// Fix up input topology for geometry shaders as necessary
if (shaderInfo.stage == VK_SHADER_STAGE_GEOMETRY_BIT) {
VkPrimitiveTopology iaTopology = shaders.tes ? shaders.tes->info().outputTopology : state.ia.primitiveTopology();
info.inputTopology = determineGsInputTopology(shaderInfo.inputTopology, iaTopology);
}
return info;
}
@ -1190,6 +1232,16 @@ namespace dxvk {
if ((vsInputMask & ilAttributeMask) != vsInputMask)
return false;
if (m_shaders.gs != nullptr) {
// If the geometry shader's input topology is not compatible with
// the topology set to the pipeline, we need to patch the GS.
VkPrimitiveTopology iaTopology = m_shaders.tes ? m_shaders.tes->info().outputTopology : state.ia.primitiveTopology();
VkPrimitiveTopology gsTopology = m_shaders.gs->info().inputTopology;
if (determineGsInputTopology(gsTopology, iaTopology) != gsTopology)
return false;
}
if (m_shaders.tcs != nullptr) {
// If tessellation shaders are present, the input patch
// vertex count must match the shader's definition.