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/GPU/DataFormat.h"
17 #include "Common/GPU/Shader.h"
18 
19 namespace Lin {
20 class Matrix4x4;
21 }
22 
23 namespace Draw {
24 
25 // Useful in UBOs
26 typedef int bool32;
27 
28 enum class Comparison : int {
29 	NEVER,
30 	LESS,
31 	EQUAL,
32 	LESS_EQUAL,
33 	GREATER,
34 	NOT_EQUAL,
35 	GREATER_EQUAL,
36 	ALWAYS,
37 };
38 
39 // Had to prefix with LOGIC, too many clashes
40 enum class LogicOp : int {
41 	LOGIC_CLEAR,
42 	LOGIC_SET,
43 	LOGIC_COPY,
44 	LOGIC_COPY_INVERTED,
45 	LOGIC_NOOP,
46 	LOGIC_INVERT,
47 	LOGIC_AND,
48 	LOGIC_NAND,
49 	LOGIC_OR,
50 	LOGIC_NOR,
51 	LOGIC_XOR,
52 	LOGIC_EQUIV,
53 	LOGIC_AND_REVERSE,
54 	LOGIC_AND_INVERTED,
55 	LOGIC_OR_REVERSE,
56 	LOGIC_OR_INVERTED,
57 };
58 
59 enum class BlendOp : int {
60 	ADD,
61 	SUBTRACT,
62 	REV_SUBTRACT,
63 	MIN,
64 	MAX,
65 };
66 
67 enum class BlendFactor : uint8_t {
68 	ZERO,
69 	ONE,
70 	SRC_COLOR,
71 	ONE_MINUS_SRC_COLOR,
72 	DST_COLOR,
73 	ONE_MINUS_DST_COLOR,
74 	SRC_ALPHA,
75 	ONE_MINUS_SRC_ALPHA,
76 	DST_ALPHA,
77 	ONE_MINUS_DST_ALPHA,
78 	CONSTANT_COLOR,
79 	ONE_MINUS_CONSTANT_COLOR,
80 	CONSTANT_ALPHA,
81 	ONE_MINUS_CONSTANT_ALPHA,
82 	SRC1_COLOR,
83 	ONE_MINUS_SRC1_COLOR,
84 	SRC1_ALPHA,
85 	ONE_MINUS_SRC1_ALPHA,
86 };
87 
88 enum class StencilOp {
89 	KEEP = 0,
90 	ZERO = 1,
91 	REPLACE = 2,
92 	INCREMENT_AND_CLAMP = 3,
93 	DECREMENT_AND_CLAMP = 4,
94 	INVERT = 5,
95 	INCREMENT_AND_WRAP = 6,
96 	DECREMENT_AND_WRAP = 7,
97 };
98 
99 enum class TextureFilter : int {
100 	NEAREST = 0,
101 	LINEAR = 1,
102 };
103 
104 enum BufferUsageFlag : int {
105 	VERTEXDATA = 1,
106 	INDEXDATA = 2,
107 	GENERIC = 4,
108 	UNIFORM = 8,
109 
110 	DYNAMIC = 16,
111 };
112 
113 enum Semantic : int {
114 	SEM_POSITION,
115 	SEM_COLOR0,
116 	SEM_TEXCOORD0,
117 	SEM_TEXCOORD1,
118 	SEM_NORMAL,
119 	SEM_TANGENT,
120 	SEM_BINORMAL,  // really BITANGENT
121 	SEM_MAX,
122 };
123 
124 enum class Primitive {
125 	POINT_LIST,
126 	LINE_LIST,
127 	LINE_STRIP,
128 	TRIANGLE_LIST,
129 	TRIANGLE_STRIP,
130 	TRIANGLE_FAN,
131 	// Tesselation shader only
132 	PATCH_LIST,
133 	// These are for geometry shaders only.
134 	LINE_LIST_ADJ,
135 	LINE_STRIP_ADJ,
136 	TRIANGLE_LIST_ADJ,
137 	TRIANGLE_STRIP_ADJ,
138 
139 	UNDEFINED,
140 	PRIMITIVE_TYPE_COUNT,
141 };
142 
143 enum VertexShaderPreset : int {
144 	VS_COLOR_2D,
145 	VS_TEXTURE_COLOR_2D,
146 	VS_MAX_PRESET,
147 };
148 
149 enum FragmentShaderPreset : int {
150 	FS_COLOR_2D,
151 	FS_TEXTURE_COLOR_2D,
152 	FS_TEXTURE_COLOR_2D_RB_SWIZZLE,
153 	FS_MAX_PRESET,
154 };
155 
156 enum class TextureType : uint8_t {
157 	UNKNOWN,
158 	LINEAR1D,
159 	LINEAR2D,
160 	LINEAR3D,
161 	CUBE,
162 	ARRAY1D,
163 	ARRAY2D,
164 };
165 
166 enum class CullMode : uint8_t {
167 	NONE,
168 	FRONT,
169 	BACK,
170 	FRONT_AND_BACK,  // Not supported on D3D9
171 };
172 
173 enum class Facing {
174 	CCW,
175 	CW,
176 };
177 
178 enum BorderColor {
179 	DONT_CARE,
180 	TRANSPARENT_BLACK,
181 	OPAQUE_BLACK,
182 	OPAQUE_WHITE,
183 };
184 
185 enum {
186 	COLOR_MASK_R = 1,
187 	COLOR_MASK_G = 2,
188 	COLOR_MASK_B = 4,
189 	COLOR_MASK_A = 8,
190 };
191 
192 enum class TextureAddressMode {
193 	REPEAT = 0,
194 	REPEAT_MIRROR,
195 	CLAMP_TO_EDGE,
196 	CLAMP_TO_BORDER,
197 };
198 
199 enum FormatSupport {
200 	FMT_RENDERTARGET = 1,
201 	FMT_TEXTURE = 2,
202 	FMT_INPUTLAYOUT = 4,
203 	FMT_DEPTHSTENCIL = 8,
204 	FMT_AUTOGEN_MIPS = 16,
205 };
206 
207 enum InfoField {
208 	APINAME,
209 	APIVERSION,
210 	VENDORSTRING,
211 	VENDOR,
212 	SHADELANGVERSION,
213 	DRIVER,
214 };
215 
216 enum class GPUVendor {
217 	VENDOR_UNKNOWN,
218 	VENDOR_NVIDIA,
219 	VENDOR_INTEL,
220 	VENDOR_AMD,
221 	VENDOR_ARM,  // Mali
222 	VENDOR_QUALCOMM,
223 	VENDOR_IMGTEC,  // PowerVR
224 	VENDOR_BROADCOM,  // Raspberry
225 	VENDOR_VIVANTE,
226 	VENDOR_APPLE,
227 };
228 
229 enum class NativeObject {
230 	CONTEXT,
231 	CONTEXT_EX,
232 	DEVICE,
233 	DEVICE_EX,
234 	BACKBUFFER_COLOR_VIEW,
235 	BACKBUFFER_DEPTH_VIEW,
236 	BACKBUFFER_COLOR_TEX,
237 	BACKBUFFER_DEPTH_TEX,
238 	FEATURE_LEVEL,
239 	COMPATIBLE_RENDERPASS,
240 	BACKBUFFER_RENDERPASS,
241 	FRAMEBUFFER_RENDERPASS,
242 	INIT_COMMANDBUFFER,
243 	BOUND_TEXTURE0_IMAGEVIEW,
244 	BOUND_TEXTURE1_IMAGEVIEW,
245 	RENDER_MANAGER,
246 	NULL_IMAGEVIEW,
247 };
248 
249 enum FBChannel {
250 	FB_COLOR_BIT = 1,
251 	FB_DEPTH_BIT = 2,
252 	FB_STENCIL_BIT = 4,
253 
254 	// Implementation specific
255 	FB_SURFACE_BIT = 32,  // Used in conjunction with the others in D3D9 to get surfaces through get_api_texture
256 	FB_VIEW_BIT = 64,     // Used in conjunction with the others in D3D11 to get shader resource views through get_api_texture
257 	FB_FORMAT_BIT = 128,  // Actually retrieves the native format instead. D3D11 only.
258 };
259 
260 enum FBBlitFilter {
261 	FB_BLIT_NEAREST = 0,
262 	FB_BLIT_LINEAR = 1,
263 };
264 
265 enum UpdateBufferFlags {
266 	UPDATE_DISCARD = 1,
267 };
268 
269 enum class Event {
270 	// These happen on D3D resize. Only the backbuffer needs to be resized.
271 	LOST_BACKBUFFER,
272 	GOT_BACKBUFFER,
273 
274 	// These are a bit more serious...
275 	LOST_DEVICE,
276 	GOT_DEVICE,
277 
278 	RESIZED,
279 	PRESENTED,
280 };
281 
282 constexpr uint32_t MAX_TEXTURE_SLOTS = 3;
283 
284 struct FramebufferDesc {
285 	int width;
286 	int height;
287 	int depth;
288 	int numColorAttachments;
289 	bool z_stencil;
290 	const char *tag;  // For graphics debuggers
291 };
292 
293 // Binary compatible with D3D11 viewport.
294 struct Viewport {
295 	float TopLeftX;
296 	float TopLeftY;
297 	float Width;
298 	float Height;
299 	float MinDepth;
300 	float MaxDepth;
301 };
302 
303 class Bugs {
304 public:
Has(uint32_t bug)305 	bool Has(uint32_t bug) const {
306 		return (flags_ & (1 << bug)) != 0;
307 	}
Infest(uint32_t bug)308 	void Infest(uint32_t bug) {
309 		flags_ |= (1 << bug);
310 	}
311 
312 	enum : uint32_t {
313 		NO_DEPTH_CANNOT_DISCARD_STENCIL = 0,
314 		DUAL_SOURCE_BLENDING_BROKEN = 1,
315 		ANY_MAP_BUFFER_RANGE_SLOW = 2,
316 		PVR_GENMIPMAP_HEIGHT_GREATER = 3,
317 		BROKEN_NAN_IN_CONDITIONAL = 4,
318 		COLORWRITEMASK_BROKEN_WITH_DEPTHTEST = 5,
319 		BROKEN_FLAT_IN_SHADER = 6,
320 	};
321 
322 protected:
323 	uint32_t flags_ = 0;
324 };
325 
326 class RefCountedObject {
327 public:
RefCountedObject()328 	RefCountedObject() {
329 		refcount_ = 1;
330 	}
~RefCountedObject()331 	virtual ~RefCountedObject() {}
332 
AddRef()333 	void AddRef() { refcount_++; }
334 	bool Release();
335 	bool ReleaseAssertLast();
336 
337 private:
338 	std::atomic<int> refcount_;
339 };
340 
341 template <typename T>
342 struct AutoRef {
AutoRefAutoRef343 	AutoRef() {
344 	}
AutoRefAutoRef345 	explicit AutoRef(T *p) {
346 		ptr = p;
347 		if (ptr)
348 			ptr->AddRef();
349 	}
AutoRefAutoRef350 	AutoRef(const AutoRef<T> &p) {
351 		*this = p.ptr;
352 	}
~AutoRefAutoRef353 	~AutoRef() {
354 		if (ptr)
355 			ptr->Release();
356 	}
357 
358 	T *operator =(T *p) {
359 		if (ptr)
360 			ptr->Release();
361 		ptr = p;
362 		if (ptr)
363 			ptr->AddRef();
364 		return ptr;
365 	}
366 	AutoRef<T> &operator =(const AutoRef<T> &p) {
367 		*this = p.ptr;
368 		return *this;
369 	}
370 
371 	T *operator->() const {
372 		return ptr;
373 	}
374 	operator T *() {
375 		return ptr;
376 	}
377 
378 	T *ptr = nullptr;
379 };
380 
381 class BlendState : public RefCountedObject {
382 public:
383 };
384 
385 class SamplerState : public RefCountedObject {
386 public:
387 };
388 
389 class DepthStencilState : public RefCountedObject {
390 public:
391 };
392 
393 class Framebuffer : public RefCountedObject {
394 public:
Width()395 	int Width() { return width_; }
Height()396 	int Height() { return height_; }
397 protected:
398 	int width_ = -1, height_ = -1;
399 };
400 
401 class Buffer : public RefCountedObject {
402 public:
403 };
404 
405 class Texture : public RefCountedObject {
406 public:
Width()407 	int Width() { return width_; }
Height()408 	int Height() { return height_; }
Depth()409 	int Depth() { return depth_; }
410 protected:
411 	int width_ = -1, height_ = -1, depth_ = -1;
412 };
413 
414 struct BindingDesc {
415 	int stride;
416 	bool instanceRate;
417 };
418 
419 struct AttributeDesc {
420 	int binding;
421 	int location;  // corresponds to semantic
422 	DataFormat format;
423 	int offset;
424 };
425 
426 struct InputLayoutDesc {
427 	std::vector<BindingDesc> bindings;
428 	std::vector<AttributeDesc> attributes;
429 };
430 
431 class InputLayout : public RefCountedObject { };
432 
433 // Uniform types have moved to Shader.h.
434 
435 class ShaderModule : public RefCountedObject {
436 public:
437 	virtual ShaderStage GetStage() const = 0;
438 };
439 
440 class Pipeline : public RefCountedObject {
441 public:
~Pipeline()442 	virtual ~Pipeline() {}
443 	virtual bool RequiresBuffer() = 0;
444 };
445 
446 class RasterState : public RefCountedObject {};
447 
448 struct StencilSide {
449 	StencilOp failOp;
450 	StencilOp passOp;
451 	StencilOp depthFailOp;
452 	Comparison compareOp;
453 	uint8_t compareMask;
454 	uint8_t writeMask;
455 };
456 
457 struct DepthStencilStateDesc {
458 	bool depthTestEnabled;
459 	bool depthWriteEnabled;
460 	Comparison depthCompare;
461 	bool stencilEnabled;
462 	StencilSide front;
463 	StencilSide back;
464 };
465 
466 struct BlendStateDesc {
467 	bool enabled;
468 	int colorMask;
469 	BlendFactor srcCol;
470 	BlendFactor dstCol;
471 	BlendOp eqCol;
472 	BlendFactor srcAlpha;
473 	BlendFactor dstAlpha;
474 	BlendOp eqAlpha;
475 	bool logicEnabled;
476 	LogicOp logicOp;
477 };
478 
479 struct SamplerStateDesc {
480 	TextureFilter magFilter;
481 	TextureFilter minFilter;
482 	TextureFilter mipFilter;
483 	float maxAniso;
484 	TextureAddressMode wrapU;
485 	TextureAddressMode wrapV;
486 	TextureAddressMode wrapW;
487 	float maxLod;
488 	bool shadowCompareEnabled;
489 	Comparison shadowCompareFunc;
490 	BorderColor borderColor;
491 };
492 
493 struct RasterStateDesc {
494 	CullMode cull;
495 	Facing frontFace;
496 };
497 
498 struct PipelineDesc {
499 	Primitive prim;
500 	std::vector<ShaderModule *> shaders;
501 	InputLayout *inputLayout;
502 	DepthStencilState *depthStencil;
503 	BlendState *blend;
504 	RasterState *raster;
505 	const UniformBufferDesc *uniformDesc;
506 };
507 
508 struct DeviceCaps {
509 	GPUVendor vendor;
510 	uint32_t deviceID;  // use caution!
511 
512 	DataFormat preferredDepthBufferFormat;
513 	DataFormat preferredShadowMapFormatLow;
514 	DataFormat preferredShadowMapFormatHigh;
515 	bool anisoSupported;
516 	bool depthRangeMinusOneToOne;  // OpenGL style depth
517 	bool geometryShaderSupported;
518 	bool tesselationShaderSupported;
519 	bool multiViewport;
520 	bool dualSourceBlend;
521 	bool logicOpSupported;
522 	bool depthClampSupported;
523 	bool framebufferCopySupported;
524 	bool framebufferBlitSupported;
525 	bool framebufferDepthCopySupported;
526 	bool framebufferDepthBlitSupported;
527 	bool framebufferFetchSupported;
528 	std::string deviceName;  // The device name to use when creating the thin3d context, to get the same one.
529 };
530 
531 // Use to write data directly to texture memory.  initData is the pointer passed in TextureDesc.
532 // Important: only write to the provided pointer, don't read from it.
533 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;
534 
535 struct TextureDesc {
536 	TextureType type;
537 	DataFormat format;
538 	int width;
539 	int height;
540 	int depth;
541 	int mipLevels;
542 	bool generateMips;
543 	// Optional, for tracking memory usage and graphcis debuggers.
544 	const char *tag;
545 	// Does not take ownership over pointed-to data.
546 	std::vector<const uint8_t *> initData;
547 	TextureCallback initDataCallback;
548 };
549 
550 enum class RPAction {
551 	DONT_CARE,
552 	CLEAR,
553 	KEEP,
554 };
555 
556 struct RenderPassInfo {
557 	RPAction color;
558 	RPAction depth;
559 	RPAction stencil;
560 	uint32_t clearColor;
561 	float clearDepth;
562 	uint8_t clearStencil;
563 	const char *tag;
564 };
565 
566 class DrawContext {
567 public:
568 	virtual ~DrawContext();
569 	bool CreatePresets();
570 	void DestroyPresets();
571 
GetBugs()572 	Bugs GetBugs() const { return bugs_; }
573 
574 	virtual const DeviceCaps &GetDeviceCaps() const = 0;
575 	virtual uint32_t GetDataFormatSupport(DataFormat fmt) const = 0;
GetFeatureList()576 	virtual std::vector<std::string> GetFeatureList() const { return std::vector<std::string>(); }
GetExtensionList()577 	virtual std::vector<std::string> GetExtensionList() const { return std::vector<std::string>(); }
GetDeviceList()578 	virtual std::vector<std::string> GetDeviceList() const { return std::vector<std::string>(); }
579 
580 	// Describes the primary shader language that this implementation prefers.
GetShaderLanguageDesc()581 	const ShaderLanguageDesc &GetShaderLanguageDesc() {
582 		return shaderLanguageDesc_;
583 	}
584 
585 	virtual uint32_t GetSupportedShaderLanguages() const = 0;
586 
SetErrorCallback(ErrorCallbackFn callback,void * userdata)587 	virtual void SetErrorCallback(ErrorCallbackFn callback, void *userdata) {}
588 
589 	// Partial pipeline state, used to create pipelines. (in practice, in d3d11 they'll use the native state objects directly).
590 	virtual DepthStencilState *CreateDepthStencilState(const DepthStencilStateDesc &desc) = 0;
591 	virtual BlendState *CreateBlendState(const BlendStateDesc &desc) = 0;
592 	virtual SamplerState *CreateSamplerState(const SamplerStateDesc &desc) = 0;
593 	virtual RasterState *CreateRasterState(const RasterStateDesc &desc) = 0;
594 	// virtual ComputePipeline CreateComputePipeline(const ComputePipelineDesc &desc) = 0
595 	virtual InputLayout *CreateInputLayout(const InputLayoutDesc &desc) = 0;
596 
597 	// Note that these DO NOT AddRef so you must not ->Release presets unless you manually AddRef them.
GetVshaderPreset(VertexShaderPreset preset)598 	ShaderModule *GetVshaderPreset(VertexShaderPreset preset) { return vsPresets_[preset]; }
GetFshaderPreset(FragmentShaderPreset preset)599 	ShaderModule *GetFshaderPreset(FragmentShaderPreset preset) { return fsPresets_[preset]; }
600 
601 	// Resources
602 	virtual Buffer *CreateBuffer(size_t size, uint32_t usageFlags) = 0;
603 	// Does not take ownership over pointed-to initData. After this returns, can dispose of it.
604 	virtual Texture *CreateTexture(const TextureDesc &desc) = 0;
605 	// On some hardware, you might get a 24-bit depth buffer even though you only wanted a 16-bit one.
606 	virtual Framebuffer *CreateFramebuffer(const FramebufferDesc &desc) = 0;
607 
608 	virtual ShaderModule *CreateShaderModule(ShaderStage stage, ShaderLanguage language, const uint8_t *data, size_t dataSize, const std::string &tag = "thin3d") = 0;
609 	virtual Pipeline *CreateGraphicsPipeline(const PipelineDesc &desc) = 0;
610 
611 	// 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.
612 	virtual void UpdateBuffer(Buffer *buffer, const uint8_t *data, size_t offset, size_t size, UpdateBufferFlags flags) = 0;
613 
614 	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;
615 	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;
CopyFramebufferToMemorySync(Framebuffer * src,int channelBits,int x,int y,int w,int h,Draw::DataFormat format,void * pixels,int pixelStride,const char * tag)616 	virtual bool CopyFramebufferToMemorySync(Framebuffer *src, int channelBits, int x, int y, int w, int h, Draw::DataFormat format, void *pixels, int pixelStride, const char *tag) {
617 		return false;
618 	}
PreferredFramebufferReadbackFormat(Framebuffer * src)619 	virtual DataFormat PreferredFramebufferReadbackFormat(Framebuffer *src) {
620 		return DataFormat::R8G8B8A8_UNORM;
621 	}
622 
623 	// These functions should be self explanatory.
624 	// Binding a zero render target means binding the backbuffer.
625 	virtual void BindFramebufferAsRenderTarget(Framebuffer *fbo, const RenderPassInfo &rp, const char *tag) = 0;
626 	virtual Framebuffer *GetCurrentRenderTarget() = 0;
627 
628 	// binding must be < MAX_TEXTURE_SLOTS (0, 1 are okay if it's 2).
629 	virtual void BindFramebufferAsTexture(Framebuffer *fbo, int binding, FBChannel channelBit, int attachment) = 0;
630 
631 	// deprecated
GetFramebufferAPITexture(Framebuffer * fbo,int channelBits,int attachment)632 	virtual uintptr_t GetFramebufferAPITexture(Framebuffer *fbo, int channelBits, int attachment) {
633 		return 0;
634 	}
635 
636 	virtual void GetFramebufferDimensions(Framebuffer *fbo, int *w, int *h) = 0;
637 
638 	// Useful in OpenGL ES to give hints about framebuffers on tiler GPUs.
InvalidateFramebuffer(Framebuffer * fbo)639 	virtual void InvalidateFramebuffer(Framebuffer *fbo) {}
640 
641 	// Dynamic state
642 	virtual void SetScissorRect(int left, int top, int width, int height) = 0;
643 	virtual void SetViewports(int count, Viewport *viewports) = 0;
644 	virtual void SetBlendFactor(float color[4]) = 0;
645 	virtual void SetStencilRef(uint8_t ref) = 0;
646 
647 	virtual void BindSamplerStates(int start, int count, SamplerState **state) = 0;
648 	virtual void BindTextures(int start, int count, Texture **textures) = 0;
649 	virtual void BindVertexBuffers(int start, int count, Buffer **buffers, const int *offsets) = 0;
650 	virtual void BindIndexBuffer(Buffer *indexBuffer, int offset) = 0;
651 
652 	// Only supports a single dynamic uniform buffer, for maximum compatibility with the old APIs and ease of emulation.
653 	// More modern methods will be added later.
654 	virtual void UpdateDynamicUniformBuffer(const void *ub, size_t size) = 0;
655 
BindTexture(int stage,Texture * texture)656 	void BindTexture(int stage, Texture *texture) {
657 		Texture *textures[1] = { texture };
658 		BindTextures(stage, 1, textures);
659 	}  // from sampler 0 and upwards
660 
661 	// Clear state cached within thin3d. Must be called after directly calling API functions.
662 	// Note that framebuffer state (which framebuffer is bounds) may not be cached.
663 	// Must not actually perform any API calls itself since this can be called when no framebuffer is bound for rendering.
664 	virtual void InvalidateCachedState() = 0;
665 
666 	virtual void BindPipeline(Pipeline *pipeline) = 0;
667 
668 	virtual void Draw(int vertexCount, int offset) = 0;
669 	virtual void DrawIndexed(int vertexCount, int offset) = 0;  // Always 16-bit indices.
670 	virtual void DrawUP(const void *vdata, int vertexCount) = 0;
671 
672 	// Frame management (for the purposes of sync and resource management, necessary with modern APIs). Default implementations here.
BeginFrame()673 	virtual void BeginFrame() {}
674 	virtual void EndFrame() = 0;
WipeQueue()675 	virtual void WipeQueue() {}
676 
677 	// This should be avoided as much as possible, in favor of clearing when binding a render target, which is native
678 	// on Vulkan.
679 	virtual void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) = 0;
680 
681 	// Necessary to correctly flip scissor rectangles etc for OpenGL.
SetTargetSize(int w,int h)682 	virtual void SetTargetSize(int w, int h) {
683 		targetWidth_ = w;
684 		targetHeight_ = h;
685 	}
686 
687 	virtual std::string GetInfoString(InfoField info) const = 0;
688 	virtual uint64_t GetNativeObject(NativeObject obj) = 0;
689 
690 	virtual void HandleEvent(Event ev, int width, int height, void *param1 = nullptr, void *param2 = nullptr) = 0;
691 
692 	// Flush state like scissors etc so the caller can do its own custom drawing.
FlushState()693 	virtual void FlushState() {}
694 
695 	virtual int GetCurrentStepId() const = 0;
696 
697 protected:
698 	ShaderModule *vsPresets_[VS_MAX_PRESET];
699 	ShaderModule *fsPresets_[FS_MAX_PRESET];
700 
701 	ShaderLanguageDesc shaderLanguageDesc_;
702 
703 	int targetWidth_;
704 	int targetHeight_;
705 
706 	Bugs bugs_;
707 };
708 
709 extern const UniformBufferDesc UBPresetDesc;
710 
711 // UBs for the preset shaders
712 
713 struct VsTexColUB {
714 	float WorldViewProj[16];
715 };
716 extern const UniformBufferDesc vsTexColBufDesc;
717 struct VsColUB {
718 	float WorldViewProj[16];
719 };
720 extern const UniformBufferDesc vsColBufDesc;
721 
722 // Useful utility for specifying a shader in multiple languages.
723 
724 struct ShaderSource {
725 	ShaderLanguage lang;
726 	const char *src;
727 };
728 
729 ShaderModule *CreateShader(DrawContext *draw, ShaderStage stage, const std::vector<ShaderSource> &sources);
730 
731 }  // namespace Draw
732