diff --git a/CMakeLists.txt b/CMakeLists.txt index 585fb4d..0cc7953 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,6 +70,11 @@ if(MW_TRY_VULKAN) if(HAVE_VULKAN_VULKAN_H) set(MW_BUILD_VULKAN ON) list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/widget/vulkan.c") + target_compile_definitions( + Mw + PRIVATE + MW_VULKAN + ) message(STATUS "Vulkan widget has been enabled") else() message(WARNING "Vulkan widget has been disabled") diff --git a/pl/rules.pl b/pl/rules.pl index 6c23006..3da1928 100644 --- a/pl/rules.pl +++ b/pl/rules.pl @@ -131,6 +131,7 @@ if (param_get("opengl")) { new_object("src/widget/opengl.c"); } if (param_get("vulkan")) { + add_cflags("-DMW_VULKAN"); new_object("src/widget/vulkan.c"); } diff --git a/src/backend/cocoa.m b/src/backend/cocoa.m index 7051367..4cdc5b2 100644 --- a/src/backend/cocoa.m +++ b/src/backend/cocoa.m @@ -2,6 +2,11 @@ #include "../../external/stb_ds.h" #include "Mw/LowLevel/Cocoa.h" +#ifdef MW_VULKAN +#include +#include +#endif + #ifdef __clang__ #pragma clang push #pragma clang diagnostic ignored "-Wdeprecated-declarations" @@ -1087,5 +1092,17 @@ static int MwLLCocoaCallInitImpl(void) { return 0; } +#ifdef MW_VULKAN +VkMetalSurfaceCreateInfoEXT MwCocoaGetMetalSurfaceCreateInfo(MwWidget handle) { + VkMetalSurfaceCreateInfoEXT createInfo = { + .sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT, + .pNext = NULL, + .flags = 0, + .pLayer = (CAMetalLayer*)[handle->lowlevel->cocoa.real->view layer], + }; + return createInfo; +}; +#endif + #include "call.c" CALL(Cocoa); diff --git a/src/widget/vulkan.c b/src/widget/vulkan.c index 1a9ea12..195384c 100644 --- a/src/widget/vulkan.c +++ b/src/widget/vulkan.c @@ -26,6 +26,9 @@ #ifdef USE_WAYLAND #include #endif +#ifdef USE_COCOA +#include +#endif #ifdef HAS_VK_ENUM_STRING_HELPER #include @@ -167,6 +170,8 @@ static void destroy(MwWidget handle) { static void* vulkan_lib_load() { #ifdef _WIN32 return MwDynamicOpen("vulkan-1.dll"); +#elif defined(__APPLE__) + return MwDynamicOpen("libvulkan.dylib"); #else return MwDynamicOpen("libvulkan.so"); #endif @@ -230,6 +235,11 @@ static int vulkan_instance_setup(MwWidget handle, vulkan_t* o) { MwWaylandAlwaysRender = MwTRUE; } #endif +#ifdef USE_WAYLAND + if(handle->lowlevel->common.type == MwLLBackendCocoa) { + arrput(enabledExtensions, VK_EXT_METAL_SURFACE_EXTENSION_NAME); + } +#endif /* passing null gives us all the extensions provided by the current vulkan implementation */ VK_CMD(_vkEnumerateInstanceExtensionProperties(NULL, &extension_count, NULL)); @@ -338,6 +348,16 @@ static int vulkan_surface_setup(MwWidget handle, vulkan_t* o) { }; VK_CMD(_vkCreateWaylandSurfaceKHR(o->vkInstance, &createInfo, NULL, &o->vkSurface)); } +#endif +#ifdef USE_COCOA + if(handle->lowlevel->common.type == MwLLBackendCocoa) { + VkMetalSurfaceCreateInfoEXT MwCocoaGetMetalSurfaceCreateInfo(MwWidget handle); + VkMetalSurfaceCreateInfoEXT inf = MwCocoaGetMetalSurfaceCreateInfo(handle); + + LOAD_VK_FUNCTION(vkCreateMetalSurfaceEXT); + + VK_CMD(_vkCreateMetalSurfaceEXT(o->vkInstance, &inf, NULL, &o->vkSurface)); + } #endif return 0; }