#pragma once
#include <cstdint>
#include <mutex>
#include <condition_variable>
#include "Common/GPU/Vulkan/VulkanContext.h"
#include "Common/Data/Collections/Hashmaps.h"
enum {
MAX_TIMESTAMP_QUERIES = 128,
};
enum class VKRRunType {
SUBMIT,
PRESENT,
SYNC,
EXIT,
};
struct QueueProfileContext {
bool enabled = false;
bool timestampsEnabled = false;
VkQueryPool queryPool;
std::vector<std::string> timestampDescriptions;
std::string profileSummary;
double cpuStartTime;
double cpuEndTime;
double descWriteTime;
int descriptorsWritten;
int descriptorsDeduped;
#ifdef _DEBUG
int commandCounts[11];
#endif
};
class VKRFramebuffer;
struct ReadbackKey {
const VKRFramebuffer *framebuf;
int width;
int height;
};
struct CachedReadback {
VkBuffer buffer;
VmaAllocation allocation;
VkDeviceSize bufferSize;
bool isCoherent;
void Destroy(VulkanContext *vulkan);
};
struct SwapchainImageData {
VkImage image;
VkImageView view;
VkSemaphore renderingCompleteSemaphore = VK_NULL_HANDLE;
};
struct FrameDataShared {
VkFence readbackFence = VK_NULL_HANDLE;
bool useMultiThreading = false;
bool measurePresentTime = false;
std::vector<SwapchainImageData> swapchainImages_;
uint32_t swapchainImageCount_ = 0;
void Init(VulkanContext *vulkan, bool useMultiThreading, bool measurePresentTime);
void Destroy(VulkanContext *vulkan);
};
enum class FrameSubmitType {
Pending,
Sync,
FinishFrame,
};
struct FrameData {
bool skipSwap = false;
std::mutex fenceMutex;
std::condition_variable fenceCondVar;
bool readyForFence = true;
VkFence fence = VK_NULL_HANDLE;
VkSemaphore acquireSemaphore = VK_NULL_HANDLE;
VkCommandPool cmdPoolInit = VK_NULL_HANDLE;
VkCommandPool cmdPoolMain = VK_NULL_HANDLE;
VkCommandBuffer initCmd = VK_NULL_HANDLE;
VkCommandBuffer mainCmd = VK_NULL_HANDLE;
VkCommandBuffer presentCmd = VK_NULL_HANDLE;
bool hasInitCommands = false;
bool hasMainCommands = false;
bool hasPresentCommands = false;
bool hasFencePending = false;
bool hasAcquired = false;
bool syncDone = false;
uint32_t curSwapchainImage = -1;
uint64_t frameId = 0;
QueueProfileContext profile{};
DenseHashMap<ReadbackKey, CachedReadback *> readbacks_;
FrameData() : readbacks_(8) {}
void Init(VulkanContext *vulkan, int index);
void Destroy(VulkanContext *vulkan);
void AcquireNextImage(VulkanContext *vulkan);
VkResult QueuePresent(VulkanContext *vulkan, FrameDataShared &shared);
VkCommandBuffer GetInitCmd(VulkanContext *vulkan);
void Submit(VulkanContext *vulkan, FrameSubmitType type, FrameDataShared &shared);
private:
int index = -1;
};