diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 3b55f27f..e78c125c 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -1987,11 +1987,11 @@ namespace dxvk { auto shader = commonShader.GetShader(); - if (shader->hasCapability(spv::CapabilityStencilExportEXT) + if (shader->flags().test(DxvkShaderFlag::ExportsStencilRef) && !m_dxvkDevice->extensions().extShaderStencilExport) return E_INVALIDARG; - if (shader->hasCapability(spv::CapabilityShaderViewportIndexLayerEXT) + if (shader->flags().test(DxvkShaderFlag::ExportsViewportIndexLayerFromVertexStage) && !m_dxvkDevice->extensions().extShaderViewportIndexLayer) return E_INVALIDARG; diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 82cd58e0..cadd72a0 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -29,13 +29,13 @@ namespace dxvk { m_vsIn = m_shaders.vs != nullptr ? m_shaders.vs->interfaceSlots().inputSlots : 0; m_fsOut = m_shaders.fs != nullptr ? m_shaders.fs->interfaceSlots().outputSlots : 0; - if (m_shaders.gs != nullptr && m_shaders.gs->hasCapability(spv::CapabilityTransformFeedback)) + if (m_shaders.gs != nullptr && m_shaders.gs->flags().test(DxvkShaderFlag::HasTransformFeedback)) m_flags.set(DxvkGraphicsPipelineFlag::HasTransformFeedback); if (m_layout->getStorageDescriptorStages()) m_flags.set(DxvkGraphicsPipelineFlag::HasStorageDescriptors); - m_common.msSampleShadingEnable = m_shaders.fs != nullptr && m_shaders.fs->hasCapability(spv::CapabilitySampleRateShading); + m_common.msSampleShadingEnable = m_shaders.fs != nullptr && m_shaders.fs->flags().test(DxvkShaderFlag::HasSampleRateShading); m_common.msSampleShadingFactor = 1.0f; } diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index d258f799..8e2f6080 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -127,8 +127,21 @@ namespace dxvk { m_o1IdxOffset = ins.offset() + 3; } - if (ins.opCode() == spv::OpCapability) - m_capabilities.push_back(spv::Capability(ins.arg(1))); + if (ins.opCode() == spv::OpExecutionMode) { + if (ins.arg(2) == spv::ExecutionModeStencilRefReplacingEXT) + m_flags.set(DxvkShaderFlag::ExportsStencilRef); + + if (ins.arg(2) == spv::ExecutionModeXfb) + m_flags.set(DxvkShaderFlag::HasTransformFeedback); + } + + if (ins.opCode() == spv::OpCapability) { + if (ins.arg(1) == spv::CapabilitySampleRateShading) + m_flags.set(DxvkShaderFlag::HasSampleRateShading); + + if (ins.arg(1) == spv::CapabilityShaderViewportIndexLayerEXT) + m_flags.set(DxvkShaderFlag::ExportsViewportIndexLayerFromVertexStage); + } } } @@ -138,15 +151,6 @@ namespace dxvk { } - bool DxvkShader::hasCapability(spv::Capability cap) { - auto entry = std::find( - m_capabilities.begin(), - m_capabilities.end(), cap); - - return entry != m_capabilities.end(); - } - - void DxvkShader::defineResourceSlots( DxvkDescriptorSlotMapping& mapping) const { for (const auto& slot : m_slots) diff --git a/src/dxvk/dxvk_shader.h b/src/dxvk/dxvk_shader.h index 50526a80..716c0cf0 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -33,7 +33,21 @@ namespace dxvk { RasterizerSampleCount = SpecConstantRangeStart + 0, FirstPipelineConstant }; - + + /** + * \brief Shader flags + * + * Provides extra information about the features + * used by a shader. + */ + enum DxvkShaderFlag : uint64_t { + HasSampleRateShading, + HasTransformFeedback, + ExportsStencilRef, + ExportsViewportIndexLayerFromVertexStage, + }; + + using DxvkShaderFlags = Flags; /** * \brief Shader interface slots @@ -143,16 +157,12 @@ namespace dxvk { } /** - * \brief Checks whether a capability is enabled - * - * If the shader contains an \c OpCapability - * instruction with the given capability, it - * is considered enabled. This may be required - * to correctly set up certain pipeline states. - * \param [in] cap The capability to check - * \returns \c true if \c cap is enabled + * \brief Retrieves shader flags + * \returns Shader flags */ - bool hasCapability(spv::Capability cap); + DxvkShaderFlags flags() const { + return m_flags; + } /** * \brief Adds resource slots definitions to a mapping @@ -274,13 +284,12 @@ namespace dxvk { std::vector m_slots; std::vector m_idOffsets; DxvkInterfaceSlots m_interface; + DxvkShaderFlags m_flags; DxvkShaderOptions m_options; DxvkShaderConstData m_constData; DxvkShaderKey m_key; size_t m_hash = 0; - std::vector m_capabilities; - size_t m_o1IdxOffset = 0; size_t m_o1LocOffset = 0;