Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions include/zwidget/window/cocoanativehandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,22 @@
@class NSView;
@class CAMetalLayer;
#else
class NSWindow;
class NSView;
class CAMetalLayer;
// Forward declarations for C++ - use opaque pointers to avoid conflicts with Metal headers
typedef struct NSWindow_t* NSWindow;
typedef struct NSView_t* NSView;

// CAMetalLayer may already be defined by vulkan_metal.h, so guard against redefinition
#ifndef VK_EXT_metal_surface
typedef struct CAMetalLayer_t* CAMetalLayer;
#endif
#endif


struct CocoaNativeHandle
{
NSWindow* nsWindow = nullptr;
NSView* nsView = nullptr;
CAMetalLayer* metalLayer = nullptr;

// Use void* to avoid typedef conflicts when CAMetalLayer is defined differently by Vulkan headers
void* metalLayer = nullptr;
};
6 changes: 0 additions & 6 deletions src/window/cocoa/cocoa_display_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@
#include <string>
#include <vector>

#ifdef HAVE_VULKAN
struct VkInstance_T;
typedef struct VkInstance_T* VkInstance;
#endif


struct CocoaDisplayWindowImpl;

class CocoaDisplayWindow : public DisplayWindow
Expand Down
50 changes: 38 additions & 12 deletions src/window/cocoa/cocoa_display_window.mm
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,42 @@
#include <map>
#include <dlfcn.h>
#include <cmath>
#ifdef HAVE_VULKAN
#define VK_USE_PLATFORM_METAL_EXT
#include <vulkan/vulkan.h>
#include <vulkan/vulkan_metal.h>
// Minimal Vulkan type definitions (no headers required)
#ifndef VK_VERSION_1_0

#define VKAPI_CALL
#define VKAPI_PTR VKAPI_CALL

typedef uint32_t VkFlags;
typedef enum VkStructureType {
VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT = 1000217000,
VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF
} VkStructureType;
typedef enum VkResult {
VK_SUCCESS = 0,
VK_RESULT_MAX_ENUM = 0x7FFFFFFF
} VkResult;
typedef struct VkAllocationCallbacks VkAllocationCallbacks;

typedef void (VKAPI_PTR* PFN_vkVoidFunction)(void);
typedef PFN_vkVoidFunction(VKAPI_PTR* PFN_vkGetInstanceProcAddr)(VkInstance instance, const char* pName);

#ifndef VK_EXT_metal_surface
typedef VkFlags VkMetalSurfaceCreateFlagsEXT;
typedef struct VkMetalSurfaceCreateInfoEXT {
VkStructureType sType;
const void* pNext;
VkMetalSurfaceCreateFlagsEXT flags;
const void* pLayer; // CAMetalLayer*
} VkMetalSurfaceCreateInfoEXT;

typedef VkResult(VKAPI_PTR* PFN_vkCreateMetalSurfaceEXT)(
VkInstance instance,
const VkMetalSurfaceCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSurfaceKHR* pSurface);
#endif

#endif
#include <zwidget/core/image.h>
#include "zwidget/window/cocoanativehandle.h"
Expand Down Expand Up @@ -1053,7 +1085,7 @@ - (id)initWithImpl:(CocoaDisplayWindowImpl*)d
handle->nsWindow = impl->window;
handle->nsView = [impl->window contentView];
#ifdef HAVE_METAL
handle->metalLayer = impl->metalLayer;
handle->metalLayer = (__bridge void*)impl->metalLayer;
#endif
}
return handle;
Expand All @@ -1063,15 +1095,12 @@ - (id)initWithImpl:(CocoaDisplayWindowImpl*)d
std::vector<std::string> CocoaDisplayWindow::GetVulkanInstanceExtensions()
{
std::vector<std::string> extensions;
#ifdef HAVE_VULKAN
extensions.push_back("VK_KHR_surface");
extensions.push_back("VK_EXT_metal_surface");
#endif
return extensions;
}
VkSurfaceKHR CocoaDisplayWindow::CreateVulkanSurface(VkInstance instance)
{
#ifdef HAVE_VULKAN
if (impl->window && impl->metalLayer)
{
// Dynamically load vkCreateMetalSurfaceEXT
Expand All @@ -1089,7 +1118,7 @@ - (id)initWithImpl:(CocoaDisplayWindowImpl*)d
{
VkMetalSurfaceCreateInfoEXT surfaceInfo = {};
surfaceInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT;
surfaceInfo.pLayer = impl->metalLayer;
surfaceInfo.pLayer = (__bridge void*)impl->metalLayer;

VkSurfaceKHR surface = nullptr;
VkResult err = vkCreateMetalSurfaceEXT(instance, &surfaceInfo, nullptr, &surface);
Expand All @@ -1099,9 +1128,6 @@ - (id)initWithImpl:(CocoaDisplayWindowImpl*)d
}
}
throw std::runtime_error("Could not create vulkan surface: no metal layer");
#else
throw std::runtime_error("Vulkan support not compiled into zwidget");
#endif
}

void* CocoaDisplayWindow::GetMetalDevice()
Expand Down
2 changes: 2 additions & 0 deletions src/window/sdl2/sdl2_display_window.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "sdl2_display_window.h"
#include <stdexcept>
#include <vector>
#include <string>
#include <SDL2/SDL_vulkan.h>

Uint32 SDL2DisplayWindow::PaintEventNumber = 0xffffffff;
Expand Down