// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
#pragma once
#if GRAPHICS_API_VULKAN
#include "Engine/Graphics/GPUTimerQuery.h"
#include "GPUDeviceVulkan.h"
///
/// GPU timer query object for Vulkan backend.
///
class GPUTimerQueryVulkan : public GPUResourceVulkan
{
private:
struct Query
{
BufferedQueryPoolVulkan* Pool;
uint32 Index;
uint64 Result;
};
struct QueryPair
{
Query Begin;
Query End;
};
bool _hasResult = false;
bool _endCalled = false;
bool _interrupted = false;
float _timeDelta = 0.0f;
int32 _queryIndex;
Array> _queries;
public:
///
/// Initializes a new instance of the class.
///
/// The graphics device.
GPUTimerQueryVulkan(GPUDeviceVulkan* device);
public:
///
/// Interrupts an in-progress query, allowing the command buffer to submitted. Interrupted queries must be resumed using Resume().
///
/// The GPU commands buffer.
void Interrupt(CmdBufferVulkan* cmdBuffer);
///
/// Resumes an interrupted query, restoring it back to its original in-progress state.
///
/// The GPU commands buffer.
void Resume(CmdBufferVulkan* cmdBuffer);
private:
bool GetResult(Query& query);
void WriteTimestamp(CmdBufferVulkan* cmdBuffer, Query& query, VkPipelineStageFlagBits stage) const;
bool TryGetResult();
bool UseQueries();
public:
// [GPUTimerQuery]
void Begin() override;
void End() override;
bool HasResult() override;
float GetResult() override;
protected:
// [GPUResourceVulkan]
void OnReleaseGPU() override;
};
#endif