// 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