diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 848007b7..75c6ddd5 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -5322,6 +5322,50 @@ namespace dxvk { emitValueStore(ptr, value, mask); } break; + case DxbcSystemValue::RenderTargetId: { + if (m_version.type() != DxbcProgramType::GeometryShader) + enableShaderViewportIndexLayer(); + + if (m_gs.builtinLayer == 0) { + m_gs.builtinLayer = emitNewBuiltinVariable({ + { DxbcScalarType::Uint32, 1, 0 }, + spv::StorageClassOutput }, + spv::BuiltInLayer, + "o_layer"); + } + + DxbcRegisterPointer ptr; + ptr.type = { DxbcScalarType::Uint32, 1 }; + ptr.id = m_gs.builtinLayer; + + emitValueStore( + ptr, emitRegisterExtract(value, mask), + DxbcRegMask(true, false, false, false)); + } break; + + case DxbcSystemValue::ViewportId: { + if (m_version.type() != DxbcProgramType::GeometryShader) + enableShaderViewportIndexLayer(); + + if (m_gs.builtinViewportId == 0) { + m_module.enableCapability(spv::CapabilityMultiViewport); + + m_gs.builtinViewportId = emitNewBuiltinVariable({ + { DxbcScalarType::Uint32, 1, 0 }, + spv::StorageClassOutput }, + spv::BuiltInViewportIndex, + "o_viewport"); + } + + DxbcRegisterPointer ptr; + ptr.type = { DxbcScalarType::Uint32, 1}; + ptr.id = m_gs.builtinViewportId; + + emitValueStore( + ptr, emitRegisterExtract(value, mask), + DxbcRegMask(true, false, false, false)); + } break; + default: Logger::warn(str::format( "DxbcCompiler: Unhandled VS SV output: ", sv)); @@ -5394,47 +5438,11 @@ namespace dxvk { case DxbcSystemValue::Position: case DxbcSystemValue::CullDistance: case DxbcSystemValue::ClipDistance: + case DxbcSystemValue::RenderTargetId: + case DxbcSystemValue::ViewportId: emitVsSystemValueStore(sv, mask, value); break; - case DxbcSystemValue::RenderTargetId: { - if (m_gs.builtinLayer == 0) { - m_gs.builtinLayer = emitNewBuiltinVariable({ - { DxbcScalarType::Uint32, 1, 0 }, - spv::StorageClassOutput }, - spv::BuiltInLayer, - "gs_layer"); - } - - DxbcRegisterPointer ptr; - ptr.type = { DxbcScalarType::Uint32, 1 }; - ptr.id = m_gs.builtinLayer; - - emitValueStore( - ptr, emitRegisterExtract(value, mask), - DxbcRegMask(true, false, false, false)); - } break; - - case DxbcSystemValue::ViewportId: { - if (m_gs.builtinViewportId == 0) { - m_module.enableCapability(spv::CapabilityMultiViewport); - - m_gs.builtinViewportId = emitNewBuiltinVariable({ - { DxbcScalarType::Uint32, 1, 0 }, - spv::StorageClassOutput }, - spv::BuiltInViewportIndex, - "gs_viewport_id"); - } - - DxbcRegisterPointer ptr; - ptr.type = { DxbcScalarType::Uint32, 1}; - ptr.id = m_gs.builtinViewportId; - - emitValueStore( - ptr, emitRegisterExtract(value, mask), - DxbcRegMask(true, false, false, false)); - } break; - case DxbcSystemValue::PrimitiveId: { if (m_primitiveIdOut == 0) { m_primitiveIdOut = emitNewBuiltinVariable({ @@ -5477,6 +5485,8 @@ namespace dxvk { case DxbcSystemValue::Position: case DxbcSystemValue::CullDistance: case DxbcSystemValue::ClipDistance: + case DxbcSystemValue::RenderTargetId: + case DxbcSystemValue::ViewportId: emitVsSystemValueStore(sv, mask, value); break; @@ -6318,6 +6328,16 @@ namespace dxvk { } + void DxbcCompiler::enableShaderViewportIndexLayer() { + if (!m_extensions.shaderViewportIndexLayer) { + m_extensions.shaderViewportIndexLayer = true; + + m_module.enableExtension("SPV_EXT_shader_viewport_index_layer"); + m_module.enableCapability(spv::CapabilityShaderViewportIndexLayerEXT); + } + } + + DxbcCfgBlock* DxbcCompiler::cfgFindBlock( const std::initializer_list& types) { for (auto cur = m_controlFlowBlocks.rbegin(); diff --git a/src/dxbc/dxbc_compiler.h b/src/dxbc/dxbc_compiler.h index a48ffea5..79bcf615 100644 --- a/src/dxbc/dxbc_compiler.h +++ b/src/dxbc/dxbc_compiler.h @@ -328,6 +328,18 @@ namespace dxvk { uint32_t stride; }; + + /** + * \brief SPIR-V extension set + * + * Keeps track of which optional SPIR-V extensions + * are enabled so that any required setup code is + * only run once. + */ + struct DxbcSpirvExtensions { + bool shaderViewportIndexLayer = false; + }; + /** * \brief DXBC to SPIR-V shader compiler @@ -472,6 +484,10 @@ namespace dxvk { DxbcCompilerGsPart m_gs; DxbcCompilerPsPart m_ps; DxbcCompilerCsPart m_cs; + + ///////////////////////////// + // Enabled SPIR-V extensions + DxbcSpirvExtensions m_extensions; ///////////////////////////////////////////////////// // Shader interface and metadata declaration methods @@ -1050,6 +1066,10 @@ namespace dxvk { uint32_t emitBuiltinTessLevelInner( spv::StorageClass storageClass); + + //////////////////////////////// + // Extension enablement methods + void enableShaderViewportIndexLayer(); //////////////// // Misc methods