1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-11 19:24:11 +01:00

[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.
This commit is contained in:
Philip Rebohle 2019-02-07 00:27:11 +01:00
parent 24dca37fce
commit 023cf01c3c
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99

View File

@ -3274,46 +3274,58 @@ namespace dxvk {
const DxvkDescriptorSlot binding = layout->binding(i); const DxvkDescriptorSlot binding = layout->binding(i);
const DxvkShaderResourceSlot& slot = m_rc[binding.slot]; const DxvkShaderResourceSlot& slot = m_rc[binding.slot];
DxvkAccessFlags access = DxvkAccess::Read; DxvkAccessFlags dstAccess = DxvkAccess::Read;
DxvkAccessFlags srcAccess = 0;
switch (binding.type) { switch (binding.type) {
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
if (binding.access & VK_ACCESS_SHADER_WRITE_BIT) if (binding.access & VK_ACCESS_SHADER_WRITE_BIT)
access.set(DxvkAccess::Write); dstAccess.set(DxvkAccess::Write);
/* fall through */ /* fall through */
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
requiresBarrier = m_barriers.isBufferDirty( srcAccess = m_barriers.getBufferAccess(
slot.bufferSlice.getSliceHandle(), access); slot.bufferSlice.getSliceHandle());
break; break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
if (binding.access & VK_ACCESS_SHADER_WRITE_BIT) if (binding.access & VK_ACCESS_SHADER_WRITE_BIT)
access.set(DxvkAccess::Write); dstAccess.set(DxvkAccess::Write);
/* fall through */ /* fall through */
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
requiresBarrier = m_barriers.isBufferDirty( srcAccess = m_barriers.getBufferAccess(
slot.bufferView->getSliceHandle(), access); slot.bufferView->getSliceHandle());
break; break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
if (binding.access & VK_ACCESS_SHADER_WRITE_BIT) if (binding.access & VK_ACCESS_SHADER_WRITE_BIT)
access.set(DxvkAccess::Write); dstAccess.set(DxvkAccess::Write);
/* fall through */ /* fall through */
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
requiresBarrier = m_barriers.isImageDirty( srcAccess = m_barriers.getImageAccess(
slot.imageView->image(), slot.imageView->image(),
slot.imageView->subresources(), slot.imageView->subresources());
access);
break; break;
default: default:
/* nothing to do */; /* 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);
} }
} }