From d2c22cc125fa2b2df5fcf259f39cac994c66b1e0 Mon Sep 17 00:00:00 2001 From: Marius Pelegrin Date: Wed, 7 May 2025 10:28:02 +0200 Subject: [PATCH] Fix Vulkan WSI instance extensions This commit fixes 3 bugs: - `VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME` missing in `kSurfaceExtensions` - `cli_wsi_extension_` not being set (nor possible to set) when replaying on Android - If offscreen content is captured and replayed specifying a WSI, it was possible to end up with instance extensions containing a surface extension but no `VK_KHR_surface` Change-Id: I51d89bd639b6f7bc32f045c872d697c0dec1a54c --- framework/application/application.cpp | 7 +++--- framework/application/application.h | 5 +++- .../decode/vulkan_replay_consumer_base.cpp | 24 +++++++++++++++---- tools/replay/android_main.cpp | 5 ++-- tools/replay/desktop_main.cpp | 2 +- 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/framework/application/application.cpp b/framework/application/application.cpp index c76853e482..3e5da8bf12 100644 --- a/framework/application/application.cpp +++ b/framework/application/application.cpp @@ -58,19 +58,20 @@ GFXRECON_BEGIN_NAMESPACE(gfxrecon) GFXRECON_BEGIN_NAMESPACE(application) Application::Application(const std::string& name, decode::FileProcessor* file_processor) : - Application(name, std::string(), file_processor) + Application(name, file_processor, std::string(), nullptr) {} Application::Application(const std::string& name, + decode::FileProcessor* file_processor, const std::string& cli_wsi_extension, - decode::FileProcessor* file_processor) : + void* platform_specific_wsi_data) : name_(name), file_processor_(file_processor), running_(false), paused_(false), pause_frame_(0), cli_wsi_extension_(cli_wsi_extension), fps_info_(nullptr) { if (!cli_wsi_extension_.empty()) { - InitializeWsiContext(cli_wsi_extension_.c_str()); + InitializeWsiContext(cli_wsi_extension_.c_str(), platform_specific_wsi_data); } } diff --git a/framework/application/application.h b/framework/application/application.h index 03e6c2a224..58776480c6 100644 --- a/framework/application/application.h +++ b/framework/application/application.h @@ -46,7 +46,10 @@ class Application final public: Application(const std::string& name, decode::FileProcessor* file_processor); - Application(const std::string& name, const std::string& cli_wsi_extension, decode::FileProcessor* file_processor); + Application(const std::string& name, + decode::FileProcessor* file_processor, + const std::string& cli_wsi_extension, + void* platform_specific_wsi_data); ~Application(); diff --git a/framework/decode/vulkan_replay_consumer_base.cpp b/framework/decode/vulkan_replay_consumer_base.cpp index 7930af341c..28af3f5f91 100644 --- a/framework/decode/vulkan_replay_consumer_base.cpp +++ b/framework/decode/vulkan_replay_consumer_base.cpp @@ -77,10 +77,12 @@ const char kUnknownDeviceLabel[] = ""; const char kValidationLayerName[] = "VK_LAYER_KHRONOS_validation"; const std::unordered_set kSurfaceExtensions = { - VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, VK_MVK_IOS_SURFACE_EXTENSION_NAME, VK_MVK_MACOS_SURFACE_EXTENSION_NAME, - VK_KHR_MIR_SURFACE_EXTENSION_NAME, VK_NN_VI_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, - VK_KHR_WIN32_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_EXTENSION_NAME, VK_KHR_XLIB_SURFACE_EXTENSION_NAME, - VK_EXT_METAL_SURFACE_EXTENSION_NAME, + VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, VK_MVK_IOS_SURFACE_EXTENSION_NAME, + VK_MVK_MACOS_SURFACE_EXTENSION_NAME, VK_KHR_MIR_SURFACE_EXTENSION_NAME, + VK_NN_VI_SURFACE_EXTENSION_NAME, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, + VK_KHR_WIN32_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_EXTENSION_NAME, + VK_KHR_XLIB_SURFACE_EXTENSION_NAME, VK_EXT_METAL_SURFACE_EXTENSION_NAME, + VK_EXT_HEADLESS_SURFACE_EXTENSION_NAME, }; // Device extensions to enable for trimming state setup, when available. @@ -2693,6 +2695,20 @@ void VulkanReplayConsumerBase::ModifyCreateInstanceInfo( } } + // If a WSI was specified by CLI but there was none at capture time, it's possible to end up with a surface + // extension without having VK_KHR_surface. Check for that and fix that. + if (!feature_util::IsSupportedExtension(modified_extensions, VK_KHR_SURFACE_EXTENSION_NAME)) + { + for (const std::string& current_extension : modified_extensions) + { + if (kSurfaceExtensions.find(current_extension) != kSurfaceExtensions.end()) + { + modified_extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); + break; + } + } + } + // Sanity checks depending on extension availability std::vector available_extensions; if (feature_util::GetInstanceExtensions(instance_extension_proc, &available_extensions) == VK_SUCCESS) diff --git a/tools/replay/android_main.cpp b/tools/replay/android_main.cpp index 1f7d573d87..b13bd24a98 100644 --- a/tools/replay/android_main.cpp +++ b/tools/replay/android_main.cpp @@ -136,9 +136,8 @@ void android_main(struct android_app* app) } else { - auto application = - std::make_shared(kApplicationName, file_processor.get()); - application->InitializeWsiContext(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, app); + auto application = std::make_shared( + kApplicationName, file_processor.get(), VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, app); gfxrecon::decode::VulkanTrackedObjectInfoTable tracked_object_info_table; gfxrecon::decode::VulkanReplayOptions replay_options = diff --git a/tools/replay/desktop_main.cpp b/tools/replay/desktop_main.cpp index abd418342c..ce03a4b85b 100644 --- a/tools/replay/desktop_main.cpp +++ b/tools/replay/desktop_main.cpp @@ -153,7 +153,7 @@ int main(int argc, const char** argv) // Select WSI context based on CLI std::string wsi_extension = GetWsiExtensionName(GetWsiPlatform(arg_parser)); auto application = std::make_shared( - kApplicationName, wsi_extension, file_processor.get()); + kApplicationName, file_processor.get(), wsi_extension, nullptr); gfxrecon::decode::VulkanTrackedObjectInfoTable tracked_object_info_table; gfxrecon::decode::VulkanReplayOptions vulkan_replay_options =