From a49615e192d75a5be73c71c065b44b61bfb75493 Mon Sep 17 00:00:00 2001 From: assiduous Date: Thu, 18 Feb 2021 16:07:52 -0800 Subject: Reworked FenceVkImpl to use atomics --- .../GraphicsEngineVulkan/include/FenceVkImpl.hpp | 6 +++++- Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp | 22 ++++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-) (limited to 'Graphics/GraphicsEngineVulkan') diff --git a/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.hpp index ab8da006..303fe6cf 100644 --- a/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.hpp @@ -31,6 +31,8 @@ /// Declaration of Diligent::FenceVkImpl class #include +#include + #include "FenceVk.h" #include "FenceBase.hpp" #include "VulkanUtilities/VulkanFencePool.hpp" @@ -76,9 +78,11 @@ public: void Wait(Uint64 Value); private: + inline void UpdateLastCompletedFenceValue(uint64_t NewValue); + VulkanUtilities::VulkanFencePool m_FencePool; std::deque> m_PendingFences; - volatile Uint64 m_LastCompletedFenceValue = 0; + std::atomic_uint64_t m_LastCompletedFenceValue{0}; }; } // namespace Diligent diff --git a/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp index 0d109b38..fa4c4536 100644 --- a/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp @@ -64,6 +64,15 @@ FenceVkImpl::~FenceVkImpl() } } +void FenceVkImpl::UpdateLastCompletedFenceValue(uint64_t NewValue) +{ + auto LastCompletedValue = m_LastCompletedFenceValue.load(); + while (!m_LastCompletedFenceValue.compare_exchange_strong(LastCompletedValue, std::max(LastCompletedValue, NewValue))) + { + // If exchange fails, LastCompletedValue will hold the actual value of m_LastCompletedFenceValue. + } +} + Uint64 FenceVkImpl::GetCompletedValue() { const auto& LogicalDevice = m_pDevice->GetLogicalDevice(); @@ -74,8 +83,7 @@ Uint64 FenceVkImpl::GetCompletedValue() auto status = LogicalDevice.GetFenceStatus(Value_Fence.second); if (status == VK_SUCCESS) { - if (Value_Fence.first > m_LastCompletedFenceValue) - m_LastCompletedFenceValue = Value_Fence.first; + UpdateLastCompletedFenceValue(Value_Fence.first); m_FencePool.DisposeFence(std::move(Value_Fence.second)); m_PendingFences.pop_front(); } @@ -85,14 +93,13 @@ Uint64 FenceVkImpl::GetCompletedValue() } } - return m_LastCompletedFenceValue; + return m_LastCompletedFenceValue.load(); } void FenceVkImpl::Reset(Uint64 Value) { - DEV_CHECK_ERR(Value >= m_LastCompletedFenceValue, "Resetting fence '", m_Desc.Name, "' to the value (", Value, ") that is smaller than the last completed value (", m_LastCompletedFenceValue, ")"); - if (Value > m_LastCompletedFenceValue) - m_LastCompletedFenceValue = Value; + DEV_CHECK_ERR(Value >= m_LastCompletedFenceValue.load(), "Resetting fence '", m_Desc.Name, "' to the value (", Value, ") that is smaller than the last completed value (", m_LastCompletedFenceValue, ")"); + UpdateLastCompletedFenceValue(Value); } @@ -115,8 +122,7 @@ void FenceVkImpl::Wait(Uint64 Value) DEV_CHECK_ERR(status == VK_SUCCESS, "All pending fences must now be complete!"); (void)status; - if (val_fence.first > m_LastCompletedFenceValue) - m_LastCompletedFenceValue = val_fence.first; + UpdateLastCompletedFenceValue(val_fence.first); m_FencePool.DisposeFence(std::move(val_fence.second)); m_PendingFences.pop_front(); -- cgit v1.2.3