From f1e650e2c4c90c7586417fb758aee0a00174c33d Mon Sep 17 00:00:00 2001 From: Eric Womer Date: Sun, 29 Dec 2019 11:12:34 -0500 Subject: [PATCH 1/7] Applying KungFuJesus's patch from https://github.com/RobertBeckebans/RBDOOM-3-BFG/issues/398#issuecomment-569442019 --- neo/CMakeLists.txt | 7 ++- neo/idlib/geometry/DrawVert.h | 4 +- neo/idlib/precompiled.h | 2 +- neo/idlib/sys/sys_types.h | 6 +- neo/renderer/Image.h | 4 ++ neo/renderer/Vulkan/Allocator_VK.cpp | 10 ++-- neo/renderer/Vulkan/RenderBackend_VK.cpp | 51 +++++++++++++--- neo/renderer/Vulkan/RenderProgs_VK.cpp | 6 +- neo/renderer/Vulkan/qvk.h | 5 +- neo/renderer/Vulkan/vma.h | 1 + neo/swf/SWF_Sprites.h | 3 + neo/sys/posix/platform_linux.cpp | 76 +++++++++++++++++++++++- neo/sys/posix/posix_public.h | 18 ++++++ neo/sys/sdl/sdl_glimp.cpp | 18 ++++++ 14 files changed, 182 insertions(+), 29 deletions(-) diff --git a/neo/CMakeLists.txt b/neo/CMakeLists.txt index b8ef7fef..736204f6 100644 --- a/neo/CMakeLists.txt +++ b/neo/CMakeLists.txt @@ -315,10 +315,10 @@ if(USE_VULKAN) #option(ENABLE_NV_EXTENSIONS "Enables support of Nvidia-specific extensions" ON) #option(ENABLE_OPT "Enables spirv-opt capability if present" ON) - set(GLSLANG_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libs/glslang) - add_subdirectory(${GLSLANG_DIR}) + #set(GLSLANG_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libs/glslang) + #add_subdirectory(${GLSLANG_DIR}) - include_directories(${GLSLANG_DIR}/glslang) + #include_directories(${GLSLANG_DIR}/glslang) else() @@ -1321,6 +1321,7 @@ if(MSVC) ${Vulkan_LIBRARY} glslang SPIRV + xcb ) if(ENABLE_GLSLANG_BINARIES) diff --git a/neo/idlib/geometry/DrawVert.h b/neo/idlib/geometry/DrawVert.h index 2c97f855..bbbe5805 100644 --- a/neo/idlib/geometry/DrawVert.h +++ b/neo/idlib/geometry/DrawVert.h @@ -122,11 +122,11 @@ class idDrawVert public: idVec3 xyz; // 12 bytes -private: - // RB: don't let the old tools code mess with these values halfFloat_t st[2]; // 4 bytes byte normal[4]; // 4 bytes byte tangent[4]; // 4 bytes -- [3] is texture polarity sign +//private: + // RB: don't let the old tools code mess with these values public: byte color[4]; // 4 bytes byte color2[4]; // 4 bytes -- weights for skinning diff --git a/neo/idlib/precompiled.h b/neo/idlib/precompiled.h index f476597a..229e5800 100644 --- a/neo/idlib/precompiled.h +++ b/neo/idlib/precompiled.h @@ -113,7 +113,7 @@ const uint32 NUM_FRAME_DATA = 2; #include "../ui/UserInterface.h" // RB: required for SWF extensions -#include "rapidjson/document.h" +//#include "rapidjson/document.h" #include "../swf/SWF.h" diff --git a/neo/idlib/sys/sys_types.h b/neo/idlib/sys/sys_types.h index 7af3bbb5..1a2e5746 100644 --- a/neo/idlib/sys/sys_types.h +++ b/neo/idlib/sys/sys_types.h @@ -118,9 +118,9 @@ struct idNullPtr //#endif // C99 Standard -#ifndef nullptr -#define nullptr idNullPtr() -#endif +//#ifndef nullptr +//#define nullptr idNullPtr() +//#endif #ifndef BIT #define BIT( num ) ( 1ULL << ( num ) ) diff --git a/neo/renderer/Image.h b/neo/renderer/Image.h index 183fee75..b69103bf 100644 --- a/neo/renderer/Image.h +++ b/neo/renderer/Image.h @@ -394,7 +394,11 @@ public: ActuallyLoadImage( true ); } + #ifndef USE_VULKAN return ( void* )( intptr_t )texnum; + #else + return ( void* )( intptr_t )garbageIndex; + #endif } // DG end diff --git a/neo/renderer/Vulkan/Allocator_VK.cpp b/neo/renderer/Vulkan/Allocator_VK.cpp index 5a8236e8..006cf22b 100644 --- a/neo/renderer/Vulkan/Allocator_VK.cpp +++ b/neo/renderer/Vulkan/Allocator_VK.cpp @@ -610,11 +610,11 @@ CONSOLE_COMMAND( Vulkan_PrintHeapInfo, "Print out the heap information for this { VkPhysicalDeviceMemoryProperties& props = vkcontext.gpu->memProps; - idLib::Printf( "Heaps %lu\n------------------------\n", props.memoryHeapCount ); + idLib::Printf( "Heaps %u\n------------------------\n", props.memoryHeapCount ); for( uint32 i = 0; i < props.memoryHeapCount; ++i ) { VkMemoryHeap heap = props.memoryHeaps[ i ]; - idLib::Printf( "id=%d, size=%llu, flags=", i, heap.size ); + idLib::Printf( "id=%d, size=%lu, flags=", i, heap.size ); if( heap.flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT ) { idLib::Printf( "DEVICE_LOCAL" ); @@ -657,11 +657,11 @@ CONSOLE_COMMAND( Vulkan_PrintHeapInfo, "Print out the heap information for this if( properties.Length() > 0 ) { - idLib::Printf( "memory_type=%lu\n", j ); - idLib::Printf( properties.c_str() ); + idLib::Printf( "memory_type=%u\n", j ); + idLib::Printf( "%s", properties.c_str() ); } } idLib::Printf( "\n" ); } -} \ No newline at end of file +} diff --git a/neo/renderer/Vulkan/RenderBackend_VK.cpp b/neo/renderer/Vulkan/RenderBackend_VK.cpp index a3f865d4..e6dcc442 100644 --- a/neo/renderer/Vulkan/RenderBackend_VK.cpp +++ b/neo/renderer/Vulkan/RenderBackend_VK.cpp @@ -31,6 +31,10 @@ If you have questions concerning this license or the applicable additional terms #pragma hdrstop #include "precompiled.h" +#ifdef __linux__ +#include "../../sys/posix/posix_public.h" +#endif + #include "../RenderCommon.h" #include "../RenderBackend.h" #include "Staging_VK.h" @@ -53,7 +57,7 @@ static const int g_numInstanceExtensions = 2; static const char* g_instanceExtensions[ g_numInstanceExtensions ] = { VK_KHR_SURFACE_EXTENSION_NAME, - VK_KHR_WIN32_SURFACE_EXTENSION_NAME + VK_KHR_XCB_SURFACE_EXTENSION_NAME }; static const int g_numDebugInstanceExtensions = 1; @@ -301,6 +305,8 @@ static void EnumeratePhysicalDevices() uint32 numDevices = 0; ID_VK_CHECK( vkEnumeratePhysicalDevices( vkcontext.instance, &numDevices, NULL ) ); ID_VK_VALIDATE( numDevices > 0, "vkEnumeratePhysicalDevices returned zero devices." ); + + idLib::Printf("found %u devices\n", numDevices); idList< VkPhysicalDevice > devices; devices.SetNum( numDevices ); @@ -312,11 +318,15 @@ static void EnumeratePhysicalDevices() for( uint32 i = 0; i < numDevices; ++i ) { + idLib::Printf("Iterating over gpu %u\n", i); gpuInfo_t& gpu = vkcontext.gpus[ i ]; + idLib::Printf("have gpuInfo_t ref at %p\n", &vkcontext.gpus[i]); gpu.device = devices[ i ]; + idLib::Printf("set gpu.device\n"); // get Queue family properties { + idLib::Printf("Getting queue family props...\n"); uint32 numQueues = 0; vkGetPhysicalDeviceQueueFamilyProperties( gpu.device, &numQueues, NULL ); ID_VK_VALIDATE( numQueues > 0, "vkGetPhysicalDeviceQueueFamilyProperties returned zero queues." ); @@ -328,6 +338,7 @@ static void EnumeratePhysicalDevices() // grab available Vulkan extensions { + idLib::Printf("Getting available vulkan extensions...\n"); uint32 numExtension; ID_VK_CHECK( vkEnumerateDeviceExtensionProperties( gpu.device, NULL, &numExtension, NULL ) ); ID_VK_VALIDATE( numExtension > 0, "vkEnumerateDeviceExtensionProperties returned zero extensions." ); @@ -422,10 +433,11 @@ static void CreateSurface() VkXcbSurfaceCreateInfoKHR createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; createInfo.pNext = NULL; + createInfo.flags = 0; createInfo.connection = info.connection; createInfo.window = info.window; - ID_VK_CHECK( vkCreateXcbSurfaceKHR( info.inst, &createInfo, NULL, &info.surface ) ); + ID_VK_CHECK( vkCreateXcbSurfaceKHR( vkcontext.instance, &createInfo, NULL, &vkcontext.surface ) ); #endif // _WIN32 @@ -540,22 +552,22 @@ static void SelectPhysicalDevice() switch( gpu.props.vendorID ) { case 0x8086: - idLib::Printf( "Vendor: Intel\n", i ); + idLib::Printf( "Vendor: Intel\n"); glConfig.vendor = VENDOR_INTEL; break; case 0x10DE: - idLib::Printf( "Vendor: NVIDIA\n", i ); + idLib::Printf( "Vendor: NVIDIA\n"); glConfig.vendor = VENDOR_NVIDIA; break; case 0x1002: - idLib::Printf( "Vendor: AMD\n", i ); + idLib::Printf( "Vendor: AMD\n"); glConfig.vendor = VENDOR_AMD; break; default: - idLib::Printf( "Vendor: Unknown (0x%x)\n", i, gpu.props.vendorID ); + idLib::Printf( "Vendor: Unknown (0x%x)\n", gpu.props.vendorID ); } return; @@ -1276,30 +1288,38 @@ void idRenderBackend::Init() glConfig.driverType = GLDRV_VULKAN; glConfig.gpuSkinningAvailable = true; + idLib::Printf( "Creating Vulkan Instance...\n" ); // create the Vulkan instance and enable validation layers CreateVulkanInstance(); // create the windowing interface -#ifdef _WIN32 +//#ifdef _WIN32 + idLib::Printf( "Creating Vulkan Surface...\n" ); CreateSurface(); -#endif +//#endif // Enumerate physical devices and get their properties + idLib::Printf( "Enumerating physical devices and their properties...\n" ); EnumeratePhysicalDevices(); // Find queue family/families supporting graphics and present. + idLib::Printf( "Selecting physical device...\n" ); SelectPhysicalDevice(); // Create logical device and queues + idLib::Printf( "Creating logical device and queues...\n" ); CreateLogicalDeviceAndQueues(); // Create semaphores for image acquisition and rendering completion + idLib::Printf( "Creating semaphores...\n" ); CreateSemaphores(); // Create Command Pool + idLib::Printf( "Creating command pool...\n" ); CreateCommandPool(); // Create Command Buffer + idLib::Printf( "Creating command buffer...\n" ); CreateCommandBuffer(); // setup the allocator @@ -1319,21 +1339,27 @@ void idRenderBackend::Init() #endif // Start the Staging Manager + idLib::Printf( "Creating staging manager...\n" ); stagingManager.Init(); // Create Swap Chain + idLib::Printf( "Creating swapchain...\n" ); CreateSwapChain(); // Create Render Targets + idLib::Printf( "Creating render targets...\n" ); CreateRenderTargets(); // Create Render Pass + idLib::Printf( "Creating render pass...\n" ); CreateRenderPass(); // Create Pipeline Cache + idLib::Printf( "Creating pipeline cache...\n" ); CreatePipelineCache(); // Create Frame Buffers + idLib::Printf( "Creating frame buffers...\n" ); CreateFrameBuffers(); // init RenderProg Manager @@ -2355,4 +2381,11 @@ void Framebuffer::Check() void Framebuffer::CheckFramebuffers() { // TODO -} \ No newline at end of file +} + +void idRenderBackend::ImGui_RenderDrawLists( ImDrawData* draw_data ) +{ + // TODO + + renderProgManager.Unbind(); +} diff --git a/neo/renderer/Vulkan/RenderProgs_VK.cpp b/neo/renderer/Vulkan/RenderProgs_VK.cpp index a528ac3d..a641c399 100644 --- a/neo/renderer/Vulkan/RenderProgs_VK.cpp +++ b/neo/renderer/Vulkan/RenderProgs_VK.cpp @@ -343,8 +343,8 @@ CompileGLSLtoSPIRV #include #include -#include -#include +#include +//#include namespace glslang { @@ -352,7 +352,7 @@ namespace glslang // These are the default resources for TBuiltInResources, used for both // - parsing this string for the case where the user didn't supply one, // - dumping out a template for user construction of a config file. -#if 0 +#if 1 extern const TBuiltInResource DefaultTBuiltInResource; #else const TBuiltInResource DefaultTBuiltInResource = diff --git a/neo/renderer/Vulkan/qvk.h b/neo/renderer/Vulkan/qvk.h index dbd8b85e..8e9c8bc0 100644 --- a/neo/renderer/Vulkan/qvk.h +++ b/neo/renderer/Vulkan/qvk.h @@ -32,7 +32,8 @@ If you have questions concerning this license or the applicable additional terms #if defined( USE_VULKAN ) -#define VK_USE_PLATFORM_WIN32_KHR +//#define VK_USE_PLATFORM_XLIB_KHR +#define VK_USE_PLATFORM_XCB_KHR #define USE_AMD_ALLOCATOR #include @@ -64,4 +65,4 @@ static const int MAX_UBO_PARMS = 2; #endif -#endif \ No newline at end of file +#endif diff --git a/neo/renderer/Vulkan/vma.h b/neo/renderer/Vulkan/vma.h index f0138a99..e70e9657 100644 --- a/neo/renderer/Vulkan/vma.h +++ b/neo/renderer/Vulkan/vma.h @@ -766,6 +766,7 @@ remove them if not needed. #include // for assert #include // for min, max #include // for std::mutex +#include #if !defined(_WIN32) #include // for aligned_alloc() diff --git a/neo/swf/SWF_Sprites.h b/neo/swf/SWF_Sprites.h index ba1f652f..6001d4f5 100644 --- a/neo/swf/SWF_Sprites.h +++ b/neo/swf/SWF_Sprites.h @@ -29,6 +29,9 @@ If you have questions concerning this license or the applicable additional terms #ifndef __SWF_SPRITES_H__ #define __SWF_SPRITES_H__ +#undef Bool +#include "rapidjson/document.h" + /* ================================================ What the swf file format calls a "sprite" is known as a "movie clip" in Flash diff --git a/neo/sys/posix/platform_linux.cpp b/neo/sys/posix/platform_linux.cpp index 3837ceac..afcee59e 100644 --- a/neo/sys/posix/platform_linux.cpp +++ b/neo/sys/posix/platform_linux.cpp @@ -49,6 +49,10 @@ static int cmdargc = 0; #include #endif +#ifdef USE_VULKAN +#include +#endif + /* ============== Sys_EXEPath @@ -509,6 +513,61 @@ void Sys_ReLaunch() // DG end } +#ifdef USE_VULKAN +/* Declare the global posixInfo */ +posixInfo info; + +static void createWindow(size_t winWidth, size_t winHeight) +{ + /* establish the connection with DISPLAYNAME as NULL, + * this will leverage the DISPLAY env var */ + int screenp = 0; /* which "screen" to use */ + info.connection = xcb_connect(NULL, &screenp); + + /* Check for errors */ + int xcbErr = xcb_connection_has_error(info.connection); + + if (xcbErr) { + common->Printf("Failed to connect to X server using XCB."); + exit(-1); + } + + /* Setup the window, iterating through screens */ + const struct xcb_setup_t *xcbSetup = NULL; + xcbSetup = xcb_get_setup(info.connection); + + xcb_screen_iterator_t scrIter = xcb_setup_roots_iterator(xcbSetup); + + for (int screen = screenp; screen > 0; --screen) { + xcb_screen_next(&scrIter); + } + + info.screen = scrIter.data; + + /* Now generate the xid used for our window */ + info.window = xcb_generate_id(info.connection); + + /* Register events, creating background pixel */ + uint32_t eventMask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; + uint32_t valueList[] = { info.screen->black_pixel, 0 }; + + /* Create the window, finally */ + xcb_create_window(info.connection, XCB_COPY_FROM_PARENT, info.window, + info.screen->root, 0, 0, winWidth, winHeight, 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, info.screen->root_visual, + eventMask, valueList); + + /* Set some properties, such as the window name, maybe? */ + xcb_change_property(info.connection, XCB_PROP_MODE_REPLACE, + info.window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, + 8, 7, "vkDOOM3"); + + /* map the window to the screen and flush the stream to the server */ + xcb_map_window(info.connection, info.window); + xcb_flush(info.connection); +} +#endif + /* =============== main @@ -525,7 +584,14 @@ int main( int argc, const char** argv ) mcheck( abrt_func ); Sys_Printf( "memory consistency checking enabled\n" ); #endif - + +#ifdef USE_VULKAN + /* Create the window if using Vulkan */ + xcb_generic_event_t *event; + xcb_client_message_event_t *cm; + createWindow(1920, 1080); +#endif + Posix_EarlyInit( ); if( argc > 1 ) @@ -538,9 +604,17 @@ int main( int argc, const char** argv ) } Posix_LateInit( ); + while( 1 ) { +#ifdef USE_VULKAN + /* I'm not 100% sure if intercepting these xcb events interferes with + * SDL's input handling or not, but I suspect that it's necessary + * to pump some event loop. We'll see */ + /*event = xcb_wait_for_event(info.connection); + free(event); */ +#endif common->Frame(); } } diff --git a/neo/sys/posix/posix_public.h b/neo/sys/posix/posix_public.h index c0a9a05e..8fc2d3fc 100644 --- a/neo/sys/posix/posix_public.h +++ b/neo/sys/posix/posix_public.h @@ -31,6 +31,10 @@ If you have questions concerning this license or the applicable additional terms #include +#ifdef USE_VULKAN +#include +#endif + void Posix_QueEvent( sysEventType_t type, int value, int value2, int ptrLength, void* ptr ); const char* Posix_Cwd(); @@ -66,5 +70,19 @@ enum clk_id_t { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_MONOTONIC_RAW }; int clock_gettime( clk_id_t clock, struct timespec* tp ); #endif +#ifdef USE_VULKAN +/* Struct that holds global xcb state for vulkan */ +typedef struct _posixInfo { + xcb_connection_t *connection; + xcb_window_t window; + xcb_screen_t *screen; + xcb_atom_t wmProtocols; + xcb_atom_t wmDeleteWin; +} posixInfo; + +extern posixInfo info; + +#endif + #endif diff --git a/neo/sys/sdl/sdl_glimp.cpp b/neo/sys/sdl/sdl_glimp.cpp index 7c7967d2..0f479f9a 100644 --- a/neo/sys/sdl/sdl_glimp.cpp +++ b/neo/sys/sdl/sdl_glimp.cpp @@ -30,6 +30,7 @@ If you have questions concerning this license or the applicable additional terms */ #include "../../idlib/precompiled.h" +#include // DG: SDL.h somehow needs the following functions, so #undef those silly // "don't use" #defines from Str.h @@ -98,6 +99,10 @@ GLimp_Init */ bool GLimp_Init( glimpParms_t parms ) { + #ifdef USE_VULKAN + return true; + #endif + common->Printf( "Initializing OpenGL subsystem\n" ); GLimp_PreInit(); // DG: make sure SDL is initialized @@ -439,6 +444,10 @@ GLimp_SetScreenParms */ bool GLimp_SetScreenParms( glimpParms_t parms ) { +#ifdef USE_VULKAN + return true; +#endif + #if SDL_VERSION_ATLEAST(2, 0, 0) if( parms.fullScreen > 0 || parms.fullScreen == -2 ) { @@ -506,7 +515,12 @@ GLimp_Shutdown */ void GLimp_Shutdown() { +#ifdef USE_VULKAN + common->Printf( "Shutting down Vulkan subsystem\n" ); + return; +#else common->Printf( "Shutting down OpenGL subsystem\n" ); +#endif #if SDL_VERSION_ATLEAST(2, 0, 0) if( context ) @@ -528,6 +542,7 @@ void GLimp_Shutdown() GLimp_SwapBuffers =================== */ +#ifndef USE_VULKAN void GLimp_SwapBuffers() { #if SDL_VERSION_ATLEAST(2, 0, 0) @@ -536,6 +551,7 @@ void GLimp_SwapBuffers() SDL_GL_SwapBuffers(); #endif } +#endif /* ================= @@ -544,6 +560,7 @@ GLimp_SetGamma */ void GLimp_SetGamma( unsigned short red[256], unsigned short green[256], unsigned short blue[256] ) { +#ifndef USE_VULKAN if( !window ) { common->Warning( "GLimp_SetGamma called without window" ); @@ -556,6 +573,7 @@ void GLimp_SetGamma( unsigned short red[256], unsigned short green[256], unsigne if( SDL_SetGammaRamp( red, green, blue ) ) #endif common->Warning( "Couldn't set gamma ramp: %s", SDL_GetError() ); +#endif } /* From 7145d9b3f1b66c5795edda6abf3af5373e4b2340 Mon Sep 17 00:00:00 2001 From: Eric Womer Date: Sun, 29 Dec 2019 17:05:33 -0500 Subject: [PATCH 2/7] Compiling/Linking/Running, but no rendering, there is audio. glConfig as a temp fix for the surfaces having a width and height of 0 since renderSystem->getHeight()/getWidth() access glConfig.nativeResolutionHeight/Width directly. --- neo/CMakeLists.txt | 18 ++++++++++++++---- neo/idlib/sys/sys_types.h | 4 +++- neo/renderer/Vulkan/Allocator_VK.cpp | 18 +++++++++--------- neo/renderer/Vulkan/RenderBackend_VK.cpp | 12 ++++++------ neo/renderer/Vulkan/RenderProgs_VK.cpp | 7 ++++--- neo/renderer/Vulkan/qvk.h | 1 + neo/renderer/Vulkan/vma.cpp | 8 ++++---- neo/renderer/Vulkan/vma.h | 3 ++- neo/sys/posix/platform_linux.cpp | 6 +++++- neo/sys/posix/posix_public.h | 2 ++ 10 files changed, 50 insertions(+), 29 deletions(-) diff --git a/neo/CMakeLists.txt b/neo/CMakeLists.txt index 7688b35f..9281830b 100644 --- a/neo/CMakeLists.txt +++ b/neo/CMakeLists.txt @@ -328,7 +328,16 @@ if(USE_VULKAN) add_definitions(-DUSE_VULKAN) include_directories($ENV{VULKAN_SDK}/Include) - + + find_package(XCB) + if(NOT XCB_FOUND) + message(FATAL_ERROR "Could not find XCB library!") + else() + message(STATUS ${XCB_LIBRARIES}) + endif() + + include_directories(${XCB_INCLUDE_DIRS}) + if(SPIRV_SHADERC) add_definitions(-DSPIRV_SHADERC) @@ -343,7 +352,7 @@ if(USE_VULKAN) # options required by November 2018 release SET_OPTION(ENABLE_SPVREMAPPER OFF) - SET_OPTION(ENABLE_GLSLANG_BINARIES OFF) + SET_OPTION(ENABLE_GLSLANG_BINARIES ON) SET_OPTION(ENABLE_HLSL OFF) SET_OPTION(ENABLE_OPT ON) SET_OPTION(SPIRV_SKIP_EXECUTABLES ON) @@ -357,7 +366,7 @@ if(USE_VULKAN) set(GLSLANG_DIR ${CMAKE_CURRENT_SOURCE_DIR}/extern/glslang) add_subdirectory(${GLSLANG_DIR}) - include_directories(${GLSLANG_DIR}/glslang) + include_directories(${GLSLANG_DIR}) endif() else() @@ -1618,9 +1627,9 @@ else() set(Vulkan_LIBRARIES ${Vulkan_LIBRARY} + ${XCB_LIBRARIES} glslang SPIRV - xcb ) if(ENABLE_GLSLANG_BINARIES) @@ -1719,6 +1728,7 @@ else() target_link_libraries(RBDoom3BFG idlib + ${Vulkan_LIBRARIES} ${OPENGL_LIBRARIES} pthread ${RT_LIBRARY} diff --git a/neo/idlib/sys/sys_types.h b/neo/idlib/sys/sys_types.h index 31496d94..871f7210 100644 --- a/neo/idlib/sys/sys_types.h +++ b/neo/idlib/sys/sys_types.h @@ -73,12 +73,14 @@ assert_sizeof( uint64, 8 ); #define MAX_UNSIGNED_TYPE( x ) ( ( ( ( 1U << ( ( sizeof( x ) - 1 ) * 8 ) ) - 1 ) << 8 ) | 255U ) #define MIN_UNSIGNED_TYPE( x ) 0 + template< typename _type_ > bool IsSignedType( const _type_ t ) { return _type_( -1 ) < 0; } +#if !defined(USE_AMD_ALLOCATOR) template T Max( T x, T y ) { return ( x > y ) ? x : y; @@ -87,7 +89,7 @@ template T Min( T x, T y ) { return ( x < y ) ? x : y; } - +#endif // USE_AMD_ALLOCATOR class idFile; diff --git a/neo/renderer/Vulkan/Allocator_VK.cpp b/neo/renderer/Vulkan/Allocator_VK.cpp index 7f38bfdf..e5f192b8 100644 --- a/neo/renderer/Vulkan/Allocator_VK.cpp +++ b/neo/renderer/Vulkan/Allocator_VK.cpp @@ -438,7 +438,7 @@ void idVulkanBlock::Free( vulkanAllocation_t& allocation ) if( current == NULL ) { - idLib::Warning( "idVulkanBlock::Free: Tried to free an unknown allocation. %p - %lu", this, allocation.id ); + idLib::Warning( "idVulkanBlock::Free: Tried to free an unknown allocation. %p - %u", this, allocation.id ); return; } @@ -492,21 +492,21 @@ void idVulkanBlock::Print() count++; } - idLib::Printf( "Type Index: %lu\n", memoryTypeIndex ); + idLib::Printf( "Type Index: %u\n", memoryTypeIndex ); idLib::Printf( "Usage: %s\n", memoryUsageStrings[ usage ] ); idLib::Printf( "Count: %d\n", count ); - idLib::Printf( "Size: %llu\n", size ); - idLib::Printf( "Allocated: %llu\n", allocated ); - idLib::Printf( "Next Block: %lu\n", nextBlockId ); + idLib::Printf( "Size: %lu\n", size ); + idLib::Printf( "Allocated: %lu\n", allocated ); + idLib::Printf( "Next Block: %u\n", nextBlockId ); idLib::Printf( "------------------------\n" ); for( chunk_t* current = head; current != NULL; current = current->next ) { idLib::Printf( "{\n" ); - idLib::Printf( "\tId: %lu\n", current->id ); - idLib::Printf( "\tSize: %llu\n", current->size ); - idLib::Printf( "\tOffset: %llu\n", current->offset ); + idLib::Printf( "\tId: %u\n", current->id ); + idLib::Printf( "\tSize: %lu\n", current->size ); + idLib::Printf( "\tOffset: %lu\n", current->offset ); idLib::Printf( "\tType: %s\n", allocationTypeStrings[ current->type ] ); idLib::Printf( "}\n" ); @@ -679,7 +679,7 @@ void idVulkanAllocator::Print() { idLib::Printf( "Device Local MB: %d\n", int( deviceLocalMemoryBytes / 1024 * 1024 ) ); idLib::Printf( "Host Visible MB: %d\n", int( hostVisibleMemoryBytes / 1024 * 1024 ) ); - idLib::Printf( "Buffer Granularity: %llu\n", bufferImageGranularity ); + idLib::Printf( "Buffer Granularity: %lu\n", bufferImageGranularity ); idLib::Printf( "\n" ); for( int i = 0; i < VK_MAX_MEMORY_TYPES; ++i ) diff --git a/neo/renderer/Vulkan/RenderBackend_VK.cpp b/neo/renderer/Vulkan/RenderBackend_VK.cpp index 1b5166af..5117fc9b 100644 --- a/neo/renderer/Vulkan/RenderBackend_VK.cpp +++ b/neo/renderer/Vulkan/RenderBackend_VK.cpp @@ -439,7 +439,7 @@ static void CreateSurface() createInfo.connection = info.connection; createInfo.window = info.window; - ID_VK_CHECK( vkCreateXcbSurfaceKHR( info.inst, &createInfo, NULL, &info.surface ) ); + ID_VK_CHECK( vkCreateXcbSurfaceKHR( vkcontext.instance, &createInfo, NULL, &vkcontext.surface ) ); #endif // _WIN32 @@ -554,22 +554,22 @@ static void SelectPhysicalDevice() switch( gpu.props.vendorID ) { case 0x8086: - idLib::Printf( "Vendor: Intel\n", i ); + idLib::Printf( "Vendor: Intel\n"); glConfig.vendor = VENDOR_INTEL; break; case 0x10DE: - idLib::Printf( "Vendor: NVIDIA\n", i ); + idLib::Printf( "Vendor: NVIDIA\n"); glConfig.vendor = VENDOR_NVIDIA; break; case 0x1002: - idLib::Printf( "Vendor: AMD\n", i ); + idLib::Printf( "Vendor: AMD\n"); glConfig.vendor = VENDOR_AMD; break; default: - idLib::Printf( "Vendor: Unknown (0x%x)\n", i, gpu.props.vendorID ); + idLib::Printf( "Vendor: Unknown (0x%x)\n", gpu.props.vendorID ); } return; @@ -966,7 +966,7 @@ static void CreateRenderTargets() VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT ); } - + idLib::Printf( "renderSystem->GetWidth()/GetHeight() %ix%i\n", renderSystem->GetWidth(), renderSystem->GetHeight() ); idImageOpts depthOptions; depthOptions.format = FMT_DEPTH; depthOptions.width = renderSystem->GetWidth(); diff --git a/neo/renderer/Vulkan/RenderProgs_VK.cpp b/neo/renderer/Vulkan/RenderProgs_VK.cpp index 6b67f403..16fa2649 100644 --- a/neo/renderer/Vulkan/RenderProgs_VK.cpp +++ b/neo/renderer/Vulkan/RenderProgs_VK.cpp @@ -395,9 +395,10 @@ static int CompileGLSLtoSPIRV( const char* filename, const idStr& dataGLSL, cons } #else -#include +#include #include -#include +#include + //#include namespace glslang @@ -581,7 +582,7 @@ static int CompileGLSLtoSPIRV( const char* filename, const idStr& dataGLSL, cons idLib::Printf( "%s\n", shader.getInfoDebugLog() ); } - // All that’s left to do now is to convert the program’s intermediate representation into SpirV: + // All that�s left to do now is to convert the program�s intermediate representation into SpirV: std::vector spirV; spv::SpvBuildLogger logger; glslang::SpvOptions spvOptions; diff --git a/neo/renderer/Vulkan/qvk.h b/neo/renderer/Vulkan/qvk.h index 72048b4a..a24723cf 100644 --- a/neo/renderer/Vulkan/qvk.h +++ b/neo/renderer/Vulkan/qvk.h @@ -33,6 +33,7 @@ If you have questions concerning this license or the applicable additional terms #if defined( USE_VULKAN ) //#define VK_USE_PLATFORM_XLIB_KHR + #define VK_USE_PLATFORM_XCB_KHR #define USE_AMD_ALLOCATOR diff --git a/neo/renderer/Vulkan/vma.cpp b/neo/renderer/Vulkan/vma.cpp index e9294027..3ccab2e2 100644 --- a/neo/renderer/Vulkan/vma.cpp +++ b/neo/renderer/Vulkan/vma.cpp @@ -22,16 +22,16 @@ #pragma warning( disable: 4244 ) // warning C4244: conversion from 'double' to 'float', possible loss of data -template T Max( T x, T y ) +template T VMax( T x, T y ) { return ( x > y ) ? x : y; } -template T Min( T x, T y ) +template T VMin( T x, T y ) { return ( x < y ) ? x : y; } #define VMA_IMPLEMENTATION -#define VMA_MAX( v1, v2 ) Max( (v1), (v2) ) -#define VMA_MIN( v1, v2 ) Min( (v1), (v2) ) +#define VMA_MAX( v1, v2 ) VMax( (v1), (v2) ) +#define VMA_MIN( v1, v2 ) VMin( (v1), (v2) ) #include "vma.h" \ No newline at end of file diff --git a/neo/renderer/Vulkan/vma.h b/neo/renderer/Vulkan/vma.h index 3a63c34c..09c92a2a 100644 --- a/neo/renderer/Vulkan/vma.h +++ b/neo/renderer/Vulkan/vma.h @@ -1956,6 +1956,7 @@ template class VmaList { public: + class const_iterator; class iterator { public: @@ -2031,7 +2032,7 @@ public: } friend class VmaList; - friend class VmaList:: const_iterator; + friend class VmaList::const_iterator; }; class const_iterator diff --git a/neo/sys/posix/platform_linux.cpp b/neo/sys/posix/platform_linux.cpp index 0619ea7a..bb3ae566 100644 --- a/neo/sys/posix/platform_linux.cpp +++ b/neo/sys/posix/platform_linux.cpp @@ -571,6 +571,10 @@ static void createWindow(size_t winWidth, size_t winHeight) /* map the window to the screen and flush the stream to the server */ xcb_map_window(info.connection, info.window); xcb_flush(info.connection); + + glConfig.nativeScreenWidth = winWidth; + glConfig.nativeScreenHeight = winHeight; + } #endif @@ -595,7 +599,7 @@ int main( int argc, const char** argv ) /* Create the window if using Vulkan */ xcb_generic_event_t *event; xcb_client_message_event_t *cm; - createWindow(1920, 1080); + createWindow(1600, 900); #endif Posix_EarlyInit( ); diff --git a/neo/sys/posix/posix_public.h b/neo/sys/posix/posix_public.h index 8fc2d3fc..ee12436f 100644 --- a/neo/sys/posix/posix_public.h +++ b/neo/sys/posix/posix_public.h @@ -35,6 +35,8 @@ If you have questions concerning this license or the applicable additional terms #include #endif +extern glconfig_t glConfig; + void Posix_QueEvent( sysEventType_t type, int value, int value2, int ptrLength, void* ptr ); const char* Posix_Cwd(); From 89387330508e4581f2e8b77c79c1eed9f9f08353 Mon Sep 17 00:00:00 2001 From: Eric Womer Date: Sun, 29 Dec 2019 17:07:51 -0500 Subject: [PATCH 3/7] Added Sascha Willems FindXCB.cmake module for finding the XCB library and headers --- neo/cmake/FindXCB.cmake | 51 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 neo/cmake/FindXCB.cmake diff --git a/neo/cmake/FindXCB.cmake b/neo/cmake/FindXCB.cmake new file mode 100644 index 00000000..89ed904b --- /dev/null +++ b/neo/cmake/FindXCB.cmake @@ -0,0 +1,51 @@ +# - FindXCB +# +# Copyright 2015 Valve Coporation + +find_package(PkgConfig) + +if(NOT XCB_FIND_COMPONENTS) + set(XCB_FIND_COMPONENTS xcb) +endif() + +include(FindPackageHandleStandardArgs) +set(XCB_FOUND true) +set(XCB_INCLUDE_DIRS "") +set(XCB_LIBRARIES "") +foreach(comp ${XCB_FIND_COMPONENTS}) + # component name + string(TOUPPER ${comp} compname) + string(REPLACE "-" "_" compname ${compname}) + # header name + string(REPLACE "xcb-" "" headername xcb/${comp}.h) + # library name + set(libname ${comp}) + + pkg_check_modules(PC_${comp} QUIET ${comp}) + + find_path(${compname}_INCLUDE_DIR NAMES ${headername} + HINTS + ${PC_${comp}_INCLUDEDIR} + ${PC_${comp}_INCLUDE_DIRS} + ) + + find_library(${compname}_LIBRARY NAMES ${libname} + HINTS + ${PC_${comp}_LIBDIR} + ${PC_${comp}_LIBRARY_DIRS} + ) + + find_package_handle_standard_args(${comp} + FOUND_VAR ${comp}_FOUND + REQUIRED_VARS ${compname}_INCLUDE_DIR ${compname}_LIBRARY) + mark_as_advanced(${compname}_INCLUDE_DIR ${compname}_LIBRARY) + + list(APPEND XCB_INCLUDE_DIRS ${${compname}_INCLUDE_DIR}) + list(APPEND XCB_LIBRARIES ${${compname}_LIBRARY}) + + if(NOT ${comp}_FOUND) + set(XCB_FOUND false) + endif() +endforeach() + +list(REMOVE_DUPLICATES XCB_INCLUDE_DIRS) \ No newline at end of file From e9ef21ce5c058bf80d28fc3239cdd5209351799c Mon Sep 17 00:00:00 2001 From: Eric Womer Date: Mon, 30 Dec 2019 15:20:15 -0500 Subject: [PATCH 4/7] SDL2/Vulkan on Linux, still broken for Doom3BFG --- neo/CMakeLists.txt | 46 +- neo/cmake/FindX11_XCB.cmake | 32 ++ neo/cmake/FindXCB.cmake | 51 -- neo/renderer/RenderBackend.h | 6 + neo/renderer/RenderCommon.h | 38 +- neo/renderer/RenderSystem_init.cpp | 16 +- neo/renderer/Vulkan/RenderBackend_VK.cpp | 73 ++- neo/renderer/Vulkan/qvk.h | 7 +- neo/sys/posix/platform_linux.cpp | 12 +- neo/sys/posix/posix_public.h | 3 +- neo/sys/sdl/sdl_events.cpp | 7 +- neo/sys/sdl/sdl_local.h | 5 +- neo/sys/sdl/sdl_vkimp.cpp | 648 +++++++++++++++++++++++ 13 files changed, 842 insertions(+), 102 deletions(-) create mode 100644 neo/cmake/FindX11_XCB.cmake delete mode 100644 neo/cmake/FindXCB.cmake create mode 100644 neo/sys/sdl/sdl_vkimp.cpp diff --git a/neo/CMakeLists.txt b/neo/CMakeLists.txt index 9281830b..522bc5b1 100644 --- a/neo/CMakeLists.txt +++ b/neo/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 2.8) # Eric: These are rookie numbers, you need to bump those numbers up. set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) project(RBDoom3BFG) @@ -86,6 +86,13 @@ if (FORCE_COLOR_OUTPUT) endif () endif () +# Eric: Hard dependency on SDL2 for the Vulkan renderer on Linux +if(UNIX) + if(USE_VULKAN) + SET(SDL2 ON) + endif() +endif() + if(MSVC) #message(STATUS CMAKE_ROOT: ${CMAKE_ROOT}) @@ -318,8 +325,7 @@ if(USE_VULKAN) message( STATUS "Using module to find Vulkan" ) find_package(Vulkan) endif() - - + if(NOT Vulkan_FOUND) message(FATAL_ERROR "Could not find Vulkan library!") else() @@ -329,15 +335,16 @@ if(USE_VULKAN) add_definitions(-DUSE_VULKAN) include_directories($ENV{VULKAN_SDK}/Include) - find_package(XCB) - if(NOT XCB_FOUND) - message(FATAL_ERROR "Could not find XCB library!") - else() - message(STATUS ${XCB_LIBRARIES}) + # Eric: For use with SDL2/Vulkan + if(UNIX) + find_package(X11_XCB) + if(X11_XCB_FOUND) + add_definitions(-DHAVE_X11_XCB) + list(APPEND SUBSYSTEMS [X11]) + include_directories(${X11_XCB_INCLUDE_DIRS}) + endif() endif() - include_directories(${XCB_INCLUDE_DIRS}) - if(SPIRV_SHADERC) add_definitions(-DSPIRV_SHADERC) @@ -548,7 +555,6 @@ file(GLOB MINIZIP_INCLUDES libs/zlib/minizip/*.h) file(GLOB MINIZIP_SOURCES libs/zlib/minizip/*.c libs/zlib/minizip/*.cpp) - set(FREETYPE_SOURCES libs/freetype/src/autofit/autofit.c libs/freetype/src/bdf/bdf.c @@ -1004,6 +1010,16 @@ file(GLOB COMMON_SOURCES sys/common/*.cpp) file(GLOB SDL_INCLUDES sys/sdl/*.h) file(GLOB SDL_SOURCES sys/sdl/*.cpp) +# Eric: Utilize either the Vulkan or GL implementation of SDL +if(UNIX) + if(USE_VULKAN) + get_filename_component(sdl_glimp_cpp_full_path ${CMAKE_CURRENT_SOURCE_DIR}/sys/sdl/sdl_glimp.cpp ABSOLUTE) + list(REMOVE_ITEM SDL_SOURCES "${sdl_glimp_cpp_full_path}") + else() + get_filename_component(sdl_vkimp_cpp_full_path ${CMAKE_CURRENT_SOURCE_DIR}/sys/sdl/sdl_vkimp.cpp ABSOLUTE) + list(REMOVE_ITEM SDL_SOURCES "${sdl_vkimp_cpp_full_path}") + endif() +endif() source_group("aas" FILES ${AAS_INCLUDES}) source_group("aas" FILES ${AAS_SOURCES}) @@ -1627,11 +1643,11 @@ else() set(Vulkan_LIBRARIES ${Vulkan_LIBRARY} - ${XCB_LIBRARIES} + ${X11_XCB_LIBRARIES} glslang SPIRV ) - + if(ENABLE_GLSLANG_BINARIES) list(APPEND Vulkan_LIBRARIES glslang-default-resource-limits) endif() @@ -1710,7 +1726,7 @@ else() # make sure this is run after creating idlib add_dependencies(precomp_header_rbdoom3bfg idlib) endif() - + add_executable(RBDoom3BFG WIN32 ${RBDOOM3_SOURCES}) if (USE_PRECOMPILED_HEADERS) @@ -1739,7 +1755,7 @@ else() ${PNG_LIBRARY} ${JPEG_LIBRARY} ${GLEW_LIBRARY} - ${CMAKE_DL_LIBS} + ${CMAKE_DL_LIBS} ) endif() diff --git a/neo/cmake/FindX11_XCB.cmake b/neo/cmake/FindX11_XCB.cmake new file mode 100644 index 00000000..956bf89d --- /dev/null +++ b/neo/cmake/FindX11_XCB.cmake @@ -0,0 +1,32 @@ +# - Try to find libX11-xcb +# Once done this will define +# +# X11_XCB_FOUND - system has libX11-xcb +# X11_XCB_LIBRARIES - Link these to use libX11-xcb +# X11_XCB_INCLUDE_DIR - the libX11-xcb include dir +# X11_XCB_DEFINITIONS - compiler switches required for using libX11-xcb + +# Copyright (c) 2011 Fredrik Höglund +# Copyright (c) 2008 Helio Chissini de Castro, +# Copyright (c) 2007 Matthias Kretz, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +IF (NOT WIN32) + # use pkg-config to get the directories and then use these values + # in the FIND_PATH() and FIND_LIBRARY() calls + FIND_PACKAGE(PkgConfig) + PKG_CHECK_MODULES(PKG_X11_XCB QUIET x11-xcb) + + SET(X11_XCB_DEFINITIONS ${PKG_X11_XCB_CFLAGS}) + + FIND_PATH(X11_XCB_INCLUDE_DIR NAMES X11/Xlib-xcb.h HINTS ${PKG_X11_XCB_INCLUDE_DIRS}) + FIND_LIBRARY(X11_XCB_LIBRARIES NAMES X11-xcb HINTS ${PKG_X11_XCB_LIBRARY_DIRS}) + + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(X11_XCB DEFAULT_MSG X11_XCB_LIBRARIES X11_XCB_INCLUDE_DIR) + + MARK_AS_ADVANCED(X11_XCB_INCLUDE_DIR X11_XCB_LIBRARIES) +ENDIF (NOT WIN32) + diff --git a/neo/cmake/FindXCB.cmake b/neo/cmake/FindXCB.cmake deleted file mode 100644 index 89ed904b..00000000 --- a/neo/cmake/FindXCB.cmake +++ /dev/null @@ -1,51 +0,0 @@ -# - FindXCB -# -# Copyright 2015 Valve Coporation - -find_package(PkgConfig) - -if(NOT XCB_FIND_COMPONENTS) - set(XCB_FIND_COMPONENTS xcb) -endif() - -include(FindPackageHandleStandardArgs) -set(XCB_FOUND true) -set(XCB_INCLUDE_DIRS "") -set(XCB_LIBRARIES "") -foreach(comp ${XCB_FIND_COMPONENTS}) - # component name - string(TOUPPER ${comp} compname) - string(REPLACE "-" "_" compname ${compname}) - # header name - string(REPLACE "xcb-" "" headername xcb/${comp}.h) - # library name - set(libname ${comp}) - - pkg_check_modules(PC_${comp} QUIET ${comp}) - - find_path(${compname}_INCLUDE_DIR NAMES ${headername} - HINTS - ${PC_${comp}_INCLUDEDIR} - ${PC_${comp}_INCLUDE_DIRS} - ) - - find_library(${compname}_LIBRARY NAMES ${libname} - HINTS - ${PC_${comp}_LIBDIR} - ${PC_${comp}_LIBRARY_DIRS} - ) - - find_package_handle_standard_args(${comp} - FOUND_VAR ${comp}_FOUND - REQUIRED_VARS ${compname}_INCLUDE_DIR ${compname}_LIBRARY) - mark_as_advanced(${compname}_INCLUDE_DIR ${compname}_LIBRARY) - - list(APPEND XCB_INCLUDE_DIRS ${${compname}_INCLUDE_DIR}) - list(APPEND XCB_LIBRARIES ${${compname}_LIBRARY}) - - if(NOT ${comp}_FOUND) - set(XCB_FOUND false) - endif() -endforeach() - -list(REMOVE_DUPLICATES XCB_INCLUDE_DIRS) \ No newline at end of file diff --git a/neo/renderer/RenderBackend.h b/neo/renderer/RenderBackend.h index 154b913a..6a0148c9 100644 --- a/neo/renderer/RenderBackend.h +++ b/neo/renderer/RenderBackend.h @@ -131,6 +131,8 @@ void RB_SetVertexColorParms( stageVertexColor_t svc ); //bool CreateGameWindow( gfxImpParms_t parms ); #if defined( USE_VULKAN ) +#include +#include struct gpuInfo_t { @@ -146,6 +148,10 @@ struct gpuInfo_t struct vulkanContext_t { + // Eric: If on linux, use this to pass SDL_Window pointer to the SDL_Vulkan_* methods not in sdl_vkimp.cpp file. +#if defined(__linux__) + SDL_Window* vkwindow = nullptr; +#endif uint64 frameCounter; uint32 frameParity; diff --git a/neo/renderer/RenderCommon.h b/neo/renderer/RenderCommon.h index 667d9424..9391c175 100644 --- a/neo/renderer/RenderCommon.h +++ b/neo/renderer/RenderCommon.h @@ -1187,6 +1187,42 @@ struct glimpParms_t int multiSamples; }; +// Eric: If on Linux using Vulkan use the sdl_vkimp.cpp methods +#if defined(__linux__) && defined(USE_VULKAN) +#include + +#define CLAMP(x, lo, hi) ((x) < (lo) ? (lo) : (x) > (hi) ? (hi) : (x)) +// Helper function for using SDL2 and Vulkan on Linux. +std::vector get_required_extensions(const std::vector& instanceExtensions, bool enableValidationLayers); + +const std::vector sdlInstanceExtensions = {}; + +extern vulkanContext_t vkcontext; + +// DG: R_GetModeListForDisplay is called before GLimp_Init(), but SDL needs SDL_Init() first. +// So add PreInit for platforms that need it, others can just stub it. +void VKimp_PreInit(); + +// If the desired mode can't be set satisfactorily, false will be returned. +// If succesful, sets glConfig.nativeScreenWidth, glConfig.nativeScreenHeight, and glConfig.pixelAspect +// The renderer will then reset the glimpParms to "safe mode" of 640x480 +// fullscreen and try again. If that also fails, the error will be fatal. +bool VKimp_Init( glimpParms_t parms ); + +// will set up gl up with the new parms +bool VKimp_SetScreenParms( glimpParms_t parms ); + +// Destroys the rendering context, closes the window, resets the resolution, +// and resets the gamma ramps. +void VKimp_Shutdown(); + +// Sets the hardware gamma ramps for gamma and brightness adjustment. +// These are now taken as 16 bit values, so we can take full advantage +// of dacs with >8 bits of precision +void VKimp_SetGamma( unsigned short red[256], + unsigned short green[256], + unsigned short blue[256] ); +#else // DG: R_GetModeListForDisplay is called before GLimp_Init(), but SDL needs SDL_Init() first. // So add PreInit for platforms that need it, others can just stub it. void GLimp_PreInit(); @@ -1211,7 +1247,7 @@ void GLimp_SetGamma( unsigned short red[256], unsigned short green[256], unsigned short blue[256] ); - +#endif /* ============================================================ diff --git a/neo/renderer/RenderSystem_init.cpp b/neo/renderer/RenderSystem_init.cpp index 9da9d341..e0d44d40 100644 --- a/neo/renderer/RenderSystem_init.cpp +++ b/neo/renderer/RenderSystem_init.cpp @@ -351,6 +351,7 @@ void R_SetNewMode( const bool fullInit ) r_fullscreen.SetInteger( 1 ); R_GetModeListForDisplay( r_fullscreen.GetInteger() - 1, modeList ); } + if( modeList.Num() < 1 ) { idLib::Printf( "Going to safe mode because mode list failed." ); @@ -412,7 +413,11 @@ void R_SetNewMode( const bool fullInit ) if( fullInit ) { // create the context as well as setting up the window - if( GLimp_Init( parms ) ) +#if defined(__linux__) && defined(USE_VULKAN) + if( VKimp_Init( parms ) ) +#else + if( GLimp_Init( parms ) ) +#endif { // it worked @@ -425,7 +430,11 @@ void R_SetNewMode( const bool fullInit ) else { // just rebuild the window +#if defined(__linux__) && defined(USE_VULKAN) + if(VKimp_SetScreenParms( parms )) +#else if( GLimp_SetScreenParms( parms ) ) +#endif { // it worked @@ -1699,8 +1708,11 @@ void R_SetColorMappings() int inf = idMath::Ftoi( 0xffff * pow( j / 255.0f, invg ) + 0.5f ); tr.gammaTable[i] = idMath::ClampInt( 0, 0xFFFF, inf ); } - +#if defined(__linux__) && defined(USE_VULKAN) + VKimp_SetGamma( tr.gammaTable, tr.gammaTable, tr.gammaTable); +#else GLimp_SetGamma( tr.gammaTable, tr.gammaTable, tr.gammaTable ); +#endif } /* diff --git a/neo/renderer/Vulkan/RenderBackend_VK.cpp b/neo/renderer/Vulkan/RenderBackend_VK.cpp index 5117fc9b..a61b345c 100644 --- a/neo/renderer/Vulkan/RenderBackend_VK.cpp +++ b/neo/renderer/Vulkan/RenderBackend_VK.cpp @@ -31,7 +31,7 @@ If you have questions concerning this license or the applicable additional terms #pragma hdrstop #include "precompiled.h" -#ifdef __linux__ +#if 0 // defined(__linux__) #include "../../sys/posix/posix_public.h" #endif @@ -51,14 +51,14 @@ idCVar r_syncEveryFrame( "r_syncEveryFrame", "1", CVAR_BOOL, "Don't let the GPU idCVar r_vkEnableValidationLayers( "r_vkEnableValidationLayers", "0", CVAR_BOOL | CVAR_INIT, "" ); -vulkanContext_t vkcontext; - +#if defined(_WIN32) static const int g_numInstanceExtensions = 2; static const char* g_instanceExtensions[ g_numInstanceExtensions ] = { VK_KHR_SURFACE_EXTENSION_NAME, - VK_KHR_XCB_SURFACE_EXTENSION_NAME + VK_KHR_WIN32_SURFACE_EXTENSION_NAME }; +#endif static const int g_numDebugInstanceExtensions = 1; static const char* g_debugInstanceExtensions[ g_numDebugInstanceExtensions ] = @@ -234,6 +234,7 @@ static void ValidateValidationLayers() } } } + /* ============= CreateVulkanInstance @@ -253,16 +254,17 @@ static void CreateVulkanInstance() createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.pApplicationInfo = &appInfo; - const bool enableLayers = r_vkEnableValidationLayers.GetBool(); + const bool enableLayers = true; // r_vkEnableValidationLayers.GetBool(); EW: Testing vkcontext.instanceExtensions.Clear(); vkcontext.deviceExtensions.Clear(); vkcontext.validationLayers.Clear(); - +#if defined(_WIN32) for( int i = 0; i < g_numInstanceExtensions; ++i ) { vkcontext.instanceExtensions.Append( g_instanceExtensions[ i ] ); } +#endif for( int i = 0; i < g_numDeviceExtensions; ++i ) { @@ -283,9 +285,15 @@ static void CreateVulkanInstance() ValidateValidationLayers(); } - +#if defined(__linux__) + auto extensions = get_required_extensions(sdlInstanceExtensions, enableLayers); + createInfo.enabledExtensionCount = static_cast(extensions.size()); + createInfo.ppEnabledExtensionNames = extensions.data(); +#else createInfo.enabledExtensionCount = vkcontext.instanceExtensions.Num(); createInfo.ppEnabledExtensionNames = vkcontext.instanceExtensions.Ptr(); +#endif + createInfo.enabledLayerCount = vkcontext.validationLayers.Num(); createInfo.ppEnabledLayerNames = vkcontext.validationLayers.Ptr(); @@ -337,7 +345,8 @@ static void EnumeratePhysicalDevices() vkGetPhysicalDeviceQueueFamilyProperties( gpu.device, &numQueues, gpu.queueFamilyProps.Ptr() ); ID_VK_VALIDATE( numQueues > 0, "vkGetPhysicalDeviceQueueFamilyProperties returned zero queues." ); } - + // Eric: Bypass this since on linux we use SDL_Vulkan_GetInstanceExtensions to query for extensions. +#if defined(__linux__) // grab available Vulkan extensions { idLib::Printf("Getting available vulkan extensions...\n"); @@ -348,14 +357,14 @@ static void EnumeratePhysicalDevices() gpu.extensionProps.SetNum( numExtension ); ID_VK_CHECK( vkEnumerateDeviceExtensionProperties( gpu.device, NULL, &numExtension, gpu.extensionProps.Ptr() ) ); ID_VK_VALIDATE( numExtension > 0, "vkEnumerateDeviceExtensionProperties returned zero extensions." ); - #if 0 for( uint32 j = 0; j < numExtension; j++ ) { idLib::Printf( "Found Vulkan Extension '%s' on device %d\n", gpu.extensionProps[j].extensionName, i ); } -#endif +#endif // 0 } +#endif // __linux__ // grab surface specific information ID_VK_CHECK( vkGetPhysicalDeviceSurfaceCapabilitiesKHR( gpu.device, vkcontext.surface, &gpu.surfaceCaps ) ); @@ -431,6 +440,11 @@ static void CreateSurface() ID_VK_CHECK( vkCreateWaylandSurfaceKHR( info.inst, &createInfo, NULL, &info.surface ) ); +#else +#if defined(__linux__) + if(!SDL_Vulkan_CreateSurface(vkcontext.vkwindow, vkcontext.instance, &vkcontext.surface)) { + idLib::FatalError("Error while creating Vulkan surface: %s", SDL_GetError()); + } #else VkXcbSurfaceCreateInfoKHR createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; @@ -440,12 +454,12 @@ static void CreateSurface() createInfo.window = info.window; ID_VK_CHECK( vkCreateXcbSurfaceKHR( vkcontext.instance, &createInfo, NULL, &vkcontext.surface ) ); +#endif // __linux__ + #endif // _WIN32 - } - /* ============= CheckPhysicalDeviceExtensionSupport @@ -554,22 +568,22 @@ static void SelectPhysicalDevice() switch( gpu.props.vendorID ) { case 0x8086: - idLib::Printf( "Vendor: Intel\n"); + idLib::Printf( "Device[%i] : Vendor: Intel \n", i); glConfig.vendor = VENDOR_INTEL; break; case 0x10DE: - idLib::Printf( "Vendor: NVIDIA\n"); + idLib::Printf( "Device[%i] : Vendor: NVIDIA\n", i); glConfig.vendor = VENDOR_NVIDIA; break; case 0x1002: - idLib::Printf( "Vendor: AMD\n"); + idLib::Printf( "Device[%i] : Vendor: AMD\n", i); glConfig.vendor = VENDOR_AMD; break; default: - idLib::Printf( "Vendor: Unknown (0x%x)\n", gpu.props.vendorID ); + idLib::Printf( "Device[%i] : Vendor: Unknown (0x%x)\n", i, gpu.props.vendorID ); } return; @@ -710,14 +724,20 @@ static VkExtent2D ChooseSurfaceExtent( VkSurfaceCapabilitiesKHR& caps ) { VkExtent2D extent; - if( caps.currentExtent.width == -1 ) + int width; + int height; + SDL_Vulkan_GetDrawableSize(vkcontext.vkwindow, &width, &height); + width = CLAMP(width, caps.minImageExtent.width, caps.maxImageExtent.width); + height = CLAMP(height, caps.minImageExtent.height, caps.maxImageExtent.height); + + if( caps.currentExtent.width == -1 ) { - extent.width = glConfig.nativeScreenWidth; - extent.height = glConfig.nativeScreenHeight; + extent.width = width; + extent.height = height; } else { - extent = caps.currentExtent; + extent = caps.currentExtent; } return extent; @@ -966,7 +986,7 @@ static void CreateRenderTargets() VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT ); } - idLib::Printf( "renderSystem->GetWidth()/GetHeight() %ix%i\n", renderSystem->GetWidth(), renderSystem->GetHeight() ); + idImageOpts depthOptions; depthOptions.format = FMT_DEPTH; depthOptions.width = renderSystem->GetWidth(); @@ -1275,8 +1295,13 @@ void idRenderBackend::Init() idLib::FatalError( "R_InitVulkan called while active" ); } + // DG: make sure SDL has setup video so getting supported modes in R_SetNewMode() works - GLimp_PreInit(); +#if defined(__linux__) && defined(USE_VULKAN) + VKimp_PreInit(); +#else + GLimp_PreInit(); +#endif // DG end R_SetNewMode( true ); @@ -1447,7 +1472,11 @@ void idRenderBackend::Shutdown() ClearContext(); // destroy main window +#if defined(__linux__) && defined(USE_VULKAN) + VKimp_Shutdown(); +#else GLimp_Shutdown(); +#endif } diff --git a/neo/renderer/Vulkan/qvk.h b/neo/renderer/Vulkan/qvk.h index a24723cf..3f26411d 100644 --- a/neo/renderer/Vulkan/qvk.h +++ b/neo/renderer/Vulkan/qvk.h @@ -32,13 +32,18 @@ If you have questions concerning this license or the applicable additional terms #if defined( USE_VULKAN ) -//#define VK_USE_PLATFORM_XLIB_KHR +// #define VK_USE_PLATFORM_XLIB_KHR #define VK_USE_PLATFORM_XCB_KHR #define USE_AMD_ALLOCATOR #include +#if defined(VK_USE_PLATFORM_XCB_KHR) +#include +#include +#endif + #if defined( USE_AMD_ALLOCATOR ) #include "vma.h" #endif diff --git a/neo/sys/posix/platform_linux.cpp b/neo/sys/posix/platform_linux.cpp index bb3ae566..62ec5961 100644 --- a/neo/sys/posix/platform_linux.cpp +++ b/neo/sys/posix/platform_linux.cpp @@ -49,7 +49,7 @@ static int cmdargc = 0; #include #endif -#ifdef USE_VULKAN +#if 0 // defined(USE_VULKAN) #include #endif @@ -519,7 +519,7 @@ void Sys_ReLaunch() // DG end } -#ifdef USE_VULKAN +#if 0 //defined(USE_VULKAN) /* Declare the global posixInfo */ posixInfo info; @@ -566,7 +566,7 @@ static void createWindow(size_t winWidth, size_t winHeight) /* Set some properties, such as the window name, maybe? */ xcb_change_property(info.connection, XCB_PROP_MODE_REPLACE, info.window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, - 8, 7, "vkDOOM3"); + 8, 7, "vkRBDoom3BFG"); /* map the window to the screen and flush the stream to the server */ xcb_map_window(info.connection, info.window); @@ -595,11 +595,11 @@ int main( int argc, const char** argv ) Sys_Printf( "memory consistency checking enabled\n" ); #endif -#ifdef USE_VULKAN +#if 0 // defined(USE_VULKAN) /* Create the window if using Vulkan */ xcb_generic_event_t *event; xcb_client_message_event_t *cm; - createWindow(1600, 900); + createWindow(1280, 720); #endif Posix_EarlyInit( ); @@ -618,7 +618,7 @@ int main( int argc, const char** argv ) while( 1 ) { -#ifdef USE_VULKAN +#if 0 //defined(USE_VULKAN) /* I'm not 100% sure if intercepting these xcb events interferes with * SDL's input handling or not, but I suspect that it's necessary * to pump some event loop. We'll see */ diff --git a/neo/sys/posix/posix_public.h b/neo/sys/posix/posix_public.h index ee12436f..f8a86048 100644 --- a/neo/sys/posix/posix_public.h +++ b/neo/sys/posix/posix_public.h @@ -72,7 +72,8 @@ enum clk_id_t { CLOCK_REALTIME, CLOCK_MONOTONIC, CLOCK_MONOTONIC_RAW }; int clock_gettime( clk_id_t clock, struct timespec* tp ); #endif -#ifdef USE_VULKAN +// Eric: Not used on Linux since using SDL2 +#if 0 //defined(USE_VULKAN) /* Struct that holds global xcb state for vulkan */ typedef struct _posixInfo { xcb_connection_t *connection; diff --git a/neo/sys/sdl/sdl_events.cpp b/neo/sys/sdl/sdl_events.cpp index 3d2b70a2..486167b4 100644 --- a/neo/sys/sdl/sdl_events.cpp +++ b/neo/sys/sdl/sdl_events.cpp @@ -852,8 +852,11 @@ void Sys_GrabMouseCursor( bool grabIt ) { flags = GRAB_SETSTATE; } - - GLimp_GrabInput( flags ); +#if defined(__linux__) && defined(USE_VULKAN) + VKimp_GrabInput( flags ); +#else + GLimp_GrabInput( flags ); +#endif } /* diff --git a/neo/sys/sdl/sdl_local.h b/neo/sys/sdl/sdl_local.h index b6b814e4..47bac611 100644 --- a/neo/sys/sdl/sdl_local.h +++ b/neo/sys/sdl/sdl_local.h @@ -35,8 +35,11 @@ const int GRAB_REENABLE = ( 1 << 1 ); const int GRAB_HIDECURSOR = ( 1 << 2 ); const int GRAB_SETSTATE = ( 1 << 3 ); +#if defined(__linux__) && defined(USE_VULKAN) +void VKimp_GrabInput( int flags); +#else void GLimp_GrabInput( int flags ); - +#endif char* Sys_ConsoleInput(); #endif diff --git a/neo/sys/sdl/sdl_vkimp.cpp b/neo/sys/sdl/sdl_vkimp.cpp new file mode 100644 index 00000000..9391a640 --- /dev/null +++ b/neo/sys/sdl/sdl_vkimp.cpp @@ -0,0 +1,648 @@ +/* +=========================================================================== + +Doom 3 GPL Source Code +Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. +Copyright (C) 2012 dhewg (dhewm3) +Copyright (C) 2012-2014 Robert Beckebans +Copyright (C) 2013 Daniel Gibson + +This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code"). + +Doom 3 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 3 of the License, or +(at your option) any later version. + +Doom 3 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 Doom 3 Source Code. If not, see . + +In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below. + +If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. + +=========================================================================== +*/ + +#include "../../idlib/precompiled.h" + +// DG: SDL.h somehow needs the following functions, so #undef those silly +// "don't use" #defines from Str.h +#undef strncmp +#undef strcasecmp +#undef vsnprintf +// DG end + +#include +#include +#include +#include + +#include "renderer/RenderCommon.h" +#include "sdl_local.h" + +idCVar in_nograb( "in_nograb", "0", CVAR_SYSTEM | CVAR_NOCHEAT, "prevents input grabbing" ); + +// RB: FIXME this shit. We need the OpenGL alpha channel for advanced rendering effects +idCVar r_waylandcompat( "r_waylandcompat", "0", CVAR_SYSTEM | CVAR_NOCHEAT | CVAR_ARCHIVE, "wayland compatible framebuffer" ); + +// RB: only relevant if using SDL 2.0 +#if defined(__APPLE__) + // only core profile is supported on OS X + idCVar r_useOpenGL32( "r_useOpenGL32", "2", CVAR_INTEGER, "0 = OpenGL 3.x, 1 = OpenGL 3.2 compatibility profile, 2 = OpenGL 3.2 core profile", 0, 2 ); +#elif defined(__linux__) + // Linux open source drivers suck + idCVar r_useOpenGL32( "r_useOpenGL32", "0", CVAR_INTEGER, "0 = OpenGL 3.x, 1 = OpenGL 3.2 compatibility profile, 2 = OpenGL 3.2 core profile", 0, 2 ); +#else + idCVar r_useOpenGL32( "r_useOpenGL32", "1", CVAR_INTEGER, "0 = OpenGL 3.x, 1 = OpenGL 3.2 compatibility profile, 2 = OpenGL 3.2 core profile", 0, 2 ); +#endif +// RB end + +static bool grabbed = false; + +vulkanContext_t vkcontext; // Eric: I added this to pass SDL_Window* window to the SDL_Vulkan_* methods that are used else were. + +static SDL_Window* window = nullptr; + +// Eric: Integrate this into RBDoom3BFG's source code ecosystem. +// Helper function for using SDL2 and Vulkan on Linux. +std::vector get_required_extensions(const std::vector& instanceExtensions, bool enableValidationLayers) +{ + uint32_t sdlCount = 0; + std::vector sdlInstanceExtensions; + + SDL_Vulkan_GetInstanceExtensions(nullptr, &sdlCount, nullptr); + sdlInstanceExtensions.resize(sdlCount); + SDL_Vulkan_GetInstanceExtensions(nullptr, &sdlCount, sdlInstanceExtensions.data()); + + if (enableValidationLayers) { + idLib::Printf("\nNumber of availiable instance extensions\t%i\n", sdlCount); + idLib::Printf( "Available Extension List: \n"); + for (auto ext : sdlInstanceExtensions) { + idLib::Printf( "\t%s\n", ext); + } + } + + if (enableValidationLayers) { + sdlInstanceExtensions.push_back("VK_EXT_debug_report"); + sdlInstanceExtensions.push_back("VK_EXT_debug_utils"); + + idLib::Printf("Number of active instance extensions\t%zu\n",sdlInstanceExtensions.size()); + idLib::Printf( "Active Extension List: \n"); + for (auto const& ext : sdlInstanceExtensions) { + idLib::Printf("\t%s\n",ext); + } + } + + return sdlInstanceExtensions; +} + +/* +=================== +VKimp_PreInit + + R_GetModeListForDisplay is called before VKimp_Init(), but SDL needs SDL_Init() first. + So do that in VKimp_PreInit() + Calling that function more than once doesn't make a difference +=================== +*/ +void VKimp_PreInit() // DG: added this function for SDL compatibility +{ + if( !SDL_WasInit( SDL_INIT_VIDEO ) ) + { + if( SDL_Init( SDL_INIT_VIDEO ) ) + { + common->Error( "Error while initializing SDL: %s", SDL_GetError() ); + } + } +} + + +/* Eric: Is the majority of this function not needed since switching from GL to Vulkan? +=================== +VKimp_Init +=================== +*/ +bool VKimp_Init( glimpParms_t parms ) +{ + + common->Printf( "Initializing Vulkan subsystem\n" ); + + VKimp_PreInit(); // DG: make sure SDL is initialized + + // DG: make window resizable + Uint32 flags = SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE; + // DG end + + if( parms.fullScreen ) + { + flags |= SDL_WINDOW_FULLSCREEN; + } + + int colorbits = 24; + int depthbits = 24; + int stencilbits = 8; + + for( int i = 0; i < 16; i++ ) + { + // 0 - default + // 1 - minus colorbits + // 2 - minus depthbits + // 3 - minus stencil + if( ( i % 4 ) == 0 && i ) + { + // one pass, reduce + switch( i / 4 ) + { + case 2 : + if( colorbits == 24 ) + { + colorbits = 16; + } + break; + case 1 : + if( depthbits == 24 ) + { + depthbits = 16; + } + else if( depthbits == 16 ) + { + depthbits = 8; + } + case 3 : + if( stencilbits == 24 ) + { + stencilbits = 16; + } + else if( stencilbits == 16 ) + { + stencilbits = 8; + } + } + } + + int tcolorbits = colorbits; + int tdepthbits = depthbits; + int tstencilbits = stencilbits; + + if( ( i % 4 ) == 3 ) + { + // reduce colorbits + if( tcolorbits == 24 ) + { + tcolorbits = 16; + } + } + + if( ( i % 4 ) == 2 ) + { + // reduce depthbits + if( tdepthbits == 24 ) + { + tdepthbits = 16; + } + else if( tdepthbits == 16 ) + { + tdepthbits = 8; + } + } + + if( ( i % 4 ) == 1 ) + { + // reduce stencilbits + if( tstencilbits == 24 ) + { + tstencilbits = 16; + } + else if( tstencilbits == 16 ) + { + tstencilbits = 8; + } + else + { + tstencilbits = 0; + } + } + + int channelcolorbits = 4; + if( tcolorbits == 24 ) + { + channelcolorbits = 8; + } + + // DG: set display num for fullscreen + int windowPos = SDL_WINDOWPOS_UNDEFINED; + if( parms.fullScreen > 0 ) + { + if( parms.fullScreen > SDL_GetNumVideoDisplays() ) + { + common->Warning( "Couldn't set display to num %i because we only have %i displays", + parms.fullScreen, SDL_GetNumVideoDisplays() ); + } + else + { + // -1 because SDL starts counting displays at 0, while parms.fullScreen starts at 1 + windowPos = SDL_WINDOWPOS_UNDEFINED_DISPLAY( ( parms.fullScreen - 1 ) ); + } + } + // TODO: if parms.fullScreen == -1 there should be a borderless window spanning multiple displays + /* + * NOTE that this implicitly handles parms.fullScreen == -2 (from r_fullscreen -2) meaning + * "do fullscreen, but I don't care on what monitor", at least on my box it's the monitor with + * the mouse cursor. + */ + + window = SDL_CreateWindow( GAME_NAME, + windowPos, + windowPos, + parms.width, parms.height, flags ); + // DG end + + if( !window ) + { + common->DPrintf( "Couldn't set GL mode %d/%d/%d: %s", + channelcolorbits, tdepthbits, tstencilbits, SDL_GetError() ); + continue; + } + vkcontext.vkwindow = window; + // RB begin + SDL_GetWindowSize( window, &glConfig.nativeScreenWidth, &glConfig.nativeScreenHeight ); + // RB end + + glConfig.isFullscreen = ( SDL_GetWindowFlags( window ) & SDL_WINDOW_FULLSCREEN ) == SDL_WINDOW_FULLSCREEN; + + common->Printf( "Using %d color bits, %d depth, %d stencil display\n", + channelcolorbits, tdepthbits, tstencilbits ); + + glConfig.colorBits = tcolorbits; + glConfig.depthBits = tdepthbits; + glConfig.stencilBits = tstencilbits; + + // RB begin + glConfig.displayFrequency = 60; + glConfig.isStereoPixelFormat = parms.stereo; + glConfig.multisamples = parms.multiSamples; + + glConfig.pixelAspect = 1.0f; // FIXME: some monitor modes may be distorted + // should side-by-side stereo modes be consider aspect 0.5? + + // RB end + + break; + } + + if( !window ) + { + common->Printf( "No usable GL mode found: %s", SDL_GetError() ); + return false; + } + +#ifdef __APPLE__ + glewExperimental = GL_TRUE; +#endif + + // DG: disable cursor, we have two cursors in menu (because mouse isn't grabbed in menu) + SDL_ShowCursor( SDL_DISABLE ); + // DG end + + return true; +} + +/* +=================== + Helper functions for VKimp_SetScreenParms() +=================== +*/ +static int ScreenParmsHandleDisplayIndex( glimpParms_t parms ) +{ + int displayIdx; + if( parms.fullScreen > 0 ) + { + displayIdx = parms.fullScreen - 1; // first display for SDL is 0, in parms it's 1 + } + else // -2 == use current display + { + displayIdx = SDL_GetWindowDisplayIndex( window ); + if( displayIdx < 0 ) // for some reason the display for the window couldn't be detected + { + displayIdx = 0; + } + } + + if( parms.fullScreen > SDL_GetNumVideoDisplays() ) + { + common->Warning( "Can't set fullscreen mode to display number %i, because SDL2 only knows about %i displays!", + parms.fullScreen, SDL_GetNumVideoDisplays() ); + return -1; + } + + if( parms.fullScreen != glConfig.isFullscreen ) + { + // we have to switch to another display + if( glConfig.isFullscreen ) + { + // if we're already in fullscreen mode but want to switch to another monitor + // we have to go to windowed mode first to move the window.. SDL-oddity. + SDL_SetWindowFullscreen( window, SDL_FALSE ); + } + // select display ; SDL_WINDOWPOS_UNDEFINED_DISPLAY() doesn't work. + int x = SDL_WINDOWPOS_CENTERED_DISPLAY( displayIdx ); + // move window to the center of selected display + SDL_SetWindowPosition( window, x, x ); + } + return displayIdx; +} + +static bool SetScreenParmsFullscreen( glimpParms_t parms ) +{ + SDL_DisplayMode m = {0}; + int displayIdx = ScreenParmsHandleDisplayIndex( parms ); + if( displayIdx < 0 ) + { + return false; + } + + // get current mode of display the window should be full-screened on + SDL_GetCurrentDisplayMode( displayIdx, &m ); + + // change settings in that display mode according to parms + // FIXME: check if refreshrate, width and height are supported? + // m.refresh_rate = parms.displayHz; + m.w = parms.width; + m.h = parms.height; + + // set that displaymode + if( SDL_SetWindowDisplayMode( window, &m ) < 0 ) + { + common->Warning( "Couldn't set window mode for fullscreen, reason: %s", SDL_GetError() ); + return false; + } + + // if we're currently not in fullscreen mode, we need to switch to fullscreen + if( !( SDL_GetWindowFlags( window ) & SDL_WINDOW_FULLSCREEN ) ) + { + if( SDL_SetWindowFullscreen( window, SDL_TRUE ) < 0 ) + { + common->Warning( "Couldn't switch to fullscreen mode, reason: %s!", SDL_GetError() ); + return false; + } + } + return true; +} + +static bool SetScreenParmsWindowed( glimpParms_t parms ) +{ + SDL_SetWindowSize( window, parms.width, parms.height ); + SDL_SetWindowPosition( window, parms.x, parms.y ); + + // if we're currently in fullscreen mode, we need to disable that + if( SDL_GetWindowFlags( window ) & SDL_WINDOW_FULLSCREEN ) + { + if( SDL_SetWindowFullscreen( window, SDL_FALSE ) < 0 ) + { + common->Warning( "Couldn't switch to windowed mode, reason: %s!", SDL_GetError() ); + return false; + } + } + return true; +} + + +/* +=================== +VKimp_SetScreenParms +=================== +*/ +bool VKimp_SetScreenParms( glimpParms_t parms ) +{ + + if( parms.fullScreen > 0 || parms.fullScreen == -2 ) + { + if( !SetScreenParmsFullscreen( parms ) ) + { + return false; + } + } + else if( parms.fullScreen == 0 ) // windowed mode + { + if( !SetScreenParmsWindowed( parms ) ) + { + return false; + } + } + else + { + common->Warning( "VKimp_SetScreenParms: fullScreen -1 (borderless window for multiple displays) currently unsupported!" ); + return false; + } + + glConfig.isFullscreen = parms.fullScreen; + glConfig.isStereoPixelFormat = parms.stereo; + glConfig.nativeScreenWidth = parms.width; + glConfig.nativeScreenHeight = parms.height; + glConfig.displayFrequency = parms.displayHz; + glConfig.multisamples = parms.multiSamples; + + return true; +} + +/* +=================== +VKimp_Shutdown +=================== +*/ +void VKimp_Shutdown() +{ + common->Printf( "Shutting down Vulkan subsystem\n" ); + + if( window ) + { + SDL_DestroyWindow( window ); + window = nullptr; + } + +} + +/* Eric: Is this needed/used for Vulkan? +================= +VKimp_SetGamma +================= +*/ +void VKimp_SetGamma( unsigned short red[256], unsigned short green[256], unsigned short blue[256] ) +{ +#ifndef USE_VULKAN + if( !window ) + { + common->Warning( "VKimp_SetGamma called without window" ); + return; + } + +#if SDL_VERSION_ATLEAST(2, 0, 0) + if( SDL_SetWindowGammaRamp( window, red, green, blue ) ) +#else + if( SDL_SetGammaRamp( red, green, blue ) ) +#endif + common->Warning( "Couldn't set gamma ramp: %s", SDL_GetError() ); +#endif +} + +/* +=================== +VKimp_ExtensionPointer +=================== +*/ +/* +GLExtension_t VKimp_ExtensionPointer(const char *name) { + assert(SDL_WasInit(SDL_INIT_VIDEO)); + + return (GLExtension_t)SDL_GL_GetProcAddress(name); +} +*/ + +void VKimp_GrabInput( int flags ) +{ + bool grab = flags & GRAB_ENABLE; + + if( grab && ( flags & GRAB_REENABLE ) ) + { + grab = false; + } + + if( flags & GRAB_SETSTATE ) + { + grabbed = grab; + } + + if( in_nograb.GetBool() ) + { + grab = false; + } + + if( !window ) + { + common->Warning( "VKimp_GrabInput called without window" ); + return; + } + + // DG: disabling the cursor is now done once in VKimp_Init() because it should always be disabled + + // DG: check for GRAB_ENABLE instead of GRAB_HIDECURSOR because we always wanna hide it + SDL_SetRelativeMouseMode( flags & GRAB_ENABLE ? SDL_TRUE : SDL_FALSE ); + SDL_SetWindowGrab( window, grab ? SDL_TRUE : SDL_FALSE ); + +} + +/* +==================== +DumpAllDisplayDevices +==================== +*/ +void DumpAllDisplayDevices() +{ + common->DPrintf( "TODO: DumpAllDisplayDevices\n" ); +} + +class idSort_VidMode : public idSort_Quick< vidMode_t, idSort_VidMode > +{ +public: + int Compare( const vidMode_t& a, const vidMode_t& b ) const + { + int wd = a.width - b.width; + int hd = a.height - b.height; + int fd = a.displayHz - b.displayHz; + return ( hd != 0 ) ? hd : ( wd != 0 ) ? wd : fd; + } +}; + +// RB: resolutions supported by XreaL +static void FillStaticVidModes( idList& modeList ) +{ + modeList.AddUnique( vidMode_t( 320, 240, 60 ) ); + modeList.AddUnique( vidMode_t( 400, 300, 60 ) ); + modeList.AddUnique( vidMode_t( 512, 384, 60 ) ); + modeList.AddUnique( vidMode_t( 640, 480, 60 ) ); + modeList.AddUnique( vidMode_t( 800, 600, 60 ) ); + modeList.AddUnique( vidMode_t( 960, 720, 60 ) ); + modeList.AddUnique( vidMode_t( 1024, 768, 60 ) ); + modeList.AddUnique( vidMode_t( 1152, 864, 60 ) ); + modeList.AddUnique( vidMode_t( 1280, 720, 60 ) ); + modeList.AddUnique( vidMode_t( 1280, 768, 60 ) ); + modeList.AddUnique( vidMode_t( 1280, 800, 60 ) ); + modeList.AddUnique( vidMode_t( 1280, 1024, 60 ) ); + modeList.AddUnique( vidMode_t( 1360, 768, 60 ) ); + modeList.AddUnique( vidMode_t( 1440, 900, 60 ) ); + modeList.AddUnique( vidMode_t( 1680, 1050, 60 ) ); + modeList.AddUnique( vidMode_t( 1600, 1200, 60 ) ); + modeList.AddUnique( vidMode_t( 1920, 1080, 60 ) ); + modeList.AddUnique( vidMode_t( 1920, 1200, 60 ) ); + modeList.AddUnique( vidMode_t( 2048, 1536, 60 ) ); + modeList.AddUnique( vidMode_t( 2560, 1600, 60 ) ); + + modeList.SortWithTemplate( idSort_VidMode() ); +} + +/* +==================== +R_GetModeListForDisplay +==================== +*/ +bool R_GetModeListForDisplay( const int requestedDisplayNum, idList& modeList ) +{ + assert( requestedDisplayNum >= 0 ); + + modeList.Clear(); + + // DG: SDL2 implementation + if( requestedDisplayNum >= SDL_GetNumVideoDisplays() ) + { + // requested invalid displaynum + return false; + } + + int numModes = SDL_GetNumDisplayModes( requestedDisplayNum ); + if( numModes > 0 ) + { + for( int i = 0; i < numModes; i++ ) + { + SDL_DisplayMode m; + int ret = SDL_GetDisplayMode( requestedDisplayNum, i, &m ); + if( ret != 0 ) + { + common->Warning( "Can't get video mode no %i, because of %s\n", i, SDL_GetError() ); + continue; + } + + vidMode_t mode; + mode.width = m.w; + mode.height = m.h; + mode.displayHz = m.refresh_rate ? m.refresh_rate : 60; // default to 60 if unknown (0) + modeList.AddUnique( mode ); + } + + if( modeList.Num() < 1 ) + { + common->Warning( "Couldn't get a single video mode for display %i, using default ones..!\n", requestedDisplayNum ); + FillStaticVidModes( modeList ); + } + + // sort with lowest resolution first + modeList.SortWithTemplate( idSort_VidMode() ); + } + else + { + common->Warning( "Can't get Video Info, using default modes...\n" ); + if( numModes < 0 ) + { + common->Warning( "Reason was: %s\n", SDL_GetError() ); + } + FillStaticVidModes( modeList ); + } + + return true; + // DG end +} From ae07018a3c4412c2a4cc1361827f04cc03187342 Mon Sep 17 00:00:00 2001 From: Eric Womer Date: Mon, 30 Dec 2019 15:39:41 -0500 Subject: [PATCH 5/7] Removed an inclusion guard as it is needed for Physical Device extensions and not Instance extensions. --- neo/renderer/Vulkan/RenderBackend_VK.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/neo/renderer/Vulkan/RenderBackend_VK.cpp b/neo/renderer/Vulkan/RenderBackend_VK.cpp index a61b345c..a57f0a07 100644 --- a/neo/renderer/Vulkan/RenderBackend_VK.cpp +++ b/neo/renderer/Vulkan/RenderBackend_VK.cpp @@ -345,8 +345,7 @@ static void EnumeratePhysicalDevices() vkGetPhysicalDeviceQueueFamilyProperties( gpu.device, &numQueues, gpu.queueFamilyProps.Ptr() ); ID_VK_VALIDATE( numQueues > 0, "vkGetPhysicalDeviceQueueFamilyProperties returned zero queues." ); } - // Eric: Bypass this since on linux we use SDL_Vulkan_GetInstanceExtensions to query for extensions. -#if defined(__linux__) + // grab available Vulkan extensions { idLib::Printf("Getting available vulkan extensions...\n"); @@ -364,7 +363,6 @@ static void EnumeratePhysicalDevices() } #endif // 0 } -#endif // __linux__ // grab surface specific information ID_VK_CHECK( vkGetPhysicalDeviceSurfaceCapabilitiesKHR( gpu.device, vkcontext.surface, &gpu.surfaceCaps ) ); From 4f38ce06338e825abb8c1e56c67cd4ec292b4b45 Mon Sep 17 00:00:00 2001 From: Eric Womer Date: Wed, 1 Jan 2020 14:25:38 -0500 Subject: [PATCH 6/7] CMakeLists.txt: * Added defining VK_USE_PLATFORM_* during CMake configuration, one for windows and one for UNIX * Fixed a case issue when adding Vulkans include directory --- neo/CMakeLists.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/neo/CMakeLists.txt b/neo/CMakeLists.txt index 522bc5b1..c8c5d3cf 100644 --- a/neo/CMakeLists.txt +++ b/neo/CMakeLists.txt @@ -333,7 +333,7 @@ if(USE_VULKAN) endif() add_definitions(-DUSE_VULKAN) - include_directories($ENV{VULKAN_SDK}/Include) + include_directories($ENV{VULKAN_SDK}/include) # Eric: For use with SDL2/Vulkan if(UNIX) @@ -343,6 +343,9 @@ if(USE_VULKAN) list(APPEND SUBSYSTEMS [X11]) include_directories(${X11_XCB_INCLUDE_DIRS}) endif() + add_definitions(-DVK_USE_PLATFORM_XLIB_KHR) + elseif(WIN32) + add_definitions(-DVK_USE_PLATFORM_WIN32_KHR) endif() if(SPIRV_SHADERC) From 596fbb18ca7bfe3874fb7c539cd653067b7534c2 Mon Sep 17 00:00:00 2001 From: Eric Womer Date: Wed, 1 Jan 2020 14:31:28 -0500 Subject: [PATCH 7/7] RenderBackend.h: * Renamed vkwindow to sdlWindow in struct vulkanContext_t to matche the rest of the struct naming conventions. Image_VK.cpp: * disabled printing "Vulkan Image alloc " to the terminal, flooding it with data RenderBackend_VK.cpp: * Re-enabled r_vkEnableValidationLayers enabling/disabling Vulkan validation checking, I had it hard-coded to true for testing reasons. * static void DestroySwapChain(): * I don't know if the changes I introduced here are helping or not, or even doing anything, so this part can be ignored or changed back. * GL_StartFrame() and GL_BlockingSwapBuffers(): * VkResult for these two functions, vkAcquireNextImageKHR and vkQueuePresentKHR, don't need to return VK_SUCCESS for the application to be valid, so handle them differently here. There may be others like this, but I don't know. qvk.h: * Since VK_USE_PLATFORM_* is defined in the CMakeLists.txt file, for now anyways, use them to wrap the correct platform headers instead of defining them here. sdl_vkimp.cpp: * Some debug printing changes, from GL to Vulkan, since this is for the Vulkan API. --- neo/renderer/RenderBackend.h | 2 +- neo/renderer/Vulkan/Image_VK.cpp | 3 +- neo/renderer/Vulkan/RenderBackend_VK.cpp | 65 ++++++++++++++++++++---- neo/renderer/Vulkan/qvk.h | 15 +++++- neo/sys/sdl/sdl_vkimp.cpp | 6 +-- 5 files changed, 75 insertions(+), 16 deletions(-) diff --git a/neo/renderer/RenderBackend.h b/neo/renderer/RenderBackend.h index 6a0148c9..3a90b485 100644 --- a/neo/renderer/RenderBackend.h +++ b/neo/renderer/RenderBackend.h @@ -150,7 +150,7 @@ struct vulkanContext_t { // Eric: If on linux, use this to pass SDL_Window pointer to the SDL_Vulkan_* methods not in sdl_vkimp.cpp file. #if defined(__linux__) - SDL_Window* vkwindow = nullptr; + SDL_Window* sdlWindow = nullptr; #endif uint64 frameCounter; uint32 frameParity; diff --git a/neo/renderer/Vulkan/Image_VK.cpp b/neo/renderer/Vulkan/Image_VK.cpp index a992b43e..62031afd 100644 --- a/neo/renderer/Vulkan/Image_VK.cpp +++ b/neo/renderer/Vulkan/Image_VK.cpp @@ -567,7 +567,8 @@ void idImage::AllocImage() ID_VK_CHECK( vkBindImageMemory( vkcontext.device, image, allocation.deviceMemory, allocation.offset ) ); #endif - idLib::Printf( "Vulkan Image alloc '%s': %p\n", GetName(), image ); + // Eric: disable for now to clean the terminal output + // idLib::Printf( "Vulkan Image alloc '%s': %p\n", GetName(), image ); // Create Image View VkImageViewCreateInfo viewCreateInfo = {}; diff --git a/neo/renderer/Vulkan/RenderBackend_VK.cpp b/neo/renderer/Vulkan/RenderBackend_VK.cpp index a57f0a07..3f038174 100644 --- a/neo/renderer/Vulkan/RenderBackend_VK.cpp +++ b/neo/renderer/Vulkan/RenderBackend_VK.cpp @@ -254,7 +254,7 @@ static void CreateVulkanInstance() createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; createInfo.pApplicationInfo = &appInfo; - const bool enableLayers = true; // r_vkEnableValidationLayers.GetBool(); EW: Testing + const bool enableLayers = r_vkEnableValidationLayers.GetBool(); vkcontext.instanceExtensions.Clear(); vkcontext.deviceExtensions.Clear(); @@ -440,7 +440,7 @@ static void CreateSurface() #else #if defined(__linux__) - if(!SDL_Vulkan_CreateSurface(vkcontext.vkwindow, vkcontext.instance, &vkcontext.surface)) { + if(!SDL_Vulkan_CreateSurface(vkcontext.sdlWindow, vkcontext.instance, &vkcontext.surface)) { idLib::FatalError("Error while creating Vulkan surface: %s", SDL_GetError()); } #else @@ -724,7 +724,7 @@ static VkExtent2D ChooseSurfaceExtent( VkSurfaceCapabilitiesKHR& caps ) int width; int height; - SDL_Vulkan_GetDrawableSize(vkcontext.vkwindow, &width, &height); + SDL_Vulkan_GetDrawableSize(vkcontext.sdlWindow, &width, &height); width = CLAMP(width, caps.minImageExtent.width, caps.maxImageExtent.width); height = CLAMP(height, caps.minImageExtent.height, caps.maxImageExtent.height); @@ -825,7 +825,8 @@ DestroySwapChain */ static void DestroySwapChain() { - for( uint32 i = 0; i < NUM_FRAME_DATA; ++i ) + + for( uint32 i = 0; i < NUM_FRAME_DATA; ++i ) { vkDestroyImageView( vkcontext.device, vkcontext.swapchainViews[ i ], NULL ); } @@ -984,11 +985,21 @@ static void CreateRenderTargets() VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT ); } + idImageOpts depthOptions; + depthOptions.format = FMT_DEPTH; - idImageOpts depthOptions; - depthOptions.format = FMT_DEPTH; - depthOptions.width = renderSystem->GetWidth(); + // Eric: See if this fixes resizing +#if defined(__linux__) + gpuInfo_t& gpu = *vkcontext.gpu; + VkExtent2D extent = ChooseSurfaceExtent( gpu.surfaceCaps ); + + depthOptions.width = extent.width; + depthOptions.height = extent.height; +#else + depthOptions.width = renderSystem->GetWidth(); depthOptions.height = renderSystem->GetHeight(); +#endif + depthOptions.numLevels = 1; depthOptions.samples = static_cast< textureSamples_t >( vkcontext.sampleCount ); @@ -1736,7 +1747,24 @@ idRenderBackend::GL_StartFrame */ void idRenderBackend::GL_StartFrame() { - ID_VK_CHECK( vkAcquireNextImageKHR( vkcontext.device, vkcontext.swapchain, UINT64_MAX, vkcontext.acquireSemaphores[ vkcontext.frameParity ], VK_NULL_HANDLE, &vkcontext.currentSwapIndex ) ); + // Eric: Since VK_SUBOPTIMAL_KHR is not a hard fault and VK_ERROR_OUT_OF_DATE_KHR means the window is being resized (or other stuff) handle them instead of killing the app. + VkResult result = vkAcquireNextImageKHR( vkcontext.device, vkcontext.swapchain, UINT64_MAX, vkcontext.acquireSemaphores[ vkcontext.frameParity ], VK_NULL_HANDLE, &vkcontext.currentSwapIndex ); + switch (result) { + case VK_SUCCESS: + case VK_SUBOPTIMAL_KHR: + break; + case VK_ERROR_OUT_OF_DATE_KHR: + DestroySwapChain(); + CreateSwapChain(); + return; + // return on_window_size_changed(); + break; + default: + idLib::FatalError("VK: %s - %s", VK_ErrorToString(result), + "vkAcquireNextImageKHR( vkcontext.device, vkcontext.swapchain, UINT64_MAX, vkcontext.acquireSemaphores[ vkcontext.frameParity ], VK_NULL_HANDLE, &vkcontext.currentSwapIndex )"); + return; + } + // ID_VK_CHECK( vkAcquireNextImageKHR( vkcontext.device, vkcontext.swapchain, UINT64_MAX, vkcontext.acquireSemaphores[ vkcontext.frameParity ], VK_NULL_HANDLE, &vkcontext.currentSwapIndex ) ); idImage::EmptyGarbage(); @@ -1857,7 +1885,26 @@ void idRenderBackend::GL_BlockingSwapBuffers() presentInfo.pSwapchains = &vkcontext.swapchain; presentInfo.pImageIndices = &vkcontext.currentSwapIndex; - ID_VK_CHECK( vkQueuePresentKHR( vkcontext.presentQueue, &presentInfo ) ); + // Eric: // Eric: Since VK_SUBOPTIMAL_KHR and VK_ERROR_OUT_OF_DATE_KHR here means + // the window is being resized (or other stuff) handle them instead of killing the app. + VkResult result = vkQueuePresentKHR( vkcontext.presentQueue, &presentInfo ); + switch (result) { + case VK_SUCCESS: + break; + case VK_ERROR_OUT_OF_DATE_KHR: + case VK_SUBOPTIMAL_KHR: + // return on_window_size_changed(); Eric: Handle resizing the window. + DestroySwapChain(); + CreateSwapChain(); + return; + break; + default: + idLib::FatalError("VK: %s - %s", VK_ErrorToString(result), + "vkQueuePresentKHR( vkcontext.presentQueue, &presentInfo )"); + return; + } + + // ID_VK_CHECK( vkQueuePresentKHR( vkcontext.presentQueue, &presentInfo ) ); // RB: at this time the image is presented on the screen diff --git a/neo/renderer/Vulkan/qvk.h b/neo/renderer/Vulkan/qvk.h index 3f26411d..2f35e42f 100644 --- a/neo/renderer/Vulkan/qvk.h +++ b/neo/renderer/Vulkan/qvk.h @@ -32,9 +32,20 @@ If you have questions concerning this license or the applicable additional terms #if defined( USE_VULKAN ) -// #define VK_USE_PLATFORM_XLIB_KHR +#if defined(VK_USE_PLATFORM_WIN32_KHR) +#include +#elif defined(VK_USE_PLATFORM_XCB_KHR) +#include +#include +#include + +#elif defined(VK_USE_PLATFORM_XLIB_KHR) +#include +#include +#include +#include +#endif -#define VK_USE_PLATFORM_XCB_KHR #define USE_AMD_ALLOCATOR #include diff --git a/neo/sys/sdl/sdl_vkimp.cpp b/neo/sys/sdl/sdl_vkimp.cpp index 9391a640..560a8199 100644 --- a/neo/sys/sdl/sdl_vkimp.cpp +++ b/neo/sys/sdl/sdl_vkimp.cpp @@ -265,11 +265,11 @@ bool VKimp_Init( glimpParms_t parms ) if( !window ) { - common->DPrintf( "Couldn't set GL mode %d/%d/%d: %s", + common->DPrintf( "Couldn't set Vulkan mode %d/%d/%d: %s", channelcolorbits, tdepthbits, tstencilbits, SDL_GetError() ); continue; } - vkcontext.vkwindow = window; + vkcontext.sdlWindow = window; // RB begin SDL_GetWindowSize( window, &glConfig.nativeScreenWidth, &glConfig.nativeScreenHeight ); // RB end @@ -298,7 +298,7 @@ bool VKimp_Init( glimpParms_t parms ) if( !window ) { - common->Printf( "No usable GL mode found: %s", SDL_GetError() ); + common->Printf( "No usable VK mode found: %s", SDL_GetError() ); return false; }