From d750e4d417acd4d115a2fe5560e7bfc6ce3fafff Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 24 Aug 2023 18:02:55 +1000 Subject: [PATCH] VulkanDevice: Fix for MacOS --- src/util/cocoa_tools.h | 17 +++++++----- src/util/platform_misc_mac.mm | 47 ++++++++++++++++++++++++++++++++++ src/util/vulkan_device.cpp | 2 ++ src/util/vulkan_swap_chain.cpp | 13 +++------- 4 files changed, 64 insertions(+), 15 deletions(-) diff --git a/src/util/cocoa_tools.h b/src/util/cocoa_tools.h index cd4b5436c..49766747c 100644 --- a/src/util/cocoa_tools.h +++ b/src/util/cocoa_tools.h @@ -10,16 +10,21 @@ struct WindowInfo; #import namespace CocoaTools { - NSString* StringViewToNSString(const std::string_view& str); +NSString* StringViewToNSString(const std::string_view& str); } #endif namespace CocoaTools { - /// Add a handler to be run when macOS changes between dark and light themes - void AddThemeChangeHandler(void* ctx, void(handler)(void* ctx)); +/// Add a handler to be run when macOS changes between dark and light themes +void AddThemeChangeHandler(void* ctx, void(handler)(void* ctx)); - /// Remove a handler previously added using AddThemeChangeHandler with the given context - void RemoveThemeChangeHandler(void* ctx); -} +/// Remove a handler previously added using AddThemeChangeHandler with the given context +void RemoveThemeChangeHandler(void* ctx); +/// Creates metal layer on specified window surface. +bool CreateMetalLayer(WindowInfo* wi); + +/// Destroys metal layer on specified window surface. +void DestroyMetalLayer(WindowInfo* wi); +} // namespace CocoaTools diff --git a/src/util/platform_misc_mac.mm b/src/util/platform_misc_mac.mm index 57d2b08b8..d1cf6ba68 100644 --- a/src/util/platform_misc_mac.mm +++ b/src/util/platform_misc_mac.mm @@ -147,3 +147,50 @@ void CocoaTools::RemoveThemeChangeHandler(void* ctx) assert([NSThread isMainThread]); [s_themeChangeHandler removeCallback:ctx]; } + +bool CocoaTools::CreateMetalLayer(WindowInfo *wi) +{ + // Punt off to main thread if we're not calling from it already. + if (![NSThread isMainThread]) + { + bool ret; + dispatch_sync(dispatch_get_main_queue(), [&ret, wi]() { + ret = CreateMetalLayer(wi); + }); + return ret; + } + + CAMetalLayer* layer = [CAMetalLayer layer]; + if (layer == nil) + { + Log_ErrorPrint("Failed to create CAMetalLayer"); + return false; + } + + NSView* view = (__bridge NSView*)wi->window_handle; + [view setWantsLayer:TRUE]; + [view setLayer:layer]; + [layer setContentsScale:[[[view window] screen] backingScaleFactor]]; + + wi->surface_handle = (__bridge void*)layer; + return true; +} + +void CocoaTools::DestroyMetalLayer(WindowInfo *wi) +{ + if (!wi->surface_handle) + return; + + // Punt off to main thread if we're not calling from it already. + if (![NSThread isMainThread]) + { + dispatch_sync(dispatch_get_main_queue(), [wi]() { DestroyMetalLayer(wi); }); + return; + } + + NSView* view = (__bridge NSView*)wi->window_handle; + CAMetalLayer* layer = (__bridge CAMetalLayer*)wi->surface_handle; + [view setLayer:nil]; + [view setWantsLayer:NO]; + [layer release]; +} diff --git a/src/util/vulkan_device.cpp b/src/util/vulkan_device.cpp index 885d9a2f4..f16b4f347 100644 --- a/src/util/vulkan_device.cpp +++ b/src/util/vulkan_device.cpp @@ -48,6 +48,7 @@ enum : u32 MAX_DRAW_CALLS_PER_FRAME = 2048, MAX_COMBINED_IMAGE_SAMPLER_DESCRIPTORS_PER_FRAME = GPUDevice::MAX_TEXTURE_SAMPLERS * MAX_DRAW_CALLS_PER_FRAME, MAX_DESCRIPTOR_SETS_PER_FRAME = MAX_DRAW_CALLS_PER_FRAME, + MAX_SAMPLER_DESCRIPTORS = 8192, VERTEX_BUFFER_SIZE = 32 * 1024 * 1024, INDEX_BUFFER_SIZE = 16 * 1024 * 1024, @@ -741,6 +742,7 @@ bool VulkanDevice::CreatePersistentDescriptorPool() { static constexpr const VkDescriptorPoolSize pool_sizes[] = { {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1}, + {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, MAX_SAMPLER_DESCRIPTORS}, {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 16}, {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 16}, }; diff --git a/src/util/vulkan_swap_chain.cpp b/src/util/vulkan_swap_chain.cpp index 88494c431..05831244a 100644 --- a/src/util/vulkan_swap_chain.cpp +++ b/src/util/vulkan_swap_chain.cpp @@ -16,6 +16,10 @@ #include #endif +#if defined(VK_USE_PLATFORM_METAL_EXT) +#include "util/cocoa_tools.h" +#endif + Log_SetChannel(VulkanDevice); VulkanSwapChain::VulkanSwapChain(const WindowInfo& wi, VkSurfaceKHR surface, bool vsync, @@ -60,7 +64,6 @@ VkSurfaceKHR VulkanSwapChain::CreateVulkanSurface(VkInstance instance, VkPhysica #if defined(VK_USE_PLATFORM_METAL_EXT) if (wi->type == WindowInfo::Type::MacOS) { -#if 0 // TODO: FIXME if (!wi->surface_handle && !CocoaTools::CreateMetalLayer(wi)) return VK_NULL_HANDLE; @@ -77,10 +80,6 @@ VkSurfaceKHR VulkanSwapChain::CreateVulkanSurface(VkInstance instance, VkPhysica } return surface; -#else - Panic("Fixme"); - return VK_NULL_HANDLE; -#endif } #endif @@ -156,12 +155,8 @@ void VulkanSwapChain::DestroyVulkanSurface(VkInstance instance, WindowInfo* wi, vkDestroySurfaceKHR(VulkanDevice::GetInstance().GetVulkanInstance(), surface, nullptr); #if defined(__APPLE__) -#if 0 if (wi->type == WindowInfo::Type::MacOS && wi->surface_handle) CocoaTools::DestroyMetalLayer(wi); -#else - Panic("TODO"); -#endif #endif }