diff --git a/src/dxvk/dxvk_constant_state.h b/src/dxvk/dxvk_constant_state.h index c8903093..a0718f87 100644 --- a/src/dxvk/dxvk_constant_state.h +++ b/src/dxvk/dxvk_constant_state.h @@ -59,11 +59,9 @@ namespace dxvk { * aspects of multisampling. */ struct DxvkMultisampleState { - uint32_t sampleMask; - VkBool32 enableAlphaToCoverage; - VkBool32 enableAlphaToOne; - VkBool32 enableSampleShading; - float minSampleShading; + uint32_t sampleMask; + VkBool32 enableAlphaToCoverage; + VkBool32 enableAlphaToOne; }; diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index eed988f2..d1b1c10b 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1277,8 +1277,6 @@ namespace dxvk { m_state.gp.state.msSampleMask = ms.sampleMask; m_state.gp.state.msEnableAlphaToCoverage = ms.enableAlphaToCoverage; m_state.gp.state.msEnableAlphaToOne = ms.enableAlphaToOne; - m_state.gp.state.msEnableSampleShading = ms.enableSampleShading; - m_state.gp.state.msMinSampleShading = ms.minSampleShading; m_flags.set(DxvkContextFlag::GpDirtyPipelineState); } diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 4d2b5098..0bd690f9 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -64,6 +64,9 @@ namespace dxvk { m_vsIn = vs != nullptr ? vs->interfaceSlots().inputSlots : 0; m_fsOut = fs != nullptr ? fs->interfaceSlots().outputSlots : 0; + + m_common.msSampleShadingEnable = fs != nullptr && fs->hasCapability(spv::CapabilitySampleRateShading); + m_common.msSampleShadingFactor = 1.0f; } @@ -183,8 +186,8 @@ namespace dxvk { msInfo.pNext = nullptr; msInfo.flags = 0; msInfo.rasterizationSamples = state.msSampleCount; - msInfo.sampleShadingEnable = state.msEnableSampleShading; - msInfo.minSampleShading = state.msMinSampleShading; + msInfo.sampleShadingEnable = m_common.msSampleShadingEnable; + msInfo.minSampleShading = m_common.msSampleShadingFactor; msInfo.pSampleMask = &state.msSampleMask; msInfo.alphaToCoverageEnable = state.msEnableAlphaToCoverage; msInfo.alphaToOneEnable = state.msEnableAlphaToOne; diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 283ec2b2..67d620ee 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -59,8 +59,6 @@ namespace dxvk { uint32_t msSampleMask; VkBool32 msEnableAlphaToCoverage; VkBool32 msEnableAlphaToOne; - VkBool32 msEnableSampleShading; - float msMinSampleShading; VkBool32 dsEnableDepthTest; VkBool32 dsEnableDepthWrite; @@ -79,6 +77,18 @@ namespace dxvk { }; + /** + * \brief Common graphics pipeline state + * + * Non-dynamic pipeline state that cannot + * be changed dynamically. + */ + struct DxvkGraphicsCommonPipelineStateInfo { + bool msSampleShadingEnable; + float msSampleShadingFactor; + }; + + /** * \brief Graphics pipeline * @@ -135,8 +145,8 @@ namespace dxvk { const DxvkDevice* const m_device; const Rc m_vkd; - Rc m_cache; - Rc m_layout; + Rc m_cache; + Rc m_layout; Rc m_vs; Rc m_tcs; @@ -147,6 +157,8 @@ namespace dxvk { uint32_t m_vsIn = 0; uint32_t m_fsOut = 0; + DxvkGraphicsCommonPipelineStateInfo m_common; + std::vector m_pipelines; VkPipeline m_basePipeline = VK_NULL_HANDLE; diff --git a/src/dxvk/dxvk_shader.cpp b/src/dxvk/dxvk_shader.cpp index abedefd9..f104078d 100644 --- a/src/dxvk/dxvk_shader.cpp +++ b/src/dxvk/dxvk_shader.cpp @@ -57,6 +57,20 @@ namespace dxvk { } + bool DxvkShader::hasCapability(spv::Capability cap) { + for (auto ins : m_code) { + // OpCapability instructions come first + if (ins.opCode() != spv::OpCapability) + return false; + + if (ins.arg(1) == cap) + return true; + } + + return false; + } + + 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 e6ebd7a6..ce64624a 100644 --- a/src/dxvk/dxvk_shader.h +++ b/src/dxvk/dxvk_shader.h @@ -98,6 +98,18 @@ namespace dxvk { ~DxvkShader(); + /** + * \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 + */ + bool hasCapability(spv::Capability cap); + /** * \brief Adds resource slots definitions to a mapping * diff --git a/src/dxvk/hud/dxvk_hud.cpp b/src/dxvk/hud/dxvk_hud.cpp index 2d3c9ac3..7a7fdf7a 100644 --- a/src/dxvk/hud/dxvk_hud.cpp +++ b/src/dxvk/hud/dxvk_hud.cpp @@ -198,8 +198,6 @@ namespace dxvk::hud { msState.sampleMask = 0xFFFFFFFF; msState.enableAlphaToCoverage = VK_FALSE; msState.enableAlphaToOne = VK_FALSE; - msState.enableSampleShading = VK_FALSE; - msState.minSampleShading = 1.0f; m_context->setMultisampleState(msState); VkStencilOpState stencilOp;