// Copyright 2012-2022 David Robillard // SPDX-License-Identifier: ISC #define VK_NO_PROTOTYPES 1 #include "attributes.h" #include "stub.h" #include "types.h" #include "x11.h" #include "pugl/pugl.h" #include "pugl/vulkan.h" #include #include #include #include #include struct PuglVulkanLoaderImpl { void* libvulkan; PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr; }; PuglVulkanLoader* puglNewVulkanLoader(PuglWorld* PUGL_UNUSED(world), const char* const libraryName) { const char* const filename = libraryName ? libraryName : "libvulkan.so"; void* const libvulkan = dlopen(filename, RTLD_LAZY); if (!libvulkan) { return NULL; } PuglVulkanLoader* const loader = (PuglVulkanLoader*)calloc(1, sizeof(PuglVulkanLoader)); if (!loader) { dlclose(libvulkan); return NULL; } loader->libvulkan = libvulkan; loader->vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)dlsym( loader->libvulkan, "vkGetInstanceProcAddr"); loader->vkGetDeviceProcAddr = (PFN_vkGetDeviceProcAddr)dlsym(loader->libvulkan, "vkGetDeviceProcAddr"); return loader; } void puglFreeVulkanLoader(PuglVulkanLoader* loader) { if (loader) { dlclose(loader->libvulkan); free(loader); } } PFN_vkGetInstanceProcAddr puglGetInstanceProcAddrFunc(const PuglVulkanLoader* loader) { return loader->vkGetInstanceProcAddr; } PFN_vkGetDeviceProcAddr puglGetDeviceProcAddrFunc(const PuglVulkanLoader* loader) { return loader->vkGetDeviceProcAddr; } const PuglBackend* puglVulkanBackend(void) { static const PuglBackend backend = {puglX11Configure, puglStubCreate, puglStubDestroy, puglStubEnter, puglStubLeave, puglStubGetContext}; return &backend; } const char* const* puglGetInstanceExtensions(uint32_t* const count) { static const char* const extensions[] = {"VK_KHR_surface", "VK_KHR_xlib_surface"}; *count = 2; return extensions; } VkResult puglCreateSurface(PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr, PuglView* const view, VkInstance instance, const VkAllocationCallbacks* const allocator, VkSurfaceKHR* const surface) { PuglInternals* const impl = view->impl; PuglWorldInternals* world_impl = view->world->impl; PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR = (PFN_vkCreateXlibSurfaceKHR)vkGetInstanceProcAddr(instance, "vkCreateXlibSurfaceKHR"); const VkXlibSurfaceCreateInfoKHR info = { VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, NULL, 0, world_impl->display, impl->win, }; return vkCreateXlibSurfaceKHR(instance, &info, allocator, surface); }