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