/* vid_x11_vulkan.c Vulkan X11 video driver Copyright (C) 1996-1997 Id Software, Inc. Copyright (C) 1999-2000 contributors of the QuakeForge project Copyright (C) 2000 Marcus Sundberg [mackan@stacken.kth.se] Copyright (C) 1999,2000 contributors of the QuakeForge project Please see the file "AUTHORS" for a list of contributors This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to: Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_UNISTD_H # include #endif #include #include #include #include #define VK_NO_PROTOTYPES #define VK_USE_PLATFORM_XLIB_KHR #include #include "QF/cvar.h" #include "QF/set.h" #include "QF/sys.h" #include "context_x11.h" #include "vid_internal.h" #include "vid_vulkan.h" static cvar_t *vulkan_library_name; typedef struct vulkan_presentation_s { #define INSTANCE_LEVEL_VULKAN_FUNCTION(name) PFN_##name name; #include "QF/Vulkan/funclist.h" Display *display; Window window; int num_visuals; XVisualInfo *visinfo; set_t *usable_visuals; } vulkan_presentation_t; static const char *required_extensions[] = { VK_KHR_XLIB_SURFACE_EXTENSION_NAME, 0 }; static void *vulkan_library; static void load_vulkan_library (vulkan_ctx_t *ctx) { vulkan_library = dlopen (vulkan_library_name->string, RTLD_DEEPBIND | RTLD_NOW); if (!vulkan_library) { Sys_Error ("Couldn't load vulkan library %s: %s", vulkan_library_name->name, dlerror ()); } #define EXPORTED_VULKAN_FUNCTION(name) \ ctx->name = (PFN_##name) dlsym (vulkan_library, #name); \ if (!ctx->name) { \ Sys_Error ("Couldn't find exported vulkan function %s", #name); \ } #define GLOBAL_LEVEL_VULKAN_FUNCTION(name) \ ctx->name = (PFN_##name) ctx->vkGetInstanceProcAddr (0, #name); \ if (!ctx->name) { \ Sys_Error ("Couldn't find global-level function %s", #name); \ } #include "QF/Vulkan/funclist.h" } static void unload_vulkan_library (vulkan_ctx_t *ctx) { dlclose (vulkan_library); vulkan_library = 0; } static int x11_vulkan_get_presentation_support (vulkan_ctx_t *ctx, VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex) { vulkan_presentation_t *pres = ctx->presentation; set_empty (pres->usable_visuals); for (int i = 0; i < pres->num_visuals; i++) { VisualID visID = pres->visinfo[i].visualid; if (pres->vkGetPhysicalDeviceXlibPresentationSupportKHR ( physicalDevice, queueFamilyIndex, pres->display, visID)) { set_add (pres->usable_visuals, i); } } return !set_is_empty (pres->usable_visuals); } static VkSurfaceKHR x11_vulkan_create_surface (vulkan_ctx_t *ctx) { vulkan_presentation_t *pres = ctx->presentation; VkSurfaceKHR surface; VkXlibSurfaceCreateInfoKHR createInfo = { .sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, .flags = 0, .dpy = pres->display, .window = pres->window }; if (pres->vkCreateXlibSurfaceKHR (ctx->instance, &createInfo, 0, &surface) != VK_SUCCESS) { return 0; } return surface; } vulkan_ctx_t * X11_Vulkan_Context (void) { vulkan_ctx_t *ctx = calloc (1, sizeof (vulkan_ctx_t)); ctx->load_vulkan = load_vulkan_library; ctx->unload_vulkan = unload_vulkan_library; ctx->get_presentation_support = x11_vulkan_get_presentation_support; ctx->create_surface = x11_vulkan_create_surface; ctx->required_extensions = required_extensions; return ctx; } void X11_Vulkan_Init_Cvars (void) { vulkan_library_name = Cvar_Get ("vulkan_library", "libvulkan.so.1", CVAR_ROM, 0, "the name of the vulkan shared library"); }