Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/servers/rendering/rendering_device_graph.h
20837 views
1
/**************************************************************************/
2
/* rendering_device_graph.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#include "core/object/worker_thread_pool.h"
34
#include "rendering_device_commons.h"
35
#include "rendering_device_driver.h"
36
37
// Buffer barriers have not shown any significant improvement or shown to be
38
// even detrimental to performance. However, there are currently some known
39
// cases where using them can solve problems that using singular memory
40
// barriers does not, probably due to driver issues (see comment on PR #84976
41
// https://github.com/godotengine/godot/pull/84976#issuecomment-1878566830).
42
43
#define USE_BUFFER_BARRIERS 1
44
45
class RenderingDeviceGraph {
46
public:
47
struct RaytracingListInstruction {
48
enum Type {
49
TYPE_NONE,
50
TYPE_BIND_PIPELINE,
51
TYPE_BIND_UNIFORM_SET,
52
TYPE_SET_PUSH_CONSTANT,
53
TYPE_TRACE_RAYS,
54
TYPE_UNIFORM_SET_PREPARE_FOR_USE,
55
};
56
57
Type type = TYPE_NONE;
58
};
59
60
struct ComputeListInstruction {
61
enum Type {
62
TYPE_NONE,
63
TYPE_BIND_PIPELINE,
64
TYPE_BIND_UNIFORM_SETS,
65
TYPE_DISPATCH,
66
TYPE_DISPATCH_INDIRECT,
67
TYPE_SET_PUSH_CONSTANT,
68
TYPE_UNIFORM_SET_PREPARE_FOR_USE
69
};
70
71
Type type = TYPE_NONE;
72
};
73
74
struct DrawListInstruction {
75
enum Type {
76
TYPE_NONE,
77
TYPE_BIND_INDEX_BUFFER,
78
TYPE_BIND_PIPELINE,
79
TYPE_BIND_UNIFORM_SETS,
80
TYPE_BIND_VERTEX_BUFFERS,
81
TYPE_CLEAR_ATTACHMENTS,
82
TYPE_DRAW,
83
TYPE_DRAW_INDEXED,
84
TYPE_DRAW_INDIRECT,
85
TYPE_DRAW_INDEXED_INDIRECT,
86
TYPE_EXECUTE_COMMANDS,
87
TYPE_NEXT_SUBPASS,
88
TYPE_SET_BLEND_CONSTANTS,
89
TYPE_SET_LINE_WIDTH,
90
TYPE_SET_PUSH_CONSTANT,
91
TYPE_SET_SCISSOR,
92
TYPE_SET_VIEWPORT,
93
TYPE_UNIFORM_SET_PREPARE_FOR_USE
94
};
95
96
Type type = TYPE_NONE;
97
};
98
99
struct RecordedCommand {
100
enum Type {
101
TYPE_NONE,
102
TYPE_ACCELERATION_STRUCTURE_BUILD,
103
TYPE_BUFFER_CLEAR,
104
TYPE_BUFFER_COPY,
105
TYPE_BUFFER_GET_DATA,
106
TYPE_BUFFER_UPDATE,
107
TYPE_COMPUTE_LIST,
108
TYPE_RAYTRACING_LIST,
109
TYPE_DRAW_LIST,
110
TYPE_TEXTURE_CLEAR_COLOR,
111
TYPE_TEXTURE_CLEAR_DEPTH_STENCIL,
112
TYPE_TEXTURE_COPY,
113
TYPE_TEXTURE_GET_DATA,
114
TYPE_TEXTURE_RESOLVE,
115
TYPE_TEXTURE_UPDATE,
116
TYPE_CAPTURE_TIMESTAMP,
117
TYPE_DRIVER_CALLBACK,
118
TYPE_MAX
119
};
120
121
Type type = TYPE_NONE;
122
int32_t adjacent_command_list_index = -1;
123
RDD::MemoryAccessBarrier memory_barrier;
124
int32_t normalization_barrier_index = -1;
125
int normalization_barrier_count = 0;
126
int32_t transition_barrier_index = -1;
127
int32_t transition_barrier_count = 0;
128
#if USE_BUFFER_BARRIERS
129
int32_t buffer_barrier_index = -1;
130
int32_t buffer_barrier_count = 0;
131
#endif
132
int32_t acceleration_structure_barrier_index = -1;
133
int32_t acceleration_structure_barrier_count = 0;
134
int32_t label_index = -1;
135
BitField<RDD::PipelineStageBits> previous_stages = {};
136
BitField<RDD::PipelineStageBits> next_stages = {};
137
BitField<RDD::PipelineStageBits> self_stages = {};
138
};
139
140
struct RecordedBufferCopy {
141
RDD::BufferID source;
142
RDD::BufferCopyRegion region;
143
};
144
145
struct RecordedBufferToTextureCopy {
146
RDD::BufferID from_buffer;
147
RDD::BufferTextureCopyRegion region;
148
};
149
150
enum ResourceUsage {
151
RESOURCE_USAGE_NONE,
152
RESOURCE_USAGE_COPY_FROM,
153
RESOURCE_USAGE_COPY_TO,
154
RESOURCE_USAGE_RESOLVE_FROM,
155
RESOURCE_USAGE_RESOLVE_TO,
156
RESOURCE_USAGE_UNIFORM_BUFFER_READ,
157
RESOURCE_USAGE_INDIRECT_BUFFER_READ,
158
RESOURCE_USAGE_TEXTURE_BUFFER_READ,
159
RESOURCE_USAGE_TEXTURE_BUFFER_READ_WRITE,
160
RESOURCE_USAGE_STORAGE_BUFFER_READ,
161
RESOURCE_USAGE_STORAGE_BUFFER_READ_WRITE,
162
RESOURCE_USAGE_VERTEX_BUFFER_READ,
163
RESOURCE_USAGE_INDEX_BUFFER_READ,
164
RESOURCE_USAGE_TEXTURE_SAMPLE,
165
RESOURCE_USAGE_STORAGE_IMAGE_READ,
166
RESOURCE_USAGE_STORAGE_IMAGE_READ_WRITE,
167
RESOURCE_USAGE_ATTACHMENT_COLOR_READ_WRITE,
168
RESOURCE_USAGE_ATTACHMENT_DEPTH_STENCIL_READ_WRITE,
169
RESOURCE_USAGE_ATTACHMENT_FRAGMENT_SHADING_RATE_READ,
170
RESOURCE_USAGE_ATTACHMENT_FRAGMENT_DENSITY_MAP_READ,
171
RESOURCE_USAGE_GENERAL,
172
RESOURCE_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT,
173
RESOURCE_USAGE_ACCELERATION_STRUCTURE_READ,
174
RESOURCE_USAGE_ACCELERATION_STRUCTURE_READ_WRITE,
175
RESOURCE_USAGE_MAX
176
};
177
178
struct ResourceTracker {
179
uint32_t reference_count = 0;
180
int64_t command_frame = -1;
181
BitField<RDD::PipelineStageBits> previous_frame_stages = {};
182
BitField<RDD::PipelineStageBits> current_frame_stages = {};
183
int32_t read_full_command_list_index = -1;
184
int32_t read_slice_command_list_index = -1;
185
int32_t write_command_or_list_index = -1;
186
int32_t draw_list_index = -1;
187
ResourceUsage draw_list_usage = RESOURCE_USAGE_NONE;
188
int32_t compute_list_index = -1;
189
int32_t raytracing_list_index = -1;
190
ResourceUsage compute_list_usage = RESOURCE_USAGE_NONE;
191
ResourceUsage raytracing_list_usage = RESOURCE_USAGE_NONE;
192
ResourceUsage usage = RESOURCE_USAGE_NONE;
193
BitField<RDD::BarrierAccessBits> usage_access = {};
194
RDD::BufferID buffer_driver_id;
195
RDD::TextureID texture_driver_id;
196
RDD::AccelerationStructureID acceleration_structure_driver_id;
197
RDD::TextureSubresourceRange texture_subresources;
198
Size2i texture_size;
199
uint32_t texture_usage = 0;
200
int32_t texture_slice_command_index = -1;
201
ResourceTracker *parent = nullptr;
202
ResourceTracker *dirty_shared_list = nullptr;
203
ResourceTracker *next_shared = nullptr;
204
Rect2i texture_slice_or_dirty_rect;
205
bool in_parent_dirty_list = false;
206
bool write_command_list_enabled = false;
207
bool is_discardable = false;
208
209
_FORCE_INLINE_ void reset_if_outdated(int64_t new_command_frame) {
210
if (new_command_frame != command_frame) {
211
command_frame = new_command_frame;
212
previous_frame_stages = current_frame_stages;
213
current_frame_stages.clear();
214
read_full_command_list_index = -1;
215
read_slice_command_list_index = -1;
216
write_command_or_list_index = -1;
217
draw_list_index = -1;
218
compute_list_index = -1;
219
raytracing_list_index = -1;
220
texture_slice_command_index = -1;
221
write_command_list_enabled = false;
222
}
223
}
224
};
225
226
typedef RDD::RenderPassID (*RenderPassCreationFunction)(RenderingDeviceDriver *p_driver, VectorView<RDD::AttachmentLoadOp> p_load_ops, VectorView<RDD::AttachmentStoreOp> p_store_ops, void *p_user_data);
227
228
struct FramebufferStorage {
229
RDD::FramebufferID framebuffer;
230
RDD::RenderPassID render_pass;
231
};
232
233
struct FramebufferCache {
234
uint32_t width = 0;
235
uint32_t height = 0;
236
LocalVector<RDD::TextureID> textures;
237
LocalVector<ResourceTracker *> trackers;
238
HashMap<uint64_t, FramebufferStorage> storage_map;
239
void *render_pass_creation_user_data = nullptr;
240
};
241
242
struct CommandBufferPool {
243
// Provided by RenderingDevice.
244
RDD::CommandPoolID pool;
245
246
// Created internally by RenderingDeviceGraph.
247
LocalVector<RDD::CommandBufferID> buffers;
248
LocalVector<RDD::SemaphoreID> semaphores;
249
uint32_t buffers_used = 0;
250
};
251
252
struct WorkaroundsState {
253
bool draw_list_found = false;
254
};
255
256
enum AttachmentOperation {
257
// Loads or ignores if the attachment is discardable.
258
ATTACHMENT_OPERATION_DEFAULT,
259
// Clear the attachment to a value.
260
ATTACHMENT_OPERATION_CLEAR,
261
// Ignore any contents from the attachment.
262
ATTACHMENT_OPERATION_IGNORE,
263
};
264
265
private:
266
struct InstructionList {
267
LocalVector<uint8_t> data;
268
LocalVector<ResourceTracker *> command_trackers;
269
LocalVector<ResourceUsage> command_tracker_usages;
270
BitField<RDD::PipelineStageBits> stages = {};
271
int32_t index = 0;
272
273
void clear() {
274
data.clear();
275
command_trackers.clear();
276
command_tracker_usages.clear();
277
stages.clear();
278
}
279
};
280
281
struct ComputeInstructionList : InstructionList {
282
#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
283
uint32_t breadcrumb;
284
#endif
285
};
286
287
struct RaytracingInstructionList : InstructionList {
288
// No extra contents.
289
};
290
291
struct DrawInstructionList : InstructionList {
292
FramebufferCache *framebuffer_cache = nullptr;
293
RDD::RenderPassID render_pass;
294
RDD::FramebufferID framebuffer;
295
Rect2i region;
296
LocalVector<AttachmentOperation> attachment_operations;
297
LocalVector<RDD::RenderPassClearValue> attachment_clear_values;
298
299
#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
300
uint32_t breadcrumb;
301
#endif
302
bool split_cmd_buffer = false;
303
};
304
305
struct RecordedCommandSort {
306
uint32_t level = 0;
307
uint32_t priority = 0;
308
int32_t index = -1;
309
310
RecordedCommandSort() = default;
311
312
bool operator<(const RecordedCommandSort &p_other) const {
313
if (level < p_other.level) {
314
return true;
315
} else if (level > p_other.level) {
316
return false;
317
}
318
319
if (priority < p_other.priority) {
320
return true;
321
} else if (priority > p_other.priority) {
322
return false;
323
}
324
325
return index < p_other.index;
326
}
327
};
328
329
struct RecordedCommandListNode {
330
int32_t command_index = -1;
331
int32_t next_list_index = -1;
332
};
333
334
struct RecordedSliceListNode {
335
int32_t command_index = -1;
336
int32_t next_list_index = -1;
337
Rect2i subresources;
338
bool partial_coverage = false;
339
};
340
341
struct RecordedAccelerationStructureBuildCommand : RecordedCommand {
342
RDD::AccelerationStructureID acceleration_structure;
343
RDD::BufferID scratch_buffer;
344
};
345
346
struct RecordedBufferClearCommand : RecordedCommand {
347
RDD::BufferID buffer;
348
uint32_t offset = 0;
349
uint32_t size = 0;
350
};
351
352
struct RecordedBufferCopyCommand : RecordedCommand {
353
RDD::BufferID source;
354
RDD::BufferID destination;
355
RDD::BufferCopyRegion region;
356
};
357
358
struct RecordedBufferGetDataCommand : RecordedCommand {
359
RDD::BufferID source;
360
RDD::BufferID destination;
361
RDD::BufferCopyRegion region;
362
};
363
364
struct RecordedBufferUpdateCommand : RecordedCommand {
365
RDD::BufferID destination;
366
uint32_t buffer_copies_count = 0;
367
368
_FORCE_INLINE_ RecordedBufferCopy *buffer_copies() {
369
return reinterpret_cast<RecordedBufferCopy *>(&this[1]);
370
}
371
372
_FORCE_INLINE_ const RecordedBufferCopy *buffer_copies() const {
373
return reinterpret_cast<const RecordedBufferCopy *>(&this[1]);
374
}
375
};
376
377
struct RecordedDriverCallbackCommand : RecordedCommand {
378
RDD::DriverCallback callback;
379
void *userdata = nullptr;
380
};
381
382
struct RecordedRaytracingListCommand : RecordedCommand {
383
uint32_t instruction_data_size = 0;
384
385
_FORCE_INLINE_ uint8_t *instruction_data() {
386
return reinterpret_cast<uint8_t *>(&this[1]);
387
}
388
389
_FORCE_INLINE_ const uint8_t *instruction_data() const {
390
return reinterpret_cast<const uint8_t *>(&this[1]);
391
}
392
};
393
394
struct RecordedComputeListCommand : RecordedCommand {
395
uint32_t instruction_data_size = 0;
396
uint32_t breadcrumb = 0;
397
398
_FORCE_INLINE_ uint8_t *instruction_data() {
399
return reinterpret_cast<uint8_t *>(&this[1]);
400
}
401
402
_FORCE_INLINE_ const uint8_t *instruction_data() const {
403
return reinterpret_cast<const uint8_t *>(&this[1]);
404
}
405
};
406
407
struct RecordedDrawListCommand : RecordedCommand {
408
FramebufferCache *framebuffer_cache = nullptr;
409
RDD::FramebufferID framebuffer;
410
RDD::RenderPassID render_pass;
411
uint32_t instruction_data_size = 0;
412
RDD::CommandBufferType command_buffer_type;
413
Rect2i region;
414
uint32_t clear_values_count = 0;
415
uint32_t trackers_count = 0;
416
417
#if defined(DEBUG_ENABLED) || defined(DEV_ENABLED)
418
uint32_t breadcrumb = 0;
419
#endif
420
bool split_cmd_buffer = false;
421
422
_FORCE_INLINE_ RDD::RenderPassClearValue *clear_values() {
423
return reinterpret_cast<RDD::RenderPassClearValue *>(&this[1]);
424
}
425
426
_FORCE_INLINE_ const RDD::RenderPassClearValue *clear_values() const {
427
return reinterpret_cast<const RDD::RenderPassClearValue *>(&this[1]);
428
}
429
430
_FORCE_INLINE_ ResourceTracker **trackers() {
431
return reinterpret_cast<ResourceTracker **>(&clear_values()[clear_values_count]);
432
}
433
434
_FORCE_INLINE_ ResourceTracker *const *trackers() const {
435
return reinterpret_cast<ResourceTracker *const *>(&clear_values()[clear_values_count]);
436
}
437
438
_FORCE_INLINE_ RDD::AttachmentLoadOp *load_ops() {
439
return reinterpret_cast<RDD::AttachmentLoadOp *>(&trackers()[trackers_count]);
440
}
441
442
_FORCE_INLINE_ const RDD::AttachmentLoadOp *load_ops() const {
443
return reinterpret_cast<const RDD::AttachmentLoadOp *>(&trackers()[trackers_count]);
444
}
445
446
_FORCE_INLINE_ RDD::AttachmentStoreOp *store_ops() {
447
return reinterpret_cast<RDD::AttachmentStoreOp *>(&load_ops()[trackers_count]);
448
}
449
450
_FORCE_INLINE_ const RDD::AttachmentStoreOp *store_ops() const {
451
return reinterpret_cast<const RDD::AttachmentStoreOp *>(&load_ops()[trackers_count]);
452
}
453
454
_FORCE_INLINE_ uint8_t *instruction_data() {
455
return reinterpret_cast<uint8_t *>(&store_ops()[trackers_count]);
456
}
457
458
_FORCE_INLINE_ const uint8_t *instruction_data() const {
459
return reinterpret_cast<const uint8_t *>(&store_ops()[trackers_count]);
460
}
461
};
462
463
struct RecordedTextureClearColorCommand : RecordedCommand {
464
RDD::TextureID texture;
465
RDD::TextureSubresourceRange range;
466
Color color;
467
};
468
469
struct RecordedTextureClearDepthStencilCommand : RecordedCommand {
470
RDD::TextureID texture;
471
RDD::TextureSubresourceRange range;
472
float depth;
473
uint8_t stencil;
474
};
475
476
struct RecordedTextureCopyCommand : RecordedCommand {
477
RDD::TextureID from_texture;
478
RDD::TextureID to_texture;
479
uint32_t texture_copy_regions_count = 0;
480
481
_FORCE_INLINE_ RDD::TextureCopyRegion *texture_copy_regions() {
482
return reinterpret_cast<RDD::TextureCopyRegion *>(&this[1]);
483
}
484
485
_FORCE_INLINE_ const RDD::TextureCopyRegion *texture_copy_regions() const {
486
return reinterpret_cast<const RDD::TextureCopyRegion *>(&this[1]);
487
}
488
};
489
490
struct RecordedTextureGetDataCommand : RecordedCommand {
491
RDD::TextureID from_texture;
492
RDD::BufferID to_buffer;
493
uint32_t buffer_texture_copy_regions_count = 0;
494
495
_FORCE_INLINE_ RDD::BufferTextureCopyRegion *buffer_texture_copy_regions() {
496
return reinterpret_cast<RDD::BufferTextureCopyRegion *>(&this[1]);
497
}
498
499
_FORCE_INLINE_ const RDD::BufferTextureCopyRegion *buffer_texture_copy_regions() const {
500
return reinterpret_cast<const RDD::BufferTextureCopyRegion *>(&this[1]);
501
}
502
};
503
504
struct RecordedTextureResolveCommand : RecordedCommand {
505
RDD::TextureID from_texture;
506
RDD::TextureID to_texture;
507
uint32_t src_layer = 0;
508
uint32_t src_mipmap = 0;
509
uint32_t dst_layer = 0;
510
uint32_t dst_mipmap = 0;
511
};
512
513
struct RecordedTextureUpdateCommand : RecordedCommand {
514
RDD::TextureID to_texture;
515
uint32_t buffer_to_texture_copies_count = 0;
516
517
_FORCE_INLINE_ RecordedBufferToTextureCopy *buffer_to_texture_copies() {
518
return reinterpret_cast<RecordedBufferToTextureCopy *>(&this[1]);
519
}
520
521
_FORCE_INLINE_ const RecordedBufferToTextureCopy *buffer_to_texture_copies() const {
522
return reinterpret_cast<const RecordedBufferToTextureCopy *>(&this[1]);
523
}
524
};
525
526
struct RecordedCaptureTimestampCommand : RecordedCommand {
527
RDD::QueryPoolID pool;
528
uint32_t index = 0;
529
};
530
531
struct DrawListBindIndexBufferInstruction : DrawListInstruction {
532
RDD::BufferID buffer;
533
RenderingDeviceCommons::IndexBufferFormat format;
534
uint32_t offset = 0;
535
};
536
537
struct DrawListBindPipelineInstruction : DrawListInstruction {
538
RDD::PipelineID pipeline;
539
};
540
541
struct DrawListBindUniformSetsInstruction : DrawListInstruction {
542
RDD::ShaderID shader;
543
uint32_t first_set_index = 0;
544
uint32_t set_count = 0;
545
uint32_t dynamic_offsets_mask = 0u;
546
547
_FORCE_INLINE_ RDD::UniformSetID *uniform_set_ids() {
548
return reinterpret_cast<RDD::UniformSetID *>(&this[1]);
549
}
550
551
_FORCE_INLINE_ const RDD::UniformSetID *uniform_set_ids() const {
552
return reinterpret_cast<const RDD::UniformSetID *>(&this[1]);
553
}
554
};
555
556
struct DrawListBindVertexBuffersInstruction : DrawListInstruction {
557
uint32_t vertex_buffers_count = 0;
558
uint64_t dynamic_offsets_mask = 0;
559
560
_FORCE_INLINE_ RDD::BufferID *vertex_buffers() {
561
return reinterpret_cast<RDD::BufferID *>(&this[1]);
562
}
563
564
_FORCE_INLINE_ const RDD::BufferID *vertex_buffers() const {
565
return reinterpret_cast<const RDD::BufferID *>(&this[1]);
566
}
567
568
_FORCE_INLINE_ uint64_t *vertex_buffer_offsets() {
569
return reinterpret_cast<uint64_t *>(&vertex_buffers()[vertex_buffers_count]);
570
}
571
572
_FORCE_INLINE_ const uint64_t *vertex_buffer_offsets() const {
573
return reinterpret_cast<const uint64_t *>(&vertex_buffers()[vertex_buffers_count]);
574
}
575
};
576
577
struct DrawListClearAttachmentsInstruction : DrawListInstruction {
578
uint32_t attachments_clear_count = 0;
579
uint32_t attachments_clear_rect_count = 0;
580
581
_FORCE_INLINE_ RDD::AttachmentClear *attachments_clear() {
582
return reinterpret_cast<RDD::AttachmentClear *>(&this[1]);
583
}
584
585
_FORCE_INLINE_ const RDD::AttachmentClear *attachments_clear() const {
586
return reinterpret_cast<const RDD::AttachmentClear *>(&this[1]);
587
}
588
589
_FORCE_INLINE_ Rect2i *attachments_clear_rect() {
590
return reinterpret_cast<Rect2i *>(&attachments_clear()[attachments_clear_count]);
591
}
592
593
_FORCE_INLINE_ const Rect2i *attachments_clear_rect() const {
594
return reinterpret_cast<const Rect2i *>(&attachments_clear()[attachments_clear_count]);
595
}
596
};
597
598
struct DrawListDrawInstruction : DrawListInstruction {
599
uint32_t vertex_count = 0;
600
uint32_t instance_count = 0;
601
};
602
603
struct DrawListDrawIndexedInstruction : DrawListInstruction {
604
uint32_t index_count = 0;
605
uint32_t instance_count = 0;
606
uint32_t first_index = 0;
607
};
608
609
struct DrawListDrawIndirectInstruction : DrawListInstruction {
610
RDD::BufferID buffer;
611
uint32_t offset = 0;
612
uint32_t draw_count = 0;
613
uint32_t stride = 0;
614
};
615
616
struct DrawListDrawIndexedIndirectInstruction : DrawListInstruction {
617
RDD::BufferID buffer;
618
uint32_t offset = 0;
619
uint32_t draw_count = 0;
620
uint32_t stride = 0;
621
};
622
623
struct DrawListEndRenderPassInstruction : DrawListInstruction {
624
// No contents.
625
};
626
627
struct DrawListExecuteCommandsInstruction : DrawListInstruction {
628
RDD::CommandBufferID command_buffer;
629
};
630
631
struct DrawListSetPushConstantInstruction : DrawListInstruction {
632
uint32_t size = 0;
633
RDD::ShaderID shader;
634
635
_FORCE_INLINE_ uint8_t *data() {
636
return reinterpret_cast<uint8_t *>(&this[1]);
637
}
638
639
_FORCE_INLINE_ const uint8_t *data() const {
640
return reinterpret_cast<const uint8_t *>(&this[1]);
641
}
642
};
643
644
struct DrawListNextSubpassInstruction : DrawListInstruction {
645
RDD::CommandBufferType command_buffer_type;
646
};
647
648
struct DrawListSetBlendConstantsInstruction : DrawListInstruction {
649
Color color;
650
};
651
652
struct DrawListSetLineWidthInstruction : DrawListInstruction {
653
float width;
654
};
655
656
struct DrawListSetScissorInstruction : DrawListInstruction {
657
Rect2i rect;
658
};
659
660
struct DrawListSetViewportInstruction : DrawListInstruction {
661
Rect2i rect;
662
};
663
664
struct DrawListUniformSetPrepareForUseInstruction : DrawListInstruction {
665
RDD::UniformSetID uniform_set;
666
RDD::ShaderID shader;
667
uint32_t set_index = 0;
668
};
669
670
struct RaytracingListBuildAccelerationStructureInstruction : RaytracingListInstruction {
671
RDD::AccelerationStructureID acceleration_structure;
672
RDD::AccelerationStructureType acceleration_structure_type;
673
};
674
675
struct RaytracingListBindPipelineInstruction : RaytracingListInstruction {
676
RDD::RaytracingPipelineID pipeline;
677
};
678
679
struct RaytracingListBindUniformSetInstruction : RaytracingListInstruction {
680
RDD::UniformSetID uniform_set;
681
RDD::ShaderID shader;
682
uint32_t set_index = 0;
683
};
684
685
struct RaytracingListSetPushConstantInstruction : RaytracingListInstruction {
686
uint32_t size = 0;
687
RDD::ShaderID shader;
688
689
_FORCE_INLINE_ uint8_t *data() {
690
return reinterpret_cast<uint8_t *>(&this[1]);
691
}
692
693
_FORCE_INLINE_ const uint8_t *data() const {
694
return reinterpret_cast<const uint8_t *>(&this[1]);
695
}
696
};
697
698
struct RaytracingListTraceRaysInstruction : RaytracingListInstruction {
699
uint32_t width = 0;
700
uint32_t height = 0;
701
};
702
703
struct RaytracingListUniformSetPrepareForUseInstruction : RaytracingListInstruction {
704
RDD::UniformSetID uniform_set;
705
RDD::ShaderID shader;
706
uint32_t set_index = 0;
707
};
708
709
struct ComputeListBindPipelineInstruction : ComputeListInstruction {
710
RDD::PipelineID pipeline;
711
};
712
713
struct ComputeListBindUniformSetsInstruction : ComputeListInstruction {
714
RDD::ShaderID shader;
715
uint32_t first_set_index = 0;
716
uint32_t set_count = 0;
717
uint32_t dynamic_offsets_mask = 0u;
718
719
_FORCE_INLINE_ RDD::UniformSetID *uniform_set_ids() {
720
return reinterpret_cast<RDD::UniformSetID *>(&this[1]);
721
}
722
723
_FORCE_INLINE_ const RDD::UniformSetID *uniform_set_ids() const {
724
return reinterpret_cast<const RDD::UniformSetID *>(&this[1]);
725
}
726
};
727
728
struct ComputeListDispatchInstruction : ComputeListInstruction {
729
uint32_t x_groups = 0;
730
uint32_t y_groups = 0;
731
uint32_t z_groups = 0;
732
};
733
734
struct ComputeListDispatchIndirectInstruction : ComputeListInstruction {
735
RDD::BufferID buffer;
736
uint32_t offset = 0;
737
};
738
739
struct ComputeListSetPushConstantInstruction : ComputeListInstruction {
740
uint32_t size = 0;
741
RDD::ShaderID shader;
742
743
_FORCE_INLINE_ uint8_t *data() {
744
return reinterpret_cast<uint8_t *>(&this[1]);
745
}
746
747
_FORCE_INLINE_ const uint8_t *data() const {
748
return reinterpret_cast<const uint8_t *>(&this[1]);
749
}
750
};
751
752
struct ComputeListUniformSetPrepareForUseInstruction : ComputeListInstruction {
753
RDD::UniformSetID uniform_set;
754
RDD::ShaderID shader;
755
uint32_t set_index = 0;
756
};
757
758
struct BarrierGroup {
759
BitField<RDD::PipelineStageBits> src_stages = {};
760
BitField<RDD::PipelineStageBits> dst_stages = {};
761
RDD::MemoryAccessBarrier memory_barrier;
762
LocalVector<RDD::TextureBarrier> normalization_barriers;
763
LocalVector<RDD::TextureBarrier> transition_barriers;
764
#if USE_BUFFER_BARRIERS
765
LocalVector<RDD::BufferBarrier> buffer_barriers;
766
#endif
767
LocalVector<RDD::AccelerationStructureBarrier> acceleration_structure_barriers;
768
769
void clear() {
770
src_stages.clear();
771
dst_stages.clear();
772
memory_barrier.src_access.clear();
773
memory_barrier.dst_access.clear();
774
normalization_barriers.clear();
775
transition_barriers.clear();
776
#if USE_BUFFER_BARRIERS
777
buffer_barriers.clear();
778
#endif
779
acceleration_structure_barriers.clear();
780
}
781
};
782
783
struct SecondaryCommandBuffer {
784
LocalVector<uint8_t> instruction_data;
785
RDD::CommandBufferID command_buffer;
786
RDD::CommandPoolID command_pool;
787
RDD::RenderPassID render_pass;
788
RDD::FramebufferID framebuffer;
789
WorkerThreadPool::TaskID task;
790
};
791
792
struct Frame {
793
TightLocalVector<SecondaryCommandBuffer> secondary_command_buffers;
794
uint32_t secondary_command_buffers_used = 0;
795
};
796
797
RDD *driver = nullptr;
798
RenderingContextDriver::Device device;
799
RenderPassCreationFunction render_pass_creation_function = nullptr;
800
int64_t tracking_frame = 0;
801
LocalVector<uint8_t> command_data;
802
LocalVector<uint32_t> command_data_offsets;
803
LocalVector<RDD::TextureBarrier> command_normalization_barriers;
804
LocalVector<RDD::TextureBarrier> command_transition_barriers;
805
LocalVector<RDD::BufferBarrier> command_buffer_barriers;
806
LocalVector<RDD::AccelerationStructureBarrier> command_acceleration_structure_barriers;
807
LocalVector<char> command_label_chars;
808
LocalVector<Color> command_label_colors;
809
LocalVector<uint32_t> command_label_offsets;
810
int32_t command_label_index = -1;
811
DrawInstructionList draw_instruction_list;
812
ComputeInstructionList compute_instruction_list;
813
RaytracingInstructionList raytracing_instruction_list;
814
uint32_t command_count = 0;
815
uint32_t command_label_count = 0;
816
LocalVector<RecordedCommandListNode> command_list_nodes;
817
LocalVector<RecordedSliceListNode> read_slice_list_nodes;
818
LocalVector<RecordedSliceListNode> write_slice_list_nodes;
819
int32_t command_timestamp_index = -1;
820
int32_t command_synchronization_index = -1;
821
bool command_synchronization_pending = false;
822
BarrierGroup barrier_group;
823
bool driver_honors_barriers : 1;
824
bool driver_clears_with_copy_engine : 1;
825
bool driver_buffers_require_transitions : 1;
826
WorkaroundsState workarounds_state;
827
TightLocalVector<Frame> frames;
828
uint32_t frame = 0;
829
830
#ifdef DEV_ENABLED
831
RBMap<ResourceTracker *, uint32_t> write_dependency_counters;
832
#endif
833
834
static String _usage_to_string(ResourceUsage p_usage);
835
static bool _is_write_usage(ResourceUsage p_usage);
836
static RDD::TextureLayout _usage_to_image_layout(ResourceUsage p_usage);
837
static RDD::BarrierAccessBits _usage_to_access_bits(ResourceUsage p_usage);
838
bool _check_command_intersection(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index) const;
839
bool _check_command_partial_coverage(ResourceTracker *p_resource_tracker, int32_t p_command_index) const;
840
int32_t _add_to_command_list(int32_t p_command_index, int32_t p_list_index);
841
void _add_adjacent_command(int32_t p_previous_command_index, int32_t p_command_index, RecordedCommand *r_command);
842
int32_t _add_to_slice_read_list(int32_t p_command_index, Rect2i p_subresources, int32_t p_list_index);
843
int32_t _add_to_write_list(int32_t p_command_index, Rect2i p_subresources, int32_t p_list_index, bool p_partial_coverage);
844
RecordedCommand *_allocate_command(uint32_t p_command_size, int32_t &r_command_index);
845
DrawListInstruction *_allocate_draw_list_instruction(uint32_t p_instruction_size);
846
ComputeListInstruction *_allocate_compute_list_instruction(uint32_t p_instruction_size);
847
void _check_discardable_attachment_dependency(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index);
848
RaytracingListInstruction *_allocate_raytracing_list_instruction(uint32_t p_instruction_size);
849
void _add_command_to_graph(ResourceTracker **p_resource_trackers, ResourceUsage *p_resource_usages, uint32_t p_resource_count, int32_t p_command_index, RecordedCommand *r_command);
850
void _add_texture_barrier_to_command(RDD::TextureID p_texture_id, BitField<RDD::BarrierAccessBits> p_src_access, BitField<RDD::BarrierAccessBits> p_dst_access, ResourceUsage p_prev_usage, ResourceUsage p_next_usage, RDD::TextureSubresourceRange p_subresources, LocalVector<RDD::TextureBarrier> &r_barrier_vector, int32_t &r_barrier_index, int32_t &r_barrier_count);
851
#if USE_BUFFER_BARRIERS
852
void _add_buffer_barrier_to_command(RDD::BufferID p_buffer_id, BitField<RDD::BarrierAccessBits> p_src_access, BitField<RDD::BarrierAccessBits> p_dst_access, int32_t &r_barrier_index, int32_t &r_barrier_count);
853
#endif
854
void _add_acceleration_structure_barrier_to_command(RDD::AccelerationStructureID p_acceleration_structure_id, BitField<RDD::BarrierAccessBits> p_src_access, BitField<RDD::BarrierAccessBits> p_dst_access, LocalVector<RDD::AccelerationStructureBarrier> &r_barrier_vector, int32_t &r_barrier_index, int32_t &r_barrier_count);
855
void _run_compute_list_command(RDD::CommandBufferID p_command_buffer, const uint8_t *p_instruction_data, uint32_t p_instruction_data_size);
856
void _get_draw_list_render_pass_and_framebuffer(const RecordedDrawListCommand *p_draw_list_command, RDD::RenderPassID &r_render_pass, RDD::FramebufferID &r_framebuffer);
857
void _run_raytracing_list_command(RDD::CommandBufferID p_command_buffer, const uint8_t *p_instruction_data, uint32_t p_instruction_data_size);
858
void _run_draw_list_command(RDD::CommandBufferID p_command_buffer, const uint8_t *p_instruction_data, uint32_t p_instruction_data_size);
859
void _add_draw_list_begin(FramebufferCache *p_framebuffer_cache, RDD::RenderPassID p_render_pass, RDD::FramebufferID p_framebuffer, Rect2i p_region, VectorView<AttachmentOperation> p_attachment_operations, VectorView<RDD::RenderPassClearValue> p_attachment_clear_values, BitField<RDD::PipelineStageBits> p_stages, uint32_t p_breadcrumb, bool p_split_cmd_buffer);
860
void _run_secondary_command_buffer_task(const SecondaryCommandBuffer *p_secondary);
861
void _wait_for_secondary_command_buffer_tasks();
862
void _run_render_commands(int32_t p_level, const RecordedCommandSort *p_sorted_commands, uint32_t p_sorted_commands_count, RDD::CommandBufferID &r_command_buffer, CommandBufferPool &r_command_buffer_pool, int32_t &r_current_label_index, int32_t &r_current_label_level);
863
void _run_label_command_change(RDD::CommandBufferID p_command_buffer, int32_t p_new_label_index, int32_t p_new_level, bool p_ignore_previous_value, bool p_use_label_for_empty, const RecordedCommandSort *p_sorted_commands, uint32_t p_sorted_commands_count, int32_t &r_current_label_index, int32_t &r_current_label_level);
864
void _boost_priority_for_render_commands(RecordedCommandSort *p_sorted_commands, uint32_t p_sorted_commands_count, uint32_t &r_boosted_priority);
865
void _group_barriers_for_render_commands(RDD::CommandBufferID p_command_buffer, const RecordedCommandSort *p_sorted_commands, uint32_t p_sorted_commands_count, bool p_full_memory_barrier);
866
void _print_render_commands(const RecordedCommandSort *p_sorted_commands, uint32_t p_sorted_commands_count);
867
void _print_draw_list(const uint8_t *p_instruction_data, uint32_t p_instruction_data_size);
868
void _print_compute_list(const uint8_t *p_instruction_data, uint32_t p_instruction_data_size);
869
void _print_raytracing_list(const uint8_t *p_instruction_data, uint32_t p_instruction_data_size);
870
871
public:
872
RenderingDeviceGraph();
873
~RenderingDeviceGraph();
874
void initialize(RDD *p_driver, RenderingContextDriver::Device p_device, RenderPassCreationFunction p_render_pass_creation_function, uint32_t p_frame_count, RDD::CommandQueueFamilyID p_secondary_command_queue_family, uint32_t p_secondary_command_buffers_per_frame);
875
void finalize();
876
void begin();
877
void add_acceleration_structure_build(RDD::AccelerationStructureID p_acceleration_structure, RDD::BufferID p_scratch_buffer, ResourceTracker *p_dst_tracker, VectorView<ResourceTracker *> p_src_trackers);
878
void add_buffer_clear(RDD::BufferID p_dst, ResourceTracker *p_dst_tracker, uint32_t p_offset, uint32_t p_size);
879
void add_buffer_copy(RDD::BufferID p_src, ResourceTracker *p_src_tracker, RDD::BufferID p_dst, ResourceTracker *p_dst_tracker, RDD::BufferCopyRegion p_region);
880
void add_buffer_get_data(RDD::BufferID p_src, ResourceTracker *p_src_tracker, RDD::BufferID p_dst, RDD::BufferCopyRegion p_region);
881
void add_buffer_update(RDD::BufferID p_dst, ResourceTracker *p_dst_tracker, VectorView<RecordedBufferCopy> p_buffer_copies);
882
void add_driver_callback(RDD::DriverCallback p_callback, void *p_userdata, VectorView<ResourceTracker *> p_trackers, VectorView<ResourceUsage> p_usages);
883
void add_raytracing_list_begin();
884
void add_raytracing_list_bind_pipeline(RDD::RaytracingPipelineID p_pipeline);
885
void add_raytracing_list_bind_uniform_set(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index);
886
void add_raytracing_list_set_push_constant(RDD::ShaderID p_shader, const void *p_data, uint32_t p_data_size);
887
void add_raytracing_list_trace_rays(uint32_t p_width, uint32_t p_height);
888
void add_raytracing_list_uniform_set_prepare_for_use(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index);
889
void add_raytracing_list_usage(ResourceTracker *p_tracker, ResourceUsage p_usage);
890
void add_raytracing_list_usages(VectorView<ResourceTracker *> p_trackers, VectorView<ResourceUsage> p_usages);
891
void add_raytracing_list_end();
892
void add_compute_list_begin(RDD::BreadcrumbMarker p_phase = RDD::BreadcrumbMarker::NONE, uint32_t p_breadcrumb_data = 0);
893
void add_compute_list_bind_pipeline(RDD::PipelineID p_pipeline);
894
void add_compute_list_bind_uniform_set(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index);
895
void add_compute_list_bind_uniform_sets(RDD::ShaderID p_shader, VectorView<RDD::UniformSetID> p_uniform_set, uint32_t p_first_set_index, uint32_t p_set_count);
896
void add_compute_list_dispatch(uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups);
897
void add_compute_list_dispatch_indirect(RDD::BufferID p_buffer, uint32_t p_offset);
898
void add_compute_list_set_push_constant(RDD::ShaderID p_shader, const void *p_data, uint32_t p_data_size);
899
void add_compute_list_uniform_set_prepare_for_use(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index);
900
void add_compute_list_usage(ResourceTracker *p_tracker, ResourceUsage p_usage);
901
void add_compute_list_usages(VectorView<ResourceTracker *> p_trackers, VectorView<ResourceUsage> p_usages);
902
void add_compute_list_end();
903
void add_draw_list_begin(FramebufferCache *p_framebuffer_cache, Rect2i p_region, VectorView<AttachmentOperation> p_attachment_operations, VectorView<RDD::RenderPassClearValue> p_attachment_clear_values, BitField<RDD::PipelineStageBits> p_stages, uint32_t p_breadcrumb = 0, bool p_split_cmd_buffer = false);
904
void add_draw_list_begin(RDD::RenderPassID p_render_pass, RDD::FramebufferID p_framebuffer, Rect2i p_region, VectorView<AttachmentOperation> p_attachment_operations, VectorView<RDD::RenderPassClearValue> p_attachment_clear_values, BitField<RDD::PipelineStageBits> p_stages, uint32_t p_breadcrumb = 0, bool p_split_cmd_buffer = false);
905
void add_draw_list_bind_index_buffer(RDD::BufferID p_buffer, RDD::IndexBufferFormat p_format, uint32_t p_offset);
906
void add_draw_list_bind_pipeline(RDD::PipelineID p_pipeline, BitField<RDD::PipelineStageBits> p_pipeline_stage_bits);
907
void add_draw_list_bind_uniform_set(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index);
908
void add_draw_list_bind_uniform_sets(RDD::ShaderID p_shader, VectorView<RDD::UniformSetID> p_uniform_set, uint32_t p_first_index, uint32_t p_set_count);
909
void add_draw_list_bind_vertex_buffers(Span<RDD::BufferID> p_vertex_buffers, Span<uint64_t> p_vertex_buffer_offsets);
910
void add_draw_list_clear_attachments(VectorView<RDD::AttachmentClear> p_attachments_clear, VectorView<Rect2i> p_attachments_clear_rect);
911
void add_draw_list_draw(uint32_t p_vertex_count, uint32_t p_instance_count);
912
void add_draw_list_draw_indexed(uint32_t p_index_count, uint32_t p_instance_count, uint32_t p_first_index);
913
void add_draw_list_draw_indirect(RDD::BufferID p_buffer, uint32_t p_offset, uint32_t p_draw_count, uint32_t p_stride);
914
void add_draw_list_draw_indexed_indirect(RDD::BufferID p_buffer, uint32_t p_offset, uint32_t p_draw_count, uint32_t p_stride);
915
void add_draw_list_execute_commands(RDD::CommandBufferID p_command_buffer);
916
void add_draw_list_next_subpass(RDD::CommandBufferType p_command_buffer_type);
917
void add_draw_list_set_blend_constants(const Color &p_color);
918
void add_draw_list_set_line_width(float p_width);
919
void add_draw_list_set_push_constant(RDD::ShaderID p_shader, const void *p_data, uint32_t p_data_size);
920
void add_draw_list_set_scissor(Rect2i p_rect);
921
void add_draw_list_set_viewport(Rect2i p_rect);
922
void add_draw_list_uniform_set_prepare_for_use(RDD::ShaderID p_shader, RDD::UniformSetID p_uniform_set, uint32_t set_index);
923
void add_draw_list_usage(ResourceTracker *p_tracker, ResourceUsage p_usage);
924
void add_draw_list_usages(VectorView<ResourceTracker *> p_trackers, VectorView<ResourceUsage> p_usages);
925
void add_draw_list_end();
926
void add_texture_clear_color(RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, const Color &p_color, const RDD::TextureSubresourceRange &p_range);
927
void add_texture_clear_depth_stencil(RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, float p_depth, uint8_t p_stencil, const RDD::TextureSubresourceRange &p_range);
928
void add_texture_copy(RDD::TextureID p_src, ResourceTracker *p_src_tracker, RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, VectorView<RDD::TextureCopyRegion> p_texture_copy_regions);
929
void add_texture_get_data(RDD::TextureID p_src, ResourceTracker *p_src_tracker, RDD::BufferID p_dst, VectorView<RDD::BufferTextureCopyRegion> p_buffer_texture_copy_regions, ResourceTracker *p_dst_tracker = nullptr);
930
void add_texture_resolve(RDD::TextureID p_src, ResourceTracker *p_src_tracker, RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, uint32_t p_src_layer, uint32_t p_src_mipmap, uint32_t p_dst_layer, uint32_t p_dst_mipmap);
931
void add_texture_update(RDD::TextureID p_dst, ResourceTracker *p_dst_tracker, VectorView<RecordedBufferToTextureCopy> p_buffer_copies, VectorView<ResourceTracker *> p_buffer_trackers = VectorView<ResourceTracker *>());
932
void add_capture_timestamp(RDD::QueryPoolID p_query_pool, uint32_t p_index);
933
void add_synchronization();
934
void begin_label(const Span<char> &p_label_name, const Color &p_color);
935
void end_label();
936
void end(bool p_reorder_commands, bool p_full_barriers, RDD::CommandBufferID &r_command_buffer, CommandBufferPool &r_command_buffer_pool);
937
static ResourceTracker *resource_tracker_create();
938
static void resource_tracker_free(ResourceTracker *p_tracker);
939
static FramebufferCache *framebuffer_cache_create();
940
static void framebuffer_cache_free(RDD *p_driver, FramebufferCache *p_cache);
941
};
942
943
using RDG = RenderingDeviceGraph;
944
945