From e61cc0234a748caa5c979bd26865e5cfa8d47fdd Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Wed, 9 Feb 2022 11:12:01 +0100 Subject: [PATCH] vkd3d: Allow debug ring to know about device lost scenarios. For this case, we want to block and teardown the debug ring thread. It's okay to fish for dead messages in the ring, since we know there won't be more GPU work submitted. Signed-off-by: Hans-Kristian Arntzen --- libs/vkd3d/command.c | 3 +-- libs/vkd3d/debug_ring.c | 22 ++++++++++++++++++++++ libs/vkd3d/vkd3d_private.h | 6 ++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 83b1aac2..d54deb36 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -359,8 +359,7 @@ static void vkd3d_wait_for_gpu_timeline_semaphore(struct vkd3d_fence_worker *wor } /* This is a good time to kick the debug threads into action. */ - if (device->debug_ring.active) - pthread_cond_signal(&device->debug_ring.ring_cond); + vkd3d_shader_debug_ring_kick(&device->debug_ring, device, false); vkd3d_descriptor_debug_kick_qa_check(device->descriptor_qa_global_info); TRACE("Signaling fence %p value %#"PRIx64".\n", fence->fence, fence->value); diff --git a/libs/vkd3d/debug_ring.c b/libs/vkd3d/debug_ring.c index 8a0e7d9f..c63b0092 100644 --- a/libs/vkd3d/debug_ring.c +++ b/libs/vkd3d/debug_ring.c @@ -358,3 +358,25 @@ void vkd3d_shader_debug_ring_cleanup(struct vkd3d_shader_debug_ring *ring, vkd3d_free_device_memory(device, &ring->host_buffer_memory); vkd3d_free_device_memory(device, &ring->device_atomic_buffer_memory); } + +static pthread_mutex_t debug_ring_teardown_lock = PTHREAD_MUTEX_INITIALIZER; + +void vkd3d_shader_debug_ring_kick(struct vkd3d_shader_debug_ring *ring, struct d3d12_device *device, bool device_lost) +{ + if (device_lost) + { + /* Need a global lock here since multiple threads can observe device lost at the same time. */ + pthread_mutex_lock(&debug_ring_teardown_lock); + { + ring->device_lost = true; + /* We're going to die or hang after this most likely, so make sure we get to see all messages the + * GPU had to write. Just cleanup now. */ + vkd3d_shader_debug_ring_cleanup(ring, device); + } + pthread_mutex_unlock(&debug_ring_teardown_lock); + } + else + { + pthread_cond_signal(&ring->ring_cond); + } +} diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 05deec1f..cd31f1bf 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -2327,6 +2327,7 @@ struct vkd3d_shader_debug_ring pthread_t ring_thread; pthread_mutex_t ring_lock; pthread_cond_t ring_cond; + bool device_lost; bool active; }; @@ -2349,6 +2350,9 @@ void vkd3d_shader_debug_ring_cleanup(struct vkd3d_shader_debug_ring *state, void *vkd3d_shader_debug_ring_thread_main(void *arg); void vkd3d_shader_debug_ring_init_spec_constant(struct d3d12_device *device, struct vkd3d_shader_debug_ring_spec_info *info, vkd3d_shader_hash_t hash); +/* If we assume device lost, try really hard to fish for messages. */ +void vkd3d_shader_debug_ring_kick(struct vkd3d_shader_debug_ring *state, + struct d3d12_device *device, bool device_lost); enum vkd3d_breadcrumb_command_type { @@ -2481,9 +2485,11 @@ void vkd3d_breadcrumb_tracer_end_command_list(struct d3d12_command_list *list); } \ } while(0) +/* Remember to kick debug ring as well. */ #define VKD3D_DEVICE_REPORT_BREADCRUMB_IF(device, cond) do { \ if ((vkd3d_config_flags & VKD3D_CONFIG_FLAG_BREADCRUMBS) && (cond)) { \ vkd3d_breadcrumb_tracer_report_device_lost(&(device)->breadcrumb_tracer, device); \ + vkd3d_shader_debug_ring_kick(&(device)->debug_ring, device, true); \ } \ } while(0) #else