diff --git a/include/vkd3d.h b/include/vkd3d.h index 4eebff43..8e5816ff 100644 --- a/include/vkd3d.h +++ b/include/vkd3d.h @@ -89,6 +89,7 @@ extern "C" { #define VKD3D_CONFIG_FLAG_SHADER_CACHE_SYNC (1ull << 27) #define VKD3D_CONFIG_FLAG_FORCE_RAW_VA_CBV (1ull << 28) #define VKD3D_CONFIG_FLAG_ZERO_MEMORY_WORKAROUNDS_COMMITTED_BUFFER_UAV (1ull << 29) +#define VKD3D_CONFIG_FLAG_BREADCRUMBS_TRACE (1ull << 30) typedef HRESULT (*PFN_vkd3d_signal_event)(HANDLE event); diff --git a/libs/vkd3d/breadcrumbs.c b/libs/vkd3d/breadcrumbs.c index b0642b1d..c9d6b295 100644 --- a/libs/vkd3d/breadcrumbs.c +++ b/libs/vkd3d/breadcrumbs.c @@ -291,8 +291,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"); @@ -305,6 +308,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. */ @@ -360,6 +369,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 f0a871f9..3adc5f65 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -11255,6 +11255,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; @@ -11303,6 +11306,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; @@ -11317,6 +11333,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; } @@ -11330,6 +11349,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. @@ -11370,6 +11394,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); } @@ -12473,6 +12501,18 @@ static void *d3d12_command_queue_submission_worker_main(void *userdata) for (i = 0; i < submission.execute.outstanding_submissions_counter_count; i++) InterlockedDecrement(submission.execute.outstanding_submissions_counters[i]); vkd3d_free(submission.execute.outstanding_submissions_counters); +#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 19090951..6ec2821d 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -664,6 +664,7 @@ static const struct vkd3d_debug_option vkd3d_config_options[] = {"pipeline_library_app_cache", VKD3D_CONFIG_FLAG_PIPELINE_LIBRARY_APP_CACHE_ONLY}, {"shader_cache_sync", VKD3D_CONFIG_FLAG_SHADER_CACHE_SYNC}, {"force_raw_va_cbv", VKD3D_CONFIG_FLAG_FORCE_RAW_VA_CBV}, + {"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 2c6229e6..8a7cfa28 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -2373,6 +2373,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; }; @@ -2655,6 +2661,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; \