Browse Source

Merge pull request #98760 from ze2j/optimize_texture_create_shared_from_slice

Optimize shared texture creations
Thaddeus Crews 3 months ago
parent
commit
b743eb96e3
2 changed files with 16 additions and 9 deletions
  1. 15 8
      servers/rendering/rendering_device.cpp
  2. 1 1
      servers/rendering/rendering_device.h

+ 15 - 8
servers/rendering/rendering_device.cpp

@@ -1108,6 +1108,7 @@ RID RenderingDevice::texture_create_shared(const TextureView &p_view, RID p_with
 	// Create view.
 	// Create view.
 
 
 	Texture texture = *src_texture;
 	Texture texture = *src_texture;
+	texture.slice_trackers = nullptr;
 	texture.shared_fallback = nullptr;
 	texture.shared_fallback = nullptr;
 
 
 	RDD::TextureView tv;
 	RDD::TextureView tv;
@@ -1166,8 +1167,6 @@ RID RenderingDevice::texture_create_shared(const TextureView &p_view, RID p_with
 
 
 	ERR_FAIL_COND_V(!texture.driver_id, RID());
 	ERR_FAIL_COND_V(!texture.driver_id, RID());
 
 
-	texture.slice_trackers.clear();
-
 	if (texture.draw_tracker != nullptr) {
 	if (texture.draw_tracker != nullptr) {
 		texture.draw_tracker->reference_count++;
 		texture.draw_tracker->reference_count++;
 	}
 	}
@@ -1262,6 +1261,7 @@ RID RenderingDevice::texture_create_shared_from_slice(const TextureView &p_view,
 	}
 	}
 
 
 	Texture texture = *src_texture;
 	Texture texture = *src_texture;
+	texture.slice_trackers = nullptr;
 	texture.shared_fallback = nullptr;
 	texture.shared_fallback = nullptr;
 
 
 	get_image_format_required_size(texture.format, texture.width, texture.height, texture.depth, p_mipmap + 1, &texture.width, &texture.height);
 	get_image_format_required_size(texture.format, texture.width, texture.height, texture.depth, p_mipmap + 1, &texture.width, &texture.height);
@@ -5873,9 +5873,12 @@ bool RenderingDevice::_texture_make_mutable(Texture *p_texture, RID p_texture_id
 					p_texture->draw_tracker->reference_count++;
 					p_texture->draw_tracker->reference_count++;
 				} else {
 				} else {
 					// Slice texture.
 					// Slice texture.
-					HashMap<Rect2i, RDG::ResourceTracker *>::ConstIterator draw_tracker_iterator = owner_texture->slice_trackers.find(p_texture->slice_rect);
+					if (owner_texture->slice_trackers == nullptr) {
+						owner_texture->slice_trackers = memnew((HashMap<Rect2i, RDG::ResourceTracker *>));
+					}
+					HashMap<Rect2i, RDG::ResourceTracker *>::ConstIterator draw_tracker_iterator = owner_texture->slice_trackers->find(p_texture->slice_rect);
 					RDG::ResourceTracker *draw_tracker = nullptr;
 					RDG::ResourceTracker *draw_tracker = nullptr;
-					if (draw_tracker_iterator != owner_texture->slice_trackers.end()) {
+					if (draw_tracker_iterator != owner_texture->slice_trackers->end()) {
 						// Reuse the tracker at the matching rectangle.
 						// Reuse the tracker at the matching rectangle.
 						draw_tracker = draw_tracker_iterator->value;
 						draw_tracker = draw_tracker_iterator->value;
 					} else {
 					} else {
@@ -5887,10 +5890,9 @@ bool RenderingDevice::_texture_make_mutable(Texture *p_texture, RID p_texture_id
 						draw_tracker->texture_subresources = p_texture->barrier_range();
 						draw_tracker->texture_subresources = p_texture->barrier_range();
 						draw_tracker->texture_usage = p_texture->usage_flags;
 						draw_tracker->texture_usage = p_texture->usage_flags;
 						draw_tracker->texture_slice_or_dirty_rect = p_texture->slice_rect;
 						draw_tracker->texture_slice_or_dirty_rect = p_texture->slice_rect;
-						owner_texture->slice_trackers[p_texture->slice_rect] = draw_tracker;
+						(*owner_texture->slice_trackers)[p_texture->slice_rect] = draw_tracker;
 					}
 					}
 
 
-					p_texture->slice_trackers.clear();
 					p_texture->draw_tracker = draw_tracker;
 					p_texture->draw_tracker = draw_tracker;
 					p_texture->draw_tracker->reference_count++;
 					p_texture->draw_tracker->reference_count++;
 				}
 				}
@@ -6049,8 +6051,13 @@ void RenderingDevice::_free_internal(RID p_id) {
 				if (texture->owner.is_valid() && (texture->slice_type != TEXTURE_SLICE_MAX)) {
 				if (texture->owner.is_valid() && (texture->slice_type != TEXTURE_SLICE_MAX)) {
 					// If this was a texture slice, erase the tracker from the map.
 					// If this was a texture slice, erase the tracker from the map.
 					Texture *owner_texture = texture_owner.get_or_null(texture->owner);
 					Texture *owner_texture = texture_owner.get_or_null(texture->owner);
-					if (owner_texture != nullptr) {
-						owner_texture->slice_trackers.erase(texture->slice_rect);
+					if (owner_texture != nullptr && owner_texture->slice_trackers != nullptr) {
+						owner_texture->slice_trackers->erase(texture->slice_rect);
+
+						if (owner_texture->slice_trackers->is_empty()) {
+							memdelete(owner_texture->slice_trackers);
+							owner_texture->slice_trackers = nullptr;
+						}
 					}
 					}
 				}
 				}
 			}
 			}

+ 1 - 1
servers/rendering/rendering_device.h

@@ -321,7 +321,7 @@ public:
 		RID owner;
 		RID owner;
 
 
 		RDG::ResourceTracker *draw_tracker = nullptr;
 		RDG::ResourceTracker *draw_tracker = nullptr;
-		HashMap<Rect2i, RDG::ResourceTracker *> slice_trackers;
+		HashMap<Rect2i, RDG::ResourceTracker *> *slice_trackers = nullptr;
 		SharedFallback *shared_fallback = nullptr;
 		SharedFallback *shared_fallback = nullptr;
 		int32_t transfer_worker_index = -1;
 		int32_t transfer_worker_index = -1;
 		uint64_t transfer_worker_operation = 0;
 		uint64_t transfer_worker_operation = 0;