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 <post@arntzen-software.no>
This commit is contained in:
Hans-Kristian Arntzen 2022-02-09 11:12:01 +01:00
parent c54895b4b7
commit e61cc0234a
3 changed files with 29 additions and 2 deletions

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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