diff --git a/runtime/Includes/Core/Profiler.h b/runtime/Includes/Core/Profiler.h index 3d5e56d..7d85b21 100644 --- a/runtime/Includes/Core/Profiler.h +++ b/runtime/Includes/Core/Profiler.h @@ -47,7 +47,6 @@ namespace mlx std::unordered_map> m_profile_data; std::ofstream m_output_stream; - std::mutex m_mutex; bool m_runtime_session_began = false; }; diff --git a/runtime/Includes/Core/SDLManager.h b/runtime/Includes/Core/SDLManager.h index cc13ef8..415cc7e 100644 --- a/runtime/Includes/Core/SDLManager.h +++ b/runtime/Includes/Core/SDLManager.h @@ -20,7 +20,6 @@ namespace mlx void SetInputBinding(std::function functor); VkSurfaceKHR CreateVulkanSurface(Handle window, VkInstance instance) const noexcept; - std::vector GetRequiredVulkanInstanceExtentions(Handle window) const noexcept; Vec2ui GetVulkanDrawableSize(Handle window) const noexcept; void MoveMouseOnWindow(Handle window, int x, int y) const noexcept; void GetScreenSizeWindowIsOn(Handle window, int* x, int* y) const noexcept; diff --git a/runtime/Includes/Platform/Window.h b/runtime/Includes/Platform/Window.h index e0076b2..5bb919a 100644 --- a/runtime/Includes/Platform/Window.h +++ b/runtime/Includes/Platform/Window.h @@ -35,7 +35,6 @@ namespace mlx MLX_FORCEINLINE void GetSize(int* x, int* y) { *x = GetWidth(); *y = GetHeight(); } MLX_FORCEINLINE VkSurfaceKHR CreateVulkanSurface(VkInstance instance) const noexcept { return SDLManager::Get().CreateVulkanSurface(p_window, instance); } - MLX_FORCEINLINE std::vector GetRequiredVulkanInstanceExtentions() const noexcept { return SDLManager::Get().GetRequiredVulkanInstanceExtentions(p_window); } MLX_FORCEINLINE Vec2ui GetVulkanDrawableSize() const noexcept { return SDLManager::Get().GetVulkanDrawableSize(p_window); } [[nodiscard]] inline Handle GetRawHandle() const noexcept { return p_window; } diff --git a/runtime/Includes/PreCompiled.h b/runtime/Includes/PreCompiled.h index c9485f0..e42560a 100644 --- a/runtime/Includes/PreCompiled.h +++ b/runtime/Includes/PreCompiled.h @@ -25,12 +25,12 @@ #error Failed to find SDL2 headers #endif -#if __has_include() - #include -#elif __has_include() - #include +#if __has_include() + #include +#elif __has_include() + #include #else - #error Failed to find SDL2 Vulkan headers + #error Failed to find SDL2 SysWMinfo #endif #include diff --git a/runtime/Includes/Renderer/Surface.h b/runtime/Includes/Renderer/Surface.h new file mode 100644 index 0000000..9be38bd --- /dev/null +++ b/runtime/Includes/Renderer/Surface.h @@ -0,0 +1,56 @@ +#ifndef __MLX_SURFACE__ +#define __MLX_SURFACE__ + +#include +#include + +namespace mlx +{ + class Surface + { + public: + Surface() = default; + + void Init(NonOwningPtr window); + void Destroy(); + + [[nodiscard]] inline VkSurfaceKHR Get() const noexcept { return m_surface; } + + ~Surface() = default; + + private: + #ifdef VK_USE_PLATFORM_ANDROID_KHR + // VK_KHR_android_surface + void Create(ANativeWindow* window, VkAndroidSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + // VK_KHR_xcb_surface + void Create(xcb_connection_t* connection, xcb_window_t window, VkXcbSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + // VK_KHR_xlib_surface + void Create(Display* display, ::Window window, VkXlibSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + // VK_KHR_wayland_surface + void Create(wl_display* display, wl_surface* surface, VkWaylandSurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + // VK_KHR_win32_surface + void Create(HINSTANCE instance, HWND handle, VkWin32SurfaceCreateFlagsKHR flags = 0, const VkAllocationCallbacks* allocator = nullptr); + #endif + + #ifdef VK_USE_PLATFORM_METAL_EXT + void Create(id layer, const VkAllocationCallbacks* allocator = nullptr); + #endif + + private: + VkSurfaceKHR m_surface = VK_NULL_HANDLE; + }; +} + +#endif diff --git a/runtime/Includes/Renderer/Vulkan/VulkanDefs.h b/runtime/Includes/Renderer/Vulkan/VulkanDefs.h index 5ee802e..d2de9a7 100644 --- a/runtime/Includes/Renderer/Vulkan/VulkanDefs.h +++ b/runtime/Includes/Renderer/Vulkan/VulkanDefs.h @@ -123,5 +123,41 @@ MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR) MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR) MLX_VULKAN_INSTANCE_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR) + + #ifdef VK_USE_PLATFORM_ANDROID_KHR + #ifdef VK_KHR_android_surface + MLX_VULKAN_INSTANCE_FUNCTION(vkCreateAndroidSurfaceKHR) + #endif + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + #ifdef VK_KHR_xcb_surface + MLX_VULKAN_INSTANCE_FUNCTION(vkCreateXcbSurfaceKHR) + #endif + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + #ifdef VK_KHR_xlib_surface + MLX_VULKAN_INSTANCE_FUNCTION(vkCreateXlibSurfaceKHR) + #endif + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + #ifdef VK_KHR_wayland_surface + MLX_VULKAN_INSTANCE_FUNCTION(vkCreateWaylandSurfaceKHR) + #endif + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + #ifdef VK_KHR_win32_surface + MLX_VULKAN_INSTANCE_FUNCTION(vkCreateWin32SurfaceKHR) + #endif + #endif + + #ifdef VK_USE_PLATFORM_METAL_EXT + #ifdef VK_EXT_metal_surface + MLX_VULKAN_INSTANCE_FUNCTION(vkCreateMetalSurfaceEXT) + #endif + #endif #endif #endif diff --git a/runtime/Sources/Core/Profiler.cpp b/runtime/Sources/Core/Profiler.cpp index b7c106b..8fc2e1d 100644 --- a/runtime/Sources/Core/Profiler.cpp +++ b/runtime/Sources/Core/Profiler.cpp @@ -8,7 +8,6 @@ namespace mlx void Profiler::BeginRuntimeSession() { - std::lock_guard lock(m_mutex); if(m_runtime_session_began) return; m_output_stream.open("./runtime_profile.mlx.json", std::ofstream::out | std::ofstream::trunc); @@ -22,7 +21,6 @@ namespace mlx void Profiler::AppendProfileData(ProfileResult&& result) { - std::lock_guard lock(m_mutex); auto it = m_profile_data.find(result.name); if(it != m_profile_data.end()) { @@ -49,7 +47,6 @@ namespace mlx void Profiler::EndRuntimeSession() { - std::lock_guard lock(m_mutex); if(!m_runtime_session_began) return; for(auto& [_, pair] : m_profile_data) diff --git a/runtime/Sources/Core/SDLManager.cpp b/runtime/Sources/Core/SDLManager.cpp index ca9deab..91afe68 100644 --- a/runtime/Sources/Core/SDLManager.cpp +++ b/runtime/Sources/Core/SDLManager.cpp @@ -43,7 +43,7 @@ namespace mlx Internal::WindowInfos* infos = new Internal::WindowInfos; Verify(infos != nullptr, "SDL: window allocation failed"); - std::uint32_t flags = SDL_WINDOW_VULKAN; + std::uint32_t flags = 0; if(hidden) flags |= SDL_WINDOW_HIDDEN; else @@ -88,28 +88,38 @@ namespace mlx VkSurfaceKHR SDLManager::CreateVulkanSurface(Handle window, VkInstance instance) const noexcept { - VkSurfaceKHR surface; - if(!SDL_Vulkan_CreateSurface(static_cast(window)->window, instance, &surface)) - FatalError("SDL: could not create a Vulkan surface; %", SDL_GetError()); - return surface; - } + SDL_SysWMinfo info; + SDL_VERSION(&info.version); + if(SDL_GetWindowWMInfo(static_cast(window)->window, &info) != SDL_TRUE) + FatalError("SDL Manager: cannot retrieve window informations"); - std::vector SDLManager::GetRequiredVulkanInstanceExtentions(Handle window) const noexcept - { - std::uint32_t count; - if(!SDL_Vulkan_GetInstanceExtensions(static_cast(window)->window, &count, nullptr)) - FatalError("SDL Manager: could not retrieve Vulkan instance extensions"); - std::vector extensions(count); - if(!SDL_Vulkan_GetInstanceExtensions(static_cast(window)->window, &count, extensions.data())) - FatalError("SDL Manager: could not retrieve Vulkan instance extensions"); - extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); - return extensions; + switch(info.subsystem) + { + #ifdef SDL_VIDEO_DRIVER_WINDOWS + case SDL_SYSWM_WINDOWS: return kvfCreateSurfaceKHR(instance, KVF_SURFACE_WINDOWS, static_cast(info.info.win.hinstance), static_cast(info.info.win.window)); + #endif + #ifdef SDL_VIDEO_DRIVER_X11 + case SDL_SYSWM_X11: return kvfCreateSurfaceKHR(instance, KVF_SURFACE_XLIB, static_cast(info.info.x11.display), static_cast(&info.info.x11.window)); + #endif + #ifdef SDL_VIDEO_DRIVER_COCOA + case SDL_SYSWM_COCOA: FatalError("SDL Manager: Vulkan surfaces over Metal are not supported yet. Please fill an issue here https://github.com/seekrs/MacroLibX/issues/new"); + #endif + #ifdef SDL_VIDEO_DRIVER_WAYLAND + case SDL_SYSWM_WAYLAND: return kvfCreateSurfaceKHR(instance, KVF_SURFACE_WAYLAND, static_cast(info.info.wl.display), static_cast(info.info.wl.surface)); + #endif + #ifdef SDL_VIDEO_DRIVER_ANDROID + case SDL_SYSWM_ANDROID: return kvfCreateSurfaceKHR(instance, KVF_SURFACE_ANDROID, nullptr, static_cast(info.info.android.window)); + #endif + + default : FatalError("SDL Manager: unsupported windowing system"); break; + } + return VK_NULL_HANDLE; } Vec2ui SDLManager::GetVulkanDrawableSize(Handle window) const noexcept { Vec2i extent; - SDL_Vulkan_GetDrawableSize(static_cast(window)->window, &extent.x, &extent.y); + SDL_GetWindowSizeInPixels(static_cast(window)->window, &extent.x, &extent.y); return Vec2ui{ extent }; } @@ -266,6 +276,7 @@ namespace mlx case SDL_WINDOWEVENT_LEAVE: functor(MLX_WINDOW_EVENT, id, 6); break; case SDL_WINDOWEVENT_FOCUS_LOST: functor(MLX_WINDOW_EVENT, id, 7); break; case SDL_WINDOWEVENT_SIZE_CHANGED: functor(MLX_WINDOW_EVENT, id, 8); break; + case SDL_WINDOWEVENT_RESTORED: functor(MLX_WINDOW_EVENT, id, 11); break; default : break; } @@ -284,6 +295,7 @@ namespace mlx { if(m_drop_sdl_responsability) return; + SDL_QuitSubSystem(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTS); SDL_Quit(); s_instance = nullptr; diff --git a/runtime/Sources/Renderer/Pipelines/Graphics.cpp b/runtime/Sources/Renderer/Pipelines/Graphics.cpp index eee0446..d2a3bb8 100644 --- a/runtime/Sources/Renderer/Pipelines/Graphics.cpp +++ b/runtime/Sources/Renderer/Pipelines/Graphics.cpp @@ -127,6 +127,9 @@ namespace mlx void GraphicPipeline::Destroy() noexcept { MLX_PROFILE_FUNCTION(); + if(m_pipeline == VK_NULL_HANDLE) + return; + p_vertex_shader.reset(); p_fragment_shader.reset(); for(auto fb : m_framebuffers) diff --git a/runtime/Sources/Renderer/RenderCore.cpp b/runtime/Sources/Renderer/RenderCore.cpp index 9e89fea..2ef3084 100644 --- a/runtime/Sources/Renderer/RenderCore.cpp +++ b/runtime/Sources/Renderer/RenderCore.cpp @@ -100,8 +100,25 @@ namespace mlx info.width = 1; info.height = 1; window = std::make_unique(&info, true); - instance_extensions = window->GetRequiredVulkanInstanceExtentions(); - #ifdef MLX_PLAT_MACOS + instance_extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); + #ifdef VK_USE_PLATFORM_XCB_KHR + instance_extensions.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + instance_extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + instance_extensions.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME); + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + instance_extensions.push_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); + #endif + + #ifdef VK_USE_PLATFORM_METAL_EXT + instance_extensions.push_back(VK_EXT_METAL_SURFACE_EXTENSION_NAME); instance_extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); #endif } @@ -185,6 +202,41 @@ namespace mlx MLX_LOAD_FUNCTION(vkGetPhysicalDeviceSurfaceFormatsKHR); MLX_LOAD_FUNCTION(vkGetPhysicalDeviceSurfacePresentModesKHR); MLX_LOAD_FUNCTION(vkGetPhysicalDeviceSurfaceSupportKHR); + #ifdef VK_USE_PLATFORM_ANDROID_KHR + #ifdef VK_KHR_android_surface + MLX_LOAD_FUNCTION(vkCreateAndroidSurfaceKHR); + #endif + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + #ifdef VK_KHR_xcb_surface + MLX_LOAD_FUNCTION(vkCreateXcbSurfaceKHR); + #endif + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + #ifdef VK_KHR_xlib_surface + MLX_LOAD_FUNCTION(vkCreateXlibSurfaceKHR); + #endif + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + #ifdef VK_KHR_wayland_surface + MLX_LOAD_FUNCTION(vkCreateWaylandSurfaceKHR); + #endif + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + #ifdef VK_KHR_win32_surface + MLX_LOAD_FUNCTION(vkCreateWin32SurfaceKHR); + #endif + #endif + + #ifdef VK_USE_PLATFORM_METAL_EXT + #ifdef VK_EXT_metal_surface + MLX_LOAD_FUNCTION(vkCreateMetalSurfaceEXT); + #endif + #endif kvfPassInstanceVulkanFunctionPointers(&pfns); } diff --git a/third_party/kvf.h b/third_party/kvf.h index 03accb4..dbfe23d 100755 --- a/third_party/kvf.h +++ b/third_party/kvf.h @@ -55,6 +55,46 @@ #define VK_NO_PROTOTYPES #endif +#ifndef KVF_NO_KHR + #ifdef VK_USE_PLATFORM_ANDROID_KHR + #include + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + #include + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + typedef struct HINSTANCE__* HINSTANCE; + typedef struct HWND__* HWND; + typedef struct HMONITOR__* HMONITOR; + typedef void* HANDLE; + typedef /*_Null_terminated_*/ const wchar_t* LPCWSTR; + typedef unsigned long DWORD; + typedef struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES; + #include + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + struct xcb_connection_t; + typedef uint32_t xcb_window_t; + typedef uint32_t xcb_visualid_t; + #include + #endif + + #ifdef VK_USE_PLATFORM_METAL_EXT + #include + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + typedef struct _XDisplay Display; + typedef unsigned long XID; + typedef XID Window; + typedef unsigned long VisualID; + #include + #endif +#endif + #include #include @@ -82,6 +122,18 @@ typedef enum KVF_IMAGE_OTHER = 4, } KvfImageType; +#ifndef KVF_NO_KHR + typedef enum + { + KVF_SURFACE_ANDROID = 0, + KVF_SURFACE_XLIB = 1, + KVF_SURFACE_XCB = 2, + KVF_SURFACE_WAYLAND = 3, + KVF_SURFACE_WINDOWS = 4, + KVF_SURFACE_METAL = 5, + } KvfSurfaceType; +#endif + typedef void (*KvfErrorCallback)(const char* message); #ifdef KVF_IMPL_VK_NO_PROTOTYPES @@ -148,6 +200,33 @@ void kvfDestroySemaphore(VkDevice device, VkSemaphore semaphore); uint32_t kvfGetSwapchainMinImagesCount(VkSwapchainKHR swapchain); VkExtent2D kvfGetSwapchainImagesSize(VkSwapchainKHR swapchain); void kvfDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain); + + /** + * For Windows: + * - instance_handle -> HINSTANCE + * - window_handle -> HWND window handle + * + * For Wayland: + * - instance_handle -> wl_display + * - window_handle -> wl_surface + * + * For XLIB: + * - instance_handle -> Display + * - window_handle -> Window + * + * For XCB: + * - instance_handle -> xcb_connection_t + * - window_handle -> xcb_window_t + * + * For Metal: + * - instance_handle -> ignored + * - window_handle -> CAMetalLayer + * + * For Android: + * - instance_handle -> ignored + * - window_handle -> ANativeWindow + */ + VkSurfaceKHR kvfCreateSurfaceKHR(VkInstance instance, KvfSurfaceType type, void* instance_handle, void* window_handle); #endif VkImage kvfCreateImage(VkDevice device, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, KvfImageType type); @@ -272,6 +351,42 @@ int32_t kvfFindMemoryType(VkPhysicalDevice physical_device, uint32_t type_filter KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetPhysicalDeviceSurfaceFormatsKHR); KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetPhysicalDeviceSurfacePresentModesKHR); KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkGetPhysicalDeviceSurfaceSupportKHR); + + #ifdef VK_USE_PLATFORM_ANDROID_KHR + #ifdef VK_KHR_android_surface + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateAndroidSurfaceKHR); + #endif + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + #ifdef VK_KHR_xcb_surface + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateXcbSurfaceKHR); + #endif + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + #ifdef VK_KHR_xlib_surface + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateXlibSurfaceKHR); + #endif + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + #ifdef VK_KHR_wayland_surface + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateWaylandSurfaceKHR); + #endif + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + #ifdef VK_KHR_win32_surface + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateWin32SurfaceKHR); + #endif + #endif + + #ifdef VK_USE_PLATFORM_METAL_EXT + #ifdef VK_EXT_metal_surface + KVF_DEFINE_VULKAN_FUNCTION_PROTOTYPE(vkCreateMetalSurfaceEXT); + #endif + #endif #endif }; @@ -2093,6 +2208,98 @@ void kvfDestroySemaphore(VkDevice device, VkSemaphore semaphore) KVF_ASSERT(device != VK_NULL_HANDLE); __kvfDestroySwapchain(device, swapchain); } + + VkSurfaceKHR kvfCreateSurfaceKHR(VkInstance instance, KvfSurfaceType type, void* instance_handle, void* window_handle) + { + VkSurfaceKHR surface = VK_NULL_HANDLE; + switch(type) + { + #ifdef VK_USE_PLATFORM_ANDROID_KHR + case KVF_SURFACE_ANDROID: + { + VkAndroidSurfaceCreateInfoKHR create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; + create_info.pNext = nullptr; + create_info.flags = 0; + create_info.window = (ANativeWindow*)window_handle; + kvfCheckVk(KVF_GET_INSTANCE_FUNCTION(vkCreateAndroidSurfaceKHR)(instance, &create_info, NULL, &surface)); + break; + } + #endif + + #ifdef VK_USE_PLATFORM_XLIB_KHR + case KVF_SURFACE_XLIB: + { + VkXlibSurfaceCreateInfoKHR create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; + create_info.pNext = nullptr; + create_info.flags = 0; + create_info.dpy = (Display*)instance_handle; + create_info.window = *(Window*)window_handle; + kvfCheckVk(KVF_GET_INSTANCE_FUNCTION(vkCreateXlibSurfaceKHR)(instance, &create_info, NULL, &surface)); + break; + } + #endif + + #ifdef VK_USE_PLATFORM_XCB_KHR + case KVF_SURFACE_XCB: + { + VkXcbSurfaceCreateInfoKHR create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; + create_info.pNext = nullptr; + create_info.flags = 0; + create_info.connection = (xcb_connection_t*)instance_handle; + create_info.window = (*xcb_window_t*)window_handle; + kvfCheckVk(KVF_GET_INSTANCE_FUNCTION(vkCreateXcbSurfaceKHR)(instance, &create_info, NULL, &surface)); + break; + } + #endif + + #ifdef VK_USE_PLATFORM_WAYLAND_KHR + case KVF_SURFACE_WAYLAND: + { + VkWaylandSurfaceCreateInfoKHR create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; + create_info.pNext = nullptr; + create_info.flags = 0; + create_info.display = (wl_display*)instance_handle; + create_info.surface = (wl_surface*)window_handle; + kvfCheckVk(KVF_GET_INSTANCE_FUNCTION(vkCreateWaylandSurfaceKHR)(instance, &create_info, NULL, &surface)); + break; + } + #endif + + #ifdef VK_USE_PLATFORM_WIN32_KHR + case KVF_SURFACE_WINDOWS: + { + VkWin32SurfaceCreateInfoKHR create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + create_info.pNext = nullptr; + create_info.flags = 0; + create_info.hinstance = (HINSTANCE)instance_handle; + create_info.hwnd = (HWND)window_handle; + kvfCheckVk(KVF_GET_INSTANCE_FUNCTION(vkCreateWin32SurfaceKHR)(instance, &create_info, NULL, &surface)); + break; + } + #endif + + #ifdef VK_USE_PLATFORM_METAL_EXT + case KVF_SURFACE_METAL: + { + VkMetalSurfaceCreateInfoEXT create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_KHR; + create_info.pNext = nullptr; + create_info.flags = 0; + create_info.pLayer = (CAMetalLayer*)window_handle; + kvfCheckVk(KVF_GET_INSTANCE_FUNCTION(vkCreateMetalSurfaceEXT)(instance, &create_info, NULL, &surface)); + break; + } + #endif + + default: break; + } + return surface; + } #endif VkImage kvfCreateImage(VkDevice device, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, KvfImageType type)