Add support for VK_EXT_metal_surface extension

This commit is contained in:
2025-04-20 16:00:21 +03:00
parent 51132b1bd4
commit 9552103c58
12 changed files with 39 additions and 16 deletions

View File

@@ -18,7 +18,7 @@ void AndroidVulkanPlatform::GetDeviceExtensions(Array<const char*>& extensions,
extensions.Add(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME); extensions.Add(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME);
} }
void AndroidVulkanPlatform::CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* surface) void AndroidVulkanPlatform::CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* surface)
{ {
ASSERT(window); ASSERT(window);
void* windowHandle = window->GetNativePtr(); void* windowHandle = window->GetNativePtr();

View File

@@ -9,6 +9,8 @@
// Support more backbuffers in case driver decides to use more // Support more backbuffers in case driver decides to use more
#define VULKAN_BACK_BUFFERS_COUNT_MAX 8 #define VULKAN_BACK_BUFFERS_COUNT_MAX 8
class GPUDeviceVulkan;
/// <summary> /// <summary>
/// The implementation for the Vulkan API support for Android platform. /// The implementation for the Vulkan API support for Android platform.
/// </summary> /// </summary>
@@ -17,7 +19,7 @@ class AndroidVulkanPlatform : public VulkanPlatformBase
public: public:
static void GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers); static void GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers);
static void GetDeviceExtensions(Array<const char*>& extensions, Array<const char*>& layers); static void GetDeviceExtensions(Array<const char*>& extensions, Array<const char*>& layers);
static void CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* surface); static void CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* surface);
}; };
typedef AndroidVulkanPlatform VulkanPlatform; typedef AndroidVulkanPlatform VulkanPlatform;

View File

@@ -192,7 +192,7 @@ bool GPUSwapChainVulkan::CreateSwapChain(int32 width, int32 height)
ASSERT_LOW_LAYER(_backBuffers.Count() == 0); ASSERT_LOW_LAYER(_backBuffers.Count() == 0);
// Create platform-dependent surface // Create platform-dependent surface
VulkanPlatform::CreateSurface(_window, GPUDeviceVulkan::Instance, &_surface); VulkanPlatform::CreateSurface(_window, _device, GPUDeviceVulkan::Instance, &_surface);
if (_surface == VK_NULL_HANDLE) if (_surface == VK_NULL_HANDLE)
{ {
LOG(Warning, "Failed to create Vulkan surface."); LOG(Warning, "Failed to create Vulkan surface.");

View File

@@ -30,7 +30,7 @@ void LinuxVulkanPlatform::GetInstanceExtensions(Array<const char*>& extensions,
extensions.Add(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); extensions.Add(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
} }
void LinuxVulkanPlatform::CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* surface) void LinuxVulkanPlatform::CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* surface)
{ {
#if !PLATFORM_SDL #if !PLATFORM_SDL
void* windowHandle = window->GetNativePtr(); void* windowHandle = window->GetNativePtr();

View File

@@ -12,6 +12,8 @@
// Prevent wierd error 'Invalid VkValidationCacheEXT Object' // Prevent wierd error 'Invalid VkValidationCacheEXT Object'
#define VULKAN_USE_VALIDATION_CACHE 0 #define VULKAN_USE_VALIDATION_CACHE 0
class GPUDeviceVulkan;
/// <summary> /// <summary>
/// The implementation for the Vulkan API support for Linux platform. /// The implementation for the Vulkan API support for Linux platform.
/// </summary> /// </summary>
@@ -19,7 +21,7 @@ class LinuxVulkanPlatform : public VulkanPlatformBase
{ {
public: public:
static void GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers); static void GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers);
static void CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* outSurface); static void CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* outSurface);
}; };
typedef LinuxVulkanPlatform VulkanPlatform; typedef LinuxVulkanPlatform VulkanPlatform;

View File

