Skip to content

Commit

Permalink
Added Frame Range Option to Convert Tool
Browse files Browse the repository at this point in the history
Frame range option allows to only retrieve relevant data and reduce waiting time, especially useful for  bigger traces

Change-Id: I3b7298a20c41d2c67a59069ddf31961f37a3b12d
  • Loading branch information
laurentiu-erhan-arm committed May 8, 2024
1 parent b8b598c commit ebaf99e
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 22 deletions.
4 changes: 2 additions & 2 deletions framework/util/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
GFXRECON_BEGIN_NAMESPACE(gfxrecon)
GFXRECON_BEGIN_NAMESPACE(util)

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

Expand Down Expand Up @@ -118,7 +118,7 @@ std::vector<UintRange> GetUintRanges(const char* args, const char* option_name)
}

// Check for invalid start range.
if (uint_range.first == 0)
if (uint_range.first == 0 && !include_frame_zero)
{
GFXRECON_LOG_WARNING(
"Ignoring invalid range \"%s\" for %s, with range start equal to zero", range.c_str(), option_name);
Expand Down
2 changes: 1 addition & 1 deletion framework/util/options.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ struct UintRange
uint32_t last{ 0 };
};

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

enum class ScreenshotFormat : uint32_t
{
Expand Down
127 changes: 108 additions & 19 deletions tools/convert/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ using Dx12JsonConsumer =
#endif
const char kOptions[] = "-h|--help,--version,--no-debug-popup,--file-per-frame,--include-binaries,--expand-flags";

const char kArguments[] = "--output,--format";
const char kArguments[] = "--output,--format,--frame-range";

static void PrintUsage(const char* exe_name)
{
Expand Down Expand Up @@ -81,6 +81,12 @@ static void PrintUsage(const char* exe_name)
GFXRECON_WRITE_CONSOLE(
" --file-per-frame\tCreates a new file for every frame processed. Frame number is added as a suffix");
GFXRECON_WRITE_CONSOLE(" \tto the output file name.");
GFXRECON_WRITE_CONSOLE(" --frame-range <N1[-N2][,...]>");
GFXRECON_WRITE_CONSOLE(" \tFrame ranges to be converted. In order to retrieve trim trace state,"
" frame 0 has to be in frame range.");
GFXRECON_WRITE_CONSOLE(" \tFrame ranges should be specified in ascending order and cannot "
"overlap. Frame numbering is zero-indexed and inclusive.");
GFXRECON_WRITE_CONSOLE(" \tExample: 0-2,5,8-10 will generate data for 7 frames.");

#if defined(WIN32) && defined(_DEBUG)
GFXRECON_WRITE_CONSOLE(" --no-debug-popup\tDisable the 'Abort, Retry, Ignore' message box");
Expand Down Expand Up @@ -142,6 +148,34 @@ static gfxrecon::util::JsonFormat GetOutputFormat(const gfxrecon::util::Argument
return JsonFormat::JSON;
}

static std::vector<uint32_t> GetFrameIndices(const gfxrecon::util::ArgumentParser& arg_parser)
{
const std::string& input_ranges = arg_parser.GetArgumentValue(kFrameRange);

std::vector<gfxrecon::util::UintRange> frame_ranges =
gfxrecon::util::GetUintRanges(input_ranges.c_str(), "frames to be converted", true);

std::vector<uint32_t> frame_indices;

for (uint32_t i = 0; i < frame_ranges.size(); ++i)
{
gfxrecon::util::UintRange& range = frame_ranges[i];

uint32_t diff = range.last - range.first + 1;

for (uint32_t j = 0; j < diff; ++j)
{
uint32_t frame_index = range.first + j;

frame_indices.push_back(frame_index);
}
}
std::sort(frame_indices.begin(), frame_indices.end());
std::reverse(frame_indices.begin(), frame_indices.end());

return frame_indices;
}

std::string FormatFrameNumber(uint32_t frame_number)
{
std::ostringstream stream;
Expand Down Expand Up @@ -181,18 +215,19 @@ int main(int argc, const char** argv)
}
#endif

const auto& positional_arguments = arg_parser.GetPositionalArguments();
std::string input_filename = positional_arguments[0];
JsonFormat output_format = GetOutputFormat(arg_parser);
std::string output_filename = GetOutputFileName(arg_parser, input_filename, output_format);
std::string filename_stem = gfxrecon::util::filepath::GetFilenameStem(output_filename);
std::string output_dir = gfxrecon::util::filepath::GetBasedir(output_filename);
std::string data_dir = gfxrecon::util::filepath::Join(output_dir, filename_stem);
bool dump_binaries = arg_parser.IsOptionSet(kIncludeBinariesOption);
bool expand_flags = arg_parser.IsOptionSet(kExpandFlagsOption);
bool file_per_frame = arg_parser.IsOptionSet(kFilePerFrameOption);
bool output_to_stdout = output_filename == "stdout";

const auto& positional_arguments = arg_parser.GetPositionalArguments();
std::string input_filename = positional_arguments[0];
JsonFormat output_format = GetOutputFormat(arg_parser);
std::string output_filename = GetOutputFileName(arg_parser, input_filename, output_format);
std::string filename_stem = gfxrecon::util::filepath::GetFilenameStem(output_filename);
std::string output_dir = gfxrecon::util::filepath::GetBasedir(output_filename);
std::string data_dir = gfxrecon::util::filepath::Join(output_dir, filename_stem);
std::vector<uint32_t> frame_indices = GetFrameIndices(arg_parser);
bool frame_range_option = !arg_parser.GetArgumentValue(kFrameRange).empty();
bool dump_binaries = arg_parser.IsOptionSet(kIncludeBinariesOption);
bool expand_flags = arg_parser.IsOptionSet(kExpandFlagsOption);
bool file_per_frame = arg_parser.IsOptionSet(kFilePerFrameOption);
bool output_to_stdout = output_filename == "stdout";
gfxrecon::decode::FileProcessor file_processor;

#ifndef CONVERT_EXPERIMENTAL_D3D12
Expand Down Expand Up @@ -223,8 +258,14 @@ int main(int argc, const char** argv)
{
std::string json_filename;
FILE* out_file_handle = nullptr;
FILE* tmp_file_handle = nullptr;

if (file_per_frame)
if (file_per_frame && frame_range_option)
{
json_filename = gfxrecon::util::filepath::InsertFilenamePostfix(
output_filename, +"_" + FormatFrameNumber(frame_indices.back()));
}
else if (file_per_frame)
{
json_filename = gfxrecon::util::filepath::InsertFilenamePostfix(
output_filename, +"_" + FormatFrameNumber(file_processor.GetCurrentFrameNumber()));
Expand Down Expand Up @@ -272,27 +313,71 @@ int main(int argc, const char** argv)
json_consumer.Initialize(&json_writer, vulkan_version);
json_writer.StartStream(&out_stream);

if (frame_range_option)
{
tmp_file_handle = tmpfile();
if (tmp_file_handle == nullptr)
{
ret_code = 1;
success = false;
GFXRECON_LOG_ERROR("Failed to create temp file");
}
if (frame_indices.back() == file_processor.GetCurrentFrameNumber())
{
out_stream.Reset(out_file_handle);
frame_indices.pop_back();
}
else
{
out_stream.Reset(tmp_file_handle);
}
}
// If CONVERT_EXPERIMENTAL_D3D12 was set, then add DX12 consumer/decoder
#ifdef CONVERT_EXPERIMENTAL_D3D12
Dx12JsonConsumer dx12_json_consumer;
gfxrecon::decode::Dx12Decoder dx12_decoder;
Dx12JsonConsumer dx12_json_consumer;
gfxrecon::decode::Dx12Decoder dx12_decoder;

dx12_decoder.AddConsumer(&dx12_json_consumer);
file_processor.AddDecoder(&dx12_decoder);
auto dx12_json_flags = output_format == JsonFormat::JSON ? gfxrecon::util::kToString_Formatted
: gfxrecon::util::kToString_Unformatted;
dx12_json_consumer.Initialize(&json_writer);
#endif

while (success)
{
success = file_processor.ProcessNextFrame();

if (success && frame_range_option)
{
if (frame_indices.empty())
{
break;
}

if (frame_indices.back() == file_processor.GetCurrentFrameNumber())
{
out_stream.Reset(out_file_handle);
json_filename = gfxrecon::util::filepath::InsertFilenamePostfix(
output_filename, +"_" + FormatFrameNumber(frame_indices.back()));
frame_indices.pop_back();
}
else
{
out_stream.Reset(tmp_file_handle);
continue;
}
}
if (success && file_per_frame)
{
json_writer.EndStream();
gfxrecon::util::platform::FileClose(out_file_handle);
json_filename = gfxrecon::util::filepath::InsertFilenamePostfix(
output_filename, +"_" + FormatFrameNumber(file_processor.GetCurrentFrameNumber()));

json_filename =
(frame_range_option)
? json_filename
: gfxrecon::util::filepath::InsertFilenamePostfix(
output_filename, +"_" + FormatFrameNumber(file_processor.GetCurrentFrameNumber()));

gfxrecon::util::platform::FileOpen(&out_file_handle, json_filename.c_str(), "w");
success = out_file_handle != nullptr;
if (success)
Expand All @@ -312,6 +397,10 @@ int main(int argc, const char** argv)
#ifdef CONVERT_EXPERIMENTAL_D3D12
dx12_json_consumer.Destroy();
#endif
if (tmp_file_handle != nullptr)
{
gfxrecon::util::platform::FileClose(tmp_file_handle);
}
if (!output_to_stdout)
{
gfxrecon::util::platform::FileClose(out_file_handle);
Expand Down
1 change: 1 addition & 0 deletions tools/tool_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ const char kFormatArgument[] = "--format";
const char kIncludeBinariesOption[] = "--include-binaries";
const char kExpandFlagsOption[] = "--expand-flags";
const char kFilePerFrameOption[] = "--file-per-frame";
const char kFrameRange[] = "--frame-range";
const char kSkipGetFenceStatus[] = "--skip-get-fence-status";
const char kSkipGetFenceRanges[] = "--skip-get-fence-ranges";
const char kWaitBeforePresent[] = "--wait-before-present";
Expand Down

0 comments on commit ebaf99e

Please sign in to comment.