Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/GPU/Vulkan/DrawEngineVulkan.h
3187 views
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/CommonTypes.h"
35
#include "Common/Data/Collections/Hashmaps.h"
36
37
#include "GPU/Vulkan/VulkanUtil.h"
38
39
#include "GPU/GPUState.h"
40
#include "GPU/Common/GPUDebugInterface.h"
41
#include "GPU/Common/IndexGenerator.h"
42
#include "GPU/Common/VertexDecoderCommon.h"
43
#include "GPU/Common/DrawEngineCommon.h"
44
#include "GPU/Common/GPUStateUtils.h"
45
#include "GPU/Vulkan/StateMappingVulkan.h"
46
#include "GPU/Vulkan/VulkanRenderManager.h"
47
48
struct DecVtxFormat;
49
struct UVScale;
50
51
class ShaderManagerVulkan;
52
class PipelineManagerVulkan;
53
class TextureCacheVulkan;
54
class FramebufferManagerVulkan;
55
56
class VulkanContext;
57
class VulkanPushPool;
58
struct VulkanPipeline;
59
60
struct DrawEngineVulkanStats {
61
int pushVertexSpaceUsed;
62
int pushIndexSpaceUsed;
63
};
64
65
class VulkanRenderManager;
66
67
class TessellationDataTransferVulkan : public TessellationDataTransfer {
68
public:
69
TessellationDataTransferVulkan(VulkanContext *vulkan) : vulkan_(vulkan) {}
70
71
void SetPushPool(VulkanPushPool *push) { push_ = push; }
72
// Send spline/bezier's control points and weights to vertex shader through structured shader buffer.
73
void SendDataToShader(const SimpleVertex *const *points, int size_u, int size_v, u32 vertType, const Spline::Weight2D &weights) override;
74
const VkDescriptorBufferInfo *GetBufferInfo() { return bufInfo_; }
75
private:
76
VulkanContext *vulkan_;
77
VulkanPushPool *push_; // Updated each frame.
78
VkDescriptorBufferInfo bufInfo_[3]{};
79
};
80
81
enum {
82
DRAW_BINDING_TEXTURE = 0,
83
DRAW_BINDING_2ND_TEXTURE = 1,
84
DRAW_BINDING_DEPAL_TEXTURE = 2,
85
DRAW_BINDING_DYNUBO_BASE = 3,
86
DRAW_BINDING_DYNUBO_LIGHT = 4,
87
DRAW_BINDING_DYNUBO_BONE = 5,
88
DRAW_BINDING_TESS_STORAGE_BUF = 6,
89
DRAW_BINDING_TESS_STORAGE_BUF_WU = 7,
90
DRAW_BINDING_TESS_STORAGE_BUF_WV = 8,
91
DRAW_BINDING_COUNT = 9,
92
};
93
94
// Handles transform, lighting and drawing.
95
class DrawEngineVulkan : public DrawEngineCommon {
96
public:
97
DrawEngineVulkan(Draw::DrawContext *draw);
98
~DrawEngineVulkan();
99
100
// We reference feature flags, so this is called after construction.
101
void InitDeviceObjects();
102
103
void SetShaderManager(ShaderManagerVulkan *shaderManager) {
104
shaderManager_ = shaderManager;
105
}
106
void SetPipelineManager(PipelineManagerVulkan *pipelineManager) {
107
pipelineManager_ = pipelineManager;
108
}
109
void SetTextureCache(TextureCacheVulkan *textureCache) {
110
textureCache_ = textureCache;
111
}
112
void SetFramebufferManager(FramebufferManagerVulkan *fbManager) {
113
framebufferManager_ = fbManager;
114
}
115
116
void DeviceLost() override;
117
void DeviceRestore(Draw::DrawContext *draw) override;
118
119
void Flush() override;
120
121
void FinishDeferred() {
122
// Decode any pending vertices. And also flush while we're at it, for simplicity.
123
// It might be possible to only decode like in the other backends, but meh, it can't matter.
124
// Issue #10095 has a nice example of where this is required.
125
Flush();
126
}
127
128
VKRPipelineLayout *GetPipelineLayout() const {
129
return pipelineLayout_;
130
}
131
132
void BeginFrame() override;
133
void EndFrame();
134
135
void DirtyAllUBOs();
136
137
void DirtyPipeline() {
138
lastPipeline_ = nullptr;
139
}
140
141
VulkanPushPool *GetPushBufferForTextureData() {
142
return pushUBO_;
143
}
144
145
const DrawEngineVulkanStats &GetStats() const {
146
return stats_;
147
}
148
149
void SetDepalTexture(VkImageView depal, bool smooth) {
150
if (boundDepal_ != depal) {
151
boundDepal_ = depal;
152
boundDepalSmoothed_ = smooth;
153
gstate_c.Dirty(DIRTY_FRAGMENTSHADER_STATE);
154
}
155
}
156
157
private:
158
void Invalidate(InvalidationCallbackFlags flags);
159
160
void ApplyDrawStateLate(VulkanRenderManager *renderManager, bool applyStencilRef, uint8_t stencilRef, bool useBlendConstant);
161
void ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManager, ShaderManagerVulkan *shaderManager, int prim, VulkanPipelineRasterStateKey &key, VulkanDynamicState &dynState);
162
void BindShaderBlendTex();
163
164
void DestroyDeviceObjects();
165
166
void UpdateUBOs();
167
168
NO_INLINE void ResetAfterDraw();
169
170
Draw::DrawContext *draw_;
171
172
// We use a shared descriptor set layouts for all PSP draws.
173
VKRPipelineLayout *pipelineLayout_ = nullptr;
174
VulkanPipeline *lastPipeline_ = nullptr;
175
VkDescriptorSet lastDs_ = VK_NULL_HANDLE;
176
177
// Secondary texture for shader blending
178
VkImageView boundSecondary_ = VK_NULL_HANDLE;
179
180
// CLUT texture for shader depal
181
VkImageView boundDepal_ = VK_NULL_HANDLE;
182
bool boundDepalSmoothed_ = false;
183
VkSampler samplerSecondaryLinear_ = VK_NULL_HANDLE;
184
VkSampler samplerSecondaryNearest_ = VK_NULL_HANDLE;
185
186
struct DescriptorSetKey {
187
VkImageView imageView_;
188
VkImageView secondaryImageView_;
189
VkImageView depalImageView_;
190
VkSampler sampler_;
191
VkBuffer base_, light_, bone_; // All three UBO slots will be set to this. This will usually be identical
192
// for all draws in a frame, except when the buffer has to grow.
193
};
194
195
GEPrimitiveType lastPrim_ = GE_PRIM_INVALID;
196
197
// This one's not accurately named, it's used for all kinds of stuff that's not vertices or indices.
198
VulkanPushPool *pushUBO_ = nullptr;
199
200
VulkanPushPool *pushVertex_ = nullptr;
201
VulkanPushPool *pushIndex_ = nullptr;
202
203
// Other
204
ShaderManagerVulkan *shaderManager_ = nullptr;
205
PipelineManagerVulkan *pipelineManager_ = nullptr;
206
TextureCacheVulkan *textureCache_ = nullptr;
207
FramebufferManagerVulkan *framebufferManager_ = nullptr;
208
209
// State cache
210
uint64_t dirtyUniforms_ = 0;
211
uint32_t baseUBOOffset = 0;
212
uint32_t lightUBOOffset = 0;
213
uint32_t boneUBOOffset = 0;
214
VkBuffer baseBuf = VK_NULL_HANDLE;
215
VkBuffer lightBuf = VK_NULL_HANDLE;
216
VkBuffer boneBuf = VK_NULL_HANDLE;
217
VkImageView imageView = VK_NULL_HANDLE;
218
VkSampler sampler = VK_NULL_HANDLE;
219
220
// For null texture
221
VkSampler nullSampler_ = VK_NULL_HANDLE;
222
223
DrawEngineVulkanStats stats_{};
224
225
VulkanPipelineRasterStateKey pipelineKey_{};
226
VulkanDynamicState dynState_{};
227
228
int tessOffset_ = 0;
229
FBOTexState fboTexBindState_ = FBO_TEX_NONE;
230
231
// Hardware tessellation
232
TessellationDataTransferVulkan *tessDataTransferVulkan = nullptr;
233
};
234
235