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<DxvkGraphicsPipelineFlag>;
@@ -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;
 
   };