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/GPU/Vulkan/DrawEngineVulkan.h
Views: 1401
1
// Copyright (c) 2015- PPSSPP Project.
2
3
// This program is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, version 2.0 or later versions.
6
7
// This program is distributed in the hope that it will be useful,
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
// GNU General Public License 2.0 for more details.
11
12
// A copy of the GPL 2.0 should have been included with the program.
13
// If not, see http://www.gnu.org/licenses/
14
15
// Official git repository and contact information can be found at
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17
18
#pragma once
19
20
// The Descriptor Set used for the majority of PSP rendering looks like this:
21
//
22
// * binding 0: Texture/Sampler (the PSP texture)
23
// * binding 1: Secondary texture sampler for shader blending
24
// * binding 2: Depal palette
25
// * binding 3: Base Uniform Buffer (includes fragment state)
26
// * binding 4: Light uniform buffer
27
// * binding 5: Bone uniform buffer
28
// * binding 6: Tess data storage buffer
29
//
30
// All shaders conform to this layout, so they are all compatible with the same descriptor set.
31
// The format of the various uniform buffers may vary though - vertex shaders that don't skin
32
// won't get any bone data, etc.
33
34
#include "Common/Data/Collections/Hashmaps.h"
35
36
#include "GPU/Vulkan/VulkanUtil.h"
37
38
#include "GPU/GPUState.h"
39
#include "GPU/Common/GPUDebugInterface.h"
40
#include "GPU/Common/IndexGenerator.h"
41
#include "GPU/Common/VertexDecoderCommon.h"
42
#include "GPU/Common/DrawEngineCommon.h"
43
#include "GPU/Common/GPUStateUtils.h"
44
#include "GPU/Vulkan/StateMappingVulkan.h"
45
#include "GPU/Vulkan/VulkanRenderManager.h"
46
47
48
// TODO: Move to some appropriate header.
49
#ifdef _MSC_VER
50
#define NO_INLINE __declspec(noinline)
51
#else
52
#define NO_INLINE __attribute__((noinline))
53
#endif
54
55
struct DecVtxFormat;
56
struct UVScale;
57
58
class ShaderManagerVulkan;
59
class PipelineManagerVulkan;
60
class TextureCacheVulkan;
61
class FramebufferManagerVulkan;
62
63
class VulkanContext;
64
class VulkanPushPool;
65
struct VulkanPipeline;
66
67
struct DrawEngineVulkanStats {
68
int pushVertexSpaceUsed;
69
int pushIndexSpaceUsed;
70
};
71
72
class VulkanRenderManager;
73
74
class TessellationDataTransferVulkan : public TessellationDataTransfer {
75
public:
76
TessellationDataTransferVulkan(VulkanContext *vulkan) : vulkan_(vulkan) {}
77
78
void SetPushPool(VulkanPushPool *push) { push_ = push; }
79
// Send spline/bezier's control points and weights to vertex shader through structured shader buffer.
80
void SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Spline::Weight2D &weights) override;
81
const VkDescriptorBufferInfo *GetBufferInfo() { return bufInfo_; }
82
private:
83
VulkanContext *vulkan_;
84
VulkanPushPool *push_; // Updated each frame.
85
VkDescriptorBufferInfo bufInfo_[3]{};
86
};
87
88
enum {
89
DRAW_BINDING_TEXTURE = 0,
90
DRAW_BINDING_2ND_TEXTURE = 1,
91
DRAW_BINDING_DEPAL_TEXTURE = 2,
92
DRAW_BINDING_DYNUBO_BASE = 3,
93
DRAW_BINDING_DYNUBO_LIGHT = 4,
94
DRAW_BINDING_DYNUBO_BONE = 5,
95
DRAW_BINDING_TESS_STORAGE_BUF = 6,
96
DRAW_BINDING_TESS_STORAGE_BUF_WU = 7,
97
DRAW_BINDING_TESS_STORAGE_BUF_WV = 8,
98
DRAW_BINDING_COUNT = 9,
99
};
100
101
// Handles transform, lighting and drawing.
102
class DrawEngineVulkan : public DrawEngineCommon {
103
public:
104
DrawEngineVulkan(Draw::DrawContext *draw);
105
~DrawEngineVulkan();
106
107
// We reference feature flags, so this is called after construction.
108
void InitDeviceObjects();
109
110
void SetShaderManager(ShaderManagerVulkan *shaderManager) {
111
shaderManager_ = shaderManager;
112
}
113
void SetPipelineManager(PipelineManagerVulkan *pipelineManager) {
114
pipelineManager_ = pipelineManager;
115
}
116
void SetTextureCache(TextureCacheVulkan *textureCache) {
117
textureCache_ = textureCache;
118
}
119
void SetFramebufferManager(FramebufferManagerVulkan *fbManager) {
120
framebufferManager_ = fbManager;
121
}
122
123
void DeviceLost() override;
124
void DeviceRestore(Draw::DrawContext *draw) override;
125
126
// So that this can be inlined
127
void Flush() {
128
if (!numDrawInds_)
129
return;
130
DoFlush();
131
}
132
133
void FinishDeferred() {
134
if (!numDrawInds_)
135
return;
136
// Decode any pending vertices. And also flush while we're at it, for simplicity.
137
// It might be possible to only decode like in the other backends, but meh, it can't matter.
138
// Issue #10095 has a nice example of where this is required.
139
DoFlush();
140
}
141
142
void DispatchFlush() override {
143
if (!numDrawInds_)
144
return;
145
DoFlush();
146
}
147
148
VKRPipelineLayout *GetPipelineLayout() const {
149
return pipelineLayout_;
150
}
151
152
void BeginFrame();
153
void EndFrame();
154
155
void DirtyAllUBOs();
156
157
void DirtyPipeline() {
158
lastPipeline_ = nullptr;
159
}
160
161
VulkanPushPool *GetPushBufferForTextureData() {
162
return pushUBO_;
163
}
164
165
const DrawEngineVulkanStats &GetStats() const {
166
return stats_;
167
}
168
169
void SetDepalTexture(VkImageView depal, bool smooth) {
170
if (boundDepal_ != depal) {
171
boundDepal_ = depal;
172
boundDepalSmoothed_ = smooth;
173
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
174
}
175
}
176
177
private:
178
void Invalidate(InvalidationCallbackFlags flags);
179
180
void ApplyDrawStateLate(VulkanRenderManager *renderManager, bool applyStencilRef, uint8_t stencilRef, bool useBlendConstant);
181
void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, ShaderManagerVulkan *shaderManager, int prim, VulkanPipelineRasterStateKey &key, VulkanDynamicState &dynState);
182
void BindShaderBlendTex();
183
184
void DestroyDeviceObjects();
185
186
void DoFlush();
187
void UpdateUBOs();
188
189
NO_INLINE void ResetAfterDraw();
190
191
Draw::DrawContext *draw_;
192
193
// We use a shared descriptor set layouts for all PSP draws.
194
VKRPipelineLayout *pipelineLayout_ = nullptr;
195
VulkanPipeline *lastPipeline_ = nullptr;
196
VkDescriptorSet lastDs_ = VK_NULL_HANDLE;
197
198
// Secondary texture for shader blending
199
VkImageView boundSecondary_ = VK_NULL_HANDLE;
200
201
// CLUT texture for shader depal
202
VkImageView boundDepal_ = VK_NULL_HANDLE;
203
bool boundDepalSmoothed_ = false;
204
VkSampler samplerSecondaryLinear_ = VK_NULL_HANDLE;
205
VkSampler samplerSecondaryNearest_ = VK_NULL_HANDLE;
206
207
struct DescriptorSetKey {
208
VkImageView imageView_;
209
VkImageView secondaryImageView_;
210
VkImageView depalImageView_;
211
VkSampler sampler_;
212
VkBuffer base_, light_, bone_; // All three UBO slots will be set to this. This will usually be identical
213
// for all draws in a frame, except when the buffer has to grow.
214
};
215
216
GEPrimitiveType lastPrim_ = GE_PRIM_INVALID;
217
218
// This one's not accurately named, it's used for all kinds of stuff that's not vertices or indices.
219
VulkanPushPool *pushUBO_ = nullptr;
220
221
VulkanPushPool *pushVertex_ = nullptr;
222
VulkanPushPool *pushIndex_ = nullptr;
223
224
// Other
225
ShaderManagerVulkan *shaderManager_ = nullptr;
226
PipelineManagerVulkan *pipelineManager_ = nullptr;
227
TextureCacheVulkan *textureCache_ = nullptr;
228
FramebufferManagerVulkan *framebufferManager_ = nullptr;
229
230
// State cache
231
uint64_t dirtyUniforms_ = 0;
232
uint32_t baseUBOOffset = 0;
233
uint32_t lightUBOOffset = 0;
234
uint32_t boneUBOOffset = 0;
235
VkBuffer baseBuf = VK_NULL_HANDLE;
236
VkBuffer lightBuf = VK_NULL_HANDLE;
237
VkBuffer boneBuf = VK_NULL_HANDLE;
238
VkImageView imageView = VK_NULL_HANDLE;
239
VkSampler sampler = VK_NULL_HANDLE;
240
241
// For null texture
242
VkSampler nullSampler_ = VK_NULL_HANDLE;
243
244
DrawEngineVulkanStats stats_{};
245
246
VulkanPipelineRasterStateKey pipelineKey_{};
247
VulkanDynamicState dynState_{};
248
249
int tessOffset_ = 0;
250
FBOTexState fboTexBindState_ = FBO_TEX_NONE;
251
252
// Hardware tessellation
253
TessellationDataTransferVulkan *tessDataTransferVulkan;
254
};
255
256