From 54d7296051e07b6e3b1fba635812f32640ad8001 Mon Sep 17 00:00:00 2001 From: Bartosz Muszarski Date: Mon, 12 Jun 2023 23:25:34 +0200 Subject: [PATCH] Add wait before present option Force wait on completion of queue operations for all queues before calling Present. This is needed for accurate acquisition of instrumentation data on some platforms. Change-Id: Ie5c07df95ad4420ed516f6f59c719d91887fa73a --- USAGE_android.md | 6 +++++- USAGE_desktop_Vulkan.md | 9 ++++++--- android/scripts/gfxrecon.py | 4 ++++ framework/decode/vulkan_replay_consumer_base.cpp | 6 ++++++ framework/decode/vulkan_replay_options.h | 1 + tools/replay/replay_settings.h | 6 +++++- tools/tool_settings.h | 5 +++++ 7 files changed, 32 insertions(+), 5 deletions(-) diff --git a/USAGE_android.md b/USAGE_android.md index c23eeff06d..26938718ba 100644 --- a/USAGE_android.md +++ b/USAGE_android.md @@ -833,7 +833,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] - [--use-colorspace-fallback] + [--use-colorspace-fallback] [--wait-before-present] [file] Launch the replay tool. @@ -973,6 +973,10 @@ optional arguments: --sgfr FRAME-RANGES, --skip-get-fence-ranges FRAME-RANGES Frame ranges where --sgfs applies. Default is all frames (forwarded to replay tool) + --wait-before-present + Force wait on completion of queue operations for all queues + before calling Present. This is needed for accurate acquisition + of instrumentation data on some platforms. ``` The command will force-stop an active replay process before starting the replay diff --git a/USAGE_desktop_Vulkan.md b/USAGE_desktop_Vulkan.md index 29c8b2ddad..20de38232e 100644 --- a/USAGE_desktop_Vulkan.md +++ b/USAGE_desktop_Vulkan.md @@ -526,14 +526,13 @@ gfxrecon-replay [-h | --help] [--version] [--gpu ] [--surface-index ] [--remove-unsupported] [--validate] [-m | --memory-translation ] [--fwo | --force-windowed-origin ] - [--use-captured-swapchain-indices] [--swapchain MODE] [--use-captured-swapchain-indices] [--mfr|--measurement-frame-range -] [--measurement-file ] [--quit-after-measurement-range] [--flush-measurement-range] [--log-level ] [--log-file ] [--log-debugview] - [--no-debug-popup] - [--use-colorspace-fallback] + [--no-debug-popup] [--use-colorspace-fallback] + [--wait-before-present] Required arguments: Path to the capture file to replay. @@ -695,6 +694,10 @@ Optional arguments: --sgfr Frame ranges where --sgfs applies. The format is: -[,-]* + --wait-before-present + Force wait on completion of queue operations for all queues + before calling Present. This is needed for accurate acquisition + of instrumentation data on some platforms. ``` ### Key Controls diff --git a/android/scripts/gfxrecon.py b/android/scripts/gfxrecon.py index adb160f6b9..e6ae3d96d4 100644 --- a/android/scripts/gfxrecon.py +++ b/android/scripts/gfxrecon.py @@ -93,6 +93,7 @@ def CreateReplayParser(): parser.add_argument('--flush-inside-measurement-range', action='store_true', default=False, help='If this is specified the replayer will flush and wait for all current GPU work to finish at end of each frame inside the measurement range. (forwarded to replay tool)') parser.add_argument('--sgfs', '--skip-get-fence-status', metavar='STATUS', default=0, help='Specify behaviour to skip calls to vkWaitForFences and vkGetFenceStatus. Default is 0 - No skip (forwarded to replay tool)') parser.add_argument('--sgfr', '--skip-get-fence-ranges', metavar='FRAME-RANGES', default='', help='Frame ranges where --sgfs applies. Default is all frames (forwarded to replay tool)') + parser.add_argument('--wait-before-present', action='store_true', default=False, help='Force wait on completion of queue operations for all queues before calling Present. This is needed for accurate acquisition of instrumentation data on some platforms.') parser.add_argument('-m', '--memory-translation', metavar='MODE', choices=['none', 'remap', 'realign', 'rebind'], help='Enable memory translation for replay on GPUs with memory types that are not compatible with the capture GPU\'s memory types. Available modes are: none, remap, realign, rebind (forwarded to replay tool)') parser.add_argument('--swapchain', metavar='MODE', choices=['virtual', 'captured', 'offscreen'], help='Choose a swapchain mode to replay. Available modes are: virtual, captured, offscreen (forwarded to replay tool)') parser.add_argument('--vssb', '--virtual-swapchain-skip-blit', action='store_true', default=False, help='Skip blit to real swapchain to gain performance during replay.') @@ -217,6 +218,9 @@ def MakeExtrasString(args): arg_list.append('-m') arg_list.append('{}'.format(args.memory_translation)) + if args.wait_before_present: + arg_list.append('--wait-before-present') + if args.file: arg_list.append(args.file) elif not args.version: diff --git a/framework/decode/vulkan_replay_consumer_base.cpp b/framework/decode/vulkan_replay_consumer_base.cpp index ed80c1e01a..fda9e8fe50 100644 --- a/framework/decode/vulkan_replay_consumer_base.cpp +++ b/framework/decode/vulkan_replay_consumer_base.cpp @@ -6143,6 +6143,12 @@ VulkanReplayConsumerBase::OverrideQueuePresentKHR(PFN_vkQueuePresentKHR modified_present_info.pImageIndices = modified_image_indices_.data(); } + if (options_.wait_before_present) + { + VkDevice device = MapHandle(queue_info->parent_id, &VulkanObjectInfoTable::GetDeviceInfo); + GetDeviceTable(device)->DeviceWaitIdle(device); + } + // Only attempt to find imported or shadow semaphores if we know at least one around. if ((!have_imported_semaphores_) && (shadow_semaphores_.empty()) && (modified_present_info.swapchainCount != 0)) { diff --git a/framework/decode/vulkan_replay_options.h b/framework/decode/vulkan_replay_options.h index d0c788d365..c9bb843f6c 100644 --- a/framework/decode/vulkan_replay_options.h +++ b/framework/decode/vulkan_replay_options.h @@ -71,6 +71,7 @@ struct VulkanReplayOptions : public ReplayOptions std::string replace_dir; SkipGetFenceStatus skip_get_fence_status{ SkipGetFenceStatus::NoSkip }; std::vector skip_get_fence_ranges; + bool wait_before_present{ false }; }; GFXRECON_END_NAMESPACE(decode) diff --git a/tools/replay/replay_settings.h b/tools/replay/replay_settings.h index a24d5047bf..f009c9c489 100644 --- a/tools/replay/replay_settings.h +++ b/tools/replay/replay_settings.h @@ -32,7 +32,7 @@ const char kOptions[] = "screenshot-all,--onhb|--omit-null-hardware-buffers,--qamr|--quit-after-measurement-range,--fmr|--flush-" "measurement-range,--flush-inside-measurement-range,--vssb|--virtual-swapchain-skip-blit,--use-captured-swapchain-" "indices,--dcp,--discard-cached-psos,--use-colorspace-fallback,--use-cached-psos,--dx12-override-object-names,--" - "offscreen-swapchain-frame-boundary"; + "offscreen-swapchain-frame-boundary,--wait-before-present"; 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,--" @@ -255,6 +255,10 @@ static void PrintUsage(const char* exe_name) GFXRECON_WRITE_CONSOLE(" --sgfr "); GFXRECON_WRITE_CONSOLE(" \t\tFrame ranges where --sgfs applies. The format is:"); GFXRECON_WRITE_CONSOLE(" \t\t\t-[,-]*"); + GFXRECON_WRITE_CONSOLE(" --wait-before-present"); + GFXRECON_WRITE_CONSOLE(" \t\tForce wait on completion of queue operations for all queues"); + GFXRECON_WRITE_CONSOLE(" \t\tbefore calling Present. This is needed for accurate acquisition"); + GFXRECON_WRITE_CONSOLE(" \t\tof instrumentation data on some platforms."); #if defined(WIN32) GFXRECON_WRITE_CONSOLE("") diff --git a/tools/tool_settings.h b/tools/tool_settings.h index 2e450f52a7..410260c99a 100644 --- a/tools/tool_settings.h +++ b/tools/tool_settings.h @@ -119,6 +119,7 @@ const char kExpandFlagsOption[] = "--expand-flags"; const char kFilePerFrameOption[] = "--file-per-frame"; const char kSkipGetFenceStatus[] = "--skip-get-fence-status"; const char kSkipGetFenceRanges[] = "--skip-get-fence-ranges"; +const char kWaitBeforePresent[] = "--wait-before-present"; #if defined(WIN32) const char kDxTwoPassReplay[] = "--dx12-two-pass-replay"; const char kDxOverrideObjectNames[] = "--dx12-override-object-names"; @@ -957,6 +958,10 @@ GetVulkanReplayOptions(const gfxrecon::util::ArgumentParser& arg_parse replay_options.skip_get_fence_ranges = gfxrecon::util::GetUintRanges(skip_get_fence_ranges.c_str(), "skip-get-fence-ranges"); } + if (arg_parser.IsOptionSet(kWaitBeforePresent)) + { + replay_options.wait_before_present = true; + } return replay_options; }