diff --git a/Source/Engine/GraphicsDevice/Vulkan/Config.h b/Source/Engine/GraphicsDevice/Vulkan/Config.h index 16a19030e..e3cf01dba 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/Config.h +++ b/Source/Engine/GraphicsDevice/Vulkan/Config.h @@ -28,7 +28,7 @@ #define VULKAN_RESOURCE_DELETE_SAFE_FRAMES_COUNT 20 #define VULKAN_ENABLE_API_DUMP 0 -#define VULKAN_RESET_QUERY_POOLS 0 +#define VULKAN_RESET_QUERY_POOLS 1 #define VULKAN_HASH_POOLS_WITH_LAYOUT_TYPES 1 #define VULKAN_USE_DEBUG_LAYER GPU_ENABLE_DIAGNOSTICS #define VULKAN_USE_DEBUG_DATA (GPU_ENABLE_DIAGNOSTICS && COMPILE_WITH_DEV_ENV) diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp index febeb22a1..9b6d4ba2c 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp @@ -594,8 +594,6 @@ RenderPassVulkan::~RenderPassVulkan() QueryPoolVulkan::QueryPoolVulkan(GPUDeviceVulkan* device, int32 capacity, VkQueryType type) : _device(device) , _handle(VK_NULL_HANDLE) - , _count(0) - , _capacity(capacity) , _type(type) { VkQueryPoolCreateInfo createInfo; @@ -603,9 +601,11 @@ QueryPoolVulkan::QueryPoolVulkan(GPUDeviceVulkan* device, int32 capacity, VkQuer createInfo.queryType = type; createInfo.queryCount = capacity; VALIDATE_VULKAN_RESULT(vkCreateQueryPool(device->Device, &createInfo, nullptr, &_handle)); + #if VULKAN_RESET_QUERY_POOLS + // New queries have to be reset before use + ResetBeforeUse = true; _resetRanges.Add(Range{ 0, static_cast(capacity) }); - device->QueriesToReset.Add(this); #endif } @@ -626,6 +626,7 @@ void QueryPoolVulkan::Reset(CmdBufferVulkan* cmdBuffer) vkCmdResetQueryPool(cmdBuffer->GetHandle(), _handle, range.Start, range.Count); } _resetRanges.Clear(); + ResetBeforeUse = false; } #endif @@ -640,9 +641,9 @@ BufferedQueryPoolVulkan::BufferedQueryPoolVulkan(GPUDeviceVulkan* device, int32 _readResultsBits.AddZeroed((capacity + 63) / 64); } -bool BufferedQueryPoolVulkan::AcquireQuery(uint32& resultIndex) +bool BufferedQueryPoolVulkan::AcquireQuery(CmdBufferVulkan* cmdBuffer, uint32& resultIndex) { - const uint64 allUsedMask = (uint64)-1; + const uint64 allUsedMask = MAX_uint64; for (int32 wordIndex = _lastBeginIndex / 64; wordIndex < _usedQueryBits.Count(); wordIndex++) { uint64 beginQueryWord = _usedQueryBits[wordIndex]; @@ -659,10 +660,11 @@ bool BufferedQueryPoolVulkan::AcquireQuery(uint32& resultIndex) _usedQueryBits[wordIndex] = _usedQueryBits[wordIndex] | bit; _readResultsBits[wordIndex] &= ~bit; _lastBeginIndex = resultIndex + 1; + if (ResetBeforeUse) + Reset(cmdBuffer); return true; } } - return false; } @@ -675,7 +677,7 @@ void BufferedQueryPoolVulkan::ReleaseQuery(uint32 queryIndex) if (queryIndex < (uint32)_lastBeginIndex) { // Use the lowest word available - const uint64 allUsedMask = (uint64)-1; + const uint64 allUsedMask = MAX_uint64; const int32 lastQueryWord = _lastBeginIndex / 64; if (lastQueryWord < _usedQueryBits.Count() && _usedQueryBits[lastQueryWord] == allUsedMask) { @@ -736,7 +738,7 @@ bool BufferedQueryPoolVulkan::GetResults(GPUContextVulkan* context, uint32 index bool BufferedQueryPoolVulkan::HasRoom() const { - const uint64 allUsedMask = (uint64)-1; + const uint64 allUsedMask = MAX_uint64; if (_lastBeginIndex < _usedQueryBits.Count() * 64) { ASSERT((_usedQueryBits[_lastBeginIndex / 64] & allUsedMask) != allUsedMask); diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h index 054c677a0..d31149d20 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h @@ -259,8 +259,6 @@ protected: GPUDeviceVulkan* _device; VkQueryPool _handle; - volatile int32 _count; - const uint32 _capacity; const VkQueryType _type; #if VULKAN_RESET_QUERY_POOLS Array _resetRanges; @@ -277,6 +275,7 @@ public: } #if VULKAN_RESET_QUERY_POOLS + bool ResetBeforeUse; void Reset(CmdBufferVulkan* cmdBuffer); #endif }; @@ -294,7 +293,7 @@ private: public: BufferedQueryPoolVulkan(GPUDeviceVulkan* device, int32 capacity, VkQueryType type); - bool AcquireQuery(uint32& resultIndex); + bool AcquireQuery(CmdBufferVulkan* cmdBuffer, uint32& resultIndex); void ReleaseQuery(uint32 queryIndex); void MarkQueryAsStarted(uint32 queryIndex); bool GetResults(GPUContextVulkan* context, uint32 index, uint64& result); diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUTimerQueryVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUTimerQueryVulkan.cpp index 72107e84a..aee221183 100644 --- a/Source/Engine/GraphicsDevice/Vulkan/GPUTimerQueryVulkan.cpp +++ b/Source/Engine/GraphicsDevice/Vulkan/GPUTimerQueryVulkan.cpp @@ -60,13 +60,18 @@ void GPUTimerQueryVulkan::WriteTimestamp(CmdBufferVulkan* cmdBuffer, Query& quer { auto pool = _device->FindAvailableTimestampQueryPool(); uint32 index; - pool->AcquireQuery(index); - - vkCmdWriteTimestamp(cmdBuffer->GetHandle(), stage, pool->GetHandle(), index); - pool->MarkQueryAsStarted(index); - - query.Pool = pool; - query.Index = index; + if (pool->AcquireQuery(cmdBuffer, index)) + { + vkCmdWriteTimestamp(cmdBuffer->GetHandle(), stage, pool->GetHandle(), index); + pool->MarkQueryAsStarted(index); + query.Pool = pool; + query.Index = index; + } + else + { + query.Pool = nullptr; + query.Index = 0; + } } bool GPUTimerQueryVulkan::TryGetResult() @@ -104,16 +109,10 @@ bool GPUTimerQueryVulkan::TryGetResult() for (int32 i = 0; i < _queries.Count(); i++) { auto& e = _queries[i]; - if (e.Begin.Pool) - { e.Begin.Pool->ReleaseQuery(e.Begin.Index); - } - if (e.End.Pool) - { e.End.Pool->ReleaseQuery(e.End.Index); - } } _queries.Clear(); #else @@ -141,16 +140,10 @@ void GPUTimerQueryVulkan::OnReleaseGPU() for (int32 i = 0; i < _queries.Count(); i++) { auto& e = _queries[i]; - if (e.Begin.Pool) - { e.Begin.Pool->ReleaseQuery(e.Begin.Index); - } - if (e.End.Pool) - { e.End.Pool->ReleaseQuery(e.End.Index); - } } _queries.Clear(); } @@ -208,7 +201,6 @@ bool GPUTimerQueryVulkan::HasResult() return false; if (_hasResult) return true; - return TryGetResult(); } @@ -216,7 +208,6 @@ float GPUTimerQueryVulkan::GetResult() { if (_hasResult) return _timeDelta; - TryGetResult(); return _timeDelta; }