From 8d2af6ff7b303139be00618dd7ddfa35a12281db Mon Sep 17 00:00:00 2001 From: Spoike Date: Sat, 30 Jul 2016 17:59:55 +0000 Subject: [PATCH] Vulkan: Fall back on (XLib-)XCB if (regular)XLib is not supported by the loader/icd. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5014 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/renderer.c | 3 ++ engine/client/snd_dma.c | 3 +- engine/gl/gl_vidlinuxglx.c | 76 ++++++++++++++++++++++++++++++++------ engine/vk/vk_init.c | 43 +++++++++++++++++---- engine/vk/vkrenderer.h | 10 ++++- 5 files changed, 112 insertions(+), 23 deletions(-) diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 9e009b6c..1f042048 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -1163,7 +1163,10 @@ qboolean R_ApplyRenderer (rendererstate_t *newr) if (qrenderer == QR_NONE) { if (newr->renderer->rtype == qrenderer && currentrendererstate.renderer) + { + R_SetRenderer(newr->renderer); return true; //no point + } Sys_CloseTerminal (); } diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index a7807b09..8c4e462c 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -2015,7 +2015,6 @@ void S_Init (void) #ifdef VOICECHAT S_Voip_Init(); #endif - S_EnumerateDevices(); #ifdef MULTITHREAD mixermutex = Sys_CreateMutex(); @@ -2032,6 +2031,8 @@ void S_Init (void) return; } + S_EnumerateDevices(); + p = COM_CheckParm ("-soundspeed"); if (!p) p = COM_CheckParm ("-sspeed"); diff --git a/engine/gl/gl_vidlinuxglx.c b/engine/gl/gl_vidlinuxglx.c index 8d149531..ec958683 100644 --- a/engine/gl/gl_vidlinuxglx.c +++ b/engine/gl/gl_vidlinuxglx.c @@ -60,7 +60,8 @@ none of these issues will be fixed by a compositing window manager, because ther #ifdef VKQUAKE #include "vk/vkrenderer.h" -static qboolean XVK_SetupSurface(void); +static qboolean XVK_SetupSurface_XLib(void); +static qboolean XVK_SetupSurface_XCB(void); #endif #ifdef GLQUAKE #include @@ -184,9 +185,10 @@ static struct XIC unicodecontext; XIM inputmethod; } x11; + static qboolean x11_initlib(void) { - dllfunction_t x11_functable[] = + static dllfunction_t x11_functable[] = { {(void**)&x11.pXChangeProperty, "XChangeProperty"}, {(void**)&x11.pXCloseDisplay, "XCloseDisplay"}, @@ -281,6 +283,35 @@ static qboolean x11_initlib(void) return !!x11.lib; } +#ifdef VK_USE_PLATFORM_XCB_KHR +static struct +{ + void *lib; + xcb_connection_t *(*pXGetXCBConnection)(Display *dpy); +} x11xcb; +static qboolean x11xcb_initlib(void) +{ + static dllfunction_t x11xcb_functable[] = + { + {(void**)&x11xcb.pXGetXCBConnection, "XGetXCBConnection"}, + {NULL, NULL} + }; + + if (!x11xcb.lib) + { + x11xcb.lib = Sys_LoadLibrary("libX11-xcb.so.1", x11xcb_functable); + if (!x11xcb.lib) + x11xcb.lib = Sys_LoadLibrary("libX11-xcb", x11xcb_functable); + + if (!x11xcb.lib) + Con_Printf("Unable to load libX11-xcb\n"); + } + + return !!x11xcb.lib; +} +#endif + + #define FULLSCREEN_VMODE 1 //using xf86 vidmode (we can actually change modes) #define FULLSCREEN_VMODEACTIVE 2 //xf86 vidmode currently forced #define FULLSCREEN_LEGACY 4 //override redirect used @@ -333,7 +364,7 @@ static struct } vm; static qboolean VMODE_Init(void) { - dllfunction_t vm_functable[] = + static dllfunction_t vm_functable[] = { {(void**)&vm.pXF86VidModeQueryVersion, "XF86VidModeQueryVersion"}, {(void**)&vm.pXF86VidModeGetGammaRampSize, "XF86VidModeGetGammaRampSize"}, @@ -401,7 +432,7 @@ static struct } dgam; static qboolean DGAM_Init(void) { - dllfunction_t dgam_functable[] = + static dllfunction_t dgam_functable[] = { {(void**)&dgam.pXF86DGADirectVideo, "XF86DGADirectVideo"}, {NULL, NULL} @@ -467,7 +498,7 @@ static struct } xi2; static qboolean XI2_Init(void) { - dllfunction_t xi2_functable[] = + static dllfunction_t xi2_functable[] = { {(void**)&xi2.pXIQueryVersion, "XIQueryVersion"}, {(void**)&xi2.pXISelectEvents, "XISelectEvents"}, @@ -1901,12 +1932,17 @@ qboolean X11VID_Init (rendererstate_t *info, unsigned char *palette, int psl) #endif #ifdef VKQUAKE case PSL_VULKAN: - if (!VK_Init(info, VK_KHR_XLIB_SURFACE_EXTENSION_NAME, XVK_SetupSurface)) - { - Con_Printf("Failed to create vulkan context.\n"); - GLVID_Shutdown(); - } - break; +#ifdef VK_USE_PLATFORM_XLIB_KHR + if (VK_Init(info, VK_KHR_XLIB_SURFACE_EXTENSION_NAME, XVK_SetupSurface_XLib)) + break; +#endif +#ifdef VK_USE_PLATFORM_XCB_KHR + if (x11xcb_initlib() && VK_Init(info, VK_KHR_XCB_SURFACE_EXTENSION_NAME, XVK_SetupSurface_XCB)) + break; +#endif + Con_Printf("Failed to create a vulkan context.\n"); + GLVID_Shutdown(); + return false; #endif case PSL_NONE: break; @@ -2190,7 +2226,8 @@ rendererinfo_t eglrendererinfo = #endif #ifdef VKQUAKE -static qboolean XVK_SetupSurface(void) +#ifdef VK_USE_PLATFORM_XLIB_KHR +static qboolean XVK_SetupSurface_XLib(void) { VkXlibSurfaceCreateInfoKHR inf = {VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR}; inf.flags = 0; @@ -2201,6 +2238,20 @@ static qboolean XVK_SetupSurface(void) return true; return false; } +#endif +#ifdef VK_USE_PLATFORM_XCB_KHR +static qboolean XVK_SetupSurface_XCB(void) +{ + VkXcbSurfaceCreateInfoKHR inf = {VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR}; + inf.flags = 0; + inf.connection = x11xcb.pXGetXCBConnection(vid_dpy); + inf.window = vid_window; + + if (VK_SUCCESS == vkCreateXcbSurfaceKHR(vk.instance, &inf, vkallocationcb, &vk.surface)) + return true; + return false; +} +#endif rendererinfo_t vkrendererinfo = { "Vulkan(X11)", @@ -2323,3 +2374,4 @@ qboolean X11_GetDesktopParameters(int *width, int *height, int *bpp, int *refres return true; } + diff --git a/engine/vk/vk_init.c b/engine/vk/vk_init.c index d01b3cc4..3866dd5e 100644 --- a/engine/vk/vk_init.c +++ b/engine/vk/vk_init.c @@ -2803,6 +2803,24 @@ qboolean VK_Init(rendererstate_t *info, const char *sysextname, qboolean (*creat return false; case VK_ERROR_EXTENSION_NOT_PRESENT: Con_Printf("VK_ERROR_EXTENSION_NOT_PRESENT: something on a system level is probably misconfigured\n"); + { + uint32_t count, i, j; + VkExtensionProperties *ext; + vkEnumerateInstanceExtensionProperties(NULL, &count, NULL); + ext = malloc(sizeof(*ext)*count); + vkEnumerateInstanceExtensionProperties(NULL, &count, ext); + for (i = 0; i < extensions_count; i++) + { + for (j = 0; j < count; j++) + { + if (!strcmp(ext[j].extensionName, extensions[i])) + break; + } + if (j == count) + Con_Printf("Missing extension: %s\n", extensions[i]); + } + free(ext); + } return false; case VK_ERROR_LAYER_NOT_PRESENT: Con_Printf("VK_ERROR_LAYER_NOT_PRESENT: requested layer is not known/usable\n"); @@ -3166,12 +3184,15 @@ void VK_Shutdown(void) VKBE_RT_Gen_Cube(&vk_rt_cubemap, 0, false); VK_R_BloomShutdown(); - vkDestroyCommandPool(vk.device, vk.cmdpool, vkallocationcb); + if (vk.cmdpool) + vkDestroyCommandPool(vk.device, vk.cmdpool, vkallocationcb); VK_DestroyRenderPass(); #ifndef THREADACQUIRE - vkDestroyFence(vk.device, vk.acquirefence, vkallocationcb); + if (vk.acquirefence) + vkDestroyFence(vk.device, vk.acquirefence, vkallocationcb); #endif + if (vk.pipelinecache) { size_t size; if (VK_SUCCESS == vkGetPipelineCacheData(vk.device, vk.pipelinecache, &size, NULL)) @@ -3184,17 +3205,23 @@ void VK_Shutdown(void) vkDestroyPipelineCache(vk.device, vk.pipelinecache, vkallocationcb); } - vkDestroyDevice(vk.device, vkallocationcb); + if (vk.device) + vkDestroyDevice(vk.device, vkallocationcb); if (vk_debugcallback) { vkDestroyDebugReportCallbackEXT(vk.instance, vk_debugcallback, vkallocationcb); vk_debugcallback = VK_NULL_HANDLE; } - vkDestroySurfaceKHR(vk.instance, vk.surface, vkallocationcb); - vkDestroyInstance(vk.instance, vkallocationcb); - Sys_DestroyMutex(vk.swapchain_mutex); - Sys_DestroyConditional(vk.submitcondition); - Sys_DestroyConditional(vk.acquirecondition); + if (vk.surface) + vkDestroySurfaceKHR(vk.instance, vk.surface, vkallocationcb); + if (vk.instance) + vkDestroyInstance(vk.instance, vkallocationcb); + if (vk.swapchain_mutex) + Sys_DestroyMutex(vk.swapchain_mutex); + if (vk.submitcondition) + Sys_DestroyConditional(vk.submitcondition); + if (vk.acquirecondition) + Sys_DestroyConditional(vk.acquirecondition); memset(&vk, 0, sizeof(vk)); qrenderer = QR_NONE; diff --git a/engine/vk/vkrenderer.h b/engine/vk/vkrenderer.h index 2ebe7b62..30fcccab 100644 --- a/engine/vk/vkrenderer.h +++ b/engine/vk/vkrenderer.h @@ -9,6 +9,9 @@ #ifdef __linux__ #define VK_USE_PLATFORM_XLIB_KHR #define VKInstXLibFuncs VKFunc(CreateXlibSurfaceKHR) + +#define VK_USE_PLATFORM_XCB_KHR +#define VKInstXCBFuncs VKFunc(CreateXcbSurfaceKHR) #endif #define VK_NO_PROTOTYPES @@ -28,6 +31,11 @@ #ifndef VKInstXLibFuncs #define VKInstXLibFuncs #endif +#ifndef VKInstXCBFuncs +#define VKInstXCBFuncs +#endif +#define VKInstArchFuncs VKInstWin32Funcs VKInstXLibFuncs VKInstXCBFuncs + //funcs needed for creating an instance #define VKInstFuncs \ @@ -35,8 +43,6 @@ VKFunc(EnumerateInstanceExtensionProperties) \ VKFunc(CreateInstance) -#define VKInstArchFuncs VKInstWin32Funcs VKInstXLibFuncs - //funcs specific to an instance #define VKInst2Funcs \ VKFunc(EnumeratePhysicalDevices) \