From 0d81c1e6535e0bc957aab043b02911dc01bca7e2 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Thu, 30 Jun 2022 13:10:41 +0200 Subject: [PATCH] vkd3d: Add full tracing of every submitted command list. Replays relevant commands in submission order. Signed-off-by: Hans-Kristian Arntzen --- include/vkd3d.h | 1 + libs/vkd3d/breadcrumbs.c | 16 +++++++++++++++ libs/vkd3d/command.c | 41 ++++++++++++++++++++++++++++++++++++++ libs/vkd3d/device.c | 1 + libs/vkd3d/vkd3d_private.h | 10 ++++++++++ 5 files changed, 69 insertions(+) diff --git a/include/vkd3d.h b/include/vkd3d.h index 907e4f0fa5..d1bfec3ac8 100644 --- a/include/vkd3d.h +++ b/include/vkd3d.h @@ -92,6 +92,7 @@ extern "C" { #define VKD3D_CONFIG_FLAG_ALLOW_SBT_COLLECTION (1ull << 30) #define VKD3D_CONFIG_FLAG_FORCE_NATIVE_FP16 (1ull << 31) #define VKD3D_CONFIG_FLAG_USE_HOST_IMPORT_FALLBACK (1ull << 32) +#define VKD3D_CONFIG_FLAG_BREADCRUMBS_TRACE (1ull << 33) typedef HRESULT (*PFN_vkd3d_signal_event)(HANDLE event); diff --git a/libs/vkd3d/breadcrumbs.c b/libs/vkd3d/breadcrumbs.c index 5e708db2c5..2917b227a4 100644 --- a/libs/vkd3d/breadcrumbs.c +++ b/libs/vkd3d/breadcrumbs.c @@ -295,8 +295,11 @@ static void vkd3d_breadcrumb_tracer_report_command_list( const struct vkd3d_breadcrumb_command *cmd; bool observed_begin_cmd = false; bool observed_end_cmd = false; + bool ignore_markers; unsigned int i; + ignore_markers = begin_marker == UINT32_MAX && end_marker == UINT32_MAX; + if (end_marker == 0) { ERR(" ===== Potential crash region BEGIN (make sure RADV_DEBUG=syncshaders is used for maximum accuracy) =====\n"); @@ -309,6 +312,12 @@ static void vkd3d_breadcrumb_tracer_report_command_list( { cmd = &context->commands[i]; + if (ignore_markers && (cmd->type == VKD3D_BREADCRUMB_COMMAND_SET_TOP_MARKER || + cmd->type == VKD3D_BREADCRUMB_COMMAND_SET_BOTTOM_MARKER)) + { + continue; + } + /* If there is a command which sets TOP_OF_PIPE, but we haven't observed the marker yet, * the command processor hasn't gotten there yet (most likely ...), so that should be the * natural end-point. */ @@ -368,6 +377,13 @@ static void vkd3d_breadcrumb_tracer_report_command_list( } } +void vkd3d_breadcrumb_tracer_dump_command_list(struct vkd3d_breadcrumb_tracer *tracer, + unsigned int index) +{ + vkd3d_breadcrumb_tracer_report_command_list(&tracer->trace_contexts[index], + UINT32_MAX, UINT32_MAX); +} + static void vkd3d_breadcrumb_tracer_report_command_list_amd(struct vkd3d_breadcrumb_tracer *tracer, unsigned int context_index) { diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 059c673dd1..5014838744 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -11894,6 +11894,9 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm size_t num_transitions, num_command_buffers; struct d3d12_command_queue_submission sub; struct d3d12_command_list *cmd_list; +#ifdef VKD3D_ENABLE_BREADCRUMBS + unsigned int *breadcrumb_indices; +#endif VkCommandBuffer *buffers; LONG **outstanding; unsigned int i, j; @@ -11942,6 +11945,19 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm return; } +#ifdef VKD3D_ENABLE_BREADCRUMBS + if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_BREADCRUMBS_TRACE) + { + if (!(breadcrumb_indices = vkd3d_malloc(sizeof(unsigned int) * command_list_count))) + { + vkd3d_free(outstanding); + vkd3d_free(buffers); + } + } + else + breadcrumb_indices = NULL; +#endif + sub.execute.debug_capture = false; num_transitions = 0; @@ -11956,6 +11972,9 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm "Command list %p is in recording state.\n", command_lists[i]); vkd3d_free(outstanding); vkd3d_free(buffers); +#ifdef VKD3D_ENABLE_BREADCRUMBS + vkd3d_free(breadcrumb_indices); +#endif return; } @@ -11969,6 +11988,11 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm buffers[j++] = cmd_list->vk_command_buffer; if (cmd_list->debug_capture) sub.execute.debug_capture = true; + +#ifdef VKD3D_ENABLE_BREADCRUMBS + if (breadcrumb_indices) + breadcrumb_indices[i] = cmd_list->breadcrumb_context_index; +#endif } /* Append a full GPU barrier between submissions. @@ -12009,6 +12033,10 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm sub.execute.cmd_count = num_command_buffers; sub.execute.outstanding_submissions_counters = outstanding; sub.execute.outstanding_submissions_counter_count = command_list_count; +#ifdef VKD3D_ENABLE_BREADCRUMBS + sub.execute.breadcrumb_indices = breadcrumb_indices; + sub.execute.breadcrumb_indices_count = breadcrumb_indices ? command_list_count : 0; +#endif d3d12_command_queue_add_submission(command_queue, &sub); } @@ -13112,6 +13140,7 @@ static void *d3d12_command_queue_submission_worker_main(void *userdata) struct d3d12_command_queue *queue = userdata; uint64_t transition_timeline_value = 0; VkCommandBuffer transition_cmd; + VKD3D_UNUSED unsigned int i; HRESULT hr; VKD3D_REGION_DECL(queue_wait); @@ -13186,6 +13215,18 @@ static void *d3d12_command_queue_submission_worker_main(void *userdata) * On error, the counters are freed early, so there is no risk of leak. */ vkd3d_free(submission.execute.cmd); vkd3d_free(submission.execute.transitions); +#ifdef VKD3D_ENABLE_BREADCRUMBS + for (i = 0; i < submission.execute.breadcrumb_indices_count; i++) + { + INFO("=== Executing command list context %u on VkQueue %p, queue family %u ===\n", + submission.execute.breadcrumb_indices[i], + (void*)queue->vkd3d_queue->vk_queue, queue->vkd3d_queue->vk_family_index); + vkd3d_breadcrumb_tracer_dump_command_list(&queue->device->breadcrumb_tracer, + submission.execute.breadcrumb_indices[i]); + INFO("============================\n"); + } + vkd3d_free(submission.execute.breadcrumb_indices); +#endif VKD3D_REGION_END(queue_execute); break; diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index 1283556d58..110f006d79 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -716,6 +716,7 @@ static const struct vkd3d_debug_option vkd3d_config_options[] = {"force_raw_va_cbv", VKD3D_CONFIG_FLAG_FORCE_RAW_VA_CBV}, {"allow_sbt_collection", VKD3D_CONFIG_FLAG_ALLOW_SBT_COLLECTION}, {"host_import_fallback", VKD3D_CONFIG_FLAG_USE_HOST_IMPORT_FALLBACK}, + {"breadcrumbs_trace", VKD3D_CONFIG_FLAG_BREADCRUMBS | VKD3D_CONFIG_FLAG_BREADCRUMBS_TRACE}, }; static void vkd3d_config_flags_init_once(void) diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 8e95aabffe..77823f2d01 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -2528,6 +2528,12 @@ struct d3d12_command_queue_submission_execute struct vkd3d_initial_transition *transitions; size_t transition_count; +#ifdef VKD3D_ENABLE_BREADCRUMBS + /* Replays commands in submission order for heavy debug. */ + unsigned int *breadcrumb_indices; + size_t breadcrumb_indices_count; +#endif + bool debug_capture; }; @@ -2838,6 +2844,10 @@ void vkd3d_breadcrumb_tracer_register_placed_resource(struct d3d12_heap *heap, s VkDeviceSize heap_offset, VkDeviceSize required_size); void vkd3d_breadcrumb_tracer_unregister_placed_resource(struct d3d12_heap *heap, struct d3d12_resource *resource); +/* For heavy debug, replays the trace stream in submission order. */ +void vkd3d_breadcrumb_tracer_dump_command_list(struct vkd3d_breadcrumb_tracer *tracer, + unsigned int index); + #define VKD3D_BREADCRUMB_COMMAND(cmd_type) do { \ if (vkd3d_config_flags & VKD3D_CONFIG_FLAG_BREADCRUMBS) { \ struct vkd3d_breadcrumb_command breadcrumb_cmd; \