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