From 99d9a5df0b6b52f92845529c6cd6cc6c9f92e14c Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Sat, 31 Mar 2018 16:41:19 +0200 Subject: [PATCH] [dxbc] Respect GloballyCoherent flag for UAVs --- src/dxbc/dxbc_compiler.cpp | 25 ++++++++++++++++++------- src/dxbc/dxbc_decoder.cpp | 2 ++ src/dxbc/dxbc_decoder.h | 3 +-- src/dxbc/dxbc_enums.h | 9 +++++++++ 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 9d557434e..9dc71f11c 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -861,6 +861,9 @@ namespace dxvk { m_module.decorateDescriptorSet(varId, 0); m_module.decorateBinding(varId, bindingId); + if (ins.controls.uavFlags.test(DxbcUavFlag::GloballyCoherent)) + m_module.decorate(varId, spv::DecorationCoherent); + // Declare a specialization constant which will // store whether or not the resource is bound. const uint32_t specConstId = m_module.specConstBool(true); @@ -979,6 +982,9 @@ namespace dxvk { m_module.decorateDescriptorSet(varId, 0); m_module.decorateBinding(varId, bindingId); + if (ins.controls.uavFlags.test(DxbcUavFlag::GloballyCoherent)) + m_module.decorate(varId, spv::DecorationCoherent); + // Declare a specialization constant which will // store whether or not the resource is bound. const uint32_t specConstId = m_module.specConstBool(true); @@ -1995,15 +2001,20 @@ namespace dxvk { } // Define memory scope and semantics based on the operands - uint32_t semantics = isUav - ? spv::MemorySemanticsUniformMemoryMask - : spv::MemorySemanticsWorkgroupMemoryMask; + uint32_t scope = 0; + uint32_t semantics = 0; - // TODO verify whether this is even remotely correct - semantics |= spv::MemorySemanticsAcquireReleaseMask; + if (isUav) { + scope = spv::ScopeDevice; + semantics = spv::MemorySemanticsImageMemoryMask + | spv::MemorySemanticsAcquireReleaseMask; + } else { + scope = spv::ScopeWorkgroup; + semantics = spv::MemorySemanticsWorkgroupMemoryMask + | spv::MemorySemanticsAcquireReleaseMask; + } - // TODO for UAVs, respect globally coherent flag - const uint32_t scopeId = m_module.constu32(spv::ScopeWorkgroup); + const uint32_t scopeId = m_module.constu32(scope); const uint32_t semanticsId = m_module.constu32(semantics); // Perform the atomic operation on the given pointer diff --git a/src/dxbc/dxbc_decoder.cpp b/src/dxbc/dxbc_decoder.cpp index fda43ac0f..918dce2c1 100644 --- a/src/dxbc/dxbc_decoder.cpp +++ b/src/dxbc/dxbc_decoder.cpp @@ -132,6 +132,8 @@ namespace dxvk { static_cast(bit::extract(token, 11, 13)); m_instruction.controls.tessPartitioning = static_cast(bit::extract(token, 11, 13)); + m_instruction.controls.uavFlags = + static_cast(bit::extract(token, 16, 16)); m_instruction.controls.controlPointCount = static_cast(bit::extract(token, 11, 16)); diff --git a/src/dxbc/dxbc_decoder.h b/src/dxbc/dxbc_decoder.h index 8bc4d9838..2c6a8ad9f 100644 --- a/src/dxbc/dxbc_decoder.h +++ b/src/dxbc/dxbc_decoder.h @@ -201,8 +201,6 @@ namespace dxvk { /** * \brief Instruction operand - * - * */ struct DxbcRegister { DxbcOperandType type; @@ -254,6 +252,7 @@ namespace dxvk { DxbcTessDomain tessDomain; DxbcTessOutputPrimitive tessOutputPrimitive; DxbcTessPartitioning tessPartitioning; + DxbcUavFlags uavFlags; uint32_t controlPointCount; }; diff --git a/src/dxbc/dxbc_enums.h b/src/dxbc/dxbc_enums.h index 5a2919b5b..a02523ffc 100644 --- a/src/dxbc/dxbc_enums.h +++ b/src/dxbc/dxbc_enums.h @@ -574,6 +574,15 @@ namespace dxvk { FractEven = 4, }; + /** + * \brief UAV definition flags + */ + enum class DxbcUavFlag : uint32_t { + GloballyCoherent = 0, + }; + + using DxbcUavFlags = Flags; + /** * \brief Tessellator output primitive */