From 8f77fc9371d739978b664716f2073e8db090094e Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 14 Feb 2025 21:42:30 +0100 Subject: [PATCH] [dxvk] Rework compute barrier tracking --- src/dxvk/dxvk_context.cpp | 76 ++++++++++----------------------------- src/dxvk/dxvk_context.h | 3 +- 2 files changed, 19 insertions(+), 60 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index ed04ef949..7a8deeb86 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -6610,7 +6610,13 @@ namespace dxvk { return false; } - this->commitComputeBarriers(); + if (this->checkComputeHazards()) { + this->flushBarriers(); + + // Dirty descriptors if this hasn't happened yet for + // whatever reason in order to re-emit barriers + m_descriptorState.dirtyStages(VK_SHADER_STAGE_COMPUTE_BIT); + } if (m_descriptorState.hasDirtyComputeSets()) this->updateComputeShaderResources(); @@ -6705,63 +6711,6 @@ namespace dxvk { } - template - void DxvkContext::commitComputeBarriers() { - const auto& layout = m_state.cp.pipeline->getBindings()->layout(); - - // Exit early if we're only checking for hazards and - // if the barrier set is empty, to avoid some overhead. - if (!DoEmit && m_barrierTracker.empty()) - return; - - for (uint32_t i = 0; i < DxvkDescriptorSets::CsSetCount; i++) { - uint32_t bindingCount = layout.getBindingCount(i); - - for (uint32_t j = 0; j < bindingCount; j++) { - const DxvkBindingInfo& binding = layout.getBinding(i, j); - const DxvkShaderResourceSlot& slot = m_rc[binding.resourceBinding]; - - bool requiresBarrier = false; - - switch (binding.descriptorType) { - case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: - if (likely(slot.bufferSlice.length())) { - requiresBarrier = this->checkBufferBarrier(slot.bufferSlice, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, binding.access); - } - break; - - case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: - case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - if (likely(slot.bufferView != nullptr)) { - requiresBarrier = this->checkBufferViewBarrier(slot.bufferView, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, binding.access); - } - break; - - case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: - if (likely(slot.imageView != nullptr)) { - requiresBarrier = this->checkImageViewBarrier(slot.imageView, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, binding.access); - } - break; - - default: - /* nothing to do */; - } - - if (requiresBarrier) { - flushBarriers(); - return; - } - } - } - } - - template bool DxvkContext::checkResourceHazards( const DxvkBindingLayout& layout, @@ -6842,6 +6791,17 @@ namespace dxvk { } + bool DxvkContext::checkComputeHazards() { + // Exit early if we know that there cannot be any hazards to avoid + // some overhead after barriers are flushed. This is common. + if (m_barrierTracker.empty()) + return false; + + const auto& layout = m_state.cp.pipeline->getBindings()->layout(); + return checkResourceHazards(layout, layout.getSetMask()); + } + + template bool DxvkContext::checkGraphicsHazards() { if (m_barrierControl.test(DxvkBarrierControl::IgnoreGraphicsBarriers)) diff --git a/src/dxvk/dxvk_context.h b/src/dxvk/dxvk_context.h index c70b1701d..d1131032f 100644 --- a/src/dxvk/dxvk_context.h +++ b/src/dxvk/dxvk_context.h @@ -1762,8 +1762,7 @@ namespace dxvk { const DxvkBindingLayout& layout, uint32_t setMask); - template - void commitComputeBarriers(); + bool checkComputeHazards(); template bool checkGraphicsHazards();