Skip to content

Commit

Permalink
Refactor parsing of integer ranges for options
Browse files Browse the repository at this point in the history
  • Loading branch information
davidd-lunarg committed Jun 28, 2023
1 parent f76cd3e commit 077e853
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 208 deletions.
23 changes: 14 additions & 9 deletions framework/encode/capture_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,14 +188,14 @@ void CaptureManager::DestroyInstance(std::function<const CaptureManager*()> GetI
}
}

std::vector<uint32_t> CalcScreenshotIndices(std::vector<util::FrameRange> ranges)
std::vector<uint32_t> CalcScreenshotIndices(std::vector<util::UintRange> ranges)
{
// Take a range of frames and convert it to a flat list of indices
std::vector<uint32_t> indices;

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

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

Expand Down Expand Up @@ -320,7 +320,13 @@ bool CaptureManager::Initialize(std::string base_filename, const CaptureSettings
{
// Override default kModeWrite capture mode.
trim_enabled_ = true;
trim_ranges_ = trace_settings.trim_ranges;
std::transform(trace_settings.trim_ranges.begin(),
trace_settings.trim_ranges.end(),
std::back_inserter(trim_ranges_),
[](const util::UintRange& range) {
GFXRECON_ASSERT(range.last >= range.first);
return TrimRange({ range.first, (range.last - range.first + 1) });
});

// Determine if trim starts at the first frame
if (!trace_settings.trim_ranges.empty())
Expand Down Expand Up @@ -610,8 +616,8 @@ void CaptureManager::CheckContinueCaptureForWriteMode()
{
// Trimming was configured to capture two consecutive frames, so we need to start a new capture
// file for the current frame.
const CaptureSettings::TrimRange& trim_range = trim_ranges_[trim_current_range_];
bool success = CreateCaptureFile(CreateTrimFilename(base_filename_, trim_range));
const TrimRange& trim_range = trim_ranges_[trim_current_range_];
bool success = CreateCaptureFile(CreateTrimFilename(base_filename_, trim_range));
if (success)
{
ActivateTrimming();
Expand Down Expand Up @@ -641,8 +647,8 @@ void CaptureManager::CheckStartCaptureForTrackMode()
{
if (trim_ranges_[trim_current_range_].first == current_frame_)
{
const CaptureSettings::TrimRange& trim_range = trim_ranges_[trim_current_range_];
bool success = CreateCaptureFile(CreateTrimFilename(base_filename_, trim_range));
const TrimRange& trim_range = trim_ranges_[trim_current_range_];
bool success = CreateCaptureFile(CreateTrimFilename(base_filename_, trim_range));
if (success)
{
ActivateTrimming();
Expand Down Expand Up @@ -730,8 +736,7 @@ void CaptureManager::EndFrame()
}
}

std::string CaptureManager::CreateTrimFilename(const std::string& base_filename,
const CaptureSettings::TrimRange& trim_range)
std::string CaptureManager::CreateTrimFilename(const std::string& base_filename, const TrimRange& trim_range)
{
assert(trim_range.total > 0);

Expand Down
10 changes: 8 additions & 2 deletions framework/encode/capture_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,12 @@ class CaptureManager
std::vector<uint8_t> scratch_buffer_;
};

struct TrimRange
{
uint32_t first{ 0 }; // First frame to capture.
uint32_t total{ 0 }; // Total number of frames to capture.
};

protected:
static bool CreateInstance(std::function<CaptureManager*()> GetInstanceFunc, std::function<void()> NewInstanceFunc);

Expand Down Expand Up @@ -240,7 +246,7 @@ class CaptureManager
bool GetDisableDxrSetting() const { return disable_dxr_; }
auto GetAccelStructPaddingSetting() const { return accel_struct_padding_; }

std::string CreateTrimFilename(const std::string& base_filename, const CaptureSettings::TrimRange& trim_range);
std::string CreateTrimFilename(const std::string& base_filename, const TrimRange& trim_range);
bool CreateCaptureFile(const std::string& base_filename);
void ActivateTrimming();
void DeactivateTrimming();
Expand Down Expand Up @@ -308,7 +314,7 @@ class CaptureManager
bool page_guard_signal_handler_watcher_;
PageGuardMemoryMode page_guard_memory_mode_;
bool trim_enabled_;
std::vector<CaptureSettings::TrimRange> trim_ranges_;
std::vector<TrimRange> trim_ranges_;
std::string trim_key_;
uint32_t trim_key_frames_;
uint32_t trim_key_first_frame_;
Expand Down
141 changes: 10 additions & 131 deletions framework/encode/capture_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,8 @@ void CaptureSettings::ProcessOptions(OptionsMap* options, CaptureSettings* setti
// trim ranges and trim hotkey are exclusive
// with trim key will be parsed only
// if trim ranges is empty, else it will be ignored
ParseTrimRangeString(FindOption(options, kOptionKeyCaptureFrames), &settings->trace_settings_.trim_ranges);
ParseUintRangeList(
FindOption(options, kOptionKeyCaptureFrames), &settings->trace_settings_.trim_ranges, "capture frames");
std::string trim_key_option = FindOption(options, kOptionKeyCaptureTrigger);
std::string trim_key_frames_option = FindOption(options, kOptionKeyCaptureTriggerFrames);
if (!trim_key_option.empty())
Expand Down Expand Up @@ -524,7 +525,9 @@ void CaptureSettings::ProcessOptions(OptionsMap* options, CaptureSettings* setti
// Screenshot options
settings->trace_settings_.screenshot_dir =
FindOption(options, kOptionKeyScreenshotDir, settings->trace_settings_.screenshot_dir);
ParseFramesList(FindOption(options, kOptionKeyScreenshotFrames), &settings->trace_settings_.screenshot_ranges);
ParseUintRangeList(FindOption(options, kOptionKeyScreenshotFrames),
&settings->trace_settings_.screenshot_ranges,
"screenshot frames");
settings->trace_settings_.screenshot_format = ParseScreenshotFormatString(
FindOption(options, kOptionKeyScreenshotFormat), settings->trace_settings_.screenshot_format);

Expand Down Expand Up @@ -767,143 +770,19 @@ util::Log::Severity CaptureSettings::ParseLogLevelString(const std::string& val
return result;
}

void CaptureSettings::ParseTrimRangeString(const std::string& value_string,
std::vector<CaptureSettings::TrimRange>* ranges)
{
assert(ranges != nullptr);

if (!value_string.empty())
{
std::istringstream value_string_input;
value_string_input.str(value_string);

for (std::string range; std::getline(value_string_input, range, ',');)
{
if (range.empty() || (std::count(range.begin(), range.end(), '-') > 1))
{
GFXRECON_LOG_WARNING("Settings Loader: Ignoring invalid capture frame range \"%s\"", range.c_str());
continue;
}

util::strings::RemoveWhitespace(range);

// Split string on '-' delimiter.
bool invalid = false;
std::vector<std::string> values;
std::istringstream range_input;
range_input.str(range);

for (std::string value; std::getline(range_input, value, '-');)
{
if (value.empty())
{
break;
}

// Check that the value string only contains numbers.
size_t count = std::count_if(value.begin(), value.end(), ::isdigit);
if (count == value.length())
{
values.push_back(value);
}
else
{
GFXRECON_LOG_WARNING("Settings Loader: Ignoring invalid capture frame range \"%s\", which contains "
"non-numeric values",
range.c_str());
invalid = true;
break;
}
}

if (!invalid)
{
CaptureSettings::TrimRange trim_range;

if (values.size() == 1)
{
if (std::count(range.begin(), range.end(), '-') == 0)
{
trim_range.first = std::stoi(values[0]);
trim_range.total = 1;
}
else
{
GFXRECON_LOG_WARNING("Settings Loader: Ignoring invalid capture frame range \"%s\"",
range.c_str());
continue;
}
}
else if (values.size() == 2)
{
trim_range.first = std::stoi(values[0]);

uint32_t last = std::stoi(values[1]);
if (last >= trim_range.first)
{
trim_range.total = (last - trim_range.first) + 1;
}
else
{
GFXRECON_LOG_WARNING(
"Settings Loader: Ignoring invalid capture frame range \"%s\", where first "
"frame is greater than last frame",
range.c_str());
continue;
}
}
else
{
GFXRECON_LOG_WARNING("Settings Loader: Ignoring invalid capture frame range \"%s\"", range.c_str());
continue;
}

// Check for invalid start frame of 0.
if (trim_range.first == 0)
{
GFXRECON_LOG_WARNING(
"Settings Loader: Ignoring invalid capture frame range \"%s\", with first frame equal to zero",
range.c_str());
continue;
}

uint32_t next_allowed = 0;

// Check that start frame is outside the bounds of the previous range.
if (!ranges->empty())
{
// This produces the number of the frame after the last frame in the range.
next_allowed = ranges->back().first + ranges->back().total;
}

if (trim_range.first >= next_allowed)
{
ranges->emplace_back(trim_range);
}
else
{
GFXRECON_LOG_WARNING("Settings Loader: Ignoring invalid capture frame range \"%s\", "
"where start frame precedes the end of the previous range \"%u-%u\"",
range.c_str(),
ranges->back().first,
(next_allowed - 1));
}
}
}
}
}

void CaptureSettings::ParseFramesList(const std::string& value_string, std::vector<util::FrameRange>* frames)
void CaptureSettings::ParseUintRangeList(const std::string& value_string,
std::vector<util::UintRange>* frames,
const char* option_name)
{
GFXRECON_ASSERT(frames != nullptr);

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

for (uint32_t i = 0; i < frame_ranges.size(); ++i)
{
util::FrameRange range{};
util::UintRange range{};
range.first = frame_ranges[i].first;
range.last = frame_ranges[i].last;
frames->push_back(range);
Expand Down
63 changes: 28 additions & 35 deletions framework/encode/capture_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,6 @@ class CaptureSettings
kDisabled = 2
};

struct TrimRange
{
uint32_t first{ 0 }; // First frame to capture.
uint32_t total{ 0 }; // Total number of frames to capture.
};

const static char kDefaultCaptureFileName[];

struct ResourveValueAnnotationInfo
Expand All @@ -83,32 +77,32 @@ class CaptureSettings

struct TraceSettings
{
std::string capture_file{ kDefaultCaptureFileName };
format::EnabledOptions capture_file_options;
bool time_stamp_file{ true };
bool force_flush{ false };
MemoryTrackingMode memory_tracking_mode{ kPageGuard };
std::string screenshot_dir;
std::vector<util::FrameRange> screenshot_ranges;
util::ScreenshotFormat screenshot_format;
std::vector<TrimRange> trim_ranges;
std::string trim_key;
uint32_t trim_key_frames{ 0 };
RuntimeTriggerState runtime_capture_trigger{ kNotUsed };
int page_guard_signal_handler_watcher_max_restores{ 1 };
bool page_guard_copy_on_map{ util::PageGuardManager::kDefaultEnableCopyOnMap };
bool page_guard_separate_read{ util::PageGuardManager::kDefaultEnableSeparateRead };
bool page_guard_persistent_memory{ false };
bool page_guard_align_buffer_sizes{ false };
bool page_guard_track_ahb_memory{ false };
bool page_guard_unblock_sigsegv{ false };
bool page_guard_signal_handler_watcher{ false };
bool debug_layer{ false };
bool debug_device_lost{ false };
bool disable_dxr{ false };
uint32_t accel_struct_padding{ 0 };
bool force_command_serialization{ false };
bool queue_zero_only{ false };
std::string capture_file{ kDefaultCaptureFileName };
format::EnabledOptions capture_file_options;
bool time_stamp_file{ true };
bool force_flush{ false };
MemoryTrackingMode memory_tracking_mode{ kPageGuard };
std::string screenshot_dir;
std::vector<util::UintRange> screenshot_ranges;
util::ScreenshotFormat screenshot_format;
std::vector<util::UintRange> trim_ranges;
std::string trim_key;
uint32_t trim_key_frames{ 0 };
RuntimeTriggerState runtime_capture_trigger{ kNotUsed };
int page_guard_signal_handler_watcher_max_restores{ 1 };
bool page_guard_copy_on_map{ util::PageGuardManager::kDefaultEnableCopyOnMap };
bool page_guard_separate_read{ util::PageGuardManager::kDefaultEnableSeparateRead };
bool page_guard_persistent_memory{ false };
bool page_guard_align_buffer_sizes{ false };
bool page_guard_track_ahb_memory{ false };
bool page_guard_unblock_sigsegv{ false };
bool page_guard_signal_handler_watcher{ false };
bool debug_layer{ false };
bool debug_device_lost{ false };
bool disable_dxr{ false };
uint32_t accel_struct_padding{ 0 };
bool force_command_serialization{ false };
bool queue_zero_only{ false };

// An optimization for the page_guard memory tracking mode that eliminates the need for shadow memory by
// overriding vkAllocateMemory so that all host visible allocations use the external memory extension with a
Expand Down Expand Up @@ -175,9 +169,8 @@ class CaptureSettings

static util::Log::Severity ParseLogLevelString(const std::string& value_string, util::Log::Severity default_value);

static void ParseFramesList(const std::string& value_string, std::vector<util::FrameRange>* frames);

static void ParseTrimRangeString(const std::string& value_string, std::vector<CaptureSettings::TrimRange>* ranges);
static void
ParseUintRangeList(const std::string& value_string, std::vector<util::UintRange>* frames, const char* option_name);

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

Expand Down
Loading

0 comments on commit 077e853

Please sign in to comment.