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..0fc983662f 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; @@ -528,32 +565,807 @@ void Dx12DumpResources::BeginRenderPass( after_ds_desc.StencilBeginningAccess.Type = D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE; p_after_ds_desc = &after_ds_desc; } - command_list4_after->BeginRenderPass(NumRenderTargets, after_rt_descs.data(), p_after_ds_desc, Flags); - } - else if (dump_command_sets.size() == 1) - { - graphics::dx12::ID3D12GraphicsCommandList4ComPtr command_list4; - dump_command_sets[0].list->QueryInterface(IID_PPV_ARGS(&command_list4)); - command_list4->BeginRenderPass( - NumRenderTargets, pRenderTargets->GetPointer(), pDepthStencil->GetPointer(), Flags); + command_list4_after->BeginRenderPass(NumRenderTargets, after_rt_descs.data(), p_after_ds_desc, Flags); + } + else if (dump_command_sets.size() == 1) + { + graphics::dx12::ID3D12GraphicsCommandList4ComPtr command_list4; + dump_command_sets[0].list->QueryInterface(IID_PPV_ARGS(&command_list4)); + command_list4->BeginRenderPass( + NumRenderTargets, pRenderTargets->GetPointer(), pDepthStencil->GetPointer(), Flags); + } + } +} + +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) +{ + 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 (increment == 0) + { + out_heap_index = 0; + } + else + { + out_heap_index = (capture_gpu_addr.ptr - heap_info.capture_gpu_addr_begin) / increment; + } + } + 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_->WriteNotFoundView(json_path_sub, heap_id, heap_index); + } + continue; + } + + switch (info_entry->second.type) + { + case D3D12_DESCRIPTOR_RANGE_TYPE_CBV: + { + const auto& desc = info_entry->second.cbv.captured_desc; + + json_path_sub = json_path; + json_path_sub.emplace_back("descs", json_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: + { + json_path_sub = json_path; + json_path_sub.emplace_back("descs", 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; + } + 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: + { + json_path_sub = json_path; + json_path_sub.emplace_back("descs", 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); + + 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); + + 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; } } } -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) +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) { - for (auto gpu_addr : captured_gpu_addrs) + std::vector> json_path; + std::vector> json_path_sub; + auto json_index = 0; + for (const auto& param : root_parameters) { - 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))) + json_path.clear(); + json_path.emplace_back(Dx12ResourceTypeToString(res_type), json_index); + active_delegate_->WriteRootParameterInfo(json_path, param.first, param.second); + + switch (param.second.cmd_bind_type) { - return true; + 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) + { + 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: + { + 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; } + ++json_index; } - return false; } void Dx12DumpResources::CopyDrawCallResources(DxObjectInfo* queue_object_info, @@ -565,318 +1377,340 @@ 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 json_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) + { + json_index = 0; + for (const auto& view : *vertex_buffer_views) + { + json_path.clear(); + json_path.emplace_back("vertices", json_index); + + if(CopyDrawCallResourceByGPUVA(queue_object_info, + front_command_list_ids, + view.BufferLocation, + view.SizeInBytes, + json_path, + Dx12DumpResourceType::kVertex, + pos, + format::kNullHandleId, + 0)) + { + ++json_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) { - // shader resource - resource_index = 0; - for (const auto& info_pair : heap_extra_info->shader_resource_infos) + 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) + { + 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. + json_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)) + { + continue; + } + json_path.clear(); + 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()) { - uint64_t offset = 0; - uint64_t size = 0; - switch (info.view.ViewDimension) + 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); - CopyDrawCallResourceBySubresource(queue_object_info, - front_command_list_ids, - info.resource_id, - 0, - 0, - info.subresource_indices, - json_path, - Dx12DumpResourceType::kRtv, - pos, - descriptor_heap_id, - descriptor_heap_index); - ++resource_index; - break; + 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; + } } } - } - - // 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); + + 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; + + 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); + } } } } @@ -922,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, @@ -932,28 +1766,35 @@ 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; + 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, @@ -965,6 +1806,15 @@ void Dx12DumpResources::CopyDrawCallResourceBySubresource(DxObjectInfo* format::HandleId descriptor_heap_id, uint32_t descriptor_heap_index) { + if (source_resource_id == format::kNullHandleId) + { + 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; copy_resource_data->json_path = json_path; @@ -975,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. @@ -985,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; } @@ -1482,9 +2333,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); - util::platform::FileOpen(&json_file_handle_, json_filename_.c_str(), "w"); + auto file_path = json_options_.root_dir + util::filepath::kPathSepStr + json_filename_; + + 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 +2363,7 @@ void DefaultDx12DumpResourcesDelegate::BeginDumpResources(const std::string& void DefaultDx12DumpResourcesDelegate::DumpResource(CopyResourceDataPtr resource_data) { + auto* jdata_sub = &draw_call_; WriteResource(resource_data); } @@ -1520,15 +2374,11 @@ void DefaultDx12DumpResourcesDelegate::EndDumpResources() EndFile(); } -void DefaultDx12DumpResourcesDelegate::WriteResource(const CopyResourceDataPtr resource_data) +nlohmann::ordered_json* +DefaultDx12DumpResourcesDelegate::FindDrawCallJsonNode(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,9 +2389,116 @@ 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_node = FindDrawCallJsonNode(json_path); + util::FieldToJson((*jdata_node)[key], value, json_options_); +} + +void DefaultDx12DumpResourcesDelegate::WriteSingleData(const std::vector>& json_path, + const uint32_t index, + uint64_t value) +{ + 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_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_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_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) { @@ -1560,16 +2517,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 +2543,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 +2616,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 +2645,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..46909d2390 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,28 @@ 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 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 @@ -163,6 +187,29 @@ 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 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); @@ -175,7 +222,10 @@ class DefaultDx12DumpResourcesDelegate : public Dx12DumpResourcesDelegate void WriteBlockStart(); void WriteBlockEnd(); + nlohmann::ordered_json* FindDrawCallJsonNode(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); @@ -241,17 +291,37 @@ 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); 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); - 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, @@ -261,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, diff --git a/framework/decode/dx12_object_info.h b/framework/decode/dx12_object_info.h index 2198fffde9..e3f6756fca 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,47 +284,64 @@ 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; + std::vector subresource_indices; // Only use for dump resources }; -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; + std::vector subresource_indices; // Only use for dump resources +}; + +struct DHCbvSrvUavInfo +{ + D3D12_DESCRIPTOR_RANGE_TYPE type{}; + DHConstantBufferViewInfo cbv; + DHShaderResourceViewInfo srv; + DHUnorderedAccessViewInfo uav; }; -struct RenderTargetInfo +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; + std::vector subresource_indices; // Only use for dump resources }; -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; + std::vector subresource_indices; // Only use for dump resources +}; + +struct DHSamplerInfo +{ + D3D12_SAMPLER_DESC desc{}; + D3D12_CPU_DESCRIPTOR_HANDLE replay_handle{ kNullCpuAddress }; }; struct D3D12DescriptorHeapInfo : DxObjectExtraInfo @@ -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..537495fd06 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,27 +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); } -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) +void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateSampler( + const ApiCallInfo& call_info, + DxObjectInfo* object_info, + StructPointerDecoder* pDesc, + Decoded_D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) { - 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; + 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); } void Dx12ReplayConsumerBase::PostCall_ID3D12Device_CreateShaderResourceView( @@ -4533,272 +4530,33 @@ 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) + 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.view.ViewDimension) + GFXRECON_ASSERT(dump_resources_); + if (pResource != format::kNullHandleId) { - case D3D12_SRV_DIMENSION_BUFFER: - info.subresource_indices.emplace_back(0); - break; - case D3D12_SRV_DIMENSION_TEXTURE1D: - { - auto view = info.view.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 = GetDescriptorSubresourceIndices( - view.MostDetailedMip, mip_size, mip_count, 0, 1, array_count, 0); - } - else - { - mip_size -= view.MostDetailedMip; - 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 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 = 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); - } - break; - } - case D3D12_SRV_DIMENSION_TEXTURE2D: - { - auto view = info.view.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 = GetDescriptorSubresourceIndices( - view.MostDetailedMip, mip_size, mip_count, 0, 1, array_count, view.PlaneSlice); - } - else - { - mip_size -= view.MostDetailedMip; - 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 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 = 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); - } - break; - } - case D3D12_SRV_DIMENSION_TEXTURE2DMS: - { - 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 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_SRV_DIMENSION_TEXTURE3D: - { - array_count = 1; - auto view = info.view.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 = GetDescriptorSubresourceIndices( - view.MostDetailedMip, mip_size, mip_count, 0, 1, array_count, 0); - } - else - { - 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 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 = GetDescriptorSubresourceIndices( - view.MostDetailedMip, mip_size, mip_count, 0, 1, array_count, 0); - } - else - { - 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 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 = 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); - } - 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); } } } - 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,92 +4570,34 @@ 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) + 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.view.ViewDimension) + GFXRECON_ASSERT(dump_resources_); + if (pResource != format::kNullHandleId) { - case D3D12_UAV_DIMENSION_BUFFER: - 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); - break; - case D3D12_UAV_DIMENSION_TEXTURE1DARRAY: - { - auto view = info.view.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_UAV_DIMENSION_TEXTURE2D: - info.subresource_indices = GetDescriptorSubresourceIndices( - info.view.Texture2D.MipSlice, 1, mip_count, 0, 1, array_count, info.view.Texture2D.PlaneSlice); - break; - case D3D12_UAV_DIMENSION_TEXTURE2DARRAY: - { - auto view = info.view.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_UAV_DIMENSION_TEXTURE2DMS: - 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 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_UAV_DIMENSION_TEXTURE3D: - { - // DUMPTODO: handle FirstWSlice and WSize - info.subresource_indices = - GetDescriptorSubresourceIndices(info.view.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); } } } - 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,91 +4610,31 @@ 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) + 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.view.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.view.Texture1D.MipSlice, 1, mip_count, 0, 1, array_count, 0); - break; - case D3D12_RTV_DIMENSION_TEXTURE1DARRAY: - { - auto view = info.view.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.view.Texture2D.MipSlice, 1, mip_count, 0, 1, array_count, info.view.Texture2D.PlaneSlice); - break; - case D3D12_RTV_DIMENSION_TEXTURE2DARRAY: - { - auto view = info.view.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.view.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.view.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); } } } - 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,81 +4647,31 @@ 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) + 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.view.ViewDimension) + GFXRECON_ASSERT(dump_resources_); + if (pResource != format::kNullHandleId) { - case D3D12_DSV_DIMENSION_TEXTURE1D: - info.subresource_indices = GetDescriptorSubresourceIndices( - info.view.Texture1D.MipSlice, 1, mip_count, 0, 1, array_count, 0); - break; - case D3D12_DSV_DIMENSION_TEXTURE1DARRAY: - { - auto view = info.view.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.view.Texture2D.MipSlice, 1, mip_count, 0, 1, array_count, 0); - break; - case D3D12_DSV_DIMENSION_TEXTURE2DARRAY: - { - auto view = info.view.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.view.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); } } } - 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 +4804,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 +4852,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,