/* =========================================================================== Copyright (C) 1999-2005 Id Software, Inc. This file is part of Quake III Arena source code. Quake III Arena source code 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. Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ /* ** QVK_WIN.C ** ** This file implements the operating system binding of Vulkan to QVulkan function ** pointers. When doing a port of Quake3 you must implement the following ** two functions: ** ** QVK_Init() - loads libraries, assigns function pointers, etc. ** QVK_Shutdown() - unloads libraries, NULLs function pointers */ #ifdef USE_VULKAN_API #include "../qcommon/q_shared.h" #include "../qcommon/qcommon.h" #include "../renderercommon/tr_types.h" #include "glw_win.h" #include "win_local.h" #define VK_USE_PLATFORM_WIN32_KHR #include "../renderercommon/vulkan/vulkan.h" static PFN_vkGetInstanceProcAddr qvkGetInstanceProcAddr; static PFN_vkCreateWin32SurfaceKHR qvkCreateWin32SurfaceKHR; /* ** QVK_Shutdown ** ** Unloads the specified DLL then nulls out all the proc pointers. This ** is only called during a hard shutdown of the Vulkan subsystem (e.g. vid_restart). */ void QVK_Shutdown( qboolean unloadDLL ) { Com_Printf( "...shutting down QVK\n" ); if ( glw_state.VulkanLib && unloadDLL ) { Com_Printf( "...unloading Vulkan DLL\n" ); Sys_UnloadLibrary( glw_state.VulkanLib ); glw_state.VulkanLib = NULL; qvkGetInstanceProcAddr = NULL; } qvkCreateWin32SurfaceKHR = NULL; } void *VK_GetInstanceProcAddr( VkInstance instance, const char *name ) { return qvkGetInstanceProcAddr( instance, name ); } qboolean VK_CreateSurface( VkInstance instance, VkSurfaceKHR *pSurface ) { VkWin32SurfaceCreateInfoKHR desc; qvkCreateWin32SurfaceKHR = /*(PFN_vkCreateWin32SurfaceKHR)*/ VK_GetInstanceProcAddr( instance, "vkCreateWin32SurfaceKHR" ); if ( !qvkCreateWin32SurfaceKHR ) return qfalse; desc.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; desc.pNext = NULL; desc.flags = 0; desc.hinstance = GetModuleHandle( NULL ); desc.hwnd = g_wv.hWnd; if ( qvkCreateWin32SurfaceKHR( instance, &desc, NULL, pSurface ) == VK_SUCCESS ) return qtrue; else return qfalse; } static HINSTANCE load_vulkan_library( const char *dllname ) { HINSTANCE lib; lib = Sys_LoadLibrary( dllname ); if ( lib ) { qvkGetInstanceProcAddr = /*(PFN_vkGetInstanceProcAddr)*/ Sys_LoadFunction( lib, "vkGetInstanceProcAddr" ); if ( qvkGetInstanceProcAddr ) { return lib; } Sys_UnloadLibrary( lib ); } return NULL; } /* ** QVK_Init ** ** This is responsible for binding our qvk function pointers to ** the appropriate Vulkan stuff. In Windows this means doing a ** LoadLibrary and a bunch of calls to GetProcAddress. On other ** operating systems we need to do the right thing, whatever that ** might be. */ qboolean QVK_Init( void ) { Com_Printf( "...initializing QVK\n" ); if ( glw_state.VulkanLib == NULL ) { const char *dllnames[] = { "vulkan-1.dll", #if idx64 "amdvlk64.dll", "igvk64.dll" #else "amdvlk32.dll", "igvk32.dll" #endif }; int i; for ( i = 0; i < ARRAY_LEN( dllnames ); i++ ) { glw_state.VulkanLib = load_vulkan_library( dllnames[i] ); //Com_Printf( "...loading '%s' : %s\n", dllnames[i], glw_state.VulkanLib ? "success" : "failed" ); if ( glw_state.VulkanLib ) { char libName[1024]; #ifdef UNICODE TCHAR buffer[1024]; GetModuleFileName( glw_state.VulkanLib, buffer, ARRAY_LEN( buffer ) ); buffer[ ARRAY_LEN( buffer ) - 1 ] = '\0'; Q_strncpyz( libName, WtoA( buffer ), sizeof( libName ) ); #else GetModuleFileName( glw_state.VulkanLib, libName, sizeof( libName ) ); libName[ sizeof( libName ) - 1 ] = '\0'; #endif Com_Printf( "...loading '%s' : %s\n", libName, "success" ); break; } else { Com_Printf( "...loading '%s' : %s\n", dllnames[i], "failed" ); } } if ( !glw_state.VulkanLib ) { return qfalse; } } Sys_LoadFunctionErrors(); // reset error counter return qtrue; } #endif // USE_VULKAN_API