From 62c2cebda1e778f676a65baf58e2c7a7247fd27b Mon Sep 17 00:00:00 2001 From: Locke Lin Date: Fri, 11 Oct 2024 15:38:08 -0600 Subject: [PATCH 1/3] Dump root parameters, insted of descriptor heap 1. Dump SetXXXRootDescriptorTable, SetXXXRootConstantBufferView, SetXXXRootShaderResourceView, SetXXXRootUnorderedAccessView, instead of descriptor heap. Root parameters are more straightforward since they are used by shaders. 2. Find RootParameters info in dx12_browse_consumer.h and Dx12DumpResources::CreateRootSignature, and then dump them. 3. Dump some infos about root parameters. Although root_signature_type and cmd_bind_type are the same thing, but I saw some titles that they were different, so I chose to write both. That's mistakes and should trigger validation log. Added a function Dx12DumpResourcesDelegate::WriteNote to write some help info into .json, like some mistakes are found. 4. Added two flags in dx12_dump_resources.cpp: TEST_WRITE_NOT_FOUND_VIEWS,TEST_WRITE_NULL_RESOURCE_VIEWS. The NumDescriptors in RootParameters could be large, but the index might not be found in cbv_srv_uav_infos of D3D12DescriptorHeapInfo. Set TEST_WRITE_NOT_FOUND_VIEWS: true to write the heap index info even if the index isn't found. Set false to skip it. BufferLocation in CreateConstantBufferView or pResource in CreateShaderResourceView or CreateUnorderedAccessView could be 0. Set TEST_WRITE_NULL_RESOURCE_VIEWS: true to write the heap index info even if the value is 0. Set false to skip it. 5. CreateConstantBufferView, CreateShaderResourceView and CreateUnorderedAccessView could set the same DestDescriptor. The newer view setting could override it to get the DestDescriptor. The older view setting is quit. In this case, changed these struct infos into one struct info. 6. If the target drawcall is dispatch, dump compute root parameters. If it's not, dump graphics. But if it's ExecuteIndirect, dump both graphics and compute root parameters, since we don't know what it's inside. 7. CaptureGPUAddrMatchDescriptorHeap find the index of the heap for the address of root descriptor tables. Use the index to find the view in the map in the heap. Not using MatchDescriptorCPUGPUHandle and "for loop" to find the view any more. MatchDescriptorCPUGPUHandle has a bug to find a wrong view. RelayCPUAddrMatchDescriptorHeap find the index of the heap for the address of rtvs and dsv. Use the index to find the view in the map in the heap. 8. Skip dump vertices, index, rtv and dsv if the taget drawcall is dispatch. --- .../decode/custom_dx12_replay_commands.h | 10 + framework/decode/dx12_browse_consumer.h | 305 +++- framework/decode/dx12_dump_resources.cpp | 1237 ++++++++++++----- framework/decode/dx12_dump_resources.h | 44 + framework/decode/dx12_object_info.h | 56 +- .../decode/dx12_replay_consumer_base.cpp | 317 +++-- framework/decode/dx12_replay_consumer_base.h | 5 + 7 files changed, 1412 insertions(+), 562 deletions(-) diff --git a/framework/decode/custom_dx12_replay_commands.h b/framework/decode/custom_dx12_replay_commands.h index fa0a6084f6..37fd7f35dc 100644 --- a/framework/decode/custom_dx12_replay_commands.h +++ b/framework/decode/custom_dx12_replay_commands.h @@ -74,6 +74,16 @@ struct CustomReplayPostCall +struct CustomReplayPostCall +{ + template + static void Dispatch(Dx12ReplayConsumerBase* replay, Args... args) + { + replay->PostCall_ID3D12Device_CreateSampler(args...); + } +}; + template <> struct CustomReplayPostCall { diff --git a/framework/decode/dx12_browse_consumer.h b/framework/decode/dx12_browse_consumer.h index e643030fe7..d82a107dc8 100644 --- a/framework/decode/dx12_browse_consumer.h +++ b/framework/decode/dx12_browse_consumer.h @@ -47,6 +47,31 @@ struct ExecuteIndirectInfo uint64_t count_offset{ 0 }; }; +struct TrackRootParameter +{ + // These are tracked in commandlist bindings. + D3D12_ROOT_PARAMETER_TYPE cmd_bind_type{}; + D3D12_GPU_DESCRIPTOR_HANDLE cmd_bind_captured_base_descriptor{ kNullGpuAddress }; // RootDescriptorTable + D3D12_GPU_VIRTUAL_ADDRESS cmd_bind_captured_buffer_location; // RootConstantBufferView, RootShaderResourceView, + // RootUnorderedAccessView + // Root32BitConstant has no resources or descriptors info, so no track. + + // These are tracked in Dx12DumpResources::CreateRootSignature. + D3D12_ROOT_PARAMETER_TYPE root_signature_type{}; + std::vector root_signature_descriptor_tables; // D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE + + // The other parameter types have no resources or descriptors info, so no track. +}; + +enum DumpDrawCallType +{ + kUnknown, + kDraw, + kDispatch, + kIndirect, + kBundle +}; + struct TrackDumpDrawCall { DumpResourcesTarget dump_resources_target{}; @@ -56,8 +81,9 @@ struct TrackDumpDrawCall uint64_t begin_renderpass_block_index{ 0 }; uint64_t end_renderpass_block_index{ 0 }; uint64_t set_render_targets_block_index{ 0 }; - format::HandleId root_signature_handle_id{ format::kNullHandleId }; - bool is_draw{ false }; // true: DrawInstanced, DrawIndexedInstanced, false: Dispatch, ExecuteIndirect, ExecuteBundle + format::HandleId compute_root_signature_handle_id{ format::kNullHandleId }; + format::HandleId graphics_root_signature_handle_id{ format::kNullHandleId }; + DumpDrawCallType drawcall_type{ DumpDrawCallType::kUnknown }; // vertex std::vector captured_vertex_buffer_views; @@ -66,8 +92,9 @@ struct TrackDumpDrawCall D3D12_INDEX_BUFFER_VIEW captured_index_buffer_view{}; // descriptor - std::vector descriptor_heap_ids; - std::map captured_descriptor_gpu_handles; + std::vector descriptor_heap_ids; + std::unordered_map compute_root_parameters; + std::unordered_map graphics_root_parameters; // ExecuteIndirect ExecuteIndirectInfo execute_indirect_info{}; @@ -84,9 +111,13 @@ struct TrackDumpDrawCall { captured_vertex_buffer_views.clear(); descriptor_heap_ids.clear(); - captured_descriptor_gpu_handles.clear(); - bundle_commandlist_id = format::kNullHandleId; - bundle_target_draw_call = nullptr; + compute_root_parameters.clear(); + graphics_root_parameters.clear(); + compute_root_signature_handle_id = format::kNullHandleId; + graphics_root_signature_handle_id = format::kNullHandleId; + bundle_commandlist_id = format::kNullHandleId; + bundle_target_draw_call = nullptr; + drawcall_type = DumpDrawCallType::kUnknown; } }; @@ -95,7 +126,8 @@ struct TrackDumpCommandList uint64_t begin_block_index{ 0 }; uint64_t current_begin_renderpass_block_index{ 0 }; uint64_t current_set_render_targets_block_index{ 0 }; - format::HandleId current_root_signature_handle_id{ format::kNullHandleId }; + format::HandleId current_compute_root_signature_handle_id{ format::kNullHandleId }; + format::HandleId current_graphics_root_signature_handle_id{ format::kNullHandleId }; // vertex std::vector current_captured_vertex_buffer_views; @@ -104,8 +136,9 @@ struct TrackDumpCommandList D3D12_INDEX_BUFFER_VIEW current_captured_index_buffer_view{}; // descriptor - std::vector current_descriptor_heap_ids; - std::map current_captured_descriptor_gpu_handles; + std::vector current_descriptor_heap_ids; + std::unordered_map current_compute_root_parameters; + std::unordered_map current_graphics_root_parameters; // render target // Track render target info in replay, not here. @@ -118,10 +151,13 @@ struct TrackDumpCommandList begin_block_index = 0; current_begin_renderpass_block_index = 0; current_set_render_targets_block_index = 0; + current_compute_root_signature_handle_id = format::kNullHandleId; + current_graphics_root_signature_handle_id = format::kNullHandleId; current_captured_vertex_buffer_views.clear(); current_captured_index_buffer_view = {}; current_descriptor_heap_ids.clear(); - current_captured_descriptor_gpu_handles.clear(); + current_compute_root_parameters.clear(); + current_graphics_root_parameters.clear(); track_dump_draw_calls.clear(); } }; @@ -260,7 +296,7 @@ class Dx12BrowseConsumer : public Dx12Consumer auto it = track_commandlist_infos_.find(object_id); if (it != track_commandlist_infos_.end()) { - it->second.current_root_signature_handle_id = pRootSignature; + it->second.current_compute_root_signature_handle_id = pRootSignature; } } } @@ -274,7 +310,7 @@ class Dx12BrowseConsumer : public Dx12Consumer auto it = track_commandlist_infos_.find(object_id); if (it != track_commandlist_infos_.end()) { - it->second.current_root_signature_handle_id = pRootSignature; + it->second.current_graphics_root_signature_handle_id = pRootSignature; } } } @@ -341,7 +377,6 @@ class Dx12BrowseConsumer : public Dx12Consumer { it->second.current_descriptor_heap_ids[i] = heap_ids[i]; } - it->second.current_captured_descriptor_gpu_handles.clear(); } } } @@ -357,8 +392,10 @@ class Dx12BrowseConsumer : public Dx12Consumer auto it = track_commandlist_infos_.find(object_id); if (it != track_commandlist_infos_.end()) { - it->second.current_captured_descriptor_gpu_handles[RootParameterIndex] = - (*BaseDescriptor.decoded_value); + TrackRootParameter param = {}; + param.cmd_bind_type = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + param.cmd_bind_captured_base_descriptor = (*BaseDescriptor.decoded_value); + it->second.current_compute_root_parameters[RootParameterIndex] = param; } } } @@ -374,12 +411,202 @@ class Dx12BrowseConsumer : public Dx12Consumer auto it = track_commandlist_infos_.find(object_id); if (it != track_commandlist_infos_.end()) { - it->second.current_captured_descriptor_gpu_handles[RootParameterIndex] = - (*BaseDescriptor.decoded_value); + TrackRootParameter param = {}; + param.cmd_bind_type = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + param.cmd_bind_captured_base_descriptor = (*BaseDescriptor.decoded_value); + it->second.current_graphics_root_parameters[RootParameterIndex] = param; + } + } + } + + virtual void Process_ID3D12GraphicsCommandList_SetComputeRoot32BitConstant(const ApiCallInfo& call_info, + format::HandleId object_id, + UINT RootParameterIndex, + UINT SrcData, + UINT DestOffsetIn32BitValues) + { + if (target_command_list_ == format::kNullHandleId) + { + auto it = track_commandlist_infos_.find(object_id); + if (it != track_commandlist_infos_.end()) + { + TrackRootParameter param = {}; + param.cmd_bind_type = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + it->second.current_compute_root_parameters[RootParameterIndex] = param; + } + } + } + + virtual void Process_ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant(const ApiCallInfo& call_info, + format::HandleId object_id, + UINT RootParameterIndex, + UINT SrcData, + UINT DestOffsetIn32BitValues) + { + if (target_command_list_ == format::kNullHandleId) + { + auto it = track_commandlist_infos_.find(object_id); + if (it != track_commandlist_infos_.end()) + { + TrackRootParameter param = {}; + param.cmd_bind_type = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + it->second.current_graphics_root_parameters[RootParameterIndex] = param; + } + } + } + + virtual void Process_ID3D12GraphicsCommandList_SetComputeRoot32BitConstants(const ApiCallInfo& call_info, + format::HandleId object_id, + UINT RootParameterIndex, + UINT Num32BitValuesToSet, + PointerDecoder* pSrcData, + UINT DestOffsetIn32BitValues) + { + if (target_command_list_ == format::kNullHandleId) + { + auto it = track_commandlist_infos_.find(object_id); + if (it != track_commandlist_infos_.end()) + { + TrackRootParameter param = {}; + param.cmd_bind_type = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + it->second.current_compute_root_parameters[RootParameterIndex] = param; } } } + virtual void Process_ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants(const ApiCallInfo& call_info, + format::HandleId object_id, + UINT RootParameterIndex, + UINT Num32BitValuesToSet, + PointerDecoder* pSrcData, + UINT DestOffsetIn32BitValues) + { + if (target_command_list_ == format::kNullHandleId) + { + auto it = track_commandlist_infos_.find(object_id); + if (it != track_commandlist_infos_.end()) + { + TrackRootParameter param = {}; + param.cmd_bind_type = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + it->second.current_graphics_root_parameters[RootParameterIndex] = param; + } + } + } + + virtual void + Process_ID3D12GraphicsCommandList_SetComputeRootConstantBufferView(const ApiCallInfo& call_info, + format::HandleId object_id, + UINT RootParameterIndex, + D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) + { + if (target_command_list_ == format::kNullHandleId) + { + auto it = track_commandlist_infos_.find(object_id); + if (it != track_commandlist_infos_.end()) + { + TrackRootParameter param = {}; + param.cmd_bind_type = D3D12_ROOT_PARAMETER_TYPE_CBV; + param.cmd_bind_captured_buffer_location = BufferLocation; + it->second.current_compute_root_parameters[RootParameterIndex] = param; + } + } + } + + virtual void + Process_ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(const ApiCallInfo& call_info, + format::HandleId object_id, + UINT RootParameterIndex, + D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) + { + if (target_command_list_ == format::kNullHandleId) + { + auto it = track_commandlist_infos_.find(object_id); + if (it != track_commandlist_infos_.end()) + { + TrackRootParameter param = {}; + param.cmd_bind_type = D3D12_ROOT_PARAMETER_TYPE_CBV; + param.cmd_bind_captured_buffer_location = BufferLocation; + it->second.current_graphics_root_parameters[RootParameterIndex] = param; + } + } + } + + virtual void + Process_ID3D12GraphicsCommandList_SetComputeRootShaderResourceView(const ApiCallInfo& call_info, + format::HandleId object_id, + UINT RootParameterIndex, + D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) + { + if (target_command_list_ == format::kNullHandleId) + { + auto it = track_commandlist_infos_.find(object_id); + if (it != track_commandlist_infos_.end()) + { + TrackRootParameter param = {}; + param.cmd_bind_type = D3D12_ROOT_PARAMETER_TYPE_SRV; + param.cmd_bind_captured_buffer_location = BufferLocation; + it->second.current_compute_root_parameters[RootParameterIndex] = param; + } + } + } + + virtual void + Process_ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(const ApiCallInfo& call_info, + format::HandleId object_id, + UINT RootParameterIndex, + D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) + { + if (target_command_list_ == format::kNullHandleId) + { + auto it = track_commandlist_infos_.find(object_id); + if (it != track_commandlist_infos_.end()) + { + TrackRootParameter param = {}; + param.cmd_bind_type = D3D12_ROOT_PARAMETER_TYPE_SRV; + param.cmd_bind_captured_buffer_location = BufferLocation; + it->second.current_graphics_root_parameters[RootParameterIndex] = param; + } + } + } + + virtual void + Process_ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(const ApiCallInfo& call_info, + format::HandleId object_id, + UINT RootParameterIndex, + D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) + { + if (target_command_list_ == format::kNullHandleId) + { + auto it = track_commandlist_infos_.find(object_id); + if (it != track_commandlist_infos_.end()) + { + TrackRootParameter param = {}; + param.cmd_bind_type = D3D12_ROOT_PARAMETER_TYPE_UAV; + param.cmd_bind_captured_buffer_location = BufferLocation; + it->second.current_compute_root_parameters[RootParameterIndex] = param; + } + } + } + + virtual void + Process_ID3D12GraphicsCommandList_SetGraphicsRootUnorderedAccessView(const ApiCallInfo& call_info, + format::HandleId object_id, + UINT RootParameterIndex, + D3D12_GPU_VIRTUAL_ADDRESS BufferLocation) + { + if (target_command_list_ == format::kNullHandleId) + { + auto it = track_commandlist_infos_.find(object_id); + if (it != track_commandlist_infos_.end()) + { + TrackRootParameter param = {}; + param.cmd_bind_type = D3D12_ROOT_PARAMETER_TYPE_UAV; + param.cmd_bind_captured_buffer_location = BufferLocation; + it->second.current_graphics_root_parameters[RootParameterIndex] = param; + } + } + } + virtual void Process_ID3D12GraphicsCommandList_DrawInstanced(const ApiCallInfo& call_info, format::HandleId object_id, UINT VertexCountPerInstance, @@ -387,7 +614,7 @@ class Dx12BrowseConsumer : public Dx12Consumer UINT StartVertexLocation, UINT StartInstanceLocation) { - TrackTargetDrawCall(call_info, object_id, true); + TrackTargetDrawCall(call_info, object_id, DumpDrawCallType::kDraw); } virtual void Process_ID3D12GraphicsCommandList_DrawIndexedInstanced(const ApiCallInfo& call_info, @@ -398,7 +625,7 @@ class Dx12BrowseConsumer : public Dx12Consumer INT BaseVertexLocation, UINT StartInstanceLocation) { - TrackTargetDrawCall(call_info, object_id, true); + TrackTargetDrawCall(call_info, object_id, DumpDrawCallType::kDraw); } virtual void Process_ID3D12GraphicsCommandList_Dispatch(const ApiCallInfo& call_info, @@ -407,7 +634,7 @@ class Dx12BrowseConsumer : public Dx12Consumer UINT ThreadGroupCountY, UINT ThreadGroupCountZ) { - TrackTargetDrawCall(call_info, object_id, false); + TrackTargetDrawCall(call_info, object_id, DumpDrawCallType::kDispatch); } virtual void Process_ID3D12GraphicsCommandList_ExecuteIndirect(const ApiCallInfo& call_info, @@ -419,16 +646,27 @@ class Dx12BrowseConsumer : public Dx12Consumer format::HandleId pCountBuffer, UINT64 CountBufferOffset) { - TrackTargetDrawCall( - call_info, object_id, false, pArgumentBuffer, ArgumentBufferOffset, pCountBuffer, CountBufferOffset); + TrackTargetDrawCall(call_info, + object_id, + DumpDrawCallType::kIndirect, + pArgumentBuffer, + ArgumentBufferOffset, + pCountBuffer, + CountBufferOffset); } virtual void Process_ID3D12GraphicsCommandList_ExecuteBundle(const ApiCallInfo& call_info, format::HandleId object_id, format::HandleId pCommandList) { - TrackTargetDrawCall( - call_info, object_id, false, format::kNullHandleId, 0, format::kNullHandleId, 0, pCommandList); + TrackTargetDrawCall(call_info, + object_id, + DumpDrawCallType::kBundle, + format::kNullHandleId, + 0, + format::kNullHandleId, + 0, + pCommandList); } virtual void Process_ID3D12GraphicsCommandList_Close(const ApiCallInfo& call_info, @@ -500,7 +738,8 @@ class Dx12BrowseConsumer : public Dx12Consumer ++all_draw_call_count; if (all_draw_call_count > dump_resources_target_.draw_call_index) { - if (TEST_AVAILABLE_ARGS == 2 && !bundle_draw_call->is_draw) + if (TEST_AVAILABLE_ARGS == 2 && + bundle_draw_call->drawcall_type != DumpDrawCallType::kDraw) { // Finding the target in the following draw call. is_modified_args = true; @@ -531,7 +770,7 @@ class Dx12BrowseConsumer : public Dx12Consumer ++all_draw_call_count; if (all_draw_call_count > dump_resources_target_.draw_call_index) { - if (TEST_AVAILABLE_ARGS == 2 && !draw_call->is_draw) + if (TEST_AVAILABLE_ARGS == 2 && draw_call->drawcall_type != DumpDrawCallType::kDraw) { // Finding the target in the following draw call. is_modified_args = true; @@ -623,7 +862,7 @@ class Dx12BrowseConsumer : public Dx12Consumer void TrackTargetDrawCall(const ApiCallInfo& call_info, format::HandleId object_id, - bool is_draw, + DumpDrawCallType drawcall_type, format::HandleId exe_indirect_argument_id = format::kNullHandleId, uint64_t exe_indirect_argument_offset = 0, format::HandleId exe_indirect_count_id = format::kNullHandleId, @@ -638,20 +877,24 @@ class Dx12BrowseConsumer : public Dx12Consumer TrackDumpDrawCall track_draw_call = {}; track_draw_call.command_list_id = object_id; track_draw_call.draw_call_block_index = call_info.index; - track_draw_call.is_draw = is_draw; + track_draw_call.drawcall_type = drawcall_type; track_draw_call.begin_block_index = it->second.begin_block_index; track_draw_call.begin_renderpass_block_index = it->second.current_begin_renderpass_block_index; track_draw_call.set_render_targets_block_index = it->second.current_set_render_targets_block_index; - track_draw_call.root_signature_handle_id = it->second.current_root_signature_handle_id; track_draw_call.captured_vertex_buffer_views = it->second.current_captured_vertex_buffer_views; track_draw_call.captured_index_buffer_view = it->second.current_captured_index_buffer_view; track_draw_call.descriptor_heap_ids = it->second.current_descriptor_heap_ids; - track_draw_call.captured_descriptor_gpu_handles = it->second.current_captured_descriptor_gpu_handles; track_draw_call.execute_indirect_info.argument_id = exe_indirect_argument_id; track_draw_call.execute_indirect_info.argument_offset = exe_indirect_argument_offset; track_draw_call.execute_indirect_info.count_id = exe_indirect_count_id; track_draw_call.execute_indirect_info.count_offset = exe_indirect_count_offset; track_draw_call.bundle_commandlist_id = bundle_commandlist_id; + track_draw_call.graphics_root_signature_handle_id = + it->second.current_graphics_root_signature_handle_id; + track_draw_call.graphics_root_parameters = it->second.current_graphics_root_parameters; + track_draw_call.compute_root_signature_handle_id = it->second.current_compute_root_signature_handle_id; + track_draw_call.compute_root_parameters = it->second.current_compute_root_parameters; + it->second.track_dump_draw_calls.emplace_back( std::make_shared(std::move(track_draw_call))); diff --git a/framework/decode/dx12_dump_resources.cpp b/framework/decode/dx12_dump_resources.cpp index 0aec96c308..6231a176ae 100644 --- a/framework/decode/dx12_dump_resources.cpp +++ b/framework/decode/dx12_dump_resources.cpp @@ -24,6 +24,7 @@ #include "decode/dx12_dump_resources.h" // TODO: It should change the file name of "vulkan" #include "generated/generated_vulkan_struct_to_json.h" +#include "generated/generated_dx12_enum_to_string.h" #include "decode/dx12_object_mapping_util.h" #include "util/platform.h" #include "util/logging.h" @@ -46,6 +47,12 @@ GFXRECON_BEGIN_NAMESPACE(decode) constexpr bool TEST_READABLE = false; constexpr bool TEST_SHADER_RES = true; +// root parameter's descriptor range type's index mightn't have a view in heap. +constexpr bool TEST_WRITE_NOT_FOUND_VIEWS = true; + +// resource id or BufferLocation could be 0 in view of heap. +constexpr bool TEST_WRITE_NULL_RESOURCE_VIEWS = true; + static const char* Dx12ResourceTypeToString(Dx12DumpResourceType type) { switch (type) @@ -70,6 +77,10 @@ static const char* Dx12ResourceTypeToString(Dx12DumpResourceType type) return "eiArgs"; case Dx12DumpResourceType::kExecuteIndirectCount: return "eiCount"; + case Dx12DumpResourceType::kGraphicsRootParameters: + return "graphics_root_parameters"; + case Dx12DumpResourceType::kComputeRootParameters: + return "compute_root_parameters"; case Dx12DumpResourceType::kUnknown: default: return ""; @@ -261,110 +272,136 @@ bool Dx12DumpResources::CreateRootSignature(DxObjectInfo* device_ { bool is_complete = false; auto handld_id = *root_signature_decoder->GetPointer(); - if (track_dump_resources_.target.root_signature_handle_id == handld_id) + std::unordered_map* track_root_parameters = nullptr; + + if (track_dump_resources_.target.bundle_target_draw_call != nullptr) + { + if (track_dump_resources_.target.bundle_target_draw_call->graphics_root_signature_handle_id == handld_id) + { + track_root_parameters = &track_dump_resources_.target.bundle_target_draw_call->graphics_root_parameters; + } + else if (track_dump_resources_.target.bundle_target_draw_call->compute_root_signature_handle_id == handld_id) + { + track_root_parameters = &track_dump_resources_.target.bundle_target_draw_call->compute_root_parameters; + } + } + + if (track_root_parameters == nullptr) + { + if (track_dump_resources_.target.graphics_root_signature_handle_id == handld_id) + { + track_root_parameters = &track_dump_resources_.target.graphics_root_parameters; + } + else if (track_dump_resources_.target.compute_root_signature_handle_id == handld_id) + { + track_root_parameters = &track_dump_resources_.target.compute_root_parameters; + } + } + + if (track_root_parameters) { auto device = static_cast(device_object_info->object); + // Trimming doesn't track D3D12SerializeVersionedRootSignature. + // Use D3D12CreateVersionedRootSignatureDeserializer to get info. // DATA_STATIC causes error for ResourceBarrier. Change it to NONE. graphics::dx12::ID3D12VersionedRootSignatureDeserializerComPtr root_sig_deserializer{ nullptr }; HRESULT result = D3D12CreateVersionedRootSignatureDeserializer( blob_with_root_signature_decoder->GetPointer(), blob_length_in_bytes, IID_PPV_ARGS(&root_sig_deserializer)); - auto versioned_root_sig = root_sig_deserializer->GetUnconvertedRootSignatureDesc(); - D3D12_VERSIONED_ROOT_SIGNATURE_DESC modified_root_sig = *versioned_root_sig; - if (modified_root_sig.Version == D3D_ROOT_SIGNATURE_VERSION_1_1 || - modified_root_sig.Version == D3D_ROOT_SIGNATURE_VERSION_1_2) + const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *versioned_root_sig = nullptr; + root_sig_deserializer->GetRootSignatureDescAtVersion(D3D_ROOT_SIGNATURE_VERSION_1_2, &versioned_root_sig); + auto modified_root_sig = *versioned_root_sig; + + bool is_modified = false; + std::vector params; + std::vector> ranges; + uint32_t param_size = modified_root_sig.Desc_1_2.NumParameters; + params.resize(param_size); + std::memcpy(params.data(), modified_root_sig.Desc_1_2.pParameters, param_size * sizeof(D3D12_ROOT_PARAMETER1)); + ranges.resize(param_size); + + for (uint32_t pi = 0; pi < param_size; ++pi) { - bool is_modified = false; - std::vector params; - std::vector> ranges; - uint32_t param_size = 0; - if (modified_root_sig.Version == D3D_ROOT_SIGNATURE_VERSION_1_1) - { - param_size = modified_root_sig.Desc_1_1.NumParameters; - params.resize(param_size); - std::memcpy( - params.data(), modified_root_sig.Desc_1_1.pParameters, param_size * sizeof(D3D12_ROOT_PARAMETER1)); - } - else if (modified_root_sig.Version == D3D_ROOT_SIGNATURE_VERSION_1_2) + TrackRootParameter root_param; + auto param_entry = track_root_parameters->find(pi); + if (param_entry != track_root_parameters->end()) { - param_size = modified_root_sig.Desc_1_2.NumParameters; - params.resize(param_size); - std::memcpy( - params.data(), modified_root_sig.Desc_1_2.pParameters, param_size * sizeof(D3D12_ROOT_PARAMETER1)); + root_param = param_entry->second; } - ranges.resize(param_size); - for (uint32_t i = 0; i < param_size; ++i) + root_param.root_signature_type = params[pi].ParameterType; + + switch (root_param.root_signature_type) { - switch (params[i].ParameterType) + case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: { - case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: + auto range_size = params[pi].DescriptorTable.NumDescriptorRanges; + ranges[pi].resize(range_size); + std::memcpy(ranges[pi].data(), + params[pi].DescriptorTable.pDescriptorRanges, + range_size * sizeof(D3D12_DESCRIPTOR_RANGE1)); + for (uint32_t ri = 0; ri < range_size; ++ri) { - auto range_size = params[i].DescriptorTable.NumDescriptorRanges; - ranges[i].resize(range_size); - std::memcpy(ranges[i].data(), - params[i].DescriptorTable.pDescriptorRanges, - range_size * sizeof(D3D12_DESCRIPTOR_RANGE1)); - for (uint32_t j = 0; j < range_size; ++j) + // DATA_STATIC could cause error for splitted commandlists. + // Error log is like: Resource is bound as DATA_STATIC on Command List. Its state was + // changed by a previous command list execution which indicates a change to its data (or + // possibly resource metadata), but it is invalid to change it until this command list + // has finished executing for the last time. + if (ranges[pi][ri].Flags & D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC) { - // DATA_STATIC could cause error for splitted commandlists. - // Error log is like: Resource is bound as DATA_STATIC on Command List. Its state was - // changed by a previous command list execution which indicates a change to its data (or - // possibly resource metadata), but it is invalid to change it until this command list has - // finished executing for the last time. - if (ranges[i][j].Flags & D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC) - { - ranges[i][j].Flags &= ~D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC; - ranges[i][j].Flags |= D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE; - is_modified = true; - GFXRECON_LOG_WARNING( - "D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC could cause error for dump resources. " - "Modify to D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE."); - } + ranges[pi][ri].Flags &= ~D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC; + ranges[pi][ri].Flags |= + D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE; + is_modified = true; + GFXRECON_LOG_WARNING( + "D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC could cause error for dump resources. " + "Modify to D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE."); } - params[i].DescriptorTable.pDescriptorRanges = ranges[i].data(); - break; + root_param.root_signature_descriptor_tables.emplace_back(ranges[pi][ri]); } - default: - break; + params[pi].DescriptorTable.pDescriptorRanges = ranges[pi].data(); + break; } + default: + break; } - if (is_modified) + (*track_root_parameters)[pi] = root_param; + } + if (is_modified) + { + if (modified_root_sig.Version == D3D_ROOT_SIGNATURE_VERSION_1_1) { - if (modified_root_sig.Version == D3D_ROOT_SIGNATURE_VERSION_1_1) - { - modified_root_sig.Desc_1_1.pParameters = params.data(); - } - else if (modified_root_sig.Version == D3D_ROOT_SIGNATURE_VERSION_1_2) - { - modified_root_sig.Desc_1_2.pParameters = params.data(); - } - - ID3D10Blob* p_modified_blob = nullptr; - ID3D10Blob* p_modified_error_blob = nullptr; - replay_result = - D3D12SerializeVersionedRootSignature(&modified_root_sig, &p_modified_blob, &p_modified_error_blob); - - GFXRECON_ASSERT(SUCCEEDED(replay_result)); - - auto modified_size = p_modified_blob->GetBufferSize(); - auto modified_buffer = p_modified_blob->GetBufferPointer(); - - // TODO: This new signautre use NONE, instead of DATA_STATIC. - // DATA_STATIC is optimization, so new signature might impact the performance. - // It could create two root signatures. Keep original one and create new one. - // The only target command llist use the new one. The others use the original one. - // But if it has two root signatures, it also needs to have two PipeStates. - // The target command list needs to use the new PipeStates for Create and Reset. - replay_result = device->CreateRootSignature(node_mask, - modified_buffer, - modified_size, - *riid.decoded_value, - root_signature_decoder->GetHandlePointer()); - GFXRECON_ASSERT(SUCCEEDED(replay_result)); - is_complete = true; + modified_root_sig.Desc_1_1.pParameters = params.data(); } + else if (modified_root_sig.Version == D3D_ROOT_SIGNATURE_VERSION_1_2) + { + modified_root_sig.Desc_1_2.pParameters = params.data(); + } + + ID3D10Blob* p_modified_blob = nullptr; + ID3D10Blob* p_modified_error_blob = nullptr; + replay_result = D3D12SerializeVersionedRootSignature( + &modified_root_sig, &p_modified_blob, &p_modified_error_blob); + + GFXRECON_ASSERT(SUCCEEDED(replay_result)); + + auto modified_size = p_modified_blob->GetBufferSize(); + auto modified_buffer = p_modified_blob->GetBufferPointer(); + + // TODO: This new signautre use NONE, instead of DATA_STATIC. + // DATA_STATIC is optimization, so new signature might impact the performance. + // It could create two root signatures. Keep original one and create new one. + // The only target command llist use the new one. The others use the original one. + // But if it has two root signatures, it also needs to have two PipeStates. + // The target command list needs to use the new PipeStates for Create and Reset. + replay_result = device->CreateRootSignature(node_mask, + modified_buffer, + modified_size, + *riid.decoded_value, + root_signature_decoder->GetHandlePointer()); + GFXRECON_ASSERT(SUCCEEDED(replay_result)); + is_complete = true; } } return is_complete; @@ -540,20 +577,418 @@ void Dx12DumpResources::BeginRenderPass( } } -bool MatchDescriptorCPUGPUHandle(size_t replay_cpu_addr_begin, - size_t replay_target_cpu_addr, - uint64_t capture_gpu_addr_begin, - std::map captured_gpu_addrs) +bool CaptureGPUAddrMatchDescriptorHeap(const D3D12_GPU_DESCRIPTOR_HANDLE capture_gpu_addr, + const D3D12DescriptorHeapInfo& heap_info, + uint32_t& out_heap_index) { - for (auto gpu_addr : captured_gpu_addrs) + auto increment = (*heap_info.capture_increments)[heap_info.descriptor_type]; + auto capture_gpu_addr_end = heap_info.capture_gpu_addr_begin + heap_info.descriptor_count * increment; + + bool is_match = true ? (heap_info.capture_gpu_addr_begin <= capture_gpu_addr.ptr && + capture_gpu_addr.ptr <= capture_gpu_addr_end) + : false; + if (is_match) { - if ((gpu_addr.second.ptr >= capture_gpu_addr_begin) && - ((replay_target_cpu_addr - replay_cpu_addr_begin) == (gpu_addr.second.ptr - capture_gpu_addr_begin))) + if (increment == 0) { - return true; + out_heap_index = 0; + } + else + { + out_heap_index = (capture_gpu_addr.ptr - heap_info.capture_gpu_addr_begin) / increment; } } - return false; + return is_match; +} + +bool ReplayCPUAddrMatchDescriptorHeap(const D3D12_CPU_DESCRIPTOR_HANDLE replay_cpu_addr, + const D3D12DescriptorHeapInfo& heap_info, + uint32_t& out_heap_index) +{ + auto increment = (*heap_info.replay_increments)[heap_info.descriptor_type]; + auto replay_cpu_addr_end = heap_info.replay_cpu_addr_begin + heap_info.descriptor_count * increment; + + bool is_match = true ? (heap_info.replay_cpu_addr_begin <= replay_cpu_addr.ptr && + replay_cpu_addr.ptr <= replay_cpu_addr_end) + : false; + if (is_match) + { + if (increment == 0) + { + out_heap_index = 0; + } + else + { + out_heap_index = (replay_cpu_addr.ptr - heap_info.replay_cpu_addr_begin) / increment; + } + } + return is_match; +} + +// If range is null, it means not D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE, so it dumps only one descriptor. +void Dx12DumpResources::WriteDescripotTable(DxObjectInfo* queue_object_info, + const std::vector& front_command_list_ids, + graphics::dx12::Dx12DumpResourcePos pos, + std::vector> json_path, + const D3D12DescriptorHeapInfo* heap_info, + format::HandleId heap_id, + uint32_t root_heap_index, + const D3D12_DESCRIPTOR_RANGE1* range) +{ + const std::vector sub_indices_emptry{ 0 }; + std::vector> json_path_sub; + + uint32_t num_descriptors = 1; + if (range != nullptr) + { + num_descriptors = range->NumDescriptors; + } + + uint32_t heap_index = root_heap_index; + uint32_t json_index = 0; + for (uint32_t i = 0; i < num_descriptors; ++i) + { + heap_index = root_heap_index + i; + auto info_entry = heap_info->cbv_srv_uav_infos.find(heap_index); + if (info_entry == heap_info->cbv_srv_uav_infos.end()) + { + if (TEST_WRITE_NOT_FOUND_VIEWS) + { + json_path_sub = json_path; + json_path_sub.emplace_back("descs", json_index); + ++json_index; + active_delegate_->WriteSingleData(json_path_sub, "heap_id", heap_id); + active_delegate_->WriteSingleData(json_path_sub, "heap_index", heap_index); + active_delegate_->WriteNote( + json_path_sub, "This heap_index can't be found a view in this heap_id"); + } + continue; + } + + switch (info_entry->second.type) + { + case D3D12_DESCRIPTOR_RANGE_TYPE_CBV: + { + const auto& desc = info_entry->second.cbv.captured_desc; + + if (desc.BufferLocation == kNullGpuAddress) + { + if (TEST_WRITE_NULL_RESOURCE_VIEWS) + { + json_path_sub = json_path; + json_path_sub.emplace_back("descs", json_index); + ++json_index; + active_delegate_->WriteSingleData(json_path_sub, "heap_id", heap_id); + active_delegate_->WriteSingleData(json_path_sub, "heap_index", heap_index); + active_delegate_->WriteSingleData(json_path_sub, "buffer_location", kNullGpuAddress); + } + continue; + } + json_path_sub = json_path; + json_path_sub.emplace_back("descs", json_index); + ++json_index; + + active_delegate_->WriteSingleData(json_path_sub, "buffer_location", desc.BufferLocation); + CopyDrawCallResourceByGPUVA(queue_object_info, + front_command_list_ids, + desc.BufferLocation, + desc.SizeInBytes, + json_path_sub, + Dx12DumpResourceType::kCbv, + pos, + heap_id, + heap_index); + break; + } + case D3D12_DESCRIPTOR_RANGE_TYPE_SRV: + { + if (info_entry->second.srv.resource_id == format::kNullHandleId) + { + if (TEST_WRITE_NULL_RESOURCE_VIEWS) + { + json_path_sub = json_path; + json_path_sub.emplace_back("descs", json_index); + ++json_index; + active_delegate_->WriteSingleData(json_path_sub, "heap_id", heap_id); + active_delegate_->WriteSingleData(json_path_sub, "heap_index", heap_index); + active_delegate_->WriteSingleData(json_path_sub, "res_id", format::kNullHandleId); + } + continue; + } + json_path_sub = json_path; + json_path_sub.emplace_back("descs", json_index); + ++json_index; + + const auto& desc = info_entry->second.srv.desc; + uint64_t offset = 0; + uint64_t size = 0; + switch (desc.ViewDimension) + { + case D3D12_SRV_DIMENSION_BUFFER: + { + auto size = desc.Buffer.StructureByteStride; + if (size == 0) + { + size = graphics::dx12::GetSubresourcePixelByteSize(desc.Format); + } + offset = desc.Buffer.FirstElement * size; + size = desc.Buffer.NumElements * size; + break; + } + default: + break; + } + CopyDrawCallResourceBySubresource(queue_object_info, + front_command_list_ids, + info_entry->second.srv.resource_id, + offset, + size, + info_entry->second.srv.subresource_indices, + json_path_sub, + Dx12DumpResourceType::kSrv, + pos, + heap_id, + heap_index); + break; + } + case D3D12_DESCRIPTOR_RANGE_TYPE_UAV: + { + if (info_entry->second.uav.resource_id == format::kNullHandleId) + { + if (TEST_WRITE_NULL_RESOURCE_VIEWS) + { + json_path_sub = json_path; + json_path_sub.emplace_back("descs", json_index); + ++json_index; + active_delegate_->WriteSingleData(json_path_sub, "heap_id", heap_id); + active_delegate_->WriteSingleData(json_path_sub, "heap_index", heap_index); + active_delegate_->WriteSingleData(json_path_sub, "res_id", format::kNullHandleId); + } + continue; + } + json_path_sub = json_path; + json_path_sub.emplace_back("descs", json_index); + ++json_index; + + const auto& desc = info_entry->second.uav.desc; + uint64_t offset = 0; + uint64_t size = 0; + switch (desc.ViewDimension) + { + case D3D12_UAV_DIMENSION_BUFFER: + { + auto size = desc.Buffer.StructureByteStride; + if (size == 0) + { + size = graphics::dx12::GetSubresourcePixelByteSize(desc.Format); + } + offset = desc.Buffer.FirstElement * size; + size = desc.Buffer.NumElements * size; + break; + } + default: + break; + } + json_path_sub.emplace_back("resource", format::kNoneIndex); + + CopyDrawCallResourceBySubresource(queue_object_info, + front_command_list_ids, + info_entry->second.uav.resource_id, + offset, + size, + info_entry->second.uav.subresource_indices, + json_path_sub, + Dx12DumpResourceType::kUav, + pos, + heap_id, + heap_index); + + json_path_sub.emplace_back("counter_resource", format::kNoneIndex); + active_delegate_->WriteSingleData( + json_path_sub, "res_id", info_entry->second.uav.counter_resource_id); + + CopyDrawCallResourceBySubresource(queue_object_info, + front_command_list_ids, + info_entry->second.uav.counter_resource_id, + desc.Buffer.CounterOffsetInBytes, + 0, + sub_indices_emptry, + json_path_sub, + Dx12DumpResourceType::kUavCounter, + pos, + heap_id, + heap_index); + break; + } + default: + break; + } + } +} + +void Dx12DumpResources::WriteRootParameters(DxObjectInfo* queue_object_info, + const std::vector& front_command_list_ids, + graphics::dx12::Dx12DumpResourcePos pos, + Dx12DumpResourceType res_type, + const std::vector& descriptor_heap_ids, + const std::unordered_map& root_parameters) +{ + std::vector> json_path; + std::vector> json_path_sub; + auto index = 0; + for (const auto& param : root_parameters) + { + json_path.clear(); + json_path.emplace_back(Dx12ResourceTypeToString(res_type), index); + active_delegate_->WriteSingleData(json_path, "root_parameter_index", param.first); + active_delegate_->WriteSingleData(json_path, "root_signature_type", util::ToString(param.second.root_signature_type)); + active_delegate_->WriteSingleData(json_path, "cmd_bind_type", util::ToString(param.second.cmd_bind_type)); + + if (param.second.root_signature_type != param.second.cmd_bind_type) + { + active_delegate_->WriteNote(json_path, "root_signature_type and cmd_bind_type are different."); + } + + switch (param.second.root_signature_type) + { + case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: + { + uint32_t di = 0; + for (const auto& table : param.second.root_signature_descriptor_tables) + { + json_path_sub = json_path; + json_path_sub.emplace_back("tables", di); + active_delegate_->WriteSingleData(json_path_sub, "range_type", util::ToString(table.RangeType)); + active_delegate_->WriteSingleData(json_path_sub, "num_descriptors", table.NumDescriptors); + ++di; + } + break; + } + default: + break; + } + + switch (param.second.cmd_bind_type) + { + case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: + { + for (const auto& heap_id : descriptor_heap_ids) + { + auto heap_object_info = get_object_info_func_(heap_id); + auto heap_extra_info = GetExtraInfo(heap_object_info); + + uint32_t table_heap_index = 0; + if (!CaptureGPUAddrMatchDescriptorHeap( + param.second.cmd_bind_captured_base_descriptor, *heap_extra_info, table_heap_index)) + { + continue; + } + + active_delegate_->WriteSingleData( + json_path, "descriptor_heap_type", util::ToString(heap_extra_info->descriptor_type)); + switch (heap_extra_info->descriptor_type) + { + case D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV: + { + if (param.second.root_signature_type != D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE) + { + active_delegate_->WriteNote(json_path, + "root_signature_type isn't DESCRIPTOR_TABLE and no " + "NumDescriptors, so dump only one descriptor."); + WriteDescripotTable(queue_object_info, + front_command_list_ids, + pos, + json_path, + heap_extra_info, + heap_id, + table_heap_index, + nullptr); + break; + } + + uint32_t table_index = 0; + uint32_t root_heap_index = table_heap_index; + uint32_t di = 0; + for (const auto& table : param.second.root_signature_descriptor_tables) + { + if (table_index > 0) + { + root_heap_index += + param.second.root_signature_descriptor_tables[table_index - 1].NumDescriptors; + } + json_path_sub = json_path; + json_path_sub.emplace_back("tables", di); + WriteDescripotTable(queue_object_info, + front_command_list_ids, + pos, + json_path_sub, + heap_extra_info, + heap_id, + root_heap_index, + &table); + ++di; + } + break; + } + case D3D12_DESCRIPTOR_HEAP_TYPE_RTV: + case D3D12_DESCRIPTOR_HEAP_TYPE_DSV: + { + // D3D12_DESCRIPTOR_HEAP_TYPE_RTV, D3D12_DESCRIPTOR_HEAP_TYPE_DSV + active_delegate_->WriteNote( + json_path, "This descriptor_heap_type shouldn't be used in root parameter."); + break; + } + default: + // D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER + break; + } + } + break; + } + case D3D12_ROOT_PARAMETER_TYPE_CBV: + case D3D12_ROOT_PARAMETER_TYPE_SRV: + case D3D12_ROOT_PARAMETER_TYPE_UAV: + { + if (param.second.cmd_bind_captured_buffer_location == kNullGpuAddress) + { + if (TEST_WRITE_NULL_RESOURCE_VIEWS) + { + active_delegate_->WriteSingleData(json_path, "buffer_location", kNullGpuAddress); + } + break; + } + Dx12DumpResourceType type = Dx12DumpResourceType::kUnknown; + switch (param.second.cmd_bind_type) + { + case D3D12_ROOT_PARAMETER_TYPE_CBV: + type = Dx12DumpResourceType::kCbv; + break; + case D3D12_ROOT_PARAMETER_TYPE_SRV: + type = Dx12DumpResourceType::kSrv; + break; + case D3D12_ROOT_PARAMETER_TYPE_UAV: + type = Dx12DumpResourceType::kUav; + break; + default: + break; + } + CopyDrawCallResourceByGPUVA(queue_object_info, + front_command_list_ids, + param.second.cmd_bind_captured_buffer_location, + 0, + json_path, + type, + pos, + format::kNullHandleId, + 0); + break; + } + default: + // D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS + break; + } + ++index; + } } void Dx12DumpResources::CopyDrawCallResources(DxObjectInfo* queue_object_info, @@ -565,318 +1000,342 @@ void Dx12DumpResources::CopyDrawCallResources(DxObjectInfo* // pair first: path name, second: resource index. If index is kNoneIndex, it means not a array. std::vector> json_path; - uint32_t resource_index = 0; + uint32_t index = 0; const std::vector sub_indices_emptry{ 0 }; - // vertex - const std::vector* vertex_buffer_views = nullptr; - if (bundle_target_draw_call && !bundle_target_draw_call->captured_vertex_buffer_views.empty()) + auto drawcall_type = track_dump_resources_.target.drawcall_type; + std::string drawcall_type_name = ""; + + if (bundle_target_draw_call) { - vertex_buffer_views = &bundle_target_draw_call->captured_vertex_buffer_views; + drawcall_type = bundle_target_draw_call->drawcall_type; + drawcall_type_name = "bundle_"; } - else + + switch (drawcall_type) { - vertex_buffer_views = &track_dump_resources_.target.captured_vertex_buffer_views; + case DumpDrawCallType::kDraw: + drawcall_type_name += "draw"; + break; + case DumpDrawCallType::kDispatch: + drawcall_type_name += "dispatch"; + break; + case DumpDrawCallType::kIndirect: + drawcall_type_name += "indirect"; + break; + default: + // It shouldn't be kBundle or kUnknown + break; } - if (vertex_buffer_views) + active_delegate_->WriteSingleData(json_path, "drawcall_type", drawcall_type_name); + + if (drawcall_type != DumpDrawCallType::kDispatch) { - resource_index = 0; - for (const auto& view : *vertex_buffer_views) + // vertex + const std::vector* vertex_buffer_views = nullptr; + if (bundle_target_draw_call && !bundle_target_draw_call->captured_vertex_buffer_views.empty()) + { + vertex_buffer_views = &bundle_target_draw_call->captured_vertex_buffer_views; + } + else + { + vertex_buffer_views = &track_dump_resources_.target.captured_vertex_buffer_views; + } + if (vertex_buffer_views) + { + index = 0; + for (const auto& view : *vertex_buffer_views) + { + json_path.clear(); + json_path.emplace_back("vertices", index); + + CopyDrawCallResourceByGPUVA(queue_object_info, + front_command_list_ids, + view.BufferLocation, + view.SizeInBytes, + json_path, + Dx12DumpResourceType::kVertex, + pos, + format::kNullHandleId, + 0); + ++index; + } + } + + // index + const D3D12_INDEX_BUFFER_VIEW* index_buffer_view = nullptr; + if (bundle_target_draw_call && + bundle_target_draw_call->captured_index_buffer_view.BufferLocation != kNullGpuAddress) + { + index_buffer_view = &bundle_target_draw_call->captured_index_buffer_view; + } + else if (track_dump_resources_.target.captured_index_buffer_view.BufferLocation != kNullGpuAddress) + { + index_buffer_view = &track_dump_resources_.target.captured_index_buffer_view; + } + if (index_buffer_view) { json_path.clear(); - json_path.emplace_back("vertex", resource_index); + json_path.emplace_back("index", format::kNoneIndex); + CopyDrawCallResourceByGPUVA(queue_object_info, front_command_list_ids, - view.BufferLocation, - view.SizeInBytes, + index_buffer_view->BufferLocation, + index_buffer_view->SizeInBytes, json_path, - Dx12DumpResourceType::kVertex, + Dx12DumpResourceType::kIndex, pos, format::kNullHandleId, 0); - ++resource_index; } } - // index - const D3D12_INDEX_BUFFER_VIEW* index_buffer_view = nullptr; - if (bundle_target_draw_call && bundle_target_draw_call->captured_index_buffer_view.BufferLocation != kNullGpuAddress) - { - index_buffer_view = &bundle_target_draw_call->captured_index_buffer_view; - } - else - { - index_buffer_view = &track_dump_resources_.target.captured_index_buffer_view; - } - if (index_buffer_view) + // root parameters + const std::vector* descriptor_heap_ids = nullptr; + const std::unordered_map* root_parameters = nullptr; + + if (bundle_target_draw_call) { - json_path.clear(); - json_path.emplace_back("index", format::kNoneIndex); - CopyDrawCallResourceByGPUVA(queue_object_info, - front_command_list_ids, - index_buffer_view->BufferLocation, - index_buffer_view->SizeInBytes, - json_path, - Dx12DumpResourceType::kIndex, - pos, - format::kNullHandleId, - 0); - } - - // descriptor - std::vector> json_path_sub; - const std::vector* descriptor_heap_ids = nullptr; - const std::map* descriptor_gpu_handles = nullptr; - if (bundle_target_draw_call && !bundle_target_draw_call->descriptor_heap_ids.empty()) - { - descriptor_heap_ids = &bundle_target_draw_call->descriptor_heap_ids; + if (!bundle_target_draw_call->descriptor_heap_ids.empty()) + { + descriptor_heap_ids = &bundle_target_draw_call->descriptor_heap_ids; + } } - else + if (!descriptor_heap_ids) { descriptor_heap_ids = &track_dump_resources_.target.descriptor_heap_ids; } - if (bundle_target_draw_call && !bundle_target_draw_call->captured_descriptor_gpu_handles.empty()) - { - descriptor_gpu_handles = &bundle_target_draw_call->captured_descriptor_gpu_handles; - } - else - { - descriptor_gpu_handles = &track_dump_resources_.target.captured_descriptor_gpu_handles; - } - if (descriptor_heap_ids && descriptor_gpu_handles) - { - json_path.clear(); - json_path.emplace_back("descriptor_heap", format::kNoneIndex); - auto heap_size = descriptor_heap_ids->size(); - for (uint32_t heap_index = 0; heap_index < heap_size; ++heap_index) + if (descriptor_heap_ids && !descriptor_heap_ids->empty()) + { + bool bundle_write_root_params = false; + + if (bundle_target_draw_call) { - auto descriptor_heap_id = (*descriptor_heap_ids)[heap_index]; - - json_path.emplace_back("heap_id_" + util::HandleIdToString(descriptor_heap_id), format::kNoneIndex); - - auto heap_object_info = get_object_info_func_(descriptor_heap_id); - auto heap_extra_info = GetExtraInfo(heap_object_info); - - // constant buffer - resource_index = 0; - for (const auto& info_pair : heap_extra_info->constant_buffer_infos) + switch (bundle_target_draw_call->drawcall_type) { - auto descriptor_heap_index = info_pair.first; - const auto& info = info_pair.second; - if (MatchDescriptorCPUGPUHandle(heap_extra_info->replay_cpu_addr_begin, - info.replay_handle.ptr, - heap_extra_info->capture_gpu_addr_begin, - *descriptor_gpu_handles)) + case DumpDrawCallType::kDraw: { - json_path_sub = json_path; - json_path_sub.emplace_back("constant_buffer_views", resource_index); - CopyDrawCallResourceByGPUVA(queue_object_info, - front_command_list_ids, - info.captured_view.BufferLocation, - info.captured_view.SizeInBytes, - json_path_sub, - Dx12DumpResourceType::kCbv, - pos, - descriptor_heap_id, - descriptor_heap_index); - ++resource_index; + if (!bundle_target_draw_call->graphics_root_parameters.empty()) + { + bundle_write_root_params = true; + WriteRootParameters(queue_object_info, + front_command_list_ids, + pos, + Dx12DumpResourceType::kGraphicsRootParameters, + *descriptor_heap_ids, + bundle_target_draw_call->graphics_root_parameters); + } + break; + } + case DumpDrawCallType::kDispatch: + { + if (!bundle_target_draw_call->compute_root_parameters.empty()) + { + bundle_write_root_params = true; + WriteRootParameters(queue_object_info, + front_command_list_ids, + pos, + Dx12DumpResourceType::kComputeRootParameters, + *descriptor_heap_ids, + bundle_target_draw_call->compute_root_parameters); + } + break; + } + case DumpDrawCallType::kIndirect: + { + // ExecuteIndirect could run draw or dispatch. + if (!bundle_target_draw_call->graphics_root_parameters.empty()) + { + bundle_write_root_params = true; + WriteRootParameters(queue_object_info, + front_command_list_ids, + pos, + Dx12DumpResourceType::kGraphicsRootParameters, + *descriptor_heap_ids, + bundle_target_draw_call->graphics_root_parameters); + } + if (!bundle_target_draw_call->compute_root_parameters.empty()) + { + bundle_write_root_params = true; + WriteRootParameters(queue_object_info, + front_command_list_ids, + pos, + Dx12DumpResourceType::kComputeRootParameters, + *descriptor_heap_ids, + bundle_target_draw_call->compute_root_parameters); + } + break; } + default: + // It shouldn't be kBundle or kUnknown + break; } - - if (TEST_SHADER_RES) + } + if (!bundle_write_root_params) + { + auto target_drawcall_type = track_dump_resources_.target.drawcall_type; + if (target_drawcall_type == DumpDrawCallType::kBundle && !bundle_write_root_params && + bundle_target_draw_call) + { + json_path.clear(); + active_delegate_->WriteNote( + json_path, + "Bundle doesn't have root parameters info. Dump root parameters from the target commandlist."); + target_drawcall_type = bundle_target_draw_call->drawcall_type; + } + switch (target_drawcall_type) { - // shader resource - resource_index = 0; - for (const auto& info_pair : heap_extra_info->shader_resource_infos) + case DumpDrawCallType::kDraw: { - auto descriptor_heap_index = info_pair.first; - const auto& info = info_pair.second; - if (MatchDescriptorCPUGPUHandle(heap_extra_info->replay_cpu_addr_begin, - info.replay_handle.ptr, - heap_extra_info->capture_gpu_addr_begin, - *descriptor_gpu_handles)) + if (!track_dump_resources_.target.graphics_root_parameters.empty()) { - uint64_t offset = 0; - uint64_t size = 0; - switch (info.view.ViewDimension) - { - case D3D12_SRV_DIMENSION_BUFFER: - { - auto size = info.view.Buffer.StructureByteStride; - if (size == 0) - { - size = graphics::dx12::GetSubresourcePixelByteSize(info.view.Format); - } - offset = info.view.Buffer.FirstElement * size; - size = info.view.Buffer.NumElements * size; - break; - } - default: - break; - } - json_path_sub = json_path; - json_path_sub.emplace_back("shader_resource_views", resource_index); - CopyDrawCallResourceBySubresource(queue_object_info, - front_command_list_ids, - info.resource_id, - offset, - size, - info.subresource_indices, - json_path_sub, - Dx12DumpResourceType::kSrv, - pos, - descriptor_heap_id, - descriptor_heap_index); - ++resource_index; + WriteRootParameters(queue_object_info, + front_command_list_ids, + pos, + Dx12DumpResourceType::kGraphicsRootParameters, + *descriptor_heap_ids, + track_dump_resources_.target.graphics_root_parameters); } + break; } - - // unordered access - resource_index = 0; - for (const auto& info_pair : heap_extra_info->unordered_access_infos) + case DumpDrawCallType::kDispatch: { - auto descriptor_heap_index = info_pair.first; - const auto& info = info_pair.second; - if (MatchDescriptorCPUGPUHandle(heap_extra_info->replay_cpu_addr_begin, - info.replay_handle.ptr, - heap_extra_info->capture_gpu_addr_begin, - *descriptor_gpu_handles)) + if (!track_dump_resources_.target.compute_root_parameters.empty()) { - uint64_t offset = 0; - uint64_t size = 0; - switch (info.view.ViewDimension) - { - case D3D12_UAV_DIMENSION_BUFFER: - { - auto size = info.view.Buffer.StructureByteStride; - if (size == 0) - { - size = graphics::dx12::GetSubresourcePixelByteSize(info.view.Format); - } - offset = info.view.Buffer.FirstElement * size; - size = info.view.Buffer.NumElements * size; - break; - } - default: - break; - } - json_path_sub = json_path; - json_path_sub.emplace_back("unordered_access_views", resource_index); - json_path_sub.emplace_back("resource", format::kNoneIndex); - CopyDrawCallResourceBySubresource(queue_object_info, - front_command_list_ids, - info.resource_id, - offset, - size, - info.subresource_indices, - json_path_sub, - Dx12DumpResourceType::kUav, - pos, - descriptor_heap_id, - descriptor_heap_index); - - if (info.counter_resource_id != format::kNullHandleId) - { - json_path_sub = json_path; - json_path_sub.emplace_back("unordered_access_views", resource_index); - json_path_sub.emplace_back("counter_resource", format::kNoneIndex); - CopyDrawCallResourceBySubresource(queue_object_info, - front_command_list_ids, - info.counter_resource_id, - info.view.Buffer.CounterOffsetInBytes, - 0, - sub_indices_emptry, - json_path_sub, - Dx12DumpResourceType::kUavCounter, - pos, - descriptor_heap_id, - descriptor_heap_index); - } - ++resource_index; + WriteRootParameters(queue_object_info, + front_command_list_ids, + pos, + Dx12DumpResourceType::kComputeRootParameters, + *descriptor_heap_ids, + track_dump_resources_.target.compute_root_parameters); } + break; } + case DumpDrawCallType::kIndirect: + { + // ExecuteIndirect could run draw or dispatch. + if (!track_dump_resources_.target.graphics_root_parameters.empty()) + { + WriteRootParameters(queue_object_info, + front_command_list_ids, + pos, + Dx12DumpResourceType::kGraphicsRootParameters, + *descriptor_heap_ids, + track_dump_resources_.target.graphics_root_parameters); + } + if (!track_dump_resources_.target.compute_root_parameters.empty()) + { + WriteRootParameters(queue_object_info, + front_command_list_ids, + pos, + Dx12DumpResourceType::kComputeRootParameters, + *descriptor_heap_ids, + track_dump_resources_.target.compute_root_parameters); + } + break; + } + default: + // It shouldn't be kBundle or kUnknown + break; } } } - // render target - // render target isn't available in Bundle. - resource_index = 0; - auto rt_size = track_dump_resources_.replay_render_target_handles.size(); - for (uint32_t i = 0; i < rt_size; ++i) + if (drawcall_type != DumpDrawCallType::kDispatch) { - auto descriptor_heap_id = track_dump_resources_.render_target_heap_ids[i]; - auto heap_object_info = get_object_info_func_(descriptor_heap_id); - auto heap_extra_info = GetExtraInfo(heap_object_info); - - for (const auto& info_pair : heap_extra_info->render_target_infos) + // render target + // render target isn't available in Bundle. + index = 0; + auto rt_size = track_dump_resources_.replay_render_target_handles.size(); + for (uint32_t i = 0; i < rt_size; ++i) { - auto descriptor_heap_index = info_pair.first; - const auto& info = info_pair.second; - if (info.replay_handle.ptr == track_dump_resources_.replay_render_target_handles[i].ptr) + auto descriptor_heap_id = track_dump_resources_.render_target_heap_ids[i]; + auto heap_object_info = get_object_info_func_(descriptor_heap_id); + auto heap_extra_info = GetExtraInfo(heap_object_info); + + uint32_t rt_heap_index = 0; + if (!ReplayCPUAddrMatchDescriptorHeap( + track_dump_resources_.replay_render_target_handles[i], *heap_extra_info, rt_heap_index)) { - uint64_t offset = 0; - uint64_t size = 0; - switch (info.view.ViewDimension) + continue; + } + json_path.clear(); + json_path.emplace_back("render_target_views", index); + active_delegate_->WriteSingleData(json_path, "heap_id", descriptor_heap_id); + active_delegate_->WriteSingleData(json_path, "heap_index", rt_heap_index); + + auto info_entry = heap_extra_info->rtv_infos.find(rt_heap_index); + if (info_entry != heap_extra_info->rtv_infos.end()) + { + auto descriptor_heap_index = info_entry->first; + const auto& info = info_entry->second; + uint64_t offset = 0; + uint64_t size = 0; + switch (info.desc.ViewDimension) { case D3D12_RTV_DIMENSION_BUFFER: { - auto size = graphics::dx12::GetSubresourcePixelByteSize(info.view.Format); - offset = info.view.Buffer.FirstElement * size; - size = info.view.Buffer.NumElements * size; + auto size = graphics::dx12::GetSubresourcePixelByteSize(info.desc.Format); + offset = info.desc.Buffer.FirstElement * size; + size = info.desc.Buffer.NumElements * size; break; } default: break; } - json_path.clear(); - json_path.emplace_back("render_target_views", resource_index); + active_delegate_->WriteSingleData(json_path, "res_id", info.resource_id); + CopyDrawCallResourceBySubresource(queue_object_info, front_command_list_ids, info.resource_id, - 0, - 0, + offset, + size, info.subresource_indices, json_path, Dx12DumpResourceType::kRtv, pos, descriptor_heap_id, descriptor_heap_index); - ++resource_index; - break; } } - } - - // depth stencil - // depth stencil isn't available in Bundle. - if (track_dump_resources_.replay_depth_stencil_handle.ptr != kNullCpuAddress) - { - auto descriptor_heap_id = track_dump_resources_.depth_stencil_heap_id; - auto heap_object_info = get_object_info_func_(descriptor_heap_id); - auto heap_extra_info = GetExtraInfo(heap_object_info); - for (const auto& info_pair : heap_extra_info->depth_stencil_infos) + // depth stencil + // depth stencil isn't available in Bundle. + if (track_dump_resources_.replay_depth_stencil_handle.ptr != kNullCpuAddress) { - auto descriptor_heap_index = info_pair.first; - const auto& info = info_pair.second; - if (info.replay_handle.ptr == track_dump_resources_.replay_depth_stencil_handle.ptr) + auto descriptor_heap_id = track_dump_resources_.depth_stencil_heap_id; + auto heap_object_info = get_object_info_func_(descriptor_heap_id); + auto heap_extra_info = GetExtraInfo(heap_object_info); + + uint32_t ds_heap_index = 0; + if (ReplayCPUAddrMatchDescriptorHeap( + track_dump_resources_.replay_depth_stencil_handle, *heap_extra_info, ds_heap_index)) { json_path.clear(); - json_path.emplace_back("depth_stencil_views", format::kNoneIndex); - CopyDrawCallResourceBySubresource(queue_object_info, - front_command_list_ids, - info.resource_id, - 0, - 0, - info.subresource_indices, - json_path, - Dx12DumpResourceType::kDsv, - pos, - descriptor_heap_id, - descriptor_heap_index); - break; + json_path.emplace_back("depth_stencil_view", format::kNoneIndex); + active_delegate_->WriteSingleData(json_path, "heap_id", descriptor_heap_id); + active_delegate_->WriteSingleData(json_path, "heap_index", ds_heap_index); + + auto info_entry = heap_extra_info->dsv_infos.find(ds_heap_index); + if (info_entry != heap_extra_info->dsv_infos.end()) + { + auto descriptor_heap_index = info_entry->first; + const auto& info = info_entry->second; + active_delegate_->WriteSingleData(json_path, "res_id", info.resource_id); + + CopyDrawCallResourceBySubresource(queue_object_info, + front_command_list_ids, + info.resource_id, + 0, + 0, + info.subresource_indices, + json_path, + Dx12DumpResourceType::kDsv, + pos, + descriptor_heap_id, + descriptor_heap_index); + } } } } @@ -932,7 +1391,7 @@ void Dx12DumpResources::CopyDrawCallResourceByGPUVA(DxObjectInfo* format::HandleId descriptor_heap_id, uint32_t descriptor_heap_index) { - if (captured_source_gpu_va == 0) + if (captured_source_gpu_va == kNullGpuAddress) { return; } @@ -965,6 +1424,10 @@ void Dx12DumpResources::CopyDrawCallResourceBySubresource(DxObjectInfo* format::HandleId descriptor_heap_id, uint32_t descriptor_heap_index) { + if (source_resource_id == format::kNullHandleId) + { + return; + } CopyResourceDataPtr copy_resource_data(new CopyResourceData()); copy_resource_data->subresource_indices = subresource_indices; copy_resource_data->json_path = json_path; @@ -1482,9 +1945,11 @@ void DefaultDx12DumpResourcesDelegate::BeginDumpResources(const std::string& } json_filename_ += "_dr." + util::get_json_format(json_options_.format); json_options_.data_sub_dir = util::filepath::GetFilenameStem(json_filename_); - json_options_.root_dir = util::filepath::GetBasedir(json_filename_); + json_options_.root_dir = util::filepath::GetBasedir(capture_file_name); + + auto file_path = json_options_.root_dir + util::filepath::kPathSepStr + json_filename_; - util::platform::FileOpen(&json_file_handle_, json_filename_.c_str(), "w"); + util::platform::FileOpen(&json_file_handle_, file_path.c_str(), "w"); header_["D3D12SDKVersion"] = std::to_string(D3D12SDKVersion); header_["gfxreconversion"] = GFXRECON_PROJECT_VERSION_STRING; @@ -1510,6 +1975,7 @@ void DefaultDx12DumpResourcesDelegate::BeginDumpResources(const std::string& void DefaultDx12DumpResourcesDelegate::DumpResource(CopyResourceDataPtr resource_data) { + auto* jdata_sub = &draw_call_; WriteResource(resource_data); } @@ -1520,15 +1986,11 @@ void DefaultDx12DumpResourcesDelegate::EndDumpResources() EndFile(); } -void DefaultDx12DumpResourcesDelegate::WriteResource(const CopyResourceDataPtr resource_data) +nlohmann::ordered_json* +DefaultDx12DumpResourcesDelegate::FindDrawCallJsonPath(const std::vector>& json_path) { - if (resource_data->source_resource_id == format::kNullHandleId) - { - return; - } - auto* jdata_sub = &draw_call_; - for (const auto& path : resource_data->json_path) + for (const auto& path : json_path) { if (path.second == format::kNoneIndex) { @@ -1539,6 +2001,55 @@ void DefaultDx12DumpResourcesDelegate::WriteResource(const CopyResourceDataPtr r jdata_sub = &(*jdata_sub)[path.first][path.second]; } } + return jdata_sub; +} + +void DefaultDx12DumpResourcesDelegate::WriteSingleData(const std::vector>& json_path, + const std::string& key, + uint64_t value) +{ + auto* jdata_sub = FindDrawCallJsonPath(json_path); + util::FieldToJson((*jdata_sub)[key], value, json_options_); +} + +void DefaultDx12DumpResourcesDelegate::WriteSingleData(const std::vector>& json_path, + const uint32_t index, + uint64_t value) +{ + auto* jdata_sub = FindDrawCallJsonPath(json_path); + util::FieldToJson((*jdata_sub)[index], value, json_options_); +} + +void DefaultDx12DumpResourcesDelegate::WriteSingleData(const std::vector>& json_path, + const std::string& key, + const std::string& value) +{ + auto* jdata_sub = FindDrawCallJsonPath(json_path); + util::FieldToJson((*jdata_sub)[key], value, json_options_); +} + +void DefaultDx12DumpResourcesDelegate::WriteEmptyNode(const std::vector>& json_path) +{ + FindDrawCallJsonPath(json_path); +} + +void DefaultDx12DumpResourcesDelegate::WriteNote(const std::vector>& json_path, + const std::string& value) +{ + auto* jdata_sub = FindDrawCallJsonPath(json_path); + auto& jdata_notes = (*jdata_sub)[NameNotes()]; + auto size = jdata_notes.size(); + util::FieldToJson(jdata_notes[size], value, json_options_); +} + +void DefaultDx12DumpResourcesDelegate::WriteResource(const CopyResourceDataPtr resource_data) +{ + if (resource_data->source_resource_id == format::kNullHandleId) + { + return; + } + auto* jdata_sub = FindDrawCallJsonPath(resource_data->json_path); + std::string prefix_file_name = json_options_.data_sub_dir + "_" + Dx12ResourceTypeToString(resource_data->resource_type); WriteResource(*jdata_sub, prefix_file_name, resource_data); @@ -1560,16 +2071,20 @@ void DefaultDx12DumpResourcesDelegate::WriteResource(nlohmann::ordered_json& j std::string file_name = prefix_file_name + "_res_id_" + std::to_string(resource_data->source_resource_id); + util::FieldToJson(jdata["heap_id"], resource_data->descriptor_heap_id, json_options_); + util::FieldToJson(jdata["heap_index"], resource_data->descriptor_heap_index, json_options_); util::FieldToJson(jdata["res_id"], resource_data->source_resource_id, json_options_); + util::FieldToJson(jdata["dimension"], util::ToString(resource_data->desc.Dimension), json_options_); std::string suffix = Dx12DumpResourcePosToString(resource_data->dump_position); std::string json_path = suffix + "_file"; + auto json_sub_index = 0; for (const auto sub_index : resource_data->subresource_indices) { auto offset = resource_data->subresource_offsets[sub_index]; auto size = resource_data->subresource_sizes[sub_index]; - auto& jdata_sub = jdata["sub"][sub_index]; + auto& jdata_sub = jdata["subs"][json_sub_index]; util::FieldToJson(jdata_sub["index"], sub_index, json_options_); util::FieldToJson(jdata_sub["offset"], offset, json_options_); util::FieldToJson(jdata_sub["size"], size, json_options_); @@ -1582,6 +2097,7 @@ void DefaultDx12DumpResourcesDelegate::WriteResource(nlohmann::ordered_json& j std::string file_path = gfxrecon::util::filepath::Join(json_options_.root_dir, file_name_sub); WriteBinaryFile(file_path, resource_data->datas[sub_index], offset, size); + ++json_sub_index; } } @@ -1654,23 +2170,27 @@ void DefaultDx12DumpResourcesDelegate::TestWriteImageResource(const std::string& double bytes_per_pixel = static_cast(row_pitch_aligned_size) / (static_cast(resource_data->footprints[sub_index].Footprint.RowPitch / 4) * resource_data->footprints[sub_index].Footprint.Height); + + std::string suffix = Dx12DumpResourcePosToString(resource_data->dump_position); + file_name_sub += "_" + suffix + ".bmp "; + if (bytes_per_pixel != 4.0) { - GFXRECON_LOG_WARNING("Dump images could not be created for before and after resource of " - "'%s_before\\after.bmp'. Only formats " - "with 4 bytes per pixel are supported. Current format %s " - "is %.2f bytes per pixel.", - file_name_sub.c_str(), - util::ToString(resource_data->footprints[sub_index].Footprint.Format).c_str(), - bytes_per_pixel); + std::string msg = "Dump images could not be created for before and after resource of " + file_name_sub + + ".Only formats with 4 bytes per pixel are supported.Current format " + + util::ToString(resource_data->footprints[sub_index].Footprint.Format) + "is " + + std::to_string(bytes_per_pixel) + " bytes per pixel."; + GFXRECON_LOG_ERROR(msg.c_str()); + + auto json_path_sub = resource_data->json_path; + json_path_sub.emplace_back("subs", sub_index); + WriteNote(json_path_sub, msg); continue; } // Write data. GFXRECON_ASSERT(!resource_data->datas[sub_index].empty()); - std::string suffix = Dx12DumpResourcePosToString(resource_data->dump_position); - file_name_sub += "_" + suffix + ".bmp "; std::string file_path = gfxrecon::util::filepath::Join(json_options_.root_dir, file_name_sub); if (!util::imagewriter::WriteBmpImage(file_path, resource_data->footprints[sub_index].Footprint.Width, @@ -1679,7 +2199,12 @@ void DefaultDx12DumpResourcesDelegate::TestWriteImageResource(const std::string& resource_data->datas[sub_index].data() + offset, resource_data->footprints[sub_index].Footprint.RowPitch)) { - GFXRECON_LOG_ERROR("Dump image could not be created: failed to write BMP file %s", file_name_sub.c_str()); + std::string msg = "Dump image could not be created: failed to write BMP file " + file_name_sub; + GFXRECON_LOG_ERROR(msg.c_str()); + + auto json_path_sub = resource_data->json_path; + json_path_sub.emplace_back("subs", sub_index); + WriteNote(json_path_sub, msg); } } } diff --git a/framework/decode/dx12_dump_resources.h b/framework/decode/dx12_dump_resources.h index 6dd959d308..4d015790a3 100644 --- a/framework/decode/dx12_dump_resources.h +++ b/framework/decode/dx12_dump_resources.h @@ -56,6 +56,8 @@ enum class Dx12DumpResourceType : uint32_t kCbv, kExecuteIndirectArg, kExecuteIndirectCount, + kGraphicsRootParameters, + kComputeRootParameters, }; struct CopyResourceData @@ -152,6 +154,17 @@ class Dx12DumpResourcesDelegate virtual void BeginDumpResources(const std::string& filename, const TrackDumpResources& track_dump_resources) = 0; virtual void DumpResource(CopyResourceDataPtr resource_data) = 0; virtual void EndDumpResources() = 0; + virtual void WriteSingleData(const std::vector>& json_path, + const std::string& key, + uint64_t value) = 0; + virtual void WriteSingleData(const std::vector>& json_path, + const uint32_t index, + uint64_t value) = 0; + virtual void WriteSingleData(const std::vector>& json_path, + const std::string& key, + const std::string& value) = 0; + virtual void WriteEmptyNode(const std::vector>& json_path) = 0; + virtual void WriteNote(const std::vector>& json_path, const std::string& value) = 0; }; class DefaultDx12DumpResourcesDelegate : public Dx12DumpResourcesDelegate @@ -163,6 +176,18 @@ class DefaultDx12DumpResourcesDelegate : public Dx12DumpResourcesDelegate const TrackDumpResources& track_dump_resources) override; virtual void DumpResource(CopyResourceDataPtr resource_data) override; virtual void EndDumpResources() override; + virtual void WriteSingleData(const std::vector>& json_path, + const std::string& key, + uint64_t value) override; + virtual void WriteSingleData(const std::vector>& json_path, + const uint32_t index, + uint64_t value) override; + virtual void WriteSingleData(const std::vector>& json_path, + const std::string& key, + const std::string& value) override; + virtual void WriteEmptyNode(const std::vector>& json_path) override; + virtual void WriteNote(const std::vector>& json_path, + const std::string& value) override; private: void WriteResource(const CopyResourceDataPtr resource_data); @@ -175,7 +200,10 @@ class DefaultDx12DumpResourcesDelegate : public Dx12DumpResourcesDelegate void WriteBlockStart(); void WriteBlockEnd(); + nlohmann::ordered_json* FindDrawCallJsonPath(const std::vector>& json_path); + constexpr const char* NameDrawCall() const { return "draw_call"; } + constexpr const char* NameNotes() const { return "notes"; } bool WriteBinaryFile(const std::string& filename, const std::vector& data, uint64_t offset, uint64_t size); @@ -247,6 +275,22 @@ class Dx12DumpResources void FinishDump(DxObjectInfo* queue_object_info); void CloseDump(); + void WriteDescripotTable(DxObjectInfo* queue_object_info, + const std::vector& front_command_list_ids, + graphics::dx12::Dx12DumpResourcePos pos, + std::vector> json_path, + const D3D12DescriptorHeapInfo* heap_info, + format::HandleId heap_id, + uint32_t heap_index, + const D3D12_DESCRIPTOR_RANGE1* range); + + void WriteRootParameters(DxObjectInfo* queue_object_info, + const std::vector& front_command_list_ids, + graphics::dx12::Dx12DumpResourcePos pos, + Dx12DumpResourceType res_type, + const std::vector& descriptor_heap_ids, + const std::unordered_map& root_parameters); + void CopyDrawCallResources(DxObjectInfo* queue_object_info, const std::vector& front_command_list_ids, graphics::dx12::Dx12DumpResourcePos pos); diff --git a/framework/decode/dx12_object_info.h b/framework/decode/dx12_object_info.h index 2198fffde9..2ac21963e9 100644 --- a/framework/decode/dx12_object_info.h +++ b/framework/decode/dx12_object_info.h @@ -50,8 +50,6 @@ GFXRECON_BEGIN_NAMESPACE(decode) constexpr size_t kNullCpuAddress = 0; constexpr uint64_t kNullGpuAddress = 0; -typedef std::array DescriptorIncrements; - enum class DxObjectInfoType : uint32_t { kUnused = 0, @@ -286,49 +284,66 @@ struct D3D12DeviceInfo : DxObjectExtraInfo bool is_uma{ false }; }; -struct ConstantBufferInfo +// Constant Buffer View, Shader Resource View and Unordered Access View could overrride each other. +// So they should be in the one container. +struct DHConstantBufferViewInfo { - D3D12_CONSTANT_BUFFER_VIEW_DESC captured_view{}; + D3D12_CONSTANT_BUFFER_VIEW_DESC captured_desc{}; + bool is_desc_null{ false }; D3D12_CPU_DESCRIPTOR_HANDLE replay_handle{ kNullCpuAddress }; }; -struct ShaderResourceInfo +struct DHShaderResourceViewInfo { + D3D12_SHADER_RESOURCE_VIEW_DESC desc{}; + bool is_desc_null{ false }; format::HandleId resource_id{ format::kNullHandleId }; - D3D12_SHADER_RESOURCE_VIEW_DESC view{}; - bool is_view_null{ false }; D3D12_CPU_DESCRIPTOR_HANDLE replay_handle{ kNullCpuAddress }; std::vector subresource_indices; }; -struct UnorderedAccessInfo +struct DHUnorderedAccessViewInfo { + D3D12_UNORDERED_ACCESS_VIEW_DESC desc{}; + bool is_desc_null{ false }; format::HandleId resource_id{ format::kNullHandleId }; format::HandleId counter_resource_id{ format::kNullHandleId }; - D3D12_UNORDERED_ACCESS_VIEW_DESC view{}; - bool is_view_null{ false }; D3D12_CPU_DESCRIPTOR_HANDLE replay_handle{ kNullCpuAddress }; std::vector subresource_indices; }; -struct RenderTargetInfo +struct DHCbvSrvUavInfo +{ + D3D12_DESCRIPTOR_RANGE_TYPE type{}; + DHConstantBufferViewInfo cbv; + DHShaderResourceViewInfo srv; + DHUnorderedAccessViewInfo uav; +}; + +struct DHRenderTargetViewInfo { format::HandleId resource_id{ format::kNullHandleId }; - D3D12_RENDER_TARGET_VIEW_DESC view{}; - bool is_view_null{ false }; + D3D12_RENDER_TARGET_VIEW_DESC desc{}; + bool is_desc_null{ false }; D3D12_CPU_DESCRIPTOR_HANDLE replay_handle{ kNullCpuAddress }; std::vector subresource_indices; }; -struct DepthStencilInfo +struct DHDepthStencilViewInfo { format::HandleId resource_id{ format::kNullHandleId }; - D3D12_DEPTH_STENCIL_VIEW_DESC view{}; - bool is_view_null{ false }; + D3D12_DEPTH_STENCIL_VIEW_DESC desc{}; + bool is_desc_null{ false }; D3D12_CPU_DESCRIPTOR_HANDLE replay_handle{ kNullCpuAddress }; std::vector subresource_indices; }; +struct DHSamplerInfo +{ + D3D12_SAMPLER_DESC desc{}; + D3D12_CPU_DESCRIPTOR_HANDLE replay_handle{ kNullCpuAddress }; +}; + struct D3D12DescriptorHeapInfo : DxObjectExtraInfo { static constexpr DxObjectInfoType kType = DxObjectInfoType::kID3D12DescriptorHeapInfo; @@ -344,11 +359,10 @@ struct D3D12DescriptorHeapInfo : DxObjectExtraInfo uint64_t replay_gpu_addr_begin{ kNullGpuAddress }; // Descriptor info maps. Key is descriptor's uint32_t heap index. - std::map constant_buffer_infos; - std::map shader_resource_infos; - std::map unordered_access_infos; - std::map render_target_infos; - std::map depth_stencil_infos; + std::map cbv_srv_uav_infos; + std::map rtv_infos; + std::map dsv_infos; + std::map sampler_infos; }; struct D3D12FenceInfo : DxObjectExtraInfo diff --git a/framework/decode/dx12_replay_consumer_base.cpp b/framework/decode/dx12_replay_consumer_base.cpp index 5b1fbc8210..4358bd2010 100644 --- a/framework/decode/dx12_replay_consumer_base.cpp +++ b/framework/decode/dx12_replay_consumer_base.cpp @@ -4475,7 +4475,6 @@ void Dx12ReplayConsumerBase::PreCall_ID3D12Device_CreateConstantBufferView( { auto heap_object_info = GetObjectInfo(DestDescriptor.heap_id); auto heap_extra_info = GetExtraInfo(heap_object_info); - GFXRECON_ASSERT(pDesc != nullptr); auto desc = pDesc->GetMetaStructPointer(); @@ -4484,10 +4483,11 @@ void Dx12ReplayConsumerBase::PreCall_ID3D12Device_CreateConstantBufferView( // The decoded D3D12_CONSTANT_BUFFER_VIEW_DESC pointer from pDesc is an optional parameter in the API // ID3D12Device::CreateConstantBufferView. In this case, the meta struct pointer returned from the // StructPointerDecoder could be null, so check for it. - ConstantBufferInfo info; - info.captured_view = *(desc->decoded_value); + DHCbvSrvUavInfo info; + info.type = D3D12_DESCRIPTOR_RANGE_TYPE_CBV; + info.cbv.captured_desc = *(desc->decoded_value); - heap_extra_info->constant_buffer_infos[DestDescriptor.index] = std::move(info); + heap_extra_info->cbv_srv_uav_infos[DestDescriptor.index] = std::move(info); } } @@ -4500,7 +4500,24 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateConstantBufferView( auto heap_object_info = GetObjectInfo(DestDescriptor.heap_id); auto heap_extra_info = GetExtraInfo(heap_object_info); - heap_extra_info->constant_buffer_infos[DestDescriptor.index].replay_handle = (*DestDescriptor.decoded_value); + heap_extra_info->cbv_srv_uav_infos[DestDescriptor.index].cbv.replay_handle = (*DestDescriptor.decoded_value); +} + +void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateSampler( + const ApiCallInfo& call_info, + DxObjectInfo* object_info, + StructPointerDecoder* pDesc, + Decoded_D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) +{ + auto heap_object_info = GetObjectInfo(DestDescriptor.heap_id); + auto heap_extra_info = GetExtraInfo(heap_object_info); + GFXRECON_ASSERT(pDesc != nullptr); + auto desc = pDesc->GetMetaStructPointer(); + + DHSamplerInfo info; + info.desc = *(desc->decoded_value); + info.replay_handle = (*DestDescriptor.decoded_value); + heap_extra_info->sampler_infos[DestDescriptor.index] = std::move(info); } std::vector GetDescriptorSubresourceIndices(uint32_t first_mip_slice, @@ -4533,32 +4550,34 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateShaderResourceView( auto heap_object_info = GetObjectInfo(DestDescriptor.heap_id); auto heap_extra_info = GetExtraInfo(heap_object_info); - ShaderResourceInfo info; - info.resource_id = pResource; - info.replay_handle = *DestDescriptor.decoded_value; + DHCbvSrvUavInfo info; + info.type = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + auto& srv_info = info.srv; + srv_info.resource_id = pResource; + srv_info.replay_handle = *DestDescriptor.decoded_value; if (pDesc->IsNull()) { - info.is_view_null = true; - info.subresource_indices.emplace_back(0); + srv_info.is_desc_null = true; + srv_info.subresource_indices.emplace_back(0); } else { - info.view = *(pDesc->GetMetaStructPointer()->decoded_value); - info.is_view_null = false; + srv_info.desc = *(pDesc->GetMetaStructPointer()->decoded_value); + srv_info.is_desc_null = false; if (pResource != format::kNullHandleId) { auto desc = reinterpret_cast(GetObjectInfo(pResource)->object)->GetDesc(); auto mip_count = desc.MipLevels; auto array_count = desc.DepthOrArraySize; - switch (info.view.ViewDimension) + switch (srv_info.desc.ViewDimension) { case D3D12_SRV_DIMENSION_BUFFER: - info.subresource_indices.emplace_back(0); + srv_info.subresource_indices.emplace_back(0); break; case D3D12_SRV_DIMENSION_TEXTURE1D: { - auto view = info.view.Texture1D; + auto view = srv_info.desc.Texture1D; auto mip_size = view.MipLevels; if (mip_size == -1) { @@ -4570,20 +4589,20 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateShaderResourceView( { mip_size -= view.MostDetailedMip; } - info.subresource_indices = GetDescriptorSubresourceIndices( + srv_info.subresource_indices = GetDescriptorSubresourceIndices( view.MostDetailedMip, mip_size, mip_count, 0, 1, array_count, 0); } else { mip_size -= view.MostDetailedMip; - info.subresource_indices = GetDescriptorSubresourceIndices( + srv_info.subresource_indices = GetDescriptorSubresourceIndices( view.ResourceMinLODClamp, mip_size, mip_count, 0, 1, array_count, 0); } break; } case D3D12_SRV_DIMENSION_TEXTURE1DARRAY: { - auto view = info.view.Texture1DArray; + auto view = srv_info.desc.Texture1DArray; auto mip_size = view.MipLevels; if (mip_size == -1) { @@ -4600,30 +4619,30 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateShaderResourceView( { mip_size -= view.MostDetailedMip; } - info.subresource_indices = GetDescriptorSubresourceIndices(view.MostDetailedMip, - mip_size, - mip_count, - view.FirstArraySlice, - array_size, - array_count, - 0); + srv_info.subresource_indices = GetDescriptorSubresourceIndices(view.MostDetailedMip, + mip_size, + mip_count, + view.FirstArraySlice, + array_size, + array_count, + 0); } else { mip_size -= view.MostDetailedMip; - info.subresource_indices = GetDescriptorSubresourceIndices(view.ResourceMinLODClamp, - mip_size, - mip_count, - view.FirstArraySlice, - array_size, - array_count, - 0); + srv_info.subresource_indices = GetDescriptorSubresourceIndices(view.ResourceMinLODClamp, + mip_size, + mip_count, + view.FirstArraySlice, + array_size, + array_count, + 0); } break; } case D3D12_SRV_DIMENSION_TEXTURE2D: { - auto view = info.view.Texture2D; + auto view = srv_info.desc.Texture2D; auto mip_size = view.MipLevels; if (mip_size == -1) { @@ -4635,20 +4654,20 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateShaderResourceView( { mip_size -= view.MostDetailedMip; } - info.subresource_indices = GetDescriptorSubresourceIndices( + srv_info.subresource_indices = GetDescriptorSubresourceIndices( view.MostDetailedMip, mip_size, mip_count, 0, 1, array_count, view.PlaneSlice); } else { mip_size -= view.MostDetailedMip; - info.subresource_indices = GetDescriptorSubresourceIndices( + srv_info.subresource_indices = GetDescriptorSubresourceIndices( view.ResourceMinLODClamp, mip_size, mip_count, 0, 1, array_count, view.PlaneSlice); } break; } case D3D12_SRV_DIMENSION_TEXTURE2DARRAY: { - auto view = info.view.Texture2DArray; + auto view = srv_info.desc.Texture2DArray; auto mip_size = view.MipLevels; if (mip_size == -1) { @@ -4665,48 +4684,49 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateShaderResourceView( { mip_size -= view.MostDetailedMip; } - info.subresource_indices = GetDescriptorSubresourceIndices(view.MostDetailedMip, - mip_size, - mip_count, - view.FirstArraySlice, - array_size, - array_count, - view.PlaneSlice); + srv_info.subresource_indices = GetDescriptorSubresourceIndices(view.MostDetailedMip, + mip_size, + mip_count, + view.FirstArraySlice, + array_size, + array_count, + view.PlaneSlice); } else { mip_size -= view.MostDetailedMip; - info.subresource_indices = GetDescriptorSubresourceIndices(view.ResourceMinLODClamp, - mip_size, - mip_count, - view.FirstArraySlice, - array_size, - array_count, - view.PlaneSlice); + srv_info.subresource_indices = GetDescriptorSubresourceIndices(view.ResourceMinLODClamp, + mip_size, + mip_count, + view.FirstArraySlice, + array_size, + array_count, + view.PlaneSlice); } break; } case D3D12_SRV_DIMENSION_TEXTURE2DMS: { - info.subresource_indices = GetDescriptorSubresourceIndices(0, 1, mip_count, 0, 1, array_count, 0); + srv_info.subresource_indices = + GetDescriptorSubresourceIndices(0, 1, mip_count, 0, 1, array_count, 0); break; } case D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY: { - auto view = info.view.Texture2DMSArray; + auto view = srv_info.desc.Texture2DMSArray; auto array_size = view.ArraySize; if (array_size == -1) { array_size = array_count; } - info.subresource_indices = GetDescriptorSubresourceIndices( + srv_info.subresource_indices = GetDescriptorSubresourceIndices( 0, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); break; } case D3D12_SRV_DIMENSION_TEXTURE3D: { array_count = 1; - auto view = info.view.Texture3D; + auto view = srv_info.desc.Texture3D; auto mip_size = view.MipLevels; if (mip_size == -1) { @@ -4718,19 +4738,19 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateShaderResourceView( { mip_size -= view.MostDetailedMip; } - info.subresource_indices = GetDescriptorSubresourceIndices( + srv_info.subresource_indices = GetDescriptorSubresourceIndices( view.MostDetailedMip, mip_size, mip_count, 0, 1, array_count, 0); } else { - info.subresource_indices = GetDescriptorSubresourceIndices( + srv_info.subresource_indices = GetDescriptorSubresourceIndices( view.ResourceMinLODClamp, mip_size, mip_count, 0, 1, array_count, 0); } break; } case D3D12_SRV_DIMENSION_TEXTURECUBE: { - auto view = info.view.TextureCube; + auto view = srv_info.desc.TextureCube; auto mip_size = view.MipLevels; if (mip_size == -1) { @@ -4742,19 +4762,19 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateShaderResourceView( { mip_size -= view.MostDetailedMip; } - info.subresource_indices = GetDescriptorSubresourceIndices( + srv_info.subresource_indices = GetDescriptorSubresourceIndices( view.MostDetailedMip, mip_size, mip_count, 0, 1, array_count, 0); } else { - info.subresource_indices = GetDescriptorSubresourceIndices( + srv_info.subresource_indices = GetDescriptorSubresourceIndices( view.ResourceMinLODClamp, mip_size, mip_count, 0, 1, array_count, 0); } break; } case D3D12_SRV_DIMENSION_TEXTURECUBEARRAY: { - auto view = info.view.TextureCubeArray; + auto view = srv_info.desc.TextureCubeArray; auto mip_size = view.MipLevels; if (mip_size == -1) { @@ -4771,23 +4791,23 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateShaderResourceView( { mip_size -= view.MostDetailedMip; } - info.subresource_indices = GetDescriptorSubresourceIndices(view.MostDetailedMip, - mip_size, - mip_count, - view.First2DArrayFace, - array_size, - array_count, - 0); + srv_info.subresource_indices = GetDescriptorSubresourceIndices(view.MostDetailedMip, + mip_size, + mip_count, + view.First2DArrayFace, + array_size, + array_count, + 0); } else { - info.subresource_indices = GetDescriptorSubresourceIndices(view.ResourceMinLODClamp, - mip_size, - mip_count, - view.First2DArrayFace, - array_size, - array_count, - 0); + srv_info.subresource_indices = GetDescriptorSubresourceIndices(view.ResourceMinLODClamp, + mip_size, + mip_count, + view.First2DArrayFace, + array_size, + array_count, + 0); } break; } @@ -4798,7 +4818,7 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateShaderResourceView( } } } - heap_extra_info->shader_resource_infos[DestDescriptor.index] = std::move(info); + heap_extra_info->cbv_srv_uav_infos[DestDescriptor.index] = std::move(info); } void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateUnorderedAccessView( @@ -4812,82 +4832,91 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateUnorderedAccessView( auto heap_object_info = GetObjectInfo(DestDescriptor.heap_id); auto heap_extra_info = GetExtraInfo(heap_object_info); - UnorderedAccessInfo info; - info.resource_id = pResource; - info.counter_resource_id = pCounterResource; - info.replay_handle = *DestDescriptor.decoded_value; + DHCbvSrvUavInfo info; + info.type = D3D12_DESCRIPTOR_RANGE_TYPE_UAV; + auto& uav_info = info.uav; + uav_info.resource_id = pResource; + uav_info.counter_resource_id = pCounterResource; + uav_info.replay_handle = *DestDescriptor.decoded_value; if (pDesc->IsNull()) { - info.is_view_null = true; - info.subresource_indices.emplace_back(0); + uav_info.is_desc_null = true; + uav_info.subresource_indices.emplace_back(0); } else { - info.view = *(pDesc->GetMetaStructPointer()->decoded_value); - info.is_view_null = false; + uav_info.desc = *(pDesc->GetMetaStructPointer()->decoded_value); + uav_info.is_desc_null = false; if (pResource != format::kNullHandleId) { auto desc = reinterpret_cast(GetObjectInfo(pResource)->object)->GetDesc(); auto mip_count = desc.MipLevels; auto array_count = desc.DepthOrArraySize; - switch (info.view.ViewDimension) + switch (uav_info.desc.ViewDimension) { case D3D12_UAV_DIMENSION_BUFFER: - info.subresource_indices.emplace_back(0); + uav_info.subresource_indices.emplace_back(0); break; case D3D12_UAV_DIMENSION_TEXTURE1D: - info.subresource_indices = GetDescriptorSubresourceIndices( - info.view.Texture1D.MipSlice, 1, mip_count, 0, 1, array_count, 0); + uav_info.subresource_indices = GetDescriptorSubresourceIndices( + uav_info.desc.Texture1D.MipSlice, 1, mip_count, 0, 1, array_count, 0); break; case D3D12_UAV_DIMENSION_TEXTURE1DARRAY: { - auto view = info.view.Texture1DArray; + auto view = uav_info.desc.Texture1DArray; auto array_size = view.ArraySize; if (array_size == -1) { array_size = array_count; } - info.subresource_indices = GetDescriptorSubresourceIndices( + uav_info.subresource_indices = GetDescriptorSubresourceIndices( view.MipSlice, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); break; } case D3D12_UAV_DIMENSION_TEXTURE2D: - info.subresource_indices = GetDescriptorSubresourceIndices( - info.view.Texture2D.MipSlice, 1, mip_count, 0, 1, array_count, info.view.Texture2D.PlaneSlice); + uav_info.subresource_indices = + GetDescriptorSubresourceIndices(uav_info.desc.Texture2D.MipSlice, + 1, + mip_count, + 0, + 1, + array_count, + uav_info.desc.Texture2D.PlaneSlice); break; case D3D12_UAV_DIMENSION_TEXTURE2DARRAY: { - auto view = info.view.Texture2DArray; + auto view = uav_info.desc.Texture2DArray; auto array_size = view.ArraySize; if (array_size == -1) { array_size = array_count; } - info.subresource_indices = GetDescriptorSubresourceIndices( + uav_info.subresource_indices = GetDescriptorSubresourceIndices( view.MipSlice, 1, mip_count, view.FirstArraySlice, array_size, array_count, view.PlaneSlice); break; } case D3D12_UAV_DIMENSION_TEXTURE2DMS: - info.subresource_indices = GetDescriptorSubresourceIndices(0, 1, mip_count, 0, 1, array_count, 0); + uav_info.subresource_indices = + GetDescriptorSubresourceIndices(0, 1, mip_count, 0, 1, array_count, 0); break; case D3D12_UAV_DIMENSION_TEXTURE2DMSARRAY: { - auto view = info.view.Texture2DMSArray; + auto view = uav_info.desc.Texture2DMSArray; auto array_size = view.ArraySize; if (array_size == -1) { array_size = array_count; } - info.subresource_indices = GetDescriptorSubresourceIndices( + uav_info.subresource_indices = GetDescriptorSubresourceIndices( 0, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); break; } case D3D12_UAV_DIMENSION_TEXTURE3D: { // DUMPTODO: handle FirstWSlice and WSize - info.subresource_indices = - GetDescriptorSubresourceIndices(info.view.Texture3D.MipSlice, 1, mip_count, 0, 1, 1, 0); + uav_info.subresource_indices = GetDescriptorSubresourceIndices( + uav_info.desc.Texture3D.MipSlice, 1, mip_count, 0, 1, 1, 0); break; } case D3D12_UAV_DIMENSION_UNKNOWN: @@ -4897,7 +4926,7 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateUnorderedAccessView( } } } - heap_extra_info->unordered_access_infos[DestDescriptor.index] = std::move(info); + heap_extra_info->cbv_srv_uav_infos[DestDescriptor.index] = std::move(info); } void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateRenderTargetView( @@ -4910,36 +4939,36 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateRenderTargetView( auto heap_object_info = GetObjectInfo(DestDescriptor.heap_id); auto heap_extra_info = GetExtraInfo(heap_object_info); - RenderTargetInfo info; + DHRenderTargetViewInfo info; info.resource_id = pResource; info.replay_handle = *DestDescriptor.decoded_value; if (pDesc->IsNull()) { - info.is_view_null = true; + info.is_desc_null = true; info.subresource_indices.emplace_back(0); } else { - info.view = *(pDesc->GetMetaStructPointer()->decoded_value); - info.is_view_null = false; + info.desc = *(pDesc->GetMetaStructPointer()->decoded_value); + info.is_desc_null = false; if (pResource != format::kNullHandleId) { auto desc = reinterpret_cast(GetObjectInfo(pResource)->object)->GetDesc(); auto mip_count = desc.MipLevels; auto array_count = desc.DepthOrArraySize; - switch (info.view.ViewDimension) + switch (info.desc.ViewDimension) { case D3D12_RTV_DIMENSION_BUFFER: info.subresource_indices.emplace_back(0); break; case D3D12_RTV_DIMENSION_TEXTURE1D: info.subresource_indices = GetDescriptorSubresourceIndices( - info.view.Texture1D.MipSlice, 1, mip_count, 0, 1, array_count, 0); + info.desc.Texture1D.MipSlice, 1, mip_count, 0, 1, array_count, 0); break; case D3D12_RTV_DIMENSION_TEXTURE1DARRAY: { - auto view = info.view.Texture1DArray; + auto view = info.desc.Texture1DArray; auto array_size = view.ArraySize; if (array_size == -1) { @@ -4951,11 +4980,11 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateRenderTargetView( } case D3D12_RTV_DIMENSION_TEXTURE2D: info.subresource_indices = GetDescriptorSubresourceIndices( - info.view.Texture2D.MipSlice, 1, mip_count, 0, 1, array_count, info.view.Texture2D.PlaneSlice); + info.desc.Texture2D.MipSlice, 1, mip_count, 0, 1, array_count, info.desc.Texture2D.PlaneSlice); break; case D3D12_RTV_DIMENSION_TEXTURE2DARRAY: { - auto view = info.view.Texture2DArray; + auto view = info.desc.Texture2DArray; auto array_size = view.ArraySize; if (array_size == -1) { @@ -4970,7 +4999,7 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateRenderTargetView( break; case D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY: { - auto view = info.view.Texture2DMSArray; + auto view = info.desc.Texture2DMSArray; auto array_size = view.ArraySize; if (array_size == -1) { @@ -4984,7 +5013,7 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateRenderTargetView( { // DUMPTODO: Handle FirstWSlice and WSize info.subresource_indices = - GetDescriptorSubresourceIndices(info.view.Texture3D.MipSlice, 1, mip_count, 0, 1, 1, 0); + GetDescriptorSubresourceIndices(info.desc.Texture3D.MipSlice, 1, mip_count, 0, 1, 1, 0); break; } case D3D12_RTV_DIMENSION_UNKNOWN: @@ -4994,7 +5023,7 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateRenderTargetView( } } } - heap_extra_info->render_target_infos[DestDescriptor.index] = std::move(info); + heap_extra_info->rtv_infos[DestDescriptor.index] = std::move(info); } void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateDepthStencilView( @@ -5007,33 +5036,33 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateDepthStencilView( auto heap_object_info = GetObjectInfo(DestDescriptor.heap_id); auto heap_extra_info = GetExtraInfo(heap_object_info); - DepthStencilInfo info; + DHDepthStencilViewInfo info; info.resource_id = pResource; info.replay_handle = *DestDescriptor.decoded_value; if (pDesc->IsNull()) { - info.is_view_null = true; + info.is_desc_null = true; info.subresource_indices.emplace_back(0); } else { - info.view = *(pDesc->GetMetaStructPointer()->decoded_value); - info.is_view_null = false; + info.desc = *(pDesc->GetMetaStructPointer()->decoded_value); + info.is_desc_null = false; if (pResource != format::kNullHandleId) { auto desc = reinterpret_cast(GetObjectInfo(pResource)->object)->GetDesc(); auto mip_count = desc.MipLevels; auto array_count = desc.DepthOrArraySize; - switch (info.view.ViewDimension) + switch (info.desc.ViewDimension) { case D3D12_DSV_DIMENSION_TEXTURE1D: info.subresource_indices = GetDescriptorSubresourceIndices( - info.view.Texture1D.MipSlice, 1, mip_count, 0, 1, array_count, 0); + info.desc.Texture1D.MipSlice, 1, mip_count, 0, 1, array_count, 0); break; case D3D12_DSV_DIMENSION_TEXTURE1DARRAY: { - auto view = info.view.Texture1DArray; + auto view = info.desc.Texture1DArray; auto array_size = view.ArraySize; if (array_size == -1) { @@ -5045,11 +5074,11 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateDepthStencilView( } case D3D12_DSV_DIMENSION_TEXTURE2D: info.subresource_indices = GetDescriptorSubresourceIndices( - info.view.Texture2D.MipSlice, 1, mip_count, 0, 1, array_count, 0); + info.desc.Texture2D.MipSlice, 1, mip_count, 0, 1, array_count, 0); break; case D3D12_DSV_DIMENSION_TEXTURE2DARRAY: { - auto view = info.view.Texture2DArray; + auto view = info.desc.Texture2DArray; auto array_size = view.ArraySize; if (array_size == -1) { @@ -5064,7 +5093,7 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateDepthStencilView( break; case D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY: { - auto view = info.view.Texture2DMSArray; + auto view = info.desc.Texture2DMSArray; auto array_size = view.ArraySize; if (array_size == -1) { @@ -5081,7 +5110,7 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateDepthStencilView( } } } - heap_extra_info->depth_stencil_infos[DestDescriptor.index] = std::move(info); + heap_extra_info->dsv_infos[DestDescriptor.index] = std::move(info); } void Dx12ReplayConsumerBase::PostCall_ID3D12GraphicsCommandList_OMSetRenderTargets( @@ -5214,28 +5243,17 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CopyDescriptors( auto dest_idx = dest_descriptor_info.index + dest_i + i; auto src_idx = src_descriptor_info.index + src_i + i; - if (src_heap_extra_info->constant_buffer_infos.count(src_idx) > 0) + if (src_heap_extra_info->cbv_srv_uav_infos.count(src_idx) > 0) { - dest_heap_extra_info->constant_buffer_infos[dest_idx] = - src_heap_extra_info->constant_buffer_infos[src_idx]; + dest_heap_extra_info->cbv_srv_uav_infos[dest_idx] = src_heap_extra_info->cbv_srv_uav_infos[src_idx]; } - if (src_heap_extra_info->shader_resource_infos.count(src_idx) > 0) + if (src_heap_extra_info->rtv_infos.count(src_idx) > 0) { - dest_heap_extra_info->shader_resource_infos[dest_idx] = - src_heap_extra_info->shader_resource_infos[src_idx]; + dest_heap_extra_info->rtv_infos[dest_idx] = src_heap_extra_info->rtv_infos[src_idx]; } - if (src_heap_extra_info->unordered_access_infos.count(src_idx) > 0) + if (src_heap_extra_info->dsv_infos.count(src_idx) > 0) { - dest_heap_extra_info->unordered_access_infos[dest_idx] = - src_heap_extra_info->unordered_access_infos[src_idx]; - } - if (src_heap_extra_info->render_target_infos.count(src_idx) > 0) - { - dest_heap_extra_info->render_target_infos[dest_idx] = src_heap_extra_info->render_target_infos[src_idx]; - } - if (src_heap_extra_info->depth_stencil_infos.count(src_idx) > 0) - { - dest_heap_extra_info->depth_stencil_infos[dest_idx] = src_heap_extra_info->depth_stencil_infos[src_idx]; + dest_heap_extra_info->dsv_infos[dest_idx] = src_heap_extra_info->dsv_infos[src_idx]; } } @@ -5273,26 +5291,17 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CopyDescriptorsSimple( auto dest_idx = DestDescriptorRangeStart.index + i; auto src_idx = SrcDescriptorRangeStart.index + i; - if (src_heap_extra_info->constant_buffer_infos.count(src_idx) > 0) - { - dest_heap_extra_info->constant_buffer_infos[dest_idx] = src_heap_extra_info->constant_buffer_infos[src_idx]; - } - if (src_heap_extra_info->shader_resource_infos.count(src_idx) > 0) - { - dest_heap_extra_info->shader_resource_infos[dest_idx] = src_heap_extra_info->shader_resource_infos[src_idx]; - } - if (src_heap_extra_info->unordered_access_infos.count(src_idx) > 0) + if (src_heap_extra_info->cbv_srv_uav_infos.count(src_idx) > 0) { - dest_heap_extra_info->unordered_access_infos[dest_idx] = - src_heap_extra_info->unordered_access_infos[src_idx]; + dest_heap_extra_info->cbv_srv_uav_infos[dest_idx] = src_heap_extra_info->cbv_srv_uav_infos[src_idx]; } - if (src_heap_extra_info->render_target_infos.count(src_idx) > 0) + if (src_heap_extra_info->rtv_infos.count(src_idx) > 0) { - dest_heap_extra_info->render_target_infos[dest_idx] = src_heap_extra_info->render_target_infos[src_idx]; + dest_heap_extra_info->rtv_infos[dest_idx] = src_heap_extra_info->rtv_infos[src_idx]; } - if (src_heap_extra_info->depth_stencil_infos.count(src_idx) > 0) + if (src_heap_extra_info->dsv_infos.count(src_idx) > 0) { - dest_heap_extra_info->depth_stencil_infos[dest_idx] = src_heap_extra_info->depth_stencil_infos[src_idx]; + dest_heap_extra_info->dsv_infos[dest_idx] = src_heap_extra_info->dsv_infos[src_idx]; } } } diff --git a/framework/decode/dx12_replay_consumer_base.h b/framework/decode/dx12_replay_consumer_base.h index 6029cf702e..d8f2ddf594 100644 --- a/framework/decode/dx12_replay_consumer_base.h +++ b/framework/decode/dx12_replay_consumer_base.h @@ -154,6 +154,11 @@ class Dx12ReplayConsumerBase : public Dx12Consumer StructPointerDecoder* pDesc, Decoded_D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + void PostCall_ID3D12Device_CreateSampler(const ApiCallInfo& call_info, + DxObjectInfo* object_info, + StructPointerDecoder* pDesc, + Decoded_D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + void PostCall_ID3D12Device_CreateShaderResourceView(const ApiCallInfo& call_info, DxObjectInfo* object_info, From 6c3c13e0b52e2df34aa0a80b8360f231619b87a8 Mon Sep 17 00:00:00 2001 From: Locke Lin Date: Tue, 19 Nov 2024 00:06:27 -0700 Subject: [PATCH 2/3] Move GetDescriptorSubresourceIndices Move GetDescriptorSubresourceIndices to Dx12DumpResources. And fix two "<=" to "<". --- framework/decode/dx12_dump_resources.cpp | 457 +++++++++++++++- framework/decode/dx12_dump_resources.h | 4 + framework/decode/dx12_object_info.h | 8 +- .../decode/dx12_replay_consumer_base.cpp | 487 +----------------- 4 files changed, 487 insertions(+), 469 deletions(-) diff --git a/framework/decode/dx12_dump_resources.cpp b/framework/decode/dx12_dump_resources.cpp index 6231a176ae..af9e5d7fa8 100644 --- a/framework/decode/dx12_dump_resources.cpp +++ b/framework/decode/dx12_dump_resources.cpp @@ -577,6 +577,459 @@ void Dx12DumpResources::BeginRenderPass( } } +std::vector GetDescSubIndices(uint32_t first_mip_slice, + uint32_t mip_size, + uint32_t total_mip_count, + uint32_t first_array_slice, + uint32_t array_size, + uint32_t total_array_count, + uint32_t plane_slice) +{ + std::vector result; + for (UINT array_index = first_array_slice; array_index < (first_array_slice + array_size); ++array_index) + { + for (UINT mip_index = first_mip_slice; mip_index < (first_mip_slice + mip_size); ++mip_index) + { + result.push_back(mip_index + (array_index * total_mip_count) + + (plane_slice * total_mip_count * total_array_count)); + } + } + return result; +} + +void Dx12DumpResources::GetDescriptorSubresourceIndices(DHShaderResourceViewInfo& info, const DxObjectInfo* resource) +{ + auto res_desc = reinterpret_cast(resource->object)->GetDesc(); + auto mip_count = res_desc.MipLevels; + auto array_count = res_desc.DepthOrArraySize; + switch (info.desc.ViewDimension) + { + case D3D12_SRV_DIMENSION_BUFFER: + info.subresource_indices.emplace_back(0); + break; + case D3D12_SRV_DIMENSION_TEXTURE1D: + { + auto view = info.desc.Texture1D; + auto mip_size = view.MipLevels; + if (mip_size == -1) + { + mip_size = mip_count; + } + if (view.MostDetailedMip != 0) + { + if (mip_size == -1) + { + mip_size -= view.MostDetailedMip; + } + info.subresource_indices = + GetDescSubIndices(view.MostDetailedMip, mip_size, mip_count, 0, 1, array_count, 0); + } + else + { + mip_size -= view.MostDetailedMip; + info.subresource_indices = + GetDescSubIndices(view.ResourceMinLODClamp, mip_size, mip_count, 0, 1, array_count, 0); + } + break; + } + case D3D12_SRV_DIMENSION_TEXTURE1DARRAY: + { + auto view = info.desc.Texture1DArray; + auto mip_size = view.MipLevels; + if (mip_size == -1) + { + mip_size = mip_count; + } + auto array_size = view.ArraySize; + if (array_size == -1) + { + array_size = array_count; + } + if (view.MostDetailedMip != 0) + { + if (mip_size == -1) + { + mip_size -= view.MostDetailedMip; + } + info.subresource_indices = GetDescSubIndices( + view.MostDetailedMip, mip_size, mip_count, view.FirstArraySlice, array_size, array_count, 0); + } + else + { + mip_size -= view.MostDetailedMip; + info.subresource_indices = GetDescSubIndices( + view.ResourceMinLODClamp, mip_size, mip_count, view.FirstArraySlice, array_size, array_count, 0); + } + break; + } + case D3D12_SRV_DIMENSION_TEXTURE2D: + { + auto view = info.desc.Texture2D; + auto mip_size = view.MipLevels; + if (mip_size == -1) + { + mip_size = mip_count; + } + if (view.MostDetailedMip != 0) + { + if (mip_size == -1) + { + mip_size -= view.MostDetailedMip; + } + info.subresource_indices = + GetDescSubIndices(view.MostDetailedMip, mip_size, mip_count, 0, 1, array_count, view.PlaneSlice); + } + else + { + mip_size -= view.MostDetailedMip; + info.subresource_indices = GetDescSubIndices( + view.ResourceMinLODClamp, mip_size, mip_count, 0, 1, array_count, view.PlaneSlice); + } + break; + } + case D3D12_SRV_DIMENSION_TEXTURE2DARRAY: + { + auto view = info.desc.Texture2DArray; + auto mip_size = view.MipLevels; + if (mip_size == -1) + { + mip_size = mip_count; + } + auto array_size = view.ArraySize; + if (array_size == -1) + { + array_size = array_count; + } + if (view.MostDetailedMip != 0) + { + if (mip_size == -1) + { + mip_size -= view.MostDetailedMip; + } + info.subresource_indices = GetDescSubIndices(view.MostDetailedMip, + mip_size, + mip_count, + view.FirstArraySlice, + array_size, + array_count, + view.PlaneSlice); + } + else + { + mip_size -= view.MostDetailedMip; + info.subresource_indices = GetDescSubIndices(view.ResourceMinLODClamp, + mip_size, + mip_count, + view.FirstArraySlice, + array_size, + array_count, + view.PlaneSlice); + } + break; + } + case D3D12_SRV_DIMENSION_TEXTURE2DMS: + { + info.subresource_indices = GetDescSubIndices(0, 1, mip_count, 0, 1, array_count, 0); + break; + } + case D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY: + { + auto view = info.desc.Texture2DMSArray; + auto array_size = view.ArraySize; + if (array_size == -1) + { + array_size = array_count; + } + info.subresource_indices = + GetDescSubIndices(0, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); + break; + } + case D3D12_SRV_DIMENSION_TEXTURE3D: + { + array_count = 1; + auto view = info.desc.Texture3D; + auto mip_size = view.MipLevels; + if (mip_size == -1) + { + mip_size = mip_count; + } + if (view.MostDetailedMip != 0) + { + if (mip_size == -1) + { + mip_size -= view.MostDetailedMip; + } + info.subresource_indices = + GetDescSubIndices(view.MostDetailedMip, mip_size, mip_count, 0, 1, array_count, 0); + } + else + { + info.subresource_indices = + GetDescSubIndices(view.ResourceMinLODClamp, mip_size, mip_count, 0, 1, array_count, 0); + } + break; + } + case D3D12_SRV_DIMENSION_TEXTURECUBE: + { + auto view = info.desc.TextureCube; + auto mip_size = view.MipLevels; + if (mip_size == -1) + { + mip_size = mip_count; + } + if (view.MostDetailedMip != 0) + { + if (mip_size == -1) + { + mip_size -= view.MostDetailedMip; + } + info.subresource_indices = + GetDescSubIndices(view.MostDetailedMip, mip_size, mip_count, 0, 1, array_count, 0); + } + else + { + info.subresource_indices = + GetDescSubIndices(view.ResourceMinLODClamp, mip_size, mip_count, 0, 1, array_count, 0); + } + break; + } + case D3D12_SRV_DIMENSION_TEXTURECUBEARRAY: + { + auto view = info.desc.TextureCubeArray; + auto mip_size = view.MipLevels; + if (mip_size == -1) + { + mip_size = mip_count; + } + auto array_size = view.NumCubes; + if (array_size == -1) + { + array_size = array_count; + } + if (view.MostDetailedMip != 0) + { + if (mip_size == -1) + { + mip_size -= view.MostDetailedMip; + } + info.subresource_indices = GetDescSubIndices( + view.MostDetailedMip, mip_size, mip_count, view.First2DArrayFace, array_size, array_count, 0); + } + else + { + info.subresource_indices = GetDescSubIndices( + view.ResourceMinLODClamp, mip_size, mip_count, view.First2DArrayFace, array_size, array_count, 0); + } + break; + } + case D3D12_SRV_DIMENSION_UNKNOWN: + default: + GFXRECON_LOG_ERROR("Unknown D3D12_SRV_DIMENSION_UNKNOWN."); + break; + } +} + +void Dx12DumpResources::GetDescriptorSubresourceIndices(DHUnorderedAccessViewInfo& info, const DxObjectInfo* resource) +{ + auto res_desc = reinterpret_cast(resource->object)->GetDesc(); + auto mip_count = res_desc.MipLevels; + auto array_count = res_desc.DepthOrArraySize; + switch (info.desc.ViewDimension) + { + case D3D12_UAV_DIMENSION_BUFFER: + info.subresource_indices.emplace_back(0); + break; + case D3D12_UAV_DIMENSION_TEXTURE1D: + info.subresource_indices = + GetDescSubIndices(info.desc.Texture1D.MipSlice, 1, mip_count, 0, 1, array_count, 0); + break; + case D3D12_UAV_DIMENSION_TEXTURE1DARRAY: + { + auto view = info.desc.Texture1DArray; + auto array_size = view.ArraySize; + if (array_size == -1) + { + array_size = array_count; + } + info.subresource_indices = + GetDescSubIndices(view.MipSlice, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); + break; + } + case D3D12_UAV_DIMENSION_TEXTURE2D: + info.subresource_indices = GetDescSubIndices( + info.desc.Texture2D.MipSlice, 1, mip_count, 0, 1, array_count, info.desc.Texture2D.PlaneSlice); + break; + case D3D12_UAV_DIMENSION_TEXTURE2DARRAY: + { + auto view = info.desc.Texture2DArray; + auto array_size = view.ArraySize; + if (array_size == -1) + { + array_size = array_count; + } + info.subresource_indices = GetDescSubIndices( + view.MipSlice, 1, mip_count, view.FirstArraySlice, array_size, array_count, view.PlaneSlice); + break; + } + case D3D12_UAV_DIMENSION_TEXTURE2DMS: + info.subresource_indices = GetDescSubIndices(0, 1, mip_count, 0, 1, array_count, 0); + break; + case D3D12_UAV_DIMENSION_TEXTURE2DMSARRAY: + { + auto view = info.desc.Texture2DMSArray; + auto array_size = view.ArraySize; + if (array_size == -1) + { + array_size = array_count; + } + info.subresource_indices = + GetDescSubIndices(0, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); + break; + } + case D3D12_UAV_DIMENSION_TEXTURE3D: + { + // DUMPTODO: handle FirstWSlice and WSize + info.subresource_indices = GetDescSubIndices(info.desc.Texture3D.MipSlice, 1, mip_count, 0, 1, 1, 0); + break; + } + case D3D12_UAV_DIMENSION_UNKNOWN: + default: + GFXRECON_LOG_ERROR("Unknown D3D12_UAV_DIMENSION_UNKNOWN."); + break; + } +} + +void Dx12DumpResources::GetDescriptorSubresourceIndices(DHRenderTargetViewInfo& info, const DxObjectInfo* resource) +{ + auto res_desc = reinterpret_cast(resource->object)->GetDesc(); + auto mip_count = res_desc.MipLevels; + auto array_count = res_desc.DepthOrArraySize; + switch (info.desc.ViewDimension) + { + case D3D12_RTV_DIMENSION_BUFFER: + info.subresource_indices.emplace_back(0); + break; + case D3D12_RTV_DIMENSION_TEXTURE1D: + info.subresource_indices = + GetDescSubIndices(info.desc.Texture1D.MipSlice, 1, mip_count, 0, 1, array_count, 0); + break; + case D3D12_RTV_DIMENSION_TEXTURE1DARRAY: + { + auto view = info.desc.Texture1DArray; + auto array_size = view.ArraySize; + if (array_size == -1) + { + array_size = array_count; + } + info.subresource_indices = + GetDescSubIndices(view.MipSlice, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); + break; + } + case D3D12_RTV_DIMENSION_TEXTURE2D: + info.subresource_indices = GetDescSubIndices( + info.desc.Texture2D.MipSlice, 1, mip_count, 0, 1, array_count, info.desc.Texture2D.PlaneSlice); + break; + case D3D12_RTV_DIMENSION_TEXTURE2DARRAY: + { + auto view = info.desc.Texture2DArray; + auto array_size = view.ArraySize; + if (array_size == -1) + { + array_size = array_count; + } + info.subresource_indices = GetDescSubIndices( + view.MipSlice, 1, mip_count, view.FirstArraySlice, array_size, array_count, view.PlaneSlice); + break; + } + case D3D12_RTV_DIMENSION_TEXTURE2DMS: + info.subresource_indices = GetDescSubIndices(0, 1, mip_count, 0, 1, array_count, 0); + break; + case D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY: + { + auto view = info.desc.Texture2DMSArray; + auto array_size = view.ArraySize; + if (array_size == -1) + { + array_size = array_count; + } + info.subresource_indices = + GetDescSubIndices(0, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); + break; + } + case D3D12_RTV_DIMENSION_TEXTURE3D: + { + // DUMPTODO: Handle FirstWSlice and WSize + info.subresource_indices = GetDescSubIndices(info.desc.Texture3D.MipSlice, 1, mip_count, 0, 1, 1, 0); + break; + } + case D3D12_RTV_DIMENSION_UNKNOWN: + default: + GFXRECON_LOG_ERROR("Unknown D3D12_RTV_DIMENSION_UNKNOWN."); + break; + } +} + +void Dx12DumpResources::GetDescriptorSubresourceIndices(DHDepthStencilViewInfo& info, const DxObjectInfo* resource) +{ + auto res_desc = reinterpret_cast(resource->object)->GetDesc(); + auto mip_count = res_desc.MipLevels; + auto array_count = res_desc.DepthOrArraySize; + switch (info.desc.ViewDimension) + { + case D3D12_DSV_DIMENSION_TEXTURE1D: + info.subresource_indices = + GetDescSubIndices(info.desc.Texture1D.MipSlice, 1, mip_count, 0, 1, array_count, 0); + break; + case D3D12_DSV_DIMENSION_TEXTURE1DARRAY: + { + auto view = info.desc.Texture1DArray; + auto array_size = view.ArraySize; + if (array_size == -1) + { + array_size = array_count; + } + info.subresource_indices = + GetDescSubIndices(view.MipSlice, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); + break; + } + case D3D12_DSV_DIMENSION_TEXTURE2D: + info.subresource_indices = + GetDescSubIndices(info.desc.Texture2D.MipSlice, 1, mip_count, 0, 1, array_count, 0); + break; + case D3D12_DSV_DIMENSION_TEXTURE2DARRAY: + { + auto view = info.desc.Texture2DArray; + auto array_size = view.ArraySize; + if (array_size == -1) + { + array_size = array_count; + } + info.subresource_indices = + GetDescSubIndices(view.MipSlice, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); + break; + } + case D3D12_DSV_DIMENSION_TEXTURE2DMS: + info.subresource_indices = GetDescSubIndices(0, 1, mip_count, 0, 1, array_count, 0); + break; + case D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY: + { + auto view = info.desc.Texture2DMSArray; + auto array_size = view.ArraySize; + if (array_size == -1) + { + array_size = array_count; + } + info.subresource_indices = + GetDescSubIndices(0, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); + break; + } + case D3D12_DSV_DIMENSION_UNKNOWN: + default: + GFXRECON_LOG_ERROR("Unknown D3D12_DSV_DIMENSION."); + break; + } +} + bool CaptureGPUAddrMatchDescriptorHeap(const D3D12_GPU_DESCRIPTOR_HANDLE capture_gpu_addr, const D3D12DescriptorHeapInfo& heap_info, uint32_t& out_heap_index) @@ -585,7 +1038,7 @@ bool CaptureGPUAddrMatchDescriptorHeap(const D3D12_GPU_DESCRIPTOR_HANDLE capture auto capture_gpu_addr_end = heap_info.capture_gpu_addr_begin + heap_info.descriptor_count * increment; bool is_match = true ? (heap_info.capture_gpu_addr_begin <= capture_gpu_addr.ptr && - capture_gpu_addr.ptr <= capture_gpu_addr_end) + capture_gpu_addr.ptr < capture_gpu_addr_end) : false; if (is_match) { @@ -609,7 +1062,7 @@ bool ReplayCPUAddrMatchDescriptorHeap(const D3D12_CPU_DESCRIPTOR_HANDLE replay_c auto replay_cpu_addr_end = heap_info.replay_cpu_addr_begin + heap_info.descriptor_count * increment; bool is_match = true ? (heap_info.replay_cpu_addr_begin <= replay_cpu_addr.ptr && - replay_cpu_addr.ptr <= replay_cpu_addr_end) + replay_cpu_addr.ptr < replay_cpu_addr_end) : false; if (is_match) { diff --git a/framework/decode/dx12_dump_resources.h b/framework/decode/dx12_dump_resources.h index 4d015790a3..6cb5b668ad 100644 --- a/framework/decode/dx12_dump_resources.h +++ b/framework/decode/dx12_dump_resources.h @@ -269,6 +269,10 @@ class Dx12DumpResources StructPointerDecoder* pDepthStencil, D3D12_RENDER_PASS_FLAGS Flags, uint64_t block_index); + void GetDescriptorSubresourceIndices(DHShaderResourceViewInfo& info, const DxObjectInfo* resource); + void GetDescriptorSubresourceIndices(DHUnorderedAccessViewInfo& info, const DxObjectInfo* resource); + void GetDescriptorSubresourceIndices(DHRenderTargetViewInfo& info, const DxObjectInfo* resource); + void GetDescriptorSubresourceIndices(DHDepthStencilViewInfo& info, const DxObjectInfo* resource); private: void StartDump(ID3D12Device* device, const std::string& filename); diff --git a/framework/decode/dx12_object_info.h b/framework/decode/dx12_object_info.h index 2ac21963e9..e3f6756fca 100644 --- a/framework/decode/dx12_object_info.h +++ b/framework/decode/dx12_object_info.h @@ -299,7 +299,7 @@ struct DHShaderResourceViewInfo bool is_desc_null{ false }; format::HandleId resource_id{ format::kNullHandleId }; D3D12_CPU_DESCRIPTOR_HANDLE replay_handle{ kNullCpuAddress }; - std::vector subresource_indices; + std::vector subresource_indices; // Only use for dump resources }; struct DHUnorderedAccessViewInfo @@ -309,7 +309,7 @@ struct DHUnorderedAccessViewInfo format::HandleId resource_id{ format::kNullHandleId }; format::HandleId counter_resource_id{ format::kNullHandleId }; D3D12_CPU_DESCRIPTOR_HANDLE replay_handle{ kNullCpuAddress }; - std::vector subresource_indices; + std::vector subresource_indices; // Only use for dump resources }; struct DHCbvSrvUavInfo @@ -326,7 +326,7 @@ struct DHRenderTargetViewInfo D3D12_RENDER_TARGET_VIEW_DESC desc{}; bool is_desc_null{ false }; D3D12_CPU_DESCRIPTOR_HANDLE replay_handle{ kNullCpuAddress }; - std::vector subresource_indices; + std::vector subresource_indices; // Only use for dump resources }; struct DHDepthStencilViewInfo @@ -335,7 +335,7 @@ struct DHDepthStencilViewInfo D3D12_DEPTH_STENCIL_VIEW_DESC desc{}; bool is_desc_null{ false }; D3D12_CPU_DESCRIPTOR_HANDLE replay_handle{ kNullCpuAddress }; - std::vector subresource_indices; + std::vector subresource_indices; // Only use for dump resources }; struct DHSamplerInfo diff --git a/framework/decode/dx12_replay_consumer_base.cpp b/framework/decode/dx12_replay_consumer_base.cpp index 4358bd2010..537495fd06 100644 --- a/framework/decode/dx12_replay_consumer_base.cpp +++ b/framework/decode/dx12_replay_consumer_base.cpp @@ -4520,26 +4520,6 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateSampler( heap_extra_info->sampler_infos[DestDescriptor.index] = std::move(info); } -std::vector GetDescriptorSubresourceIndices(uint32_t first_mip_slice, - uint32_t mip_size, - uint32_t total_mip_count, - uint32_t first_array_slice, - uint32_t array_size, - uint32_t total_array_count, - uint32_t plane_slice) -{ - std::vector result; - for (UINT array_index = first_array_slice; array_index < (first_array_slice + array_size); ++array_index) - { - for (UINT mip_index = first_mip_slice; mip_index < (first_mip_slice + mip_size); ++mip_index) - { - result.push_back(mip_index + (array_index * total_mip_count) + - (plane_slice * total_mip_count * total_array_count)); - } - } - return result; -} - void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateShaderResourceView( const ApiCallInfo& call_info, DxObjectInfo* object_info, @@ -4565,256 +4545,14 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateShaderResourceView( srv_info.desc = *(pDesc->GetMetaStructPointer()->decoded_value); srv_info.is_desc_null = false; - if (pResource != format::kNullHandleId) + if (options_.enable_dump_resources) { - auto desc = reinterpret_cast(GetObjectInfo(pResource)->object)->GetDesc(); - auto mip_count = desc.MipLevels; - auto array_count = desc.DepthOrArraySize; - switch (srv_info.desc.ViewDimension) + GFXRECON_ASSERT(dump_resources_); + if (pResource != format::kNullHandleId) { - case D3D12_SRV_DIMENSION_BUFFER: - srv_info.subresource_indices.emplace_back(0); - break; - case D3D12_SRV_DIMENSION_TEXTURE1D: - { - auto view = srv_info.desc.Texture1D; - auto mip_size = view.MipLevels; - if (mip_size == -1) - { - mip_size = mip_count; - } - if (view.MostDetailedMip != 0) - { - if (mip_size == -1) - { - mip_size -= view.MostDetailedMip; - } - srv_info.subresource_indices = GetDescriptorSubresourceIndices( - view.MostDetailedMip, mip_size, mip_count, 0, 1, array_count, 0); - } - else - { - mip_size -= view.MostDetailedMip; - srv_info.subresource_indices = GetDescriptorSubresourceIndices( - view.ResourceMinLODClamp, mip_size, mip_count, 0, 1, array_count, 0); - } - break; - } - case D3D12_SRV_DIMENSION_TEXTURE1DARRAY: - { - auto view = srv_info.desc.Texture1DArray; - auto mip_size = view.MipLevels; - if (mip_size == -1) - { - mip_size = mip_count; - } - auto array_size = view.ArraySize; - if (array_size == -1) - { - array_size = array_count; - } - if (view.MostDetailedMip != 0) - { - if (mip_size == -1) - { - mip_size -= view.MostDetailedMip; - } - srv_info.subresource_indices = GetDescriptorSubresourceIndices(view.MostDetailedMip, - mip_size, - mip_count, - view.FirstArraySlice, - array_size, - array_count, - 0); - } - else - { - mip_size -= view.MostDetailedMip; - srv_info.subresource_indices = GetDescriptorSubresourceIndices(view.ResourceMinLODClamp, - mip_size, - mip_count, - view.FirstArraySlice, - array_size, - array_count, - 0); - } - break; - } - case D3D12_SRV_DIMENSION_TEXTURE2D: - { - auto view = srv_info.desc.Texture2D; - auto mip_size = view.MipLevels; - if (mip_size == -1) - { - mip_size = mip_count; - } - if (view.MostDetailedMip != 0) - { - if (mip_size == -1) - { - mip_size -= view.MostDetailedMip; - } - srv_info.subresource_indices = GetDescriptorSubresourceIndices( - view.MostDetailedMip, mip_size, mip_count, 0, 1, array_count, view.PlaneSlice); - } - else - { - mip_size -= view.MostDetailedMip; - srv_info.subresource_indices = GetDescriptorSubresourceIndices( - view.ResourceMinLODClamp, mip_size, mip_count, 0, 1, array_count, view.PlaneSlice); - } - break; - } - case D3D12_SRV_DIMENSION_TEXTURE2DARRAY: - { - auto view = srv_info.desc.Texture2DArray; - auto mip_size = view.MipLevels; - if (mip_size == -1) - { - mip_size = mip_count; - } - auto array_size = view.ArraySize; - if (array_size == -1) - { - array_size = array_count; - } - if (view.MostDetailedMip != 0) - { - if (mip_size == -1) - { - mip_size -= view.MostDetailedMip; - } - srv_info.subresource_indices = GetDescriptorSubresourceIndices(view.MostDetailedMip, - mip_size, - mip_count, - view.FirstArraySlice, - array_size, - array_count, - view.PlaneSlice); - } - else - { - mip_size -= view.MostDetailedMip; - srv_info.subresource_indices = GetDescriptorSubresourceIndices(view.ResourceMinLODClamp, - mip_size, - mip_count, - view.FirstArraySlice, - array_size, - array_count, - view.PlaneSlice); - } - break; - } - case D3D12_SRV_DIMENSION_TEXTURE2DMS: - { - srv_info.subresource_indices = - GetDescriptorSubresourceIndices(0, 1, mip_count, 0, 1, array_count, 0); - break; - } - case D3D12_SRV_DIMENSION_TEXTURE2DMSARRAY: - { - auto view = srv_info.desc.Texture2DMSArray; - auto array_size = view.ArraySize; - if (array_size == -1) - { - array_size = array_count; - } - srv_info.subresource_indices = GetDescriptorSubresourceIndices( - 0, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); - break; - } - case D3D12_SRV_DIMENSION_TEXTURE3D: - { - array_count = 1; - auto view = srv_info.desc.Texture3D; - auto mip_size = view.MipLevels; - if (mip_size == -1) - { - mip_size = mip_count; - } - if (view.MostDetailedMip != 0) - { - if (mip_size == -1) - { - mip_size -= view.MostDetailedMip; - } - srv_info.subresource_indices = GetDescriptorSubresourceIndices( - view.MostDetailedMip, mip_size, mip_count, 0, 1, array_count, 0); - } - else - { - srv_info.subresource_indices = GetDescriptorSubresourceIndices( - view.ResourceMinLODClamp, mip_size, mip_count, 0, 1, array_count, 0); - } - break; - } - case D3D12_SRV_DIMENSION_TEXTURECUBE: - { - auto view = srv_info.desc.TextureCube; - auto mip_size = view.MipLevels; - if (mip_size == -1) - { - mip_size = mip_count; - } - if (view.MostDetailedMip != 0) - { - if (mip_size == -1) - { - mip_size -= view.MostDetailedMip; - } - srv_info.subresource_indices = GetDescriptorSubresourceIndices( - view.MostDetailedMip, mip_size, mip_count, 0, 1, array_count, 0); - } - else - { - srv_info.subresource_indices = GetDescriptorSubresourceIndices( - view.ResourceMinLODClamp, mip_size, mip_count, 0, 1, array_count, 0); - } - break; - } - case D3D12_SRV_DIMENSION_TEXTURECUBEARRAY: - { - auto view = srv_info.desc.TextureCubeArray; - auto mip_size = view.MipLevels; - if (mip_size == -1) - { - mip_size = mip_count; - } - auto array_size = view.NumCubes; - if (array_size == -1) - { - array_size = array_count; - } - if (view.MostDetailedMip != 0) - { - if (mip_size == -1) - { - mip_size -= view.MostDetailedMip; - } - srv_info.subresource_indices = GetDescriptorSubresourceIndices(view.MostDetailedMip, - mip_size, - mip_count, - view.First2DArrayFace, - array_size, - array_count, - 0); - } - else - { - srv_info.subresource_indices = GetDescriptorSubresourceIndices(view.ResourceMinLODClamp, - mip_size, - mip_count, - view.First2DArrayFace, - array_size, - array_count, - 0); - } - break; - } - case D3D12_SRV_DIMENSION_UNKNOWN: - default: - GFXRECON_LOG_ERROR("Unknown D3D12_SRV_DIMENSION_UNKNOWN."); - break; + auto res_obj = GetObjectInfo(pResource); + GFXRECON_ASSERT(res_obj); + dump_resources_->GetDescriptorSubresourceIndices(srv_info, res_obj); } } } @@ -4848,81 +4586,14 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateUnorderedAccessView( uav_info.desc = *(pDesc->GetMetaStructPointer()->decoded_value); uav_info.is_desc_null = false; - if (pResource != format::kNullHandleId) + if (options_.enable_dump_resources) { - auto desc = reinterpret_cast(GetObjectInfo(pResource)->object)->GetDesc(); - auto mip_count = desc.MipLevels; - auto array_count = desc.DepthOrArraySize; - switch (uav_info.desc.ViewDimension) + GFXRECON_ASSERT(dump_resources_); + if (pResource != format::kNullHandleId) { - case D3D12_UAV_DIMENSION_BUFFER: - uav_info.subresource_indices.emplace_back(0); - break; - case D3D12_UAV_DIMENSION_TEXTURE1D: - uav_info.subresource_indices = GetDescriptorSubresourceIndices( - uav_info.desc.Texture1D.MipSlice, 1, mip_count, 0, 1, array_count, 0); - break; - case D3D12_UAV_DIMENSION_TEXTURE1DARRAY: - { - auto view = uav_info.desc.Texture1DArray; - auto array_size = view.ArraySize; - if (array_size == -1) - { - array_size = array_count; - } - uav_info.subresource_indices = GetDescriptorSubresourceIndices( - view.MipSlice, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); - break; - } - case D3D12_UAV_DIMENSION_TEXTURE2D: - uav_info.subresource_indices = - GetDescriptorSubresourceIndices(uav_info.desc.Texture2D.MipSlice, - 1, - mip_count, - 0, - 1, - array_count, - uav_info.desc.Texture2D.PlaneSlice); - break; - case D3D12_UAV_DIMENSION_TEXTURE2DARRAY: - { - auto view = uav_info.desc.Texture2DArray; - auto array_size = view.ArraySize; - if (array_size == -1) - { - array_size = array_count; - } - uav_info.subresource_indices = GetDescriptorSubresourceIndices( - view.MipSlice, 1, mip_count, view.FirstArraySlice, array_size, array_count, view.PlaneSlice); - break; - } - case D3D12_UAV_DIMENSION_TEXTURE2DMS: - uav_info.subresource_indices = - GetDescriptorSubresourceIndices(0, 1, mip_count, 0, 1, array_count, 0); - break; - case D3D12_UAV_DIMENSION_TEXTURE2DMSARRAY: - { - auto view = uav_info.desc.Texture2DMSArray; - auto array_size = view.ArraySize; - if (array_size == -1) - { - array_size = array_count; - } - uav_info.subresource_indices = GetDescriptorSubresourceIndices( - 0, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); - break; - } - case D3D12_UAV_DIMENSION_TEXTURE3D: - { - // DUMPTODO: handle FirstWSlice and WSize - uav_info.subresource_indices = GetDescriptorSubresourceIndices( - uav_info.desc.Texture3D.MipSlice, 1, mip_count, 0, 1, 1, 0); - break; - } - case D3D12_UAV_DIMENSION_UNKNOWN: - default: - GFXRECON_LOG_ERROR("Unknown D3D12_UAV_DIMENSION_UNKNOWN."); - break; + auto res_obj = GetObjectInfo(pResource); + GFXRECON_ASSERT(res_obj); + dump_resources_->GetDescriptorSubresourceIndices(uav_info, res_obj); } } } @@ -4952,74 +4623,14 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateRenderTargetView( info.desc = *(pDesc->GetMetaStructPointer()->decoded_value); info.is_desc_null = false; - if (pResource != format::kNullHandleId) + if (options_.enable_dump_resources) { - auto desc = reinterpret_cast(GetObjectInfo(pResource)->object)->GetDesc(); - auto mip_count = desc.MipLevels; - auto array_count = desc.DepthOrArraySize; - switch (info.desc.ViewDimension) + GFXRECON_ASSERT(dump_resources_); + if (pResource != format::kNullHandleId) { - case D3D12_RTV_DIMENSION_BUFFER: - info.subresource_indices.emplace_back(0); - break; - case D3D12_RTV_DIMENSION_TEXTURE1D: - info.subresource_indices = GetDescriptorSubresourceIndices( - info.desc.Texture1D.MipSlice, 1, mip_count, 0, 1, array_count, 0); - break; - case D3D12_RTV_DIMENSION_TEXTURE1DARRAY: - { - auto view = info.desc.Texture1DArray; - auto array_size = view.ArraySize; - if (array_size == -1) - { - array_size = array_count; - } - info.subresource_indices = GetDescriptorSubresourceIndices( - view.MipSlice, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); - break; - } - case D3D12_RTV_DIMENSION_TEXTURE2D: - info.subresource_indices = GetDescriptorSubresourceIndices( - info.desc.Texture2D.MipSlice, 1, mip_count, 0, 1, array_count, info.desc.Texture2D.PlaneSlice); - break; - case D3D12_RTV_DIMENSION_TEXTURE2DARRAY: - { - auto view = info.desc.Texture2DArray; - auto array_size = view.ArraySize; - if (array_size == -1) - { - array_size = array_count; - } - info.subresource_indices = GetDescriptorSubresourceIndices( - view.MipSlice, 1, mip_count, view.FirstArraySlice, array_size, array_count, view.PlaneSlice); - break; - } - case D3D12_RTV_DIMENSION_TEXTURE2DMS: - info.subresource_indices = GetDescriptorSubresourceIndices(0, 1, mip_count, 0, 1, array_count, 0); - break; - case D3D12_RTV_DIMENSION_TEXTURE2DMSARRAY: - { - auto view = info.desc.Texture2DMSArray; - auto array_size = view.ArraySize; - if (array_size == -1) - { - array_size = array_count; - } - info.subresource_indices = GetDescriptorSubresourceIndices( - 0, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); - break; - } - case D3D12_RTV_DIMENSION_TEXTURE3D: - { - // DUMPTODO: Handle FirstWSlice and WSize - info.subresource_indices = - GetDescriptorSubresourceIndices(info.desc.Texture3D.MipSlice, 1, mip_count, 0, 1, 1, 0); - break; - } - case D3D12_RTV_DIMENSION_UNKNOWN: - default: - GFXRECON_LOG_ERROR("Unknown D3D12_RTV_DIMENSION_UNKNOWN."); - break; + auto res_obj = GetObjectInfo(pResource); + GFXRECON_ASSERT(res_obj); + dump_resources_->GetDescriptorSubresourceIndices(info, res_obj); } } } @@ -5049,64 +4660,14 @@ void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateDepthStencilView( info.desc = *(pDesc->GetMetaStructPointer()->decoded_value); info.is_desc_null = false; - if (pResource != format::kNullHandleId) + if (options_.enable_dump_resources) { - auto desc = reinterpret_cast(GetObjectInfo(pResource)->object)->GetDesc(); - auto mip_count = desc.MipLevels; - auto array_count = desc.DepthOrArraySize; - switch (info.desc.ViewDimension) + GFXRECON_ASSERT(dump_resources_); + if (pResource != format::kNullHandleId) { - case D3D12_DSV_DIMENSION_TEXTURE1D: - info.subresource_indices = GetDescriptorSubresourceIndices( - info.desc.Texture1D.MipSlice, 1, mip_count, 0, 1, array_count, 0); - break; - case D3D12_DSV_DIMENSION_TEXTURE1DARRAY: - { - auto view = info.desc.Texture1DArray; - auto array_size = view.ArraySize; - if (array_size == -1) - { - array_size = array_count; - } - info.subresource_indices = GetDescriptorSubresourceIndices( - view.MipSlice, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); - break; - } - case D3D12_DSV_DIMENSION_TEXTURE2D: - info.subresource_indices = GetDescriptorSubresourceIndices( - info.desc.Texture2D.MipSlice, 1, mip_count, 0, 1, array_count, 0); - break; - case D3D12_DSV_DIMENSION_TEXTURE2DARRAY: - { - auto view = info.desc.Texture2DArray; - auto array_size = view.ArraySize; - if (array_size == -1) - { - array_size = array_count; - } - info.subresource_indices = GetDescriptorSubresourceIndices( - view.MipSlice, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); - break; - } - case D3D12_DSV_DIMENSION_TEXTURE2DMS: - info.subresource_indices = GetDescriptorSubresourceIndices(0, 1, mip_count, 0, 1, array_count, 0); - break; - case D3D12_DSV_DIMENSION_TEXTURE2DMSARRAY: - { - auto view = info.desc.Texture2DMSArray; - auto array_size = view.ArraySize; - if (array_size == -1) - { - array_size = array_count; - } - info.subresource_indices = GetDescriptorSubresourceIndices( - 0, 1, mip_count, view.FirstArraySlice, array_size, array_count, 0); - break; - } - case D3D12_DSV_DIMENSION_UNKNOWN: - default: - GFXRECON_LOG_ERROR("Unknown D3D12_DSV_DIMENSION."); - break; + auto res_obj = GetObjectInfo(pResource); + GFXRECON_ASSERT(res_obj); + dump_resources_->GetDescriptorSubresourceIndices(info, res_obj); } } } From c17da5d48e6a862200b4648ca48b2adecbd799fd Mon Sep 17 00:00:00 2001 From: Locke Lin Date: Thu, 14 Nov 2024 10:39:58 -0700 Subject: [PATCH 3/3] Clean up writing dump infos Add WriteRootParameterInfo, WriteNotFoundView, WriteNULLResource, WriteNULLBufferLocation in Dx12DumpResourcesDelegate to make writing infos simpler. Move checking TEST_WRITE_NULL_RESOURCE_VIEWS into CopyDrawCallResourceByGPUVA and CopyDrawCallResourceBySubresource. --- framework/decode/dx12_dump_resources.cpp | 351 +++++++++++------------ framework/decode/dx12_dump_resources.h | 32 ++- 2 files changed, 199 insertions(+), 184 deletions(-) diff --git a/framework/decode/dx12_dump_resources.cpp b/framework/decode/dx12_dump_resources.cpp index af9e5d7fa8..0fc983662f 100644 --- a/framework/decode/dx12_dump_resources.cpp +++ b/framework/decode/dx12_dump_resources.cpp @@ -1110,10 +1110,7 @@ void Dx12DumpResources::WriteDescripotTable(DxObjectInfo* json_path_sub = json_path; json_path_sub.emplace_back("descs", json_index); ++json_index; - active_delegate_->WriteSingleData(json_path_sub, "heap_id", heap_id); - active_delegate_->WriteSingleData(json_path_sub, "heap_index", heap_index); - active_delegate_->WriteNote( - json_path_sub, "This heap_index can't be found a view in this heap_id"); + active_delegate_->WriteNotFoundView(json_path_sub, heap_id, heap_index); } continue; } @@ -1124,53 +1121,27 @@ void Dx12DumpResources::WriteDescripotTable(DxObjectInfo* { const auto& desc = info_entry->second.cbv.captured_desc; - if (desc.BufferLocation == kNullGpuAddress) - { - if (TEST_WRITE_NULL_RESOURCE_VIEWS) - { - json_path_sub = json_path; - json_path_sub.emplace_back("descs", json_index); - ++json_index; - active_delegate_->WriteSingleData(json_path_sub, "heap_id", heap_id); - active_delegate_->WriteSingleData(json_path_sub, "heap_index", heap_index); - active_delegate_->WriteSingleData(json_path_sub, "buffer_location", kNullGpuAddress); - } - continue; - } json_path_sub = json_path; json_path_sub.emplace_back("descs", json_index); - ++json_index; - active_delegate_->WriteSingleData(json_path_sub, "buffer_location", desc.BufferLocation); - CopyDrawCallResourceByGPUVA(queue_object_info, - front_command_list_ids, - desc.BufferLocation, - desc.SizeInBytes, - json_path_sub, - Dx12DumpResourceType::kCbv, - pos, - heap_id, - heap_index); + if (CopyDrawCallResourceByGPUVA(queue_object_info, + front_command_list_ids, + desc.BufferLocation, + desc.SizeInBytes, + json_path_sub, + Dx12DumpResourceType::kCbv, + pos, + heap_id, + heap_index)) + { + ++json_index; + } break; } case D3D12_DESCRIPTOR_RANGE_TYPE_SRV: { - if (info_entry->second.srv.resource_id == format::kNullHandleId) - { - if (TEST_WRITE_NULL_RESOURCE_VIEWS) - { - json_path_sub = json_path; - json_path_sub.emplace_back("descs", json_index); - ++json_index; - active_delegate_->WriteSingleData(json_path_sub, "heap_id", heap_id); - active_delegate_->WriteSingleData(json_path_sub, "heap_index", heap_index); - active_delegate_->WriteSingleData(json_path_sub, "res_id", format::kNullHandleId); - } - continue; - } json_path_sub = json_path; json_path_sub.emplace_back("descs", json_index); - ++json_index; const auto& desc = info_entry->second.srv.desc; uint64_t offset = 0; @@ -1191,37 +1162,26 @@ void Dx12DumpResources::WriteDescripotTable(DxObjectInfo* default: break; } - CopyDrawCallResourceBySubresource(queue_object_info, - front_command_list_ids, - info_entry->second.srv.resource_id, - offset, - size, - info_entry->second.srv.subresource_indices, - json_path_sub, - Dx12DumpResourceType::kSrv, - pos, - heap_id, - heap_index); + if (CopyDrawCallResourceBySubresource(queue_object_info, + front_command_list_ids, + info_entry->second.srv.resource_id, + offset, + size, + info_entry->second.srv.subresource_indices, + json_path_sub, + Dx12DumpResourceType::kSrv, + pos, + heap_id, + heap_index)) + { + ++json_index; + } break; } case D3D12_DESCRIPTOR_RANGE_TYPE_UAV: { - if (info_entry->second.uav.resource_id == format::kNullHandleId) - { - if (TEST_WRITE_NULL_RESOURCE_VIEWS) - { - json_path_sub = json_path; - json_path_sub.emplace_back("descs", json_index); - ++json_index; - active_delegate_->WriteSingleData(json_path_sub, "heap_id", heap_id); - active_delegate_->WriteSingleData(json_path_sub, "heap_index", heap_index); - active_delegate_->WriteSingleData(json_path_sub, "res_id", format::kNullHandleId); - } - continue; - } json_path_sub = json_path; json_path_sub.emplace_back("descs", json_index); - ++json_index; const auto& desc = info_entry->second.uav.desc; uint64_t offset = 0; @@ -1244,21 +1204,22 @@ void Dx12DumpResources::WriteDescripotTable(DxObjectInfo* } json_path_sub.emplace_back("resource", format::kNoneIndex); - CopyDrawCallResourceBySubresource(queue_object_info, - front_command_list_ids, - info_entry->second.uav.resource_id, - offset, - size, - info_entry->second.uav.subresource_indices, - json_path_sub, - Dx12DumpResourceType::kUav, - pos, - heap_id, - heap_index); + if (CopyDrawCallResourceBySubresource(queue_object_info, + front_command_list_ids, + info_entry->second.uav.resource_id, + offset, + size, + info_entry->second.uav.subresource_indices, + json_path_sub, + Dx12DumpResourceType::kUav, + pos, + heap_id, + heap_index)) + { + ++json_index; + } json_path_sub.emplace_back("counter_resource", format::kNoneIndex); - active_delegate_->WriteSingleData( - json_path_sub, "res_id", info_entry->second.uav.counter_resource_id); CopyDrawCallResourceBySubresource(queue_object_info, front_command_list_ids, @@ -1288,38 +1249,12 @@ void Dx12DumpResources::WriteRootParameters(DxObjectInfo* { std::vector> json_path; std::vector> json_path_sub; - auto index = 0; + auto json_index = 0; for (const auto& param : root_parameters) { json_path.clear(); - json_path.emplace_back(Dx12ResourceTypeToString(res_type), index); - active_delegate_->WriteSingleData(json_path, "root_parameter_index", param.first); - active_delegate_->WriteSingleData(json_path, "root_signature_type", util::ToString(param.second.root_signature_type)); - active_delegate_->WriteSingleData(json_path, "cmd_bind_type", util::ToString(param.second.cmd_bind_type)); - - if (param.second.root_signature_type != param.second.cmd_bind_type) - { - active_delegate_->WriteNote(json_path, "root_signature_type and cmd_bind_type are different."); - } - - switch (param.second.root_signature_type) - { - case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: - { - uint32_t di = 0; - for (const auto& table : param.second.root_signature_descriptor_tables) - { - json_path_sub = json_path; - json_path_sub.emplace_back("tables", di); - active_delegate_->WriteSingleData(json_path_sub, "range_type", util::ToString(table.RangeType)); - active_delegate_->WriteSingleData(json_path_sub, "num_descriptors", table.NumDescriptors); - ++di; - } - break; - } - default: - break; - } + json_path.emplace_back(Dx12ResourceTypeToString(res_type), json_index); + active_delegate_->WriteRootParameterInfo(json_path, param.first, param.second); switch (param.second.cmd_bind_type) { @@ -1345,9 +1280,6 @@ void Dx12DumpResources::WriteRootParameters(DxObjectInfo* { if (param.second.root_signature_type != D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE) { - active_delegate_->WriteNote(json_path, - "root_signature_type isn't DESCRIPTOR_TABLE and no " - "NumDescriptors, so dump only one descriptor."); WriteDescripotTable(queue_object_info, front_command_list_ids, pos, @@ -1402,14 +1334,6 @@ void Dx12DumpResources::WriteRootParameters(DxObjectInfo* case D3D12_ROOT_PARAMETER_TYPE_SRV: case D3D12_ROOT_PARAMETER_TYPE_UAV: { - if (param.second.cmd_bind_captured_buffer_location == kNullGpuAddress) - { - if (TEST_WRITE_NULL_RESOURCE_VIEWS) - { - active_delegate_->WriteSingleData(json_path, "buffer_location", kNullGpuAddress); - } - break; - } Dx12DumpResourceType type = Dx12DumpResourceType::kUnknown; switch (param.second.cmd_bind_type) { @@ -1440,7 +1364,7 @@ void Dx12DumpResources::WriteRootParameters(DxObjectInfo* // D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS break; } - ++index; + ++json_index; } } @@ -1453,7 +1377,7 @@ void Dx12DumpResources::CopyDrawCallResources(DxObjectInfo* // pair first: path name, second: resource index. If index is kNoneIndex, it means not a array. std::vector> json_path; - uint32_t index = 0; + uint32_t json_index = 0; const std::vector sub_indices_emptry{ 0 }; auto drawcall_type = track_dump_resources_.target.drawcall_type; @@ -1496,13 +1420,13 @@ void Dx12DumpResources::CopyDrawCallResources(DxObjectInfo* } if (vertex_buffer_views) { - index = 0; + json_index = 0; for (const auto& view : *vertex_buffer_views) { json_path.clear(); - json_path.emplace_back("vertices", index); + json_path.emplace_back("vertices", json_index); - CopyDrawCallResourceByGPUVA(queue_object_info, + if(CopyDrawCallResourceByGPUVA(queue_object_info, front_command_list_ids, view.BufferLocation, view.SizeInBytes, @@ -1510,8 +1434,10 @@ void Dx12DumpResources::CopyDrawCallResources(DxObjectInfo* Dx12DumpResourceType::kVertex, pos, format::kNullHandleId, - 0); - ++index; + 0)) + { + ++json_index; + } } } @@ -1699,7 +1625,7 @@ void Dx12DumpResources::CopyDrawCallResources(DxObjectInfo* { // render target // render target isn't available in Bundle. - index = 0; + json_index = 0; auto rt_size = track_dump_resources_.replay_render_target_handles.size(); for (uint32_t i = 0; i < rt_size; ++i) { @@ -1714,9 +1640,7 @@ void Dx12DumpResources::CopyDrawCallResources(DxObjectInfo* continue; } json_path.clear(); - json_path.emplace_back("render_target_views", index); - active_delegate_->WriteSingleData(json_path, "heap_id", descriptor_heap_id); - active_delegate_->WriteSingleData(json_path, "heap_index", rt_heap_index); + json_path.emplace_back("render_target_views", json_index); auto info_entry = heap_extra_info->rtv_infos.find(rt_heap_index); if (info_entry != heap_extra_info->rtv_infos.end()) @@ -1737,19 +1661,20 @@ void Dx12DumpResources::CopyDrawCallResources(DxObjectInfo* default: break; } - active_delegate_->WriteSingleData(json_path, "res_id", info.resource_id); - - CopyDrawCallResourceBySubresource(queue_object_info, - front_command_list_ids, - info.resource_id, - offset, - size, - info.subresource_indices, - json_path, - Dx12DumpResourceType::kRtv, - pos, - descriptor_heap_id, - descriptor_heap_index); + if (CopyDrawCallResourceBySubresource(queue_object_info, + front_command_list_ids, + info.resource_id, + offset, + size, + info.subresource_indices, + json_path, + Dx12DumpResourceType::kRtv, + pos, + descriptor_heap_id, + descriptor_heap_index)) + { + ++json_index; + } } } @@ -1767,15 +1692,12 @@ void Dx12DumpResources::CopyDrawCallResources(DxObjectInfo* { json_path.clear(); json_path.emplace_back("depth_stencil_view", format::kNoneIndex); - active_delegate_->WriteSingleData(json_path, "heap_id", descriptor_heap_id); - active_delegate_->WriteSingleData(json_path, "heap_index", ds_heap_index); auto info_entry = heap_extra_info->dsv_infos.find(ds_heap_index); if (info_entry != heap_extra_info->dsv_infos.end()) { auto descriptor_heap_index = info_entry->first; const auto& info = info_entry->second; - active_delegate_->WriteSingleData(json_path, "res_id", info.resource_id); CopyDrawCallResourceBySubresource(queue_object_info, front_command_list_ids, @@ -1834,7 +1756,7 @@ void Dx12DumpResources::CopyDrawCallResources(DxObjectInfo* } } -void Dx12DumpResources::CopyDrawCallResourceByGPUVA(DxObjectInfo* queue_object_info, +bool Dx12DumpResources::CopyDrawCallResourceByGPUVA(DxObjectInfo* queue_object_info, const std::vector& front_command_list_ids, D3D12_GPU_VIRTUAL_ADDRESS captured_source_gpu_va, uint64_t source_size, @@ -1846,26 +1768,33 @@ void Dx12DumpResources::CopyDrawCallResourceByGPUVA(DxObjectInfo* { if (captured_source_gpu_va == kNullGpuAddress) { - return; + if (TEST_WRITE_NULL_RESOURCE_VIEWS) + { + active_delegate_->WriteNULLBufferLocation(json_path, descriptor_heap_id, descriptor_heap_index); + return true; + } + return false; } + active_delegate_->WriteSingleData(json_path, "buffer_location", captured_source_gpu_va); + auto source_resource_id = object_mapping::FindResourceIDbyGpuVA(captured_source_gpu_va, gpu_va_map_); auto source_resource_object_info = get_object_info_func_(source_resource_id); auto source_resource_extra_info = GetExtraInfo(source_resource_object_info); - CopyDrawCallResourceBySubresource(queue_object_info, - front_command_list_ids, - source_resource_id, - (captured_source_gpu_va - source_resource_extra_info->capture_address_), - source_size, - { 0 }, - json_path, - resource_type, - pos, - descriptor_heap_id, - descriptor_heap_index); + return CopyDrawCallResourceBySubresource(queue_object_info, + front_command_list_ids, + source_resource_id, + (captured_source_gpu_va - source_resource_extra_info->capture_address_), + source_size, + { 0 }, + json_path, + resource_type, + pos, + descriptor_heap_id, + descriptor_heap_index); } -void Dx12DumpResources::CopyDrawCallResourceBySubresource(DxObjectInfo* queue_object_info, +bool Dx12DumpResources::CopyDrawCallResourceBySubresource(DxObjectInfo* queue_object_info, const std::vector& front_command_list_ids, format::HandleId source_resource_id, uint64_t source_offset, @@ -1879,7 +1808,12 @@ void Dx12DumpResources::CopyDrawCallResourceBySubresource(DxObjectInfo* { if (source_resource_id == format::kNullHandleId) { - return; + if (TEST_WRITE_NULL_RESOURCE_VIEWS) + { + active_delegate_->WriteNULLResource(json_path, descriptor_heap_id, descriptor_heap_index); + return true; + } + return false; } CopyResourceDataPtr copy_resource_data(new CopyResourceData()); copy_resource_data->subresource_indices = subresource_indices; @@ -1891,6 +1825,7 @@ void Dx12DumpResources::CopyDrawCallResourceBySubresource(DxObjectInfo* CopyDrawCallResource( queue_object_info, front_command_list_ids, source_resource_id, source_offset, source_size, copy_resource_data); + return true; } // If source_size = 0, the meaning is the whole after offset. @@ -1901,7 +1836,7 @@ void Dx12DumpResources::CopyDrawCallResource(DxObjectInfo* uint64_t source_size, CopyResourceDataPtr copy_resource_data) { - if (source_resource_id == 0) + if (source_resource_id == format::kNullHandleId) { return; } @@ -2440,7 +2375,7 @@ void DefaultDx12DumpResourcesDelegate::EndDumpResources() } nlohmann::ordered_json* -DefaultDx12DumpResourcesDelegate::FindDrawCallJsonPath(const std::vector>& json_path) +DefaultDx12DumpResourcesDelegate::FindDrawCallJsonNode(const std::vector>& json_path) { auto* jdata_sub = &draw_call_; for (const auto& path : json_path) @@ -2461,51 +2396,109 @@ void DefaultDx12DumpResourcesDelegate::WriteSingleData(const std::vector>& json_path, const uint32_t index, uint64_t value) { - auto* jdata_sub = FindDrawCallJsonPath(json_path); - util::FieldToJson((*jdata_sub)[index], value, json_options_); + auto* jdata_node = FindDrawCallJsonNode(json_path); + util::FieldToJson((*jdata_node)[index], value, json_options_); } void DefaultDx12DumpResourcesDelegate::WriteSingleData(const std::vector>& json_path, const std::string& key, const std::string& value) { - auto* jdata_sub = FindDrawCallJsonPath(json_path); - util::FieldToJson((*jdata_sub)[key], value, json_options_); -} - -void DefaultDx12DumpResourcesDelegate::WriteEmptyNode(const std::vector>& json_path) -{ - FindDrawCallJsonPath(json_path); + auto* jdata_node = FindDrawCallJsonNode(json_path); + util::FieldToJson((*jdata_node)[key], value, json_options_); } void DefaultDx12DumpResourcesDelegate::WriteNote(const std::vector>& json_path, const std::string& value) { - auto* jdata_sub = FindDrawCallJsonPath(json_path); - auto& jdata_notes = (*jdata_sub)[NameNotes()]; + auto* jdata_node = FindDrawCallJsonNode(json_path); + auto& jdata_notes = (*jdata_node)[NameNotes()]; auto size = jdata_notes.size(); util::FieldToJson(jdata_notes[size], value, json_options_); } +void DefaultDx12DumpResourcesDelegate::WriteRootParameterInfo( + const std::vector>& json_path, + uint32_t root_parameter_index, + const TrackRootParameter& root_parameter) +{ + auto* jdata_node = FindDrawCallJsonNode(json_path); + util::FieldToJson((*jdata_node)["root_parameter_index"], root_parameter_index, json_options_); + util::FieldToJson((*jdata_node)["root_signature_type"],util::ToString(root_parameter.root_signature_type), json_options_); + util::FieldToJson((*jdata_node)["cmd_bind_type"], util::ToString(root_parameter.cmd_bind_type), json_options_); + + if (root_parameter.root_signature_type != root_parameter.cmd_bind_type) + { + WriteNote(json_path, "root_signature_type and cmd_bind_type are different."); + + if (root_parameter.cmd_bind_type == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE) + { + WriteNote(json_path, + "root_signature_type isn't DESCRIPTOR_TABLE and no NumDescriptors, so dump only one descriptor."); + } + } + + uint32_t di = 0; + for (const auto& table : root_parameter.root_signature_descriptor_tables) + { + util::FieldToJson((*jdata_node)["tables"][di]["range_type"], util::ToString(table.RangeType), json_options_); + util::FieldToJson((*jdata_node)["tables"][di]["num_descriptors"], table.NumDescriptors, json_options_); + ++di; + } +} + +void DefaultDx12DumpResourcesDelegate::WriteNotFoundView(const std::vector>& json_path, + format::HandleId heap_id, + uint32_t heap_index) +{ + auto* jdata_node = FindDrawCallJsonNode(json_path); + util::FieldToJson((*jdata_node)["heap_id"], heap_id, json_options_); + util::FieldToJson((*jdata_node)["heap_index"], heap_index, json_options_); + + WriteNote(json_path, "This heap_index can't be found a view in this heap_id"); +} + +void DefaultDx12DumpResourcesDelegate::WriteNULLResource(const std::vector>& json_path, + format::HandleId heap_id, + uint32_t heap_index) +{ + auto* jdata_node = FindDrawCallJsonNode(json_path); + util::FieldToJson((*jdata_node)["heap_id"], heap_id, json_options_); + util::FieldToJson((*jdata_node)["heap_index"], heap_index, json_options_); + util::FieldToJson((*jdata_node)["res_id"], 0, json_options_); +} + +void DefaultDx12DumpResourcesDelegate::WriteNULLBufferLocation( + const std::vector>& json_path, format::HandleId heap_id, uint32_t heap_index) +{ + auto* jdata_node = FindDrawCallJsonNode(json_path); + if (heap_id != format::kNullHandleId) + { + util::FieldToJson((*jdata_node)["heap_id"], heap_id, json_options_); + util::FieldToJson((*jdata_node)["heap_index"], heap_index, json_options_); + } + util::FieldToJson((*jdata_node)["buffer_location"], 0, json_options_); +} + void DefaultDx12DumpResourcesDelegate::WriteResource(const CopyResourceDataPtr resource_data) { if (resource_data->source_resource_id == format::kNullHandleId) { return; } - auto* jdata_sub = FindDrawCallJsonPath(resource_data->json_path); + auto* jdata_node = FindDrawCallJsonNode(resource_data->json_path); std::string prefix_file_name = json_options_.data_sub_dir + "_" + Dx12ResourceTypeToString(resource_data->resource_type); - WriteResource(*jdata_sub, prefix_file_name, resource_data); + WriteResource(*jdata_node, prefix_file_name, resource_data); if (TEST_READABLE) { diff --git a/framework/decode/dx12_dump_resources.h b/framework/decode/dx12_dump_resources.h index 6cb5b668ad..46909d2390 100644 --- a/framework/decode/dx12_dump_resources.h +++ b/framework/decode/dx12_dump_resources.h @@ -163,8 +163,19 @@ class Dx12DumpResourcesDelegate virtual void WriteSingleData(const std::vector>& json_path, const std::string& key, const std::string& value) = 0; - virtual void WriteEmptyNode(const std::vector>& json_path) = 0; virtual void WriteNote(const std::vector>& json_path, const std::string& value) = 0; + virtual void WriteRootParameterInfo(const std::vector>& json_path, + uint32_t root_parameter_index, + const TrackRootParameter& root_parameter) = 0; + virtual void WriteNotFoundView(const std::vector>& json_path, + format::HandleId heap_id, + uint32_t heap_index) = 0; + virtual void WriteNULLResource(const std::vector>& json_path, + format::HandleId heap_id, + uint32_t heap_index) = 0; + virtual void WriteNULLBufferLocation(const std::vector>& json_path, + format::HandleId heap_id, + uint32_t heap_index) = 0; }; class DefaultDx12DumpResourcesDelegate : public Dx12DumpResourcesDelegate @@ -185,9 +196,20 @@ class DefaultDx12DumpResourcesDelegate : public Dx12DumpResourcesDelegate virtual void WriteSingleData(const std::vector>& json_path, const std::string& key, const std::string& value) override; - virtual void WriteEmptyNode(const std::vector>& json_path) override; virtual void WriteNote(const std::vector>& json_path, const std::string& value) override; + virtual void WriteRootParameterInfo(const std::vector>& json_path, + uint32_t root_parameter_index, + const TrackRootParameter& root_parameter) override; + virtual void WriteNotFoundView(const std::vector>& json_path, + format::HandleId heap_id, + uint32_t heap_index) override; + virtual void WriteNULLResource(const std::vector>& json_path, + format::HandleId heap_id, + uint32_t heap_index) override; + virtual void WriteNULLBufferLocation(const std::vector>& json_path, + format::HandleId heap_id, + uint32_t heap_index) override; private: void WriteResource(const CopyResourceDataPtr resource_data); @@ -200,7 +222,7 @@ class DefaultDx12DumpResourcesDelegate : public Dx12DumpResourcesDelegate void WriteBlockStart(); void WriteBlockEnd(); - nlohmann::ordered_json* FindDrawCallJsonPath(const std::vector>& json_path); + nlohmann::ordered_json* FindDrawCallJsonNode(const std::vector>& json_path); constexpr const char* NameDrawCall() const { return "draw_call"; } constexpr const char* NameNotes() const { return "notes"; } @@ -299,7 +321,7 @@ class Dx12DumpResources const std::vector& front_command_list_ids, graphics::dx12::Dx12DumpResourcePos pos); - void CopyDrawCallResourceByGPUVA(DxObjectInfo* queue_object_info, + bool CopyDrawCallResourceByGPUVA(DxObjectInfo* queue_object_info, const std::vector& front_command_list_ids, D3D12_GPU_VIRTUAL_ADDRESS capture_source_gpu_va, uint64_t source_size, @@ -309,7 +331,7 @@ class Dx12DumpResources format::HandleId descriptor_heap_id, uint32_t descriptor_heap_index); - void CopyDrawCallResourceBySubresource(DxObjectInfo* queue_object_info, + bool CopyDrawCallResourceBySubresource(DxObjectInfo* queue_object_info, const std::vector& front_command_list_ids, format::HandleId source_resource_id, uint64_t source_offset,