New cvars: r_renderAPI , r_renderAPICompareWindow.
r_renderAPI specifies rendering API to use (0 - opengl, 1 - vulkan). r_renderAPICompareWindow shows additional window which does the same rendering as the main windows but uses different graphics API. The idea is to use r_renderAPICompareWindow for debugging to be sure that both APIs render identical/similar pictures.
This commit is contained in:
parent
dd372cad1b
commit
e9b972d562
|
|
@ -1,7 +1,7 @@
|
||||||
Removed cvars:
|
Removed cvars:
|
||||||
* r_allowExtensions
|
* r_allowExtensions (always use extensions if available)
|
||||||
* r_allowSoftwareGL
|
* r_allowSoftwareGL
|
||||||
* r_colorbits (use desktop color depth by default)
|
* r_colorbits (use desktop color depth)
|
||||||
* r_ext_multitexture (mandatory feature)
|
* r_ext_multitexture (required)
|
||||||
* r_maskMinidriver
|
* r_maskMinidriver
|
||||||
* r_primitives (always use qglDrawElements)
|
* r_primitives (always use qglDrawElements)
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,6 @@ typedef struct
|
||||||
|
|
||||||
HINSTANCE hinstOpenGL; // HINSTANCE for the OpenGL library
|
HINSTANCE hinstOpenGL; // HINSTANCE for the OpenGL library
|
||||||
|
|
||||||
qboolean pixelFormatSet;
|
|
||||||
|
|
||||||
int desktopBitsPixel;
|
int desktopBitsPixel;
|
||||||
int desktopWidth, desktopHeight;
|
int desktopWidth, desktopHeight;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,13 +47,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#include "sdl/SDL.h"
|
#include "sdl/SDL.h"
|
||||||
#include "sdl/SDL_syswm.h"
|
#include "sdl/SDL_syswm.h"
|
||||||
|
|
||||||
|
|
||||||
extern void WG_CheckHardwareGamma( void );
|
extern void WG_CheckHardwareGamma( void );
|
||||||
extern void WG_RestoreGamma( 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
|
// function declaration
|
||||||
|
|
@ -202,7 +203,7 @@ static int GLW_ChoosePixelFormat(HDC hDC, const PIXELFORMATDESCRIPTOR *pPFD)
|
||||||
return bestMatch;
|
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 =
|
const PIXELFORMATDESCRIPTOR pfd_base =
|
||||||
{
|
{
|
||||||
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
|
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
|
||||||
|
|
@ -237,55 +238,49 @@ static bool GLW_SetPixelFormat(PIXELFORMATDESCRIPTOR *pPFD, int colorbits, int d
|
||||||
pPFD->dwFlags |= PFD_STEREO;
|
pPFD->dwFlags |= PFD_STEREO;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pixelformat = GLW_ChoosePixelFormat(glw_state.hDC, pPFD);
|
int pixelformat = GLW_ChoosePixelFormat(hdc, pPFD);
|
||||||
if (pixelformat == 0) {
|
if (pixelformat == 0) {
|
||||||
ri.Printf( PRINT_ALL, "...GLW_ChoosePixelFormat failed\n");
|
ri.Printf( PRINT_ALL, "...GLW_ChoosePixelFormat failed\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ri.Printf( PRINT_ALL, "...PIXELFORMAT %d selected\n", pixelformat );
|
ri.Printf( PRINT_ALL, "...PIXELFORMAT %d selected\n", pixelformat );
|
||||||
|
|
||||||
DescribePixelFormat( glw_state.hDC, pixelformat, sizeof( *pPFD ), pPFD );
|
DescribePixelFormat(hdc, pixelformat, sizeof( *pPFD ), pPFD);
|
||||||
if (SetPixelFormat( glw_state.hDC, pixelformat, pPFD ) == FALSE) {
|
if (SetPixelFormat(hdc, pixelformat, pPFD ) == FALSE) {
|
||||||
ri.Printf (PRINT_ALL, "...SetPixelFormat failed\n", glw_state.hDC);
|
ri.Printf (PRINT_ALL, "...SetPixelFormat failed\n", hdc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sets pixel format and creates opengl context for the given window.
|
||||||
// Sets pixel format and creates opengl context.
|
static qboolean GLW_InitDriver(HWND hwnd) {
|
||||||
static qboolean GLW_InitDriver() {
|
|
||||||
|
|
||||||
ri.Printf( PRINT_ALL, "Initializing OpenGL driver\n" );
|
ri.Printf( PRINT_ALL, "Initializing OpenGL driver\n" );
|
||||||
|
|
||||||
//
|
glw_state.hDC = NULL;
|
||||||
// get a DC for our window if we don't already have one allocated
|
glw_state.hGLRC = NULL;
|
||||||
//
|
|
||||||
if (glw_state.hDC == NULL) {
|
|
||||||
ri.Printf( PRINT_ALL, "...getting DC: " );
|
|
||||||
|
|
||||||
glw_state.hDC = GetDC(g_wv.hWnd);
|
//
|
||||||
if (glw_state.hDC == NULL ) {
|
// get a DC for our window
|
||||||
ri.Printf( PRINT_ALL, "failed\n" );
|
//
|
||||||
|
ri.Printf(PRINT_ALL, "...getting DC: ");
|
||||||
|
HDC hdc = GetDC(hwnd);
|
||||||
|
if (hdc == NULL) {
|
||||||
|
ri.Printf(PRINT_ALL, "failed\n");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
ri.Printf( PRINT_ALL, "succeeded\n" );
|
ri.Printf(PRINT_ALL, "succeeded\n");
|
||||||
}
|
|
||||||
|
|
||||||
int colorbits = glw_state.desktopBitsPixel;
|
|
||||||
int depthbits = (r_depthbits->integer == 0) ? 24 : r_depthbits->integer;
|
|
||||||
int stencilbits = r_stencilbits->integer;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// set pixel format
|
// 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;
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
if (!glw_state.pixelFormatSet) {
|
if (!GLW_SetPixelFormat(hdc, &pfd, colorbits, depthbits, stencilbits, (qboolean)r_stereo->integer)) {
|
||||||
|
ReleaseDC(hwnd, hdc);
|
||||||
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");
|
ri.Printf(PRINT_ALL, "...failed to find an appropriate PIXELFORMAT\n");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
|
|
@ -295,34 +290,33 @@ static qboolean GLW_InitDriver() {
|
||||||
ri.Printf(PRINT_ALL, "...failed to select stereo pixel format\n");
|
ri.Printf(PRINT_ALL, "...failed to select stereo pixel format\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
glw_state.pixelFormatSet = qtrue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// startup the OpenGL subsystem by creating a context and making it current
|
// startup the OpenGL subsystem by creating a context and making it current
|
||||||
//
|
//
|
||||||
if (!glw_state.hGLRC) {
|
|
||||||
ri.Printf(PRINT_ALL, "...creating GL context: ");
|
ri.Printf(PRINT_ALL, "...creating GL context: ");
|
||||||
glw_state.hGLRC = qwglCreateContext(glw_state.hDC);
|
HGLRC hglrc = qwglCreateContext(hdc);
|
||||||
if (glw_state.hGLRC == NULL) {
|
if (hglrc == NULL) {
|
||||||
|
ReleaseDC(hwnd, hdc);
|
||||||
ri.Printf(PRINT_ALL, "failed\n");
|
ri.Printf(PRINT_ALL, "failed\n");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
ri.Printf(PRINT_ALL, "succeeded\n");
|
ri.Printf(PRINT_ALL, "succeeded\n");
|
||||||
|
|
||||||
ri.Printf(PRINT_ALL, "...making context current: ");
|
ri.Printf(PRINT_ALL, "...making context current: ");
|
||||||
if (!qwglMakeCurrent(glw_state.hDC, glw_state.hGLRC)) {
|
if (!qwglMakeCurrent(hdc, hglrc)) {
|
||||||
qwglDeleteContext(glw_state.hGLRC);
|
qwglDeleteContext(hglrc);
|
||||||
glw_state.hGLRC = NULL;
|
ReleaseDC(hwnd, hdc);
|
||||||
ri.Printf(PRINT_ALL, "failed\n");
|
ri.Printf(PRINT_ALL, "failed\n");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
ri.Printf(PRINT_ALL, "succeeded\n");
|
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.colorBits = ( int ) pfd.cColorBits;
|
||||||
glConfig.depthBits = ( int ) pfd.cDepthBits;
|
glConfig.depthBits = ( int ) pfd.cDepthBits;
|
||||||
glConfig.stencilBits = ( int ) pfd.cStencilBits;
|
glConfig.stencilBits = ( int ) pfd.cStencilBits;
|
||||||
|
|
@ -331,12 +325,12 @@ static qboolean GLW_InitDriver() {
|
||||||
return qtrue;
|
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
|
// register the window class if necessary
|
||||||
//
|
//
|
||||||
if ( !s_classRegistered )
|
if (!s_main_window_class_registered)
|
||||||
{
|
{
|
||||||
WNDCLASS wc;
|
WNDCLASS wc;
|
||||||
|
|
||||||
|
|
@ -351,21 +345,16 @@ static void GLW_CreateWindow(int width, int height, qboolean fullscreen)
|
||||||
wc.hCursor = LoadCursor (NULL,IDC_ARROW);
|
wc.hCursor = LoadCursor (NULL,IDC_ARROW);
|
||||||
wc.hbrBackground = (HBRUSH) (void *)COLOR_GRAYTEXT;
|
wc.hbrBackground = (HBRUSH) (void *)COLOR_GRAYTEXT;
|
||||||
wc.lpszMenuName = 0;
|
wc.lpszMenuName = 0;
|
||||||
wc.lpszClassName = WINDOW_CLASS_NAME;
|
wc.lpszClassName = MAIN_WINDOW_CLASS_NAME;
|
||||||
|
|
||||||
if ( !RegisterClass( &wc ) )
|
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" );
|
ri.Printf( PRINT_ALL, "...registered window class\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// create the HWND if one does not already exist
|
|
||||||
//
|
|
||||||
if ( !g_wv.hWnd )
|
|
||||||
{
|
|
||||||
//
|
//
|
||||||
// compute width and height
|
// compute width and height
|
||||||
//
|
//
|
||||||
|
|
@ -420,9 +409,9 @@ static void GLW_CreateWindow(int width, int height, qboolean fullscreen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_wv.hWnd = CreateWindowEx (
|
HWND hwnd = CreateWindowEx(
|
||||||
0,
|
0,
|
||||||
WINDOW_CLASS_NAME,
|
MAIN_WINDOW_CLASS_NAME,
|
||||||
"Quake 3: Arena",
|
"Quake 3: Arena",
|
||||||
stylebits,
|
stylebits,
|
||||||
x, y, w, h,
|
x, y, w, h,
|
||||||
|
|
@ -431,19 +420,108 @@ static void GLW_CreateWindow(int width, int height, qboolean fullscreen)
|
||||||
g_wv.hInstance,
|
g_wv.hInstance,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if ( !g_wv.hWnd )
|
if (!hwnd)
|
||||||
{
|
{
|
||||||
ri.Error (ERR_FATAL, "GLW_CreateWindow() - Couldn't create window");
|
ri.Error (ERR_FATAL, "create_main_window() - Couldn't create window");
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowWindow( g_wv.hWnd, SW_SHOW );
|
ShowWindow(hwnd, SW_SHOW);
|
||||||
UpdateWindow( g_wv.hWnd );
|
UpdateWindow(hwnd);
|
||||||
ri.Printf( PRINT_ALL, "...created window@%d,%d (%dx%d)\n", x, y, w, h );
|
ri.Printf(PRINT_ALL, "...created window@%d,%d (%dx%d)\n", x, y, w, h);
|
||||||
}
|
return hwnd;
|
||||||
else
|
}
|
||||||
|
|
||||||
|
static HWND create_api_compare_window(int width, int height)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// register the window class if necessary
|
||||||
|
//
|
||||||
|
if (!s_api_compare_window_class_registered)
|
||||||
{
|
{
|
||||||
ri.Printf( PRINT_ALL, "...window already present, CreateWindowEx skipped\n" );
|
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;
|
glConfig.isFullscreen = fullscreen;
|
||||||
ri.Printf( PRINT_ALL, " %d %d %s\n", glConfig.vidWidth, glConfig.vidHeight, fullscreen ? "FS" : "W");
|
ri.Printf( PRINT_ALL, " %d %d %s\n", glConfig.vidWidth, glConfig.vidHeight, fullscreen ? "FS" : "W");
|
||||||
|
|
||||||
GLW_CreateWindow(glConfig.vidWidth, glConfig.vidHeight, fullscreen);
|
|
||||||
|
|
||||||
if (!GLW_InitDriver()) {
|
|
||||||
ShowWindow(g_wv.hWnd, SW_HIDE);
|
|
||||||
DestroyWindow(g_wv.hWnd);
|
|
||||||
g_wv.hWnd = NULL;
|
g_wv.hWnd = NULL;
|
||||||
|
g_wv.hWnd_opengl = NULL;
|
||||||
|
g_wv.hWnd_vulkan = NULL;
|
||||||
|
|
||||||
|
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;
|
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);
|
SetForegroundWindow(g_wv.hWnd);
|
||||||
SetFocus(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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -700,66 +805,60 @@ void GLimp_Init( void )
|
||||||
*/
|
*/
|
||||||
void GLimp_Shutdown( void )
|
void GLimp_Shutdown( void )
|
||||||
{
|
{
|
||||||
// const char *strings[] = { "soft", "hard" };
|
|
||||||
const char *success[] = { "failed", "success" };
|
const char *success[] = { "failed", "success" };
|
||||||
int retVal;
|
int retVal;
|
||||||
|
|
||||||
// FIXME: Brian, we need better fallbacks from partially initialized failures
|
ri.Printf(PRINT_ALL, "Shutting down OpenGL subsystem\n");
|
||||||
if ( !qwglMakeCurrent ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ri.Printf( PRINT_ALL, "Shutting down OpenGL subsystem\n" );
|
|
||||||
|
|
||||||
// restore gamma. We do this first because 3Dfx's extension needs a valid OGL subsystem
|
// restore gamma. We do this first because 3Dfx's extension needs a valid OGL subsystem
|
||||||
WG_RestoreGamma();
|
WG_RestoreGamma();
|
||||||
|
|
||||||
// set current context to NULL
|
// set current context to NULL
|
||||||
if ( qwglMakeCurrent )
|
if (qwglMakeCurrent) {
|
||||||
{
|
retVal = qwglMakeCurrent(NULL, NULL) != 0;
|
||||||
retVal = qwglMakeCurrent( NULL, NULL ) != 0;
|
ri.Printf(PRINT_ALL, "...wglMakeCurrent( NULL, NULL ): %s\n", success[retVal]);
|
||||||
|
|
||||||
ri.Printf( PRINT_ALL, "...wglMakeCurrent( NULL, NULL ): %s\n", success[retVal] );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete HGLRC
|
// delete HGLRC
|
||||||
if ( glw_state.hGLRC )
|
if (glw_state.hGLRC) {
|
||||||
{
|
retVal = qwglDeleteContext(glw_state.hGLRC) != 0;
|
||||||
retVal = qwglDeleteContext( glw_state.hGLRC ) != 0;
|
ri.Printf(PRINT_ALL, "...deleting GL context: %s\n", success[retVal]);
|
||||||
ri.Printf( PRINT_ALL, "...deleting GL context: %s\n", success[retVal] );
|
|
||||||
glw_state.hGLRC = NULL;
|
glw_state.hGLRC = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// release DC
|
// release DC
|
||||||
if ( glw_state.hDC )
|
if (glw_state.hDC) {
|
||||||
{
|
retVal = ReleaseDC(g_wv.hWnd_opengl, glw_state.hDC) != 0;
|
||||||
retVal = ReleaseDC( g_wv.hWnd, glw_state.hDC ) != 0;
|
ri.Printf(PRINT_ALL, "...releasing DC: %s\n", success[retVal]);
|
||||||
ri.Printf( PRINT_ALL, "...releasing DC: %s\n", success[retVal] );
|
|
||||||
glw_state.hDC = NULL;
|
glw_state.hDC = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// destroy window
|
// destroy window
|
||||||
if ( g_wv.hWnd )
|
if (g_wv.hWnd_opengl) {
|
||||||
{
|
ri.Printf(PRINT_ALL, "...destroying opengl window\n");
|
||||||
ri.Printf( PRINT_ALL, "...destroying window\n" );
|
ShowWindow(g_wv.hWnd_opengl, SW_HIDE);
|
||||||
ShowWindow( g_wv.hWnd, SW_HIDE );
|
DestroyWindow(g_wv.hWnd_opengl);
|
||||||
DestroyWindow( g_wv.hWnd );
|
g_wv.hWnd_opengl = NULL;
|
||||||
g_wv.hWnd = NULL;
|
|
||||||
glw_state.pixelFormatSet = qfalse;
|
|
||||||
}
|
}
|
||||||
|
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
|
// close the r_logFile
|
||||||
if ( glw_state.log_fp )
|
if (glw_state.log_fp) {
|
||||||
{
|
fclose(glw_state.log_fp);
|
||||||
fclose( glw_state.log_fp );
|
|
||||||
glw_state.log_fp = 0;
|
glw_state.log_fp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// shutdown QGL subsystem
|
// shutdown QGL subsystem
|
||||||
QGL_Shutdown();
|
QGL_Shutdown();
|
||||||
|
|
||||||
memset( &glConfig, 0, sizeof( glConfig ) );
|
memset(&glConfig, 0, sizeof(glConfig));
|
||||||
memset( &glState, 0, sizeof( glState ) );
|
memset(&glState, 0, sizeof(glState));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,11 @@ typedef struct
|
||||||
HINSTANCE reflib_library; // Handle to refresh DLL
|
HINSTANCE reflib_library; // Handle to refresh DLL
|
||||||
qboolean reflib_active;
|
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;
|
HINSTANCE hInstance;
|
||||||
qboolean activeApp;
|
qboolean activeApp;
|
||||||
qboolean isMinimized;
|
qboolean isMinimized;
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,9 @@ glstate_t glState;
|
||||||
|
|
||||||
static void GfxInfo_f( void );
|
static void GfxInfo_f( void );
|
||||||
|
|
||||||
|
cvar_t *r_renderAPI;
|
||||||
|
cvar_t *r_renderAPICompareWindow;
|
||||||
|
|
||||||
cvar_t *r_flareSize;
|
cvar_t *r_flareSize;
|
||||||
cvar_t *r_flareFade;
|
cvar_t *r_flareFade;
|
||||||
|
|
||||||
|
|
@ -794,6 +797,9 @@ R_Register
|
||||||
*/
|
*/
|
||||||
void R_Register( void )
|
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
|
// latched and archived variables
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -979,6 +979,8 @@ extern Vulkan_Demo* vulkan_demo;
|
||||||
//
|
//
|
||||||
// cvars
|
// cvars
|
||||||
//
|
//
|
||||||
|
extern cvar_t *r_renderAPI;
|
||||||
|
extern cvar_t *r_renderAPICompareWindow;
|
||||||
extern cvar_t *r_flareSize;
|
extern cvar_t *r_flareSize;
|
||||||
extern cvar_t *r_flareFade;
|
extern cvar_t *r_flareFade;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -109,13 +109,13 @@ static VkPhysicalDevice select_physical_device(VkInstance instance) {
|
||||||
return physical_devices[0]; // just get the first one
|
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;
|
VkWin32SurfaceCreateInfoKHR desc;
|
||||||
desc.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
|
desc.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
|
||||||
desc.pNext = nullptr;
|
desc.pNext = nullptr;
|
||||||
desc.flags = 0;
|
desc.flags = 0;
|
||||||
desc.hinstance = ::GetModuleHandle(nullptr);
|
desc.hinstance = ::GetModuleHandle(nullptr);
|
||||||
desc.hwnd = window_sys_info.info.win.window;
|
desc.hwnd = hwnd;
|
||||||
|
|
||||||
VkSurfaceKHR surface;
|
VkSurfaceKHR surface;
|
||||||
VkResult result = vkCreateWin32SurfaceKHR(instance, &desc, nullptr, &surface);
|
VkResult result = vkCreateWin32SurfaceKHR(instance, &desc, nullptr, &surface);
|
||||||
|
|
@ -251,12 +251,13 @@ static VkSwapchainKHR create_swapchain(VkPhysicalDevice physical_device, VkDevic
|
||||||
return swapchain;
|
return swapchain;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initialize_vulkan(const SDL_SysWMinfo& window_sys_info) {
|
bool initialize_vulkan(HWND hwnd) {
|
||||||
|
try {
|
||||||
auto& g = vulkan_globals;
|
auto& g = vulkan_globals;
|
||||||
|
|
||||||
g.instance = create_instance();
|
g.instance = create_instance();
|
||||||
g.physical_device = select_physical_device(g.instance);
|
g.physical_device = select_physical_device(g.instance);
|
||||||
g.surface = create_surface(g.instance, window_sys_info);
|
g.surface = create_surface(g.instance, hwnd);
|
||||||
g.queue_family_index = select_queue_family(g.physical_device, g.surface);
|
g.queue_family_index = select_queue_family(g.physical_device, g.surface);
|
||||||
g.device = create_device(g.physical_device, g.queue_family_index);
|
g.device = create_device(g.physical_device, g.queue_family_index);
|
||||||
|
|
||||||
|
|
@ -293,6 +294,10 @@ void initialize_vulkan(const SDL_SysWMinfo& window_sys_info) {
|
||||||
result = vkCreateImageView(g.device, &desc, nullptr, &g.swapchain_image_views[i]);
|
result = vkCreateImageView(g.device, &desc, nullptr, &g.swapchain_image_views[i]);
|
||||||
check_vk_result(result, "vkCreateImageView");
|
check_vk_result(result, "vkCreateImageView");
|
||||||
}
|
}
|
||||||
|
} catch (const std::exception&) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void deinitialize_vulkan() {
|
void deinitialize_vulkan() {
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,7 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
struct SDL_SysWMinfo;
|
bool initialize_vulkan(HWND hwnd);
|
||||||
|
|
||||||
void initialize_vulkan(const SDL_SysWMinfo& window_sys_info);
|
|
||||||
void deinitialize_vulkan();
|
void deinitialize_vulkan();
|
||||||
|
|
||||||
VkPhysicalDevice get_physical_device();
|
VkPhysicalDevice get_physical_device();
|
||||||
|
|
|
||||||
|
|
@ -111,13 +111,11 @@ static VkFormat find_depth_format(VkPhysicalDevice physical_device) {
|
||||||
|
|
||||||
FILE* logfile;
|
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_width(window_width)
|
||||||
, window_height(window_height)
|
, window_height(window_height)
|
||||||
{
|
{
|
||||||
logfile = fopen("vk_dev.log", "w");
|
logfile = fopen("vk_dev.log", "w");
|
||||||
|
|
||||||
initialize_vulkan(window_sys_info);
|
|
||||||
get_allocator()->initialize(get_physical_device(), get_device());
|
get_allocator()->initialize(get_physical_device(), get_device());
|
||||||
get_resource_manager()->initialize(get_device());
|
get_resource_manager()->initialize(get_device());
|
||||||
create_command_pool();
|
create_command_pool();
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ struct SDL_SysWMinfo;
|
||||||
|
|
||||||
class Vulkan_Demo {
|
class Vulkan_Demo {
|
||||||
public:
|
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();
|
~Vulkan_Demo();
|
||||||
|
|
||||||
void begin_frame();
|
void begin_frame();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user