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/thin3d.h
Views: 1401
1
// Very thin API wrapper, suitable for porting UI code (like the native/ui framework) and similar but not real rendering.
2
// Does not involve context creation etc, that should be handled separately - only does drawing.
3
4
// The goals may change in the future though.
5
// MIT licensed, by Henrik RydgÄrd 2014.
6
7
#pragma once
8
9
#include <atomic>
10
#include <cstdint>
11
#include <cstddef>
12
#include <functional>
13
#include <string>
14
#include <vector>
15
16
#include "Common/Common.h"
17
#include "Common/GPU/DataFormat.h"
18
#include "Common/GPU/Shader.h"
19
#include "Common/GPU/MiscTypes.h"
20
#include "Common/Data/Collections/Slice.h"
21
#include "Common/Data/Collections/FastVec.h"
22
23
namespace Lin {
24
class Matrix4x4;
25
}
26
27
namespace Draw {
28
29
// Useful in UBOs
30
typedef int bool32;
31
32
enum class Comparison : uint8_t {
33
NEVER,
34
LESS,
35
EQUAL,
36
LESS_EQUAL,
37
GREATER,
38
NOT_EQUAL,
39
GREATER_EQUAL,
40
ALWAYS,
41
};
42
43
// Had to prefix with LOGIC, too many clashes
44
enum class LogicOp : uint8_t {
45
LOGIC_CLEAR,
46
LOGIC_SET,
47
LOGIC_COPY,
48
LOGIC_COPY_INVERTED,
49
LOGIC_NOOP,
50
LOGIC_INVERT,
51
LOGIC_AND,
52
LOGIC_NAND,
53
LOGIC_OR,
54
LOGIC_NOR,
55
LOGIC_XOR,
56
LOGIC_EQUIV,
57
LOGIC_AND_REVERSE,
58
LOGIC_AND_INVERTED,
59
LOGIC_OR_REVERSE,
60
LOGIC_OR_INVERTED,
61
};
62
63
enum class BlendOp : uint8_t {
64
ADD,
65
SUBTRACT,
66
REV_SUBTRACT,
67
MIN,
68
MAX,
69
};
70
71
enum class BlendFactor : uint8_t {
72
ZERO,
73
ONE,
74
SRC_COLOR,
75
ONE_MINUS_SRC_COLOR,
76
DST_COLOR,
77
ONE_MINUS_DST_COLOR,
78
SRC_ALPHA,
79
ONE_MINUS_SRC_ALPHA,
80
DST_ALPHA,
81
ONE_MINUS_DST_ALPHA,
82
CONSTANT_COLOR,
83
ONE_MINUS_CONSTANT_COLOR,
84
CONSTANT_ALPHA,
85
ONE_MINUS_CONSTANT_ALPHA,
86
SRC1_COLOR,
87
ONE_MINUS_SRC1_COLOR,
88
SRC1_ALPHA,
89
ONE_MINUS_SRC1_ALPHA,
90
};
91
92
enum class StencilOp {
93
KEEP = 0,
94
ZERO = 1,
95
REPLACE = 2,
96
INCREMENT_AND_CLAMP = 3,
97
DECREMENT_AND_CLAMP = 4,
98
INVERT = 5,
99
INCREMENT_AND_WRAP = 6,
100
DECREMENT_AND_WRAP = 7,
101
};
102
103
enum class TextureFilter : uint8_t {
104
NEAREST = 0,
105
LINEAR = 1,
106
};
107
108
enum BufferUsageFlag : int {
109
VERTEXDATA = 1,
110
INDEXDATA = 2,
111
GENERIC = 4,
112
UNIFORM = 8,
113
114
DYNAMIC = 16,
115
};
116
117
enum Semantic : int {
118
SEM_POSITION,
119
SEM_COLOR0,
120
SEM_COLOR1,
121
SEM_TEXCOORD0,
122
SEM_TEXCOORD1,
123
SEM_NORMAL,
124
SEM_TANGENT,
125
SEM_BINORMAL, // really BITANGENT
126
SEM_MAX,
127
};
128
129
enum class Primitive {
130
POINT_LIST,
131
LINE_LIST,
132
LINE_STRIP,
133
TRIANGLE_LIST,
134
TRIANGLE_STRIP,
135
TRIANGLE_FAN,
136
// Tesselation shader only
137
PATCH_LIST,
138
// These are for geometry shaders only.
139
LINE_LIST_ADJ,
140
LINE_STRIP_ADJ,
141
TRIANGLE_LIST_ADJ,
142
TRIANGLE_STRIP_ADJ,
143
144
UNDEFINED,
145
PRIMITIVE_TYPE_COUNT,
146
};
147
148
enum VertexShaderPreset : int {
149
VS_COLOR_2D,
150
VS_TEXTURE_COLOR_2D,
151
VS_MAX_PRESET,
152
};
153
154
enum FragmentShaderPreset : int {
155
FS_COLOR_2D,
156
FS_TEXTURE_COLOR_2D,
157
FS_TEXTURE_COLOR_2D_RB_SWIZZLE,
158
FS_MAX_PRESET,
159
};
160
161
enum class TextureType : uint8_t {
162
UNKNOWN,
163
LINEAR1D,
164
LINEAR2D,
165
LINEAR3D,
166
CUBE,
167
ARRAY1D,
168
ARRAY2D,
169
};
170
171
enum class CullMode : uint8_t {
172
NONE,
173
FRONT,
174
BACK,
175
FRONT_AND_BACK, // Not supported on D3D9
176
};
177
178
enum class Facing {
179
CCW,
180
CW,
181
};
182
183
enum BorderColor {
184
DONT_CARE,
185
TRANSPARENT_BLACK,
186
OPAQUE_BLACK,
187
OPAQUE_WHITE,
188
};
189
190
enum {
191
COLOR_MASK_R = 1,
192
COLOR_MASK_G = 2,
193
COLOR_MASK_B = 4,
194
COLOR_MASK_A = 8,
195
};
196
197
enum class TextureAddressMode {
198
REPEAT = 0,
199
REPEAT_MIRROR,
200
CLAMP_TO_EDGE,
201
CLAMP_TO_BORDER,
202
};
203
204
enum FormatSupport {
205
FMT_RENDERTARGET = 1,
206
FMT_TEXTURE = 2,
207
FMT_INPUTLAYOUT = 4,
208
FMT_DEPTHSTENCIL = 8,
209
FMT_AUTOGEN_MIPS = 16,
210
FMT_BLIT = 32,
211
FMT_STORAGE_IMAGE = 64,
212
};
213
214
enum class InfoField {
215
APINAME,
216
APIVERSION,
217
VENDORSTRING,
218
VENDOR,
219
SHADELANGVERSION,
220
DRIVER,
221
DEVICE_API_VERSION, // Vulkan-only
222
};
223
224
enum class GPUVendor {
225
VENDOR_UNKNOWN,
226
VENDOR_NVIDIA,
227
VENDOR_INTEL,
228
VENDOR_AMD,
229
VENDOR_ARM, // Mali
230
VENDOR_QUALCOMM,
231
VENDOR_IMGTEC, // PowerVR
232
VENDOR_BROADCOM, // Raspberry
233
VENDOR_VIVANTE,
234
VENDOR_APPLE,
235
VENDOR_MESA,
236
};
237
238
enum class NativeObject {
239
CONTEXT,
240
CONTEXT_EX,
241
DEVICE,
242
DEVICE_EX,
243
BACKBUFFER_COLOR_VIEW,
244
BACKBUFFER_DEPTH_VIEW,
245
BACKBUFFER_COLOR_TEX,
246
BACKBUFFER_DEPTH_TEX,
247
FEATURE_LEVEL,
248
INIT_COMMANDBUFFER,
249
BOUND_TEXTURE0_IMAGEVIEW, // Layer etc depends on how you bound it...
250
BOUND_TEXTURE1_IMAGEVIEW, // Layer etc depends on how you bound it...
251
BOUND_FRAMEBUFFER_COLOR_IMAGEVIEW_ALL_LAYERS,
252
BOUND_FRAMEBUFFER_COLOR_IMAGEVIEW_RT,
253
RENDER_MANAGER,
254
TEXTURE_VIEW,
255
NULL_IMAGEVIEW,
256
NULL_IMAGEVIEW_ARRAY,
257
THIN3D_PIPELINE_LAYOUT,
258
PUSH_POOL,
259
};
260
261
enum FBChannel {
262
FB_COLOR_BIT = 1,
263
FB_DEPTH_BIT = 2,
264
FB_STENCIL_BIT = 4,
265
266
// Implementation specific
267
FB_SURFACE_BIT = 32, // Used in conjunction with the others in D3D9 to get surfaces through get_api_texture
268
FB_VIEW_BIT = 64, // Used in conjunction with the others in D3D11 to get shader resource views through get_api_texture
269
FB_FORMAT_BIT = 128, // Actually retrieves the native format instead. D3D11 only.
270
};
271
272
enum FBInvalidationStage {
273
FB_INVALIDATION_LOAD = 1,
274
FB_INVALIDATION_STORE = 2,
275
};
276
277
enum FBBlitFilter {
278
FB_BLIT_NEAREST = 0,
279
FB_BLIT_LINEAR = 1,
280
};
281
282
enum UpdateBufferFlags {
283
UPDATE_DISCARD = 1,
284
};
285
286
enum class Event {
287
// These happen on D3D resize. Only the backbuffer needs to be resized.
288
LOST_BACKBUFFER,
289
GOT_BACKBUFFER,
290
291
// These are a bit more serious...
292
LOST_DEVICE,
293
GOT_DEVICE,
294
295
RESIZED,
296
PRESENTED,
297
};
298
299
enum class ReadbackMode {
300
BLOCK,
301
OLD_DATA_OK, // Lets the backend return old results that won't need any waiting to get.
302
};
303
304
constexpr uint32_t MAX_TEXTURE_SLOTS = 3;
305
306
struct FramebufferDesc {
307
int width;
308
int height;
309
int depth;
310
int numLayers;
311
int multiSampleLevel; // 0 = 1xaa, 1 = 2xaa, and so on.
312
bool z_stencil;
313
const char *tag; // For graphics debuggers
314
};
315
316
// Binary compatible with D3D11 viewport.
317
struct Viewport {
318
float TopLeftX;
319
float TopLeftY;
320
float Width;
321
float Height;
322
float MinDepth;
323
float MaxDepth;
324
};
325
326
class Bugs {
327
public:
328
bool Has(uint32_t bug) const {
329
return (flags_ & (1 << bug)) != 0;
330
}
331
void Infest(uint32_t bug) {
332
flags_ |= (1 << bug);
333
}
334
uint32_t MaxBugIndex() const {
335
return (uint32_t)MAX_BUG;
336
}
337
const char *GetBugName(uint32_t bug);
338
339
enum : uint32_t {
340
NO_DEPTH_CANNOT_DISCARD_STENCIL_ADRENO = 0,
341
DUAL_SOURCE_BLENDING_BROKEN = 1,
342
ANY_MAP_BUFFER_RANGE_SLOW = 2,
343
PVR_GENMIPMAP_HEIGHT_GREATER = 3,
344
BROKEN_NAN_IN_CONDITIONAL = 4,
345
COLORWRITEMASK_BROKEN_WITH_DEPTHTEST = 5,
346
BROKEN_FLAT_IN_SHADER = 6,
347
EQUAL_WZ_CORRUPTS_DEPTH = 7,
348
RASPBERRY_SHADER_COMP_HANG = 8,
349
MALI_CONSTANT_LOAD_BUG = 9,
350
SUBPASS_FEEDBACK_BROKEN = 10,
351
GEOMETRY_SHADERS_SLOW_OR_BROKEN = 11,
352
ADRENO_RESOURCE_DEADLOCK = 12,
353
UNIFORM_INDEXING_BROKEN = 13, // not a properly diagnosed issue, a workaround attempt: #17386
354
PVR_BAD_16BIT_TEXFORMATS = 14,
355
NO_DEPTH_CANNOT_DISCARD_STENCIL_MALI = 15,
356
MAX_BUG,
357
};
358
359
protected:
360
uint32_t flags_ = 0;
361
362
static_assert(sizeof(flags_) * 8 > MAX_BUG, "Ran out of space for bugs.");
363
};
364
365
class RefCountedObject {
366
public:
367
explicit RefCountedObject(const char *name) : name_(name) {
368
refcount_ = 1;
369
}
370
RefCountedObject(const RefCountedObject &other) = delete;
371
RefCountedObject& operator=(RefCountedObject const&) = delete;
372
virtual ~RefCountedObject();
373
374
void AddRef() { refcount_++; }
375
bool Release();
376
bool ReleaseAssertLast();
377
378
private:
379
std::atomic<int> refcount_;
380
const char * const name_;
381
};
382
383
template <typename T>
384
struct AutoRef {
385
AutoRef() {}
386
explicit AutoRef(T *p) {
387
ptr = p;
388
if (ptr)
389
ptr->AddRef();
390
}
391
AutoRef(const AutoRef<T> &p) {
392
*this = p.ptr;
393
}
394
~AutoRef() {
395
if (ptr)
396
ptr->Release();
397
}
398
399
T *operator =(T *p) {
400
if (ptr)
401
ptr->Release();
402
ptr = p;
403
if (ptr)
404
ptr->AddRef();
405
return ptr;
406
}
407
AutoRef<T> &operator =(const AutoRef<T> &p) {
408
*this = p.ptr;
409
return *this;
410
}
411
bool operator !=(const AutoRef<T> &p) const {
412
return ptr != p.ptr;
413
}
414
415
T *operator->() const {
416
return ptr;
417
}
418
operator T *() {
419
return ptr;
420
}
421
operator bool() const {
422
return ptr != nullptr;
423
}
424
425
// Takes over ownership over newItem, so we don't need to AddRef it, the number of owners didn't change.
426
void reset(T *newItem) {
427
if (ptr) {
428
ptr->Release();
429
}
430
ptr = newItem;
431
}
432
433
T *ptr = nullptr;
434
};
435
436
class BlendState : public RefCountedObject {
437
public:
438
BlendState() : RefCountedObject("BlendState") {}
439
};
440
441
class SamplerState : public RefCountedObject {
442
public:
443
SamplerState() : RefCountedObject("SamplerState") {}
444
};
445
446
class DepthStencilState : public RefCountedObject {
447
public:
448
DepthStencilState() : RefCountedObject("DepthStencilState") {}
449
};
450
451
class Framebuffer : public RefCountedObject {
452
public:
453
Framebuffer() : RefCountedObject("Framebuffer") {}
454
int Width() const { return width_; }
455
int Height() const { return height_; }
456
int Layers() const { return layers_; }
457
int MultiSampleLevel() { return multiSampleLevel_; }
458
459
virtual void UpdateTag(const char *tag) {}
460
protected:
461
int width_ = -1, height_ = -1, layers_ = 1, multiSampleLevel_ = 0;
462
};
463
464
class Buffer : public RefCountedObject {
465
public:
466
Buffer() : RefCountedObject("Buffer") {}
467
};
468
469
class Texture : public RefCountedObject {
470
public:
471
Texture() : RefCountedObject("Texture") {}
472
int Width() const { return width_; }
473
int Height() const { return height_; }
474
int Depth() const { return depth_; }
475
DataFormat Format() const { return format_; }
476
477
protected:
478
int width_ = -1, height_ = -1, depth_ = -1;
479
DataFormat format_ = DataFormat::UNDEFINED;
480
};
481
482
struct AttributeDesc {
483
int location; // corresponds to semantic
484
DataFormat format;
485
int offset;
486
};
487
488
struct InputLayoutDesc {
489
int stride;
490
std::vector<AttributeDesc> attributes;
491
};
492
493
class InputLayout : public RefCountedObject {
494
public:
495
InputLayout() : RefCountedObject("InputLayout") {}
496
};
497
498
// Uniform types have moved to Shader.h.
499
500
class ShaderModule : public RefCountedObject {
501
public:
502
ShaderModule() : RefCountedObject("ShaderModule") {}
503
virtual ShaderStage GetStage() const = 0;
504
};
505
506
class Pipeline : public RefCountedObject {
507
public:
508
Pipeline() : RefCountedObject("Pipeline") {}
509
};
510
511
class RasterState : public RefCountedObject {
512
public:
513
RasterState() : RefCountedObject("RasterState") {}
514
};
515
516
struct StencilSetup {
517
StencilOp failOp;
518
StencilOp passOp;
519
StencilOp depthFailOp;
520
Comparison compareOp;
521
};
522
523
struct DepthStencilStateDesc {
524
bool depthTestEnabled;
525
bool depthWriteEnabled;
526
Comparison depthCompare;
527
bool stencilEnabled;
528
StencilSetup stencil;
529
};
530
531
struct BlendStateDesc {
532
bool enabled;
533
int colorMask;
534
BlendFactor srcCol;
535
BlendFactor dstCol;
536
BlendOp eqCol;
537
BlendFactor srcAlpha;
538
BlendFactor dstAlpha;
539
BlendOp eqAlpha;
540
bool logicEnabled;
541
LogicOp logicOp;
542
};
543
544
struct SamplerStateDesc {
545
TextureFilter magFilter;
546
TextureFilter minFilter;
547
TextureFilter mipFilter;
548
float maxAniso;
549
TextureAddressMode wrapU;
550
TextureAddressMode wrapV;
551
TextureAddressMode wrapW;
552
bool shadowCompareEnabled;
553
Comparison shadowCompareFunc;
554
BorderColor borderColor;
555
};
556
557
struct RasterStateDesc {
558
CullMode cull;
559
Facing frontFace;
560
};
561
562
struct PipelineDesc {
563
Primitive prim;
564
std::vector<ShaderModule *> shaders;
565
InputLayout *inputLayout;
566
DepthStencilState *depthStencil;
567
BlendState *blend;
568
RasterState *raster;
569
const UniformBufferDesc *uniformDesc;
570
const Slice<SamplerDef> samplers;
571
};
572
573
enum class PresentMode {
574
FIFO = 1,
575
IMMEDIATE = 2,
576
MAILBOX = 4,
577
};
578
ENUM_CLASS_BITOPS(PresentMode);
579
580
struct DeviceCaps {
581
GPUVendor vendor;
582
uint32_t deviceID; // use caution!
583
584
DataFormat preferredDepthBufferFormat;
585
DataFormat preferredShadowMapFormatLow;
586
DataFormat preferredShadowMapFormatHigh;
587
bool anisoSupported;
588
bool depthRangeMinusOneToOne; // OpenGL style depth
589
bool geometryShaderSupported;
590
bool tesselationShaderSupported;
591
bool dualSourceBlend;
592
bool logicOpSupported;
593
bool depthClampSupported;
594
bool clipDistanceSupported;
595
bool cullDistanceSupported;
596
bool framebufferCopySupported;
597
bool framebufferBlitSupported;
598
bool framebufferDepthCopySupported;
599
bool framebufferSeparateDepthCopySupported;
600
bool framebufferDepthBlitSupported;
601
bool framebufferStencilBlitSupported;
602
bool framebufferFetchSupported;
603
bool texture3DSupported;
604
bool fragmentShaderInt32Supported;
605
bool textureNPOTFullySupported;
606
bool fragmentShaderDepthWriteSupported;
607
bool fragmentShaderStencilWriteSupported;
608
bool textureDepthSupported;
609
bool blendMinMaxSupported;
610
bool multiViewSupported;
611
bool isTilingGPU; // This means that it benefits from correct store-ops, msaa without backing memory, etc.
612
bool sampleRateShadingSupported;
613
bool setMaxFrameLatencySupported;
614
bool textureSwizzleSupported;
615
bool requiresHalfPixelOffset;
616
bool provokingVertexLast; // GL behavior, what the PSP does
617
bool verySlowShaderCompiler;
618
619
// From the other backends, we can detect if D3D9 support is known bad (like on Xe) and disable it.
620
bool supportsD3D9;
621
622
// Old style, for older GL or Direct3D 9.
623
u32 clipPlanesSupported;
624
625
// Presentation caps
626
int presentMaxInterval; // 1 on many backends
627
bool presentInstantModeChange;
628
PresentMode presentModesSupported;
629
630
u32 multiSampleLevelsMask; // Bit n is set if (1 << n) is a valid multisample level. Bit 0 is always set.
631
std::string deviceName; // The device name to use when creating the thin3d context, to get the same one.
632
};
633
634
// Use to write data directly to texture memory. initData is the pointer passed in TextureDesc.
635
// Important: only write to the provided pointer, don't read from it.
636
typedef std::function<bool(uint8_t *data, const uint8_t *initData, uint32_t w, uint32_t h, uint32_t d, uint32_t byteStride, uint32_t sliceByteStride)> TextureCallback;
637
638
enum class TextureSwizzle {
639
DEFAULT,
640
R8_AS_ALPHA,
641
};
642
643
struct TextureDesc {
644
TextureType type;
645
DataFormat format;
646
647
int width;
648
int height;
649
int depth;
650
int mipLevels;
651
bool generateMips;
652
TextureSwizzle swizzle;
653
// Optional, for tracking memory usage and graphcis debuggers.
654
const char *tag;
655
// Does not take ownership over pointed-to data.
656
std::vector<const uint8_t *> initData;
657
TextureCallback initDataCallback;
658
};
659
660
enum class RPAction {
661
KEEP = 0,
662
CLEAR = 1,
663
DONT_CARE = 2,
664
};
665
666
struct RenderPassInfo {
667
RPAction color;
668
RPAction depth;
669
RPAction stencil;
670
uint32_t clearColor;
671
float clearDepth;
672
uint8_t clearStencil;
673
const char *tag;
674
};
675
676
const int ALL_LAYERS = -1;
677
678
enum class TextureBindFlags {
679
NONE = 0,
680
VULKAN_BIND_ARRAY = 1,
681
};
682
ENUM_CLASS_BITOPS(TextureBindFlags);
683
684
enum class DebugFlags {
685
NONE = 0,
686
PROFILE_TIMESTAMPS = 1,
687
PROFILE_SCOPES = 2,
688
};
689
ENUM_CLASS_BITOPS(DebugFlags);
690
691
struct BackendState {
692
u32 passes;
693
bool valid;
694
};
695
696
class DrawContext {
697
public:
698
virtual ~DrawContext();
699
bool CreatePresets();
700
void DestroyPresets();
701
702
Bugs GetBugs() const { return bugs_; }
703
704
virtual void Wait() {}
705
706
virtual const DeviceCaps &GetDeviceCaps() const = 0;
707
virtual uint32_t GetDataFormatSupport(DataFormat fmt) const = 0;
708
virtual std::vector<std::string> GetFeatureList() const { return std::vector<std::string>(); }
709
virtual std::vector<std::string> GetExtensionList(bool device, bool enabledOnly) const { return std::vector<std::string>(); }
710
virtual std::vector<std::string> GetDeviceList() const { return std::vector<std::string>(); }
711
virtual std::vector<std::string> GetPresentModeList(std::string_view currentMarkerString) const { return std::vector<std::string>(); }
712
virtual std::vector<std::string> GetSurfaceFormatList() const { return std::vector<std::string>(); }
713
714
virtual BackendState GetCurrentBackendState() const {
715
return BackendState{};
716
}
717
718
// Describes the primary shader language that this implementation prefers.
719
const ShaderLanguageDesc &GetShaderLanguageDesc() {
720
return shaderLanguageDesc_;
721
}
722
723
virtual uint32_t GetSupportedShaderLanguages() const = 0;
724
725
virtual void SetErrorCallback(ErrorCallbackFn callback, void *userdata) {}
726
727
virtual void DebugAnnotate(const char *annotation) {}
728
729
// Partial pipeline state, used to create pipelines. (in practice, in d3d11 they'll use the native state objects directly).
730
// TODO: Possibly ditch these and just put the descs directly in PipelineDesc since only D3D11 benefits.
731
virtual DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) = 0;
732
virtual BlendState *CreateBlendState(const BlendStateDesc &desc) = 0;
733
virtual SamplerState *CreateSamplerState(const SamplerStateDesc &desc) = 0;
734
virtual RasterState *CreateRasterState(const RasterStateDesc &desc) = 0;
735
virtual InputLayout *CreateInputLayout(const InputLayoutDesc &desc) = 0;
736
virtual ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize, const char *tag = "thin3d") = 0;
737
virtual Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc, const char *tag) = 0;
738
739
// Note that these DO NOT AddRef so you must not ->Release presets unless you manually AddRef them.
740
ShaderModule *GetVshaderPreset(VertexShaderPreset preset) { return vsPresets_[preset]; }
741
ShaderModule *GetFshaderPreset(FragmentShaderPreset preset) { return fsPresets_[preset]; }
742
743
// Resources
744
virtual Buffer *CreateBuffer(size_t size, uint32_t usageFlags) = 0;
745
// Does not take ownership over pointed-to initData. After this returns, can dispose of it.
746
virtual Texture *CreateTexture(const TextureDesc &desc) = 0;
747
// On some hardware, you might get a 24-bit depth buffer even though you only wanted a 16-bit one.
748
virtual Framebuffer *CreateFramebuffer(const FramebufferDesc &desc) = 0;
749
750
// Copies data from the CPU over into the buffer, at a specific offset. This does not change the size of the buffer and cannot write outside it.
751
virtual void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) = 0;
752
753
// Used to optimize DrawPixels by re-using previously allocated temp textures.
754
// Do not try to update a texture that might be used by an in-flight command buffer! In OpenGL and D3D, this will cause stalls
755
// while in Vulkan this might cause various strangeness like image corruption.
756
virtual void UpdateTextureLevels(Texture *texture, const uint8_t **data, TextureCallback initDataCallback, int numLevels) = 0;
757
758
virtual void CopyFramebufferImage(Framebuffer *src, int level, int x, int y, int z, Framebuffer *dst, int dstLevel, int dstX, int dstY, int dstZ, int width, int height, int depth, int channelBits, const char *tag) = 0;
759
virtual bool BlitFramebuffer(Framebuffer *src, int srcX1, int srcY1, int srcX2, int srcY2, Framebuffer *dst, int dstX1, int dstY1, int dstX2, int dstY2, int channelBits, FBBlitFilter filter, const char *tag) = 0;
760
761
// If the backend doesn't support old data, it's "OK" to block.
762
virtual bool CopyFramebufferToMemory(Framebuffer *src, int channelBits, int x, int y, int w, int h, Draw::DataFormat format, void *pixels, int pixelStride, ReadbackMode mode, const char *tag) {
763
return false;
764
}
765
virtual DataFormat PreferredFramebufferReadbackFormat(Framebuffer *src) {
766
return DataFormat::R8G8B8A8_UNORM;
767
}
768
769
// These functions should be self explanatory.
770
// Binding a zero render target means binding the backbuffer.
771
// If an fbo has two layers, we bind for stereo rendering ALWAYS. There's no rendering to one layer anymore.
772
virtual void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) = 0;
773
774
// binding must be < MAX_TEXTURE_SLOTS (0, 1 are okay if it's 2).
775
virtual void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int layer) = 0;
776
777
// Framebuffer fetch / input attachment support, needs to be explicit in Vulkan.
778
virtual void BindCurrentFramebufferForColorInput() {}
779
780
// deprecated, only used by D3D9
781
virtual uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) {
782
return 0;
783
}
784
785
virtual void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) = 0;
786
787
// Could be useful in OpenGL ES to give hints about framebuffers on tiler GPUs
788
// using glInvalidateFramebuffer, although drivers are known to botch that so we currently don't use it.
789
// In Vulkan, this sets the LOAD_OP or the STORE_OP (depending on stage) of the current render pass instance to DONT_CARE.
790
// channels is a bitwise combination of FBChannel::COLOR, DEPTH and STENCIL.
791
virtual void InvalidateFramebuffer(FBInvalidationStage stage, uint32_t channels) {}
792
793
// Dynamic state
794
virtual void SetScissorRect(int left, int top, int width, int height) = 0;
795
virtual void SetViewport(const Viewport &viewport) = 0;
796
virtual void SetBlendFactor(float color[4]) = 0;
797
virtual void SetStencilParams(uint8_t refValue, uint8_t writeMask, uint8_t compareMask) = 0;
798
799
virtual void BindSamplerStates(int start, int count, SamplerState **state) = 0;
800
virtual void BindTextures(int start, int count, Texture **textures, TextureBindFlags flags = TextureBindFlags::NONE) = 0;
801
virtual void BindVertexBuffer(Buffer *vertexBuffer, int offset) = 0;
802
virtual void BindIndexBuffer(Buffer *indexBuffer, int offset) = 0;
803
804
// Sometimes it's necessary to bind a texture not created by thin3d, and use with a thin3d pipeline.
805
// Not pretty, and one way in the future could be to create all textures through thin3d.
806
// Data types:
807
// * Vulkan: VkImageView
808
// * D3D11: ID3D11ShaderResourceView*
809
virtual void BindNativeTexture(int sampler, void *nativeTexture) = 0;
810
811
// Only supports a single dynamic uniform buffer, for maximum compatibility with the old APIs and ease of emulation.
812
// More modern methods will be added later.
813
virtual void UpdateDynamicUniformBuffer(const void *ub, size_t size) = 0;
814
815
void BindTexture(int stage, Texture *texture) {
816
Texture *textures[1] = { texture };
817
BindTextures(stage, 1, textures);
818
} // from sampler 0 and upwards
819
820
// Clear state cached within thin3d. Must be called after directly calling API functions.
821
// Note that framebuffer state (which framebuffer is bounds) may not be cached.
822
// Must not actually perform any API calls itself since this can be called when no framebuffer is bound for rendering.
823
virtual void Invalidate(InvalidationFlags flags) = 0;
824
825
virtual void BindPipeline(Pipeline *pipeline) = 0;
826
827
virtual void Draw(int vertexCount, int offset) = 0;
828
virtual void DrawIndexed(int vertexCount, int offset) = 0; // Always 16-bit indices.
829
virtual void DrawUP(const void *vdata, int vertexCount) = 0;
830
831
// Frame management (for the purposes of sync and resource management, necessary with modern APIs). Default implementations here.
832
virtual void BeginFrame(DebugFlags debugFlags) = 0;
833
virtual void EndFrame() = 0;
834
835
// vblanks is only relevant in FIFO present mode.
836
// NOTE: Not all backends support vblanks > 1. Some backends also can't change presentation mode immediately.
837
virtual void Present(PresentMode presentMode, int vblanks) = 0;
838
839
// This should be avoided as much as possible, in favor of clearing when binding a render target, which is native
840
// on Vulkan.
841
virtual void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) = 0;
842
843
// Necessary to correctly flip scissor rectangles etc for OpenGL.
844
virtual void SetTargetSize(int w, int h) {
845
targetWidth_ = w;
846
targetHeight_ = h;
847
}
848
849
// In Vulkan, when changing things like MSAA mode, we can't have draw commands in flight (since we only support one at a time).
850
virtual void StopThreads() {}
851
virtual void StartThreads() {}
852
853
virtual std::string GetInfoString(InfoField info) const = 0;
854
virtual uint64_t GetNativeObject(NativeObject obj, void *srcObject = nullptr) = 0; // Most uses don't need an srcObject.
855
856
virtual void HandleEvent(Event ev, int width, int height, void *param1 = nullptr, void *param2 = nullptr) = 0;
857
858
// Flush state like scissors etc so the caller can do its own custom drawing.
859
virtual void FlushState() {}
860
861
// This is called when we launch a new game, so any collected internal stats in the backends don't carry over.
862
virtual void ResetStats() {}
863
864
// Used by the DrawEngines to know when they have to re-apply some state.
865
// Not very elegant, but more elegant than the old passId hack.
866
virtual void SetInvalidationCallback(InvalidationCallback callback) = 0;
867
868
// Total amount of frames rendered. Unaffected by game pause, so more robust than gpuStats.numFlips
869
virtual int GetFrameCount() = 0;
870
871
virtual std::string GetGpuProfileString() const {
872
return "";
873
}
874
875
const HistoryBuffer<FrameTimeData, FRAME_TIME_HISTORY_LENGTH> &FrameTimeHistory() const {
876
return frameTimeHistory_;
877
}
878
879
protected:
880
HistoryBuffer<FrameTimeData, FRAME_TIME_HISTORY_LENGTH> frameTimeHistory_;
881
882
ShaderModule *vsPresets_[VS_MAX_PRESET];
883
ShaderModule *fsPresets_[FS_MAX_PRESET];
884
885
ShaderLanguageDesc shaderLanguageDesc_;
886
887
int targetWidth_;
888
int targetHeight_;
889
890
Bugs bugs_;
891
};
892
893
extern const UniformBufferDesc UBPresetDesc;
894
895
// UBs for the preset shaders
896
897
struct VsTexColUB {
898
float WorldViewProj[16];
899
float tint;
900
float saturation;
901
float pad[2];
902
};
903
extern const UniformBufferDesc vsTexColBufDesc;
904
struct VsColUB {
905
float WorldViewProj[16];
906
float tint;
907
float saturation;
908
float pad[2];
909
};
910
extern const UniformBufferDesc vsColBufDesc;
911
912
// Useful utility for specifying a shader in multiple languages.
913
914
struct ShaderSource {
915
ShaderLanguage lang;
916
const char *src;
917
};
918
919
ShaderModule *CreateShader(DrawContext *draw, ShaderStage stage, const std::vector<ShaderSource> &sources);
920
921
const char *PresentModeToString(PresentMode presentMode);
922
923
} // namespace Draw
924
925