Browse Source

Make draw/compute lists threadsafe

Lock the rendering device while command buffers are in use
Brian Semrau 3 years ago
parent
commit
f123a79170

+ 12 - 0
drivers/vulkan/rendering_device_vulkan.cpp

@@ -7574,6 +7574,9 @@ Error RenderingDeviceVulkan::draw_list_switch_to_next_pass_split(uint32_t p_spli
 }
 
 Error RenderingDeviceVulkan::_draw_list_allocate(const Rect2i &p_viewport, uint32_t p_splits, uint32_t p_subpass) {
+	// Lock while draw_list is active
+	_THREAD_SAFE_LOCK_
+
 	if (p_splits == 0) {
 		draw_list = memnew(DrawList);
 		draw_list->command_buffer = frames[frame].draw_command_buffer;
@@ -7684,6 +7687,9 @@ void RenderingDeviceVulkan::_draw_list_free(Rect2i *r_last_viewport) {
 		memdelete(draw_list);
 		draw_list = nullptr;
 	}
+
+	// draw_list is no longer active
+	_THREAD_SAFE_UNLOCK_
 }
 
 void RenderingDeviceVulkan::draw_list_end(uint32_t p_post_barrier) {
@@ -7797,6 +7803,9 @@ RenderingDevice::ComputeListID RenderingDeviceVulkan::compute_list_begin(bool p_
 	ERR_FAIL_COND_V_MSG(!p_allow_draw_overlap && draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time.");
 	ERR_FAIL_COND_V_MSG(compute_list != nullptr, INVALID_ID, "Only one draw/compute list can be active at the same time.");
 
+	// Lock while compute_list is active
+	_THREAD_SAFE_LOCK_
+
 	compute_list = memnew(ComputeList);
 	compute_list->command_buffer = frames[frame].draw_command_buffer;
 	compute_list->state.allow_draw_overlap = p_allow_draw_overlap;
@@ -8270,6 +8279,9 @@ void RenderingDeviceVulkan::compute_list_end(uint32_t p_post_barrier) {
 
 	memdelete(compute_list);
 	compute_list = nullptr;
+
+	// compute_list is no longer active
+	_THREAD_SAFE_UNLOCK_
 }
 
 void RenderingDeviceVulkan::barrier(uint32_t p_from, uint32_t p_to) {

+ 0 - 1
servers/rendering/rendering_server_default.h

@@ -259,7 +259,6 @@ public:
 			command_queue.push(RSG::storage, &RendererStorage::mesh_initialize, mesh);
 			command_queue.push(RSG::storage, &RendererStorage::mesh_set_blend_shape_count, mesh, p_blend_shape_count);
 			for (int i = 0; i < p_surfaces.size(); i++) {
-				RSG::storage->mesh_add_surface(mesh, p_surfaces[i]);
 				command_queue.push(RSG::storage, &RendererStorage::mesh_add_surface, mesh, p_surfaces[i]);
 			}
 		}