-
Notifications
You must be signed in to change notification settings - Fork 0
/
rjd_gfx.h
804 lines (701 loc) · 23.6 KB
/
rjd_gfx.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
#pragma once
#include <stdint.h>
#define RJD_GFX_H 1
// interface dependencies:
// * rjd_result
// impl dependencies:
// * rjd_mem
// * rjd_math
////////////////////////////////////////////////////////////////////////////////
// platform configuration
// Supported RJG_GFX_BACKEND_* values:
// RJD_GFX_BACKEND_METAL (osx only)
// RJD_GFX_BACKEND_D3D11 (windows only)
// RJD_GFX_BACKEND_NONE (any platform, stub interface only)
#ifndef RJD_GFX_BACKEND_NONE
#define RJD_GFX_BACKEND_NONE 0
#endif
#ifndef RJD_GFX_BACKEND_METAL
#define RJD_GFX_BACKEND_METAL 0
#endif
#ifndef RJD_GFX_BACKEND_D3D11
#define RJD_GFX_BACKEND_D3D11 0
#endif
#if (RJD_GFX_BACKEND_NONE + RJD_GFX_BACKEND_METAL + RJD_GFX_BACKEND_D3D11) > 1
#error "Only one of the RJD_GFX_BACKEND_* macros may be defined."
#endif
#if !RJD_GFX_BACKEND_NONE && !RJD_GFX_BACKEND_METAL && !RJD_GFX_BACKEND_D3D11
#error "You must #define one of the following to 1 before including this file: "
"RJD_GFX_BACKEND_NONE, RJD_GFX_BACKEND_METAL, RJD_GFX_BACKEND_D3D11"
#endif
#if RJD_GFX_BACKEND_METAL
#if RJD_PLATFORM_OSX
// Workaround .c files not being able to read objective-c forward declarations
#if RJD_LANG_OBJC
@class MTKView;
RJD_STATIC_ASSERT(sizeof(void*) == sizeof(MTKView*));
#else
typedef void MTKView;
#endif
#else
#error "Metal is only supported on OSX"
#endif
#endif
#if RJD_GFX_PLATFORM_D3D11
#if RJD_PLATFORM_WINDOWS
typedef void* HWND;
#else
#error "DirectX is only supported on Windows"
#endif
#endif
////////////////////////////////////////////////////////////////////////////////
// render configuration
struct rjd_mem_allocator;
struct rjd_gfx_viewport // TODO figure out if this should have a start x,y pair
{
uint32_t width;
uint32_t height;
};
enum rjd_gfx_stencilmode
{
RJD_GFX_STENCILMODE_DISABLED,
RJD_GFX_STENCILMODE_TEST,
RJD_GFX_STENCILMODE_WRITE,
RJD_GFX_STENCILMODE_COUNT,
};
//struct rjd_gfx_render_config
//{
// struct rjd_gfx_viewport window_size; // TODO upgrade this into a render view (render target w/ size & offset)?
// enum rjd_gfx_stencilmode stencil_mode;
// int use_buffer_color: 1;
// int use_buffer_depth: 1;
//};
//
//struct rjd_gfx_render_geo2d
//{
// struct rjd_math_float16* transforms;
// union rjd_gfx_quad_uv* uvs;
// rjd_math_float4* tints;
// uint32_t count;
//};
////////////////////////////////////////////////////////////////////////////////
// resources
enum rjd_gfx_format
{
RJD_GFX_FORMAT_COLOR_U8_RGBA,
RJD_GFX_FORMAT_COLOR_U8_BGRA_NORM,
RJD_GFX_FORMAT_COLOR_U8_BGRA_NORM_SRGB,
RJD_GFX_FORMAT_DEPTHSTENCIL_F32_D32,
RJD_GFX_FORMAT_DEPTHSTENCIL_U32_D24_S8,
RJD_GFX_FORMAT_COUNT,
};
// all values correspond to the entry in the enum rjd_gfx_format
struct rjd_gfx_format_value
{
enum rjd_gfx_format type;
union
{
uint8_t color_u8_rgba[4];
union {
uint32_t value;
struct {
uint32_t depth:24;
uint32_t stencil:8;
} parts;
} depthstencil_u32_d24_s8;
float depthstencil_f32_d32;
};
};
enum rjd_gfx_texture_access
{
RJD_GFX_TEXTURE_ACCESS_CPU_WRITE_GPU_READWRITE,
RJD_GFX_TEXTURE_ACCESS_CPU_NONE_GPU_READWRITE,
RJD_GFX_TEXTURE_ACCESS_COUNT,
};
enum rjd_gfx_texture_usage
{
RJD_GFX_TEXTURE_USAGE_DEFAULT,
RJD_GFX_TEXTURE_USAGE_RENDERTARGET,
RJD_GFX_TEXTURE_USAGE_COUNT,
};
struct rjd_gfx_texture_desc
{
const char* debug_label;
void* data;
uint32_t data_length;
uint32_t pixels_width;
uint32_t pixels_height;
uint32_t msaa_samples;
enum rjd_gfx_format format;
enum rjd_gfx_texture_access access;
enum rjd_gfx_texture_usage usage;
};
struct rjd_gfx_texture
{
struct rjd_slot handle;
};
// TODO determine if this is a good idea or not
//struct rjd_gfx_shader_input_slot
//{
// const char* name;
// uint32_t index;
// enum rjd_gfx_shader_input_buffer_type_flags type_flags;
//};
enum rjd_gfx_shader_type
{
RJD_GFX_SHADER_TYPE_VERTEX,
RJD_GFX_SHADER_TYPE_PIXEL,
};
// TODO provide a precompiled path as well, preferably with a shader_precompiled_desc?
struct rjd_gfx_shader_desc
{
const char* source_name;
const char* function_name;
const void* data;
uint32_t count_data;
enum rjd_gfx_shader_type type;
//struct rjd_gfx_shader_input_slot* slots;
//uint32_t count_slots;
};
struct rjd_gfx_shader
{
struct rjd_slot handle;
};
enum rjd_gfx_vertex_format_type
{
RJD_GFX_VERTEX_FORMAT_TYPE_FLOAT1,
RJD_GFX_VERTEX_FORMAT_TYPE_FLOAT2,
RJD_GFX_VERTEX_FORMAT_TYPE_FLOAT3,
RJD_GFX_VERTEX_FORMAT_TYPE_FLOAT4,
RJD_GFX_VERTEX_FORMAT_TYPE_COUNT,
};
enum rjd_gfx_vertex_format_step
{
RJD_GFX_VERTEX_FORMAT_STEP_VERTEX,
RJD_GFX_VERTEX_FORMAT_STEP_INSTANCE,
RJD_GFX_VERTEX_FORMAT_STEP_CONSTANT,
};
enum rjd_gfx_vertex_semantic
{
RJD_GFX_VERTEX_SEMANTIC_POSITION,
RJD_GFX_VERTEX_SEMANTIC_COLOR,
RJD_GFX_VERTEX_SEMANTIC_NORMAL,
RJD_GFX_VERTEX_SEMANTIC_TEXCOORD,
RJD_GFX_VERTEX_SEMANTIC_BINORMAL,
RJD_GFX_VERTEX_SEMANTIC_TANGENT,
RJD_GFX_VERTEX_SEMANTIC_BLENDINDEX,
RJD_GFX_VERTEX_SEMANTIC_BLENDWEIGHT,
RJD_GFX_VERTEX_SEMANTIC_COUNT,
};
struct rjd_gfx_vertex_format_attribute
{
enum rjd_gfx_vertex_format_type type;
enum rjd_gfx_vertex_format_step step;
enum rjd_gfx_vertex_semantic semantic; // only used for d3d11
uint32_t attribute_index;
uint32_t shader_slot_metal;
uint32_t shader_slot_d3d11;
uint32_t stride;
uint32_t step_rate;
uint32_t offset;
};
enum rjd_gfx_winding_order
{
RJD_GFX_WINDING_ORDER_CLOCKWISE,
RJD_GFX_WINDING_ORDER_COUNTERCLOCKWISE,
};
enum rjd_gfx_cull
{
RJD_GFX_CULL_NONE,
RJD_GFX_CULL_BACK,
RJD_GFX_CULL_FRONT,
};
enum rjd_gfx_depth_compare
{
RJD_GFX_DEPTH_COMPARE_ALWAYS_SUCCEED,
RJD_GFX_DEPTH_COMPARE_ALWAYS_FAIL,
RJD_GFX_DEPTH_COMPARE_LESS,
RJD_GFX_DEPTH_COMPARE_LESSEQUAL,
RJD_GFX_DEPTH_COMPARE_GREATER,
RJD_GFX_DEPTH_COMPARE_GREATEREQUAL,
RJD_GFX_DEPTH_COMPARE_EQUAL,
RJD_GFX_DEPTH_COMPARE_NOTEQUAL,
};
struct rjd_gfx_pipeline_state_desc
{
const char* debug_name;
struct rjd_gfx_shader shader_vertex;
struct rjd_gfx_shader shader_pixel;
struct rjd_gfx_texture render_target; // specify RJD_GFX_TEXTURE_BACKBUFFER to use the backbuffer
struct rjd_gfx_texture depthstencil_target; // specify RJD_GFX_TEXTURE_BACKBUFFER to use the backbuffer
struct rjd_gfx_vertex_format_attribute* vertex_attributes;
uint32_t count_vertex_attributes;
enum rjd_gfx_depth_compare depth_compare;
bool depth_write_enabled;
enum rjd_gfx_cull cull_mode;
enum rjd_gfx_winding_order winding_order;
// TODO stencil config
};
struct rjd_gfx_pipeline_state
{
struct rjd_slot handle;
};
enum rjd_gfx_primitive_type
{
RJD_GFX_PRIMITIVE_TYPE_TRIANGLES,
};
enum rjd_gfx_index_type
{
RJD_GFX_INDEX_TYPE_UINT32,
RJD_GFX_INDEX_TYPE_UINT16,
};
enum rjd_gfx_mesh_buffer_usage_flags
{
RJD_GFX_MESH_BUFFER_USAGE_VERTEX = 1 << 0,
RJD_GFX_MESH_BUFFER_USAGE_VERTEX_CONSTANT = 1 << 1,
RJD_GFX_MESH_BUFFER_USAGE_PIXEL_CONSTANT = 1 << 2,
};
union rjd_gfx_mesh_buffer_common_desc
{
struct {
uint32_t capacity;
} constant;
struct {
const void* data;
uint32_t length;
uint32_t stride;
} vertex;
};
struct rjd_gfx_mesh_buffer_desc
{
union rjd_gfx_mesh_buffer_common_desc common;
enum rjd_gfx_mesh_buffer_usage_flags usage_flags;
uint32_t shader_slot_metal; // metal shader slots are shared between all buffer types
uint32_t shader_slot_d3d11; // d3d11 vertex/constant buffers have their own lists of slots
};
struct rjd_gfx_mesh_vertexed_desc // TODO rename to rjd_gfx_mesh_desc and put index/instance data in here as well
{
enum rjd_gfx_primitive_type primitive;
struct rjd_gfx_mesh_buffer_desc* buffers;
uint32_t count_buffers;
uint32_t count_vertices;
};
struct rjd_gfx_mesh
{
struct rjd_slot handle;
};
////////////////////////////////////////////////////////////////////////////////
// render command
struct rjd_gfx_pass_begin_desc
{
const char* debug_label;
struct rjd_gfx_texture render_target; // specify RJD_GFX_TEXTURE_BACKBUFFER to use the backbuffer
struct rjd_gfx_texture depthstencil_target; // specify RJD_GFX_TEXTURE_BACKBUFFER to use the backbuffer
struct rjd_gfx_format_value clear_color;
struct rjd_gfx_format_value clear_depthstencil;
};
struct rjd_gfx_pass_draw_buffer_offset_desc
{
uint32_t mesh_index;
uint32_t buffer_index;
uint32_t offset_bytes;
uint32_t range_bytes;
};
struct rjd_gfx_pass_draw_desc
{
const char* debug_label;
const struct rjd_gfx_viewport* viewport;
const struct rjd_gfx_pipeline_state* pipeline_state;
const struct rjd_gfx_mesh* meshes;
const struct rjd_gfx_pass_draw_buffer_offset_desc* buffer_offset_descs;
const struct rjd_gfx_texture* textures;
const uint32_t* texture_indices; // parallel array with textures
uint32_t count_meshes;
uint32_t count_constant_descs;
uint32_t count_textures;
};
struct rjd_gfx_command_buffer
{
struct rjd_slot handle;
};
////////////////////////////////////////////////////////////////////////////////
// gfx context
enum rjd_gfx_num_backbuffers
{
RJD_GFX_NUM_BACKBUFFERS_TRIPLE,
RJD_GFX_NUM_BACKBUFFERS_DOUBLE,
};
enum RJD_GFX_VSYNC_MODE
{
RJD_GFX_VSYNC_MODE_ON,
RJD_GFX_VSYNC_MODE_OFF,
};
struct rjd_gfx_context_desc
{
struct rjd_mem_allocator* allocator;
enum rjd_gfx_format backbuffer_color_format;
enum rjd_gfx_format backbuffer_depth_format;
enum rjd_gfx_num_backbuffers num_backbuffers;
#if RJD_PLATFORM_WINDOWS
struct {
void* hwnd; // HWND
} win32;
#elif RJD_PLATFORM_OSX
struct {
MTKView* view;
} osx;
#endif
};
struct rjd_gfx_context
{
char pimpl[176];
};
enum rjd_gfx_backend_impl
{
RJD_GFX_BACKEND_IMPL_NONE,
RJD_GFX_BACKEND_IMPL_METAL,
RJD_GFX_BACKEND_IMPL_D3D11,
};
////////////////////////////////////////////////////////////////////////////////
// interface
// backend
static inline enum rjd_gfx_backend_impl rjd_gfx_backend(void);
static inline int32_t rjd_gfx_backend_ismetal(void);
static inline int32_t rjd_gfx_backend_isd3d11(void);
// context
// NOTE: all functions that deal with a context are not threadsafe for simplicity. If you are making a multithreaded
// renderer, you must have a strategy for synchronizing resource creation and drawing with the context.
struct rjd_result rjd_gfx_context_create(struct rjd_gfx_context* out, struct rjd_gfx_context_desc desc);
void rjd_gfx_context_destroy(struct rjd_gfx_context* context);
uint32_t rjd_gfx_backbuffer_current_index(const struct rjd_gfx_context* context);
struct rjd_result rjd_gfx_backbuffer_msaa_is_count_supported(const struct rjd_gfx_context* context, uint32_t sample_count);
struct rjd_result rjd_gfx_backbuffer_set_msaa_count(struct rjd_gfx_context* context, uint32_t sample_count);
struct rjd_result rjd_gfx_vsync_set(struct rjd_gfx_context* context, enum RJD_GFX_VSYNC_MODE mode);
struct rjd_result rjd_gfx_wait_for_frame_begin(struct rjd_gfx_context* context);
struct rjd_result rjd_gfx_present(struct rjd_gfx_context* context);
// commands
struct rjd_result rjd_gfx_command_buffer_create(struct rjd_gfx_context* context, struct rjd_gfx_command_buffer* out);
struct rjd_result rjd_gfx_command_pass_begin(struct rjd_gfx_context* context, struct rjd_gfx_command_buffer* cmd_buffer, const struct rjd_gfx_pass_begin_desc* command);
struct rjd_result rjd_gfx_command_pass_draw(struct rjd_gfx_context* context, struct rjd_gfx_command_buffer* cmd_buffer, const struct rjd_gfx_pass_draw_desc* command);
struct rjd_result rjd_gfx_command_buffer_commit(struct rjd_gfx_context* context, struct rjd_gfx_command_buffer* cmd_buffer);
// resources
struct rjd_result rjd_gfx_texture_create(struct rjd_gfx_context* context, struct rjd_gfx_texture* out, struct rjd_gfx_texture_desc desc);
void rjd_gfx_texture_destroy(struct rjd_gfx_context* context, struct rjd_gfx_texture* texture);
struct rjd_result rjd_gfx_shader_create(struct rjd_gfx_context* context, struct rjd_gfx_shader* out, struct rjd_gfx_shader_desc desc);
void rjd_gfx_shader_destroy(struct rjd_gfx_context* context, struct rjd_gfx_shader* shader);
struct rjd_result rjd_gfx_pipeline_state_create(struct rjd_gfx_context* context, struct rjd_gfx_pipeline_state* out, struct rjd_gfx_pipeline_state_desc desc);
void rjd_gfx_pipeline_state_destroy(struct rjd_gfx_context* context, struct rjd_gfx_pipeline_state* pipeline_state);
struct rjd_result rjd_gfx_mesh_create_vertexed(struct rjd_gfx_context* context, struct rjd_gfx_mesh* out, struct rjd_gfx_mesh_vertexed_desc desc);
struct rjd_result rjd_gfx_mesh_modify(struct rjd_gfx_context* context, struct rjd_gfx_command_buffer* cmd_buffer, struct rjd_gfx_mesh* mesh, uint32_t buffer_index, uint32_t offset, const void* data, uint32_t length);
void rjd_gfx_mesh_destroy(struct rjd_gfx_context* context, struct rjd_gfx_mesh* mesh);
// constant buffer helpers
static inline uint32_t rjd_gfx_constant_buffer_alignment(void);
static inline uint32_t rjd_gfx_calc_constant_buffer_stride(uint32_t constant_size);
// format
uint32_t rjd_gfx_format_bytesize(enum rjd_gfx_format format);
bool rjd_gfx_format_iscolor(enum rjd_gfx_format format);
bool rjd_gfx_format_isdepthstencil(enum rjd_gfx_format format);
bool rjd_gfx_format_isdepth(enum rjd_gfx_format format);
bool rjd_gfx_format_isstencil(enum rjd_gfx_format format);
double rjd_gfx_format_value_to_depth(struct rjd_gfx_format_value value);
uint8_t rjd_gfx_format_value_to_stencil(struct rjd_gfx_format_value value);
static inline struct rjd_gfx_format_value rjd_gfx_format_make_color_u8_rgba(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha);
static inline struct rjd_gfx_format_value rjd_gfx_format_make_depthstencil_f32_d32(float depth);
// constants
extern const struct rjd_gfx_texture RJD_GFX_TEXTURE_BACKBUFFER;
////////////////////////////////////////////////////////////////////////////////
// inline implementations
static inline enum rjd_gfx_backend_impl rjd_gfx_backend(void)
{
#if RJD_GFX_BACKEND_NONE
return RJD_GFX_BACKEND_IMPL_NONE;
#elif RJD_GFX_BACKEND_METAL
return RJD_GFX_BACKEND_IMPL_METAL;
#elif RJD_GFX_BACKEND_D3D11
return RJD_GFX_BACKEND_IMPL_D3D11;
#endif
}
static inline int32_t rjd_gfx_backend_ismetal(void)
{
return rjd_gfx_backend() == RJD_GFX_BACKEND_IMPL_METAL;
}
static inline int32_t rjd_gfx_backend_isd3d11(void)
{
return rjd_gfx_backend() == RJD_GFX_BACKEND_IMPL_D3D11;
}
static inline uint32_t rjd_gfx_constant_buffer_alignment(void)
{
#if RJD_GFX_BACKEND_METAL || RJD_GFX_BACKEND_D3D11 || RJD_GFX_BACKEND_NONE
return 256;
#else
#error Unknown platform.
#endif
}
static inline uint32_t rjd_gfx_calc_constant_buffer_stride(uint32_t constant_size)
{
uint32_t alignment = rjd_gfx_constant_buffer_alignment();
uint32_t aligned_stride = (constant_size % alignment) + constant_size;
return aligned_stride;
}
static inline struct rjd_gfx_format_value rjd_gfx_format_make_color_u8_rgba(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha)
{
struct rjd_gfx_format_value value;
value.type = RJD_GFX_FORMAT_COLOR_U8_RGBA;
value.color_u8_rgba[0] = red;
value.color_u8_rgba[1] = green;
value.color_u8_rgba[2] = blue;
value.color_u8_rgba[3] = alpha;
return value;
}
static inline struct rjd_gfx_format_value rjd_gfx_format_make_depthstencil_f32_d32(float depth)
{
struct rjd_gfx_format_value value = {
.type = RJD_GFX_FORMAT_DEPTHSTENCIL_F32_D32,
.depthstencil_f32_d32 = depth,
};
return value;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
#if RJD_IMPL
static const struct rjd_logchannel logchannel_default = {
.enabled = true,
.name = "rjd_gfx default",
};
static const struct rjd_logchannel logchannel_error = {
.enabled = true,
.name = "rjd_gfx error",
};
#define RJD_GFX_LOG(...) RJD_LOG_CHANNEL(&logchannel_default, RJD_LOG_VERBOSITY_LOW, __VA_ARGS__)
#define RJD_GFX_LOG_ERROR(...) RJD_LOG_CHANNEL(&logchannel_error, RJD_LOG_VERBOSITY_LOW, __VA_ARGS__)
const struct rjd_gfx_texture RJD_GFX_TEXTURE_BACKBUFFER = {0};
////////////////////////////////////////////////////////////////////////////////
// platform-independent format
uint32_t rjd_gfx_format_bytesize(enum rjd_gfx_format format)
{
switch (format)
{
case RJD_GFX_FORMAT_COLOR_U8_RGBA: return sizeof(char[4]);
case RJD_GFX_FORMAT_COLOR_U8_BGRA_NORM: return sizeof(char[4]);
case RJD_GFX_FORMAT_COLOR_U8_BGRA_NORM_SRGB: return sizeof(char[4]);
case RJD_GFX_FORMAT_DEPTHSTENCIL_F32_D32: return sizeof(float);
case RJD_GFX_FORMAT_DEPTHSTENCIL_U32_D24_S8: return sizeof(uint32_t);
case RJD_GFX_FORMAT_COUNT: break;
}
RJD_ASSERTFAIL("Invalid value %d", format);
return 0;
}
bool rjd_gfx_format_iscolor(enum rjd_gfx_format format)
{
switch (format)
{
case RJD_GFX_FORMAT_COLOR_U8_RGBA: return true;
case RJD_GFX_FORMAT_COLOR_U8_BGRA_NORM: return true;
case RJD_GFX_FORMAT_COLOR_U8_BGRA_NORM_SRGB: return true;
case RJD_GFX_FORMAT_DEPTHSTENCIL_F32_D32: return false;
case RJD_GFX_FORMAT_DEPTHSTENCIL_U32_D24_S8: return false;
case RJD_GFX_FORMAT_COUNT: break;
}
RJD_ASSERTFAIL("Invalid value %d", format);
return false;
}
bool rjd_gfx_format_isdepthstencil(enum rjd_gfx_format format)
{
bool is_depth = rjd_gfx_format_isdepth(format);
bool is_stencil = rjd_gfx_format_isstencil(format);
return is_depth || is_stencil;
}
bool rjd_gfx_format_isdepth(enum rjd_gfx_format format)
{
switch (format)
{
case RJD_GFX_FORMAT_COLOR_U8_RGBA: return false;
case RJD_GFX_FORMAT_COLOR_U8_BGRA_NORM: return false;
case RJD_GFX_FORMAT_COLOR_U8_BGRA_NORM_SRGB: return false;
case RJD_GFX_FORMAT_DEPTHSTENCIL_F32_D32: return true;
case RJD_GFX_FORMAT_DEPTHSTENCIL_U32_D24_S8: return true;
case RJD_GFX_FORMAT_COUNT: break;
}
RJD_ASSERTFAIL("Invalid value %d", format);
return false;
}
bool rjd_gfx_format_isstencil(enum rjd_gfx_format format)
{
switch (format)
{
case RJD_GFX_FORMAT_COLOR_U8_RGBA: return false;
case RJD_GFX_FORMAT_COLOR_U8_BGRA_NORM: return false;
case RJD_GFX_FORMAT_COLOR_U8_BGRA_NORM_SRGB: return false;
case RJD_GFX_FORMAT_DEPTHSTENCIL_F32_D32: return false;
case RJD_GFX_FORMAT_DEPTHSTENCIL_U32_D24_S8: return true;
case RJD_GFX_FORMAT_COUNT: break;
}
RJD_ASSERTFAIL("Invalid value %d", format);
return false;
}
double rjd_gfx_format_value_to_depth(struct rjd_gfx_format_value value)
{
switch (value.type)
{
case RJD_GFX_FORMAT_COLOR_U8_RGBA:
case RJD_GFX_FORMAT_COLOR_U8_BGRA_NORM:
case RJD_GFX_FORMAT_COLOR_U8_BGRA_NORM_SRGB:
RJD_ASSERTFAIL("color values shouldn't be passed to this function");
break;
case RJD_GFX_FORMAT_DEPTHSTENCIL_F32_D32: return value.depthstencil_f32_d32;
case RJD_GFX_FORMAT_DEPTHSTENCIL_U32_D24_S8: return value.depthstencil_u32_d24_s8.parts.depth;
case RJD_GFX_FORMAT_COUNT: break;
}
RJD_ASSERTFAIL("Unhandled format %d.", value.type);
return 0;
}
uint8_t rjd_gfx_format_value_to_stencil(struct rjd_gfx_format_value value)
{
switch (value.type)
{
case RJD_GFX_FORMAT_COLOR_U8_RGBA:
case RJD_GFX_FORMAT_COLOR_U8_BGRA_NORM:
case RJD_GFX_FORMAT_COLOR_U8_BGRA_NORM_SRGB:
RJD_ASSERTFAIL("color values shouldn't be passed to this function");
break;
case RJD_GFX_FORMAT_DEPTHSTENCIL_F32_D32: return 0;
case RJD_GFX_FORMAT_DEPTHSTENCIL_U32_D24_S8: return (uint8_t)value.depthstencil_u32_d24_s8.parts.stencil; // stencil is 8 bits so the cast is fine
case RJD_GFX_FORMAT_COUNT: break;
}
RJD_ASSERTFAIL("Unhandled format %d.", value.type);
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// gfx metal and d3d11 implementation is in API-specific headers
#if RJD_GFX_BACKEND_NONE
struct rjd_result rjd_gfx_context_create(struct rjd_gfx_context* out, struct rjd_gfx_context_desc desc)
{
RJD_UNUSED_PARAM(out);
RJD_UNUSED_PARAM(desc);
return RJD_RESULT("Unimplemented");
}
void rjd_gfx_context_destroy(struct rjd_gfx_context* context)
{
RJD_UNUSED_PARAM(context);
}
uint32_t rjd_gfx_backbuffer_current_index(const struct rjd_gfx_context* context)
{
RJD_UNUSED_PARAM(context);
return 0;
}
struct rjd_result rjd_gfx_backbuffer_msaa_is_count_supported(const struct rjd_gfx_context* context, uint32_t sample_count)
{
RJD_UNUSED_PARAM(context);
RJD_UNUSED_PARAM(sample_count);
return RJD_RESULT("Unimplemented");
}
struct rjd_result rjd_gfx_backbuffer_set_msaa_count(struct rjd_gfx_context* context, uint32_t sample_count)
{
RJD_UNUSED_PARAM(context);
RJD_UNUSED_PARAM(sample_count);
return RJD_RESULT("Unimplemented");
}
struct rjd_result rjd_gfx_vsync_set(struct rjd_gfx_context* context, enum RJD_GFX_VSYNC_MODE mode)
{
RJD_UNUSED_PARAM(context);
RJD_UNUSED_PARAM(mode);
return RJD_RESULT("Unimplemented");
}
struct rjd_result rjd_gfx_wait_for_frame_begin(struct rjd_gfx_context* context)
{
RJD_UNUSED_PARAM(context);
return RJD_RESULT("Unimplemented");
}
struct rjd_result rjd_gfx_present(struct rjd_gfx_context* context)
{
RJD_UNUSED_PARAM(context);
return RJD_RESULT("Unimplemented");
}
struct rjd_result rjd_gfx_command_buffer_create(struct rjd_gfx_context* context, struct rjd_gfx_command_buffer* out)
{
RJD_UNUSED_PARAM(context);
RJD_UNUSED_PARAM(out);
return RJD_RESULT("Unimplemented");
}
struct rjd_result rjd_gfx_command_pass_begin(struct rjd_gfx_context* context, struct rjd_gfx_command_buffer* cmd_buffer, const struct rjd_gfx_pass_begin_desc* command)
{
RJD_UNUSED_PARAM(context);
RJD_UNUSED_PARAM(cmd_buffer);
RJD_UNUSED_PARAM(command);
return RJD_RESULT("Unimplemented");
}
struct rjd_result rjd_gfx_command_pass_draw(struct rjd_gfx_context* context, struct rjd_gfx_command_buffer* cmd_buffer, const struct rjd_gfx_pass_draw_desc* command)
{
RJD_UNUSED_PARAM(context);
RJD_UNUSED_PARAM(cmd_buffer);
RJD_UNUSED_PARAM(command);
return RJD_RESULT("Unimplemented");
}
struct rjd_result rjd_gfx_command_buffer_commit(struct rjd_gfx_context* context, struct rjd_gfx_command_buffer* cmd_buffer)
{
RJD_UNUSED_PARAM(context);
RJD_UNUSED_PARAM(cmd_buffer);
return RJD_RESULT("Unimplemented");
}
struct rjd_result rjd_gfx_texture_create(struct rjd_gfx_context* context, struct rjd_gfx_texture* out, struct rjd_gfx_texture_desc desc)
{
RJD_UNUSED_PARAM(context);
RJD_UNUSED_PARAM(out);
RJD_UNUSED_PARAM(desc);
return RJD_RESULT("Unimplemented");
}
void rjd_gfx_texture_destroy(struct rjd_gfx_context* context, struct rjd_gfx_texture* texture)
{
RJD_UNUSED_PARAM(context);
RJD_UNUSED_PARAM(texture);
}
struct rjd_result rjd_gfx_shader_create(struct rjd_gfx_context* context, struct rjd_gfx_shader* out, struct rjd_gfx_shader_desc desc)
{
RJD_UNUSED_PARAM(context);
RJD_UNUSED_PARAM(out);
RJD_UNUSED_PARAM(desc);
return RJD_RESULT("Unimplemented");
}
void rjd_gfx_shader_destroy(struct rjd_gfx_context* context, struct rjd_gfx_shader* shader)
{
RJD_UNUSED_PARAM(context);
RJD_UNUSED_PARAM(shader);
}
struct rjd_result rjd_gfx_pipeline_state_create(struct rjd_gfx_context* context, struct rjd_gfx_pipeline_state* out, struct rjd_gfx_pipeline_state_desc desc)
{
RJD_UNUSED_PARAM(context);
RJD_UNUSED_PARAM(out);
RJD_UNUSED_PARAM(desc);
return RJD_RESULT("Unimplemented");
}
void rjd_gfx_pipeline_state_destroy(struct rjd_gfx_context* context, struct rjd_gfx_pipeline_state* pipeline_state)
{
RJD_UNUSED_PARAM(context);
RJD_UNUSED_PARAM(pipeline_state);
}
struct rjd_result rjd_gfx_mesh_create_vertexed(struct rjd_gfx_context* context, struct rjd_gfx_mesh* out, struct rjd_gfx_mesh_vertexed_desc desc)
{
RJD_UNUSED_PARAM(context);
RJD_UNUSED_PARAM(out);
RJD_UNUSED_PARAM(desc);
return RJD_RESULT("Unimplemented");
}
struct rjd_result rjd_gfx_mesh_modify(struct rjd_gfx_context* context, struct rjd_gfx_command_buffer* cmd_buffer, struct rjd_gfx_mesh* mesh, uint32_t buffer_index, uint32_t offset, const void* data, uint32_t length)
{
RJD_UNUSED_PARAM(context);
RJD_UNUSED_PARAM(cmd_buffer);
RJD_UNUSED_PARAM(mesh);
RJD_UNUSED_PARAM(buffer_index);
RJD_UNUSED_PARAM(offset);
RJD_UNUSED_PARAM(data);
RJD_UNUSED_PARAM(length);
return RJD_RESULT("Unimplemented");
}
void rjd_gfx_mesh_destroy(struct rjd_gfx_context* context, struct rjd_gfx_mesh* mesh)
{
RJD_UNUSED_PARAM(context);
RJD_UNUSED_PARAM(mesh);
}
#endif // RJD_GFX_BACKEND_NONE
#endif // RJD_IMPL