diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 9ac5211de..9c12ae1f5 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -965,9 +965,13 @@ namespace dxvk { m_flags.set(DxvkGraphicsPipelineFlag::HasRasterizerDiscard); } - if (m_barrier.access & VK_ACCESS_SHADER_WRITE_BIT) + if (m_barrier.access & VK_ACCESS_SHADER_WRITE_BIT) { m_flags.set(DxvkGraphicsPipelineFlag::HasStorageDescriptors); + if (layout->layout().getHazardousSetMask()) + m_flags.set(DxvkGraphicsPipelineFlag::UnrollMergedDraws); + } + if (m_shaders.fs != nullptr) { if (m_shaders.fs->flags().test(DxvkShaderFlag::HasSampleRateShading)) m_flags.set(DxvkGraphicsPipelineFlag::HasSampleRateShading); diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index 3503fd896..2dde3e162 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -31,6 +31,7 @@ namespace dxvk { HasStorageDescriptors, HasSampleRateShading, HasSampleMaskExport, + UnrollMergedDraws, }; using DxvkGraphicsPipelineFlags = Flags; @@ -660,4 +661,4 @@ namespace dxvk { }; -} \ No newline at end of file +} diff --git a/src/dxvk/dxvk_pipelayout.cpp b/src/dxvk/dxvk_pipelayout.cpp index 9132d025c..cf3f69553 100644 --- a/src/dxvk/dxvk_pipelayout.cpp +++ b/src/dxvk/dxvk_pipelayout.cpp @@ -205,7 +205,7 @@ namespace dxvk { DxvkBindingLayout::DxvkBindingLayout(VkShaderStageFlags stages) - : m_pushConst { 0, 0, 0 }, m_pushConstStages(0), m_stages(stages) { + : m_pushConst { 0, 0, 0 }, m_pushConstStages(0), m_stages(stages), m_hazards(0u) { } @@ -236,6 +236,9 @@ namespace dxvk { void DxvkBindingLayout::addBinding(const DxvkBindingInfo& binding) { uint32_t set = binding.computeSetIndex(); m_bindings[set].addBinding(binding); + + if ((binding.access & VK_ACCESS_2_SHADER_WRITE_BIT) && binding.accessOp == DxvkAccessOp::None) + m_hazards |= 1u << set; } @@ -260,6 +263,8 @@ namespace dxvk { addPushConstantRange(layout.m_pushConst); m_pushConstStages |= layout.m_pushConstStages; + + m_hazards |= layout.m_hazards; } @@ -400,4 +405,4 @@ namespace dxvk { return barrier; } -} \ No newline at end of file +} diff --git a/src/dxvk/dxvk_pipelayout.h b/src/dxvk/dxvk_pipelayout.h index 07d3f8e41..4f43b60ad 100644 --- a/src/dxvk/dxvk_pipelayout.h +++ b/src/dxvk/dxvk_pipelayout.h @@ -337,6 +337,16 @@ namespace dxvk { return m_stages; } + /** + * \brief Queries hazardous sets + * + * \returns Mask of sets with storage descriptors + * that are not accessed in an order-invariant way. + */ + uint32_t getHazardousSetMask() const { + return m_hazards; + } + /** * \brief Queries defined descriptor set layouts * @@ -394,6 +404,7 @@ namespace dxvk { VkPushConstantRange m_pushConst; VkShaderStageFlags m_pushConstStages; VkShaderStageFlags m_stages; + uint32_t m_hazards; };