瀏覽代碼

Merge pull request #99073 from DarioSamo/rd-graph-dependency-fix

Improve graph's detection of intersection between draw lists.
Thaddeus Crews 10 月之前
父節點
當前提交
e71a52dff7
共有 2 個文件被更改,包括 11 次插入10 次删除
  1. 10 9
      servers/rendering/rendering_device_graph.cpp
  2. 1 1
      servers/rendering/rendering_device_graph.h

+ 10 - 9
servers/rendering/rendering_device_graph.cpp

@@ -140,7 +140,7 @@ RDD::BarrierAccessBits RenderingDeviceGraph::_usage_to_access_bits(ResourceUsage
 #endif
 }
 
-bool RenderingDeviceGraph::_check_command_intersection(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index) const {
+bool RenderingDeviceGraph::_check_command_intersection(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index, bool &r_intersection_partial_coverage) const {
 	if (p_resource_tracker->usage != RESOURCE_USAGE_ATTACHMENT_COLOR_READ_WRITE && p_resource_tracker->usage != RESOURCE_USAGE_ATTACHMENT_DEPTH_STENCIL_READ_WRITE) {
 		// We don't check possible intersections for usages that aren't consecutive color or depth writes.
 		return true;
@@ -155,6 +155,11 @@ bool RenderingDeviceGraph::_check_command_intersection(ResourceTracker *p_resour
 		return true;
 	}
 
+	if (!r_intersection_partial_coverage) {
+		// Indicate if this draw list only partially covers the region of the previous draw list.
+		r_intersection_partial_coverage = !current_draw_list_command.region.encloses(previous_draw_list_command.region);
+	}
+
 	// We check if the region used by both draw lists have an intersection.
 	return previous_draw_list_command.region.intersects(current_draw_list_command.region);
 }
@@ -471,7 +476,7 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr
 			resource_tracker->usage = new_resource_usage;
 		}
 
-		bool command_intersection_failed = false;
+		bool intersection_partial_coverage = false;
 		if (search_tracker->write_command_or_list_index >= 0) {
 			if (search_tracker->write_command_list_enabled) {
 				// Make this command adjacent to any commands that wrote to this resource and intersect with the slice if it applies.
@@ -483,7 +488,7 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr
 					if (!resource_has_parent || search_tracker_rect.intersects(write_list_node.subresources)) {
 						if (write_list_node.command_index == p_command_index) {
 							ERR_FAIL_COND_MSG(!resource_has_parent, "Command can't have itself as a dependency.");
-						} else if (_check_command_intersection(resource_tracker, write_list_node.command_index, p_command_index)) {
+						} else if (_check_command_intersection(resource_tracker, write_list_node.command_index, p_command_index, intersection_partial_coverage)) {
 							// Command is dependent on this command. Add this command to the adjacency list of the write command.
 							_add_adjacent_command(write_list_node.command_index, p_command_index, r_command);
 
@@ -499,8 +504,6 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr
 								write_list_index = write_list_node.next_list_index;
 								continue;
 							}
-						} else {
-							command_intersection_failed = true;
 						}
 					}
 
@@ -511,16 +514,14 @@ void RenderingDeviceGraph::_add_command_to_graph(ResourceTracker **p_resource_tr
 				// The index is just the latest command index that wrote to the resource.
 				if (search_tracker->write_command_or_list_index == p_command_index) {
 					ERR_FAIL_MSG("Command can't have itself as a dependency.");
-				} else if (_check_command_intersection(resource_tracker, search_tracker->write_command_or_list_index, p_command_index)) {
+				} else if (_check_command_intersection(resource_tracker, search_tracker->write_command_or_list_index, p_command_index, intersection_partial_coverage)) {
 					_add_adjacent_command(search_tracker->write_command_or_list_index, p_command_index, r_command);
-				} else {
-					command_intersection_failed = true;
 				}
 			}
 		}
 
 		if (write_usage) {
-			if (resource_has_parent || command_intersection_failed) {
+			if (resource_has_parent || intersection_partial_coverage) {
 				if (!search_tracker->write_command_list_enabled && search_tracker->write_command_or_list_index >= 0) {
 					// 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.
 					const RDD::TextureSubresourceRange &tracker_subresources = search_tracker->texture_subresources;

+ 1 - 1
servers/rendering/rendering_device_graph.h

@@ -649,7 +649,7 @@ private:
 	static bool _is_write_usage(ResourceUsage p_usage);
 	static RDD::TextureLayout _usage_to_image_layout(ResourceUsage p_usage);
 	static RDD::BarrierAccessBits _usage_to_access_bits(ResourceUsage p_usage);
-	bool _check_command_intersection(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index) const;
+	bool _check_command_intersection(ResourceTracker *p_resource_tracker, int32_t p_previous_command_index, int32_t p_command_index, bool &r_intersection_partial_coverage) const;
 	int32_t _add_to_command_list(int32_t p_command_index, int32_t p_list_index);
 	void _add_adjacent_command(int32_t p_previous_command_index, int32_t p_command_index, RecordedCommand *r_command);
 	int32_t _add_to_slice_read_list(int32_t p_command_index, Rect2i p_subresources, int32_t p_list_index);