diff --git a/changelog.md b/changelog.md index da59648..8716071 100644 --- a/changelog.md +++ b/changelog.md @@ -1,7 +1,7 @@ Removed cvars: -* r_allowExtensions +* r_allowExtensions (always use extensions if available) * r_allowSoftwareGL -* r_colorbits (use desktop color depth by default) -* r_ext_multitexture (mandatory feature) +* r_colorbits (use desktop color depth) +* r_ext_multitexture (required) * r_maskMinidriver * r_primitives (always use qglDrawElements) diff --git a/src/engine/platform/glw_win.h b/src/engine/platform/glw_win.h index e5bd51e..93b2f2e 100644 --- a/src/engine/platform/glw_win.h +++ b/src/engine/platform/glw_win.h @@ -35,8 +35,6 @@ typedef struct HINSTANCE hinstOpenGL; // HINSTANCE for the OpenGL library - qboolean pixelFormatSet; - int desktopBitsPixel; int desktopWidth, desktopHeight; diff --git a/src/engine/platform/win_glimp.c b/src/engine/platform/win_glimp.c index f2e908e..f8d4dd1 100644 --- a/src/engine/platform/win_glimp.c +++ b/src/engine/platform/win_glimp.c @@ -47,13 +47,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "sdl/SDL.h" #include "sdl/SDL_syswm.h" - extern void WG_CheckHardwareGamma( void ); extern void WG_RestoreGamma( void ); -#define WINDOW_CLASS_NAME "Quake 3: Arena" +#define MAIN_WINDOW_CLASS_NAME "Quake 3: Arena" +#define API_COMPARE_WINDOW_CLASS_NAME "Quake 3: Arena [API compare]" -static qboolean s_classRegistered = qfalse; +static bool s_main_window_class_registered = false; +static bool s_api_compare_window_class_registered = false; // // function declaration @@ -202,7 +203,7 @@ static int GLW_ChoosePixelFormat(HDC hDC, const PIXELFORMATDESCRIPTOR *pPFD) return bestMatch; } -static bool GLW_SetPixelFormat(PIXELFORMATDESCRIPTOR *pPFD, int colorbits, int depthbits, int stencilbits, qboolean stereo) { +static bool GLW_SetPixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR *pPFD, int colorbits, int depthbits, int stencilbits, qboolean stereo) { const PIXELFORMATDESCRIPTOR pfd_base = { sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd @@ -237,92 +238,85 @@ static bool GLW_SetPixelFormat(PIXELFORMATDESCRIPTOR *pPFD, int colorbits, int d pPFD->dwFlags |= PFD_STEREO; } - int pixelformat = GLW_ChoosePixelFormat(glw_state.hDC, pPFD); + int pixelformat = GLW_ChoosePixelFormat(hdc, pPFD); if (pixelformat == 0) { ri.Printf( PRINT_ALL, "...GLW_ChoosePixelFormat failed\n"); return false; } ri.Printf( PRINT_ALL, "...PIXELFORMAT %d selected\n", pixelformat ); - DescribePixelFormat( glw_state.hDC, pixelformat, sizeof( *pPFD ), pPFD ); - if (SetPixelFormat( glw_state.hDC, pixelformat, pPFD ) == FALSE) { - ri.Printf (PRINT_ALL, "...SetPixelFormat failed\n", glw_state.hDC); + DescribePixelFormat(hdc, pixelformat, sizeof( *pPFD ), pPFD); + if (SetPixelFormat(hdc, pixelformat, pPFD ) == FALSE) { + ri.Printf (PRINT_ALL, "...SetPixelFormat failed\n", hdc); return false; } return true; } - -// Sets pixel format and creates opengl context. -static qboolean GLW_InitDriver() { - +// Sets pixel format and creates opengl context for the given window. +static qboolean GLW_InitDriver(HWND hwnd) { ri.Printf( PRINT_ALL, "Initializing OpenGL driver\n" ); - // - // get a DC for our window if we don't already have one allocated - // - if (glw_state.hDC == NULL) { - ri.Printf( PRINT_ALL, "...getting DC: " ); + glw_state.hDC = NULL; + glw_state.hGLRC = NULL; - glw_state.hDC = GetDC(g_wv.hWnd); - if (glw_state.hDC == NULL ) { - ri.Printf( PRINT_ALL, "failed\n" ); - return qfalse; - } - ri.Printf( PRINT_ALL, "succeeded\n" ); + // + // get a DC for our window + // + ri.Printf(PRINT_ALL, "...getting DC: "); + HDC hdc = GetDC(hwnd); + if (hdc == NULL) { + ri.Printf(PRINT_ALL, "failed\n"); + return qfalse; } - - int colorbits = glw_state.desktopBitsPixel; - int depthbits = (r_depthbits->integer == 0) ? 24 : r_depthbits->integer; - int stencilbits = r_stencilbits->integer; + ri.Printf(PRINT_ALL, "succeeded\n"); // // set pixel format // + int colorbits = glw_state.desktopBitsPixel; + int depthbits = (r_depthbits->integer == 0) ? 24 : r_depthbits->integer; + int stencilbits = r_stencilbits->integer; + PIXELFORMATDESCRIPTOR pfd; - if (!glw_state.pixelFormatSet) { + if (!GLW_SetPixelFormat(hdc, &pfd, colorbits, depthbits, stencilbits, (qboolean)r_stereo->integer)) { + ReleaseDC(hwnd, hdc); + ri.Printf(PRINT_ALL, "...failed to find an appropriate PIXELFORMAT\n"); + return qfalse; + } - if (!GLW_SetPixelFormat(&pfd, colorbits, depthbits, stencilbits, (qboolean)r_stereo->integer)) { - ReleaseDC(g_wv.hWnd, glw_state.hDC); - glw_state.hDC = NULL; - - ri.Printf(PRINT_ALL, "...failed to find an appropriate PIXELFORMAT\n"); - return qfalse; - } - - // report if stereo is desired but unavailable - if (!(pfd.dwFlags & PFD_STEREO) && (r_stereo->integer != 0)) { - ri.Printf(PRINT_ALL, "...failed to select stereo pixel format\n"); - } - - glw_state.pixelFormatSet = qtrue; + // report if stereo is desired but unavailable + if (!(pfd.dwFlags & PFD_STEREO) && (r_stereo->integer != 0)) { + ri.Printf(PRINT_ALL, "...failed to select stereo pixel format\n"); } // // startup the OpenGL subsystem by creating a context and making it current // - if (!glw_state.hGLRC) { - ri.Printf(PRINT_ALL, "...creating GL context: "); - glw_state.hGLRC = qwglCreateContext(glw_state.hDC); - if (glw_state.hGLRC == NULL) { - ri.Printf(PRINT_ALL, "failed\n"); - return qfalse; - } - ri.Printf(PRINT_ALL, "succeeded\n"); - - ri.Printf(PRINT_ALL, "...making context current: "); - if (!qwglMakeCurrent(glw_state.hDC, glw_state.hGLRC)) { - qwglDeleteContext(glw_state.hGLRC); - glw_state.hGLRC = NULL; - ri.Printf(PRINT_ALL, "failed\n"); - return qfalse; - } - ri.Printf(PRINT_ALL, "succeeded\n"); + ri.Printf(PRINT_ALL, "...creating GL context: "); + HGLRC hglrc = qwglCreateContext(hdc); + if (hglrc == NULL) { + ReleaseDC(hwnd, hdc); + ri.Printf(PRINT_ALL, "failed\n"); + return qfalse; } + ri.Printf(PRINT_ALL, "succeeded\n"); + + ri.Printf(PRINT_ALL, "...making context current: "); + if (!qwglMakeCurrent(hdc, hglrc)) { + qwglDeleteContext(hglrc); + ReleaseDC(hwnd, hdc); + ri.Printf(PRINT_ALL, "failed\n"); + return qfalse; + } + ri.Printf(PRINT_ALL, "succeeded\n"); // - // store PFD specifics + // update global state and return // + glw_state.hDC = hdc; + glw_state.hGLRC = hglrc; + glConfig.colorBits = ( int ) pfd.cColorBits; glConfig.depthBits = ( int ) pfd.cDepthBits; glConfig.stencilBits = ( int ) pfd.cStencilBits; @@ -331,12 +325,12 @@ static qboolean GLW_InitDriver() { return qtrue; } -static void GLW_CreateWindow(int width, int height, qboolean fullscreen) +static HWND create_main_window(int width, int height, qboolean fullscreen) { // // register the window class if necessary // - if ( !s_classRegistered ) + if (!s_main_window_class_registered) { WNDCLASS wc; @@ -351,99 +345,183 @@ static void GLW_CreateWindow(int width, int height, qboolean fullscreen) wc.hCursor = LoadCursor (NULL,IDC_ARROW); wc.hbrBackground = (HBRUSH) (void *)COLOR_GRAYTEXT; wc.lpszMenuName = 0; - wc.lpszClassName = WINDOW_CLASS_NAME; + wc.lpszClassName = MAIN_WINDOW_CLASS_NAME; if ( !RegisterClass( &wc ) ) { - ri.Error( ERR_FATAL, "GLW_CreateWindow: could not register window class" ); + ri.Error( ERR_FATAL, "create_main_window: could not register window class" ); } - s_classRegistered = qtrue; + s_main_window_class_registered = true; ri.Printf( PRINT_ALL, "...registered window class\n" ); } // - // create the HWND if one does not already exist + // compute width and height // - if ( !g_wv.hWnd ) + RECT r; + r.left = 0; + r.top = 0; + r.right = width; + r.bottom = height; + + int stylebits; + if ( fullscreen ) { - // - // compute width and height - // - RECT r; - r.left = 0; - r.top = 0; - r.right = width; - r.bottom = height; - - int stylebits; - if ( fullscreen ) - { - stylebits = WS_POPUP|WS_VISIBLE|WS_SYSMENU; - } - else - { - stylebits = WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_VISIBLE | WS_SYSMENU; - AdjustWindowRect (&r, stylebits, FALSE); - } - - int w = r.right - r.left; - int h = r.bottom - r.top; - - int x, y; - - if ( fullscreen ) - { - x = 0; - y = 0; - } - else - { - cvar_t* vid_xpos = ri.Cvar_Get ("vid_xpos", "", 0); - cvar_t* vid_ypos = ri.Cvar_Get ("vid_ypos", "", 0); - x = vid_xpos->integer; - y = vid_ypos->integer; - - // adjust window coordinates if necessary - // so that the window is completely on screen - if ( x < 0 ) - x = 0; - if ( y < 0 ) - y = 0; - - if ( w < glw_state.desktopWidth && - h < glw_state.desktopHeight ) - { - if ( x + w > glw_state.desktopWidth ) - x = ( glw_state.desktopWidth - w ); - if ( y + h > glw_state.desktopHeight ) - y = ( glw_state.desktopHeight - h ); - } - } - - g_wv.hWnd = CreateWindowEx ( - 0, - WINDOW_CLASS_NAME, - "Quake 3: Arena", - stylebits, - x, y, w, h, - NULL, - NULL, - g_wv.hInstance, - NULL); - - if ( !g_wv.hWnd ) - { - ri.Error (ERR_FATAL, "GLW_CreateWindow() - Couldn't create window"); - } - - ShowWindow( g_wv.hWnd, SW_SHOW ); - UpdateWindow( g_wv.hWnd ); - ri.Printf( PRINT_ALL, "...created window@%d,%d (%dx%d)\n", x, y, w, h ); + stylebits = WS_POPUP|WS_VISIBLE|WS_SYSMENU; } else { - ri.Printf( PRINT_ALL, "...window already present, CreateWindowEx skipped\n" ); + stylebits = WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_VISIBLE | WS_SYSMENU; + AdjustWindowRect (&r, stylebits, FALSE); } + + int w = r.right - r.left; + int h = r.bottom - r.top; + + int x, y; + + if ( fullscreen ) + { + x = 0; + y = 0; + } + else + { + cvar_t* vid_xpos = ri.Cvar_Get ("vid_xpos", "", 0); + cvar_t* vid_ypos = ri.Cvar_Get ("vid_ypos", "", 0); + x = vid_xpos->integer; + y = vid_ypos->integer; + + // adjust window coordinates if necessary + // so that the window is completely on screen + if ( x < 0 ) + x = 0; + if ( y < 0 ) + y = 0; + + if ( w < glw_state.desktopWidth && + h < glw_state.desktopHeight ) + { + if ( x + w > glw_state.desktopWidth ) + x = ( glw_state.desktopWidth - w ); + if ( y + h > glw_state.desktopHeight ) + y = ( glw_state.desktopHeight - h ); + } + } + + HWND hwnd = CreateWindowEx( + 0, + MAIN_WINDOW_CLASS_NAME, + "Quake 3: Arena", + stylebits, + x, y, w, h, + NULL, + NULL, + g_wv.hInstance, + NULL); + + if (!hwnd) + { + ri.Error (ERR_FATAL, "create_main_window() - Couldn't create window"); + } + + ShowWindow(hwnd, SW_SHOW); + UpdateWindow(hwnd); + ri.Printf(PRINT_ALL, "...created window@%d,%d (%dx%d)\n", x, y, w, h); + return hwnd; +} + +static HWND create_api_compare_window(int width, int height) +{ + // + // register the window class if necessary + // + if (!s_api_compare_window_class_registered) + { + WNDCLASS wc; + + memset( &wc, 0, sizeof( wc ) ); + + wc.style = 0; + wc.lpfnWndProc = DefWindowProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = g_wv.hInstance; + wc.hIcon = LoadIcon( g_wv.hInstance, MAKEINTRESOURCE(IDI_ICON1)); + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.hbrBackground = (HBRUSH) (void *)COLOR_GRAYTEXT; + wc.lpszMenuName = 0; + wc.lpszClassName = API_COMPARE_WINDOW_CLASS_NAME; + + if ( !RegisterClass( &wc ) ) + { + ri.Error( ERR_FATAL, "create_api_compare_window: could not register window class" ); + } + s_api_compare_window_class_registered = true; + ri.Printf( PRINT_ALL, "...registered api compare window class\n" ); + } + + // + // compute width and height + // + RECT r; + r.left = 0; + r.top = 0; + r.right = width; + r.bottom = height; + + int stylebits = WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_VISIBLE | WS_SYSMENU; + AdjustWindowRect (&r, stylebits, FALSE); + + int w = r.right - r.left; + int h = r.bottom - r.top; + + cvar_t* vid_xpos = ri.Cvar_Get ("vid_xpos", "", 0); + cvar_t* vid_ypos = ri.Cvar_Get ("vid_ypos", "", 0); + int x = vid_xpos->integer + width + 5; // offset to the right of the main window + int y = vid_ypos->integer; + + // adjust window coordinates if necessary + // so that the window is completely on screen + if ( x < 0 ) + x = 0; + if ( y < 0 ) + y = 0; + + if ( w < glw_state.desktopWidth && + h < glw_state.desktopHeight ) + { + if ( x + w > glw_state.desktopWidth ) + x = ( glw_state.desktopWidth - w ); + if ( y + h > glw_state.desktopHeight ) + y = ( glw_state.desktopHeight - h ); + } + + // If r_renderAPI = 0 (OpenGL) then compare window uses Vulkan API. + // If r_renderAPI = 1 (Vulkan) then compare window uses OpenGL API. + char window_name[1024]; + sprintf(window_name, "%s [%s]", MAIN_WINDOW_CLASS_NAME, r_renderAPI->integer ? "OpenGL" : "Vulkan"); + + HWND hwnd = CreateWindowEx( + 0, + API_COMPARE_WINDOW_CLASS_NAME, + window_name, + stylebits, + x, y, w, h, + NULL, + NULL, + g_wv.hInstance, + NULL); + + if (!hwnd) + { + ri.Error (ERR_FATAL, "create_api_compare_window() - Couldn't create window"); + } + + ShowWindow(hwnd, SW_SHOW); + UpdateWindow(hwnd); + ri.Printf(PRINT_ALL, "...created api compare window@%d,%d (%dx%d)\n", x, y, w, h); + return hwnd; } /* @@ -474,30 +552,57 @@ static bool GLW_SetMode(int mode, qboolean fullscreen) { glConfig.isFullscreen = fullscreen; ri.Printf( PRINT_ALL, " %d %d %s\n", glConfig.vidWidth, glConfig.vidHeight, fullscreen ? "FS" : "W"); - GLW_CreateWindow(glConfig.vidWidth, glConfig.vidHeight, fullscreen); + g_wv.hWnd = NULL; + g_wv.hWnd_opengl = NULL; + g_wv.hWnd_vulkan = NULL; - if (!GLW_InitDriver()) { - ShowWindow(g_wv.hWnd, SW_HIDE); - DestroyWindow(g_wv.hWnd); - g_wv.hWnd = NULL; - return false; + HWND hwnd = create_main_window(glConfig.vidWidth, glConfig.vidHeight, fullscreen); + + if (r_renderAPI->integer == 0) { // opengl + if (!GLW_InitDriver(hwnd)) { + ShowWindow(hwnd, SW_HIDE); + DestroyWindow(hwnd); + return false; + } + g_wv.hWnd = hwnd; + g_wv.hWnd_opengl = hwnd; + + if (r_renderAPICompareWindow->integer) { + HWND hwnd2 = create_api_compare_window(glConfig.vidWidth, glConfig.vidHeight); + if (!initialize_vulkan(hwnd2)) { + ShowWindow(hwnd2, SW_HIDE); + DestroyWindow(hwnd2); + ri.Printf(PRINT_WARNING, "GLW_SetMode: could not create API compare window"); + } else { + g_wv.hWnd_vulkan = hwnd2; + vulkan_demo = new Vulkan_Demo(glConfig.vidWidth, glConfig.vidHeight); + } + } + } else { // vulkan + if (!initialize_vulkan(hwnd)) { + ShowWindow(hwnd, SW_HIDE); + DestroyWindow(hwnd); + return false; + } + vulkan_demo = new Vulkan_Demo(glConfig.vidWidth, glConfig.vidHeight); + + g_wv.hWnd = hwnd; + g_wv.hWnd_vulkan = hwnd; + + if (r_renderAPICompareWindow->integer) { + HWND hwnd2 = create_api_compare_window(glConfig.vidWidth, glConfig.vidHeight); + if (!GLW_InitDriver(hwnd2)) { + ShowWindow(hwnd2, SW_HIDE); + DestroyWindow(hwnd2); + ri.Printf(PRINT_WARNING, "GLW_SetMode: could not create API compare window"); + } else { + g_wv.hWnd_opengl = hwnd2; + } + } } + SetForegroundWindow(g_wv.hWnd); SetFocus(g_wv.hWnd); - - // VULKAN - if (SDL_Init(SDL_INIT_VIDEO) != 0) - ri.Error(ERR_FATAL, "SDL_Init error"); - SDL_Window* window = SDL_CreateWindow("Vulkan app", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - glConfig.vidWidth, glConfig.vidHeight, SDL_WINDOW_SHOWN); - if (window == nullptr) - ri.Error(ERR_FATAL, "failed to create SDL window"); - SDL_SysWMinfo window_sys_info; - SDL_VERSION(&window_sys_info.version) - if (SDL_GetWindowWMInfo(window, &window_sys_info) == SDL_FALSE) - ri.Error(ERR_FATAL, "failed to get platform specific window information"); - vulkan_demo = new Vulkan_Demo(glConfig.vidWidth, glConfig.vidHeight, window_sys_info); - return true; } @@ -700,66 +805,60 @@ void GLimp_Init( void ) */ void GLimp_Shutdown( void ) { -// const char *strings[] = { "soft", "hard" }; const char *success[] = { "failed", "success" }; int retVal; - // FIXME: Brian, we need better fallbacks from partially initialized failures - if ( !qwglMakeCurrent ) { - return; - } - - ri.Printf( PRINT_ALL, "Shutting down OpenGL subsystem\n" ); + ri.Printf(PRINT_ALL, "Shutting down OpenGL subsystem\n"); // restore gamma. We do this first because 3Dfx's extension needs a valid OGL subsystem WG_RestoreGamma(); // set current context to NULL - if ( qwglMakeCurrent ) - { - retVal = qwglMakeCurrent( NULL, NULL ) != 0; - - ri.Printf( PRINT_ALL, "...wglMakeCurrent( NULL, NULL ): %s\n", success[retVal] ); + if (qwglMakeCurrent) { + retVal = qwglMakeCurrent(NULL, NULL) != 0; + ri.Printf(PRINT_ALL, "...wglMakeCurrent( NULL, NULL ): %s\n", success[retVal]); } // delete HGLRC - if ( glw_state.hGLRC ) - { - retVal = qwglDeleteContext( glw_state.hGLRC ) != 0; - ri.Printf( PRINT_ALL, "...deleting GL context: %s\n", success[retVal] ); + if (glw_state.hGLRC) { + retVal = qwglDeleteContext(glw_state.hGLRC) != 0; + ri.Printf(PRINT_ALL, "...deleting GL context: %s\n", success[retVal]); glw_state.hGLRC = NULL; } // release DC - if ( glw_state.hDC ) - { - retVal = ReleaseDC( g_wv.hWnd, glw_state.hDC ) != 0; - ri.Printf( PRINT_ALL, "...releasing DC: %s\n", success[retVal] ); - glw_state.hDC = NULL; + if (glw_state.hDC) { + retVal = ReleaseDC(g_wv.hWnd_opengl, glw_state.hDC) != 0; + ri.Printf(PRINT_ALL, "...releasing DC: %s\n", success[retVal]); + glw_state.hDC = NULL; } // destroy window - if ( g_wv.hWnd ) - { - ri.Printf( PRINT_ALL, "...destroying window\n" ); - ShowWindow( g_wv.hWnd, SW_HIDE ); - DestroyWindow( g_wv.hWnd ); - g_wv.hWnd = NULL; - glw_state.pixelFormatSet = qfalse; + if (g_wv.hWnd_opengl) { + ri.Printf(PRINT_ALL, "...destroying opengl window\n"); + ShowWindow(g_wv.hWnd_opengl, SW_HIDE); + DestroyWindow(g_wv.hWnd_opengl); + g_wv.hWnd_opengl = NULL; } + if (g_wv.hWnd_vulkan) { + ri.Printf(PRINT_ALL, "...destroying vulkan window\n"); + ShowWindow(g_wv.hWnd_vulkan, SW_HIDE); + DestroyWindow(g_wv.hWnd_vulkan); + g_wv.hWnd_vulkan = NULL; + } + g_wv.hWnd = NULL; // close the r_logFile - if ( glw_state.log_fp ) - { - fclose( glw_state.log_fp ); + if (glw_state.log_fp) { + fclose(glw_state.log_fp); glw_state.log_fp = 0; } // shutdown QGL subsystem QGL_Shutdown(); - memset( &glConfig, 0, sizeof( glConfig ) ); - memset( &glState, 0, sizeof( glState ) ); + memset(&glConfig, 0, sizeof(glConfig)); + memset(&glState, 0, sizeof(glState)); } /* diff --git a/src/engine/platform/win_local.h b/src/engine/platform/win_local.h index ae82cc0..95b7a26 100644 --- a/src/engine/platform/win_local.h +++ b/src/engine/platform/win_local.h @@ -73,7 +73,11 @@ typedef struct HINSTANCE reflib_library; // Handle to refresh DLL qboolean reflib_active; - HWND hWnd; + HWND hWnd; // main window, refers either to hWnd_opengl or to hWnd_vulkan + + HWND hWnd_opengl; + HWND hWnd_vulkan; + HINSTANCE hInstance; qboolean activeApp; qboolean isMinimized; diff --git a/src/engine/renderer/tr_init.c b/src/engine/renderer/tr_init.c index 5ee27f7..52225fe 100644 --- a/src/engine/renderer/tr_init.c +++ b/src/engine/renderer/tr_init.c @@ -28,6 +28,9 @@ glstate_t glState; static void GfxInfo_f( void ); +cvar_t *r_renderAPI; +cvar_t *r_renderAPICompareWindow; + cvar_t *r_flareSize; cvar_t *r_flareFade; @@ -794,6 +797,9 @@ R_Register */ void R_Register( void ) { + r_renderAPI = ri.Cvar_Get( "r_renderAPI", "0", CVAR_ARCHIVE | CVAR_LATCH ) ; + r_renderAPICompareWindow = ri.Cvar_Get( "r_renderAPICompareWindow", "0", 0 ) ; + // // latched and archived variables // diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index 4f71f7d..42cc31b 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -979,6 +979,8 @@ extern Vulkan_Demo* vulkan_demo; // // cvars // +extern cvar_t *r_renderAPI; +extern cvar_t *r_renderAPICompareWindow; extern cvar_t *r_flareSize; extern cvar_t *r_flareFade; diff --git a/src/engine/renderer/vk.cpp b/src/engine/renderer/vk.cpp index 1fa06d7..851890f 100644 --- a/src/engine/renderer/vk.cpp +++ b/src/engine/renderer/vk.cpp @@ -109,13 +109,13 @@ static VkPhysicalDevice select_physical_device(VkInstance instance) { return physical_devices[0]; // just get the first one } -static VkSurfaceKHR create_surface(VkInstance instance, const SDL_SysWMinfo& window_sys_info) { +static VkSurfaceKHR create_surface(VkInstance instance, HWND hwnd) { VkWin32SurfaceCreateInfoKHR desc; desc.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; desc.pNext = nullptr; desc.flags = 0; desc.hinstance = ::GetModuleHandle(nullptr); - desc.hwnd = window_sys_info.info.win.window; + desc.hwnd = hwnd; VkSurfaceKHR surface; VkResult result = vkCreateWin32SurfaceKHR(instance, &desc, nullptr, &surface); @@ -251,48 +251,53 @@ static VkSwapchainKHR create_swapchain(VkPhysicalDevice physical_device, VkDevic return swapchain; } -void initialize_vulkan(const SDL_SysWMinfo& window_sys_info) { - auto& g = vulkan_globals; +bool initialize_vulkan(HWND hwnd) { + try { + auto& g = vulkan_globals; - g.instance = create_instance(); - g.physical_device = select_physical_device(g.instance); - g.surface = create_surface(g.instance, window_sys_info); - g.queue_family_index = select_queue_family(g.physical_device, g.surface); - g.device = create_device(g.physical_device, g.queue_family_index); + g.instance = create_instance(); + g.physical_device = select_physical_device(g.instance); + g.surface = create_surface(g.instance, hwnd); + g.queue_family_index = select_queue_family(g.physical_device, g.surface); + g.device = create_device(g.physical_device, g.queue_family_index); - vkGetDeviceQueue(g.device, g.queue_family_index, 0, &g.queue); + vkGetDeviceQueue(g.device, g.queue_family_index, 0, &g.queue); - g.surface_format = select_surface_format(g.physical_device, g.surface); - g.swapchain = create_swapchain(g.physical_device, g.device, g.surface, g.surface_format); + g.surface_format = select_surface_format(g.physical_device, g.surface); + g.swapchain = create_swapchain(g.physical_device, g.device, g.surface, g.surface_format); - uint32_t image_count; - VkResult result = vkGetSwapchainImagesKHR(g.device, g.swapchain, &image_count, nullptr); - check_vk_result(result, "vkGetSwapchainImagesKHR"); - g.swapchain_images.resize(image_count); - result = vkGetSwapchainImagesKHR(g.device, g.swapchain, &image_count, g.swapchain_images.data()); - check_vk_result(result, "vkGetSwapchainImagesKHR"); + uint32_t image_count; + VkResult result = vkGetSwapchainImagesKHR(g.device, g.swapchain, &image_count, nullptr); + check_vk_result(result, "vkGetSwapchainImagesKHR"); + g.swapchain_images.resize(image_count); + result = vkGetSwapchainImagesKHR(g.device, g.swapchain, &image_count, g.swapchain_images.data()); + check_vk_result(result, "vkGetSwapchainImagesKHR"); - g.swapchain_image_views.resize(image_count); - for (std::size_t i = 0; i < image_count; i++) { - VkImageViewCreateInfo desc; - desc.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - desc.pNext = nullptr; - desc.flags = 0; - desc.image = g.swapchain_images[i]; - desc.viewType = VK_IMAGE_VIEW_TYPE_2D; - desc.format = g.surface_format.format; - desc.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; - desc.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; - desc.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; - desc.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; - desc.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - desc.subresourceRange.baseMipLevel = 0; - desc.subresourceRange.levelCount = 1; - desc.subresourceRange.baseArrayLayer = 0; - desc.subresourceRange.layerCount = 1; - result = vkCreateImageView(g.device, &desc, nullptr, &g.swapchain_image_views[i]); - check_vk_result(result, "vkCreateImageView"); + g.swapchain_image_views.resize(image_count); + for (std::size_t i = 0; i < image_count; i++) { + VkImageViewCreateInfo desc; + desc.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + desc.pNext = nullptr; + desc.flags = 0; + desc.image = g.swapchain_images[i]; + desc.viewType = VK_IMAGE_VIEW_TYPE_2D; + desc.format = g.surface_format.format; + desc.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; + desc.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; + desc.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; + desc.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; + desc.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + desc.subresourceRange.baseMipLevel = 0; + desc.subresourceRange.levelCount = 1; + desc.subresourceRange.baseArrayLayer = 0; + desc.subresourceRange.layerCount = 1; + result = vkCreateImageView(g.device, &desc, nullptr, &g.swapchain_image_views[i]); + check_vk_result(result, "vkCreateImageView"); + } + } catch (const std::exception&) { + return false; } + return true; } void deinitialize_vulkan() { diff --git a/src/engine/renderer/vk.h b/src/engine/renderer/vk.h index c1d095b..bc099f9 100644 --- a/src/engine/renderer/vk.h +++ b/src/engine/renderer/vk.h @@ -9,9 +9,7 @@ #include -struct SDL_SysWMinfo; - -void initialize_vulkan(const SDL_SysWMinfo& window_sys_info); +bool initialize_vulkan(HWND hwnd); void deinitialize_vulkan(); VkPhysicalDevice get_physical_device(); diff --git a/src/engine/renderer/vk_demo.cpp b/src/engine/renderer/vk_demo.cpp index d979b05..699fc5a 100644 --- a/src/engine/renderer/vk_demo.cpp +++ b/src/engine/renderer/vk_demo.cpp @@ -111,13 +111,11 @@ static VkFormat find_depth_format(VkPhysicalDevice physical_device) { FILE* logfile; -Vulkan_Demo::Vulkan_Demo(int window_width, int window_height, const SDL_SysWMinfo& window_sys_info) +Vulkan_Demo::Vulkan_Demo(int window_width, int window_height) : window_width(window_width) , window_height(window_height) { logfile = fopen("vk_dev.log", "w"); - - initialize_vulkan(window_sys_info); get_allocator()->initialize(get_physical_device(), get_device()); get_resource_manager()->initialize(get_device()); create_command_pool(); diff --git a/src/engine/renderer/vk_demo.h b/src/engine/renderer/vk_demo.h index d7afd6d..ed62e01 100644 --- a/src/engine/renderer/vk_demo.h +++ b/src/engine/renderer/vk_demo.h @@ -11,7 +11,7 @@ struct SDL_SysWMinfo; class Vulkan_Demo { public: - Vulkan_Demo(int window_width, int window_height, const SDL_SysWMinfo& window_sys_info); + Vulkan_Demo(int window_width, int window_height); ~Vulkan_Demo(); void begin_frame();