From 08a1ce2e7610684d8fdded0ee3fb22e3cf28327a Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 16 Aug 2019 10:27:13 +0100 Subject: [PATCH] Add support for VK_EXT_metal_surface and prefer it to MVK_macos_surface --- renderdoc/driver/vulkan/CMakeLists.txt | 2 +- renderdoc/driver/vulkan/vk_android.cpp | 2 +- renderdoc/driver/vulkan/vk_apple.cpp | 77 ++++++++++++++++++--- renderdoc/driver/vulkan/vk_core.cpp | 5 ++ renderdoc/driver/vulkan/vk_core.h | 7 ++ renderdoc/driver/vulkan/vk_ggp.cpp | 2 +- renderdoc/driver/vulkan/vk_hookset_defs.h | 48 +++++++++++-- renderdoc/driver/vulkan/vk_linux.cpp | 2 +- renderdoc/driver/vulkan/vk_outputwindow.cpp | 2 +- renderdoc/driver/vulkan/vk_posix.cpp | 55 +++++++++++---- renderdoc/driver/vulkan/vk_replay.h | 2 +- renderdoc/driver/vulkan/vk_win32.cpp | 2 +- 12 files changed, 171 insertions(+), 35 deletions(-) diff --git a/renderdoc/driver/vulkan/CMakeLists.txt b/renderdoc/driver/vulkan/CMakeLists.txt index 1eadf3751..38ae52102 100644 --- a/renderdoc/driver/vulkan/CMakeLists.txt +++ b/renderdoc/driver/vulkan/CMakeLists.txt @@ -87,7 +87,7 @@ if(ANDROID) elseif(APPLE) list(APPEND sources vk_posix.cpp vk_apple.cpp vk_apple.mm) - add_definitions(-DVK_USE_PLATFORM_MACOS_MVK) + add_definitions(-DVK_USE_PLATFORM_MACOS_MVK -DVK_USE_PLATFORM_METAL_EXT) elseif(ENABLE_GGP) list(APPEND sources vk_posix.cpp vk_ggp.cpp) add_definitions(-DVK_USE_PLATFORM_GGP) diff --git a/renderdoc/driver/vulkan/vk_android.cpp b/renderdoc/driver/vulkan/vk_android.cpp index f8f2f581a..9361528f3 100644 --- a/renderdoc/driver/vulkan/vk_android.cpp +++ b/renderdoc/driver/vulkan/vk_android.cpp @@ -57,7 +57,7 @@ void VulkanReplay::OutputWindow::SetWindowHandle(WindowingData window) wnd = window.android.window; } -void VulkanReplay::OutputWindow::CreateSurface(VkInstance inst) +void VulkanReplay::OutputWindow::CreateSurface(WrappedVulkan *driver, VkInstance inst) { VkAndroidSurfaceCreateInfoKHR createInfo; diff --git a/renderdoc/driver/vulkan/vk_apple.cpp b/renderdoc/driver/vulkan/vk_apple.cpp index 5a68a6d0f..7baa5c065 100644 --- a/renderdoc/driver/vulkan/vk_apple.cpp +++ b/renderdoc/driver/vulkan/vk_apple.cpp @@ -32,6 +32,8 @@ extern "C" int getMetalLayerWidth(void *handle); extern "C" int getMetalLayerHeight(void *handle); +#if defined(VK_USE_PLATFORM_MACOS_MVK) + VkResult WrappedVulkan::vkCreateMacOSSurfaceMVK(VkInstance instance, const VkMacOSSurfaceCreateInfoMVK *pCreateInfo, const VkAllocationCallbacks *pAllocator, @@ -57,23 +59,82 @@ VkResult WrappedVulkan::vkCreateMacOSSurfaceMVK(VkInstance instance, return ret; } +#endif + +#if defined(VK_USE_PLATFORM_METAL_EXT) + +VkResult WrappedVulkan::vkCreateMetalSurfaceEXT(VkInstance instance, + const VkMetalSurfaceCreateInfoEXT *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkSurfaceKHR *pSurface) +{ + // should not come in here at all on replay + RDCASSERT(IsCaptureMode(m_State)); + + VkResult ret = + ObjDisp(instance)->CreateMetalSurfaceEXT(Unwrap(instance), pCreateInfo, pAllocator, pSurface); + + if(ret == VK_SUCCESS) + { + GetResourceManager()->WrapResource(Unwrap(instance), *pSurface); + + WrappedVkSurfaceKHR *wrapped = GetWrapped(*pSurface); + + // since there's no point in allocating a full resource record and storing the window + // handle under there somewhere, we just cast. We won't use the resource record for anything + wrapped->record = (VkResourceRecord *)(uintptr_t)pCreateInfo->pLayer; + } + + return ret; +} + +#endif + void VulkanReplay::OutputWindow::SetWindowHandle(WindowingData window) { RDCASSERT(window.system == WindowingSystem::MacOS, window.system); wnd = window.macOS.layer; } -void VulkanReplay::OutputWindow::CreateSurface(VkInstance inst) +void VulkanReplay::OutputWindow::CreateSurface(WrappedVulkan *driver, VkInstance inst) { - VkMacOSSurfaceCreateInfoMVK createInfo; +#if defined(VK_USE_PLATFORM_METAL_EXT) + if(driver->GetExtensions(GetRecord(inst)).ext_EXT_metal_surface) + { + VkMetalSurfaceCreateInfoEXT createInfo; - createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; - createInfo.pNext = NULL; - createInfo.flags = 0; - createInfo.pView = wnd; + createInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.pLayer = wnd; - VkResult vkr = ObjDisp(inst)->CreateMacOSSurfaceMVK(Unwrap(inst), &createInfo, NULL, &surface); - RDCASSERTEQUAL(vkr, VK_SUCCESS); + RDCDEBUG("Creating macOS surface with EXT_metal_surface"); + + VkResult vkr = ObjDisp(inst)->CreateMetalSurfaceEXT(Unwrap(inst), &createInfo, NULL, &surface); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + return; + } +#endif + +#if defined(VK_USE_PLATFORM_MACOS_MVK) + if(driver->GetExtensions(GetRecord(inst)).ext_MVK_macos_surface) + { + VkMacOSSurfaceCreateInfoMVK createInfo; + + createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.pView = wnd; + + RDCDEBUG("Creating macOS surface with MVK_macos_surface"); + + VkResult vkr = ObjDisp(inst)->CreateMacOSSurfaceMVK(Unwrap(inst), &createInfo, NULL, &surface); + RDCASSERTEQUAL(vkr, VK_SUCCESS); + return; + } +#endif + + RDCERR("No enabled macOS surface extension"); } void VulkanReplay::GetOutputWindowDimensions(uint64_t id, int32_t &w, int32_t &h) diff --git a/renderdoc/driver/vulkan/vk_core.cpp b/renderdoc/driver/vulkan/vk_core.cpp index 5065032a5..08c25da4c 100644 --- a/renderdoc/driver/vulkan/vk_core.cpp +++ b/renderdoc/driver/vulkan/vk_core.cpp @@ -717,6 +717,11 @@ static const VkExtensionProperties supportedExtensions[] = { { VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, VK_EXT_MEMORY_PRIORITY_SPEC_VERSION, }, +#ifdef VK_EXT_metal_surface + { + VK_EXT_METAL_SURFACE_EXTENSION_NAME, VK_EXT_METAL_SURFACE_SPEC_VERSION, + }, +#endif { VK_EXT_PCI_BUS_INFO_EXTENSION_NAME, VK_EXT_PCI_BUS_INFO_SPEC_VERSION, }, diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index 97039a9b3..dc4515f47 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -2129,4 +2129,11 @@ public: IMPLEMENT_FUNCTION_SERIALISED(void, vkCmdSetLineStippleEXT, VkCommandBuffer commandBuffer, uint32_t lineStippleFactor, uint16_t lineStipplePattern); + +#if defined(VK_USE_PLATFORM_METAL_EXT) + // VK_EXT_metal_surface + VkResult vkCreateMetalSurfaceEXT(VkInstance instance, + const VkMetalSurfaceCreateInfoEXT *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkSurfaceKHR *pSurface); +#endif }; diff --git a/renderdoc/driver/vulkan/vk_ggp.cpp b/renderdoc/driver/vulkan/vk_ggp.cpp index ceff16f2c..0d5d9bf00 100644 --- a/renderdoc/driver/vulkan/vk_ggp.cpp +++ b/renderdoc/driver/vulkan/vk_ggp.cpp @@ -54,7 +54,7 @@ void VulkanReplay::OutputWindow::SetWindowHandle(WindowingData window) return; // there are no OS specific handles to save. } -void VulkanReplay::OutputWindow::CreateSurface(VkInstance inst) +void VulkanReplay::OutputWindow::CreateSurface(WrappedVulkan *driver, VkInstance inst) { VkStreamDescriptorSurfaceCreateInfoGGP createInfo; diff --git a/renderdoc/driver/vulkan/vk_hookset_defs.h b/renderdoc/driver/vulkan/vk_hookset_defs.h index 5f601588f..381408003 100644 --- a/renderdoc/driver/vulkan/vk_hookset_defs.h +++ b/renderdoc/driver/vulkan/vk_hookset_defs.h @@ -81,18 +81,52 @@ HookDefine2(VkResult, vkReleaseFullScreenExclusiveModeEXT, VkDevice, device, VkSwapchainKHR, \ swapchain); -#elif defined(VK_USE_PLATFORM_MACOS_MVK) +#elif defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT) -#define HookInitInstance_PlatformSpecific() \ +#if defined(VK_USE_PLATFORM_MACOS_MVK) + +#define HookInitInstance_PlatformSpecific_MVK() \ HookInitExtension(VK_MVK_macos_surface, CreateMacOSSurfaceMVK); -#define HookInitDevice_PlatformSpecific() - -#define HookDefine_PlatformSpecific() \ +#define HookDefine_PlatformSpecific_MVK() \ HookDefine4(VkResult, vkCreateMacOSSurfaceMVK, VkInstance, instance, \ const VkMacOSSurfaceCreateInfoMVK *, pCreateInfo, const VkAllocationCallbacks *, \ pAllocator, VkSurfaceKHR *, pSurface); +#else + +#define HookInitInstance_PlatformSpecific_MVK() +#define HookDefine_PlatformSpecific_MVK() + +#endif + +#if defined(VK_USE_PLATFORM_METAL_EXT) + +#define HookInitInstance_PlatformSpecific_EXT() \ + HookInitExtension(VK_EXT_metal_surface, CreateMetalSurfaceEXT); + +#define HookDefine_PlatformSpecific_EXT() \ + HookDefine4(VkResult, vkCreateMetalSurfaceEXT, VkInstance, instance, \ + const VkMetalSurfaceCreateInfoEXT *, pCreateInfo, const VkAllocationCallbacks *, \ + pAllocator, VkSurfaceKHR *, pSurface); + +#else + +#define HookInitInstance_PlatformSpecific_MVK() +#define HookDefine_PlatformSpecific_EXT() + +#endif + +#define HookInitInstance_PlatformSpecific() \ + HookInitInstance_PlatformSpecific_MVK(); \ + HookInitInstance_PlatformSpecific_EXT(); + +#define HookDefine_PlatformSpecific() \ + HookDefine_PlatformSpecific_MVK(); \ + HookDefine_PlatformSpecific_EXT(); + +#define HookInitDevice_PlatformSpecific() + #elif defined(VK_USE_PLATFORM_ANDROID_KHR) #define HookInitInstance_PlatformSpecific() \ @@ -340,6 +374,7 @@ DeclExt(KHR_get_surface_capabilities2); \ DeclExt(KHR_get_display_properties2); \ DeclExt(EXT_headless_surface); \ + DeclExt(EXT_metal_surface); \ /* device extensions */ \ DeclExt(EXT_debug_marker); \ DeclExt(GGP_frame_token); \ @@ -421,7 +456,8 @@ CheckExt(EXT_sample_locations, VKXX); \ CheckExt(EXT_calibrated_timestamps, VKXX); \ CheckExt(EXT_full_screen_exclusive, VKXX); \ - CheckExt(EXT_headless_surface, VKXX); + CheckExt(EXT_headless_surface, VKXX); \ + CheckExt(EXT_metal_surface, VKXX); #define CheckDeviceExts() \ CheckExt(EXT_debug_marker, VKXX); \ diff --git a/renderdoc/driver/vulkan/vk_linux.cpp b/renderdoc/driver/vulkan/vk_linux.cpp index c75899052..b944423f6 100644 --- a/renderdoc/driver/vulkan/vk_linux.cpp +++ b/renderdoc/driver/vulkan/vk_linux.cpp @@ -155,7 +155,7 @@ void VulkanReplay::OutputWindow::SetWindowHandle(WindowingData window) RDCERR("Unrecognised/unsupported window system %d", window.system); } -void VulkanReplay::OutputWindow::CreateSurface(VkInstance inst) +void VulkanReplay::OutputWindow::CreateSurface(WrappedVulkan *driver, VkInstance inst) { #if ENABLED(RDOC_XLIB) if(m_WindowSystem == WindowingSystem::Xlib) diff --git a/renderdoc/driver/vulkan/vk_outputwindow.cpp b/renderdoc/driver/vulkan/vk_outputwindow.cpp index 8de663bf3..e811775ca 100644 --- a/renderdoc/driver/vulkan/vk_outputwindow.cpp +++ b/renderdoc/driver/vulkan/vk_outputwindow.cpp @@ -189,7 +189,7 @@ void VulkanReplay::OutputWindow::Create(WrappedVulkan *driver, VkDevice device, if(surface == VK_NULL_HANDLE && m_WindowSystem != WindowingSystem::Headless) { - CreateSurface(inst); + CreateSurface(driver, inst); GetResourceManager()->WrapResource(Unwrap(inst), surface); } diff --git a/renderdoc/driver/vulkan/vk_posix.cpp b/renderdoc/driver/vulkan/vk_posix.cpp index 4f4cbf1f4..3cd8f39a2 100644 --- a/renderdoc/driver/vulkan/vk_posix.cpp +++ b/renderdoc/driver/vulkan/vk_posix.cpp @@ -54,7 +54,7 @@ void WrappedVulkan::AddRequiredExtensions(bool instance, std::vector