diff --git a/USAGE_desktop_D3D12.md b/USAGE_desktop_D3D12.md index e08d2756a..0c32c7ca3 100644 --- a/USAGE_desktop_D3D12.md +++ b/USAGE_desktop_D3D12.md @@ -110,6 +110,7 @@ Quit after capturing frame ranges | GFXRECON_QUIT_AFTER_CAPTURE_FRAMES | BOOL | Hotkey Capture Trigger | GFXRECON_CAPTURE_TRIGGER | STRING | Specify a hotkey (any one of F1-F12, TAB, CONTROL) that will be used to start/stop capture. Example: `F3` will set the capture trigger to F3 hotkey. One capture file will be generated for each pair of start/stop hotkey presses. Default is: Empty string (hotkey capture trigger is disabled). Hotkey Capture Trigger Frames | GFXRECON_CAPTURE_TRIGGER_FRAMES | STRING | Specify a limit on the number of frames to be captured via hotkey. Example: `1` will capture exactly one frame when the trigger key is pressed. Default is: Empty string (no limit) Capture Specific GPU Queue Submits | GFXRECON_CAPTURE_QUEUE_SUBMITS | STRING | Specify one or more comma-separated GPU queue submit call ranges to capture. Queue submit calls are `vkQueueSubmit` for Vulkan and `ID3D12CommandQueue::ExecuteCommandLists` for DX12. Queue submit ranges work as described above in `GFXRECON_CAPTURE_FRAMES` but on GPU queue submit calls instead of frames. Default is: Empty string (all queue submits are captured). +Capture Specific Draw Calls | GFXRECON_CAPTURE_DRAW_CALLS | STRING | Specify one index or a range indices drawacalls(include dispatch) based on a ExecuteCommandList index and a CommandList index to capture. The index is 0-based. The args are one submit index, one command index, one or a range indices of draw calls, one or a range indices of bundle draw calls(option), like "0,0,0" or "0,0,0-2" or "0,0,0-2,0". The forth arg is an option for bundle case. If the the 3rd arg is a bundle commandlist, but it doesn't set the 4th arg, it will set 0 as default. Default is: Empty string (all draw calls are captured). Capture File Compression Type | GFXRECON_CAPTURE_COMPRESSION_TYPE | STRING | Compression format to use with the capture file. Valid values are: `LZ4`, `ZLIB`, `ZSTD`, and `NONE`. Default is: `LZ4` Capture File Timestamp | GFXRECON_CAPTURE_FILE_TIMESTAMP | BOOL | Add a timestamp to the capture file as described by [Timestamps](#timestamps). Default is: `true` Capture File Flush After Write | GFXRECON_CAPTURE_FILE_FLUSH | BOOL | Flush output stream after each packet is written to the capture file. Default is: `false` @@ -211,7 +212,7 @@ Usage: [--fwo | --force-windowed-origin ] [--log-level ] [--log-file ] [--log-debugview] [--batching-memory-usage ] - [--dump-resources ] + [--dump-resources ] [--pbi-all] [--pbis ] Required arguments: @@ -338,12 +339,12 @@ D3D12-only: for batching and does not guarantee overall max memory usage. Acceptable values range from 0 to 100 (default: 80). 0 means no batching, 100 means use all available system and GPU memory. - --dump-resources - Output binaray resources for a specific drawcall. + --dump-resources + Output binaray resources for a specific draw call. Include vertex, index, const buffer, shader resource, render target, - and depth stencil. And for before and after drawcall. + and depth stencil. And for before and after draw call. Arguments becomes three indices, submit index, command index, - drawcall index. The command index is based on its in ExecuteCommandLists. + draw call index. The command index is based on its in ExecuteCommandLists. ``` diff --git a/framework/decode/dx12_browse_consumer.h b/framework/decode/dx12_browse_consumer.h index 82f2ea431..e643030fe 100644 --- a/framework/decode/dx12_browse_consumer.h +++ b/framework/decode/dx12_browse_consumer.h @@ -47,7 +47,7 @@ struct ExecuteIndirectInfo uint64_t count_offset{ 0 }; }; -struct TrackDumpDrawcall +struct TrackDumpDrawCall { DumpResourcesTarget dump_resources_target{}; format::HandleId command_list_id{ format::kNullHandleId }; @@ -75,9 +75,9 @@ struct TrackDumpDrawcall // Bundle format::HandleId bundle_commandlist_id{ format::kNullHandleId }; // It couldn't use the structure that is the same to the parent structure, so use std::shared_ptr. - std::shared_ptr bundle_target_drawcall; + std::shared_ptr bundle_target_draw_call; - uint64_t drawcall_block_index{ 0 }; // It could also be ExecuteIndirect or ExecuteBundle block index. + uint64_t draw_call_block_index{ 0 }; // It could also be ExecuteIndirect or ExecuteBundle block index. uint64_t execute_block_index{ 0 }; void Clear() @@ -86,7 +86,7 @@ struct TrackDumpDrawcall descriptor_heap_ids.clear(); captured_descriptor_gpu_handles.clear(); bundle_commandlist_id = format::kNullHandleId; - bundle_target_drawcall = nullptr; + bundle_target_draw_call = nullptr; } }; @@ -111,7 +111,7 @@ struct TrackDumpCommandList // Track render target info in replay, not here. // Because the useful info is replay cpuDescriptor. It's only available in replay. - std::vector> track_dump_drawcalls; + std::vector> track_dump_draw_calls; void Clear() { @@ -122,7 +122,7 @@ struct TrackDumpCommandList current_captured_index_buffer_view = {}; current_descriptor_heap_ids.clear(); current_captured_descriptor_gpu_handles.clear(); - track_dump_drawcalls.clear(); + track_dump_draw_calls.clear(); } }; @@ -136,7 +136,7 @@ class Dx12BrowseConsumer : public Dx12Consumer dump_resources_target_ = dump_resources_target; } - TrackDumpDrawcall* GetTrackDumpTarget() + TrackDumpDrawCall* GetTrackDumpTarget() { if (track_submit_index_ <= dump_resources_target_.submit_index) { @@ -154,8 +154,8 @@ class Dx12BrowseConsumer : public Dx12Consumer auto it = track_commandlist_infos_.find(target_command_list_); if (it != track_commandlist_infos_.end()) { - auto drawcall_size = it->second.track_dump_drawcalls.size(); - GFXRECON_ASSERT(drawcall_size > target_drawcall_index_); + auto draw_call_size = it->second.track_dump_draw_calls.size(); + GFXRECON_ASSERT(draw_call_size > target_draw_call_index_); if (is_modified_args) { @@ -163,9 +163,9 @@ class Dx12BrowseConsumer : public Dx12Consumer "the original args.", dump_resources_target_.submit_index, dump_resources_target_.command_index, - dump_resources_target_.drawcall_index); + dump_resources_target_.draw_call_index); } - auto& target = it->second.track_dump_drawcalls[target_drawcall_index_]; + auto& target = it->second.track_dump_draw_calls[target_draw_call_index_]; target->dump_resources_target = dump_resources_target_; return target.get(); } @@ -221,11 +221,11 @@ class Dx12BrowseConsumer : public Dx12Consumer auto it = track_commandlist_infos_.find(object_id); if (it != track_commandlist_infos_.end()) { - for (auto& drawcall : it->second.track_dump_drawcalls) + for (auto& draw_call : it->second.track_dump_draw_calls) { - if (drawcall->begin_renderpass_block_index != 0 && drawcall->end_renderpass_block_index == 0) + if (draw_call->begin_renderpass_block_index != 0 && draw_call->end_renderpass_block_index == 0) { - drawcall->end_renderpass_block_index = call_info.index; + draw_call->end_renderpass_block_index = call_info.index; } } } @@ -387,7 +387,7 @@ class Dx12BrowseConsumer : public Dx12Consumer UINT StartVertexLocation, UINT StartInstanceLocation) { - TrackTargetDrawcall(call_info, object_id, true); + TrackTargetDrawCall(call_info, object_id, true); } virtual void Process_ID3D12GraphicsCommandList_DrawIndexedInstanced(const ApiCallInfo& call_info, @@ -398,7 +398,7 @@ class Dx12BrowseConsumer : public Dx12Consumer INT BaseVertexLocation, UINT StartInstanceLocation) { - TrackTargetDrawcall(call_info, object_id, true); + TrackTargetDrawCall(call_info, object_id, true); } virtual void Process_ID3D12GraphicsCommandList_Dispatch(const ApiCallInfo& call_info, @@ -407,7 +407,7 @@ class Dx12BrowseConsumer : public Dx12Consumer UINT ThreadGroupCountY, UINT ThreadGroupCountZ) { - TrackTargetDrawcall(call_info, object_id, false); + TrackTargetDrawCall(call_info, object_id, false); } virtual void Process_ID3D12GraphicsCommandList_ExecuteIndirect(const ApiCallInfo& call_info, @@ -419,7 +419,7 @@ class Dx12BrowseConsumer : public Dx12Consumer format::HandleId pCountBuffer, UINT64 CountBufferOffset) { - TrackTargetDrawcall( + TrackTargetDrawCall( call_info, object_id, false, pArgumentBuffer, ArgumentBufferOffset, pCountBuffer, CountBufferOffset); } @@ -427,7 +427,7 @@ class Dx12BrowseConsumer : public Dx12Consumer format::HandleId object_id, format::HandleId pCommandList) { - TrackTargetDrawcall( + TrackTargetDrawCall( call_info, object_id, false, format::kNullHandleId, 0, format::kNullHandleId, 0, pCommandList); } @@ -440,9 +440,9 @@ class Dx12BrowseConsumer : public Dx12Consumer auto it = track_commandlist_infos_.find(object_id); if (it != track_commandlist_infos_.end()) { - for (auto& drawcall : it->second.track_dump_drawcalls) + for (auto& draw_call : it->second.track_dump_draw_calls) { - drawcall->close_block_index = call_info.index; + draw_call->close_block_index = call_info.index; } } } @@ -464,9 +464,9 @@ class Dx12BrowseConsumer : public Dx12Consumer { ++track_submit_index_; ++dump_resources_target_.submit_index; - dump_resources_target_.command_index = 0; - dump_resources_target_.drawcall_index = 0; - is_modified_args = true; + dump_resources_target_.command_index = 0; + dump_resources_target_.draw_call_index = 0; + is_modified_args = true; return; } else @@ -486,91 +486,103 @@ class Dx12BrowseConsumer : public Dx12Consumer auto it = track_commandlist_infos_.find(cmd_list); GFXRECON_ASSERT(it != track_commandlist_infos_.end()); - uint32_t all_drawcall_count = 0; // Include normal drawcall and bundle drawcall. - uint32_t drawcall_index = 0; - for (auto& drawcall : it->second.track_dump_drawcalls) + uint32_t all_draw_call_count = 0; // Include normal draw call and bundle draw call. + uint32_t draw_call_index = 0; + for (auto& draw_call : it->second.track_dump_draw_calls) { - if (drawcall->bundle_commandlist_id != format::kNullHandleId) + if (draw_call->bundle_commandlist_id != format::kNullHandleId) { - auto bundle_it = track_commandlist_infos_.find(drawcall->bundle_commandlist_id); + auto bundle_it = track_commandlist_infos_.find(draw_call->bundle_commandlist_id); if (bundle_it != track_commandlist_infos_.end()) { - for (auto& bundle_drawcall : bundle_it->second.track_dump_drawcalls) + for (auto& bundle_draw_call : bundle_it->second.track_dump_draw_calls) { - ++all_drawcall_count; - if (all_drawcall_count > dump_resources_target_.drawcall_index) + ++all_draw_call_count; + if (all_draw_call_count > dump_resources_target_.draw_call_index) { - if (TEST_AVAILABLE_ARGS == 2 && !bundle_drawcall->is_draw) + if (TEST_AVAILABLE_ARGS == 2 && !bundle_draw_call->is_draw) { - // Find a draw drawcall in the following drawcall. + // Finding the target in the following draw call. is_modified_args = true; - ++dump_resources_target_.drawcall_index; + ++dump_resources_target_.draw_call_index; } else { - drawcall->bundle_target_drawcall = bundle_drawcall; + // Found the target. + draw_call->bundle_target_draw_call = bundle_draw_call; - drawcall->execute_block_index = call_info.index; - target_command_list_ = cmd_list; - target_drawcall_index_ = drawcall_index; + draw_call->execute_block_index = call_info.index; + target_command_list_ = cmd_list; + target_draw_call_index_ = draw_call_index; break; } } } + + // Found the target. + if (target_command_list_ != format::kNullHandleId) + { + break; + } } } else { - ++all_drawcall_count; - if (all_drawcall_count > dump_resources_target_.drawcall_index) + ++all_draw_call_count; + if (all_draw_call_count > dump_resources_target_.draw_call_index) { - if (TEST_AVAILABLE_ARGS == 2 && !drawcall->is_draw) + if (TEST_AVAILABLE_ARGS == 2 && !draw_call->is_draw) { - // Find a draw drawcall in the following drawcall. + // Finding the target in the following draw call. is_modified_args = true; - ++dump_resources_target_.drawcall_index; + ++dump_resources_target_.draw_call_index; } else { - drawcall->execute_block_index = call_info.index; + // Found the target. + draw_call->execute_block_index = call_info.index; target_command_list_ = cmd_list; - target_drawcall_index_ = drawcall_index; + target_draw_call_index_ = draw_call_index; break; } } } - ++drawcall_index; + ++draw_call_index; } - // It didn't find the target drawcall. - if (target_command_list_ == format::kNullHandleId) + // Found the target. + if (target_command_list_ != format::kNullHandleId) + { + break; + } + else { if (TEST_AVAILABLE_ARGS > 0) { - // Find a drawcall in the following command list. + // Finding the target in the following command list. is_modified_args = true; ++dump_resources_target_.command_index; - dump_resources_target_.drawcall_index = 0; + dump_resources_target_.draw_call_index = 0; } else { - GFXRECON_LOG_FATAL("The target drawcall index(%d) of dump resources is out of range(%d).", - dump_resources_target_.drawcall_index, - all_drawcall_count); - GFXRECON_ASSERT(all_drawcall_count > dump_resources_target_.drawcall_index); + GFXRECON_LOG_FATAL("The target draw call index(%d) of dump resources is out of range(%d).", + dump_resources_target_.draw_call_index, + all_draw_call_count); + GFXRECON_ASSERT(all_draw_call_count > dump_resources_target_.draw_call_index); break; } } } - // It didn't find the target drawcall. + // It didn't find the target draw call. if (TEST_AVAILABLE_ARGS > 0 && target_command_list_ == format::kNullHandleId) { - // Find a drawcall in the following submit. + // Find a draw call in the following submit. is_modified_args = true; ++dump_resources_target_.submit_index; - dump_resources_target_.command_index = 0; - dump_resources_target_.drawcall_index = 0; + dump_resources_target_.command_index = 0; + dump_resources_target_.draw_call_index = 0; } } ++track_submit_index_; @@ -584,7 +596,7 @@ class Dx12BrowseConsumer : public Dx12Consumer DumpResourcesTarget dump_resources_target_{}; uint32_t track_submit_index_{ 0 }; format::HandleId target_command_list_{ 0 }; - uint32_t target_drawcall_index_{ 0 }; + uint32_t target_draw_call_index_{ 0 }; // Key is commandlist_id. We need to know the commandlist of the info because in a commandlist block // between reset and close, it might have the other commandlist's commands. @@ -609,7 +621,7 @@ class Dx12BrowseConsumer : public Dx12Consumer } } - void TrackTargetDrawcall(const ApiCallInfo& call_info, + void TrackTargetDrawCall(const ApiCallInfo& call_info, format::HandleId object_id, bool is_draw, format::HandleId exe_indirect_argument_id = format::kNullHandleId, @@ -623,26 +635,26 @@ class Dx12BrowseConsumer : public Dx12Consumer auto it = track_commandlist_infos_.find(object_id); if (it != track_commandlist_infos_.end()) { - TrackDumpDrawcall track_drawcall = {}; - track_drawcall.command_list_id = object_id; - track_drawcall.drawcall_block_index = call_info.index; - track_drawcall.is_draw = is_draw; - track_drawcall.begin_block_index = it->second.begin_block_index; - track_drawcall.begin_renderpass_block_index = it->second.current_begin_renderpass_block_index; - track_drawcall.set_render_targets_block_index = it->second.current_set_render_targets_block_index; - track_drawcall.root_signature_handle_id = it->second.current_root_signature_handle_id; - track_drawcall.captured_vertex_buffer_views = it->second.current_captured_vertex_buffer_views; - track_drawcall.captured_index_buffer_view = it->second.current_captured_index_buffer_view; - track_drawcall.descriptor_heap_ids = it->second.current_descriptor_heap_ids; - track_drawcall.captured_descriptor_gpu_handles = it->second.current_captured_descriptor_gpu_handles; - track_drawcall.execute_indirect_info.argument_id = exe_indirect_argument_id; - track_drawcall.execute_indirect_info.argument_offset = exe_indirect_argument_offset; - track_drawcall.execute_indirect_info.count_id = exe_indirect_count_id; - track_drawcall.execute_indirect_info.count_offset = exe_indirect_count_offset; - track_drawcall.bundle_commandlist_id = bundle_commandlist_id; - - it->second.track_dump_drawcalls.emplace_back( - std::make_shared(std::move(track_drawcall))); + 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.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; + + 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 419b3101d..b59115131 100644 --- a/framework/decode/dx12_dump_resources.cpp +++ b/framework/decode/dx12_dump_resources.cpp @@ -76,43 +76,21 @@ static const char* Dx12ResourceTypeToString(Dx12DumpResourceType type) } } -static const char* Dx12DumpResourcePosToString(Dx12DumpResourcePos pos) +static const char* Dx12DumpResourcePosToString(graphics::dx12::Dx12DumpResourcePos pos) { switch (pos) { - case Dx12DumpResourcePos::kBeforeDrawCall: + case graphics::dx12::Dx12DumpResourcePos::kBeforeDrawCall: return "before"; - case Dx12DumpResourcePos::kDrawCall: - return "drawcall"; - case Dx12DumpResourcePos::kAfterDrawCall: + case graphics::dx12::Dx12DumpResourcePos::kDrawCall: + return "draw_call"; + case graphics::dx12::Dx12DumpResourcePos::kAfterDrawCall: return "after"; - case Dx12DumpResourcePos::kUnknown: default: return ""; } } -const static uint32_t kBeforeDrawCallArrayIndex = 0; -const static uint32_t kDrawCallArrayIndex = 1; -const static uint32_t kAfterDrawCallArrayIndex = 2; - -uint32_t Dx12DumpResourcePosToArrayIndex(Dx12DumpResourcePos pos) -{ - switch (pos) - { - case Dx12DumpResourcePos::kBeforeDrawCall: - return kBeforeDrawCallArrayIndex; - case Dx12DumpResourcePos::kDrawCall: - return kDrawCallArrayIndex; - case Dx12DumpResourcePos::kAfterDrawCall: - return kAfterDrawCallArrayIndex; - case Dx12DumpResourcePos::kUnknown: - default: - GFXRECON_ASSERT(false && "Invalid use of Dx12DumpResourcePosToArrayIndex."); - return 0; - } -} - Dx12DumpResources::Dx12DumpResources(std::function get_object_info_func, const graphics::Dx12GpuVaMap& gpu_va_map, DxReplayOptions& options) : @@ -217,14 +195,16 @@ bool Dx12DumpResources::ExecuteCommandLists(DxObjectInfo* // processes, for exmaples: finding resource by GPU VA, getting the resource infomation, and // write resource id, offset, size. But those duplicated processes shouldn't hurt the // performance. - CopyDrawcallResources( - replay_object_info, front_command_list_ids, Dx12DumpResourcePos::kBeforeDrawCall); + CopyDrawCallResources(replay_object_info, + front_command_list_ids, + graphics::dx12::Dx12DumpResourcePos::kBeforeDrawCall); ID3D12CommandList* ppCommandLists[] = { track_dump_resources_.split_command_sets[1].list }; replay_object->ExecuteCommandLists(1, ppCommandLists); - CopyDrawcallResources( - replay_object_info, front_command_list_ids, Dx12DumpResourcePos::kAfterDrawCall); + CopyDrawCallResources(replay_object_info, + front_command_list_ids, + graphics::dx12::Dx12DumpResourcePos::kAfterDrawCall); FinishDump(replay_object_info); @@ -253,9 +233,9 @@ void Dx12DumpResources::ExecuteBundle(DxObjectInfo* replay_object_info, auto dump_command_sets = GetCommandListsForDumpResources( replay_object_info, block_index, format::ApiCall_ID3D12GraphicsCommandList_ExecuteBundle); - // size = 1: this replay_object is the target command list, but this ExecuteBundle isn't the target drawcall. + // size = 1: this replay_object is the target command list, but this ExecuteBundle isn't the target draw call. // size = 0: this replay_object isn't the target command list. - // size = 3: this replay_object is the target command list, also this ExecuteBundle is the target drawcall. + // size = 3: this replay_object is the target command list, also this ExecuteBundle is the target draw call. if (dump_command_sets.size() == 1) { dump_command_sets[0].list->ExecuteBundle(command_list); @@ -328,10 +308,19 @@ bool Dx12DumpResources::CreateRootSignature(DxObjectInfo* device_ range_size * sizeof(D3D12_DESCRIPTOR_RANGE1)); for (uint32_t j = 0; j < range_size; ++j) { - if (ranges[i][j].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_NONE; - is_modified = true; + 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."); } } params[i].DescriptorTable.pDescriptorRanges = ranges[i].data(); @@ -467,7 +456,8 @@ void Dx12DumpResources::BeginRenderPass( // before ID3D12GraphicsCommandList4* command_list4_before; - dump_command_sets[kBeforeDrawCallArrayIndex].list->QueryInterface(IID_PPV_ARGS(&command_list4_before)); + dump_command_sets[graphics::dx12::kBeforeDrawCallArrayIndex].list->QueryInterface( + IID_PPV_ARGS(&command_list4_before)); std::vector before_rt_descs; for (uint32_t i = 0; i < NumRenderTargets; ++i) @@ -488,9 +478,10 @@ void Dx12DumpResources::BeginRenderPass( } command_list4_before->BeginRenderPass(NumRenderTargets, before_rt_descs.data(), p_before_ds_desc, Flags); - // drawcall + // draw call ID3D12GraphicsCommandList4* command_list4_draw_call; - dump_command_sets[kDrawCallArrayIndex].list->QueryInterface(IID_PPV_ARGS(&command_list4_draw_call)); + dump_command_sets[graphics::dx12::kDrawCallArrayIndex].list->QueryInterface( + IID_PPV_ARGS(&command_list4_draw_call)); std::vector draw_call_rt_descs; for (uint32_t i = 0; i < NumRenderTargets; ++i) @@ -517,7 +508,8 @@ void Dx12DumpResources::BeginRenderPass( // after ID3D12GraphicsCommandList4* command_list4_after; - dump_command_sets[kAfterDrawCallArrayIndex].list->QueryInterface(IID_PPV_ARGS(&command_list4_after)); + dump_command_sets[graphics::dx12::kAfterDrawCallArrayIndex].list->QueryInterface( + IID_PPV_ARGS(&command_list4_after)); std::vector after_rt_descs; for (uint32_t i = 0; i < NumRenderTargets; ++i) @@ -564,12 +556,12 @@ bool MatchDescriptorCPUGPUHandle(size_t rep return false; } -void Dx12DumpResources::CopyDrawcallResources(DxObjectInfo* queue_object_info, +void Dx12DumpResources::CopyDrawCallResources(DxObjectInfo* queue_object_info, const std::vector& front_command_list_ids, - Dx12DumpResourcePos pos) + graphics::dx12::Dx12DumpResourcePos pos) { // If Bundle have the bindings, using the bindings, or using the command's bindings. - auto bundle_target_drawcall = track_dump_resources_.target.bundle_target_drawcall.get(); + auto bundle_target_draw_call = track_dump_resources_.target.bundle_target_draw_call.get(); // pair first: path name, second: resource index. If index is kNoneIndex, it means not a array. std::vector> json_path; @@ -578,9 +570,9 @@ void Dx12DumpResources::CopyDrawcallResources(DxObjectInfo* // vertex const std::vector* vertex_buffer_views = nullptr; - if (bundle_target_drawcall && !bundle_target_drawcall->captured_vertex_buffer_views.empty()) + if (bundle_target_draw_call && !bundle_target_draw_call->captured_vertex_buffer_views.empty()) { - vertex_buffer_views = &bundle_target_drawcall->captured_vertex_buffer_views; + vertex_buffer_views = &bundle_target_draw_call->captured_vertex_buffer_views; } else { @@ -593,7 +585,7 @@ void Dx12DumpResources::CopyDrawcallResources(DxObjectInfo* { json_path.clear(); json_path.emplace_back("vertex", resource_index); - CopyDrawcallResourceByGPUVA(queue_object_info, + CopyDrawCallResourceByGPUVA(queue_object_info, front_command_list_ids, view.BufferLocation, view.SizeInBytes, @@ -608,9 +600,9 @@ void Dx12DumpResources::CopyDrawcallResources(DxObjectInfo* // index const D3D12_INDEX_BUFFER_VIEW* index_buffer_view = nullptr; - if (bundle_target_drawcall && bundle_target_drawcall->captured_index_buffer_view.BufferLocation != kNullGpuAddress) + if (bundle_target_draw_call && bundle_target_draw_call->captured_index_buffer_view.BufferLocation != kNullGpuAddress) { - index_buffer_view = &bundle_target_drawcall->captured_index_buffer_view; + index_buffer_view = &bundle_target_draw_call->captured_index_buffer_view; } else { @@ -620,7 +612,7 @@ void Dx12DumpResources::CopyDrawcallResources(DxObjectInfo* { json_path.clear(); json_path.emplace_back("index", format::kNoneIndex); - CopyDrawcallResourceByGPUVA(queue_object_info, + CopyDrawCallResourceByGPUVA(queue_object_info, front_command_list_ids, index_buffer_view->BufferLocation, index_buffer_view->SizeInBytes, @@ -635,17 +627,17 @@ void Dx12DumpResources::CopyDrawcallResources(DxObjectInfo* std::vector> json_path_sub; const std::vector* descriptor_heap_ids = nullptr; const std::map* descriptor_gpu_handles = nullptr; - if (bundle_target_drawcall && !bundle_target_drawcall->descriptor_heap_ids.empty()) + if (bundle_target_draw_call && !bundle_target_draw_call->descriptor_heap_ids.empty()) { - descriptor_heap_ids = &bundle_target_drawcall->descriptor_heap_ids; + descriptor_heap_ids = &bundle_target_draw_call->descriptor_heap_ids; } else { descriptor_heap_ids = &track_dump_resources_.target.descriptor_heap_ids; } - if (bundle_target_drawcall && !bundle_target_drawcall->captured_descriptor_gpu_handles.empty()) + if (bundle_target_draw_call && !bundle_target_draw_call->captured_descriptor_gpu_handles.empty()) { - descriptor_gpu_handles = &bundle_target_drawcall->captured_descriptor_gpu_handles; + descriptor_gpu_handles = &bundle_target_draw_call->captured_descriptor_gpu_handles; } else { @@ -679,7 +671,7 @@ void Dx12DumpResources::CopyDrawcallResources(DxObjectInfo* { json_path_sub = json_path; json_path_sub.emplace_back("constant_buffer_views", resource_index); - CopyDrawcallResourceByGPUVA(queue_object_info, + CopyDrawCallResourceByGPUVA(queue_object_info, front_command_list_ids, info.captured_view.BufferLocation, info.captured_view.SizeInBytes, @@ -725,7 +717,7 @@ void Dx12DumpResources::CopyDrawcallResources(DxObjectInfo* } json_path_sub = json_path; json_path_sub.emplace_back("shader_resource_views", resource_index); - CopyDrawcallResourceBySubresource(queue_object_info, + CopyDrawCallResourceBySubresource(queue_object_info, front_command_list_ids, info.resource_id, offset, @@ -772,7 +764,7 @@ void Dx12DumpResources::CopyDrawcallResources(DxObjectInfo* 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, + CopyDrawCallResourceBySubresource(queue_object_info, front_command_list_ids, info.resource_id, offset, @@ -789,7 +781,7 @@ void Dx12DumpResources::CopyDrawcallResources(DxObjectInfo* 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, + CopyDrawCallResourceBySubresource(queue_object_info, front_command_list_ids, info.counter_resource_id, info.view.Buffer.CounterOffsetInBytes, @@ -840,7 +832,7 @@ void Dx12DumpResources::CopyDrawcallResources(DxObjectInfo* } json_path.clear(); json_path.emplace_back("render_target_views", resource_index); - CopyDrawcallResourceBySubresource(queue_object_info, + CopyDrawCallResourceBySubresource(queue_object_info, front_command_list_ids, info.resource_id, 0, @@ -873,7 +865,7 @@ void Dx12DumpResources::CopyDrawcallResources(DxObjectInfo* { json_path.clear(); json_path.emplace_back("depth_stencil_views", format::kNoneIndex); - CopyDrawcallResourceBySubresource(queue_object_info, + CopyDrawCallResourceBySubresource(queue_object_info, front_command_list_ids, info.resource_id, 0, @@ -891,9 +883,9 @@ void Dx12DumpResources::CopyDrawcallResources(DxObjectInfo* // ExecuteIndirect const ExecuteIndirectInfo* exe_indirect_info = nullptr; - if (bundle_target_drawcall && bundle_target_drawcall->execute_indirect_info.argument_id != format::kNullHandleId) + if (bundle_target_draw_call && bundle_target_draw_call->execute_indirect_info.argument_id != format::kNullHandleId) { - exe_indirect_info = &bundle_target_drawcall->execute_indirect_info; + exe_indirect_info = &bundle_target_draw_call->execute_indirect_info; } else { @@ -903,7 +895,7 @@ void Dx12DumpResources::CopyDrawcallResources(DxObjectInfo* { json_path.clear(); json_path.emplace_back("execute_indirect_arguments", format::kNoneIndex); - CopyDrawcallResourceBySubresource(queue_object_info, + CopyDrawCallResourceBySubresource(queue_object_info, front_command_list_ids, exe_indirect_info->argument_id, exe_indirect_info->argument_offset, @@ -916,7 +908,7 @@ void Dx12DumpResources::CopyDrawcallResources(DxObjectInfo* 0); json_path.clear(); json_path.emplace_back("execute_indirect_counts", format::kNoneIndex); - CopyDrawcallResourceBySubresource(queue_object_info, + CopyDrawCallResourceBySubresource(queue_object_info, front_command_list_ids, exe_indirect_info->count_id, exe_indirect_info->count_offset, @@ -930,13 +922,13 @@ void Dx12DumpResources::CopyDrawcallResources(DxObjectInfo* } } -void Dx12DumpResources::CopyDrawcallResourceByGPUVA(DxObjectInfo* queue_object_info, +void 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, const std::vector>& json_path, Dx12DumpResourceType resource_type, - Dx12DumpResourcePos pos, + graphics::dx12::Dx12DumpResourcePos pos, format::HandleId descriptor_heap_id, uint32_t descriptor_heap_index) { @@ -948,7 +940,7 @@ void Dx12DumpResources::CopyDrawcallResourceByGPUVA(DxObjectInfo* 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, + CopyDrawCallResourceBySubresource(queue_object_info, front_command_list_ids, source_resource_id, (captured_source_gpu_va - source_resource_extra_info->capture_address_), @@ -961,17 +953,17 @@ void Dx12DumpResources::CopyDrawcallResourceByGPUVA(DxObjectInfo* descriptor_heap_index); } -void Dx12DumpResources::CopyDrawcallResourceBySubresource(DxObjectInfo* queue_object_info, +void Dx12DumpResources::CopyDrawCallResourceBySubresource(DxObjectInfo* queue_object_info, const std::vector& front_command_list_ids, format::HandleId source_resource_id, uint64_t source_offset, uint64_t source_size, const std::vector& subresource_indices, const std::vector>& json_path, - Dx12DumpResourceType resource_type, - Dx12DumpResourcePos pos, - format::HandleId descriptor_heap_id, - uint32_t descriptor_heap_index) + Dx12DumpResourceType resource_type, + graphics::dx12::Dx12DumpResourcePos pos, + format::HandleId descriptor_heap_id, + uint32_t descriptor_heap_index) { CopyResourceDataPtr copy_resource_data(new CopyResourceData()); copy_resource_data->subresource_indices = subresource_indices; @@ -981,12 +973,12 @@ void Dx12DumpResources::CopyDrawcallResourceBySubresource(DxObjectInfo* copy_resource_data->descriptor_heap_id = descriptor_heap_id; copy_resource_data->descriptor_heap_index = descriptor_heap_index; - CopyDrawcallResource( + CopyDrawCallResource( queue_object_info, front_command_list_ids, source_resource_id, source_offset, source_size, copy_resource_data); } // If source_size = 0, the meaning is the whole after offset. -void Dx12DumpResources::CopyDrawcallResource(DxObjectInfo* queue_object_info, +void Dx12DumpResources::CopyDrawCallResource(DxObjectInfo* queue_object_info, const std::vector& front_command_list_ids, format::HandleId source_resource_id, uint64_t source_offset, @@ -1128,7 +1120,7 @@ bool Dx12DumpResources::CopyResourceAsyncQueue(const std::vector track_dump_resources_.target.drawcall_block_index) + if (state.block_index > track_dump_resources_.target.draw_call_block_index) { is_update = false; } @@ -1294,33 +1286,32 @@ QueueSyncEventInfo Dx12DumpResources::CreateCopyResourceAsyncReadQueueSyncEvent( } }; } -std::vector Dx12DumpResources::GetCommandListsForDumpResources(DxObjectInfo* command_list_object_info, - uint64_t block_index, - format::ApiCallId api_call_id) +std::vector Dx12DumpResources::GetCommandListsForDumpResources( + DxObjectInfo* command_list_object_info, uint64_t block_index, format::ApiCallId api_call_id) { - std::vector cmd_sets; - auto cmd_list_extra_info = GetExtraInfo(command_list_object_info); - auto cmd_list = static_cast(command_list_object_info->object); - auto device = graphics::dx12::GetDeviceComPtrFromChild(cmd_list); - - std::array* command_sets = nullptr; - TrackDumpDrawcall* drawcall_info = nullptr; - bool is_bundle = false; + std::vector cmd_sets; + auto cmd_list_extra_info = GetExtraInfo(command_list_object_info); + auto cmd_list = static_cast(command_list_object_info->object); + auto device = graphics::dx12::GetDeviceComPtrFromChild(cmd_list); + + std::array* command_sets = nullptr; + TrackDumpDrawCall* draw_call_info = nullptr; + bool is_bundle = false; if ((command_list_object_info->capture_id == track_dump_resources_.target.bundle_commandlist_id) && - (track_dump_resources_.target.bundle_target_drawcall != nullptr) && - (track_dump_resources_.target.bundle_target_drawcall->begin_block_index <= block_index) && - (track_dump_resources_.target.bundle_target_drawcall->close_block_index >= block_index)) + (track_dump_resources_.target.bundle_target_draw_call != nullptr) && + (track_dump_resources_.target.bundle_target_draw_call->begin_block_index <= block_index) && + (track_dump_resources_.target.bundle_target_draw_call->close_block_index >= block_index)) { - is_bundle = true; - command_sets = &track_dump_resources_.split_bundle_command_sets; - drawcall_info = track_dump_resources_.target.bundle_target_drawcall.get(); + is_bundle = true; + command_sets = &track_dump_resources_.split_bundle_command_sets; + draw_call_info = track_dump_resources_.target.bundle_target_draw_call.get(); } else if ((command_list_object_info->capture_id == track_dump_resources_.target.command_list_id) && (track_dump_resources_.target.begin_block_index <= block_index) && (track_dump_resources_.target.close_block_index >= block_index)) { command_sets = &track_dump_resources_.split_command_sets; - drawcall_info = &track_dump_resources_.target; + draw_call_info = &track_dump_resources_.target; } else { @@ -1343,18 +1334,18 @@ std::vector Dx12DumpResources::GetCommandListsForDumpResources(DxObj } } - Dx12DumpResourcePos split_type = Dx12DumpResourcePos::kBeforeDrawCall; + graphics::dx12::Dx12DumpResourcePos split_type = graphics::dx12::Dx12DumpResourcePos::kBeforeDrawCall; - if (block_index == drawcall_info->drawcall_block_index) + if (block_index == draw_call_info->draw_call_block_index) { - split_type = Dx12DumpResourcePos::kDrawCall; + split_type = graphics::dx12::Dx12DumpResourcePos::kDrawCall; } - else if (block_index >= drawcall_info->drawcall_block_index) + else if (block_index > draw_call_info->draw_call_block_index) { - split_type = Dx12DumpResourcePos::kAfterDrawCall; + split_type = graphics::dx12::Dx12DumpResourcePos::kAfterDrawCall; } - auto split_type_array_index = Dx12DumpResourcePosToArrayIndex(split_type); + auto split_type_array_index = graphics::dx12::Dx12DumpResourcePosToArrayIndex(split_type); // Here is to split command lists. switch (api_call_id) @@ -1369,9 +1360,11 @@ std::vector Dx12DumpResources::GetCommandListsForDumpResources(DxObj } break; } - // It has to ensure that the splited command list has a pair of BeginQuery and EndQuery. + // It has to ensure that the splited command list has a pair of Queries and Events. case format::ApiCall_ID3D12GraphicsCommandList_BeginQuery: case format::ApiCall_ID3D12GraphicsCommandList_EndQuery: + case format::ApiCall_ID3D12GraphicsCommandList_BeginEvent: + case format::ApiCall_ID3D12GraphicsCommandList_EndEvent: case format::ApiCall_ID3D12GraphicsCommandList_Close: { cmd_sets.insert(cmd_sets.end(), command_sets->begin(), command_sets->end()); @@ -1415,12 +1408,12 @@ std::vector Dx12DumpResources::GetCommandListsForDumpResources(DxObj { switch (split_type) { - case Dx12DumpResourcePos::kBeforeDrawCall: + case graphics::dx12::Dx12DumpResourcePos::kBeforeDrawCall: cmd_sets.insert(cmd_sets.end(), command_sets->begin(), command_sets->end()); break; // But if the command is after DrawCall, it's just added at the third CommandList. - case Dx12DumpResourcePos::kAfterDrawCall: - cmd_sets.emplace_back((*command_sets)[kAfterDrawCallArrayIndex]); + case graphics::dx12::Dx12DumpResourcePos::kAfterDrawCall: + cmd_sets.emplace_back((*command_sets)[graphics::dx12::kAfterDrawCallArrayIndex]); break; default: break; @@ -1429,7 +1422,7 @@ std::vector Dx12DumpResources::GetCommandListsForDumpResources(DxObj } case format::ApiCall_ID3D12GraphicsCommandList4_BeginRenderPass: { - if (block_index == drawcall_info->begin_renderpass_block_index) + if (block_index == draw_call_info->begin_renderpass_block_index) { cmd_sets.insert(cmd_sets.end(), command_sets->begin(), command_sets->end()); } @@ -1441,7 +1434,7 @@ std::vector Dx12DumpResources::GetCommandListsForDumpResources(DxObj } case format::ApiCall_ID3D12GraphicsCommandList4_EndRenderPass: { - if (block_index == drawcall_info->end_renderpass_block_index) + if (block_index == draw_call_info->end_renderpass_block_index) { cmd_sets.insert(cmd_sets.end(), command_sets->begin(), command_sets->end()); } @@ -1453,7 +1446,7 @@ std::vector Dx12DumpResources::GetCommandListsForDumpResources(DxObj } case format::ApiCall_ID3D12GraphicsCommandList_ExecuteBundle: { - if (block_index == drawcall_info->drawcall_block_index) + if (block_index == draw_call_info->draw_call_block_index) { cmd_sets.insert(cmd_sets.end(), command_sets->begin(), command_sets->end()); } @@ -1465,7 +1458,7 @@ std::vector Dx12DumpResources::GetCommandListsForDumpResources(DxObj } default: { - // command type could be changed data, drawcalls. + // command type could be changed data, draw calls. cmd_sets.emplace_back((*command_sets)[split_type_array_index]); break; } @@ -1496,10 +1489,10 @@ void DefaultDx12DumpResourcesDelegate::BeginDumpResources(const std::string& header_["gfxreconversion"] = GFXRECON_PROJECT_VERSION_STRING; header_["captureFile"] = capture_file_name; - auto& dr_options = header_["dumpResourcesOptions"]; - dr_options["submit"] = std::to_string(track_dump_resources.target.dump_resources_target.submit_index); - dr_options["command"] = std::to_string(track_dump_resources.target.dump_resources_target.command_index); - dr_options["drawcall"] = std::to_string(track_dump_resources.target.dump_resources_target.drawcall_index); + auto& dr_options = header_["dumpResourcesOptions"]; + dr_options["submit"] = std::to_string(track_dump_resources.target.dump_resources_target.submit_index); + dr_options["command"] = std::to_string(track_dump_resources.target.dump_resources_target.command_index); + dr_options["draw_call"] = std::to_string(track_dump_resources.target.dump_resources_target.draw_call_index); StartFile(); @@ -1510,8 +1503,8 @@ void DefaultDx12DumpResourcesDelegate::BeginDumpResources(const std::string& WriteBlockStart(); - util::FieldToJson(drawcall_["block_index"], track_dump_resources.target.drawcall_block_index, json_options_); - util::FieldToJson(drawcall_["execute_block_index"], track_dump_resources.target.execute_block_index, json_options_); + util::FieldToJson(draw_call_["block_index"], track_dump_resources.target.draw_call_block_index, json_options_); + util::FieldToJson(draw_call_["execute_block_index"], track_dump_resources.target.execute_block_index, json_options_); } void DefaultDx12DumpResourcesDelegate::DumpResource(CopyResourceDataPtr resource_data) @@ -1521,7 +1514,7 @@ void DefaultDx12DumpResourcesDelegate::DumpResource(CopyResourceDataPtr resource void DefaultDx12DumpResourcesDelegate::EndDumpResources() { - json_data_[NameDrawCall()] = drawcall_; + json_data_[NameDrawCall()] = draw_call_; WriteBlockEnd(); EndFile(); } @@ -1533,7 +1526,7 @@ void DefaultDx12DumpResourcesDelegate::WriteResource(const CopyResourceDataPtr r return; } - auto* jdata_sub = &drawcall_; + auto* jdata_sub = &draw_call_; for (const auto& path : resource_data->json_path) { if (path.second == format::kNoneIndex) @@ -1664,10 +1657,10 @@ void DefaultDx12DumpResourcesDelegate::TestWriteImageResource(const std::string& { 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 %" PRIu32 - " is %.2f bytes per pixel.", + "with 4 bytes per pixel are supported. Current format %s " + "is %.2f bytes per pixel.", file_name_sub.c_str(), - resource_data->footprints[sub_index].Footprint.Format, + util::ToString(resource_data->footprints[sub_index].Footprint.Format).c_str(), bytes_per_pixel); continue; } diff --git a/framework/decode/dx12_dump_resources.h b/framework/decode/dx12_dump_resources.h index be9cf7018..6dd959d30 100644 --- a/framework/decode/dx12_dump_resources.h +++ b/framework/decode/dx12_dump_resources.h @@ -58,14 +58,6 @@ enum class Dx12DumpResourceType : uint32_t kExecuteIndirectCount, }; -enum class Dx12DumpResourcePos : uint32_t -{ - kUnknown, - kBeforeDrawCall, - kDrawCall, - kAfterDrawCall, -}; - struct CopyResourceData { // Allow default constructor, disallow copy constructor. @@ -83,7 +75,7 @@ struct CopyResourceData uint64_t total_size{ 0 }; bool is_cpu_accessible{ false }; - std::vector> datas; // copy resource drawcall + std::vector> datas; // copy resource draw call graphics::dx12::ID3D12GraphicsCommandListComPtr cmd_list{ nullptr }; graphics::dx12::ID3D12ResourceComPtr read_resource{ nullptr }; @@ -91,7 +83,7 @@ struct CopyResourceData std::vector> json_path; Dx12DumpResourceType resource_type{ Dx12DumpResourceType::kUnknown }; - Dx12DumpResourcePos dump_position{ Dx12DumpResourcePos::kUnknown }; + graphics::dx12::Dx12DumpResourcePos dump_position{ graphics::dx12::Dx12DumpResourcePos::kUnknown }; format::HandleId descriptor_heap_id{ format::kNullHandleId }; uint32_t descriptor_heap_index{ 0 }; @@ -113,7 +105,7 @@ struct CopyResourceData read_resource = nullptr; read_resource_is_staging_buffer = false; resource_type = Dx12DumpResourceType::kUnknown; - dump_position = Dx12DumpResourcePos::kUnknown; + dump_position = graphics::dx12::Dx12DumpResourcePos::kUnknown; descriptor_heap_id = format::kUnknown; descriptor_heap_index = 0; } @@ -121,15 +113,9 @@ struct CopyResourceData typedef std::shared_ptr CopyResourceDataPtr; -struct CommandSet -{ - graphics::dx12::ID3D12CommandAllocatorComPtr allocator; - graphics::dx12::ID3D12GraphicsCommandListComPtr list; -}; - struct TrackDumpResources { - TrackDumpDrawcall target{}; + TrackDumpDrawCall target{}; // render target std::vector render_target_heap_ids; @@ -141,8 +127,8 @@ struct TrackDumpResources graphics::dx12::ID3D12ResourceComPtr copy_staging_buffer{ nullptr }; uint64_t copy_staging_buffer_size{ 0 }; - std::array split_command_sets; - std::array split_bundle_command_sets; + std::array split_command_sets; + std::array split_bundle_command_sets; graphics::dx12::ID3D12FenceComPtr fence; HANDLE fence_event; @@ -189,7 +175,7 @@ class DefaultDx12DumpResourcesDelegate : public Dx12DumpResourcesDelegate void WriteBlockStart(); void WriteBlockEnd(); - constexpr const char* NameDrawCall() const { return "drawcall"; } + constexpr const char* NameDrawCall() const { return "draw_call"; } bool WriteBinaryFile(const std::string& filename, const std::vector& data, uint64_t offset, uint64_t size); @@ -204,7 +190,7 @@ class DefaultDx12DumpResourcesDelegate : public Dx12DumpResourcesDelegate FILE* json_file_handle_{ nullptr }; nlohmann::ordered_json json_data_; nlohmann::ordered_json header_; - nlohmann::ordered_json drawcall_; + nlohmann::ordered_json draw_call_; uint32_t num_objects_{ 0 }; uint32_t num_files_{ 0 }; }; @@ -220,11 +206,11 @@ class Dx12DumpResources void SetDelegate(Dx12DumpResourcesDelegate* delegate) { user_delegate_ = delegate; } - std::vector GetCommandListsForDumpResources(DxObjectInfo* command_list_object_info, - uint64_t block_index, - format::ApiCallId api_call_id); + std::vector GetCommandListsForDumpResources(DxObjectInfo* command_list_object_info, + uint64_t block_index, + format::ApiCallId api_call_id); - inline void SetDumpTarget(TrackDumpDrawcall& track_dump_target) + inline void SetDumpTarget(TrackDumpDrawCall& track_dump_target) { track_dump_resources_.target = track_dump_target; } @@ -261,21 +247,21 @@ class Dx12DumpResources void FinishDump(DxObjectInfo* queue_object_info); void CloseDump(); - void CopyDrawcallResources(DxObjectInfo* queue_object_info, + void CopyDrawCallResources(DxObjectInfo* queue_object_info, const std::vector& front_command_list_ids, - Dx12DumpResourcePos pos); + graphics::dx12::Dx12DumpResourcePos pos); - void CopyDrawcallResourceByGPUVA(DxObjectInfo* queue_object_info, + void CopyDrawCallResourceByGPUVA(DxObjectInfo* queue_object_info, const std::vector& front_command_list_ids, D3D12_GPU_VIRTUAL_ADDRESS capture_source_gpu_va, uint64_t source_size, const std::vector>& json_path, Dx12DumpResourceType resource_type, - Dx12DumpResourcePos pos, + graphics::dx12::Dx12DumpResourcePos pos, format::HandleId descriptor_heap_id, uint32_t descriptor_heap_index); - void CopyDrawcallResourceBySubresource(DxObjectInfo* queue_object_info, + void CopyDrawCallResourceBySubresource(DxObjectInfo* queue_object_info, const std::vector& front_command_list_ids, format::HandleId source_resource_id, uint64_t source_offset, @@ -283,11 +269,11 @@ class Dx12DumpResources const std::vector& subresource_indices, const std::vector>& json_path, Dx12DumpResourceType resource_type, - Dx12DumpResourcePos pos, + graphics::dx12::Dx12DumpResourcePos pos, format::HandleId descriptor_heap_id, uint32_t descriptor_heap_index); - void CopyDrawcallResource(DxObjectInfo* queue_object_info, + void CopyDrawCallResource(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 24aa5c002..2198fffde 100644 --- a/framework/decode/dx12_object_info.h +++ b/framework/decode/dx12_object_info.h @@ -228,6 +228,7 @@ struct DxgiSwapchainInfo : DxObjectExtraInfo static constexpr char kObjectType[] = "IDXGISwapChain"; DxgiSwapchainInfo() : DxObjectExtraInfo(kType) {} + uint32_t init_buffer_index{ 0 }; Window* window{ nullptr }; ///< Pointer to the platform-specific window object associated with the swapchain. uint64_t hwnd_id{ 0 }; ///< Capture ID for the HWND handle used with swapchain creation. @@ -386,6 +387,7 @@ struct D3D12ResourceInfo : DxObjectExtraInfo D3D12_RESOURCE_DESC1 desc = {}; format::HandleId swap_chain_id{ format::kNullHandleId }; + uint32_t buffer_index{ 0 }; size_t subresource_count{ 0 }; std::vector resource_state_infos; diff --git a/framework/decode/dx12_replay_consumer_base.cpp b/framework/decode/dx12_replay_consumer_base.cpp index 7c2e1eda5..e2ef484f5 100644 --- a/framework/decode/dx12_replay_consumer_base.cpp +++ b/framework/decode/dx12_replay_consumer_base.cpp @@ -365,26 +365,115 @@ void Dx12ReplayConsumerBase::ApplyBatchedResourceInitInfo( GFXRECON_ASSERT(resource_data_util_); if (resource_infos.size() > 0) { - resource_data_util_->ResetCommandList(); - for (auto resource_info : resource_infos) + std::unordered_map swapchain_resource_infos; + std::unordered_map others_resource_infos; + + for (auto& resource_info : resource_infos) { + auto object_info = GetObjectInfo(resource_info.second.resource_id); + if (object_info->extra_info != nullptr) + { + auto extra_info = GetExtraInfo(object_info); + if (extra_info->swap_chain_id != format::kNullHandleId) + { + swapchain_resource_infos.insert(std::pair(resource_info.first, &resource_info.second)); + } + else + { + others_resource_infos.insert(std::pair(resource_info.first, &resource_info.second)); + } + } + } + + // For copy swapchain buffers: + // 1. The queue has to been swapchain's queue. + // 2. One ExecuteCommandLists could work for only one swapchain buffer. + // 3. The current back buffer index has to match the swapchain buffer. + // 4. After ExecuteCommandLists, the current back buffer index has to back init. + // 5. It shouldn't change resource states until all Presnt are done since Present require + // D3D12_RESOURCE_STATE_PRESENT. The before_states supposes to be PRESENT. + + // Although it has only one swapchain mostly, it probably has a plural in some cases. + std::map swapchain_infos; + for (const auto& resource_info : swapchain_resource_infos) + { + auto object_info = GetObjectInfo(resource_info.second->resource_id); + auto extra_info = GetExtraInfo(object_info); + auto swapchain_info = GetObjectInfo(extra_info->swap_chain_id); + auto swapchain_extra_info = GetExtraInfo(swapchain_info); + auto swapchain = reinterpret_cast(swapchain_info->object); + swapchain_infos[swapchain] = swapchain_extra_info; + + for (auto &state : resource_info.second->before_states) + { + if (state.states != D3D12_RESOURCE_STATE_PRESENT) + { + GFXRECON_LOG_WARNING( + "Initializing Swapchain Buffers. The before state supposed to be COMMON|PRESENT, but it's %s", + util::ToString(state.states)); + } + } + + while (extra_info->buffer_index != swapchain->GetCurrentBackBufferIndex()) + { + swapchain->Present(0, 0); + } + + resource_data_util_->ResetCommandList(); if (resource_info.first != nullptr) { - resource_data_util_->WriteToResource(resource_info.second.resource, - resource_info.second.try_map_and_copy, - resource_info.second.before_states, - resource_info.second.after_states, - resource_info.second.data, - resource_info.second.subresource_offsets, - resource_info.second.subresource_sizes, - resource_info.second.staging_resource); + resource_data_util_->WriteToResource(resource_info.second->resource, + resource_info.second->try_map_and_copy, + resource_info.second->before_states, + resource_info.second->before_states, + resource_info.second->data, + resource_info.second->subresource_offsets, + resource_info.second->subresource_sizes, + resource_info.second->staging_resource); } - auto object_info = GetObjectInfo(resource_info.second.resource_id); - if (object_info->extra_info != nullptr) + extra_info->resource_state_infos = resource_info.second->after_states; + resource_data_util_->CloseCommandList(); + resource_data_util_->ExecuteAndWaitForCommandList(swapchain_extra_info->command_queue); + } + + for (const auto& info : swapchain_infos) + { + while (info.second->init_buffer_index != info.first->GetCurrentBackBufferIndex()) + { + info.first->Present(0, 0); + } + } + + for (const auto& resource_info : swapchain_resource_infos) + { + auto object_info = GetObjectInfo(resource_info.second->resource_id); + auto extra_info = GetExtraInfo(object_info); + auto swapchain_info = GetObjectInfo(extra_info->swap_chain_id); + auto swapchain_extra_info = GetExtraInfo(swapchain_info); + + resource_data_util_->ExecuteTransitionCommandList(resource_info.second->resource, + resource_info.second->before_states, + resource_info.second->after_states, + swapchain_extra_info->command_queue); + } + + resource_data_util_->ResetCommandList(); + for (const auto& resource_info : others_resource_infos) + { + if (resource_info.first != nullptr) { - auto extra_info = GetExtraInfo(object_info); - extra_info->resource_state_infos = resource_info.second.after_states; + resource_data_util_->WriteToResource(resource_info.second->resource, + resource_info.second->try_map_and_copy, + resource_info.second->before_states, + resource_info.second->after_states, + resource_info.second->data, + resource_info.second->subresource_offsets, + resource_info.second->subresource_sizes, + resource_info.second->staging_resource); } + auto object_info = GetObjectInfo(resource_info.second->resource_id); + auto extra_info = GetExtraInfo(object_info); + extra_info->resource_state_infos = resource_info.second->after_states; } resource_data_util_->CloseCommandList(); resource_data_util_->ExecuteAndWaitForCommandList(); @@ -527,7 +616,9 @@ void Dx12ReplayConsumerBase::ProcessSetSwapchainImageStateQueueSubmit(ID3D12Comm HRESULT ret = command_queue->GetDevice(IID_PPV_ARGS(&device)); GFXRECON_ASSERT(SUCCEEDED(ret)); - auto swapchain = static_cast(swapchain_info->object); + auto swapchain_extra_info = GetExtraInfo(swapchain_info); + swapchain_extra_info->init_buffer_index = current_buffer_index; + auto swapchain = static_cast(swapchain_info->object); DXGI_SWAP_CHAIN_DESC swap_chain_desc; swapchain->GetDesc(&swap_chain_desc); auto buffer_count = swap_chain_desc.BufferCount; @@ -633,7 +724,7 @@ void Dx12ReplayConsumerBase::RemoveObject(DxObjectInfo* info) } } -void Dx12ReplayConsumerBase::SetDumpTarget(TrackDumpDrawcall& track_dump_target) +void Dx12ReplayConsumerBase::SetDumpTarget(TrackDumpDrawCall& track_dump_target) { if (!dump_resources_) { @@ -2419,6 +2510,9 @@ HRESULT Dx12ReplayConsumerBase::OverrideGetBuffer(DxObjectInfo* r // object info table while the swapchain is active. ++object_info->extra_ref; + auto res_info = GetExtraInfo(object_info); + res_info->swap_chain_id = replay_object_info->capture_id; + res_info->buffer_index = buffer; // Store the surface's HandleId so the reference can be released later. swapchain_info->image_ids[buffer] = *surface->GetPointer(); } @@ -4316,8 +4410,8 @@ void Dx12ReplayConsumerBase::PreCall_ID3D12GraphicsCommandList_ResourceBarrier( { // It shouldn't change the state here. It should save the AfterState until ExecuteCommandList to change // it. It needs to record the code index. The reason is that it needs to know if this ResourceBarrier is - // before or after the target drawcall. For dump resources to set the correct state, - // it only cares before the target drawcall. + // before or after the target draw call. For dump resources to set the correct state, + // it only cares before the target draw call. ResourceStatesOrder state; state.block_index = call_info.index; state.transition = *barriers[i].Transition->decoded_value; diff --git a/framework/decode/dx12_replay_consumer_base.h b/framework/decode/dx12_replay_consumer_base.h index be975246e..17c25a17c 100644 --- a/framework/decode/dx12_replay_consumer_base.h +++ b/framework/decode/dx12_replay_consumer_base.h @@ -233,7 +233,7 @@ class Dx12ReplayConsumerBase : public Dx12Consumer void RemoveObject(DxObjectInfo* info); - void SetDumpTarget(TrackDumpDrawcall& track_dump_target); + void SetDumpTarget(TrackDumpDrawCall& track_dump_target); IDXGIAdapter* GetAdapter(); diff --git a/framework/decode/dx_replay_options.h b/framework/decode/dx_replay_options.h index dd4faf17b..43bd47b58 100644 --- a/framework/decode/dx_replay_options.h +++ b/framework/decode/dx_replay_options.h @@ -43,7 +43,7 @@ struct DumpResourcesTarget { uint32_t submit_index{ 0 }; uint32_t command_index{ 0 }; - uint32_t drawcall_index{ 0 }; + uint32_t draw_call_index{ 0 }; }; struct DxReplayOptions : public ReplayOptions diff --git a/framework/encode/api_capture_manager.h b/framework/encode/api_capture_manager.h index f4ed593f9..0042211d5 100644 --- a/framework/encode/api_capture_manager.h +++ b/framework/encode/api_capture_manager.h @@ -211,6 +211,8 @@ class ApiCaptureManager util::Keyboard& GetKeyboard() { return common_manager_->GetKeyboard(); } const std::string& GetScreenshotPrefix() const { return common_manager_->GetScreenshotPrefix(); } util::ScreenshotFormat GetScreenshotFormat() { return common_manager_->GetScreenshotFormat(); } + auto GetTrimBoundary() const { return common_manager_->GetTrimBoundary(); } + auto GetTrimDrawCalls() const { return common_manager_->GetTrimDrawCalls(); } protected: const format::ApiFamilyId api_family_; diff --git a/framework/encode/capture_manager.cpp b/framework/encode/capture_manager.cpp index e731508dc..24770710f 100644 --- a/framework/encode/capture_manager.cpp +++ b/framework/encode/capture_manager.cpp @@ -354,7 +354,7 @@ bool CommonCaptureManager::Initialize(format::ApiFamilyId api_ // External memory takes precedence over shadow memory modes. if (use_external_memory) { - page_guard_memory_mode_ = kMemoryModeExternal; + page_guard_memory_mode_ = kMemoryModeExternal; page_guard_external_memory_ = true; } else if (trace_settings.page_guard_persistent_memory) @@ -374,6 +374,7 @@ bool CommonCaptureManager::Initialize(format::ApiFamilyId api_ } if (trace_settings.trim_ranges.empty() && trace_settings.trim_key.empty() && + trace_settings.trim_boundary != CaptureSettings::TrimBoundary::kDrawCalls && trace_settings.runtime_capture_trigger == CaptureSettings::RuntimeTriggerState::kNotUsed) { // Use default kModeWrite capture mode. @@ -394,6 +395,13 @@ bool CommonCaptureManager::Initialize(format::ApiFamilyId api_ GFXRECON_ASSERT((trim_boundary_ == CaptureSettings::TrimBoundary::kFrames) || (trim_boundary_ == CaptureSettings::TrimBoundary::kQueueSubmits)); + if (trim_boundary_ == CaptureSettings::TrimBoundary::kQueueSubmits) + { + GFXRECON_LOG_WARNING("Capture has enabled the GFXRECON_CAPTURE_QUEUE_SUBMITS option. This option " + "currently uses 1-based indexing to identify the queue submit range. In the " + "future it will be switched to 0-based indexing."); + } + trim_ranges_ = trace_settings.trim_ranges; // Determine if trim starts at the first frame @@ -439,6 +447,11 @@ bool CommonCaptureManager::Initialize(format::ApiFamilyId api_ capture_mode_ = kModeTrack; } } + else if (trim_boundary_ == CaptureSettings::TrimBoundary::kDrawCalls) + { + trim_draw_calls_ = trace_settings.trim_draw_calls; + capture_mode_ = kModeTrack; + } else { // if/else blocks above should have covered all "else" cases from the parent conditional. @@ -740,6 +753,30 @@ void CommonCaptureManager::CheckContinueCaptureForWriteMode(format::ApiFamilyId } } +void CommonCaptureManager::DeactivateTrimmingDrawCalls(std::shared_lock& current_lock) +{ + if (trim_enabled_) + { + if ((capture_mode_ & kModeWrite) == kModeWrite) + { + // Stop recording and close file. + DeactivateTrimming(current_lock); + GFXRECON_LOG_INFO("Finished recording graphics API capture"); + + // No more trim ranges to capture. Capture can be disabled and resources can be released. + trim_enabled_ = false; + trim_boundary_ = CaptureSettings::TrimBoundary::kUnknown; + capture_mode_ = kModeDisabled; + // Clean up all of the capture manager's state trackers + for (auto& manager_it : api_capture_managers_) + { + manager_it.first->DestroyStateTracker(); + } + compressor_ = nullptr; + } + } +} + void CommonCaptureManager::CheckStartCaptureForTrackMode(format::ApiFamilyId api_family, uint32_t current_boundary_count, std::shared_lock& current_lock) @@ -781,6 +818,25 @@ void CommonCaptureManager::CheckStartCaptureForTrackMode(format::ApiFamilyId } } +void CommonCaptureManager::ActivateTrimmingDrawCalls(format::ApiFamilyId api_family, + std::shared_lock& current_lock) +{ + if (((capture_mode_ & kModeWrite) != kModeWrite) && ((capture_mode_ & kModeTrack) == kModeTrack)) + { + bool success = CreateCaptureFile(api_family, CreateTrimDrawCallsFilename(base_filename_, trim_draw_calls_)); + if (success) + { + ActivateTrimming(current_lock); + } + else + { + GFXRECON_LOG_FATAL("Failed to initialize capture for trim draw calls; capture has been disabled"); + trim_enabled_ = false; + capture_mode_ = kModeDisabled; + } + } +} + bool CommonCaptureManager::ShouldTriggerScreenshot() { bool triger_screenshot = false; @@ -862,6 +918,8 @@ void CommonCaptureManager::EndFrame(format::ApiFamilyId api_family, std::shared_ void CommonCaptureManager::PreQueueSubmit(format::ApiFamilyId api_family, std::shared_lock& current_lock) { + // ++ here means it's 1-based. When it changes to 0-based, it needs to move to the bottom of + // CommonCaptureManager::PostQueueSubmit and make sure trimming kQueueSubmits and kDrawCalls work correctly. ++queue_submit_count_; if (trim_enabled_ && (trim_boundary_ == CaptureSettings::TrimBoundary::kQueueSubmits)) @@ -922,6 +980,36 @@ std::string CommonCaptureManager::CreateTrimFilename(const std::string& base return util::filepath::InsertFilenamePostfix(base_filename, range_string); } +std::string CommonCaptureManager::CreateTrimDrawCallsFilename(const std::string& base_filename, + const CaptureSettings::TrimDrawCalls& trim_draw_calls) +{ + std::string range_string = "_"; + + uint32_t total = trim_draw_calls.draw_call_indices.last - trim_draw_calls.draw_call_indices.first + 1; + uint32_t bundle_total = + trim_draw_calls.bundle_draw_call_indices.last - trim_draw_calls.bundle_draw_call_indices.first + 1; + const char* boundary_str = (total > 1 || bundle_total > 1) ? "draw_calls_" : "draw_call_"; + + range_string += boundary_str; + range_string += std::to_string(trim_draw_calls.submit_index) + "_" + std::to_string(trim_draw_calls.command_index) + + "_" + std::to_string(trim_draw_calls.draw_call_indices.first); + if (total > 1) + { + range_string += "_through_"; + range_string += std::to_string(trim_draw_calls.draw_call_indices.last); + } + + range_string += "_" + std::to_string(trim_draw_calls.bundle_draw_call_indices.first); + + if (bundle_total > 1) + { + range_string += "_through_"; + range_string += std::to_string(trim_draw_calls.bundle_draw_call_indices.last); + } + + return util::filepath::InsertFilenamePostfix(base_filename, range_string); +} + bool CommonCaptureManager::CreateCaptureFile(format::ApiFamilyId api_family, const std::string& base_filename) { bool success = true; diff --git a/framework/encode/capture_manager.h b/framework/encode/capture_manager.h index 9dffe9b4d..db8f52db8 100644 --- a/framework/encode/capture_manager.h +++ b/framework/encode/capture_manager.h @@ -136,6 +136,10 @@ class CommonCaptureManager uint32_t current_boundary_count, std::shared_lock& current_lock); + void ActivateTrimmingDrawCalls(format::ApiFamilyId api_family, std::shared_lock& current_lock); + + void DeactivateTrimmingDrawCalls(std::shared_lock& current_lock); + bool IsTrimHotkeyPressed(); CaptureSettings::RuntimeTriggerState GetRuntimeTriggerState(); @@ -261,6 +265,9 @@ class CommonCaptureManager bool GetDisableDxrSetting() const { return disable_dxr_; } auto GetAccelStructPaddingSetting() const { return accel_struct_padding_; } bool GetForceFifoPresentModeSetting() const { return force_fifo_present_mode_; } + auto GetTrimBoundary() const { return trim_boundary_; } + auto GetTrimDrawCalls() const { return trim_draw_calls_; } + auto GetQueueSubmitCount() const { return queue_submit_count_; } util::Compressor* GetCompressor() { return compressor_.get(); } std::mutex& GetMappedMemoryLock() { return mapped_memory_lock_; } @@ -269,6 +276,8 @@ class CommonCaptureManager util::ScreenshotFormat GetScreenShotFormat() const { return screenshot_format_; } std::string CreateTrimFilename(const std::string& base_filename, const util::UintRange& trim_range); + std::string CreateTrimDrawCallsFilename(const std::string& base_filename, + const CaptureSettings::TrimDrawCalls& trim_draw_calls); bool CreateCaptureFile(format::ApiFamilyId api_family, const std::string& base_filename); void WriteCaptureOptions(std::string& operation_annotation); void ActivateTrimming(std::shared_lock& current_lock); @@ -365,6 +374,7 @@ class CommonCaptureManager bool trim_enabled_; CaptureSettings::TrimBoundary trim_boundary_; std::vector trim_ranges_; + CaptureSettings::TrimDrawCalls trim_draw_calls_; std::string trim_key_; uint32_t trim_key_frames_; uint32_t trim_key_first_frame_; diff --git a/framework/encode/capture_settings.cpp b/framework/encode/capture_settings.cpp index fd1989721..42996d77d 100644 --- a/framework/encode/capture_settings.cpp +++ b/framework/encode/capture_settings.cpp @@ -82,6 +82,8 @@ GFXRECON_BEGIN_NAMESPACE(encode) #define SCREENSHOT_FRAMES_UPPER "SCREENSHOT_FRAMES" #define CAPTURE_FRAMES_LOWER "capture_frames" #define CAPTURE_FRAMES_UPPER "CAPTURE_FRAMES" +#define CAPTURE_DRAW_CALLS_LOWER "capture_draw_calls" +#define CAPTURE_DRAW_CALLS_UPPER "CAPTURE_DRAW_CALLS" #define QUIT_AFTER_CAPTURE_FRAMES_LOWER "quit_after_capture_frames" #define QUIT_AFTER_CAPTURE_FRAMES_UPPER "QUIT_AFTER_CAPTURE_FRAMES" #define CAPTURE_TRIGGER_LOWER "capture_trigger" @@ -163,6 +165,7 @@ const char kScreenshotDirEnvVar[] = GFXRECON_ENV_VAR_ const char kScreenshotFormatEnvVar[] = GFXRECON_ENV_VAR_PREFIX SCREENSHOT_FORMAT_LOWER; const char kScreenshotFramesEnvVar[] = GFXRECON_ENV_VAR_PREFIX SCREENSHOT_FRAMES_LOWER; const char kCaptureFramesEnvVar[] = GFXRECON_ENV_VAR_PREFIX CAPTURE_FRAMES_LOWER; +const char kCaptureDrawCallsEnvVar[] = GFXRECON_ENV_VAR_PREFIX CAPTURE_DRAW_CALLS_LOWER; const char kQuitAfterFramesEnvVar[] = GFXRECON_ENV_VAR_PREFIX QUIT_AFTER_CAPTURE_FRAMES_LOWER; const char kCaptureTriggerEnvVar[] = GFXRECON_ENV_VAR_PREFIX CAPTURE_TRIGGER_LOWER; const char kCaptureTriggerFramesEnvVar[] = GFXRECON_ENV_VAR_PREFIX CAPTURE_TRIGGER_FRAMES_LOWER; @@ -217,6 +220,7 @@ const char kScreenshotDirEnvVar[] = GFXRECON_ENV_VAR_ const char kScreenshotFormatEnvVar[] = GFXRECON_ENV_VAR_PREFIX SCREENSHOT_FORMAT_UPPER; const char kScreenshotFramesEnvVar[] = GFXRECON_ENV_VAR_PREFIX SCREENSHOT_FRAMES_UPPER; const char kCaptureFramesEnvVar[] = GFXRECON_ENV_VAR_PREFIX CAPTURE_FRAMES_UPPER; +const char kCaptureDrawCallsEnvVar[] = GFXRECON_ENV_VAR_PREFIX CAPTURE_DRAW_CALLS_UPPER; const char kQuitAfterFramesEnvVar[] = GFXRECON_ENV_VAR_PREFIX QUIT_AFTER_CAPTURE_FRAMES_UPPER; const char kPageGuardCopyOnMapEnvVar[] = GFXRECON_ENV_VAR_PREFIX PAGE_GUARD_COPY_ON_MAP_UPPER; const char kPageGuardSeparateReadEnvVar[] = GFXRECON_ENV_VAR_PREFIX PAGE_GUARD_SEPARATE_READ_UPPER; @@ -269,6 +273,7 @@ const std::string kOptionKeyScreenshotDir = std::stri const std::string kOptionKeyScreenshotFormat = std::string(kSettingsFilter) + std::string(SCREENSHOT_FORMAT_LOWER); const std::string kOptionKeyScreenshotFrames = std::string(kSettingsFilter) + std::string(SCREENSHOT_FRAMES_LOWER); const std::string kOptionKeyCaptureFrames = std::string(kSettingsFilter) + std::string(CAPTURE_FRAMES_LOWER); +const std::string kOptionKeyCaptureDrawCalls = std::string(kSettingsFilter) + std::string(CAPTURE_DRAW_CALLS_LOWER); const std::string kOptionKeyQuitAfterCaptureFrames = std::string(kSettingsFilter) + std::string(QUIT_AFTER_CAPTURE_FRAMES_LOWER); const std::string kOptionKeyCaptureTrigger = std::string(kSettingsFilter) + std::string(CAPTURE_TRIGGER_LOWER); const std::string kOptionKeyCaptureTriggerFrames = std::string(kSettingsFilter) + std::string(CAPTURE_TRIGGER_FRAMES_LOWER); @@ -408,6 +413,7 @@ void CaptureSettings::LoadOptionsEnvVar(OptionsMap* options) // Trimming environment variables LoadSingleOptionEnvVar(options, kCaptureFramesEnvVar, kOptionKeyCaptureFrames); + LoadSingleOptionEnvVar(options, kCaptureDrawCallsEnvVar, kOptionKeyCaptureDrawCalls); LoadSingleOptionEnvVar(options, kQuitAfterFramesEnvVar, kOptionKeyQuitAfterCaptureFrames); LoadSingleOptionEnvVar(options, kCaptureTriggerEnvVar, kOptionKeyCaptureTrigger); LoadSingleOptionEnvVar(options, kCaptureTriggerFramesEnvVar, kOptionKeyCaptureTriggerFrames); @@ -507,6 +513,33 @@ void CaptureSettings::ProcessOptions(OptionsMap* options, CaptureSettings* setti } } + std::string trim_draw_calls = FindOption(options, kOptionKeyCaptureDrawCalls); + if (!trim_draw_calls.empty()) + { + std::vector trim_values; + ParseUintRangeList(trim_draw_calls, &trim_values, "capture draw calls", false, true); + if (trim_values.size() == 3 || trim_values.size() == 4) + { + settings->trace_settings_.trim_draw_calls.submit_index = trim_values[0].first; + settings->trace_settings_.trim_draw_calls.command_index = trim_values[1].first; + settings->trace_settings_.trim_draw_calls.draw_call_indices.first = trim_values[2].first; + settings->trace_settings_.trim_draw_calls.draw_call_indices.last = trim_values[2].last; + settings->trace_settings_.trim_boundary = TrimBoundary::kDrawCalls; + + if (trim_values.size() == 4) + { + settings->trace_settings_.trim_draw_calls.bundle_draw_call_indices.first = trim_values[3].first; + settings->trace_settings_.trim_draw_calls.bundle_draw_call_indices.last = trim_values[3].last; + } + else + { + // bundle_draw_call_indices is the 4th arg. The default is 0 if it doesn't set. + settings->trace_settings_.trim_draw_calls.bundle_draw_call_indices.first = 0; + settings->trace_settings_.trim_draw_calls.bundle_draw_call_indices.last = 0; + } + } + } + std::string trim_queue_submits = FindOption(options, kOptionKeyCaptureQueueSubmits); if (!trim_queue_submits.empty()) { @@ -843,13 +876,16 @@ util::Log::Severity CaptureSettings::ParseLogLevelString(const std::string& val void CaptureSettings::ParseUintRangeList(const std::string& value_string, std::vector* frames, - const char* option_name) + const char* option_name, + bool check_overlap_range, + bool allow_zero) { GFXRECON_ASSERT(frames != nullptr); if (!value_string.empty()) { - std::vector frame_ranges = util::GetUintRanges(value_string.c_str(), option_name); + std::vector frame_ranges = + util::GetUintRanges(value_string.c_str(), option_name, check_overlap_range, allow_zero); for (uint32_t i = 0; i < frame_ranges.size(); ++i) { diff --git a/framework/encode/capture_settings.h b/framework/encode/capture_settings.h index 6224ae898..b419d3a49 100644 --- a/framework/encode/capture_settings.h +++ b/framework/encode/capture_settings.h @@ -74,10 +74,20 @@ class CaptureSettings kUnknown, kFrames, kQueueSubmits, + kDrawCalls, }; const static char kDefaultCaptureFileName[]; + struct TrimDrawCalls + { + // 0-based + uint32_t submit_index{ 0 }; + uint32_t command_index{ 0 }; + util::UintRange draw_call_indices; + util::UintRange bundle_draw_call_indices; + }; + struct ResourveValueAnnotationInfo { // Annotated GPUVA mask definition @@ -99,6 +109,7 @@ class CaptureSettings util::ScreenshotFormat screenshot_format; TrimBoundary trim_boundary{ TrimBoundary::kUnknown }; std::vector trim_ranges; + TrimDrawCalls trim_draw_calls; std::string trim_key; uint32_t trim_key_frames{ 0 }; RuntimeTriggerState runtime_capture_trigger{ kNotUsed }; @@ -185,8 +196,11 @@ class CaptureSettings static util::Log::Severity ParseLogLevelString(const std::string& value_string, util::Log::Severity default_value); - static void - ParseUintRangeList(const std::string& value_string, std::vector* frames, const char* option_name); + static void ParseUintRangeList(const std::string& value_string, + std::vector* frames, + const char* option_name, + bool check_overlap_range = true, + bool allow_zero = false); static std::string ParseTrimKeyString(const std::string& value_string); diff --git a/framework/encode/d3d12_capture_manager.cpp b/framework/encode/d3d12_capture_manager.cpp index 05bb8cf58..c334c52bd 100644 --- a/framework/encode/d3d12_capture_manager.cpp +++ b/framework/encode/d3d12_capture_manager.cpp @@ -29,6 +29,9 @@ #include "encode/dx12_object_wrapper_info.h" #include "encode/dx12_state_writer.h" #include "generated/generated_dx12_wrapper_creators.h" +#include "generated/generated_dx12_struct_unwrappers.h" +#include "generated/generated_dx12_api_call_encoders.h" +#include "decode/dx12_enum_util.h" GFXRECON_BEGIN_NAMESPACE(gfxrecon) GFXRECON_BEGIN_NAMESPACE(encode) @@ -229,7 +232,7 @@ void D3D12CaptureManager::PreAcquireSwapChainImages(IDXGISwapChain_Wrapper* wrap // Initialize members of ID3D12ResourceInfo for resource_wrapper in order to track swap chain buffer // state. - InitializeSwapChainBufferResourceInfo(resource_wrapper, D3D12_RESOURCE_STATE_PRESENT); + InitializeSwapChainBufferResourceInfo(wrapper, resource_wrapper, D3D12_RESOURCE_STATE_PRESENT); } else { @@ -380,19 +383,31 @@ void D3D12CaptureManager::InitializeID3D12ResourceInfo(ID3D12Device_Wrapper* } } -void D3D12CaptureManager::InitializeSwapChainBufferResourceInfo(ID3D12Resource_Wrapper* resource_wrapper, +void D3D12CaptureManager::InitializeSwapChainBufferResourceInfo(IDXGISwapChain_Wrapper* wrapper, + ID3D12Resource_Wrapper* resource_wrapper, D3D12_RESOURCE_STATES initial_state) { GFXRECON_ASSERT(resource_wrapper != nullptr); GFXRECON_ASSERT(resource_wrapper->GetObjectInfo() != nullptr); auto info = resource_wrapper->GetObjectInfo(); + GFXRECON_ASSERT(info); + + info->swapchain_wrapper = wrapper; + + // Get the swapchain's native ID3D12Device + graphics::dx12::ID3D12DeviceComPtr device; + wrapper->GetDevice(IID_PPV_ARGS(&device)); + + // Get the ID3D12Device_Wrapper + ID3D12Device_Wrapper* device_wrapper = ID3D12Device_Wrapper::GetExistingWrapper(device); // Not all fields of ID3D12ResourceInfo are used for swap chain buffers. info->num_subresources = 1; info->mapped_subresources = std::make_unique(info->num_subresources); info->subresource_sizes = std::make_unique(info->num_subresources); info->subresource_sizes[0] = 0; + info->device_wrapper = device_wrapper; if (IsCaptureModeTrack()) { @@ -1772,7 +1787,34 @@ void D3D12CaptureManager::PreProcess_ID3D12CommandQueue_ExecuteCommandLists( } } - PreQueueSubmit(current_lock); + // Split commandlist is for trim drawcalls. It means that this is a extra ExecuteCommandLists. It shouldn't count + // queue_submit_count_. + if (!(IsTrimEnabled() && GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls && + HasSplitCommandLists(num_lists, lists))) + { + PreQueueSubmit(current_lock); + } +} + +void D3D12CaptureManager::OverrideID3D12CommandQueue_ExecuteCommandLists( + std::shared_lock& current_lock, + ID3D12CommandQueue_Wrapper* wrapper, + UINT num_lists, + ID3D12CommandList* const* lists) +{ + bool is_complete = false; + if (IsTrimEnabled() && GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls && + !HasSplitCommandLists(num_lists, lists)) + { + is_complete = TrimDrawCalls_ID3D12CommandQueue_ExecuteCommandLists(current_lock, wrapper, num_lists, lists); + } + + if (!is_complete) + { + auto queue = wrapper->GetWrappedObjectAs(); + auto unwrap_memory = GetHandleUnwrapMemory(); + queue->ExecuteCommandLists(num_lists, UnwrapObjects(lists, num_lists, unwrap_memory)); + } } void D3D12CaptureManager::PostProcess_ID3D12CommandQueue_ExecuteCommandLists( @@ -1781,7 +1823,13 @@ void D3D12CaptureManager::PostProcess_ID3D12CommandQueue_ExecuteCommandLists( UINT num_lists, ID3D12CommandList* const* lists) { - PostQueueSubmit(current_lock); + // Split commandlists are for trim drawcalls. It means that this is a extra ExecuteCommandLists. It shouldn't count + // queue_submit_count_. + if (!(IsTrimEnabled() && GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls && + HasSplitCommandLists(num_lists, lists))) + { + PostQueueSubmit(current_lock); + } if (IsCaptureModeTrack()) { @@ -1789,6 +1837,17 @@ void D3D12CaptureManager::PostProcess_ID3D12CommandQueue_ExecuteCommandLists( } } +HRESULT +D3D12CaptureManager::OverrideD3D12SerializeVersionedRootSignature( + const D3D12_VERSIONED_ROOT_SIGNATURE_DESC* pRootSignature, ID3DBlob** ppBlob, ID3DBlob** ppErrorBlob) +{ + if (IsTrimEnabled() && GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + TrimDrawCalls_D3D12SerializeVersionedRootSignature(pRootSignature, ppBlob, ppErrorBlob); + } + return GetD3D12DispatchTable().D3D12SerializeVersionedRootSignature(pRootSignature, ppBlob, ppErrorBlob); +} + D3D12_CPU_DESCRIPTOR_HANDLE D3D12CaptureManager::OverrideID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart( ID3D12DescriptorHeap_Wrapper* wrapper) { @@ -1923,14 +1982,15 @@ D3D12CaptureManager::OverrideID3D12Device_CreateCommittedResource2(ID3D12Device8 auto properties_copy = *heap_properties; EnableWriteWatch(heap_flags, properties_copy); - return device->CreateCommittedResource2(&properties_copy, - heap_flags, - desc, - initial_resource_state, - optimized_clear_value, - protected_session, - riid_resource, - ppv_resource); + return device->CreateCommittedResource2( + &properties_copy, + heap_flags, + desc, + initial_resource_state, + optimized_clear_value, + encode::GetWrappedObject(protected_session), + riid_resource, + ppv_resource); } return device->CreateCommittedResource2(heap_properties, @@ -1938,7 +1998,7 @@ D3D12CaptureManager::OverrideID3D12Device_CreateCommittedResource2(ID3D12Device8 desc, initial_resource_state, optimized_clear_value, - protected_session, + encode::GetWrappedObject(protected_session), riid_resource, ppv_resource); } @@ -2032,11 +2092,13 @@ HRESULT D3D12CaptureManager::OverrideID3D12Device_CreateHeap1(ID3D12Device4_Wrap D3D12_HEAP_DESC desc_copy = *desc; EnableWriteWatch(desc_copy.Flags, desc_copy.Properties); - return device->CreateHeap1(&desc_copy, protected_session, riid, heap); + return device->CreateHeap1( + &desc_copy, encode::GetWrappedObject(protected_session), riid, heap); } else { - return device->CreateHeap1(desc, protected_session, riid, heap); + return device->CreateHeap1( + desc, encode::GetWrappedObject(protected_session), riid, heap); } } @@ -2113,8 +2175,12 @@ HRESULT D3D12CaptureManager::OverrideIDXGIFactory2_CreateSwapChainForHwnd( { return E_INVALIDARG; } - HRESULT result = - factory2->CreateSwapChainForHwnd(pDevice, hWnd, pDesc, pFullscreenDesc, pRestrictToOutput, ppSwapChain); + HRESULT result = factory2->CreateSwapChainForHwnd(encode::GetWrappedObject(pDevice), + hWnd, + pDesc, + pFullscreenDesc, + encode::GetWrappedObject(pRestrictToOutput), + ppSwapChain); UpdateSwapChainSize(pDesc->Width, pDesc->Height, *ppSwapChain); return result; } @@ -2132,7 +2198,11 @@ D3D12CaptureManager::OverrideIDXGIFactory2_CreateSwapChainForCoreWindow(IDXGIFac { return E_INVALIDARG; } - HRESULT result = factory2->CreateSwapChainForCoreWindow(pDevice, pWindow, pDesc, pRestrictToOutput, ppSwapChain); + HRESULT result = factory2->CreateSwapChainForCoreWindow(encode::GetWrappedObject(pDevice), + encode::GetWrappedObject(pWindow), + pDesc, + encode::GetWrappedObject(pRestrictToOutput), + ppSwapChain); UpdateSwapChainSize(pDesc->Width, pDesc->Height, *ppSwapChain); return result; } @@ -2149,7 +2219,10 @@ D3D12CaptureManager::OverrideIDXGIFactory2_CreateSwapChainForComposition(IDXGIFa { return E_INVALIDARG; } - HRESULT result = factory2->CreateSwapChainForComposition(pDevice, pDesc, pRestrictToOutput, ppSwapChain); + HRESULT result = factory2->CreateSwapChainForComposition(encode::GetWrappedObject(pDevice), + pDesc, + encode::GetWrappedObject(pRestrictToOutput), + ppSwapChain); UpdateSwapChainSize(pDesc->Width, pDesc->Height, *ppSwapChain); return result; } @@ -2738,6 +2811,54 @@ void D3D12CaptureManager::OverrideGetRaytracingAccelerationStructurePrebuildInfo } } +HRESULT D3D12CaptureManager::OverrideID3D12GraphicsCommandList_Reset(ID3D12GraphicsCommandList_Wrapper* wrapper, + ID3D12CommandAllocator* pAllocator, + ID3D12PipelineState* pInitialState) +{ + auto cmd_list = wrapper->GetWrappedObjectAs(); + auto result = cmd_list->Reset(encode::GetWrappedObject(pAllocator), + encode::GetWrappedObject(pInitialState)); + + if (GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + TrimDrawCalls_ID3D12GraphicsCommandList_Reset(result, wrapper, pAllocator, pInitialState); + } + return result; +} + +void D3D12CaptureManager::OverrideID3D12GraphicsCommandList_ExecuteBundle(ID3D12GraphicsCommandList_Wrapper* wrapper, + ID3D12GraphicsCommandList* pCommandList) +{ + auto cmd_list = wrapper->GetWrappedObjectAs(); + cmd_list->ExecuteBundle(encode::GetWrappedObject(pCommandList)); + + if (GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + TrimDrawCalls_ID3D12GraphicsCommandList_ExecuteBundle(wrapper, pCommandList); + } +} + +void D3D12CaptureManager::OverrideID3D12GraphicsCommandList4_BeginRenderPass( + ID3D12GraphicsCommandList4_Wrapper* wrapper, + UINT NumRenderTargets, + const D3D12_RENDER_PASS_RENDER_TARGET_DESC* pRenderTargets, + const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC* pDepthStencil, + D3D12_RENDER_PASS_FLAGS Flags) +{ + auto cmd_list4 = wrapper->GetWrappedObjectAs(); + auto unwrap_memory = GetHandleUnwrapMemory(); + cmd_list4->BeginRenderPass(NumRenderTargets, + UnwrapStructArrayObjects(pRenderTargets, NumRenderTargets, unwrap_memory), + UnwrapStructPtrObjects(pDepthStencil, unwrap_memory), + Flags); + + if (GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + TrimDrawCalls_ID3D12GraphicsCommandList4_BeginRenderPass( + wrapper, NumRenderTargets, pRenderTargets, pDepthStencil, Flags); + } +} + void D3D12CaptureManager::PostProcess_ID3D12Device5_CreateStateObject(ID3D12Device5_Wrapper* device5_wrapper, HRESULT result, const D3D12_STATE_OBJECT_DESC* desc, @@ -2956,5 +3077,622 @@ void D3D12CaptureManager::UpdateSwapChainSize(uint32_t width, uint32_t height, I } } +void D3D12CaptureManager::TrimDrawCalls_D3D12SerializeVersionedRootSignature( + const D3D12_VERSIONED_ROOT_SIGNATURE_DESC* pRootSignature, ID3DBlob** ppBlob, ID3DBlob** ppErrorBlob) +{ + uint32_t param_size = 0; + const D3D12_ROOT_PARAMETER1* params = nullptr; + + if (pRootSignature->Version == D3D_ROOT_SIGNATURE_VERSION_1_1) + { + param_size = pRootSignature->Desc_1_1.NumParameters; + params = pRootSignature->Desc_1_1.pParameters; + } + else if (pRootSignature->Version == D3D_ROOT_SIGNATURE_VERSION_1_2) + { + param_size = pRootSignature->Desc_1_2.NumParameters; + params = pRootSignature->Desc_1_2.pParameters; + } + + if (params) + { + for (uint32_t i = 0; i < param_size; ++i) + { + switch (params[i].ParameterType) + { + case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: + { + auto range_size = params[i].DescriptorTable.NumDescriptorRanges; + for (uint32_t j = 0; j < range_size; ++j) + { + auto& range = params[i].DescriptorTable.pDescriptorRanges[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 (range.Flags & D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC) + { + GFXRECON_LOG_WARNING( + "D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC could cause error for trim draw calls. " + "Recommend using D3D12_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE."); + break; + } + } + break; + } + default: + break; + } + } + } +} + +void D3D12CaptureManager::TrimDrawCalls_ID3D12GraphicsCommandList_Reset(HRESULT replay_result, + ID3D12GraphicsCommandList_Wrapper* wrapper, + ID3D12CommandAllocator* pAllocator, + ID3D12PipelineState* pInitialState) +{ + DecrementCallScope(); + + auto trim_draw_calls_command_sets = + GetCommandListsForTrimDrawCalls(wrapper, format::ApiCall_ID3D12GraphicsCommandList_Reset); + for (auto& command_set : trim_draw_calls_command_sets) + { + auto list_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + GFXRECON_ASSERT(list_wrapper); + auto result_trim_draw_calls = list_wrapper->Reset(command_set.allocator, pInitialState); + + if (replay_result != result_trim_draw_calls) + { + GFXRECON_LOG_WARNING( + "Splitting commandlists of ID3D12GraphicsCommandList::Reset get different results: %s and %s", + decode::enumutil::GetResultValueString(replay_result).c_str(), + decode::enumutil::GetResultValueString(result_trim_draw_calls).c_str()); + } + } + IncrementCallScope(); +} + +void D3D12CaptureManager::TrimDrawCalls_ID3D12GraphicsCommandList_ExecuteBundle( + ID3D12GraphicsCommandList_Wrapper* wrapper, ID3D12GraphicsCommandList* pCommandList) +{ + DecrementCallScope(); + + auto trim_draw_calls_command_sets = + GetCommandListsForTrimDrawCalls(wrapper, format::ApiCall_ID3D12GraphicsCommandList_ExecuteBundle); + + if (trim_draw_calls_command_sets.size() == 3) + { + // Here is the target draw call for trim draw calls. + auto bunlde_wrapper = reinterpret_cast(pCommandList); + GFXRECON_ASSERT(bunlde_wrapper); + + auto bundle_info = bunlde_wrapper->GetObjectInfo(); + GFXRECON_ASSERT(bundle_info); + + auto cmd_info = wrapper->GetObjectInfo(); + GFXRECON_ASSERT(cmd_info); + cmd_info->target_bundle_commandlist_info = bundle_info; + + uint32_t i = 0; + for (auto& command_set : trim_draw_calls_command_sets) + { + GFXRECON_ASSERT(bundle_info->split_command_sets[i].list); + + auto list_wrapper = + reinterpret_cast(command_set.list.GetInterfacePtr()); + GFXRECON_ASSERT(list_wrapper); + + list_wrapper->ExecuteBundle(bundle_info->split_command_sets[i].list); + ++i; + } + } + else if (trim_draw_calls_command_sets.size() == 1) + { + auto list_wrapper = reinterpret_cast( + trim_draw_calls_command_sets[0].list.GetInterfacePtr()); + GFXRECON_ASSERT(list_wrapper); + list_wrapper->ExecuteBundle(pCommandList); + } + IncrementCallScope(); +} + +void D3D12CaptureManager::TrimDrawCalls_ID3D12GraphicsCommandList4_BeginRenderPass( + ID3D12GraphicsCommandList4_Wrapper* wrapper, + UINT NumRenderTargets, + const D3D12_RENDER_PASS_RENDER_TARGET_DESC* pRenderTargets, + const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC* pDepthStencil, + D3D12_RENDER_PASS_FLAGS Flags) +{ + DecrementCallScope(); + + auto trim_draw_calls_command_sets = + GetCommandListsForTrimDrawCalls(wrapper, format::ApiCall_ID3D12GraphicsCommandList4_BeginRenderPass); + if (trim_draw_calls_command_sets.size() == 3) + { + // before + std::vector before_rt_descs; + for (uint32_t i = 0; i < NumRenderTargets; ++i) + { + D3D12_RENDER_PASS_RENDER_TARGET_DESC desc = pRenderTargets[i]; + desc.EndingAccess.Type = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE; + before_rt_descs.emplace_back(std::move(desc)); + } + + D3D12_RENDER_PASS_DEPTH_STENCIL_DESC before_ds_desc = {}; + D3D12_RENDER_PASS_DEPTH_STENCIL_DESC* p_before_ds_desc = nullptr; + if (pDepthStencil) + { + before_ds_desc = *pDepthStencil; + before_ds_desc.DepthEndingAccess.Type = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE; + before_ds_desc.StencilEndingAccess.Type = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE; + p_before_ds_desc = &before_ds_desc; + } + + auto* before_wrappr = reinterpret_cast( + trim_draw_calls_command_sets[graphics::dx12::kBeforeDrawCallArrayIndex].list.GetInterfacePtr()); + auto* before4_wrappr = static_cast(before_wrappr); + GFXRECON_ASSERT(before4_wrappr); + + before4_wrappr->BeginRenderPass(NumRenderTargets, before_rt_descs.data(), p_before_ds_desc, Flags); + + // target + std::vector target_rt_descs; + for (uint32_t i = 0; i < NumRenderTargets; ++i) + { + D3D12_RENDER_PASS_RENDER_TARGET_DESC desc = pRenderTargets[i]; + desc.BeginningAccess.Type = D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE; + desc.EndingAccess.Type = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE; + target_rt_descs.emplace_back(std::move(desc)); + } + + D3D12_RENDER_PASS_DEPTH_STENCIL_DESC target_ds_desc = {}; + D3D12_RENDER_PASS_DEPTH_STENCIL_DESC* p_target_ds_desc = nullptr; + if (pDepthStencil) + { + target_ds_desc = *pDepthStencil; + target_ds_desc.DepthBeginningAccess.Type = D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE; + target_ds_desc.StencilBeginningAccess.Type = D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE; + target_ds_desc.DepthEndingAccess.Type = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE; + target_ds_desc.StencilEndingAccess.Type = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE; + p_target_ds_desc = &target_ds_desc; + } + + auto* target_wrappr = reinterpret_cast( + trim_draw_calls_command_sets[graphics::dx12::kDrawCallArrayIndex].list.GetInterfacePtr()); + auto* target4_wrapper = static_cast(target_wrappr); + GFXRECON_ASSERT(target4_wrapper); + + target4_wrapper->BeginRenderPass(NumRenderTargets, target_rt_descs.data(), p_target_ds_desc, Flags); + + // after + std::vector after_rt_descs; + for (uint32_t i = 0; i < NumRenderTargets; ++i) + { + D3D12_RENDER_PASS_RENDER_TARGET_DESC desc = pRenderTargets[i]; + desc.BeginningAccess.Type = D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE; + after_rt_descs.emplace_back(std::move(desc)); + } + + D3D12_RENDER_PASS_DEPTH_STENCIL_DESC after_ds_desc = {}; + D3D12_RENDER_PASS_DEPTH_STENCIL_DESC* p_after_ds_desc = nullptr; + if (pDepthStencil) + { + after_ds_desc = *pDepthStencil; + after_ds_desc.DepthBeginningAccess.Type = D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE; + after_ds_desc.StencilBeginningAccess.Type = D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_PRESERVE; + p_after_ds_desc = &after_ds_desc; + } + + auto* after_wrapper = reinterpret_cast( + trim_draw_calls_command_sets[graphics::dx12::kAfterDrawCallArrayIndex].list.GetInterfacePtr()); + auto* after4_wrapper = static_cast(after_wrapper); + GFXRECON_ASSERT(after4_wrapper); + + after4_wrapper->BeginRenderPass(NumRenderTargets, after_rt_descs.data(), p_after_ds_desc, Flags); + } + else if (trim_draw_calls_command_sets.size() == 1) + { + auto* list_wrapper = reinterpret_cast( + trim_draw_calls_command_sets[0].list.GetInterfacePtr()); + auto* list4_wrapper = static_cast(list_wrapper); + GFXRECON_ASSERT(list4_wrapper); + + list4_wrapper->BeginRenderPass(NumRenderTargets, pRenderTargets, pDepthStencil, Flags); + } + IncrementCallScope(); +} + +bool D3D12CaptureManager::TrimDrawCalls_ID3D12CommandQueue_ExecuteCommandLists( + std::shared_lock& current_lock, + ID3D12CommandQueue_Wrapper* wrapper, + UINT num_lists, + ID3D12CommandList* const* lists) +{ + auto trim_draw_calls = GetTrimDrawCalls(); + + // TODO: When queue_submit_count_ becomes 0-based, remove "-1". + if ((common_manager_->GetQueueSubmitCount() - 1) == trim_draw_calls.submit_index) + { + if (num_lists <= trim_draw_calls.command_index) + { + GFXRECON_LOG_FATAL("CAPTURE_DRAW_CALLS can't find the commandlist index(%d). It might be out of range(%d).", + trim_draw_calls.command_index, + num_lists); + GFXRECON_ASSERT(num_lists > trim_draw_calls.command_index); + } + + auto target_cmdlist = lists[trim_draw_calls.command_index]; + auto target_wrapper = reinterpret_cast(target_cmdlist); + GFXRECON_ASSERT(target_wrapper); + + auto target_info = target_wrapper->GetObjectInfo(); + GFXRECON_ASSERT(target_info); + + if (target_info->find_target_draw_call_count == 0) + { + GFXRECON_LOG_FATAL("CAPTURE_DRAW_CALLS can't find the draw call indices(%d-%d). It might be out of range.", + trim_draw_calls.draw_call_indices.first, + trim_draw_calls.draw_call_indices.last); + GFXRECON_ASSERT(target_info->find_target_draw_call_count != 0); + } + + if (target_info->find_target_draw_call_count != + (trim_draw_calls.draw_call_indices.last - trim_draw_calls.draw_call_indices.first + 1)) + { + GFXRECON_LOG_WARNING( + "CAPTURE_DRAW_CALLS didn't find the enough draw call count(%d). The indices(%d-%d) might be out of range.", + target_info->find_target_draw_call_count, + trim_draw_calls.draw_call_indices.first, + trim_draw_calls.draw_call_indices.last); + } + + if (target_info->target_bundle_commandlist_info) + { + if (target_info->target_bundle_commandlist_info->find_target_draw_call_count == 0) + { + + GFXRECON_LOG_FATAL( + "CAPTURE_DRAW_CALLS can't find the bundle draw call indices(%d-%d). It might be out of range.", + trim_draw_calls.bundle_draw_call_indices.first, + trim_draw_calls.bundle_draw_call_indices.last); + GFXRECON_ASSERT(target_info->target_bundle_commandlist_info->find_target_draw_call_count != 0); + } + + if (target_info->target_bundle_commandlist_info->find_target_draw_call_count != + (trim_draw_calls.bundle_draw_call_indices.last - trim_draw_calls.bundle_draw_call_indices.first + 1)) + { + GFXRECON_LOG_WARNING("CAPTURE_DRAW_CALLS didn't find the enough bundle draw call count(%d). The " + "indices(%d-%d) might be out of range.", + target_info->target_bundle_commandlist_info->find_target_draw_call_count, + trim_draw_calls.bundle_draw_call_indices.first, + trim_draw_calls.bundle_draw_call_indices.last); + } + } + + std::vector cmdlists; + + // before of lists and before of splitted + for (uint32_t i = 0; i < trim_draw_calls.command_index; ++i) + { + cmdlists.emplace_back(lists[i]); + } + + auto before_draw_call_cmd = target_info->split_command_sets[graphics::dx12::kBeforeDrawCallArrayIndex].list; + GFXRECON_ASSERT(before_draw_call_cmd); + cmdlists.emplace_back(before_draw_call_cmd); + + // Here has to use the wrapped queue since this ExecuteCommandLists needs to be tracked. + DecrementCallScope(); + wrapper->ExecuteCommandLists(cmdlists.size(), cmdlists.data()); + IncrementCallScope(); + + auto queue = reinterpret_cast(wrapper->GetWrappedObject()); + graphics::dx12::WaitForQueue(queue); + cmdlists.clear(); + + // target of splitted + common_manager_->ActivateTrimmingDrawCalls(format::ApiFamilyId::ApiFamily_D3D12, current_lock); + + auto target_draw_call_cmd = target_info->split_command_sets[graphics::dx12::kDrawCallArrayIndex].list; + GFXRECON_ASSERT(target_draw_call_cmd); + cmdlists.emplace_back(target_draw_call_cmd); + + auto unwrap_memory = GetHandleUnwrapMemory(); + queue->ExecuteCommandLists(cmdlists.size(), + UnwrapObjects(cmdlists.data(), cmdlists.size(), unwrap_memory)); + + Encode_ID3D12CommandQueue_ExecuteCommandLists(wrapper, cmdlists.size(), cmdlists.data()); + cmdlists.clear(); + + common_manager_->DeactivateTrimmingDrawCalls(current_lock); + + // after of splitted and after of lists + auto after_draw_call_cmd = target_info->split_command_sets[graphics::dx12::kAfterDrawCallArrayIndex].list; + GFXRECON_ASSERT(after_draw_call_cmd); + cmdlists.emplace_back(after_draw_call_cmd); + + for (uint32_t i = (trim_draw_calls.command_index + 1); i < num_lists; ++i) + { + cmdlists.emplace_back(lists[i]); + } + + queue->ExecuteCommandLists(cmdlists.size(), + UnwrapObjects(cmdlists.data(), cmdlists.size(), unwrap_memory)); + return true; + } + return false; +} + +bool D3D12CaptureManager::HasSplitCommandLists(UINT num_lists, ID3D12CommandList* const* lists) +{ + for (uint32_t i = 0; i < num_lists; ++i) + { + auto cmd_wrapper = reinterpret_cast(lists[i]); + GFXRECON_ASSERT(cmd_wrapper); + + auto cmd_info = cmd_wrapper->GetObjectInfo(); + GFXRECON_ASSERT(cmd_info); + + if (cmd_info->is_split_commandlist) + { + return true; + } + } + return false; +} + +// It does something similar to Dx12DumpResources::GetCommandListsForDumpResources, but a bit different. +// Trimming draw calls is not like dump resources that could browse the captured file to find target commandlist and +// draw call before replay. +// +// For trimming draw calls, it doesn't know the target commandlist until running the target ExecuteCommandLists. +// In this case, it assumes every commandlist could be the target commandlist. +// Every commandlist has three splitted commandlists and add command to the splitted commandlists. +// +// It also can't know which draw call is the target in advance, commandlist has a draw_call_count to count it. +// Splitted commandlists will add some redundant commands since it couldn't know the target draw call in advance, +// But it shouldn't affect the result and performance. +// +// Another different with Dx12DumpResources::GetCommandListsForDumpResources is that the draw calls could be a range. +// It needs to take care of more about kDrawCall. +std::vector +D3D12CaptureManager::GetCommandListsForTrimDrawCalls(ID3D12CommandList_Wrapper* wrapper, format::ApiCallId api_call_id) +{ + std::vector cmd_sets; + auto cmd_list_info = wrapper->GetObjectInfo(); + + // Splitted commandlists don't be splitted again. + if (!IsTrimEnabled() || cmd_list_info->is_split_commandlist) + { + return cmd_sets; + } + + auto trim_boundary = GetTrimBoundary(); + CaptureSettings::TrimDrawCalls trim_draw_calls = GetTrimDrawCalls(); + graphics::dx12::ID3D12DeviceComPtr device = nullptr; + HRESULT ret = wrapper->GetDevice(IID_PPV_ARGS(&device)); + GFXRECON_ASSERT(SUCCEEDED(ret)); + + auto device_wrapper = reinterpret_cast(device.GetInterfacePtr()); + GFXRECON_ASSERT(device_wrapper); + + for (auto& command_set : cmd_list_info->split_command_sets) + { + if (command_set.allocator == nullptr) + { + device_wrapper->CreateCommandAllocator(cmd_list_info->command_list_type, + IID_PPV_ARGS(&command_set.allocator)); + device_wrapper->CreateCommandList( + 0, cmd_list_info->command_list_type, command_set.allocator, nullptr, IID_PPV_ARGS(&command_set.list)); + + auto split_list_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + GFXRECON_ASSERT(split_list_wrapper); + auto split_list_info = split_list_wrapper->GetObjectInfo(); + split_list_info->is_split_commandlist = true; + } + } + + bool is_draw_call = false; + switch (api_call_id) + { + case format::ApiCall_ID3D12GraphicsCommandList_ExecuteBundle: + case format::ApiCall_ID3D12GraphicsCommandList_DrawInstanced: + case format::ApiCall_ID3D12GraphicsCommandList_DrawIndexedInstanced: + case format::ApiCall_ID3D12GraphicsCommandList_Dispatch: + case format::ApiCall_ID3D12GraphicsCommandList_ExecuteIndirect: + { + is_draw_call = true; + break; + } + default: + break; + }; + + graphics::dx12::Dx12DumpResourcePos split_type = graphics::dx12::Dx12DumpResourcePos::kDrawCall; + + // draw_call_count is counted at TrackCommandExecution, and TrackCommandExecution is after this function. + // It means that draw_call_count is counted after this function. + // Ex: if target draw_call index is 1, + // kBeforeDrawCall: the draw_call_count is 0 and 1(and is_draw_call is false) + // kDrawCall: the draw_call_count is 1(is_draw_call is true) + // kAfterDrawCall: the draw_call_count is larger than 1. + // + // If target draw call index is a range: 1-2, + // kBeforeDrawCall: the draw_call_count is 0 and 1(and is_draw_call is false) + // kDrawCall: the draw_call_count is 1(and is_draw_call is true) and 2. + // kAfterDrawCall: the draw_call_count is larger than 2. + if (cmd_list_info->command_list_type == D3D12_COMMAND_LIST_TYPE_BUNDLE) + { + if (cmd_list_info->draw_call_count < trim_draw_calls.bundle_draw_call_indices.first || + (cmd_list_info->draw_call_count == trim_draw_calls.bundle_draw_call_indices.first && !is_draw_call)) + { + split_type = graphics::dx12::Dx12DumpResourcePos::kBeforeDrawCall; + } + else if (cmd_list_info->draw_call_count > trim_draw_calls.bundle_draw_call_indices.last) + { + split_type = graphics::dx12::Dx12DumpResourcePos::kAfterDrawCall; + } + } + else + { + if (cmd_list_info->draw_call_count < trim_draw_calls.draw_call_indices.first || + (cmd_list_info->draw_call_count == trim_draw_calls.draw_call_indices.first && !is_draw_call)) + { + split_type = graphics::dx12::Dx12DumpResourcePos::kBeforeDrawCall; + } + else if (cmd_list_info->draw_call_count > trim_draw_calls.draw_call_indices.last) + { + split_type = graphics::dx12::Dx12DumpResourcePos::kAfterDrawCall; + } + } + auto split_type_array_index = graphics::dx12::Dx12DumpResourcePosToArrayIndex(split_type); + + // Here is to split command lists. + switch (api_call_id) + { + case format::ApiCall_ID3D12GraphicsCommandList_Reset: + { + for (auto& command_set : cmd_list_info->split_command_sets) + { + auto list_wrapper = + reinterpret_cast(command_set.list.GetInterfacePtr()); + GFXRECON_ASSERT(list_wrapper); + + auto list_info = list_wrapper->GetObjectInfo(); + if (!list_info->is_closed) + { + list_wrapper->Close(); + } + + auto alc_wrapper = + reinterpret_cast(command_set.allocator.GetInterfacePtr()); + GFXRECON_ASSERT(alc_wrapper); + + alc_wrapper->Reset(); + cmd_sets.emplace_back(command_set); + } + break; + } + // It has to ensure that every splited commandlist has a pair of Queries, Events, RenderPasses. + // It can't know which RenderPass is the target in advance, so every RenderPass is added in every commandlist. + case format::ApiCall_ID3D12GraphicsCommandList_BeginQuery: + case format::ApiCall_ID3D12GraphicsCommandList_EndQuery: + case format::ApiCall_ID3D12GraphicsCommandList_BeginEvent: + case format::ApiCall_ID3D12GraphicsCommandList_EndEvent: + case format::ApiCall_ID3D12GraphicsCommandList4_BeginRenderPass: + case format::ApiCall_ID3D12GraphicsCommandList4_EndRenderPass: + case format::ApiCall_ID3D12GraphicsCommandList_Close: + { + cmd_sets.insert( + cmd_sets.end(), cmd_list_info->split_command_sets.begin(), cmd_list_info->split_command_sets.end()); + break; + } + // binding and Set. These commands are the three command lists need. + case format::ApiCall_ID3D12GraphicsCommandList_IASetIndexBuffer: + case format::ApiCall_ID3D12GraphicsCommandList_IASetPrimitiveTopology: + case format::ApiCall_ID3D12GraphicsCommandList_IASetVertexBuffers: + case format::ApiCall_ID3D12GraphicsCommandList_OMSetBlendFactor: + case format::ApiCall_ID3D12GraphicsCommandList1_OMSetDepthBounds: + case format::ApiCall_ID3D12GraphicsCommandList_OMSetRenderTargets: + case format::ApiCall_ID3D12GraphicsCommandList_OMSetStencilRef: + case format::ApiCall_ID3D12GraphicsCommandList_RSSetScissorRects: + case format::ApiCall_ID3D12GraphicsCommandList5_RSSetShadingRate: + case format::ApiCall_ID3D12GraphicsCommandList5_RSSetShadingRateImage: + case format::ApiCall_ID3D12GraphicsCommandList_RSSetViewports: + case format::ApiCall_ID3D12GraphicsCommandList_SetComputeRoot32BitConstant: + case format::ApiCall_ID3D12GraphicsCommandList_SetComputeRoot32BitConstants: + case format::ApiCall_ID3D12GraphicsCommandList_SetComputeRootConstantBufferView: + case format::ApiCall_ID3D12GraphicsCommandList_SetComputeRootDescriptorTable: + case format::ApiCall_ID3D12GraphicsCommandList_SetComputeRootShaderResourceView: + case format::ApiCall_ID3D12GraphicsCommandList_SetComputeRootSignature: + case format::ApiCall_ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView: + case format::ApiCall_ID3D12GraphicsCommandList_SetDescriptorHeaps: + case format::ApiCall_ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant: + case format::ApiCall_ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants: + case format::ApiCall_ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView: + case format::ApiCall_ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable: + case format::ApiCall_ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView: + case format::ApiCall_ID3D12GraphicsCommandList_SetGraphicsRootSignature: + case format::ApiCall_ID3D12GraphicsCommandList_SetGraphicsRootUnorderedAccessView: + case format::ApiCall_ID3D12GraphicsCommandList_SetPipelineState: + case format::ApiCall_ID3D12GraphicsCommandList4_SetPipelineState1: + case format::ApiCall_ID3D12GraphicsCommandList_SetPredication: + case format::ApiCall_ID3D12GraphicsCommandList3_SetProtectedResourceSession: + case format::ApiCall_ID3D12GraphicsCommandList1_SetSamplePositions: + case format::ApiCall_ID3D12GraphicsCommandList1_SetViewInstanceMask: + case format::ApiCall_ID3D12GraphicsCommandList_SOSetTargets: + case format::ApiCall_ID3D12GraphicsCommandList2_WriteBufferImmediate: + { + switch (split_type) + { + case graphics::dx12::Dx12DumpResourcePos::kBeforeDrawCall: + cmd_sets.insert(cmd_sets.end(), + cmd_list_info->split_command_sets.begin(), + cmd_list_info->split_command_sets.end()); + break; + case graphics::dx12::Dx12DumpResourcePos::kDrawCall: + cmd_sets.emplace_back(cmd_list_info->split_command_sets[graphics::dx12::kDrawCallArrayIndex]); + cmd_sets.emplace_back(cmd_list_info->split_command_sets[graphics::dx12::kAfterDrawCallArrayIndex]); + break; + case graphics::dx12::Dx12DumpResourcePos::kAfterDrawCall: + cmd_sets.emplace_back(cmd_list_info->split_command_sets[graphics::dx12::kAfterDrawCallArrayIndex]); + break; + default: + break; + } + break; + } + case format::ApiCall_ID3D12GraphicsCommandList_ExecuteBundle: + { + switch (split_type) + { + case graphics::dx12::Dx12DumpResourcePos::kDrawCall: + if (trim_draw_calls.draw_call_indices.first != trim_draw_calls.draw_call_indices.last) + { + GFXRECON_LOG_FATAL( + "The target draw call is a ExecuteBundle. The draw call indices must be not a range(%d-%d).", + trim_draw_calls.draw_call_indices.first, + trim_draw_calls.draw_call_indices.last); + GFXRECON_ASSERT(trim_draw_calls.draw_call_indices.first == + trim_draw_calls.draw_call_indices.last); + } + cmd_sets.insert(cmd_sets.end(), + cmd_list_info->split_command_sets.begin(), + cmd_list_info->split_command_sets.end()); + ++cmd_list_info->find_target_draw_call_count; + break; + default: + cmd_sets.emplace_back(cmd_list_info->split_command_sets[split_type_array_index]); + break; + } + break; + } + case format::ApiCall_ID3D12GraphicsCommandList_DrawInstanced: + case format::ApiCall_ID3D12GraphicsCommandList_DrawIndexedInstanced: + case format::ApiCall_ID3D12GraphicsCommandList_Dispatch: + case format::ApiCall_ID3D12GraphicsCommandList_ExecuteIndirect: + { + switch (split_type) + { + case graphics::dx12::Dx12DumpResourcePos::kDrawCall: + ++cmd_list_info->find_target_draw_call_count; + default: + cmd_sets.emplace_back(cmd_list_info->split_command_sets[split_type_array_index]); + break; + } + break; + } + default: // command could change data, like clear and copy. + { + cmd_sets.emplace_back(cmd_list_info->split_command_sets[split_type_array_index]); + break; + } + } + return cmd_sets; +} + GFXRECON_END_NAMESPACE(encode) GFXRECON_END_NAMESPACE(gfxrecon) diff --git a/framework/encode/d3d12_capture_manager.h b/framework/encode/d3d12_capture_manager.h index b7f3999c5..44c1b9470 100644 --- a/framework/encode/d3d12_capture_manager.h +++ b/framework/encode/d3d12_capture_manager.h @@ -460,6 +460,12 @@ class D3D12CaptureManager : public ApiCaptureManager UINT num_lists, ID3D12CommandList* const* lists); + void + OverrideID3D12CommandQueue_ExecuteCommandLists(std::shared_lock& current_lock, + ID3D12CommandQueue_Wrapper* wrapper, + UINT num_lists, + ID3D12CommandList* const* lists); + void PreProcess_D3D12CreateDevice(IUnknown* pAdapter, D3D_FEATURE_LEVEL MinimumFeatureLevel, REFIID riid, @@ -609,6 +615,10 @@ class D3D12CaptureManager : public ApiCaptureManager ID3D12Pageable* const* ppObjects, const D3D12_RESIDENCY_PRIORITY* pPriorities); + HRESULT OverrideD3D12SerializeVersionedRootSignature(const D3D12_VERSIONED_ROOT_SIGNATURE_DESC* pRootSignature, + ID3DBlob** ppBlob, + ID3DBlob** ppErrorBlob); + D3D12_CPU_DESCRIPTOR_HANDLE OverrideID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(ID3D12DescriptorHeap_Wrapper* wrapper); @@ -721,6 +731,19 @@ class D3D12CaptureManager : public ApiCaptureManager const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS* pDesc, D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO* pInfo); + HRESULT OverrideID3D12GraphicsCommandList_Reset(ID3D12GraphicsCommandList_Wrapper* wrapper, + ID3D12CommandAllocator* pAllocator, + ID3D12PipelineState* pInitialState); + + void OverrideID3D12GraphicsCommandList_ExecuteBundle(ID3D12GraphicsCommandList_Wrapper* wrapper, + ID3D12GraphicsCommandList* pCommandList); + + void OverrideID3D12GraphicsCommandList4_BeginRenderPass(ID3D12GraphicsCommandList4_Wrapper* wrapper, + UINT NumRenderTargets, + const D3D12_RENDER_PASS_RENDER_TARGET_DESC* pRenderTargets, + const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC* pDepthStencil, + D3D12_RENDER_PASS_FLAGS Flags); + virtual CaptureSettings::TraceSettings GetDefaultTraceSettings(); inline format::HandleId GetEnableDebugLayerObjectId() { return track_enable_debug_layer_object_id_; } @@ -768,6 +791,35 @@ class D3D12CaptureManager : public ApiCaptureManager int GetAgsVersion() { return ags_version_; } + void TrimDrawCalls_D3D12SerializeVersionedRootSignature(const D3D12_VERSIONED_ROOT_SIGNATURE_DESC* pRootSignature, + ID3DBlob** ppBlob, + ID3DBlob** ppErrorBlob); + + void TrimDrawCalls_ID3D12GraphicsCommandList_Reset(HRESULT replay_result, + ID3D12GraphicsCommandList_Wrapper* wrapper, + ID3D12CommandAllocator* pAllocator, + ID3D12PipelineState* pInitialState); + + void TrimDrawCalls_ID3D12GraphicsCommandList_ExecuteBundle(ID3D12GraphicsCommandList_Wrapper* wrapper, + ID3D12GraphicsCommandList* pCommandList); + void + TrimDrawCalls_ID3D12GraphicsCommandList4_BeginRenderPass(ID3D12GraphicsCommandList4_Wrapper* wrapper, + UINT NumRenderTargets, + const D3D12_RENDER_PASS_RENDER_TARGET_DESC* pRenderTargets, + const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC* pDepthStencil, + D3D12_RENDER_PASS_FLAGS Flags); + + bool TrimDrawCalls_ID3D12CommandQueue_ExecuteCommandLists( + std::shared_lock& current_lock, + ID3D12CommandQueue_Wrapper* wrapper, + UINT num_lists, + ID3D12CommandList* const* lists); + + bool HasSplitCommandLists(UINT num_lists, ID3D12CommandList* const* lists); + + std::vector GetCommandListsForTrimDrawCalls(ID3D12CommandList_Wrapper* wrapper, + format::ApiCallId api_call_id); + protected: D3D12CaptureManager(); @@ -801,7 +853,8 @@ class D3D12CaptureManager : public ApiCaptureManager ID3D12Heap_Wrapper* heap_wrapper, uint64_t heap_offset); - void InitializeSwapChainBufferResourceInfo(ID3D12Resource_Wrapper* resource_wrapper, + void InitializeSwapChainBufferResourceInfo(IDXGISwapChain_Wrapper* wrapper, + ID3D12Resource_Wrapper* resource_wrapper, D3D12_RESOURCE_STATES initial_state); void InitializeID3D12DeviceInfo(IUnknown* pAdapter, void** device); diff --git a/framework/encode/dx12_object_wrapper_info.h b/framework/encode/dx12_object_wrapper_info.h index 397d3878e..821715a88 100644 --- a/framework/encode/dx12_object_wrapper_info.h +++ b/framework/encode/dx12_object_wrapper_info.h @@ -45,6 +45,7 @@ struct IUnknown_Wrapper; class ID3D12Resource_Wrapper; class ID3D12Device_Wrapper; class ID3D12Heap_Wrapper; +class IDXGISwapChain_Wrapper; struct GUID_Hash { @@ -414,14 +415,16 @@ struct ID3D12ResourceInfo : public DxWrapperInfo ID3D12Heap_Wrapper* heap_wrapper{ nullptr }; uint64_t heap_offset; + + IDXGISwapChain_Wrapper* swapchain_wrapper{ nullptr }; }; struct ID3D12HeapInfo : public DxWrapperInfo { - bool has_write_watch{ false }; - D3D12_HEAP_TYPE heap_type{}; - D3D12_CPU_PAGE_PROPERTY page_property{}; - D3D12_MEMORY_POOL memory_pool{}; + bool has_write_watch{ false }; + D3D12_HEAP_TYPE heap_type{}; + D3D12_CPU_PAGE_PROPERTY page_property{}; + D3D12_MEMORY_POOL memory_pool{}; uint64_t heap_size{ 0 }; D3D12_GPU_VIRTUAL_ADDRESS gpu_va{ 0 }; @@ -477,6 +480,14 @@ struct ID3D12CommandListInfo : public DxWrapperInfo // Track acceleration structure builds that are recorded to this command list. std::vector acceleration_structure_builds; std::vector acceleration_structure_copies; + + uint32_t draw_call_count{ 0 }; // DrawInstanced, DrawIndexedInstanced, Dispatch, ExecuteIndirect, ExecuteBundle + + // GFXRECON_CAPTURE_DRAW_CALLS + std::array split_command_sets; + bool is_split_commandlist{ false }; + uint32_t find_target_draw_call_count{ 0 }; + std::shared_ptr target_bundle_commandlist_info{ false }; }; struct ID3D10BlobInfo : public DxWrapperInfo diff --git a/framework/encode/dx12_state_tracker.cpp b/framework/encode/dx12_state_tracker.cpp index e4333d70f..9dd92008a 100644 --- a/framework/encode/dx12_state_tracker.cpp +++ b/framework/encode/dx12_state_tracker.cpp @@ -119,34 +119,46 @@ void Dx12StateTracker::TrackCommandExecution(ID3D12CommandList_Wrapper* lis auto list_info = list_wrapper->GetObjectInfo(); - if (call_id == format::ApiCallId::ApiCall_ID3D12GraphicsCommandList_Reset) + switch (call_id) { - list_info->was_reset = true; - list_info->is_closed = false; - - // Clear command data on command buffer reset. - list_info->command_data.Clear(); + case format::ApiCallId::ApiCall_ID3D12GraphicsCommandList_Reset: + list_info->was_reset = true; + list_info->is_closed = false; - // Clear pending resource transitions. - list_info->transition_barriers.clear(); + // Clear command data on command buffer reset. + list_info->command_data.Clear(); - list_info->command_cpu_descriptor_handles.clear(); - list_info->command_gpu_descriptor_handles.clear(); - list_info->command_gpu_virtual_addresses.clear(); + // Clear pending resource transitions. + list_info->transition_barriers.clear(); - for (size_t i = 0; i < D3D12GraphicsCommandObjectType::NumObjectTypes; ++i) - { - list_info->command_objects[i].clear(); - } + list_info->command_cpu_descriptor_handles.clear(); + list_info->command_gpu_descriptor_handles.clear(); + list_info->command_gpu_virtual_addresses.clear(); + list_info->draw_call_count = 0; + list_info->find_target_draw_call_count = 0; + list_info->target_bundle_commandlist_info = nullptr; - // Clear pending acceleration structure builds & copies. - list_info->acceleration_structure_builds.clear(); - list_info->acceleration_structure_copies.clear(); - } + for (size_t i = 0; i < D3D12GraphicsCommandObjectType::NumObjectTypes; ++i) + { + list_info->command_objects[i].clear(); + } - if (call_id == format::ApiCallId::ApiCall_ID3D12GraphicsCommandList_Close) - { - list_info->is_closed = true; + // Clear pending acceleration structure builds & copies. + list_info->acceleration_structure_builds.clear(); + list_info->acceleration_structure_copies.clear(); + break; + case format::ApiCallId::ApiCall_ID3D12GraphicsCommandList_Close: + list_info->is_closed = true; + break; + case format::ApiCallId::ApiCall_ID3D12GraphicsCommandList_DrawInstanced: + case format::ApiCallId::ApiCall_ID3D12GraphicsCommandList_DrawIndexedInstanced: + case format::ApiCallId::ApiCall_ID3D12GraphicsCommandList_Dispatch: + case format::ApiCallId::ApiCall_ID3D12GraphicsCommandList_ExecuteIndirect: + case format::ApiCallId::ApiCall_ID3D12GraphicsCommandList_ExecuteBundle: + ++list_info->draw_call_count; + break; + default: + break; } // Append the command data. diff --git a/framework/encode/dx12_state_writer.cpp b/framework/encode/dx12_state_writer.cpp index fd52caad8..2542137ab 100644 --- a/framework/encode/dx12_state_writer.cpp +++ b/framework/encode/dx12_state_writer.cpp @@ -621,7 +621,11 @@ void Dx12StateWriter::WriteResourceCreationState( GFXRECON_LOG_DEBUG_ONCE( "Skipping resource data capture for ray tracing acceleration structure resource(s)."); } - else if (!resource_info->is_swapchain_buffer) // swapchain buffer state is handled separately. + // Writting swapchain buffer could cause extra Present during replay. It might cause different frame count. + // So only write swapchain buffer in TrimBoundary::kDrawCalls case. + // TrimBoundary::kDrawCalls needs initial render targets, + else if (!resource_info->is_swapchain_buffer || + D3D12CaptureManager::Get()->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) { // Store resource wrappers and max resource sizes. ResourceSnapshotInfo snapshot_info; @@ -787,6 +791,13 @@ void Dx12StateWriter::WriteResourceSnapshot(graphics::Dx12ResourceDataUtil* reso bool try_map_and_copy = !is_reserved_resouce && !is_texture_with_unknown_layout; + graphics::dx12::ID3D12CommandQueueComPtr queue = nullptr; + if (resource_info->swapchain_wrapper) + { + // Needs swapchain's queue to write its buffer. + auto swapchain_info = resource_info->swapchain_wrapper->GetObjectInfo(); + queue = swapchain_info->command_queue; + } // Read the data from the resource. HRESULT result = resource_data_util->ReadFromResource(resource, try_map_and_copy, @@ -794,7 +805,9 @@ void Dx12StateWriter::WriteResourceSnapshot(graphics::Dx12ResourceDataUtil* reso resource_info->subresource_transitions, temp_subresource_data_, temp_subresource_offsets_, - temp_subresource_sizes_); + temp_subresource_sizes_, + nullptr, + queue); if (SUCCEEDED(result)) { diff --git a/framework/generated/dx12_generators/capture_overrides.json b/framework/generated/dx12_generators/capture_overrides.json index 0afb3dcfc..c7c4a9704 100644 --- a/framework/generated/dx12_generators/capture_overrides.json +++ b/framework/generated/dx12_generators/capture_overrides.json @@ -1,6 +1,7 @@ { "functions": { - "CreateDXGIFactory2": "D3D12CaptureManager::Get()->OverrideCreateDXGIFactory2" + "CreateDXGIFactory2": "D3D12CaptureManager::Get()->OverrideCreateDXGIFactory2", + "D3D12SerializeVersionedRootSignature": "D3D12CaptureManager::Get()->OverrideD3D12SerializeVersionedRootSignature" }, "classmethods": { "ID3D12DescriptorHeap": { @@ -39,6 +40,16 @@ "CreateSwapChainForHwnd": "D3D12CaptureManager::Get()->OverrideIDXGIFactory2_CreateSwapChainForHwnd", "CreateSwapChainForCoreWindow": "D3D12CaptureManager::Get()->OverrideIDXGIFactory2_CreateSwapChainForCoreWindow", "CreateSwapChainForComposition": "D3D12CaptureManager::Get()->OverrideIDXGIFactory2_CreateSwapChainForComposition" + }, + "ID3D12GraphicsCommandList": { + "Reset": "D3D12CaptureManager::Get()->OverrideID3D12GraphicsCommandList_Reset", + "ExecuteBundle": "D3D12CaptureManager::Get()->OverrideID3D12GraphicsCommandList_ExecuteBundle" + }, + "ID3D12GraphicsCommandList4": { + "BeginRenderPass": "D3D12CaptureManager::Get()->OverrideID3D12GraphicsCommandList4_BeginRenderPass" + }, + "ID3D12CommandQueue": { + "ExecuteCommandLists": "D3D12CaptureManager::Get()->OverrideID3D12CommandQueue_ExecuteCommandLists" } } } diff --git a/framework/generated/dx12_generators/dx12_wrapper_body_generator.py b/framework/generated/dx12_generators/dx12_wrapper_body_generator.py index 17523db7f..115ed8986 100644 --- a/framework/generated/dx12_generators/dx12_wrapper_body_generator.py +++ b/framework/generated/dx12_generators/dx12_wrapper_body_generator.py @@ -62,6 +62,10 @@ class Dx12WrapperBodyGenerator(Dx12BaseGenerator): 'ID3D12CommandQueue': ['ExecuteCommandLists'], } + OVERRIDECALL_TRIM_TRIGGERS = { + 'ID3D12CommandQueue': ['ExecuteCommandLists'] + } + # Functions that can activate trimming from a post call command. POSTCALL_TRIM_TRIGGERS = { 'ID3D12CommandQueue': ['ExecuteCommandLists'], @@ -731,6 +735,8 @@ def write_class_member_def(self, class_info, indent=''): wrapped_args = '' unwrapped_args = '' + trim_draw_calls_wrapped_args = '' + trim_draw_calls_unwrapped_args = '' need_unwrap_memory = False if parameters: wrapped_args, unused = self.make_arg_list( @@ -739,6 +745,12 @@ def write_class_member_def(self, class_info, indent=''): unwrapped_args, need_unwrap_memory = self.make_arg_list( parameters, True, self.increment_indent(indent) ) + trim_draw_calls_wrapped_args, unused = self.make_arg_list( + parameters, False, self.increment_indent(self.increment_indent(self.increment_indent(indent))) + ) + trim_draw_calls_unwrapped_args, need_unwrap_memory = self.make_arg_list( + parameters, True, self.increment_indent(self.increment_indent(self.increment_indent(indent))) + ) # Add custom pre call action. expr += self.gen_method_pre_call( @@ -755,18 +767,24 @@ def write_class_member_def(self, class_info, indent=''): if return_type != 'void': expr += 'result = ' + is_override = False if (class_name in self.CAPTURE_OVERRIDES['classmethods']) and ( method_name in self.CAPTURE_OVERRIDES['classmethods'][class_name] ): + is_override = True expr += '{}('.format( self.CAPTURE_OVERRIDES['classmethods'][class_name] [method_name] ) + + if (class_name in self.OVERRIDECALL_TRIM_TRIGGERS) and (method_name in self.OVERRIDECALL_TRIM_TRIGGERS[class_name]): + expr += '\n'+ self.increment_indent(indent) + 'shared_api_call_lock,' + if unwrapped_args: unwrapped_args = self.increment_indent( indent - ) + 'this,\n' + unwrapped_args + ) + 'this,\n' + wrapped_args else: unwrapped_args = self.increment_indent(indent) + 'this\n' else: @@ -781,7 +799,51 @@ def write_class_member_def(self, class_info, indent=''): expr += self.gen_wrap_object(return_type, parameters, indent) + if is_override is False and 'ID3D12GraphicsCommandList' in class_name: + indent1 = self.increment_indent(indent) + indent2 = self.increment_indent(indent1) + indent3 = self.increment_indent(indent2) + indent4 = self.increment_indent(indent3) + expr += '\n' + expr += indent + 'if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls)\n' + expr += indent + '{\n' + expr += indent1 + 'manager->DecrementCallScope();\n' + expr += indent1 + 'auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_{}_{});\n'.format(class_name, method_name) + expr += indent1 + 'for(auto& command_set : trim_draw_calls_command_sets)\n' + expr += indent1 + '{\n' + + if class_name != 'ID3D12GraphicsCommandList': + expr += indent2 + 'auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr());\n' + expr += indent2 + 'auto* wrapper = static_cast<{}_Wrapper*>(base_wrapper);\n'.format(class_name) + expr += indent2 + 'GFXRECON_ASSERT(wrapper != nullptr);\n' + else: + expr += indent2 + 'auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr());\n' + + if return_type != 'void': + expr += indent2 + 'HRESULT result_trim_draw_calls = wrapper' + else: + expr += indent2 + 'wrapper' + + expr += "->{}(".format(method_name) + if trim_draw_calls_wrapped_args: + expr += "\n" + expr += trim_draw_calls_wrapped_args + expr += ");\n" + + if return_type != 'void': + expr += indent2 + 'if (result != result_trim_draw_calls)\n' + expr += indent2 + '{\n' + expr += indent3 + 'GFXRECON_LOG_WARNING("Splitting commandlists of {}::{} get different results: %s and %s",\n'.format(class_name, method_name) + expr += indent4 + 'decode::enumutil::GetResultValueString(result).c_str(),\n' + expr += indent4 + 'decode::enumutil::GetResultValueString(result_trim_draw_calls).c_str());\n' + expr += indent2 + '}\n' + + expr += indent1 + '}\n' + expr += indent1 + 'manager->IncrementCallScope();\n' + expr += indent + '}\n' + expr += '\n' + expr += indent + 'Encode_{}_{}(\n'.format(class_name, method_name) encode_args = self.increment_indent(indent) + 'this' if wrapped_args or (return_type != 'void'): @@ -954,6 +1016,7 @@ def write_include(self): code += '#include "encode/dx12_object_wrapper_util.h"\n' code += '#include "encode/dxgi_dispatch_table.h"\n' code += '#include "encode/dx12_rv_annotation_util.h"\n' + code += '#include "decode/dx12_enum_util.h"\n' code += '#include "generated/generated_dx12_api_call_encoders.h"\n' code += '#include "generated/generated_dx12_struct_unwrappers.h"\n' code += '#include "generated/generated_dx12_wrapper_creators.h"\n' diff --git a/framework/generated/generated_dx12_wrappers.cpp b/framework/generated/generated_dx12_wrappers.cpp index 24165e2a2..ea3bdc5d1 100644 --- a/framework/generated/generated_dx12_wrappers.cpp +++ b/framework/generated/generated_dx12_wrappers.cpp @@ -36,6 +36,7 @@ #include "encode/dx12_object_wrapper_util.h" #include "encode/dxgi_dispatch_table.h" #include "encode/dx12_rv_annotation_util.h" +#include "decode/dx12_enum_util.h" #include "generated/generated_dx12_api_call_encoders.h" #include "generated/generated_dx12_struct_unwrappers.h" #include "generated/generated_dx12_wrapper_creators.h" @@ -5345,11 +5346,11 @@ HRESULT STDMETHODCALLTYPE IDXGIFactory2_Wrapper::CreateSwapChainForHwnd( result = D3D12CaptureManager::Get()->OverrideIDXGIFactory2_CreateSwapChainForHwnd( this, - encode::GetWrappedObject(pDevice), + pDevice, hWnd, pDesc, pFullscreenDesc, - encode::GetWrappedObject(pRestrictToOutput), + pRestrictToOutput, ppSwapChain); if (SUCCEEDED(result)) @@ -5431,10 +5432,10 @@ HRESULT STDMETHODCALLTYPE IDXGIFactory2_Wrapper::CreateSwapChainForCoreWindow( result = D3D12CaptureManager::Get()->OverrideIDXGIFactory2_CreateSwapChainForCoreWindow( this, - encode::GetWrappedObject(pDevice), - encode::GetWrappedObject(pWindow), + pDevice, + pWindow, pDesc, - encode::GetWrappedObject(pRestrictToOutput), + pRestrictToOutput, ppSwapChain); if (SUCCEEDED(result)) @@ -5905,9 +5906,9 @@ HRESULT STDMETHODCALLTYPE IDXGIFactory2_Wrapper::CreateSwapChainForComposition( result = D3D12CaptureManager::Get()->OverrideIDXGIFactory2_CreateSwapChainForComposition( this, - encode::GetWrappedObject(pDevice), + pDevice, pDesc, - encode::GetWrappedObject(pRestrictToOutput), + pRestrictToOutput, ppSwapChain); if (SUCCEEDED(result)) @@ -9641,7 +9642,7 @@ HRESULT WINAPI D3D12SerializeVersionedRootSignature( ppBlob, ppErrorBlob); - result = manager->GetD3D12DispatchTable().D3D12SerializeVersionedRootSignature( + result = D3D12CaptureManager::Get()->OverrideD3D12SerializeVersionedRootSignature( pRootSignature, ppBlob, ppErrorBlob); @@ -11714,6 +11715,24 @@ HRESULT STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::Close() result = GetWrappedObjectAs()->Close(); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_Close); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + HRESULT result_trim_draw_calls = wrapper->Close(); + if (result != result_trim_draw_calls) + { + GFXRECON_LOG_WARNING("Splitting commandlists of ID3D12GraphicsCommandList::Close get different results: %s and %s", + decode::enumutil::GetResultValueString(result).c_str(), + decode::enumutil::GetResultValueString(result_trim_draw_calls).c_str()); + } + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_Close( this, result); @@ -11762,9 +11781,10 @@ HRESULT STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::Reset( pAllocator, pInitialState); - result = GetWrappedObjectAs()->Reset( - encode::GetWrappedObject(pAllocator), - encode::GetWrappedObject(pInitialState)); + result = D3D12CaptureManager::Get()->OverrideID3D12GraphicsCommandList_Reset( + this, + pAllocator, + pInitialState); Encode_ID3D12GraphicsCommandList_Reset( this, @@ -11819,6 +11839,19 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::ClearState( GetWrappedObjectAs()->ClearState( encode::GetWrappedObject(pPipelineState)); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_ClearState); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->ClearState( + pPipelineState); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_ClearState( this, pPipelineState); @@ -11874,6 +11907,22 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::DrawInstanced( StartVertexLocation, StartInstanceLocation); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_DrawInstanced); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->DrawInstanced( + VertexCountPerInstance, + InstanceCount, + StartVertexLocation, + StartInstanceLocation); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_DrawInstanced( this, VertexCountPerInstance, @@ -11941,6 +11990,23 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::DrawIndexedInstanced( BaseVertexLocation, StartInstanceLocation); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_DrawIndexedInstanced); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->DrawIndexedInstanced( + IndexCountPerInstance, + InstanceCount, + StartIndexLocation, + BaseVertexLocation, + StartInstanceLocation); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_DrawIndexedInstanced( this, IndexCountPerInstance, @@ -12005,6 +12071,21 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::Dispatch( ThreadGroupCountY, ThreadGroupCountZ); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_Dispatch); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->Dispatch( + ThreadGroupCountX, + ThreadGroupCountY, + ThreadGroupCountZ); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_Dispatch( this, ThreadGroupCountX, @@ -12069,6 +12150,23 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::CopyBufferRegion( SrcOffset, NumBytes); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_CopyBufferRegion); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->CopyBufferRegion( + pDstBuffer, + DstOffset, + pSrcBuffer, + SrcOffset, + NumBytes); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_CopyBufferRegion( this, pDstBuffer, @@ -12144,6 +12242,24 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::CopyTextureRegion( UnwrapStructPtrObjects(pSrc, unwrap_memory), pSrcBox); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_CopyTextureRegion); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->CopyTextureRegion( + pDst, + DstX, + DstY, + DstZ, + pSrc, + pSrcBox); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_CopyTextureRegion( this, pDst, @@ -12208,6 +12324,20 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::CopyResource( encode::GetWrappedObject(pDstResource), encode::GetWrappedObject(pSrcResource)); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_CopyResource); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->CopyResource( + pDstResource, + pSrcResource); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_CopyResource( this, pDstResource, @@ -12272,6 +12402,24 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::CopyTiles( BufferStartOffsetInBytes, Flags); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_CopyTiles); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->CopyTiles( + pTiledResource, + pTileRegionStartCoordinate, + pTileRegionSize, + pBuffer, + BufferStartOffsetInBytes, + Flags); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_CopyTiles( this, pTiledResource, @@ -12345,6 +12493,23 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::ResolveSubresource( SrcSubresource, Format); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_ResolveSubresource); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->ResolveSubresource( + pDstResource, + DstSubresource, + pSrcResource, + SrcSubresource, + Format); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_ResolveSubresource( this, pDstResource, @@ -12403,6 +12568,19 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::IASetPrimitiveTopology GetWrappedObjectAs()->IASetPrimitiveTopology( PrimitiveTopology); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_IASetPrimitiveTopology); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->IASetPrimitiveTopology( + PrimitiveTopology); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_IASetPrimitiveTopology( this, PrimitiveTopology); @@ -12452,6 +12630,20 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::RSSetViewports( NumViewports, pViewports); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_RSSetViewports); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->RSSetViewports( + NumViewports, + pViewports); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_RSSetViewports( this, NumViewports, @@ -12504,6 +12696,20 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::RSSetScissorRects( NumRects, pRects); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_RSSetScissorRects); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->RSSetScissorRects( + NumRects, + pRects); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_RSSetScissorRects( this, NumRects, @@ -12553,6 +12759,19 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::OMSetBlendFactor( GetWrappedObjectAs()->OMSetBlendFactor( BlendFactor); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_OMSetBlendFactor); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->OMSetBlendFactor( + BlendFactor); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_OMSetBlendFactor( this, BlendFactor); @@ -12599,6 +12818,19 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::OMSetStencilRef( GetWrappedObjectAs()->OMSetStencilRef( StencilRef); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_OMSetStencilRef); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->OMSetStencilRef( + StencilRef); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_OMSetStencilRef( this, StencilRef); @@ -12645,6 +12877,19 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SetPipelineState( GetWrappedObjectAs()->SetPipelineState( encode::GetWrappedObject(pPipelineState)); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SetPipelineState); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SetPipelineState( + pPipelineState); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SetPipelineState( this, pPipelineState); @@ -12696,6 +12941,20 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::ResourceBarrier( NumBarriers, UnwrapStructArrayObjects(pBarriers, NumBarriers, unwrap_memory)); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_ResourceBarrier); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->ResourceBarrier( + NumBarriers, + pBarriers); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_ResourceBarrier( this, NumBarriers, @@ -12742,8 +13001,9 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::ExecuteBundle( this, pCommandList); - GetWrappedObjectAs()->ExecuteBundle( - encode::GetWrappedObject(pCommandList)); + D3D12CaptureManager::Get()->OverrideID3D12GraphicsCommandList_ExecuteBundle( + this, + pCommandList); Encode_ID3D12GraphicsCommandList_ExecuteBundle( this, @@ -12796,6 +13056,20 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SetDescriptorHeaps( NumDescriptorHeaps, UnwrapObjects(ppDescriptorHeaps, NumDescriptorHeaps, unwrap_memory)); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SetDescriptorHeaps); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SetDescriptorHeaps( + NumDescriptorHeaps, + ppDescriptorHeaps); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SetDescriptorHeaps( this, NumDescriptorHeaps, @@ -12845,6 +13119,19 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SetComputeRootSignatur GetWrappedObjectAs()->SetComputeRootSignature( encode::GetWrappedObject(pRootSignature)); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SetComputeRootSignature); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SetComputeRootSignature( + pRootSignature); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SetComputeRootSignature( this, pRootSignature); @@ -12891,6 +13178,19 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SetGraphicsRootSignatu GetWrappedObjectAs()->SetGraphicsRootSignature( encode::GetWrappedObject(pRootSignature)); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SetGraphicsRootSignature); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SetGraphicsRootSignature( + pRootSignature); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SetGraphicsRootSignature( this, pRootSignature); @@ -12942,6 +13242,20 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SetComputeRootDescript RootParameterIndex, BaseDescriptor); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SetComputeRootDescriptorTable); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SetComputeRootDescriptorTable( + RootParameterIndex, + BaseDescriptor); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SetComputeRootDescriptorTable( this, RootParameterIndex, @@ -12996,6 +13310,20 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SetGraphicsRootDescrip RootParameterIndex, BaseDescriptor); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SetGraphicsRootDescriptorTable( + RootParameterIndex, + BaseDescriptor); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable( this, RootParameterIndex, @@ -13051,6 +13379,21 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SetComputeRoot32BitCon SrcData, DestOffsetIn32BitValues); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SetComputeRoot32BitConstant); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SetComputeRoot32BitConstant( + RootParameterIndex, + SrcData, + DestOffsetIn32BitValues); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SetComputeRoot32BitConstant( this, RootParameterIndex, @@ -13109,6 +13452,21 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SetGraphicsRoot32BitCo SrcData, DestOffsetIn32BitValues); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SetGraphicsRoot32BitConstant( + RootParameterIndex, + SrcData, + DestOffsetIn32BitValues); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstant( this, RootParameterIndex, @@ -13170,6 +13528,22 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SetComputeRoot32BitCon pSrcData, DestOffsetIn32BitValues); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SetComputeRoot32BitConstants); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SetComputeRoot32BitConstants( + RootParameterIndex, + Num32BitValuesToSet, + pSrcData, + DestOffsetIn32BitValues); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SetComputeRoot32BitConstants( this, RootParameterIndex, @@ -13234,6 +13608,22 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SetGraphicsRoot32BitCo pSrcData, DestOffsetIn32BitValues); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SetGraphicsRoot32BitConstants( + RootParameterIndex, + Num32BitValuesToSet, + pSrcData, + DestOffsetIn32BitValues); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SetGraphicsRoot32BitConstants( this, RootParameterIndex, @@ -13294,6 +13684,20 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SetComputeRootConstant RootParameterIndex, BufferLocation); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SetComputeRootConstantBufferView); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SetComputeRootConstantBufferView( + RootParameterIndex, + BufferLocation); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SetComputeRootConstantBufferView( this, RootParameterIndex, @@ -13348,6 +13752,20 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SetGraphicsRootConstan RootParameterIndex, BufferLocation); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SetGraphicsRootConstantBufferView( + RootParameterIndex, + BufferLocation); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView( this, RootParameterIndex, @@ -13402,6 +13820,20 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SetComputeRootShaderRe RootParameterIndex, BufferLocation); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SetComputeRootShaderResourceView); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SetComputeRootShaderResourceView( + RootParameterIndex, + BufferLocation); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SetComputeRootShaderResourceView( this, RootParameterIndex, @@ -13456,6 +13888,20 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SetGraphicsRootShaderR RootParameterIndex, BufferLocation); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SetGraphicsRootShaderResourceView( + RootParameterIndex, + BufferLocation); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView( this, RootParameterIndex, @@ -13510,6 +13956,20 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SetComputeRootUnordere RootParameterIndex, BufferLocation); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SetComputeRootUnorderedAccessView( + RootParameterIndex, + BufferLocation); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView( this, RootParameterIndex, @@ -13564,6 +14024,20 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SetGraphicsRootUnorder RootParameterIndex, BufferLocation); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SetGraphicsRootUnorderedAccessView); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SetGraphicsRootUnorderedAccessView( + RootParameterIndex, + BufferLocation); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SetGraphicsRootUnorderedAccessView( this, RootParameterIndex, @@ -13620,6 +14094,19 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::IASetIndexBuffer( GetWrappedObjectAs()->IASetIndexBuffer( pView); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_IASetIndexBuffer); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->IASetIndexBuffer( + pView); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_IASetIndexBuffer( this, pView); @@ -13679,6 +14166,21 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::IASetVertexBuffers( NumViews, pViews); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_IASetVertexBuffers); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->IASetVertexBuffers( + StartSlot, + NumViews, + pViews); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_IASetVertexBuffers( this, StartSlot, @@ -13744,6 +14246,21 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SOSetTargets( NumViews, pViews); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SOSetTargets); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SOSetTargets( + StartSlot, + NumViews, + pViews); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SOSetTargets( this, StartSlot, @@ -13807,6 +14324,22 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::OMSetRenderTargets( RTsSingleHandleToDescriptorRange, UnwrapStructPtrObjects(pDepthStencilDescriptor, unwrap_memory)); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_OMSetRenderTargets); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->OMSetRenderTargets( + NumRenderTargetDescriptors, + pRenderTargetDescriptors, + RTsSingleHandleToDescriptorRange, + pDepthStencilDescriptor); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_OMSetRenderTargets( this, NumRenderTargetDescriptors, @@ -13879,6 +14412,24 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::ClearDepthStencilView( NumRects, pRects); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_ClearDepthStencilView); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->ClearDepthStencilView( + DepthStencilView, + ClearFlags, + Depth, + Stencil, + NumRects, + pRects); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_ClearDepthStencilView( this, DepthStencilView, @@ -13951,6 +14502,22 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::ClearRenderTargetView( NumRects, pRects); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_ClearRenderTargetView); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->ClearRenderTargetView( + RenderTargetView, + ColorRGBA, + NumRects, + pRects); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_ClearRenderTargetView( this, RenderTargetView, @@ -14025,6 +14592,24 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::ClearUnorderedAccessVi NumRects, pRects); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_ClearUnorderedAccessViewUint); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->ClearUnorderedAccessViewUint( + ViewGPUHandleInCurrentHeap, + ViewCPUHandle, + pResource, + Values, + NumRects, + pRects); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_ClearUnorderedAccessViewUint( this, ViewGPUHandleInCurrentHeap, @@ -14105,6 +14690,24 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::ClearUnorderedAccessVi NumRects, pRects); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_ClearUnorderedAccessViewFloat); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->ClearUnorderedAccessViewFloat( + ViewGPUHandleInCurrentHeap, + ViewCPUHandle, + pResource, + Values, + NumRects, + pRects); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_ClearUnorderedAccessViewFloat( this, ViewGPUHandleInCurrentHeap, @@ -14169,6 +14772,20 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::DiscardResource( encode::GetWrappedObject(pResource), pRegion); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_DiscardResource); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->DiscardResource( + pResource, + pRegion); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_DiscardResource( this, pResource, @@ -14224,6 +14841,21 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::BeginQuery( Type, Index); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_BeginQuery); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->BeginQuery( + pQueryHeap, + Type, + Index); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_BeginQuery( this, pQueryHeap, @@ -14282,6 +14914,21 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::EndQuery( Type, Index); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_EndQuery); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->EndQuery( + pQueryHeap, + Type, + Index); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_EndQuery( this, pQueryHeap, @@ -14349,6 +14996,24 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::ResolveQueryData( encode::GetWrappedObject(pDestinationBuffer), AlignedDestinationBufferOffset); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_ResolveQueryData); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->ResolveQueryData( + pQueryHeap, + Type, + StartIndex, + NumQueries, + pDestinationBuffer, + AlignedDestinationBufferOffset); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_ResolveQueryData( this, pQueryHeap, @@ -14416,6 +15081,21 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SetPredication( AlignedBufferOffset, Operation); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SetPredication); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SetPredication( + pBuffer, + AlignedBufferOffset, + Operation); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SetPredication( this, pBuffer, @@ -14474,6 +15154,21 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::SetMarker( pData, Size); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_SetMarker); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->SetMarker( + Metadata, + pData, + Size); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_SetMarker( this, Metadata, @@ -14532,6 +15227,21 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::BeginEvent( pData, Size); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_BeginEvent); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->BeginEvent( + Metadata, + pData, + Size); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_BeginEvent( this, Metadata, @@ -14581,6 +15291,18 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::EndEvent() GetWrappedObjectAs()->EndEvent(); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_EndEvent); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->EndEvent(); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_EndEvent( this); @@ -14639,6 +15361,24 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList_Wrapper::ExecuteIndirect( encode::GetWrappedObject(pCountBuffer), CountBufferOffset); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList_ExecuteIndirect); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + wrapper->ExecuteIndirect( + pCommandSignature, + MaxCommandCount, + pArgumentBuffer, + ArgumentBufferOffset, + pCountBuffer, + CountBufferOffset); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList_ExecuteIndirect( this, pCommandSignature, @@ -14724,6 +15464,27 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList1_Wrapper::AtomicCopyBufferUINT( UnwrapObjects(ppDependentResources, Dependencies, unwrap_memory), pDependentSubresourceRanges); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList1_AtomicCopyBufferUINT); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->AtomicCopyBufferUINT( + pDstBuffer, + DstOffset, + pSrcBuffer, + SrcOffset, + Dependencies, + ppDependentResources, + pDependentSubresourceRanges); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList1_AtomicCopyBufferUINT( this, pDstBuffer, @@ -14808,6 +15569,27 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList1_Wrapper::AtomicCopyBufferUINT6 UnwrapObjects(ppDependentResources, Dependencies, unwrap_memory), pDependentSubresourceRanges); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList1_AtomicCopyBufferUINT64); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->AtomicCopyBufferUINT64( + pDstBuffer, + DstOffset, + pSrcBuffer, + SrcOffset, + Dependencies, + ppDependentResources, + pDependentSubresourceRanges); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList1_AtomicCopyBufferUINT64( this, pDstBuffer, @@ -14875,6 +15657,22 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList1_Wrapper::OMSetDepthBounds( Min, Max); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList1_OMSetDepthBounds); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->OMSetDepthBounds( + Min, + Max); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList1_OMSetDepthBounds( this, Min, @@ -14930,6 +15728,23 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList1_Wrapper::SetSamplePositions( NumPixels, pSamplePositions); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList1_SetSamplePositions); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->SetSamplePositions( + NumSamplesPerPixel, + NumPixels, + pSamplePositions); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList1_SetSamplePositions( this, NumSamplesPerPixel, @@ -15006,6 +15821,29 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList1_Wrapper::ResolveSubresourceReg Format, ResolveMode); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList1_ResolveSubresourceRegion); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->ResolveSubresourceRegion( + pDstResource, + DstSubresource, + DstX, + DstY, + pSrcResource, + SrcSubresource, + pSrcRect, + Format, + ResolveMode); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList1_ResolveSubresourceRegion( this, pDstResource, @@ -15076,6 +15914,21 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList1_Wrapper::SetViewInstanceMask( GetWrappedObjectAs()->SetViewInstanceMask( Mask); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList1_SetViewInstanceMask); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->SetViewInstanceMask( + Mask); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList1_SetViewInstanceMask( this, Mask); @@ -15139,6 +15992,23 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList2_Wrapper::WriteBufferImmediate( pParams, pModes); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList2_WriteBufferImmediate); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->WriteBufferImmediate( + Count, + pParams, + pModes); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList2_WriteBufferImmediate( this, Count, @@ -15389,9 +16259,11 @@ void STDMETHODCALLTYPE ID3D12CommandQueue_Wrapper::ExecuteCommandLists( auto unwrap_memory = manager->GetHandleUnwrapMemory(); - GetWrappedObjectAs()->ExecuteCommandLists( + D3D12CaptureManager::Get()->OverrideID3D12CommandQueue_ExecuteCommandLists( + shared_api_call_lock, + this, NumCommandLists, - UnwrapObjects(ppCommandLists, NumCommandLists, unwrap_memory)); + ppCommandLists); Encode_ID3D12CommandQueue_ExecuteCommandLists( this, @@ -18499,7 +19371,7 @@ HRESULT STDMETHODCALLTYPE ID3D12PipelineLibrary_Wrapper::LoadGraphicsPipeline( result = D3D12CaptureManager::Get()->OverrideID3D12PipelineLibrary_LoadGraphicsPipeline( this, pName, - UnwrapStructPtrObjects(pDesc, unwrap_memory), + pDesc, riid, ppPipelineState); @@ -18577,7 +19449,7 @@ HRESULT STDMETHODCALLTYPE ID3D12PipelineLibrary_Wrapper::LoadComputePipeline( result = D3D12CaptureManager::Get()->OverrideID3D12PipelineLibrary_LoadComputePipeline( this, pName, - UnwrapStructPtrObjects(pDesc, unwrap_memory), + pDesc, riid, ppPipelineState); @@ -18763,7 +19635,7 @@ HRESULT STDMETHODCALLTYPE ID3D12PipelineLibrary1_Wrapper::LoadPipeline( result = D3D12CaptureManager::Get()->OverrideID3D12PipelineLibrary1_LoadPipeline( this, pName, - UnwrapStructPtrObjects(pDesc, unwrap_memory), + pDesc, riid, ppPipelineState); @@ -19703,7 +20575,7 @@ HRESULT STDMETHODCALLTYPE ID3D12Device4_Wrapper::CreateCommittedResource1( pDesc, InitialResourceState, pOptimizedClearValue, - encode::GetWrappedObject(pProtectedSession), + pProtectedSession, riidResource, ppvResource); @@ -19791,7 +20663,7 @@ HRESULT STDMETHODCALLTYPE ID3D12Device4_Wrapper::CreateHeap1( result = D3D12CaptureManager::Get()->OverrideID3D12Device_CreateHeap1( this, pDesc, - encode::GetWrappedObject(pProtectedSession), + pProtectedSession, riid, ppvHeap); @@ -22147,7 +23019,7 @@ HRESULT STDMETHODCALLTYPE ID3D12Device8_Wrapper::CreateCommittedResource2( pDesc, InitialResourceState, pOptimizedClearValue, - encode::GetWrappedObject(pProtectedSession), + pProtectedSession, riidResource, ppvResource); @@ -22656,6 +23528,21 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList3_Wrapper::SetProtectedResourceS GetWrappedObjectAs()->SetProtectedResourceSession( encode::GetWrappedObject(pProtectedResourceSession)); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList3_SetProtectedResourceSession); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->SetProtectedResourceSession( + pProtectedResourceSession); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList3_SetProtectedResourceSession( this, pProtectedResourceSession); @@ -22789,10 +23676,11 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList4_Wrapper::BeginRenderPass( auto unwrap_memory = manager->GetHandleUnwrapMemory(); - GetWrappedObjectAs()->BeginRenderPass( + D3D12CaptureManager::Get()->OverrideID3D12GraphicsCommandList4_BeginRenderPass( + this, NumRenderTargets, - UnwrapStructArrayObjects(pRenderTargets, NumRenderTargets, unwrap_memory), - UnwrapStructPtrObjects(pDepthStencil, unwrap_memory), + pRenderTargets, + pDepthStencil, Flags); Encode_ID3D12GraphicsCommandList4_BeginRenderPass( @@ -22847,6 +23735,20 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList4_Wrapper::EndRenderPass() GetWrappedObjectAs()->EndRenderPass(); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList4_EndRenderPass); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->EndRenderPass(); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList4_EndRenderPass( this); @@ -22896,6 +23798,23 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList4_Wrapper::InitializeMetaCommand pInitializationParametersData, InitializationParametersDataSizeInBytes); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList4_InitializeMetaCommand); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->InitializeMetaCommand( + pMetaCommand, + pInitializationParametersData, + InitializationParametersDataSizeInBytes); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList4_InitializeMetaCommand( this, pMetaCommand, @@ -22954,6 +23873,23 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList4_Wrapper::ExecuteMetaCommand( pExecutionParametersData, ExecutionParametersDataSizeInBytes); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList4_ExecuteMetaCommand); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->ExecuteMetaCommand( + pMetaCommand, + pExecutionParametersData, + ExecutionParametersDataSizeInBytes); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList4_ExecuteMetaCommand( this, pMetaCommand, @@ -23027,6 +23963,23 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList4_Wrapper::BuildRaytracingAccele NumPostbuildInfoDescs, pPostbuildInfoDescs); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList4_BuildRaytracingAccelerationStructure); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->BuildRaytracingAccelerationStructure( + pDesc, + NumPostbuildInfoDescs, + pPostbuildInfoDescs); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList4_BuildRaytracingAccelerationStructure( this, pDesc, @@ -23099,6 +24052,23 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList4_Wrapper::EmitRaytracingAcceler NumSourceAccelerationStructures, pSourceAccelerationStructureData); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList4_EmitRaytracingAccelerationStructurePostbuildInfo); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->EmitRaytracingAccelerationStructurePostbuildInfo( + pDesc, + NumSourceAccelerationStructures, + pSourceAccelerationStructureData); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList4_EmitRaytracingAccelerationStructurePostbuildInfo( this, pDesc, @@ -23161,6 +24131,23 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList4_Wrapper::CopyRaytracingAcceler SourceAccelerationStructureData, Mode); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList4_CopyRaytracingAccelerationStructure); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->CopyRaytracingAccelerationStructure( + DestAccelerationStructureData, + SourceAccelerationStructureData, + Mode); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList4_CopyRaytracingAccelerationStructure( this, DestAccelerationStructureData, @@ -23213,6 +24200,21 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList4_Wrapper::SetPipelineState1( GetWrappedObjectAs()->SetPipelineState1( encode::GetWrappedObject(pStateObject)); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList4_SetPipelineState1); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->SetPipelineState1( + pStateObject); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList4_SetPipelineState1( this, pStateObject); @@ -23266,6 +24268,21 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList4_Wrapper::DispatchRays( GetWrappedObjectAs()->DispatchRays( pDesc); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList4_DispatchRays); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->DispatchRays( + pDesc); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList4_DispatchRays( this, pDesc); @@ -23792,7 +24809,7 @@ HRESULT STDMETHODCALLTYPE ID3D12Device10_Wrapper::CreateCommittedResource3( pDesc, InitialLayout, pOptimizedClearValue, - encode::GetWrappedObject(pProtectedSession), + pProtectedSession, NumCastableFormats, pCastableFormats, riidResource, @@ -25379,6 +26396,22 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList5_Wrapper::RSSetShadingRate( baseShadingRate, combiners); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList5_RSSetShadingRate); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->RSSetShadingRate( + baseShadingRate, + combiners); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList5_RSSetShadingRate( this, baseShadingRate, @@ -25428,6 +26461,21 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList5_Wrapper::RSSetShadingRateImage GetWrappedObjectAs()->RSSetShadingRateImage( encode::GetWrappedObject(shadingRateImage)); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList5_RSSetShadingRateImage); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->RSSetShadingRateImage( + shadingRateImage); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList5_RSSetShadingRateImage( this, shadingRateImage); @@ -25484,6 +26532,23 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList6_Wrapper::DispatchMesh( ThreadGroupCountY, ThreadGroupCountZ); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList6_DispatchMesh); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->DispatchMesh( + ThreadGroupCountX, + ThreadGroupCountY, + ThreadGroupCountZ); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList6_DispatchMesh( this, ThreadGroupCountX, @@ -25545,6 +26610,22 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList7_Wrapper::Barrier( NumBarrierGroups, UnwrapStructArrayObjects(pBarrierGroups, NumBarrierGroups, unwrap_memory)); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList7_Barrier); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->Barrier( + NumBarrierGroups, + pBarrierGroups); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList7_Barrier( this, NumBarrierGroups, @@ -25601,6 +26682,22 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList8_Wrapper::OMSetFrontAndBackSten FrontStencilRef, BackStencilRef); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList8_OMSetFrontAndBackStencilRef); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->OMSetFrontAndBackStencilRef( + FrontStencilRef, + BackStencilRef); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList8_OMSetFrontAndBackStencilRef( this, FrontStencilRef, @@ -25660,6 +26757,23 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList9_Wrapper::RSSetDepthBias( DepthBiasClamp, SlopeScaledDepthBias); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList9_RSSetDepthBias); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->RSSetDepthBias( + DepthBias, + DepthBiasClamp, + SlopeScaledDepthBias); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList9_RSSetDepthBias( this, DepthBias, @@ -25712,6 +26826,21 @@ void STDMETHODCALLTYPE ID3D12GraphicsCommandList9_Wrapper::IASetIndexBufferStrip GetWrappedObjectAs()->IASetIndexBufferStripCutValue( IBStripCutValue); + if(manager->GetTrimBoundary() == CaptureSettings::TrimBoundary::kDrawCalls) + { + manager->DecrementCallScope(); + auto trim_draw_calls_command_sets = manager->GetCommandListsForTrimDrawCalls(this, format::ApiCall_ID3D12GraphicsCommandList9_IASetIndexBufferStripCutValue); + for(auto& command_set : trim_draw_calls_command_sets) + { + auto* base_wrapper = reinterpret_cast(command_set.list.GetInterfacePtr()); + auto* wrapper = static_cast(base_wrapper); + GFXRECON_ASSERT(wrapper != nullptr); + wrapper->IASetIndexBufferStripCutValue( + IBStripCutValue); + } + manager->IncrementCallScope(); + } + Encode_ID3D12GraphicsCommandList9_IASetIndexBufferStripCutValue( this, IBStripCutValue); diff --git a/framework/graphics/dx12_resource_data_util.cpp b/framework/graphics/dx12_resource_data_util.cpp index e9b3f1752..ceb9b70cd 100644 --- a/framework/graphics/dx12_resource_data_util.cpp +++ b/framework/graphics/dx12_resource_data_util.cpp @@ -388,7 +388,8 @@ HRESULT Dx12ResourceDataUtil::ReadFromResource(ID3D12Resource* std::vector& data, std::vector& subresource_offsets, std::vector& subresource_sizes, - ID3D12Resource* staging_buffer_for_batching) + ID3D12Resource* staging_buffer_for_batching, + ID3D12CommandQueue* queue) { HRESULT result = E_FAIL; @@ -441,7 +442,8 @@ HRESULT Dx12ResourceDataUtil::ReadFromResource(ID3D12Resource* before_states, after_states, staging_resource, - batching); + batching, + queue); // After the command list has completed, map the copy resource and read its data. if (!batching && SUCCEEDED(result)) @@ -611,12 +613,18 @@ bool Dx12ResourceDataUtil::CopyMappableResource(ID3D12Resource* tar return SUCCEEDED(result); } -HRESULT Dx12ResourceDataUtil::ExecuteAndWaitForCommandList() +HRESULT Dx12ResourceDataUtil::ExecuteAndWaitForCommandList(ID3D12CommandQueue* queue) { // Execute the command list and wait for completion. ID3D12CommandList* cmd_lists[] = { command_list_ }; - command_queue_->ExecuteCommandLists(1, cmd_lists); - return dx12::WaitForQueue(command_queue_, command_fence_, ++fence_value_); + + ID3D12CommandQueue* command_queue = queue; + if (command_queue == nullptr) + { + command_queue = command_queue_; + } + command_queue->ExecuteCommandLists(1, cmd_lists); + return dx12::WaitForQueue(command_queue, command_fence_, ++fence_value_); // MakeResident and Evict are ref-counted. Remove the ref count added by MakeResident. for (auto resource : resident_resources) @@ -665,7 +673,7 @@ Dx12ResourceDataUtil::RecordCommandsToCopyResource( { const dx12::ResourceStateInfo common_state = { D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_BARRIER_FLAG_NONE }; const dx12::ResourceStateInfo copy_state = { copy_type == kCopyTypeRead ? D3D12_RESOURCE_STATE_COPY_SOURCE - : D3D12_RESOURCE_STATE_COPY_DEST, + : D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_BARRIER_FLAG_NONE }; uint64_t subresource_count = subresource_layouts.size(); @@ -772,7 +780,8 @@ Dx12ResourceDataUtil::ExecuteCopyCommandList(ID3D12Resource* const std::vector& before_states, const std::vector& after_states, ID3D12Resource* staging_buffer, - bool batching) + bool batching, + ID3D12CommandQueue* queue) { // Make sure the target resource is resident. ID3D12Pageable* const pageable = target_resource; @@ -816,7 +825,7 @@ Dx12ResourceDataUtil::ExecuteCopyCommandList(ID3D12Resource* result = command_list_->Close(); if (SUCCEEDED(result)) { - result = ExecuteAndWaitForCommandList(); + result = ExecuteAndWaitForCommandList(queue); } } } @@ -833,7 +842,8 @@ Dx12ResourceDataUtil::ExecuteCopyCommandList(ID3D12Resource* HRESULT Dx12ResourceDataUtil::ExecuteTransitionCommandList(ID3D12Resource* target_resource, const std::vector& before_states, - const std::vector& after_states) + const std::vector& after_states, + ID3D12CommandQueue* queue) { GFXRECON_ASSERT(before_states.size() == after_states.size()); uint64_t subresource_count = before_states.size(); @@ -859,7 +869,7 @@ Dx12ResourceDataUtil::ExecuteTransitionCommandList(ID3D12Resource* result = command_list_->Close(); if (SUCCEEDED(result) && !cmd_list_empty) { - result = ExecuteAndWaitForCommandList(); + result = ExecuteAndWaitForCommandList(queue); } } } diff --git a/framework/graphics/dx12_resource_data_util.h b/framework/graphics/dx12_resource_data_util.h index feb06d741..855f0fe3c 100644 --- a/framework/graphics/dx12_resource_data_util.h +++ b/framework/graphics/dx12_resource_data_util.h @@ -84,7 +84,8 @@ class Dx12ResourceDataUtil std::vector& data, std::vector& subresource_offsets, std::vector& subresource_sizes, - ID3D12Resource* staging_buffer_for_batching = nullptr); + ID3D12Resource* staging_buffer_for_batching = nullptr, + ID3D12CommandQueue* queue = nullptr); HRESULT WriteToResource(ID3D12Resource* target_resource, bool try_map_and_copy, @@ -99,7 +100,7 @@ class Dx12ResourceDataUtil dx12::ID3D12ResourceComPtr GetStagingBuffer(CopyType type, uint64_t required_buffer_size); dx12::ID3D12ResourceComPtr CreateStagingBuffer(CopyType type, uint64_t required_buffer_size); - HRESULT ExecuteAndWaitForCommandList(); + HRESULT ExecuteAndWaitForCommandList(ID3D12CommandQueue* queue = nullptr); // Build and execute a command list that copies data to or from the target_resource. HRESULT ResetCommandList(); @@ -114,14 +115,16 @@ class Dx12ResourceDataUtil const std::vector& before_states, const std::vector& after_states, ID3D12Resource* staging_buffer = nullptr, - bool batching = false); + bool batching = false, + ID3D12CommandQueue* queue = nullptr); // Build and execute a command list to transition the target resource's subresources from before_states to // after_states. HRESULT ExecuteTransitionCommandList(ID3D12Resource* target_resource, const std::vector& before_states, - const std::vector& after_states); + const std::vector& after_states, + ID3D12CommandQueue* queue = nullptr); private: // Copy data to or from a mappable resource. diff --git a/framework/graphics/dx12_util.cpp b/framework/graphics/dx12_util.cpp index ea8694708..408c76a0a 100644 --- a/framework/graphics/dx12_util.cpp +++ b/framework/graphics/dx12_util.cpp @@ -170,6 +170,23 @@ static uint32_t CalculateBoxRangeBC(uint32_t start, uint32_t end) return ((end + 3) / 4) - (start / 4); } +uint32_t Dx12DumpResourcePosToArrayIndex(Dx12DumpResourcePos pos) +{ + switch (pos) + { + case Dx12DumpResourcePos::kBeforeDrawCall: + return kBeforeDrawCallArrayIndex; + case Dx12DumpResourcePos::kDrawCall: + return kDrawCallArrayIndex; + case Dx12DumpResourcePos::kAfterDrawCall: + return kAfterDrawCallArrayIndex; + case Dx12DumpResourcePos::kUnknown: + default: + GFXRECON_ASSERT(false && "Invalid use of Dx12DumpResourcePosToArrayIndex."); + return 0; + } +} + UINT GetTexturePitch(UINT64 width) { return (width * graphics::BytesPerPixel + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1) / diff --git a/framework/graphics/dx12_util.h b/framework/graphics/dx12_util.h index 6dcdefc8d..21dc69540 100644 --- a/framework/graphics/dx12_util.h +++ b/framework/graphics/dx12_util.h @@ -55,8 +55,24 @@ typedef _com_ptr_t<_com_IIID> typedef _com_ptr_t<_com_IIID> ID3D12CommandAllocatorComPtr; typedef _com_ptr_t<_com_IIID> ID3D12GraphicsCommandListComPtr; +typedef _com_ptr_t<_com_IIID> + ID3D12GraphicsCommandList1ComPtr; +typedef _com_ptr_t<_com_IIID> + ID3D12GraphicsCommandList2ComPtr; +typedef _com_ptr_t<_com_IIID> + ID3D12GraphicsCommandList3ComPtr; typedef _com_ptr_t<_com_IIID> ID3D12GraphicsCommandList4ComPtr; +typedef _com_ptr_t<_com_IIID> + ID3D12GraphicsCommandList5ComPtr; +typedef _com_ptr_t<_com_IIID> + ID3D12GraphicsCommandList6ComPtr; +typedef _com_ptr_t<_com_IIID> + ID3D12GraphicsCommandList7ComPtr; +typedef _com_ptr_t<_com_IIID> + ID3D12GraphicsCommandList8ComPtr; +typedef _com_ptr_t<_com_IIID> + ID3D12GraphicsCommandList9ComPtr; typedef _com_ptr_t<_com_IIID> ID3D12DeviceRemovedExtendedData1ComPtr; typedef _com_ptr_t< @@ -70,6 +86,26 @@ typedef _com_ptr_t< ID3D12VersionedRootSignatureDeserializerComPtr; typedef _com_ptr_t<_com_IIID> ID3D12ObjectComPtr; +struct CommandSet +{ + ID3D12CommandAllocatorComPtr allocator{ nullptr }; + ID3D12GraphicsCommandListComPtr list{ nullptr }; +}; + +enum class Dx12DumpResourcePos : uint32_t +{ + kUnknown, + kBeforeDrawCall, + kDrawCall, + kAfterDrawCall, +}; + +const static uint32_t kBeforeDrawCallArrayIndex = 0; +const static uint32_t kDrawCallArrayIndex = 1; +const static uint32_t kAfterDrawCallArrayIndex = 2; + +uint32_t Dx12DumpResourcePosToArrayIndex(Dx12DumpResourcePos pos); + struct ActiveAdapterInfo { format::DxgiAdapterDesc internal_desc; diff --git a/framework/util/options.cpp b/framework/util/options.cpp index 5a9cc7f46..33ffee09d 100644 --- a/framework/util/options.cpp +++ b/framework/util/options.cpp @@ -34,7 +34,8 @@ GFXRECON_BEGIN_NAMESPACE(gfxrecon) GFXRECON_BEGIN_NAMESPACE(util) -std::vector GetUintRanges(const char* args, const char* option_name) +std::vector +GetUintRanges(const char* args, const char* option_name, bool check_overlap_range, bool allow_zero) { std::vector ranges; @@ -118,7 +119,7 @@ std::vector GetUintRanges(const char* args, const char* option_name) } // Check for invalid start range. - if (uint_range.first == 0) + if (!allow_zero && uint_range.first == 0) { GFXRECON_LOG_WARNING( "Ignoring invalid range \"%s\" for %s, with range start equal to zero", range.c_str(), option_name); @@ -134,7 +135,7 @@ std::vector GetUintRanges(const char* args, const char* option_name) next_allowed = ranges.back().last + 1; } - if (uint_range.first >= next_allowed) + if (!check_overlap_range || uint_range.first >= next_allowed) { ranges.emplace_back(std::move(uint_range)); previous_range = range; diff --git a/framework/util/options.h b/framework/util/options.h index d0a0cafc6..dda74e0d1 100644 --- a/framework/util/options.h +++ b/framework/util/options.h @@ -39,7 +39,8 @@ struct UintRange uint32_t last{ 0 }; }; -std::vector GetUintRanges(const char* args, const char* option_name); +std::vector +GetUintRanges(const char* args, const char* option_name, bool check_overlap_range = true, bool allow_zero = false); enum class ScreenshotFormat : uint32_t { diff --git a/tools/replay/desktop_main.cpp b/tools/replay/desktop_main.cpp index 958382026..2edf04ea2 100644 --- a/tools/replay/desktop_main.cpp +++ b/tools/replay/desktop_main.cpp @@ -91,9 +91,9 @@ const char kLayerEnvVar[] = "VK_INSTANCE_LAYERS"; #if defined(D3D12_SUPPORT) bool BrowseFile(const std::string& input_filename, const gfxrecon::decode::DumpResourcesTarget& dump_resources_target, - gfxrecon::decode::TrackDumpDrawcall& out_track_dump_target) + gfxrecon::decode::TrackDumpDrawCall& out_track_dump_target) { - gfxrecon::decode::TrackDumpDrawcall* track_dump_target = nullptr; + gfxrecon::decode::TrackDumpDrawCall* track_dump_target = nullptr; gfxrecon::decode::FileProcessor file_processor; if (file_processor.Initialize(input_filename)) @@ -239,7 +239,7 @@ int main(int argc, const char** argv) if (dx_replay_options.enable_dump_resources) { - gfxrecon::decode::TrackDumpDrawcall track_dump_target; + gfxrecon::decode::TrackDumpDrawCall track_dump_target; BrowseFile(filename, dx_replay_options.dump_resources_target, track_dump_target); dx12_replay_consumer.SetDumpTarget(track_dump_target); } diff --git a/tools/tool_settings.h b/tools/tool_settings.h index abffda004..82111cf0b 100644 --- a/tools/tool_settings.h +++ b/tools/tool_settings.h @@ -1149,10 +1149,10 @@ static gfxrecon::decode::DxReplayOptions GetDxReplayOptions(const gfxrecon::util std::vector values = gfxrecon::util::strings::SplitString(dump_resources, ','); if (values.size() == 3) { - replay_options.dump_resources_target.submit_index = std::stoi(values[0]); - replay_options.dump_resources_target.command_index = std::stoi(values[1]); - replay_options.dump_resources_target.drawcall_index = std::stoi(values[2]); - replay_options.enable_dump_resources = true; + replay_options.dump_resources_target.submit_index = std::stoi(values[0]); + replay_options.dump_resources_target.command_index = std::stoi(values[1]); + replay_options.dump_resources_target.draw_call_index = std::stoi(values[2]); + replay_options.enable_dump_resources = true; } }