Grindstone Game Engine v0.2.0
An open source game engine and toolkit.
Loading...
Searching...
No Matches
Formats.hpp
1#pragma once
2
3#include <vector>
4#include <utility>
5#include <stdint.h>
6
7namespace Grindstone::GraphicsAPI {
12 union ClearColor {
13 float float32[4];
14 int32_t int32[4];
15 uint32_t uint32[4];
16
17 ClearColor() : float32{ 0.0f, 0.0f, 0.0f, 0.0f } {};
18 ClearColor(float* v) : float32{ v[0], v[1], v[2], v[3] } {};
19 ClearColor(int32_t* v) : int32{ v[0], v[1], v[2], v[3] } {};
20 ClearColor(uint32_t* v) : uint32{ v[0], v[1], v[2], v[3] } {};
21
22 ClearColor(float r, float g, float b, float a) : float32{ r, g, b, a } {};
23 ClearColor(int32_t r, int32_t g, int32_t b, int32_t a) : int32{ r, g, b, a } {};
24 ClearColor(uint32_t r, uint32_t g, uint32_t b, uint32_t a) : uint32{ r, g, b, a } {};
25
26 ClearColor(const ClearColor& other) : uint32{ other.uint32[0], other.uint32[1] , other.uint32[2] , other.uint32[3] } {};
27
28 ClearColor& operator=(const ClearColor& other) {
29 float32[0] = other.float32[0];
30 float32[1] = other.float32[1];
31 float32[2] = other.float32[2];
32 float32[3] = other.float32[3];
33 return *this;
34 };
35
36 ~ClearColor() = default;
37 };
38
39 // Clear values for the DepthStencilImage.
41 float depth = 0.f;
42 uint32_t stencil = 0;
43 };
44
45 // A union of ClearColor and ClearDepthStencil.
46 union ClearUnion {
47 ClearColor color;
49
50 ClearUnion() : color() {}
51 ClearUnion(ClearColor value) : color(value) {}
52 ClearUnion(ClearDepthStencil value) : depth(value) {}
53
54 ClearUnion(const ClearUnion& other) : color(other.color) {}
55
56 ClearUnion& operator=(const ClearUnion& other) {
57 color = other.color;
58 return *this;
59 };
60 };
61
62 enum class LoadOp {
63 Load = 0,
64 Clear,
65 DontCare
66 };
67
68 enum class StoreOp {
69 Store = 0,
70 DontCare
71 };
72
73 enum class TextureWrapMode : uint8_t {
74 Repeat = 0,
75 ClampToEdge,
76 ClampToBorder,
77 MirroredRepeat,
78 MirroredClampToEdge
79 };
80
81 enum class TextureFilter : uint8_t {
82 Nearest = 0,
83 Linear
84 };
85
86 enum class ClearMode : uint8_t {
87 Color = 1,
88 Depth = 2,
89 ColorAndDepth = 3,
90 Stencil = 4,
91 All = 7
92 };
93
94 enum class ImageLayout : uint8_t {
95 Undefined, // For newly created or discarded images
96 General, // For compute or unordered read/write
97 ColorAttachment, // Render target output
98 DepthWrite, // Depth write access
99 DepthRead, // Depth sampled (read-only)
100 ShaderRead, // Sampled image (color or depth)
101 TransferSrc, // Used as a copy/blit source
102 TransferDst, // Used as a copy/blit destination
103 Present, // Presented to screen
104 };
105
106 enum class MemoryUsage {
107 GPUOnly, // Device-local VRAM, inaccessible to CPU.
108 CPUToGPU, // Host-visible upload buffer (CPU writes, GPU reads)
109 GPUToCPU, // Host-visible readback buffer (GPU writes, CPU reads)
110 CPUOnly, // Host-visible, used as staging/upload/readback
111 Transient, // Transient GPU memory (tile memory / renderpass-only)
112 };
113
114 enum class ImageDimension {
115 Invalid,
116 Dimension1D,
117 Dimension2D,
118 Dimension3D
119 };
120
121 enum class ImageAspectBits : uint16_t {
122 None = 0,
123 Color = 0x00000001,
124 Depth = 0x00000002,
125 Stencil = 0x00000004,
126 Metadata = 0x00000008,
127 Plane0 = 0x00000010,
128 Plane1 = 0x00000020,
129 Plane2 = 0x00000040,
130 MemoryPlane0 = 0x00000080,
131 MemoryPlane1 = 0x00000100,
132 MemoryPlane2 = 0x00000200,
133 MemoryPlane3 = 0x00000400,
134 };
135
136 inline ImageAspectBits operator|(ImageAspectBits a, ImageAspectBits b) {
137 return static_cast<ImageAspectBits>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
138 }
139
140 inline ImageAspectBits& operator|=(ImageAspectBits& a, ImageAspectBits b) {
141 a = a | b;
142 return a;
143 }
144
145 enum class PipelineStageBit : uint32_t {
146 None = 0,
147 TopOfPipe = 0x00000001,
148 DrawIndirect = 0x00000002,
149 VertexInput = 0x00000004,
150 VertexShader = 0x00000008,
151 TesslationControlShader = 0x00000010,
152 TesselationEvaluationShader = 0x00000020,
153 GeometryShader = 0x00000040,
154 FragmentShader = 0x00000080,
155 EarlyFragmentTests = 0x00000100,
156 LateFragmentTests = 0x00000200,
157 ColorAttachmentOutput = 0x00000400,
158 ComputeShader = 0x00000800,
159 Transfer = 0x00001000,
160 BottomOfPipe = 0x00002000,
161 Host = 0x00004000,
162 AllGraphics = 0x00008000,
163 AllCommands = 0x00010000,
164 TransformFeedback = 0x01000000,
165 ConditionalRendering = 0x00040000,
166 AccelerationStructureBuild = 0x02000000,
167 RayTracingShader = 0x00200000,
168 FragmentDensityProcess = 0x00800000,
169 FragmentShaderRateAttachment = 0x00400000,
170 CommandPreprocess = 0x00020000,
171 TaskShader = 0x00080000,
172 MeshShader = 0x00100000,
173 };
174
175 inline PipelineStageBit operator|(PipelineStageBit a, PipelineStageBit b) {
176 return static_cast<PipelineStageBit>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
177 }
178
179 inline PipelineStageBit& operator|=(PipelineStageBit& a, PipelineStageBit b) {
180 a = a | b;
181 return a;
182 }
183
184 enum class Format {
185 Invalid,
186 R4G4_UNORM_PACK8,
187 R4G4B4A4_UNORM_PACK16,
188 B4G4R4A4_UNORM_PACK16,
189 R5G6B5_UNORM_PACK16,
190 B5G6R5_UNORM_PACK16,
191 R5G5B5A1_UNORM_PACK16,
192 B5G5R5A1_UNORM_PACK16,
193 A1R5G5B5_UNORM_PACK16,
194 R8_UNORM,
195 R8_SNORM,
196 R8_USCALED,
197 R8_SSCALED,
198 R8_UINT,
199 R8_SINT,
200 R8_SRGB,
201 R8G8_UNORM,
202 R8G8_SNORM,
203 R8G8_USCALED,
204 R8G8_SSCALED,
205 R8G8_UINT,
206 R8G8_SINT,
207 R8G8_SRGB,
208 R8G8B8_UNORM,
209 R8G8B8_SNORM,
210 R8G8B8_USCALED,
211 R8G8B8_SSCALED,
212 R8G8B8_UINT,
213 R8G8B8_SINT,
214 R8G8B8_SRGB,
215 B8G8R8_UNORM,
216 B8G8R8_SNORM,
217 B8G8R8_USCALED,
218 B8G8R8_SSCALED,
219 B8G8R8_UINT,
220 B8G8R8_SINT,
221 B8G8R8_SRGB,
222 R8G8B8A8_UNORM,
223 R8G8B8A8_SNORM,
224 R8G8B8A8_USCALED,
225 R8G8B8A8_SSCALED,
226 R8G8B8A8_UINT,
227 R8G8B8A8_SINT,
228 R8G8B8A8_SRGB,
229 B8G8R8A8_UNORM,
230 B8G8R8A8_SNORM,
231 B8G8R8A8_USCALED,
232 B8G8R8A8_SSCALED,
233 B8G8R8A8_UINT,
234 B8G8R8A8_SINT,
235 B8G8R8A8_SRGB,
236 A8B8G8R8_UNORM_PACK32,
237 A8B8G8R8_SNORM_PACK32,
238 A8B8G8R8_USCALED_PACK32,
239 A8B8G8R8_SSCALED_PACK32,
240 A8B8G8R8_UINT_PACK32,
241 A8B8G8R8_SINT_PACK32,
242 A8B8G8R8_SRGB_PACK32,
243 A2R10G10B10_UNORM_PACK32,
244 A2R10G10B10_SNORM_PACK32,
245 A2R10G10B10_USCALED_PACK32,
246 A2R10G10B10_SSCALED_PACK32,
247 A2R10G10B10_UINT_PACK32,
248 A2R10G10B10_SINT_PACK32,
249 A2B10G10R10_UNORM_PACK32,
250 A2B10G10R10_SNORM_PACK32,
251 A2B10G10R10_USCALED_PACK32,
252 A2B10G10R10_SSCALED_PACK32,
253 A2B10G10R10_UINT_PACK32,
254 A2B10G10R10_SINT_PACK32,
255 R16_UNORM,
256 R16_SNORM,
257 R16_USCALED,
258 R16_SSCALED,
259 R16_UINT,
260 R16_SINT,
261 R16_SFLOAT,
262 R16G16_UNORM,
263 R16G16_SNORM,
264 R16G16_USCALED,
265 R16G16_SSCALED,
266 R16G16_UINT,
267 R16G16_SINT,
268 R16G16_SFLOAT,
269 R16G16B16_UNORM,
270 R16G16B16_SNORM,
271 R16G16B16_USCALED,
272 R16G16B16_SSCALED,
273 R16G16B16_UINT,
274 R16G16B16_SINT,
275 R16G16B16_SFLOAT,
276 R16G16B16A16_UNORM,
277 R16G16B16A16_SNORM,
278 R16G16B16A16_USCALED,
279 R16G16B16A16_SSCALED,
280 R16G16B16A16_UINT,
281 R16G16B16A16_SINT,
282 R16G16B16A16_SFLOAT,
283 R32_UINT,
284 R32_SINT,
285 R32_SFLOAT,
286 R32G32_UINT,
287 R32G32_SINT,
288 R32G32_SFLOAT,
289 R32G32B32_UINT,
290 R32G32B32_SINT,
291 R32G32B32_SFLOAT,
292 R32G32B32A32_UINT,
293 R32G32B32A32_SINT,
294 R32G32B32A32_SFLOAT,
295 R64_UINT,
296 R64_SINT,
297 R64_SFLOAT,
298 R64G64_UINT,
299 R64G64_SINT,
300 R64G64_SFLOAT,
301 R64G64B64_UINT,
302 R64G64B64_SINT,
303 R64G64B64_SFLOAT,
304 R64G64B64A64_UINT,
305 R64G64B64A64_SINT,
306 R64G64B64A64_SFLOAT,
307 B10G11R11_UFLOAT_PACK32,
308 E5B9G9R9_UFLOAT_PACK32,
309
310 D16_UNORM,
311 X8_D24_UNORM_PACK32,
312 D32_SFLOAT,
313 S8_UINT,
314 D16_UNORM_S8_UINT,
315 D24_UNORM_S8_UINT,
316 D32_SFLOAT_S8_UINT,
317
318 BC1_RGB_UNORM_BLOCK,
319 BC1_RGB_SRGB_BLOCK,
320 BC1_RGBA_UNORM_BLOCK,
321 BC1_RGBA_SRGB_BLOCK,
322 BC2_UNORM_BLOCK,
323 BC2_SRGB_BLOCK,
324 BC3_UNORM_BLOCK,
325 BC3_SRGB_BLOCK,
326 BC4_UNORM_BLOCK,
327 BC4_SNORM_BLOCK,
328 BC5_UNORM_BLOCK,
329 BC5_SNORM_BLOCK,
330 BC6H_UFLOAT_BLOCK,
331 BC6H_SFLOAT_BLOCK,
332 BC7_UNORM_BLOCK,
333 BC7_SRGB_BLOCK,
334 ETC2_R8G8B8_UNORM_BLOCK,
335 ETC2_R8G8B8_SRGB_BLOCK,
336 ETC2_R8G8B8A1_UNORM_BLOCK,
337 ETC2_R8G8B8A1_SRGB_BLOCK,
338 ETC2_R8G8B8A8_UNORM_BLOCK,
339 ETC2_R8G8B8A8_SRGB_BLOCK,
340 EAC_R11_UNORM_BLOCK,
341 EAC_R11_SNORM_BLOCK,
342 EAC_R11G11_UNORM_BLOCK,
343 EAC_R11G11_SNORM_BLOCK,
344 ASTC_4x4_UNORM_BLOCK,
345 ASTC_4x4_SRGB_BLOCK,
346 ASTC_5x4_UNORM_BLOCK,
347 ASTC_5x4_SRGB_BLOCK,
348 ASTC_5x5_UNORM_BLOCK,
349 ASTC_5x5_SRGB_BLOCK,
350 ASTC_6x5_UNORM_BLOCK,
351 ASTC_6x5_SRGB_BLOCK,
352 ASTC_6x6_UNORM_BLOCK,
353 ASTC_6x6_SRGB_BLOCK,
354 ASTC_8x5_UNORM_BLOCK,
355 ASTC_8x5_SRGB_BLOCK,
356 ASTC_8x6_UNORM_BLOCK,
357 ASTC_8x6_SRGB_BLOCK,
358 ASTC_8x8_UNORM_BLOCK,
359 ASTC_8x8_SRGB_BLOCK,
360 ASTC_10x5_UNORM_BLOCK,
361 ASTC_10x5_SRGB_BLOCK,
362 ASTC_10x6_UNORM_BLOCK,
363 ASTC_10x6_SRGB_BLOCK,
364 ASTC_10x8_UNORM_BLOCK,
365 ASTC_10x8_SRGB_BLOCK,
366 ASTC_10x10_UNORM_BLOCK,
367 ASTC_10x10_SRGB_BLOCK,
368 ASTC_12x10_UNORM_BLOCK,
369 ASTC_12x10_SRGB_BLOCK,
370 ASTC_12x12_UNORM_BLOCK,
371 ASTC_12x12_SRGB_BLOCK,
372 G8B8G8R8_422_UNORM,
373 B8G8R8G8_422_UNORM,
374 G8_B8_R8_3PLANE_420_UNORM,
375 G8_B8R8_2PLANE_420_UNORM,
376 G8_B8_R8_3PLANE_422_UNORM,
377 G8_B8R8_2PLANE_422_UNORM,
378 G8_B8_R8_3PLANE_444_UNORM,
379 R10X6_UNORM_PACK16,
380 R10X6G10X6_UNORM_2PACK16,
381 R10X6G10X6B10X6A10X6_UNORM_4PACK16,
382 G10X6B10X6G10X6R10X6_422_UNORM_4PACK16,
383 B10X6G10X6R10X6G10X6_422_UNORM_4PACK16,
384 G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16,
385 G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16,
386 G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16,
387 G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16,
388 G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16,
389 R12X4_UNORM_PACK16,
390 R12X4G12X4_UNORM_2PACK16,
391 R12X4G12X4B12X4A12X4_UNORM_4PACK16,
392 G12X4B12X4G12X4R12X4_422_UNORM_4PACK16,
393 B12X4G12X4R12X4G12X4_422_UNORM_4PACK16,
394 G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16,
395 G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16,
396 G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16,
397 G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16,
398 G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16,
399 G16B16G16R16_422_UNORM,
400 B16G16R16G16_422_UNORM,
401 G16_B16_R16_3PLANE_420_UNORM,
402 G16_B16R16_2PLANE_420_UNORM,
403 G16_B16_R16_3PLANE_422_UNORM,
404 G16_B16R16_2PLANE_422_UNORM,
405 G16_B16_R16_3PLANE_444_UNORM,
406 G8_B8R8_2PLANE_444_UNORM,
407 G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16,
408 G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16,
409 G16_B16R16_2PLANE_444_UNORM,
410 A4R4G4B4_UNORM_PACK16,
411 A4B4G4R4_UNORM_PACK16,
412 ASTC_4x4_SFLOAT,
413 ASTC_5x4_SFLOAT,
414 ASTC_5x5_SFLOAT,
415 ASTC_6x5_SFLOAT,
416 ASTC_6x6_SFLOAT,
417 ASTC_8x5_SFLOAT,
418 ASTC_8x6_SFLOAT,
419 ASTC_8x8_SFLOAT,
420 ASTC_10x5_SFLOAT,
421 ASTC_10x6_SFLOAT,
422 ASTC_10x8_SFLOAT,
423 ASTC_10x10_SFLOAT,
424 ASTC_12x10_SFLOAT,
425 ASTC_12x12_SFLOAT,
426 PVRTC1_2BPP_UNORM,
427 PVRTC1_4BPP_UNORM,
428 PVRTC2_2BPP_UNORM,
429 PVRTC2_4BPP_UNORM,
430 PVRTC1_2BPP_SRGB,
431 PVRTC1_4BPP_SRGB,
432 PVRTC2_2BPP_SRGB,
433 PVRTC2_4BPP_SRGB,
434
435 // Limited Support:
436 R16G16_S10_5,
437 A1B5G5R5_UNORM_PACK16,
438 A8_UNORM,
439 };
440
441 enum class FormatDepthStencilType : uint8_t {
442 NotDepthStencil = 0,
443 Depth = 1 << 0,
444 Stencil = 1 << 1,
445 DepthStencil = static_cast<uint8_t>(FormatDepthStencilType::Depth) | static_cast<uint8_t>(FormatDepthStencilType::Stencil)
446 };
447
448 FormatDepthStencilType GetFormatDepthStencilType(Format format);
449 bool IsFormatCompressed(Format format);
450 uint8_t GetCompressedFormatBlockSize(Format format);
451 uint8_t GetFormatBytesPerPixel(Grindstone::GraphicsAPI::Format format);
452
453 #define SHADER_STAGE_TYPES \
454 GSExpandEntry(Vertex, 1 << 0),\
455 GSExpandEntry(TesselationEvaluation, 1 << 1),\
456 GSExpandEntry(TesselationControl, 1 << 2),\
457 GSExpandEntry(Geometry, 1 << 3),\
458 GSExpandEntry(Fragment, 1 << 4),\
459 GSExpandEntry(Task, 1 << 5),\
460 GSExpandEntry(Mesh, 1 << 6),\
461 GSExpandEntry(Compute, 1 << 7)
462
463 enum class ShaderStage : uint8_t {
464 #define GSExpandEntry(key, bit) key
465 SHADER_STAGE_TYPES,
466 #undef GSExpandEntry
467 GraphicsCount = Compute,
468 Count
469 };
470
471 constexpr uint8_t numShaderGraphicStage = static_cast<uint8_t>(ShaderStage::GraphicsCount);
472 constexpr uint8_t numShaderTotalStage = static_cast<uint8_t>(ShaderStage::Count);
473
474 enum class ShaderStageBit : uint8_t {
475 None = 0,
476#define GSExpandEntry(key, bit) key = bit
477 SHADER_STAGE_TYPES,
478#undef GSExpandEntry
479 AllGraphics = Vertex | TesselationEvaluation | TesselationControl | Geometry | Fragment | Task | Mesh,
480 All = AllGraphics | Compute
481 };
482
483 constexpr const char* shaderStageNames[] = {
484 #define GSExpandEntry(key, bit) #key
485 SHADER_STAGE_TYPES
486 #undef GSExpandEntry
487 };
488
489 inline const char* GetShaderStageName(Grindstone::GraphicsAPI::ShaderStage stage) {
490 uint8_t index = static_cast<uint8_t>(stage);
491 if (index >= static_cast<uint8_t>(ShaderStage::Count)) {
492 return "Invalid";
493 }
494
495 return shaderStageNames[index];
496 }
497
498 enum class BindingType {
499 None,
500 Sampler,
501 CombinedImageSampler,
502 SampledImage,
503 StorageImage,
504 UniformTexelBuffer,
505 StorageTexelBuffer,
506 UniformBuffer,
507 StorageBuffer,
508 UniformBufferDynamic,
509 StorageBufferDynamic,
510 AccelerationStructure
511 };
512
513#define BLEND_OPERATIONS_LIST \
514 GSExpandEntry(None),\
515 GSExpandEntry(Add),\
516 GSExpandEntry(Subtract),\
517 GSExpandEntry(ReverseSubtract),\
518 GSExpandEntry(Minimum),\
519 GSExpandEntry(Maximum),\
520 GSExpandEntry(Zero),\
521 GSExpandEntry(Source),\
522 GSExpandEntry(Destination),\
523 GSExpandEntry(SourceOver),\
524 GSExpandEntry(DestinationOver),\
525 GSExpandEntry(SourceIn),\
526 GSExpandEntry(DestinationIn),\
527 GSExpandEntry(SourceOut),\
528 GSExpandEntry(DestinationOut),\
529 GSExpandEntry(SourceAtop),\
530 GSExpandEntry(DestinationAtop),\
531 GSExpandEntry(XOR),\
532 GSExpandEntry(Multiply),\
533 GSExpandEntry(Screen),\
534 GSExpandEntry(Overlay),\
535 GSExpandEntry(Darken),\
536 GSExpandEntry(Lighten),\
537 GSExpandEntry(ColorDodge),\
538 GSExpandEntry(ColorBurn),\
539 GSExpandEntry(HardLight),\
540 GSExpandEntry(SoftLight),\
541 GSExpandEntry(Difference),\
542 GSExpandEntry(Exclusion),\
543 GSExpandEntry(Invert),\
544 GSExpandEntry(InvertRGB),\
545 GSExpandEntry(LinearDodge),\
546 GSExpandEntry(LinearBurn),\
547 GSExpandEntry(VividLight),\
548 GSExpandEntry(LinearLight),\
549 GSExpandEntry(PinLight),\
550 GSExpandEntry(HardMix),\
551 GSExpandEntry(HSLHue),\
552 GSExpandEntry(HSLSaturation),\
553 GSExpandEntry(HSLColor),\
554 GSExpandEntry(HSLLuminosity),\
555 GSExpandEntry(Plus),\
556 GSExpandEntry(PlusClamped),\
557 GSExpandEntry(PlusClampedAlpha),\
558 GSExpandEntry(PlusDark),\
559 GSExpandEntry(Minus),\
560 GSExpandEntry(MinusClamped),\
561 GSExpandEntry(Contrast),\
562 GSExpandEntry(InvertOVG),\
563 GSExpandEntry(Red),\
564 GSExpandEntry(Green),\
565 GSExpandEntry(Blue)
566
567 enum class BlendOperation : uint8_t {
568#define GSExpandEntry(key) key
569 BLEND_OPERATIONS_LIST,
570#undef GSExpandEntry
571 Count
572 };
573
574 constexpr const char* blendOperationNames[] = {
575 #define GSExpandEntry(key) #key
576 BLEND_OPERATIONS_LIST
577 #undef GSExpandEntry
578 };
579
580 inline const char* GetBlendOperationName(Grindstone::GraphicsAPI::BlendOperation op) {
581 uint8_t index = static_cast<uint8_t>(op);
582 if (index >= static_cast<uint8_t>(BlendOperation::Count)) {
583 return "Invalid";
584 }
585
586 return blendOperationNames[index];
587 }
588
589
590#define BLEND_FACTORS_LIST \
591 GSExpandEntry(Zero),\
592 GSExpandEntry(One),\
593 GSExpandEntry(SrcColor),\
594 GSExpandEntry(OneMinusSrcColor),\
595 GSExpandEntry(DstColor),\
596 GSExpandEntry(OneMinusDstColor),\
597 GSExpandEntry(SrcAlpha),\
598 GSExpandEntry(OneMinusSrcAlpha),\
599 GSExpandEntry(DstAlpha),\
600 GSExpandEntry(OneMinusDstAlpha),\
601 GSExpandEntry(ConstantColor),\
602 GSExpandEntry(OneMinusConstantColor),\
603 GSExpandEntry(ConstantAlpha),\
604 GSExpandEntry(OneMinusConstantAlpha),\
605 GSExpandEntry(SrcAlphaSaturate),\
606 GSExpandEntry(Src1Color),\
607 GSExpandEntry(OneMinusSrc1Color),\
608 GSExpandEntry(Src1Alpha),\
609 GSExpandEntry(OneMinusSrc1Alpha)
610
611 enum class BlendFactor : uint8_t {
612 #define GSExpandEntry(key) key
613 BLEND_FACTORS_LIST,
614 #undef GSExpandEntry
615 Count
616 };
617
618 constexpr const char* blendFactorNames[] = {
619 #define GSExpandEntry(key) #key
620 BLEND_FACTORS_LIST
621 #undef GSExpandEntry
622 };
623
624 inline const char* GetBlendFactorName(Grindstone::GraphicsAPI::BlendFactor factor) {
625 uint8_t index = static_cast<uint8_t>(factor);
626 if (index >= static_cast<uint8_t>(BlendFactor::Count)) {
627 return "Invalid";
628 }
629
630 return blendFactorNames[index];
631 }
632
633 struct BlendData {
634 BlendOperation colorOperation = BlendOperation::None;
635 BlendFactor colorFactorSrc = BlendFactor::One;
636 BlendFactor colorFactorDst = BlendFactor::One;
637
638 BlendOperation alphaOperation = BlendOperation::None;
639 BlendFactor alphaFactorSrc = BlendFactor::One;
640 BlendFactor alphaFactorDst = BlendFactor::One;
641
642 static BlendData NoBlending() {
643 return BlendData{
644 BlendOperation::None,
645 BlendFactor::One,
646 BlendFactor::One,
647
648 BlendOperation::None,
649 BlendFactor::One,
650 BlendFactor::One
651 };
652 };
653
654 static BlendData Additive() {
655 return BlendData{
656 BlendOperation::Add,
657 BlendFactor::One,
658 BlendFactor::One,
659
660 BlendOperation::Add,
661 BlendFactor::One,
662 BlendFactor::One
663 };
664 };
665
666 static BlendData AdditiveAlpha() {
667 return BlendData{
668 BlendOperation::Add,
669 BlendFactor::SrcAlpha,
670 BlendFactor::OneMinusSrcAlpha,
671
672 BlendOperation::Add,
673 BlendFactor::One,
674 BlendFactor::OneMinusSrcAlpha
675 };
676 };
677 };
678
679#define GEOMETRY_TYPES_LIST \
680 GSExpandEntry(Points),\
681 GSExpandEntry(Lines),\
682 GSExpandEntry(LineStrips),\
683 GSExpandEntry(LineLoops),\
684 GSExpandEntry(TriangleStrips),\
685 GSExpandEntry(TriangleFans),\
686 GSExpandEntry(Triangles),\
687 GSExpandEntry(LinesAdjacency),\
688 GSExpandEntry(TrianglesAdjacency),\
689 GSExpandEntry(TriangleStripsAdjacency),\
690 GSExpandEntry(Patches)
691
692 enum class GeometryType : uint8_t {
693 #define GSExpandEntry(key) key
694 GEOMETRY_TYPES_LIST,
695 #undef GSExpandEntry
696 Count
697 };
698
699 constexpr const char* geometryTypeNames[] = {
700 #define GSExpandEntry(key) #key
701 GEOMETRY_TYPES_LIST
702 #undef GSExpandEntry
703 };
704
705 inline const char* GetGeometryTypeName(Grindstone::GraphicsAPI::GeometryType stage) {
706 uint8_t index = static_cast<uint8_t>(stage);
707 if (index >= static_cast<uint8_t>(GeometryType::Count)) {
708 return "Invalid";
709 }
710
711 return geometryTypeNames[index];
712 }
713
714 enum class PolygonFillMode : uint8_t {
715 Point,
716 Line,
717 Fill
718 };
719
720 constexpr const char* polygonFillModeNames[] = {
721 "Point",
722 "Line",
723 "Fill"
724 };
725
726 inline const char* GetPolygonFillModeName(Grindstone::GraphicsAPI::PolygonFillMode mode) {
727 uint8_t index = static_cast<uint8_t>(mode);
728 if (index > static_cast<uint8_t>(PolygonFillMode::Fill)) {
729 return "Invalid";
730 }
731
732 return polygonFillModeNames[index];
733 }
734
735 enum class CompareOperation : uint8_t {
736 Never,
737 Less,
738 Equal,
739 LessOrEqual,
740 Greater,
741 NotEqual,
742 GreaterOrEqual,
743 Always
744 };
745
746 constexpr const char* compareOperationNames[] = {
747 #define GSExpandEntry(key, bit) #key
748 SHADER_STAGE_TYPES
749 #undef GSExpandEntry
750 };
751
752 inline const char* GetCompareOperationName(Grindstone::GraphicsAPI::CompareOperation op) {
753 uint8_t index = static_cast<uint8_t>(op);
754 if (index > static_cast<uint8_t>(CompareOperation::Always)) {
755 return "Invalid";
756 }
757
758 return compareOperationNames[index];
759 }
760
761 enum class ColorMask : uint8_t {
762 None = 0,
763 Red = 0x1,
764 Green = 0x2,
765 Blue = 0x4,
766 Alpha = 0x8,
767
768 RG = Red | Green,
769 RB = Red | Blue,
770 RA = Red | Alpha,
771 GB = Green | Blue,
772 GA = Green | Alpha,
773 BA = Blue | Alpha,
774
775 RGB = Red | Green | Blue,
776 RGA = Red | Green | Alpha,
777 RBA = Red | Blue | Alpha,
778 GBA = Green | Blue | Alpha,
779
780 RGBA = Red | Green | Blue | Alpha
781 };
782
783 constexpr const char* colorMaskNames[] = {
784 "None",
785 "R",
786 "G",
787 "RG",
788 "B",
789 "RB",
790 "GB",
791 "RGB",
792 "A",
793 "RA",
794 "GA",
795 "RGA",
796 "BA",
797 "RBA",
798 "GBA",
799 "RGBA"
800 };
801
802 inline const char* GetColorMaskName(Grindstone::GraphicsAPI::ColorMask colorMask) {
803 uint8_t index = static_cast<uint8_t>(colorMask);
804 if (index > static_cast<uint8_t>(ColorMask::RGBA)) {
805 return "Invalid";
806 }
807
808 return colorMaskNames[index];
809 }
810
811 enum class CullMode : uint8_t {
812 None = 0,
813 Front,
814 Back,
815 Both
816 };
817
818 constexpr const char* cullModeNames[] = {
819 "None",
820 "Front",
821 "Back",
822 "Both"
823 };
824
825 inline const char* GetCullModeName(Grindstone::GraphicsAPI::CullMode cullMode) {
826 uint8_t index = static_cast<uint8_t>(cullMode);
827 if (index > static_cast<uint8_t>(CullMode::Both)) {
828 return "Invalid";
829 }
830
831 return cullModeNames[index];
832 }
833
834 // This refers to semantic information about how some vertex data will be used.
835 enum class AttributeUsage {
836 Position,
837 Color,
838 TexCoord0,
839 TexCoord1,
840 TexCoord2,
841 TexCoord3,
842 Normal,
843 Tangent,
844 BlendWeights,
845 BlendIndices,
846 Other
847 };
848
849 // This refers to how the buffer should be indexed.
850 enum class VertexInputRate {
851 Vertex,
852 Instance
853 };
854
855 // A structure to define a particular kind of data in a Vertex Buffer.
857 const char* name = nullptr;
858 uint32_t bindingIndex;
859 uint32_t locationIndex = 0;
860 Format format = Format::R32_SFLOAT;
861 uint32_t byteOffset = 0;
862 AttributeUsage attributeUsage = AttributeUsage::Other;
863 };
864
865 // A structure that dictates how the Vertex Buffer data is formatted.
867 uint32_t bindingIndex;
868 uint32_t stride = 0;
869 VertexInputRate inputRate = VertexInputRate::Vertex;
870 };
871
873 std::vector<VertexBindingDescription> bindings;
874 std::vector<VertexAttributeDescription> attributes;
875 };
876
877 struct VertexInputLayoutBuilder {
878 std::vector<VertexBindingDescription> bindings;
879 std::vector<VertexAttributeDescription> attributes;
880
881 VertexInputLayoutBuilder() = default;
882
884 const char* name;
885 uint32_t locationIndex;
886 Format format;
887 uint32_t byteOffset;
888 AttributeUsage attributeUsage;
889 };
890
891 VertexInputLayoutBuilder& AddBinding(
893 std::initializer_list<InlineAttribute> newAttributes
894 ) {
895 bindings.emplace_back(binding);
896 for (const InlineAttribute& attrib : newAttributes) {
897 attributes.emplace_back(VertexAttributeDescription{
898 attrib.name,
899 binding.bindingIndex,
900 attrib.locationIndex,
901 attrib.format,
902 attrib.byteOffset,
903 attrib.attributeUsage
904 });
905 }
906
907 return *this;
908 }
909
910 VertexInputLayoutBuilder& AddBinding(VertexBindingDescription binding) {
911 bindings.emplace_back(binding);
912 return *this;
913 }
914
915 VertexInputLayoutBuilder& AddAttribute(VertexAttributeDescription attribute) {
916 attributes.emplace_back(attribute);
917 return *this;
918 }
919
920 VertexInputLayout Build() {
921 return {
922 bindings,
923 attributes
924 };
925 }
926 };
927}
928
929inline Grindstone::GraphicsAPI::ShaderStageBit ToShaderStageBit(const Grindstone::GraphicsAPI::ShaderStage stage) {
930 using ShaderStageType = uint8_t;
931 return static_cast<Grindstone::GraphicsAPI::ShaderStageBit>(1 << static_cast<ShaderStageType>(stage));
932}
933
934inline Grindstone::GraphicsAPI::ShaderStageBit operator~(const Grindstone::GraphicsAPI::ShaderStageBit stages) {
935 using ShaderStageBitType = uint8_t;
936 return static_cast<Grindstone::GraphicsAPI::ShaderStageBit>(~static_cast<ShaderStageBitType>(stages));
937}
938
939inline Grindstone::GraphicsAPI::ShaderStageBit operator|(const Grindstone::GraphicsAPI::ShaderStageBit a, const Grindstone::GraphicsAPI::ShaderStageBit b) {
940 using ShaderStageBitType = uint8_t;
941 return static_cast<Grindstone::GraphicsAPI::ShaderStageBit>(static_cast<ShaderStageBitType>(a) | static_cast<ShaderStageBitType>(b));
942}
943
944inline Grindstone::GraphicsAPI::ShaderStageBit operator&(const Grindstone::GraphicsAPI::ShaderStageBit a, const Grindstone::GraphicsAPI::ShaderStageBit b) {
945 using ShaderStageBitType = uint8_t;
946 return static_cast<Grindstone::GraphicsAPI::ShaderStageBit>(static_cast<ShaderStageBitType>(a) & static_cast<ShaderStageBitType>(b));
947}
948
949inline Grindstone::GraphicsAPI::ShaderStageBit operator^(const Grindstone::GraphicsAPI::ShaderStageBit a, const Grindstone::GraphicsAPI::ShaderStageBit b) {
950 using ShaderStageBitType = uint8_t;
951 return static_cast<Grindstone::GraphicsAPI::ShaderStageBit>(static_cast<ShaderStageBitType>(a) ^ static_cast<ShaderStageBitType>(b));
952}
953
954inline Grindstone::GraphicsAPI::ShaderStageBit& operator|=(Grindstone::GraphicsAPI::ShaderStageBit& a, const Grindstone::GraphicsAPI::ShaderStageBit b) {
955 a = a | b;
956 return a;
957}
958
959inline Grindstone::GraphicsAPI::ShaderStageBit& operator&=(Grindstone::GraphicsAPI::ShaderStageBit& a, const Grindstone::GraphicsAPI::ShaderStageBit b) {
960 a = a & b;
961 return a;
962}
963
964inline Grindstone::GraphicsAPI::ShaderStageBit& operator^=(Grindstone::GraphicsAPI::ShaderStageBit& a, const Grindstone::GraphicsAPI::ShaderStageBit b) {
965 a = a ^ b;
966 return a;
967}
968
969inline Grindstone::GraphicsAPI::ColorMask operator~(const Grindstone::GraphicsAPI::ColorMask stages) {
970 using ColorMaskType = uint8_t;
971 return static_cast<Grindstone::GraphicsAPI::ColorMask>(~static_cast<ColorMaskType>(stages));
972}
973
974inline Grindstone::GraphicsAPI::ColorMask operator|(const Grindstone::GraphicsAPI::ColorMask a, const Grindstone::GraphicsAPI::ColorMask b) {
975 using ColorMaskType = uint8_t;
976 return static_cast<Grindstone::GraphicsAPI::ColorMask>(static_cast<ColorMaskType>(a) | static_cast<ColorMaskType>(b));
977}
978
979inline Grindstone::GraphicsAPI::ColorMask operator&(const Grindstone::GraphicsAPI::ColorMask a, const Grindstone::GraphicsAPI::ColorMask b) {
980 using ColorMaskType = uint8_t;
981 return static_cast<Grindstone::GraphicsAPI::ColorMask>(static_cast<ColorMaskType>(a) & static_cast<ColorMaskType>(b));
982}
983
984inline Grindstone::GraphicsAPI::ColorMask operator^(const Grindstone::GraphicsAPI::ColorMask a, const Grindstone::GraphicsAPI::ColorMask b) {
985 using ColorMaskType = uint8_t;
986 return static_cast<Grindstone::GraphicsAPI::ColorMask>(static_cast<ColorMaskType>(a) ^ static_cast<ColorMaskType>(b));
987}
988
989inline Grindstone::GraphicsAPI::ColorMask& operator|=(Grindstone::GraphicsAPI::ColorMask& a, const Grindstone::GraphicsAPI::ColorMask b) {
990 a = a | b;
991 return a;
992}
993
994inline Grindstone::GraphicsAPI::ColorMask& operator&=(Grindstone::GraphicsAPI::ColorMask& a, const Grindstone::GraphicsAPI::ColorMask b) {
995 a = a & b;
996 return a;
997}
998
999inline Grindstone::GraphicsAPI::ColorMask& operator^=(Grindstone::GraphicsAPI::ColorMask& a, const Grindstone::GraphicsAPI::ColorMask b) {
1000 a = a ^ b;
1001 return a;
1002}
1003
1004namespace std {
1005 template<>
1006 struct std::hash<Grindstone::GraphicsAPI::VertexBindingDescription> {
1007 std::size_t operator()(const Grindstone::GraphicsAPI::VertexBindingDescription& binding) const noexcept {
1008 size_t result = std::hash<size_t>{}(
1009 static_cast<size_t>(binding.bindingIndex) << 8 |
1010 static_cast<size_t>(binding.stride) << 32
1011 );
1012 result ^= std::hash<size_t>{}(static_cast<size_t>(binding.inputRate));
1013 return result;
1014 }
1015 };
1016
1017 template<>
1018 struct std::hash<Grindstone::GraphicsAPI::VertexAttributeDescription> {
1019 std::size_t operator()(const Grindstone::GraphicsAPI::VertexAttributeDescription& attribute) const noexcept {
1020 size_t result = std::hash<size_t>{}(
1021 static_cast<size_t>(attribute.attributeUsage) |
1022 static_cast<size_t>(attribute.bindingIndex) << 32
1023 );
1024
1025 result ^= std::hash<size_t>{}(
1026 static_cast<size_t>(attribute.byteOffset) |
1027 static_cast<size_t>(attribute.format) << 32
1028 );
1029
1030 result ^= std::hash<size_t>{}(
1031 static_cast<size_t>(attribute.locationIndex) << 32
1032 );
1033
1034 return result;
1035 }
1036 };
1037
1038 template<>
1039 struct std::hash<Grindstone::GraphicsAPI::VertexInputLayout> {
1040 std::size_t operator()(const Grindstone::GraphicsAPI::VertexInputLayout& vertexInputLayout) const noexcept {
1041 size_t result = std::hash<size_t>{}(vertexInputLayout.attributes.size()) ^ std::hash<size_t>{}(vertexInputLayout.bindings.size());
1042
1043 for (const Grindstone::GraphicsAPI::VertexBindingDescription& binding : vertexInputLayout.bindings) {
1044 result ^= std::hash<Grindstone::GraphicsAPI::VertexBindingDescription>{}(binding);
1045 }
1046
1047 for (const Grindstone::GraphicsAPI::VertexAttributeDescription& attribute : vertexInputLayout.attributes) {
1048 result ^= std::hash<Grindstone::GraphicsAPI::VertexAttributeDescription>{}(attribute);
1049 }
1050
1051 return result;
1052 }
1053 };
1054}
Definition Formats.hpp:633
Definition Formats.hpp:12