From bf8ecd3a9d4b4eba33379c28a3fae82436f50737 Mon Sep 17 00:00:00 2001 From: Dario Date: Mon, 11 Nov 2024 10:31:12 -0300 Subject: [PATCH] Give the barrier pool its own mutex to avoid a deadlock with transfer workers. --- servers/rendering/rendering_device.cpp | 13 ++++++++----- servers/rendering/rendering_device.h | 2 ++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index cc67873b242..ab5de3cb7fd 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -5272,14 +5272,13 @@ void RenderingDevice::_wait_for_transfer_worker(TransferWorker *p_transfer_worke p_transfer_worker->operations_processed = p_transfer_worker->operations_submitted; } - if (!p_transfer_worker->texture_barriers.is_empty()) { - MutexLock transfer_worker_lock(transfer_worker_pool_mutex); - _flush_barriers_for_transfer_worker(p_transfer_worker); - } + _flush_barriers_for_transfer_worker(p_transfer_worker); } void RenderingDevice::_flush_barriers_for_transfer_worker(TransferWorker *p_transfer_worker) { + // Caller must have already acquired the mutex for the worker. if (!p_transfer_worker->texture_barriers.is_empty()) { + MutexLock transfer_worker_lock(transfer_worker_pool_texture_barriers_mutex); for (uint32_t i = 0; i < p_transfer_worker->texture_barriers.size(); i++) { transfer_worker_pool_texture_barriers.push_back(p_transfer_worker->texture_barriers[i]); } @@ -5352,8 +5351,11 @@ void RenderingDevice::_submit_transfer_workers(RDD::CommandBufferID p_draw_comma } } } +} - if (p_draw_command_buffer && !transfer_worker_pool_texture_barriers.is_empty()) { +void RenderingDevice::_submit_transfer_barriers(RDD::CommandBufferID p_draw_command_buffer) { + MutexLock transfer_worker_lock(transfer_worker_pool_texture_barriers_mutex); + if (!transfer_worker_pool_texture_barriers.is_empty()) { driver->command_pipeline_barrier(p_draw_command_buffer, RDD::PIPELINE_STAGE_COPY_BIT, RDD::PIPELINE_STAGE_ALL_COMMANDS_BIT, {}, {}, transfer_worker_pool_texture_barriers); transfer_worker_pool_texture_barriers.clear(); } @@ -5953,6 +5955,7 @@ void RenderingDevice::_end_frame() { // The command buffer must be copied into a stack variable as the driver workarounds can change the command buffer in use. RDD::CommandBufferID command_buffer = frames[frame].command_buffer; _submit_transfer_workers(command_buffer); + _submit_transfer_barriers(command_buffer); draw_graph.end(RENDER_GRAPH_REORDER, RENDER_GRAPH_FULL_BARRIERS, command_buffer, frames[frame].command_buffer_pool); driver->command_buffer_end(command_buffer); diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h index 9939df976f6..ccfe51043b4 100644 --- a/servers/rendering/rendering_device.h +++ b/servers/rendering/rendering_device.h @@ -1285,6 +1285,7 @@ private: LocalVector transfer_worker_pool_available_list; LocalVector transfer_worker_pool_texture_barriers; BinaryMutex transfer_worker_pool_mutex; + BinaryMutex transfer_worker_pool_texture_barriers_mutex; ConditionVariable transfer_worker_pool_condition; TransferWorker *_acquire_transfer_worker(uint32_t p_transfer_size, uint32_t p_required_align, uint32_t &r_staging_offset); @@ -1299,6 +1300,7 @@ private: void _check_transfer_worker_vertex_array(VertexArray *p_vertex_array); void _check_transfer_worker_index_array(IndexArray *p_index_array); void _submit_transfer_workers(RDD::CommandBufferID p_draw_command_buffer = RDD::CommandBufferID()); + void _submit_transfer_barriers(RDD::CommandBufferID p_draw_command_buffer); void _wait_for_transfer_workers(); void _free_transfer_workers();