@@ -5,16 +5,18 @@
#include "MacVulkanPlatform.h" #include "MacVulkanPlatform.h"
#include "../RenderToolsVulkan.h" #include "../RenderToolsVulkan.h"
#include "Engine/Platform/Window.h" #include "Engine/Platform/Window.h"
#include "Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.h"
#include <Cocoa/Cocoa.h> #include <Cocoa/Cocoa.h>
#include <QuartzCore/CAMetalLayer.h> #include <QuartzCore/CAMetalLayer.h>
void MacVulkanPlatform::GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers) void MacVulkanPlatform::GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers)
{ {
extensions.Add(VK_KHR_SURFACE_EXTENSION_NAME); extensions.Add(VK_KHR_SURFACE_EXTENSION_NAME);
extensions.Add(VK_MVK_MACOS_SURFACE_EXTENSION_NAME); extensions.Add(VK_MVK_MACOS_SURFACE_EXTENSION_NAME);
extensions.Add(VK_EXT_METAL_SURFACE_EXTENSION_NAME);
} }
void MacVulkanPlatform::CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* surface) void MacVulkanPlatform::CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* surface)
{ {
void* windowHandle = window->GetNativePtr(); void* windowHandle = window->GetNativePtr();
NSWindow* nswindow = (NSWindow*)windowHandle; NSWindow* nswindow = (NSWindow*)windowHandle;
@@ -22,10 +24,20 @@ void MacVulkanPlatform::CreateSurface(Window* window, VkInstance instance, VkSur
nswindow.contentView.wantsLayer = YES; nswindow.contentView.wantsLayer = YES;
nswindow.contentView.layer = [CAMetalLayer layer]; nswindow.contentView.layer = [CAMetalLayer layer];
#endif #endif
VkMacOSSurfaceCreateInfoMVK surfaceCreateInfo; if (device->InstanceExtensions.Contains(VK_EXT_METAL_SURFACE_EXTENSION_NAME))
RenderToolsVulkan::ZeroStruct(surfaceCreateInfo, VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK); {
surfaceCreateInfo.pView = (void*)nswindow.contentView; VkMetalSurfaceCreateInfoEXT surfaceCreateInfo;
VALIDATE_VULKAN_RESULT(vkCreateMacOSSurfaceMVK(instance, &surfaceCreateInfo, nullptr, surface)); RenderToolsVulkan::ZeroStruct(surfaceCreateInfo, VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT);
surfaceCreateInfo.pLayer = (CAMetalLayer*)nswindow.contentView.layer;
VALIDATE_VULKAN_RESULT(vkCreateMetalSurfaceEXT(instance, &surfaceCreateInfo, nullptr, surface));
}
else
{
VkMacOSSurfaceCreateInfoMVK surfaceCreateInfo;
RenderToolsVulkan::ZeroStruct(surfaceCreateInfo, VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK);
surfaceCreateInfo.pView = (void*)nswindow.contentView;
VALIDATE_VULKAN_RESULT(vkCreateMacOSSurfaceMVK(instance, &surfaceCreateInfo, nullptr, surface));
}
} }
#endif #endif

View File

@@ -11,6 +11,8 @@
// General/Validation Error:0 VK_ERROR_INITIALIZATION_FAILED: Could not create MTLCounterSampleBuffer for query pool of type VK_QUERY_TYPE_TIMESTAMP. Reverting to emulated behavior. (Error code 0): Cannot allocate sample buffer // General/Validation Error:0 VK_ERROR_INITIALIZATION_FAILED: Could not create MTLCounterSampleBuffer for query pool of type VK_QUERY_TYPE_TIMESTAMP. Reverting to emulated behavior. (Error code 0): Cannot allocate sample buffer
#define VULKAN_USE_QUERIES 0 #define VULKAN_USE_QUERIES 0
class GPUDeviceVulkan;
/// <summary> /// <summary>
/// The implementation for the Vulkan API support for Mac platform. /// The implementation for the Vulkan API support for Mac platform.
/// </summary> /// </summary>
@@ -18,7 +20,7 @@ class MacVulkanPlatform : public VulkanPlatformBase
{ {
public: public:
static void GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers); static void GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers);
static void CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* outSurface); static void CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* outSurface);
}; };
typedef MacVulkanPlatform VulkanPlatform; typedef MacVulkanPlatform VulkanPlatform;

View File

