Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/Common/GPU/Vulkan/VulkanFrameData.h
5663 views
1
#pragma once
2
3
#include <cstdint>
4
5
#include <mutex>
6
#include <condition_variable>
7
8
#include "Common/GPU/Vulkan/VulkanContext.h"
9
#include "Common/Data/Collections/Hashmaps.h"
10
11
#if PPSSPP_PLATFORM(IOS)
12
// iOS doesn't support a large number of timestamp queries natively.
13
// We don't want MoltenVK to fall back to emulation.
14
enum {
15
MAX_TIMESTAMP_QUERIES = 32,
16
};
17
#else
18
enum {
19
MAX_TIMESTAMP_QUERIES = 128,
20
};
21
#endif
22
23
enum class VKRRunType {
24
SUBMIT,
25
PRESENT,
26
SYNC,
27
EXIT,
28
};
29
30
struct QueueProfileContext {
31
bool enabled = false;
32
bool timestampsEnabled = false;
33
VkQueryPool queryPool;
34
std::vector<std::string> timestampDescriptions;
35
std::string profileSummary;
36
double cpuStartTime;
37
double cpuEndTime;
38
double descWriteTime;
39
int descriptorsWritten;
40
int descriptorsDeduped;
41
#ifdef _DEBUG
42
int commandCounts[11];
43
#endif
44
};
45
46
class VKRFramebuffer;
47
48
struct ReadbackKey {
49
const VKRFramebuffer *framebuf;
50
int width;
51
int height;
52
};
53
54
struct CachedReadback {
55
VkBuffer buffer;
56
VmaAllocation allocation;
57
VkDeviceSize bufferSize;
58
bool isCoherent;
59
60
void Destroy(VulkanContext *vulkan);
61
};
62
63
// Swap chain management
64
struct SwapchainImageData {
65
VkImage image;
66
VkImageView view;
67
VkSemaphore renderingCompleteSemaphore = VK_NULL_HANDLE;
68
};
69
70
struct FrameDataShared {
71
// For synchronous readbacks.
72
VkFence readbackFence = VK_NULL_HANDLE;
73
bool useMultiThreading = false;
74
bool measurePresentTime = false;
75
76
std::vector<SwapchainImageData> swapchainImages_;
77
uint32_t swapchainImageCount_ = 0;
78
79
void Init(VulkanContext *vulkan, bool useMultiThreading, bool measurePresentTime);
80
void Destroy(VulkanContext *vulkan);
81
};
82
83
enum class FrameSubmitType {
84
Pending,
85
Sync,
86
FinishFrame,
87
};
88
89
// Per-frame data, round-robin so we can overlap submission with execution of the previous frame.
90
struct FrameData {
91
bool skipSwap = false;
92
93
std::mutex fenceMutex;
94
std::condition_variable fenceCondVar;
95
bool readyForFence = true;
96
97
VkFence fence = VK_NULL_HANDLE;
98
VkSemaphore acquireSemaphore = VK_NULL_HANDLE;
99
100
// These are on different threads so need separate pools.
101
VkCommandPool cmdPoolInit = VK_NULL_HANDLE; // Written to from main thread
102
VkCommandPool cmdPoolMain = VK_NULL_HANDLE; // Written to from render thread, which also submits
103
104
VkCommandBuffer initCmd = VK_NULL_HANDLE;
105
VkCommandBuffer mainCmd = VK_NULL_HANDLE;
106
VkCommandBuffer presentCmd = VK_NULL_HANDLE;
107
108
bool hasInitCommands = false;
109
bool hasMainCommands = false;
110
bool hasPresentCommands = false;
111
112
bool hasFencePending = false;
113
bool hasAcquired = false;
114
115
bool syncDone = false;
116
117
// Swapchain.
118
uint32_t curSwapchainImage = -1;
119
120
// Frames need unique IDs to wait for present on, let's keep them here.
121
// Also used for indexing into the frame timing history buffer.
122
uint64_t frameId = 0;
123
124
// Profiling.
125
QueueProfileContext profile{};
126
127
// Async readback cache.
128
DenseHashMap<ReadbackKey, CachedReadback *> readbacks_;
129
130
FrameData() : readbacks_(8) {}
131
132
void Init(VulkanContext *vulkan, int index);
133
void Destroy(VulkanContext *vulkan);
134
135
void AcquireNextImage(VulkanContext *vulkan);
136
VkResult QueuePresent(VulkanContext *vulkan, FrameDataShared &shared);
137
138
// Generally called from the main thread, unlike most of the rest.
139
VkCommandBuffer GetInitCmd(VulkanContext *vulkan);
140
141
// Submits pending command buffers.
142
void Submit(VulkanContext *vulkan, FrameSubmitType type, FrameDataShared &shared);
143
144
private:
145
// Metadata for logging etc
146
int index = -1;
147
};
148
149