1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-18 02:52:10 +01:00

[dxvk] Fix hazard detection for shader resources

This commit is contained in:
Philip Rebohle 2021-09-09 14:58:04 +02:00
parent 67391a7bb0
commit c9f7ccc7f9
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 8 additions and 46 deletions

View File

@ -305,7 +305,7 @@ namespace dxvk {
} }
DxvkAccessFlags DxvkBarrierSet::getAccessTypes(VkAccessFlags flags) const { DxvkAccessFlags DxvkBarrierSet::getAccessTypes(VkAccessFlags flags) {
const VkAccessFlags rflags const VkAccessFlags rflags
= VK_ACCESS_INDIRECT_COMMAND_READ_BIT = VK_ACCESS_INDIRECT_COMMAND_READ_BIT
| VK_ACCESS_INDEX_READ_BIT | VK_ACCESS_INDEX_READ_BIT

View File

@ -84,6 +84,8 @@ namespace dxvk {
const Rc<DxvkCommandList>& commandList); const Rc<DxvkCommandList>& commandList);
void reset(); void reset();
static DxvkAccessFlags getAccessTypes(VkAccessFlags flags);
private: private:
@ -115,8 +117,6 @@ namespace dxvk {
void insertBufferSlice(BufSlice slice); void insertBufferSlice(BufSlice slice);
void insertImageSlice(ImgSlice slice); void insertImageSlice(ImgSlice slice);
DxvkAccessFlags getAccessTypes(VkAccessFlags flags) const;
}; };

View File

@ -4904,15 +4904,11 @@ 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 dstAccess = DxvkAccess::Read; DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(binding.access);
DxvkAccessFlags srcAccess = 0; DxvkAccessFlags srcAccess = 0;
switch (binding.type) { switch (binding.type) {
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
if (binding.access & VK_ACCESS_SHADER_WRITE_BIT)
dstAccess.set(DxvkAccess::Write);
/* 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:
srcAccess = m_execBarriers.getBufferAccess( srcAccess = m_execBarriers.getBufferAccess(
@ -4920,20 +4916,12 @@ namespace dxvk {
break; break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
if (binding.access & VK_ACCESS_SHADER_WRITE_BIT)
dstAccess.set(DxvkAccess::Write);
/* fall through */
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
srcAccess = m_execBarriers.getBufferAccess( srcAccess = m_execBarriers.getBufferAccess(
slot.bufferView->getSliceHandle()); 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)
dstAccess.set(DxvkAccess::Write);
/* fall through */
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
srcAccess = m_execBarriers.getImageAccess( srcAccess = m_execBarriers.getImageAccess(
@ -4951,8 +4939,7 @@ namespace dxvk {
// Skip write-after-write barriers if explicitly requested // Skip write-after-write barriers if explicitly requested
if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite)) if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite))
&& (m_execBarriers.getSrcStages() == VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT) && (m_execBarriers.getSrcStages() == VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT)
&& (srcAccess.test(DxvkAccess::Write)) && (srcAccess == DxvkAccess::Write) && (dstAccess == DxvkAccess::Write))
&& (dstAccess.test(DxvkAccess::Write)))
continue; continue;
requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write); requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write);
@ -4973,14 +4960,10 @@ namespace dxvk {
const DxvkShaderResourceSlot& slot = m_rc[binding.slot]; const DxvkShaderResourceSlot& slot = m_rc[binding.slot];
VkPipelineStageFlags stages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT; VkPipelineStageFlags stages = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
VkAccessFlags access = VK_ACCESS_SHADER_READ_BIT; VkAccessFlags access = binding.access;
switch (binding.type) { switch (binding.type) {
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
if (binding.access & VK_ACCESS_SHADER_WRITE_BIT)
access |= VK_ACCESS_SHADER_WRITE_BIT;
/* 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:
m_execBarriers.accessBuffer( m_execBarriers.accessBuffer(
@ -4991,10 +4974,6 @@ namespace dxvk {
break; break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
if (binding.access & VK_ACCESS_SHADER_WRITE_BIT)
access |= VK_ACCESS_SHADER_WRITE_BIT;
/* fall through */
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
m_execBarriers.accessBuffer( m_execBarriers.accessBuffer(
slot.bufferView->getSliceHandle(), slot.bufferView->getSliceHandle(),
@ -5004,10 +4983,6 @@ namespace dxvk {
break; break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
if (binding.access & VK_ACCESS_SHADER_WRITE_BIT)
access |= VK_ACCESS_SHADER_WRITE_BIT;
/* fall through */
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
m_execBarriers.accessImage( m_execBarriers.accessImage(
@ -5116,15 +5091,11 @@ 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 dstAccess = DxvkAccess::Read; DxvkAccessFlags dstAccess = DxvkBarrierSet::getAccessTypes(binding.access);
DxvkAccessFlags srcAccess = 0; DxvkAccessFlags srcAccess = 0;
switch (binding.type) { switch (binding.type) {
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
if (binding.access & VK_ACCESS_SHADER_WRITE_BIT)
dstAccess.set(DxvkAccess::Write);
/* 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:
if ((slot.bufferSlice.defined()) if ((slot.bufferSlice.defined())
@ -5135,10 +5106,6 @@ namespace dxvk {
break; break;
case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
if (binding.access & VK_ACCESS_SHADER_WRITE_BIT)
dstAccess.set(DxvkAccess::Write);
/* fall through */
case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
if ((slot.bufferView != nullptr) if ((slot.bufferView != nullptr)
&& (slot.bufferView->bufferInfo().access & storageBufferAccess)) { && (slot.bufferView->bufferInfo().access & storageBufferAccess)) {
@ -5148,10 +5115,6 @@ namespace dxvk {
break; break;
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
if (binding.access & VK_ACCESS_SHADER_WRITE_BIT)
dstAccess.set(DxvkAccess::Write);
/* fall through */
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
if ((slot.imageView != nullptr) if ((slot.imageView != nullptr)
@ -5170,8 +5133,7 @@ namespace dxvk {
// Skip write-after-write barriers if explicitly requested // Skip write-after-write barriers if explicitly requested
if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite)) if ((m_barrierControl.test(DxvkBarrierControl::IgnoreWriteAfterWrite))
&& (srcAccess.test(DxvkAccess::Write)) && (srcAccess == DxvkAccess::Write) && (dstAccess == DxvkAccess::Write))
&& (dstAccess.test(DxvkAccess::Write)))
continue; continue;
requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write); requiresBarrier = (srcAccess | dstAccess).test(DxvkAccess::Write);