Skip to content

Commit

Permalink
Trim drawcalls chages to 0-based
Browse files Browse the repository at this point in the history
  • Loading branch information
locke-lunarg committed Aug 22, 2024
1 parent 2f5d0bf commit 9c19f41
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 43 deletions.
2 changes: 1 addition & 1 deletion USAGE_desktop_D3D12.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +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 Drawcalls | GFXRECON_CAPTURE_DRAWCALLS | 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 1-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 drawcalls(option), like "1,1,1" or "1,1,1-2" or "1,1,1-2,1". 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 1 as default. Default is: Empty string (all drawcalls are captured).
Capture Specific Drawcalls | GFXRECON_CAPTURE_DRAWCALLS | 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 drawcalls(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 drawcalls 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`
Expand Down
7 changes: 7 additions & 0 deletions framework/encode/capture_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,11 @@ 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("Trimming queue submits will be changed to 0-based.");
}

trim_ranges_ = trace_settings.trim_ranges;

// Determine if trim starts at the first frame
Expand Down Expand Up @@ -906,6 +911,8 @@ void CommonCaptureManager::EndFrame(format::ApiFamilyId api_family)

void CommonCaptureManager::PreQueueSubmit(format::ApiFamilyId api_family)
{
// ++ 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))
Expand Down
44 changes: 19 additions & 25 deletions framework/encode/capture_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -511,32 +511,25 @@ void CaptureSettings::ProcessOptions(OptionsMap* options, CaptureSettings* setti
if (!trim_drawcalls.empty())
{
std::vector<util::UintRange> trim_values;
ParseUintRangeList(trim_drawcalls, &trim_values, "capture drawcalls", false);
ParseUintRangeList(trim_drawcalls, &trim_values, "capture drawcalls", false, true);
if (trim_values.size() == 3 || trim_values.size() == 4)
{
if (trim_values[0].first != 0)
settings->trace_settings_.trim_drawcalls.submit_index = trim_values[0].first;
settings->trace_settings_.trim_drawcalls.command_index = trim_values[1].first;
settings->trace_settings_.trim_drawcalls.drawcall_indices.first = trim_values[2].first;
settings->trace_settings_.trim_drawcalls.drawcall_indices.last = trim_values[2].last;
settings->trace_settings_.trim_boundary = TrimBoundary::kDrawcalls;

if (trim_values.size() == 4)
{
settings->trace_settings_.trim_drawcalls.bundle_drawcall_indices.first = trim_values[3].first;
settings->trace_settings_.trim_drawcalls.bundle_drawcall_indices.last = trim_values[3].last;
}
else
{
settings->trace_settings_.trim_drawcalls.submit_index = trim_values[0].first;
if (trim_values[1].first != 0)
{
settings->trace_settings_.trim_drawcalls.command_index = trim_values[1].first;
if (trim_values[2].first != 0)
{
settings->trace_settings_.trim_drawcalls.drawcall_indices.first = trim_values[2].first;
settings->trace_settings_.trim_drawcalls.drawcall_indices.last = trim_values[2].last;
settings->trace_settings_.trim_boundary = TrimBoundary::kDrawcalls;

// bundle_drawcall_indices is the 4th arg. The default it 1 if it doesn't set.
settings->trace_settings_.trim_drawcalls.bundle_drawcall_indices.first = 1;
settings->trace_settings_.trim_drawcalls.bundle_drawcall_indices.last = 1;
}

if (trim_values.size() == 4 && trim_values[3].first != 0)
{
settings->trace_settings_.trim_drawcalls.bundle_drawcall_indices.first = trim_values[3].first;
settings->trace_settings_.trim_drawcalls.bundle_drawcall_indices.last = trim_values[3].last;
}
}
// bundle_drawcall_indices is the 4th arg. The default is 0 if it doesn't set.
settings->trace_settings_.trim_drawcalls.bundle_drawcall_indices.first = 0;
settings->trace_settings_.trim_drawcalls.bundle_drawcall_indices.last = 0;
}
}
}
Expand Down Expand Up @@ -876,14 +869,15 @@ util::Log::Severity CaptureSettings::ParseLogLevelString(const std::string& val
void CaptureSettings::ParseUintRangeList(const std::string& value_string,
std::vector<util::UintRange>* frames,
const char* option_name,
bool check_overlap_range)
bool check_overlap_range,
bool allow_zero)
{
GFXRECON_ASSERT(frames != nullptr);

if (!value_string.empty())
{
std::vector<gfxrecon::util::UintRange> frame_ranges =
util::GetUintRanges(value_string.c_str(), option_name, check_overlap_range);
util::GetUintRanges(value_string.c_str(), option_name, check_overlap_range, allow_zero);

for (uint32_t i = 0; i < frame_ranges.size(); ++i)
{
Expand Down
5 changes: 3 additions & 2 deletions framework/encode/capture_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class CaptureSettings

struct TrimDrawcalls
{
// 1-based
// 0-based
uint32_t submit_index{ 0 };
uint32_t command_index{ 0 };
util::UintRange drawcall_indices;
Expand Down Expand Up @@ -198,7 +198,8 @@ class CaptureSettings
static void ParseUintRangeList(const std::string& value_string,
std::vector<util::UintRange>* frames,
const char* option_name,
bool check_overlap_range = true);
bool check_overlap_range = true,
bool allow_zero = false);

static std::string ParseTrimKeyString(const std::string& value_string);

Expand Down
24 changes: 12 additions & 12 deletions framework/encode/d3d12_capture_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1730,8 +1730,8 @@ void D3D12CaptureManager::PreProcess_ID3D12CommandQueue_ExecuteCommandLists(ID3D

if (IsTrimEnabled() && GetTrimBundary() == CaptureSettings::TrimBoundary::kDrawcalls)
{
CaptureSettings::TrimDrawcalls trim_drawcalls = GetTrimDrawcalls();
if (common_manager_->GetQueueSubmitCount() == (trim_drawcalls.submit_index - 1))
auto trim_drawcalls = GetTrimDrawcalls();
if (common_manager_->GetQueueSubmitCount() == trim_drawcalls.submit_index)
{
// before of lists and splitted
std::vector<ID3D12CommandList*> cmdlists;
Expand All @@ -1740,7 +1740,7 @@ void D3D12CaptureManager::PreProcess_ID3D12CommandQueue_ExecuteCommandLists(ID3D
cmdlists.emplace_back(lists[i]);
}

auto target_cmdlist = lists[trim_drawcalls.command_index-1];
auto target_cmdlist = lists[trim_drawcalls.command_index];
ID3D12CommandList_Wrapper* target_wrapper = nullptr;
target_cmdlist->QueryInterface(IID_IUnknown_Wrapper, reinterpret_cast<void**>(&target_wrapper));
GFXRECON_ASSERT(target_wrapper);
Expand Down Expand Up @@ -1818,15 +1818,15 @@ void D3D12CaptureManager::OverrideID3D12CommandQueue_ExecuteCommandLists(ID3D12C
bool is_complete = false;
if (IsTrimEnabled() && GetTrimBundary() == CaptureSettings::TrimBoundary::kDrawcalls)
{
CaptureSettings::TrimDrawcalls trim_drawcalls = GetTrimDrawcalls();
if (common_manager_->GetQueueSubmitCount() == trim_drawcalls.submit_index)
auto trim_drawcalls = GetTrimDrawcalls();
if ((common_manager_->GetQueueSubmitCount() - 1) == trim_drawcalls.submit_index)
{
common_manager_->ActivateTrimmingDrawcalls(format::ApiFamilyId::ApiFamily_D3D12);

std::vector<ID3D12CommandList*> cmdlists;

// target of splitted
auto target_cmdlist = lists[trim_drawcalls.command_index - 1];
auto target_cmdlist = lists[trim_drawcalls.command_index];
ID3D12CommandList_Wrapper* target_wrapper = nullptr;
target_cmdlist->QueryInterface(IID_IUnknown_Wrapper, reinterpret_cast<void**>(&target_wrapper));
GFXRECON_ASSERT(target_wrapper);
Expand Down Expand Up @@ -3365,24 +3365,24 @@ D3D12CaptureManager::GetCommandListsForTrimDrawcalls(ID3D12CommandList_Wrapper*

if (cmd_list_info->command_list_type == D3D12_COMMAND_LIST_TYPE_BUNDLE)
{
if ((cmd_list_info->drawcall_count >= (trim_drawcalls.bundle_drawcall_indices.first - 1)) &&
(cmd_list_info->drawcall_count < trim_drawcalls.bundle_drawcall_indices.last))
if ((cmd_list_info->drawcall_count >= trim_drawcalls.bundle_drawcall_indices.first) &&
(cmd_list_info->drawcall_count <= trim_drawcalls.bundle_drawcall_indices.last))
{
split_type = graphics::dx12::Dx12DumpResourcePos::kDrawCall;
}
else if (cmd_list_info->drawcall_count >= trim_drawcalls.bundle_drawcall_indices.last)
else if (cmd_list_info->drawcall_count > trim_drawcalls.bundle_drawcall_indices.last)
{
split_type = graphics::dx12::Dx12DumpResourcePos::kAfterDrawCall;
}
}
else
{
if ((cmd_list_info->drawcall_count >= (trim_drawcalls.drawcall_indices.first - 1)) &&
(cmd_list_info->drawcall_count < trim_drawcalls.drawcall_indices.last))
if ((cmd_list_info->drawcall_count >= trim_drawcalls.drawcall_indices.first) &&
(cmd_list_info->drawcall_count <= trim_drawcalls.drawcall_indices.last))
{
split_type = graphics::dx12::Dx12DumpResourcePos::kDrawCall;
}
else if (cmd_list_info->drawcall_count >= trim_drawcalls.drawcall_indices.last)
else if (cmd_list_info->drawcall_count > trim_drawcalls.drawcall_indices.last)
{
split_type = graphics::dx12::Dx12DumpResourcePos::kAfterDrawCall;
}
Expand Down
5 changes: 3 additions & 2 deletions framework/util/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@
GFXRECON_BEGIN_NAMESPACE(gfxrecon)
GFXRECON_BEGIN_NAMESPACE(util)

std::vector<UintRange> GetUintRanges(const char* args, const char* option_name, bool check_overlap_range)
std::vector<UintRange>
GetUintRanges(const char* args, const char* option_name, bool check_overlap_range, bool allow_zero)
{
std::vector<UintRange> ranges;

Expand Down Expand Up @@ -118,7 +119,7 @@ std::vector<UintRange> 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);
Expand Down
3 changes: 2 additions & 1 deletion framework/util/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ struct UintRange
uint32_t last{ 0 };
};

std::vector<UintRange> GetUintRanges(const char* args, const char* option_name, bool check_overlap_range = true);
std::vector<UintRange>
GetUintRanges(const char* args, const char* option_name, bool check_overlap_range = true, bool allow_zero = false);

enum class ScreenshotFormat : uint32_t
{
Expand Down

0 comments on commit 9c19f41

Please sign in to comment.