@@ -140,6 +140,25 @@ RDD::BarrierAccessBits RenderingDeviceGraph::_usage_to_access_bits(ResourceUsage
140
140
#endif
141
141
}
142
142
143
+ bool RenderingDeviceGraph::_check_command_intersection (ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index) const {
144
+ if (p_resource_tracker->usage != RESOURCE_USAGE_ATTACHMENT_COLOR_READ_WRITE && p_resource_tracker->usage != RESOURCE_USAGE_ATTACHMENT_DEPTH_STENCIL_READ_WRITE) {
145
+ // We don't check possible intersections for usages that aren't consecutive color or depth writes.
146
+ return true ;
147
+ }
148
+
149
+ const uint32_t previous_command_data_offset = command_data_offsets[p_previous_command_index];
150
+ const uint32_t current_command_data_offset = command_data_offsets[p_command_index];
151
+ const RecordedDrawListCommand &previous_draw_list_command = *reinterpret_cast <const RecordedDrawListCommand *>(&command_data[previous_command_data_offset]);
152
+ const RecordedDrawListCommand ¤t_draw_list_command = *reinterpret_cast <const RecordedDrawListCommand *>(&command_data[current_command_data_offset]);
153
+ if (previous_draw_list_command.type != RecordedCommand::TYPE_DRAW_LIST || current_draw_list_command.type != RecordedCommand::TYPE_DRAW_LIST) {
154
+ // We don't check possible intersections if both commands aren't draw lists.
155
+ return true ;
156
+ }
157
+
158
+ // We check if the region used by both draw lists have an intersection.
159
+ return previous_draw_list_command.region .intersects (current_draw_list_command.region );
160
+ }
161
+
143
162
int32_t RenderingDeviceGraph::_add_to_command_list (int32_t p_command_index, int32_t p_list_index) {
144
163
DEV_ASSERT (p_command_index < int32_t (command_count));
145
164
DEV_ASSERT (p_list_index < int32_t (command_list_nodes.size ()));
@@ -425,11 +444,9 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr
425
444
#if USE_BUFFER_BARRIERS
426
445
_add_buffer_barrier_to_command (resource_tracker->buffer_driver_id , resource_tracker->usage_access , new_usage_access, r_command->buffer_barrier_index , r_command->buffer_barrier_count );
427
446
#endif
428
- // FIXME: Memory barriers are currently pushed regardless of whether buffer barriers are being used or not. Refer to the comment on the
429
- // definition of USE_BUFFER_BARRIERS for the reason behind this. This can be fixed to be one case or the other once it's been confirmed
430
- // the buffer and memory barrier behavior discrepancy has been solved.
431
- r_command->memory_barrier .src_access = resource_tracker->usage_access ;
432
- r_command->memory_barrier .dst_access = new_usage_access;
447
+ // Memory barriers are pushed regardless of buffer barriers being used or not.
448
+ r_command->memory_barrier .src_access = r_command->memory_barrier .src_access | resource_tracker->usage_access ;
449
+ r_command->memory_barrier .dst_access = r_command->memory_barrier .dst_access | new_usage_access;
433
450
} else {
434
451
DEV_ASSERT (false && " Resource tracker does not contain a valid buffer or texture ID." );
435
452
}
@@ -449,10 +466,12 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr
449
466
450
467
if (different_usage) {
451
468
// Even if the usage of the resource isn't a write usage explicitly, a different usage implies a transition and it should therefore be considered a write.
452
- write_usage = true ;
469
+ // In the case of buffers however, this is not exactly necessary if the driver does not consider different buffer usages as different states.
470
+ write_usage = write_usage || bool (resource_tracker->texture_driver_id ) || driver_buffers_require_transitions;
453
471
resource_tracker->usage = new_resource_usage;
454
472
}
455
473
474
+ bool command_intersection_failed = false ;
456
475
if (search_tracker->write_command_or_list_index >= 0 ) {
457
476
if (search_tracker->write_command_list_enabled ) {
458
477
// Make this command adjacent to any commands that wrote to this resource and intersect with the slice if it applies.
@@ -464,7 +483,7 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr
464
483
if (!resource_has_parent || search_tracker_rect.intersects (write_list_node.subresources )) {
465
484
if (write_list_node.command_index == p_command_index) {
466
485
ERR_FAIL_COND_MSG (!resource_has_parent, " Command can't have itself as a dependency." );
467
- } else {
486
+ } else if ( _check_command_intersection (resource_tracker, write_list_node. command_index , p_command_index)) {
468
487
// Command is dependent on this command. Add this command to the adjacency list of the write command.
469
488
_add_adjacent_command (write_list_node.command_index , p_command_index, r_command);
470
489
@@ -480,6 +499,8 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr
480
499
write_list_index = write_list_node.next_list_index ;
481
500
continue ;
482
501
}
502
+ } else {
503
+ command_intersection_failed = true ;
483
504
}
484
505
}
485
506
@@ -490,14 +511,16 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr
490
511
// The index is just the latest command index that wrote to the resource.
491
512
if (search_tracker->write_command_or_list_index == p_command_index) {
492
513
ERR_FAIL_MSG (" Command can't have itself as a dependency." );
493
- } else {
514
+ } else if ( _check_command_intersection (resource_tracker, search_tracker-> write_command_or_list_index , p_command_index)) {
494
515
_add_adjacent_command (search_tracker->write_command_or_list_index , p_command_index, r_command);
516
+ } else {
517
+ command_intersection_failed = true ;
495
518
}
496
519
}
497
520
}
498
521
499
522
if (write_usage) {
500
- if (resource_has_parent) {
523
+ if (resource_has_parent || command_intersection_failed ) {
501
524
if (!search_tracker->write_command_list_enabled && search_tracker->write_command_or_list_index >= 0 ) {
502
525
// Write command list was not being used but there was a write command recorded. Add a new node with the entire parent resource's subresources and the recorded command index to the list.
503
526
const RDD::TextureSubresourceRange &tracker_subresources = search_tracker->texture_subresources ;
@@ -1318,6 +1341,7 @@ void RenderingDeviceGraph::initialize(RDD *p_driver, RenderingContextDriver::Dev
1318
1341
1319
1342
driver_honors_barriers = driver->api_trait_get (RDD::API_TRAIT_HONORS_PIPELINE_BARRIERS);
1320
1343
driver_clears_with_copy_engine = driver->api_trait_get (RDD::API_TRAIT_CLEARS_WITH_COPY_ENGINE);
1344
+ driver_buffers_require_transitions = driver->api_trait_get (RDD::API_TRAIT_BUFFERS_REQUIRE_TRANSITIONS);
1321
1345
}
1322
1346
1323
1347
void RenderingDeviceGraph::finalize () {
0 commit comments