From 023cf01c3ce37a40e581bd6a75f4fdc96f4edebf Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 7 Feb 2019 00:27:11 +0100 Subject: [PATCH] [dxvk] Implemet IgnoreWriteAfterWrite for compute shaders When enabled, potential write-after-write hazards will be ignored and no barrier will be inserted. Can improve performance in some cases. --- src/dxvk/dxvk_context.cpp | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index 2c704d28..8b10e889 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -3274,46 +3274,58 @@ namespace dxvk { const DxvkDescriptorSlot binding = layout->binding(i); const DxvkShaderResourceSlot& slot = m_rc[binding.slot]; - DxvkAccessFlags access = DxvkAccess::Read; + DxvkAccessFlags dstAccess = DxvkAccess::Read; + DxvkAccessFlags srcAccess = 0; switch (binding.type) { case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: if (binding.access & VK_ACCESS_SHADER_WRITE_BIT) - access.set(DxvkAccess::Write); + dstAccess.set(DxvkAccess::Write); /* fall through */ case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: - requiresBarrier = m_barriers.isBufferDirty( - slot.bufferSlice.getSliceHandle(), access); + srcAccess = m_barriers.getBufferAccess( + slot.bufferSlice.getSliceHandle()); break; case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: if (binding.access & VK_ACCESS_SHADER_WRITE_BIT) - access.set(DxvkAccess::Write); + dstAccess.set(DxvkAccess::Write); /* fall through */ case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: - requiresBarrier = m_barriers.isBufferDirty( - slot.bufferView->getSliceHandle(), access); + srcAccess = m_barriers.getBufferAccess( + slot.bufferView->getSliceHandle()); break; case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: if (binding.access & VK_ACCESS_SHADER_WRITE_BIT) - access.set(DxvkAccess::Write); + dstAccess.set(DxvkAccess::Write); /* fall through */ case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: - requiresBarrier = m_barriers.isImageDirty( + srcAccess = m_barriers.getImageAccess( slot.imageView->image(), - slot.imageView->subresources(), - access); + slot.imageView->subresources()); break; default: /* nothing to do */; } + + if (srcAccess == 0) + continue; + + // Skip write-after-write barriers if explicitly requested + if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite)) + && (m_barriers.getSrcStages() == VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT) + && (srcAccess.test(DxvkAccess::Write)) + && (dstAccess.test(DxvkAccess::Write))) + continue; + + requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write); } }