CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Common/GPU/Vulkan/VulkanFramebuffer.h
Views: 1401
1
#pragma once
2
3
#include "Common/Common.h"
4
#include "Common/GPU/Vulkan/VulkanContext.h"
5
6
class VKRRenderPass;
7
class VulkanBarrierBatch;
8
9
// Pipelines need to be created for the right type of render pass.
10
// TODO: Rename to RenderPassFlags?
11
// When you add more flags, don't forget to update rpTypeDebugNames[].
12
enum class RenderPassType {
13
DEFAULT = 0,
14
// These eight are organized so that bit 0 is DEPTH and bit 1 is INPUT and bit 2 is MULTIVIEW, so
15
// they can be OR-ed together in MergeRPTypes.
16
HAS_DEPTH = 1,
17
MULTIVIEW = 2,
18
MULTISAMPLE = 4,
19
20
// This is the odd one out, and gets special handling in MergeRPTypes.
21
// If this flag is set, none of the other flags can be set.
22
// For the backbuffer we can always use CLEAR/DONT_CARE, so bandwidth cost for a depth channel is negligible
23
// so we don't bother with a non-depth version.
24
BACKBUFFER = 8,
25
26
TYPE_COUNT = BACKBUFFER + 1,
27
};
28
ENUM_CLASS_BITOPS(RenderPassType);
29
30
// Simple independent framebuffer image.
31
struct VKRImage {
32
// These four are "immutable".
33
VkImage image;
34
35
VkImageView rtView; // Used for rendering to, and readbacks of stencil. 2D if single layer, 2D_ARRAY if multiple. Includes both depth and stencil if depth/stencil.
36
37
// This is for texturing all layers at once. If aspect is depth/stencil, does not include stencil.
38
VkImageView texAllLayersView;
39
40
// If it's a layered image (for stereo), this is two 2D views of it, to make it compatible with shaders that don't yet support stereo.
41
// If there's only one layer, layerViews[0] only is initialized.
42
VkImageView texLayerViews[2]{};
43
44
VmaAllocation alloc;
45
VkFormat format;
46
VkSampleCountFlagBits sampleCount;
47
48
// This one is used by QueueRunner's Perform functions to keep track. CANNOT be used anywhere else due to sync issues.
49
VkImageLayout layout;
50
51
int numLayers;
52
53
// For debugging.
54
std::string tag;
55
56
void Delete(VulkanContext *vulkan);
57
};
58
59
class VKRFramebuffer {
60
public:
61
VKRFramebuffer(VulkanContext *vk, VulkanBarrierBatch *barriers, VkCommandBuffer initCmd, VKRRenderPass *compatibleRenderPass, int _width, int _height, int _numLayers, int _multiSampleLevel, bool createDepthStencilBuffer, const char *tag);
62
~VKRFramebuffer();
63
64
VkFramebuffer Get(VKRRenderPass *compatibleRenderPass, RenderPassType rpType);
65
66
int width = 0;
67
int height = 0;
68
int numLayers = 0;
69
VkSampleCountFlagBits sampleCount;
70
71
VKRImage color{}; // color.image is always there.
72
VKRImage depth{}; // depth.image is allowed to be VK_NULL_HANDLE.
73
74
// These are only initialized and used if numSamples > 1.
75
VKRImage msaaColor{};
76
VKRImage msaaDepth{};
77
78
const char *Tag() const {
79
return tag_.c_str();
80
}
81
82
void UpdateTag(const char *newTag);
83
84
bool HasDepth() const {
85
return depth.image != VK_NULL_HANDLE;
86
}
87
88
VkImageView GetRTView() {
89
if (sampleCount == VK_SAMPLE_COUNT_1_BIT) {
90
return color.rtView;
91
} else {
92
return msaaColor.rtView;
93
}
94
}
95
96
VulkanContext *Vulkan() const { return vulkan_; }
97
private:
98
static void CreateImage(VulkanContext *vulkan, VulkanBarrierBatch *barriers, VkCommandBuffer cmd, VKRImage &img, int width, int height, int numLayers, VkSampleCountFlagBits sampleCount, VkFormat format, VkImageLayout initialLayout, bool color, const char *tag);
99
100
VkFramebuffer framebuf[(size_t)RenderPassType::TYPE_COUNT]{};
101
102
VulkanContext *vulkan_;
103
std::string tag_;
104
};
105
106
inline bool RenderPassTypeHasDepth(RenderPassType type) {
107
return (type & RenderPassType::HAS_DEPTH) || type == RenderPassType::BACKBUFFER;
108
}
109
110
inline bool RenderPassTypeHasMultiView(RenderPassType type) {
111
return (type & RenderPassType::MULTIVIEW) != 0;
112
}
113
114
inline bool RenderPassTypeHasMultisample(RenderPassType type) {
115
return (type & RenderPassType::MULTISAMPLE) != 0;
116
}
117
118
VkSampleCountFlagBits MultiSampleLevelToFlagBits(int count);
119
120
// Must be the same order as Draw::RPAction
121
enum class VKRRenderPassLoadAction : uint8_t {
122
KEEP, // default. avoid when possible.
123
CLEAR,
124
DONT_CARE,
125
};
126
127
enum class VKRRenderPassStoreAction : uint8_t {
128
STORE, // default. avoid when possible.
129
DONT_CARE,
130
};
131
132
struct RPKey {
133
// Only render-pass-compatibility-volatile things can be here.
134
VKRRenderPassLoadAction colorLoadAction;
135
VKRRenderPassLoadAction depthLoadAction;
136
VKRRenderPassLoadAction stencilLoadAction;
137
VKRRenderPassStoreAction colorStoreAction;
138
VKRRenderPassStoreAction depthStoreAction;
139
VKRRenderPassStoreAction stencilStoreAction;
140
};
141
142
class VKRRenderPass {
143
public:
144
VKRRenderPass(const RPKey &key) : key_(key) {}
145
146
VkRenderPass Get(VulkanContext *vulkan, RenderPassType rpType, VkSampleCountFlagBits sampleCount);
147
void Destroy(VulkanContext *vulkan) {
148
for (size_t i = 0; i < (size_t)RenderPassType::TYPE_COUNT; i++) {
149
if (pass[i]) {
150
vulkan->Delete().QueueDeleteRenderPass(pass[i]);
151
}
152
}
153
}
154
155
private:
156
// TODO: Might be better off with a hashmap once the render pass type count grows really large..
157
VkRenderPass pass[(size_t)RenderPassType::TYPE_COUNT]{};
158
VkSampleCountFlagBits sampleCounts[(size_t)RenderPassType::TYPE_COUNT]{};
159
RPKey key_;
160
};
161
162
const char *GetRPTypeName(RenderPassType rpType);
163
164