Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added handling missing VK_EXT_swapchain_colorspace #1287

Merged
merged 7 commits into from
Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions USAGE_android.md
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,7 @@ usage: gfxrecon.py replay [-h] [--push-file LOCAL_FILE] [--version] [--pause-fra
[--measurement-file DEVICE_FILE] [--quit-after-measurement-range]
[--flush-measurement-range] [-m MODE]
[--swapchain MODE] [--use-captured-swapchain-indices]
[--colorspace-fallback]
[file]

Launch the replay tool.
Expand Down Expand Up @@ -858,6 +859,10 @@ optional arguments:
If this is specified the replayer will flush and wait
for all current GPU work to finish at the start and end
of the measurement range. (forwarded to replay tool)
--colorspace-fallback
Swap the swapchain color space if unsupported by replay device.
Check if color space is not supported by replay device and swap
to VK_COLOR_SPACE_SRGB_NONLINEAR_KHR. (forwarded to replay tool).
```

The command will force-stop an active replay process before starting the replay
Expand Down
5 changes: 5 additions & 0 deletions USAGE_desktop_Vulkan.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ gfxrecon-replay [-h | --help] [--version] [--gpu <index>]
[--flush-measurement-range]
[--log-level <level>] [--log-file <file>] [--log-debugview]
[--api <api>] [--no-debug-popup] <file>
[--colorspace-fallback]

Required arguments:
<file> Path to the capture file to replay.
Expand Down Expand Up @@ -531,6 +532,10 @@ Optional arguments:
If this is specified the replayer will flush
and wait for all current GPU work to finish at the
start and end of the measurement range.
--colorspace-fallback
Swap the swapchain color space if unsupported by replay device.
Check if color space is not supported by replay device and
fallback to VK_COLOR_SPACE_SRGB_NONLINEAR_KHR.
```

### Key Controls
Expand Down
4 changes: 4 additions & 0 deletions android/scripts/gfxrecon.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def CreateReplayParser():
parser.add_argument('--remove-unsupported', action='store_true', default=False, help='Remove unsupported extensions and features from instance and device creation parameters (forwarded to replay tool)')
parser.add_argument('--validate', action='store_true', default=False, help='Enables the Khronos Vulkan validation layer (forwarded to replay tool)')
parser.add_argument('--onhb', '--omit-null-hardware-buffers', action='store_true', default=False, help='Omit Vulkan calls that would pass a NULL AHardwareBuffer* (forwarded to replay tool)')
parser.add_argument('--colorspace-fallback', action='store_true', default=False, help='Swap the swapchain color space if unsupported by replay device. Check if color space is not supported by replay device and swap to VK_COLOR_SPACE_SRGB_NONLINEAR_KHR. (forwarded to replay tool).')
parser.add_argument('--mfr', '--measurement-frame-range', metavar='START-END', help='Custom framerange to measure FPS for. This range will include the start frame but not the end frame. The measurement frame range defaults to all frames except the loading frame but can be configured for any range. If the end frame is past the last frame in the trace it will be clamped to the frame after the last (so in that case the results would include the last frame). (forwarded to replay tool)')
parser.add_argument('--measurement-file', metavar='DEVICE_FILE', help='Write measurements to a file at the specified path. Default is: \'/sdcard/gfxrecon-measurements.json\' on android and \'./gfxrecon-measurements.json\' on desktop. (forwarded to replay tool)')
parser.add_argument('--quit-after-measurement-range', action='store_true', default=False, help='If this is specified the replayer will abort when it reaches the <end_frame> specified in the --measurement-frame-range argument. (forwarded to replay tool)')
Expand Down Expand Up @@ -165,6 +166,9 @@ def MakeExtrasString(args):

if args.use_captured_swapchain_indices:
arg_list.append('--use-captured-swapchain-indices')

if args.colorspace_fallback:
arg_list.append('--colorspace-fallback')

if args.mfr:
arg_list.append('--mfr')
Expand Down
113 changes: 94 additions & 19 deletions framework/decode/vulkan_replay_consumer_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,23 @@ const std::unordered_set<std::string> kSurfaceExtensions = {
VK_KHR_WIN32_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_EXTENSION_NAME
};

const std::unordered_set<VkColorSpaceKHR> kColorspaceSwapchainExtension = { VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT,
charles-lunarg marked this conversation as resolved.
Show resolved Hide resolved
VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT,
VK_COLOR_SPACE_BT2020_LINEAR_EXT,
VK_COLOR_SPACE_BT709_LINEAR_EXT,
VK_COLOR_SPACE_BT709_NONLINEAR_EXT,
VK_COLOR_SPACE_DCI_P3_LINEAR_EXT,
VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT,
VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT,
VK_COLOR_SPACE_DOLBYVISION_EXT,
VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT,
VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT,
VK_COLOR_SPACE_HDR10_HLG_EXT,
VK_COLOR_SPACE_HDR10_ST2084_EXT,
VK_COLOR_SPACE_PASS_THROUGH_EXT };

const VkColorSpaceKHR kAMDNativeDisplayColorspace = VK_COLOR_SPACE_DISPLAY_NATIVE_AMD;

// Device extensions to enable for trimming state setup, when available.
const std::unordered_set<std::string> kTrimStateSetupDeviceExtensions = { VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME };

Expand Down Expand Up @@ -2283,6 +2300,35 @@ VulkanReplayConsumerBase::OverrideCreateInstance(VkResult original_result,
// Remove enabled extensions that are not available from the replay instance.
feature_util::RemoveUnsupportedExtensions(available_extensions, &filtered_extensions);
}
else if (options_.colorspace_fallback)
{
if (!feature_util::IsSupportedExtension(available_extensions,
VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME))
{
auto iter = std::find_if(
filtered_extensions.begin(), filtered_extensions.end(), [](const char* extension) {
return util::platform::StringCompare(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
extension) == 0;
});
if (iter != filtered_extensions.end())
{
filtered_extensions.erase(iter);
}
}
if (!feature_util::IsSupportedExtension(available_extensions,
VK_AMD_DISPLAY_NATIVE_HDR_EXTENSION_NAME))
{
auto iter = std::find_if(
filtered_extensions.begin(), filtered_extensions.end(), [](const char* extension) {
return util::platform::StringCompare(VK_AMD_DISPLAY_NATIVE_HDR_EXTENSION_NAME,
extension) == 0;
});
if (iter != filtered_extensions.end())
{
filtered_extensions.erase(iter);
}
}
charles-lunarg marked this conversation as resolved.
Show resolved Hide resolved
}
else
{
// Remove enabled extensions that are ignorable from the replay instance.
Expand Down Expand Up @@ -4998,29 +5044,58 @@ VkResult VulkanReplayConsumerBase::OverrideCreateSwapchainKHR(

ProcessSwapchainFullScreenExclusiveInfo(pCreateInfo->GetMetaStructPointer());

if (screenshot_handler_ == nullptr)
{
result = swapchain_->CreateSwapchainKHR(original_result,
func,
device_info,
replay_create_info,
GetAllocationCallbacks(pAllocator),
pSwapchain,
GetDeviceTable(device_info->handle));
}
else
VkSwapchainCreateInfoKHR modified_create_info = (*replay_create_info);

if (screenshot_handler_ != nullptr)
{
// Screenshots are active, so ensure that swapchain images can be used as a transfer source.
VkSwapchainCreateInfoKHR modified_create_info = (*replay_create_info);
modified_create_info.imageUsage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
result = swapchain_->CreateSwapchainKHR(original_result,
func,
device_info,
&modified_create_info,
GetAllocationCallbacks(pAllocator),
pSwapchain,
GetDeviceTable(device_info->handle));
}

bool colorspace_extension_used_unsupported = false;
PhysicalDeviceInfo* physical_device_info = object_info_table_.GetPhysicalDeviceInfo(device_info->parent_id);
InstanceInfo* instance_info = object_info_table_.GetInstanceInfo(physical_device_info->parent_id);

if (kColorspaceSwapchainExtension.count(replay_create_info->imageColorSpace) != 0)
{
colorspace_extension_used_unsupported =
std::find_if(instance_info->enabled_extensions.begin(),
instance_info->enabled_extensions.end(),
[](const std::string& s) { return s == VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME; }) ==
instance_info->enabled_extensions.end();
}
else if (replay_create_info->imageColorSpace == kAMDNativeDisplayColorspace)
{
colorspace_extension_used_unsupported =
std::find_if(instance_info->enabled_extensions.begin(),
instance_info->enabled_extensions.end(),
[](const std::string& s) { return s == VK_AMD_DISPLAY_NATIVE_HDR_EXTENSION_NAME; }) ==
instance_info->enabled_extensions.end();
}

if (colorspace_extension_used_unsupported)
{
if (options_.colorspace_fallback)
{
modified_create_info.imageColorSpace = VkColorSpaceKHR::VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
GFXRECON_LOG_INFO("Forcing supported color space for swapchain (ID = %" PRIu64 ")",
swapchain_info->capture_id);
}
else
{
GFXRECON_LOG_ERROR("Swapchain (ID = %" PRIu64
") uses color space provided by unsupported VK_EXT_swapchain_colorspace",
swapchain_info->capture_id);
}
}

result = swapchain_->CreateSwapchainKHR(original_result,
func,
device_info,
&modified_create_info,
GetAllocationCallbacks(pAllocator),
pSwapchain,
GetDeviceTable(device_info->handle));
}
else
{
Expand Down
1 change: 1 addition & 0 deletions framework/decode/vulkan_replay_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ struct VulkanReplayOptions : public ReplayOptions
bool skip_failed_allocations{ false };
bool omit_pipeline_cache_data{ false };
bool remove_unsupported_features{ false };
bool colorspace_fallback{ false };
charles-lunarg marked this conversation as resolved.
Show resolved Hide resolved
util::SwapchainOption swapchain_option{ util::SwapchainOption::kVirtual };
int32_t override_gpu_group_index{ -1 };
int32_t surface_index{ -1 };
Expand Down
7 changes: 6 additions & 1 deletion tools/replay/replay_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const char kOptions[] =
"opcd|--omit-pipeline-cache-data,--remove-unsupported,--validate,--debug-device-lost,--create-dummy-allocations,--"
"screenshot-all,--onhb|--omit-null-hardware-buffers,--qamr|--quit-after-measurement-"
"range,--fmr|--flush-measurement-range,--use-captured-swapchain-indices,--dcp,--discard-cached-psos,"
"--use-cached-psos,--dx12-override-object-names";
"--colorspace-fallback,--use-cached-psos,--dx12-override-object-names";
const char kArguments[] =
"--log-level,--log-file,--gpu,--gpu-group,--pause-frame,--wsi,--surface-index,-m|--memory-translation,"
"--replace-shaders,--screenshots,--denied-messages,--allowed-messages,--screenshot-format,--"
Expand Down Expand Up @@ -64,6 +64,7 @@ static void PrintUsage(const char* exe_name)
GFXRECON_WRITE_CONSOLE("\t\t\t[-m <mode> | --memory-translation <mode>]");
GFXRECON_WRITE_CONSOLE("\t\t\t[--swapchain <mode>]");
GFXRECON_WRITE_CONSOLE("\t\t\t[--use-captured-swapchain-indices]");
GFXRECON_WRITE_CONSOLE("\t\t\t[--colorspace-fallback]");
GFXRECON_WRITE_CONSOLE("\t\t\t[--mfr|--measurement-frame-range <start-frame>-<end-frame>]");
GFXRECON_WRITE_CONSOLE("\t\t\t[--measurement-file <file>] [--quit-after-measurement-range]");
GFXRECON_WRITE_CONSOLE("\t\t\t[--flush-measurement-range]");
Expand Down Expand Up @@ -206,6 +207,10 @@ static void PrintUsage(const char* exe_name)
GFXRECON_WRITE_CONSOLE(" \t\tframe but can be configured for any range. If the end frame is past the");
GFXRECON_WRITE_CONSOLE(" \t\tlast frame in the trace it will be clamped to the frame after the last");
GFXRECON_WRITE_CONSOLE(" \t\t(so in that case the results would include the last frame).");
GFXRECON_WRITE_CONSOLE(" --colorspace-fallback");
GFXRECON_WRITE_CONSOLE(" \t\tSwap the swapchain color space if unsupported by replay device.");
GFXRECON_WRITE_CONSOLE(" \t\tCheck if color space is not supported by replay device and fallback to "
"VK_COLOR_SPACE_SRGB_NONLINEAR_KHR.");
GFXRECON_WRITE_CONSOLE(" --measurement-file <file>");
GFXRECON_WRITE_CONSOLE(" \t\tWrite measurements to a file at the specified path.");
GFXRECON_WRITE_CONSOLE(" \t\tDefault is: '/sdcard/gfxrecon-measurements.json' on android and");
Expand Down
6 changes: 6 additions & 0 deletions tools/tool_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ const char kFlushMeasurementRangeOption[] = "--flush-measurement-range";
const char kSwapchainOption[] = "--swapchain";
const char kEnableUseCapturedSwapchainIndices[] =
"--use-captured-swapchain-indices"; // The same: util::SwapchainOption::kCaptured
const char kColorspaceFallback[] = "--colorspace-fallback";
const char kFormatArgument[] = "--format";
const char kIncludeBinariesOption[] = "--include-binaries";
const char kExpandFlagsOption[] = "--expand-flags";
Expand Down Expand Up @@ -867,6 +868,11 @@ GetVulkanReplayOptions(const gfxrecon::util::ArgumentParser& arg_parse
}
}

if (arg_parser.IsOptionSet(kColorspaceFallback))
{
replay_options.colorspace_fallback = true;
}

replay_options.replace_dir = arg_parser.GetArgumentValue(kShaderReplaceArgument);
replay_options.create_resource_allocator =
GetCreateResourceAllocatorFunc(arg_parser, filename, replay_options, tracked_object_info_table);
Expand Down