@@ -14,7 +14,7 @@ void Win32VulkanPlatform::GetInstanceExtensions(Array<const char*>& extensions,
extensions.Add(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); extensions.Add(VK_KHR_WIN32_SURFACE_EXTENSION_NAME);
} }
void Win32VulkanPlatform::CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* surface) void Win32VulkanPlatform::CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* surface)
{ {
void* windowHandle = window->GetNativePtr(); void* windowHandle = window->GetNativePtr();
VkWin32SurfaceCreateInfoKHR surfaceCreateInfo; VkWin32SurfaceCreateInfoKHR surfaceCreateInfo;

View File

@@ -10,6 +10,8 @@
#define VULKAN_USE_PLATFORM_WIN32_KHX 1 #define VULKAN_USE_PLATFORM_WIN32_KHX 1
#define VULKAN_USE_CREATE_WIN32_SURFACE 1 #define VULKAN_USE_CREATE_WIN32_SURFACE 1
class GPUDeviceVulkan;
/// <summary> /// <summary>
/// The implementation for the Vulkan API support for Win32 platform. /// The implementation for the Vulkan API support for Win32 platform.
/// </summary> /// </summary>
@@ -17,7 +19,7 @@ class Win32VulkanPlatform : public VulkanPlatformBase
{ {
public: public:
static void GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers); static void GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers);
static void CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* surface); static void CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* surface);
}; };
typedef Win32VulkanPlatform VulkanPlatform; typedef Win32VulkanPlatform VulkanPlatform;

View File

@@ -14,7 +14,7 @@ void iOSVulkanPlatform::GetInstanceExtensions(Array<const char*>& extensions, Ar
extensions.Add(VK_MVK_IOS_SURFACE_EXTENSION_NAME); extensions.Add(VK_MVK_IOS_SURFACE_EXTENSION_NAME);
} }
void iOSVulkanPlatform::CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* surface) void iOSVulkanPlatform::CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* surface)
{ {
void* windowHandle = window->GetNativePtr(); void* windowHandle = window->GetNativePtr();
// Create surface on a main UI Thread // Create surface on a main UI Thread

View File

@@ -11,6 +11,8 @@
// General/Validation Error:0 VK_ERROR_INITIALIZATION_FAILED: Could not create MTLCounterSampleBuffer for query pool of type VK_QUERY_TYPE_TIMESTAMP. Reverting to emulated behavior. (Error code 0): Cannot allocate sample buffer // General/Validation Error:0 VK_ERROR_INITIALIZATION_FAILED: Could not create MTLCounterSampleBuffer for query pool of type VK_QUERY_TYPE_TIMESTAMP. Reverting to emulated behavior. (Error code 0): Cannot allocate sample buffer
#define VULKAN_USE_QUERIES 0 #define VULKAN_USE_QUERIES 0
class GPUDeviceVulkan;
/// <summary> /// <summary>
/// The implementation for the Vulkan API support for iOS platform. /// The implementation for the Vulkan API support for iOS platform.
/// </summary> /// </summary>
@@ -18,7 +20,7 @@ class iOSVulkanPlatform : public VulkanPlatformBase
{ {
public: public:
static void GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers); static void GetInstanceExtensions(Array<const char*>& extensions, Array<const char*>& layers);
static void CreateSurface(Window* window, VkInstance instance, VkSurfaceKHR* outSurface); static void CreateSurface(Window* window, GPUDeviceVulkan* device, VkInstance instance, VkSurfaceKHR* outSurface);
}; };
typedef iOSVulkanPlatform VulkanPlatform; typedef iOSVulkanPlatform VulkanPlatform;

View File

@@ -43,6 +43,7 @@ public class volk : ThirdPartyModule
break; break;
case TargetPlatform.Mac: case TargetPlatform.Mac:
options.PublicDefinitions.Add("VK_USE_PLATFORM_MACOS_MVK"); options.PublicDefinitions.Add("VK_USE_PLATFORM_MACOS_MVK");
options.PublicDefinitions.Add("VK_USE_PLATFORM_METAL_EXT");
break; break;
case TargetPlatform.iOS: case TargetPlatform.iOS:
options.PublicDefinitions.Add("VK_USE_PLATFORM_IOS_MVK"); options.PublicDefinitions.Add("VK_USE_PLATFORM_IOS_MVK");