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/OpenGL/GLQueueRunner.h
Views: 1401
1
#pragma once
2
3
#include <cstdint>
4
#include <vector>
5
#include <set>
6
#include <unordered_map>
7
8
#include "Common/GPU/OpenGL/GLCommon.h"
9
#include "Common/GPU/OpenGL/GLFrameData.h"
10
#include "Common/GPU/DataFormat.h"
11
#include "Common/GPU/Shader.h"
12
#include "Common/GPU/thin3d.h"
13
#include "Common/Data/Collections/TinySet.h"
14
#include "Common/Data/Collections/FastVec.h"
15
16
struct GLRViewport {
17
float x, y, w, h, minZ, maxZ;
18
};
19
20
struct GLRect2D {
21
int x, y, w, h;
22
};
23
24
struct GLOffset2D {
25
int x, y;
26
};
27
28
enum class GLRAllocType : uint8_t {
29
NONE,
30
NEW,
31
ALIGNED,
32
};
33
34
class GLRShader;
35
class GLRTexture;
36
class GLRBuffer;
37
class GLRFramebuffer;
38
class GLRProgram;
39
class GLRInputLayout;
40
41
enum class GLRRenderCommand : uint8_t {
42
DEPTH,
43
STENCIL,
44
BLEND,
45
BLENDCOLOR,
46
LOGICOP,
47
UNIFORM4I,
48
UNIFORM4UI,
49
UNIFORM4F,
50
UNIFORMMATRIX,
51
UNIFORMSTEREOMATRIX,
52
TEXTURESAMPLER,
53
TEXTURELOD,
54
VIEWPORT,
55
SCISSOR,
56
RASTER,
57
CLEAR,
58
INVALIDATE,
59
BINDPROGRAM,
60
BINDTEXTURE,
61
BIND_FB_TEXTURE,
62
BIND_VERTEX_BUFFER,
63
GENMIPS,
64
DRAW,
65
TEXTURE_SUBIMAGE,
66
};
67
68
// TODO: Bloated since the biggest struct decides the size. Will need something more efficient (separate structs with shared
69
// type field, smashed right after each other?)
70
// Also, all GLenums are really only 16 bits.
71
struct GLRRenderData {
72
GLRRenderData(GLRRenderCommand _cmd) : cmd(_cmd) {}
73
GLRRenderCommand cmd;
74
union {
75
struct {
76
GLboolean enabled;
77
GLenum srcColor;
78
GLenum dstColor;
79
GLenum srcAlpha;
80
GLenum dstAlpha;
81
GLenum funcColor;
82
GLenum funcAlpha;
83
int mask;
84
} blend;
85
struct {
86
float color[4];
87
} blendColor;
88
struct {
89
GLboolean enabled;
90
GLenum logicOp;
91
} logic;
92
struct {
93
GLboolean enabled;
94
GLboolean write;
95
GLenum func;
96
} depth;
97
struct {
98
GLenum func;
99
GLenum sFail;
100
GLenum zFail;
101
GLenum pass;
102
GLboolean enabled;
103
uint8_t ref;
104
uint8_t compareMask;
105
uint8_t writeMask;
106
} stencil;
107
struct {
108
GLRInputLayout *inputLayout;
109
GLRBuffer *vertexBuffer;
110
GLRBuffer *indexBuffer;
111
uint32_t vertexOffset;
112
uint32_t indexOffset;
113
GLenum mode; // primitive
114
GLint first;
115
GLint count;
116
GLint indexType;
117
GLint instances;
118
} draw;
119
struct {
120
const char *name; // if null, use loc
121
const GLint *loc; // NOTE: This is a pointer so we can immediately use things that are "queried" during program creation.
122
GLint count;
123
float v[4];
124
} uniform4;
125
struct {
126
const char *name; // if null, use loc
127
const GLint *loc;
128
float m[16];
129
} uniformMatrix4;
130
struct {
131
const char *name; // if null, use loc
132
const GLint *loc;
133
float *mData; // new'd, 32 entries
134
} uniformStereoMatrix4;
135
struct {
136
uint32_t clearColor;
137
float clearZ;
138
uint8_t clearStencil;
139
uint8_t colorMask; // Like blend, but for the clear.
140
GLuint clearMask; // GL_COLOR_BUFFER_BIT etc
141
int16_t scissorX;
142
int16_t scissorY;
143
int16_t scissorW;
144
int16_t scissorH;
145
} clear; // also used for invalidate
146
struct {
147
int slot;
148
GLRTexture *texture;
149
} texture;
150
struct {
151
GLRTexture *texture;
152
Draw::DataFormat format;
153
uint8_t slot;
154
uint8_t level;
155
uint16_t width;
156
uint16_t height;
157
uint16_t x;
158
uint16_t y;
159
GLRAllocType allocType;
160
uint8_t *data; // owned, delete[]-d
161
} texture_subimage;
162
struct {
163
GLRFramebuffer* framebuffer;
164
int slot;
165
int aspect;
166
} bind_fb_texture;
167
struct {
168
GLRBuffer *buffer;
169
GLuint target;
170
} bind_buffer;
171
struct {
172
GLRProgram *program;
173
} program;
174
struct {
175
int slot;
176
GLenum wrapS;
177
GLenum wrapT;
178
GLenum magFilter;
179
GLenum minFilter; // also includes mip. GL...
180
float anisotropy;
181
} textureSampler;
182
struct {
183
int slot;
184
float minLod;
185
float maxLod;
186
float lodBias;
187
} textureLod;
188
struct {
189
GLRViewport vp;
190
} viewport;
191
struct {
192
GLRect2D rc;
193
} scissor;
194
struct {
195
GLenum frontFace;
196
GLenum cullFace;
197
GLboolean cullEnable;
198
GLboolean ditherEnable;
199
GLboolean depthClampEnable;
200
} raster;
201
};
202
};
203
204
// Unlike in Vulkan, we can't create stuff on the main thread, but need to
205
// defer this too. A big benefit will be that we'll be able to do all creation
206
// at the start of the frame.
207
enum class GLRInitStepType : uint8_t {
208
CREATE_TEXTURE,
209
CREATE_SHADER,
210
CREATE_PROGRAM,
211
CREATE_BUFFER,
212
CREATE_INPUT_LAYOUT,
213
CREATE_FRAMEBUFFER,
214
215
TEXTURE_IMAGE,
216
TEXTURE_FINALIZE,
217
BUFFER_SUBDATA,
218
};
219
220
struct GLRInitStep {
221
GLRInitStep(GLRInitStepType _type) : stepType(_type) {}
222
GLRInitStepType stepType;
223
union {
224
struct {
225
GLRTexture *texture;
226
} create_texture;
227
struct {
228
GLRShader *shader;
229
// This char arrays needs to be allocated with new[].
230
char *code;
231
GLuint stage;
232
} create_shader;
233
struct {
234
GLRProgram *program;
235
GLRShader *shaders[3];
236
int num_shaders;
237
bool support_dual_source;
238
} create_program;
239
struct {
240
GLRBuffer *buffer;
241
int size;
242
GLuint usage;
243
} create_buffer;
244
struct {
245
GLRInputLayout *inputLayout;
246
} create_input_layout;
247
struct {
248
GLRFramebuffer *framebuffer;
249
} create_framebuffer;
250
struct {
251
GLRBuffer *buffer;
252
int offset;
253
int size;
254
uint8_t *data; // owned, delete[]-d
255
bool deleteData;
256
} buffer_subdata;
257
struct {
258
GLRTexture *texture;
259
Draw::DataFormat format;
260
int level;
261
uint16_t width;
262
uint16_t height;
263
uint16_t depth;
264
GLRAllocType allocType;
265
bool linearFilter;
266
uint8_t *data; // owned, delete[]-d
267
} texture_image;
268
struct {
269
GLRTexture *texture;
270
int loadedLevels;
271
bool genMips;
272
} texture_finalize;
273
};
274
};
275
276
enum class GLRStepType : uint8_t {
277
RENDER,
278
COPY,
279
BLIT,
280
READBACK,
281
READBACK_IMAGE,
282
RENDER_SKIP,
283
};
284
285
enum class GLRRenderPassAction {
286
DONT_CARE,
287
CLEAR,
288
KEEP,
289
};
290
291
class GLRFramebuffer;
292
293
enum GLRAspect {
294
GLR_ASPECT_COLOR = 1,
295
GLR_ASPECT_DEPTH = 2,
296
GLR_ASPECT_STENCIL = 3,
297
};
298
const char *GLRAspectToString(GLRAspect aspect);
299
300
struct GLRStep {
301
GLRStep(GLRStepType _type) : stepType(_type), tag() {}
302
GLRStepType stepType;
303
FastVec<GLRRenderData> commands;
304
TinySet<const GLRFramebuffer *, 8> dependencies;
305
const char *tag;
306
union {
307
struct {
308
GLRFramebuffer *framebuffer;
309
GLRRenderPassAction color;
310
GLRRenderPassAction depth;
311
GLRRenderPassAction stencil;
312
} render;
313
struct {
314
GLRFramebuffer *src;
315
GLRFramebuffer *dst;
316
GLRect2D srcRect;
317
GLOffset2D dstPos;
318
int aspectMask;
319
} copy;
320
struct {
321
GLRFramebuffer *src;
322
GLRFramebuffer *dst;
323
GLRect2D srcRect;
324
GLRect2D dstRect;
325
int aspectMask;
326
GLboolean filter;
327
} blit;
328
struct {
329
GLRFramebuffer* src;
330
GLRect2D srcRect;
331
int aspectMask;
332
Draw::DataFormat dstFormat;
333
} readback;
334
struct {
335
GLRTexture *texture;
336
GLRect2D srcRect;
337
int mipLevel;
338
} readback_image;
339
};
340
};
341
342
class GLQueueRunner {
343
public:
344
GLQueueRunner() {}
345
346
void SetErrorCallback(ErrorCallbackFn callback, void *userdata) {
347
errorCallback_ = callback;
348
errorCallbackUserData_ = userdata;
349
}
350
351
void SetDeviceCaps(const Draw::DeviceCaps &caps) {
352
caps_ = caps;
353
}
354
355
void RunInitSteps(const FastVec<GLRInitStep> &steps, bool skipGLCalls);
356
357
void RunSteps(const std::vector<GLRStep *> &steps, GLFrameData &frameData, bool skipGLCalls, bool keepSteps, bool useVR);
358
359
void CreateDeviceObjects();
360
void DestroyDeviceObjects();
361
362
void CopyFromReadbackBuffer(GLRFramebuffer *framebuffer, int width, int height, Draw::DataFormat srcFormat, Draw::DataFormat destFormat, int pixelStride, uint8_t *pixels);
363
364
void Resize(int width, int height) {
365
targetWidth_ = width;
366
targetHeight_ = height;
367
}
368
369
bool SawOutOfMemory() {
370
return sawOutOfMemory_;
371
}
372
373
std::string GetGLString(int name) const {
374
auto it = glStrings_.find(name);
375
return it != glStrings_.end() ? it->second : "";
376
}
377
378
private:
379
void InitCreateFramebuffer(const GLRInitStep &step);
380
381
void PerformBindFramebufferAsRenderTarget(const GLRStep &pass);
382
void PerformRenderPass(const GLRStep &pass, bool first, bool last, GLQueueProfileContext &profile);
383
void PerformCopy(const GLRStep &pass);
384
void PerformBlit(const GLRStep &pass);
385
void PerformReadback(const GLRStep &pass);
386
void PerformReadbackImage(const GLRStep &pass);
387
388
void fbo_ext_create(const GLRInitStep &step);
389
void fbo_bind_fb_target(bool read, GLuint name);
390
GLenum fbo_get_fb_target(bool read, GLuint **cached);
391
void fbo_unbind();
392
393
std::string StepToString(const GLRStep &step) const;
394
395
GLRFramebuffer *curFB_ = nullptr;
396
397
GLuint globalVAO_ = 0;
398
399
Draw::DeviceCaps caps_{}; // For sanity checks.
400
401
int curFBWidth_ = 0;
402
int curFBHeight_ = 0;
403
int targetWidth_ = 0;
404
int targetHeight_ = 0;
405
406
// Readback buffer. Currently we only support synchronous readback, so we only really need one.
407
// We size it generously.
408
uint8_t *readbackBuffer_ = nullptr;
409
int readbackBufferSize_ = 0;
410
uint32_t readbackAspectMask_ = 0;
411
412
float maxAnisotropyLevel_ = 0.0f;
413
414
// Framebuffer state?
415
GLuint currentDrawHandle_ = 0;
416
GLuint currentReadHandle_ = 0;
417
418
std::unordered_map<int, std::string> glStrings_;
419
420
bool sawOutOfMemory_ = false;
421
bool useDebugGroups_ = false;
422
423
ErrorCallbackFn errorCallback_ = nullptr;
424
void *errorCallbackUserData_ = nullptr;
425
};
426
427
const char *RenderCommandToString(GLRRenderCommand cmd);
428
429