Vulkan platform specific code reorganization.
This commit is contained in:
parent
8ad279e5b9
commit
5a5b0b4d2b
|
|
@ -1539,10 +1539,6 @@ void trap_CIN_SetExtents (int handle, int x, int y, int w, int h);
|
||||||
|
|
||||||
void trap_SnapVector( float *v );
|
void trap_SnapVector( float *v );
|
||||||
|
|
||||||
qboolean trap_loadCamera(const char *name);
|
|
||||||
void trap_startCamera(int time);
|
|
||||||
qboolean trap_getCameraInfo(int time, vec3_t *origin, vec3_t *angles);
|
|
||||||
|
|
||||||
qboolean trap_GetEntityToken( char *buffer, int bufferSize );
|
qboolean trap_GetEntityToken( char *buffer, int bufferSize );
|
||||||
|
|
||||||
void CG_ClearParticles (void);
|
void CG_ClearParticles (void);
|
||||||
|
|
|
||||||
|
|
@ -175,9 +175,6 @@ void S_PaintChannels(int endtime);
|
||||||
void S_memoryLoad(sfx_t *sfx);
|
void S_memoryLoad(sfx_t *sfx);
|
||||||
portable_samplepair_t *S_GetRawSamplePointer();
|
portable_samplepair_t *S_GetRawSamplePointer();
|
||||||
|
|
||||||
// spatializes a channel
|
|
||||||
void S_Spatialize(channel_t *ch);
|
|
||||||
|
|
||||||
// adpcm functions
|
// adpcm functions
|
||||||
int S_AdpcmMemoryNeeded( const wavinfo_t *info );
|
int S_AdpcmMemoryNeeded( const wavinfo_t *info );
|
||||||
void S_AdpcmEncodeSound( sfx_t *sfx, short *samples );
|
void S_AdpcmEncodeSound( sfx_t *sfx, short *samples );
|
||||||
|
|
|
||||||
|
|
@ -28,16 +28,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
WNDPROC wndproc;
|
|
||||||
|
|
||||||
HDC hDC; // handle to device context
|
|
||||||
HGLRC hGLRC; // handle to GL rendering context
|
|
||||||
|
|
||||||
HINSTANCE hinstOpenGL; // HINSTANCE for the OpenGL library
|
|
||||||
|
|
||||||
int desktopBitsPixel;
|
|
||||||
int desktopWidth, desktopHeight;
|
|
||||||
|
|
||||||
FILE *log_fp;
|
FILE *log_fp;
|
||||||
} glwstate_t;
|
} glwstate_t;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -123,18 +123,12 @@ void GLimp_SetGamma( unsigned char red[256], unsigned char green[256], unsigned
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HDC gamma_hdc = glw_state.hDC;
|
HDC hdc = GetDC(NULL);
|
||||||
if (gamma_hdc == NULL)
|
ret = SetDeviceGammaRamp( hdc, table );
|
||||||
gamma_hdc = GetDC(NULL);
|
|
||||||
|
|
||||||
ret = SetDeviceGammaRamp( gamma_hdc, table );
|
|
||||||
if ( !ret ) {
|
if ( !ret ) {
|
||||||
Com_Printf( "SetDeviceGammaRamp failed.\n" );
|
Com_Printf( "SetDeviceGammaRamp failed.\n" );
|
||||||
}
|
}
|
||||||
|
ReleaseDC(NULL, hdc);
|
||||||
if (glw_state.hDC == NULL)
|
|
||||||
ReleaseDC(NULL, gamma_hdc);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
** WIN_GLIMP.C
|
** WIN_GLIMP.C
|
||||||
**
|
**
|
||||||
** This file contains ALL Win32 specific stuff having to do with the
|
** This file contains ALL Win32 specific stuff having to do with the
|
||||||
** OpenGL refresh. When a port is being made the following functions
|
** OpenGL/Vulkan refresh. When a port is being made the following functions
|
||||||
** must be implemented by the port:
|
** must be implemented by the port:
|
||||||
**
|
**
|
||||||
** GLimp_EndFrame
|
** GLimp_EndFrame
|
||||||
|
|
@ -31,8 +31,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
** GLimp_LogComment
|
** GLimp_LogComment
|
||||||
** GLimp_Shutdown
|
** GLimp_Shutdown
|
||||||
**
|
**
|
||||||
** Note that the GLW_xxx functions are Windows specific GL-subsystem
|
** vk_imp_init
|
||||||
** related functions that are relevant ONLY to win_glimp.c
|
** vk_imp_shutdown
|
||||||
*/
|
*/
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "../renderer/tr_local.h"
|
#include "../renderer/tr_local.h"
|
||||||
|
|
@ -60,8 +60,21 @@ void QGL_Shutdown( void );
|
||||||
//
|
//
|
||||||
// variable declarations
|
// variable declarations
|
||||||
//
|
//
|
||||||
|
static HDC gl_hdc; // handle to device context
|
||||||
|
static HGLRC gl_hglrc; // handle to GL rendering context
|
||||||
|
|
||||||
glwstate_t glw_state;
|
glwstate_t glw_state;
|
||||||
|
|
||||||
|
static int GetDesktopCaps(int index) {
|
||||||
|
HDC hdc = GetDC(GetDesktopWindow());
|
||||||
|
int value = GetDeviceCaps(hdc, index);
|
||||||
|
ReleaseDC(GetDesktopWindow(), hdc);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
static int GetDesktopColorDepth() { return GetDesktopCaps(BITSPIXEL); }
|
||||||
|
static int GetDesktopWidth() { return GetDesktopCaps(HORZRES); }
|
||||||
|
static int GetDesktopHeight() { return GetDesktopCaps(VERTRES); }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** ChoosePFD
|
** ChoosePFD
|
||||||
**
|
**
|
||||||
|
|
@ -251,15 +264,12 @@ static bool GLW_SetPixelFormat(HDC hdc, PIXELFORMATDESCRIPTOR *pPFD, int colorbi
|
||||||
static qboolean GLW_InitDriver(HWND hwnd) {
|
static qboolean GLW_InitDriver(HWND hwnd) {
|
||||||
ri.Printf( PRINT_ALL, "Initializing OpenGL driver\n" );
|
ri.Printf( PRINT_ALL, "Initializing OpenGL driver\n" );
|
||||||
|
|
||||||
glw_state.hDC = NULL;
|
|
||||||
glw_state.hGLRC = NULL;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// get a DC for our window
|
// get a DC for our window
|
||||||
//
|
//
|
||||||
ri.Printf(PRINT_ALL, "...getting DC: ");
|
ri.Printf(PRINT_ALL, "...getting DC: ");
|
||||||
HDC hdc = GetDC(hwnd);
|
gl_hdc = GetDC(hwnd);
|
||||||
if (hdc == NULL) {
|
if (gl_hdc == NULL) {
|
||||||
ri.Printf(PRINT_ALL, "failed\n");
|
ri.Printf(PRINT_ALL, "failed\n");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
|
|
@ -268,13 +278,14 @@ static qboolean GLW_InitDriver(HWND hwnd) {
|
||||||
//
|
//
|
||||||
// set pixel format
|
// set pixel format
|
||||||
//
|
//
|
||||||
int colorbits = glw_state.desktopBitsPixel;
|
int colorbits = GetDesktopColorDepth();
|
||||||
int depthbits = (r_depthbits->integer == 0) ? 24 : r_depthbits->integer;
|
int depthbits = (r_depthbits->integer == 0) ? 24 : r_depthbits->integer;
|
||||||
int stencilbits = r_stencilbits->integer;
|
int stencilbits = r_stencilbits->integer;
|
||||||
|
|
||||||
PIXELFORMATDESCRIPTOR pfd;
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
if (!GLW_SetPixelFormat(hdc, &pfd, colorbits, depthbits, stencilbits, (qboolean)r_stereo->integer)) {
|
if (!GLW_SetPixelFormat(gl_hdc, &pfd, colorbits, depthbits, stencilbits, (qboolean)r_stereo->integer)) {
|
||||||
ReleaseDC(hwnd, hdc);
|
ReleaseDC(hwnd, gl_hdc);
|
||||||
|
gl_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;
|
||||||
}
|
}
|
||||||
|
|
@ -288,34 +299,30 @@ static qboolean GLW_InitDriver(HWND hwnd) {
|
||||||
// startup the OpenGL subsystem by creating a context and making it current
|
// startup the OpenGL subsystem by creating a context and making it current
|
||||||
//
|
//
|
||||||
ri.Printf(PRINT_ALL, "...creating GL context: ");
|
ri.Printf(PRINT_ALL, "...creating GL context: ");
|
||||||
HGLRC hglrc = qwglCreateContext(hdc);
|
gl_hglrc = qwglCreateContext(gl_hdc);
|
||||||
if (hglrc == NULL) {
|
if (gl_hglrc == NULL) {
|
||||||
ReleaseDC(hwnd, hdc);
|
ReleaseDC(hwnd, gl_hdc);
|
||||||
|
gl_hdc = NULL;
|
||||||
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(hdc, hglrc)) {
|
if (!qwglMakeCurrent(gl_hdc, gl_hglrc)) {
|
||||||
qwglDeleteContext(hglrc);
|
qwglDeleteContext(gl_hglrc);
|
||||||
ReleaseDC(hwnd, hdc);
|
gl_hglrc = NULL;
|
||||||
|
ReleaseDC(hwnd, gl_hdc);
|
||||||
|
gl_hdc = NULL;
|
||||||
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");
|
||||||
|
|
||||||
//
|
|
||||||
// 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;
|
||||||
glConfig.stereoEnabled = (pfd.dwFlags & PFD_STEREO) ? qtrue : qfalse;
|
glConfig.stereoEnabled = (pfd.dwFlags & PFD_STEREO) ? qtrue : qfalse;
|
||||||
|
|
||||||
return qtrue;
|
return qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -326,12 +333,16 @@ static HWND create_main_window(int width, int height, qboolean fullscreen)
|
||||||
//
|
//
|
||||||
if (!s_main_window_class_registered)
|
if (!s_main_window_class_registered)
|
||||||
{
|
{
|
||||||
|
cvar_t* cv = ri.Cvar_Get( "win_wndproc", "", 0 );
|
||||||
|
WNDPROC wndproc;
|
||||||
|
sscanf(cv->string, "%p", (void **)&wndproc);
|
||||||
|
|
||||||
WNDCLASS wc;
|
WNDCLASS wc;
|
||||||
|
|
||||||
memset( &wc, 0, sizeof( wc ) );
|
memset( &wc, 0, sizeof( wc ) );
|
||||||
|
|
||||||
wc.style = 0;
|
wc.style = 0;
|
||||||
wc.lpfnWndProc = glw_state.wndproc;
|
wc.lpfnWndProc = wndproc;
|
||||||
wc.cbClsExtra = 0;
|
wc.cbClsExtra = 0;
|
||||||
wc.cbWndExtra = 0;
|
wc.cbWndExtra = 0;
|
||||||
wc.hInstance = g_wv.hInstance;
|
wc.hInstance = g_wv.hInstance;
|
||||||
|
|
@ -393,13 +404,15 @@ static HWND create_main_window(int width, int height, qboolean fullscreen)
|
||||||
if ( y < 0 )
|
if ( y < 0 )
|
||||||
y = 0;
|
y = 0;
|
||||||
|
|
||||||
if ( w < glw_state.desktopWidth &&
|
int desktop_width = GetDesktopWidth();
|
||||||
h < glw_state.desktopHeight )
|
int desktop_height = GetDesktopHeight();
|
||||||
|
|
||||||
|
if (w < desktop_width && h < desktop_height)
|
||||||
{
|
{
|
||||||
if ( x + w > glw_state.desktopWidth )
|
if ( x + w > desktop_width )
|
||||||
x = ( glw_state.desktopWidth - w );
|
x = ( desktop_width - w );
|
||||||
if ( y + h > glw_state.desktopHeight )
|
if ( y + h > desktop_height )
|
||||||
y = ( glw_state.desktopHeight - h );
|
y = ( desktop_height - h );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -482,13 +495,15 @@ static HWND create_api_compare_window(int width, int height)
|
||||||
if ( y < 0 )
|
if ( y < 0 )
|
||||||
y = 0;
|
y = 0;
|
||||||
|
|
||||||
if ( w < glw_state.desktopWidth &&
|
int desktop_width = GetDesktopWidth();
|
||||||
h < glw_state.desktopHeight )
|
int desktop_height = GetDesktopHeight();
|
||||||
|
|
||||||
|
if (w < desktop_width && h < desktop_height)
|
||||||
{
|
{
|
||||||
if ( x + w > glw_state.desktopWidth )
|
if ( x + w > desktop_width )
|
||||||
x = ( glw_state.desktopWidth - w );
|
x = ( desktop_width - w );
|
||||||
if ( y + h > glw_state.desktopHeight )
|
if ( y + h > desktop_height )
|
||||||
y = ( glw_state.desktopHeight - h );
|
y = ( desktop_height - h );
|
||||||
}
|
}
|
||||||
|
|
||||||
// If r_renderAPI = 0 (OpenGL) then compare window uses Vulkan API.
|
// If r_renderAPI = 0 (OpenGL) then compare window uses Vulkan API.
|
||||||
|
|
@ -518,86 +533,21 @@ static HWND create_api_compare_window(int width, int height)
|
||||||
return hwnd;
|
return hwnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void SetMode(int mode, qboolean fullscreen) {
|
||||||
** GLW_SetMode
|
|
||||||
*/
|
|
||||||
static bool GLW_SetMode(int mode, qboolean fullscreen) {
|
|
||||||
{
|
|
||||||
HDC hDC = GetDC(GetDesktopWindow());
|
|
||||||
glw_state.desktopBitsPixel = GetDeviceCaps(hDC, BITSPIXEL);
|
|
||||||
glw_state.desktopWidth = GetDeviceCaps(hDC, HORZRES);
|
|
||||||
glw_state.desktopHeight = GetDeviceCaps(hDC, VERTRES);
|
|
||||||
ReleaseDC(GetDesktopWindow(), hDC);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fullscreen) {
|
if (fullscreen) {
|
||||||
ri.Printf( PRINT_ALL, "...setting fullscreen mode:");
|
ri.Printf( PRINT_ALL, "...setting fullscreen mode:");
|
||||||
glConfig.vidWidth = glw_state.desktopWidth;
|
glConfig.vidWidth = GetDesktopWidth();
|
||||||
glConfig.vidHeight = glw_state.desktopHeight;
|
glConfig.vidHeight = GetDesktopHeight();
|
||||||
glConfig.windowAspect = 1.0f;
|
glConfig.windowAspect = 1.0f;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
ri.Printf( PRINT_ALL, "...setting mode %d:", mode );
|
ri.Printf( PRINT_ALL, "...setting mode %d:", mode );
|
||||||
if (!R_GetModeInfo(&glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode)) {
|
if (!R_GetModeInfo(&glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode)) {
|
||||||
ri.Printf( PRINT_ALL, " invalid mode\n" );
|
ri.Printf( PRINT_ALL, " invalid mode\n" );
|
||||||
return false;
|
ri.Error(ERR_FATAL, "SetMode - could not set the given mode (%d)\n", mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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");
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
g_wv.hWnd = hwnd;
|
|
||||||
g_wv.hWnd_opengl = hwnd;
|
|
||||||
|
|
||||||
if (r_renderAPICompareWindow->integer) {
|
|
||||||
HWND hwnd2 = create_api_compare_window(glConfig.vidWidth, glConfig.vidHeight);
|
|
||||||
vk_create_instance(hwnd2);
|
|
||||||
g_wv.hWnd_vulkan = hwnd2;
|
|
||||||
/*if (!vk_initialize(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;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
} else { // vulkan
|
|
||||||
if (r_renderAPICompareWindow->integer) {
|
|
||||||
HWND hwnd2 = create_api_compare_window(glConfig.vidWidth, glConfig.vidHeight);
|
|
||||||
if (!GLW_InitDriver(hwnd2)) {
|
|
||||||
DestroyWindow(hwnd2);
|
|
||||||
ri.Printf(PRINT_WARNING, "GLW_SetMode: could not create API compare window");
|
|
||||||
} else {
|
|
||||||
g_wv.hWnd_opengl = hwnd2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vk_create_instance(hwnd);
|
|
||||||
/*if (!vk_initialize(hwnd)) {
|
|
||||||
ShowWindow(hwnd, SW_HIDE);
|
|
||||||
DestroyWindow(hwnd);
|
|
||||||
return false;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
g_wv.hWnd = hwnd;
|
|
||||||
g_wv.hWnd_vulkan = hwnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetForegroundWindow(g_wv.hWnd);
|
|
||||||
SetFocus(g_wv.hWnd);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -605,12 +555,6 @@ static bool GLW_SetMode(int mode, qboolean fullscreen) {
|
||||||
*/
|
*/
|
||||||
static void GLW_InitExtensions( void )
|
static void GLW_InitExtensions( void )
|
||||||
{
|
{
|
||||||
if (!gl_active) {
|
|
||||||
qglActiveTextureARB = [] (GLenum) {};
|
|
||||||
qglClientActiveTextureARB = [](GLenum) {};
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ri.Printf( PRINT_ALL, "Initializing OpenGL extensions\n" );
|
ri.Printf( PRINT_ALL, "Initializing OpenGL extensions\n" );
|
||||||
|
|
||||||
// GL_S3_s3tc
|
// GL_S3_s3tc
|
||||||
|
|
@ -731,7 +675,7 @@ void GLimp_EndFrame (void)
|
||||||
// don't flip if drawing to front buffer
|
// don't flip if drawing to front buffer
|
||||||
if ( Q_stricmp( r_drawBuffer->string, "GL_FRONT" ) != 0 )
|
if ( Q_stricmp( r_drawBuffer->string, "GL_FRONT" ) != 0 )
|
||||||
{
|
{
|
||||||
SwapBuffers( glw_state.hDC );
|
SwapBuffers( gl_hdc );
|
||||||
}
|
}
|
||||||
|
|
||||||
// check logging
|
// check logging
|
||||||
|
|
@ -750,14 +694,8 @@ void GLimp_EndFrame (void)
|
||||||
*/
|
*/
|
||||||
void GLimp_Init( void )
|
void GLimp_Init( void )
|
||||||
{
|
{
|
||||||
cvar_t *cv;
|
|
||||||
|
|
||||||
ri.Printf( PRINT_ALL, "Initializing OpenGL subsystem\n" );
|
ri.Printf( PRINT_ALL, "Initializing OpenGL subsystem\n" );
|
||||||
|
|
||||||
// save wndproc
|
|
||||||
cv = ri.Cvar_Get( "win_wndproc", "", 0 );
|
|
||||||
sscanf( cv->string, "%p", (void **)&glw_state.wndproc );
|
|
||||||
|
|
||||||
// load appropriate DLL and initialize subsystem
|
// load appropriate DLL and initialize subsystem
|
||||||
//
|
//
|
||||||
// load the driver and bind our function pointers to it
|
// load the driver and bind our function pointers to it
|
||||||
|
|
@ -767,12 +705,22 @@ void GLimp_Init( void )
|
||||||
ri.Error(ERR_FATAL, "QGL_Init - could not load OpenGL driver\n");
|
ri.Error(ERR_FATAL, "QGL_Init - could not load OpenGL driver\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the window and set up the context
|
SetMode(r_mode->integer, (qboolean)r_fullscreen->integer);
|
||||||
if (!GLW_SetMode(r_mode->integer, (qboolean)r_fullscreen->integer))
|
|
||||||
{
|
if (r_renderAPI->integer == 0) {
|
||||||
ri.Error(ERR_FATAL, "GLW_SetMode - could not set the given mode (%d)\n", r_mode->integer);
|
g_wv.hWnd_opengl = create_main_window(glConfig.vidWidth, glConfig.vidHeight, (qboolean)r_fullscreen->integer);
|
||||||
|
g_wv.hWnd = g_wv.hWnd_opengl;
|
||||||
|
} else {
|
||||||
|
g_wv.hWnd_opengl = create_api_compare_window(glConfig.vidWidth, glConfig.vidHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!GLW_InitDriver(g_wv.hWnd_opengl)) {
|
||||||
|
ri.Error(ERR_FATAL, "GLW_InitDriver - could not initialize OpenGL subsystem\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
SetForegroundWindow(g_wv.hWnd);
|
||||||
|
SetFocus(g_wv.hWnd);
|
||||||
|
|
||||||
// get our config strings
|
// get our config strings
|
||||||
Q_strncpyz( glConfig.vendor_string, (const char*) qglGetString (GL_VENDOR), sizeof( glConfig.vendor_string ) );
|
Q_strncpyz( glConfig.vendor_string, (const char*) qglGetString (GL_VENDOR), sizeof( glConfig.vendor_string ) );
|
||||||
Q_strncpyz(glConfig.renderer_string, (const char*)qglGetString(GL_RENDERER), sizeof(glConfig.renderer_string));
|
Q_strncpyz(glConfig.renderer_string, (const char*)qglGetString(GL_RENDERER), sizeof(glConfig.renderer_string));
|
||||||
|
|
@ -792,31 +740,24 @@ void GLimp_Init( void )
|
||||||
void GLimp_Shutdown( void )
|
void GLimp_Shutdown( void )
|
||||||
{
|
{
|
||||||
const char *success[] = { "failed", "success" };
|
const char *success[] = { "failed", "success" };
|
||||||
int retVal;
|
|
||||||
|
|
||||||
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) {
|
if (qwglMakeCurrent) {
|
||||||
retVal = qwglMakeCurrent(NULL, NULL) != 0;
|
int 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
|
if (gl_hglrc) {
|
||||||
if (glw_state.hGLRC) {
|
int retVal = qwglDeleteContext(gl_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;
|
gl_hglrc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// release DC
|
if (gl_hdc) {
|
||||||
if (glw_state.hDC) {
|
int retVal = ReleaseDC(g_wv.hWnd_opengl, gl_hdc) != 0;
|
||||||
retVal = ReleaseDC(g_wv.hWnd_opengl, 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;
|
gl_hdc = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// destroy window
|
// destroy window
|
||||||
|
|
@ -824,32 +765,26 @@ void GLimp_Shutdown( void )
|
||||||
ri.Printf(PRINT_ALL, "...destroying opengl window\n");
|
ri.Printf(PRINT_ALL, "...destroying opengl window\n");
|
||||||
ShowWindow(g_wv.hWnd_opengl, SW_HIDE);
|
ShowWindow(g_wv.hWnd_opengl, SW_HIDE);
|
||||||
DestroyWindow(g_wv.hWnd_opengl);
|
DestroyWindow(g_wv.hWnd_opengl);
|
||||||
g_wv.hWnd_opengl = NULL;
|
|
||||||
}
|
if (g_wv.hWnd == g_wv.hWnd_opengl)
|
||||||
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;
|
g_wv.hWnd = NULL;
|
||||||
|
|
||||||
// close the r_logFile
|
g_wv.hWnd_opengl = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGL_Shutdown();
|
||||||
|
|
||||||
|
WG_RestoreGamma();
|
||||||
|
|
||||||
|
memset(&glConfig, 0, sizeof(glConfig));
|
||||||
|
memset(&glState, 0, sizeof(glState));
|
||||||
|
|
||||||
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
|
|
||||||
QGL_Shutdown();
|
|
||||||
|
|
||||||
memset(&glConfig, 0, sizeof(glConfig));
|
|
||||||
memset(&glState, 0, sizeof(glState));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** GLimp_LogComment
|
|
||||||
*/
|
|
||||||
void GLimp_LogComment( char *comment )
|
void GLimp_LogComment( char *comment )
|
||||||
{
|
{
|
||||||
if ( glw_state.log_fp ) {
|
if ( glw_state.log_fp ) {
|
||||||
|
|
@ -857,6 +792,69 @@ void GLimp_LogComment( char *comment )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vk_imp_init() {
|
||||||
|
ri.Printf(PRINT_ALL, "Initializing Vulkan subsystem\n");
|
||||||
|
|
||||||
|
if (!gl_enabled) {
|
||||||
|
QGL_Init(nullptr); // this will set qgl pointers to no-op placeholders
|
||||||
|
qglActiveTextureARB = [] (GLenum) {};
|
||||||
|
qglClientActiveTextureARB = [](GLenum) {};
|
||||||
|
}
|
||||||
|
|
||||||
|
SetMode(r_mode->integer, (qboolean)r_fullscreen->integer);
|
||||||
|
|
||||||
|
if (r_renderAPI->integer != 0) {
|
||||||
|
g_wv.hWnd_vulkan = create_main_window(glConfig.vidWidth, glConfig.vidHeight, (qboolean)r_fullscreen->integer);
|
||||||
|
g_wv.hWnd = g_wv.hWnd_vulkan;
|
||||||
|
} else {
|
||||||
|
g_wv.hWnd_vulkan = create_api_compare_window(glConfig.vidWidth, glConfig.vidHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
// In order to create surface we need to create VkInstance first.
|
||||||
|
vk_create_instance();
|
||||||
|
|
||||||
|
// Create VkSurfaceKHR for Win32 platform.
|
||||||
|
VkWin32SurfaceCreateInfoKHR desc;
|
||||||
|
desc.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
|
||||||
|
desc.pNext = nullptr;
|
||||||
|
desc.flags = 0;
|
||||||
|
desc.hinstance = ::GetModuleHandle(nullptr);
|
||||||
|
desc.hwnd = g_wv.hWnd_vulkan;
|
||||||
|
VK_CHECK(vkCreateWin32SurfaceKHR(vk.instance, &desc, nullptr, &vk.surface));
|
||||||
|
|
||||||
|
SetForegroundWindow(g_wv.hWnd);
|
||||||
|
SetFocus(g_wv.hWnd);
|
||||||
|
|
||||||
|
WG_CheckHardwareGamma();
|
||||||
|
}
|
||||||
|
|
||||||
|
void vk_imp_shutdown() {
|
||||||
|
ri.Printf(PRINT_ALL, "Shutting down Vulkan subsystem\n");
|
||||||
|
|
||||||
|
if (g_wv.hWnd_vulkan) {
|
||||||
|
ri.Printf(PRINT_ALL, "...destroying vulkan window\n");
|
||||||
|
DestroyWindow(g_wv.hWnd_vulkan);
|
||||||
|
|
||||||
|
if (g_wv.hWnd == g_wv.hWnd_vulkan)
|
||||||
|
g_wv.hWnd = NULL;
|
||||||
|
|
||||||
|
g_wv.hWnd_vulkan = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For vulkan mode we still have qgl pointers initialized with placeholder values.
|
||||||
|
// Thus reset them the same way as we do in opengl mode.
|
||||||
|
QGL_Shutdown();
|
||||||
|
|
||||||
|
WG_RestoreGamma();
|
||||||
|
|
||||||
|
memset(&glConfig, 0, sizeof(glConfig));
|
||||||
|
memset(&glState, 0, sizeof(glState));
|
||||||
|
|
||||||
|
if (glw_state.log_fp) {
|
||||||
|
fclose(glw_state.log_fp);
|
||||||
|
glw_state.log_fp = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===========================================================
|
===========================================================
|
||||||
|
|
@ -876,7 +874,7 @@ void GLimp_RenderThreadWrapper( void ) {
|
||||||
glimpRenderThread();
|
glimpRenderThread();
|
||||||
|
|
||||||
// unbind the context before we die
|
// unbind the context before we die
|
||||||
qwglMakeCurrent( glw_state.hDC, NULL );
|
qwglMakeCurrent( gl_hdc, NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -915,7 +913,7 @@ static int wglErrors;
|
||||||
void *GLimp_RendererSleep( void ) {
|
void *GLimp_RendererSleep( void ) {
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
if ( !qwglMakeCurrent( glw_state.hDC, NULL ) ) {
|
if ( !qwglMakeCurrent( gl_hdc, NULL ) ) {
|
||||||
wglErrors++;
|
wglErrors++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -926,7 +924,7 @@ void *GLimp_RendererSleep( void ) {
|
||||||
|
|
||||||
WaitForSingleObject( renderCommandsEvent, INFINITE );
|
WaitForSingleObject( renderCommandsEvent, INFINITE );
|
||||||
|
|
||||||
if ( !qwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ) ) {
|
if ( !qwglMakeCurrent( gl_hdc, gl_hglrc ) ) {
|
||||||
wglErrors++;
|
wglErrors++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -945,7 +943,7 @@ void *GLimp_RendererSleep( void ) {
|
||||||
void GLimp_FrontEndSleep( void ) {
|
void GLimp_FrontEndSleep( void ) {
|
||||||
WaitForSingleObject( renderCompletedEvent, INFINITE );
|
WaitForSingleObject( renderCompletedEvent, INFINITE );
|
||||||
|
|
||||||
if ( !qwglMakeCurrent( glw_state.hDC, glw_state.hGLRC ) ) {
|
if ( !qwglMakeCurrent( gl_hdc, gl_hglrc ) ) {
|
||||||
wglErrors++;
|
wglErrors++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -954,7 +952,7 @@ void GLimp_FrontEndSleep( void ) {
|
||||||
void GLimp_WakeRenderer( void *data ) {
|
void GLimp_WakeRenderer( void *data ) {
|
||||||
smpData = data;
|
smpData = data;
|
||||||
|
|
||||||
if ( !qwglMakeCurrent( glw_state.hDC, NULL ) ) {
|
if ( !qwglMakeCurrent( gl_hdc, NULL ) ) {
|
||||||
wglErrors++;
|
wglErrors++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#include "../renderer/tr_local.h"
|
#include "../renderer/tr_local.h"
|
||||||
#include "glw_win.h"
|
#include "glw_win.h"
|
||||||
|
|
||||||
|
static HINSTANCE hinstOpenGL; // HINSTANCE for the OpenGL library
|
||||||
|
|
||||||
void QGL_EnableLogging( qboolean enable );
|
void QGL_EnableLogging( qboolean enable );
|
||||||
|
|
||||||
HGLRC ( WINAPI * qwglCreateContext)(HDC);
|
HGLRC ( WINAPI * qwglCreateContext)(HDC);
|
||||||
|
|
@ -664,15 +666,17 @@ static void APIENTRY logViewport(GLint x, GLint y, GLsizei width, GLsizei height
|
||||||
*/
|
*/
|
||||||
void QGL_Shutdown( void )
|
void QGL_Shutdown( void )
|
||||||
{
|
{
|
||||||
|
if (gl_enabled) {
|
||||||
ri.Printf( PRINT_ALL, "...shutting down QGL\n" );
|
ri.Printf( PRINT_ALL, "...shutting down QGL\n" );
|
||||||
|
|
||||||
if ( glw_state.hinstOpenGL )
|
if ( hinstOpenGL )
|
||||||
{
|
{
|
||||||
ri.Printf( PRINT_ALL, "...unloading OpenGL DLL\n" );
|
ri.Printf( PRINT_ALL, "...unloading OpenGL DLL\n" );
|
||||||
FreeLibrary( glw_state.hinstOpenGL );
|
FreeLibrary( hinstOpenGL );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glw_state.hinstOpenGL = NULL;
|
hinstOpenGL = NULL;
|
||||||
|
|
||||||
qglAlphaFunc = NULL;
|
qglAlphaFunc = NULL;
|
||||||
qglBegin = NULL;
|
qglBegin = NULL;
|
||||||
|
|
@ -734,7 +738,7 @@ void QGL_Shutdown( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
# pragma warning (disable : 4113 4133 4047 )
|
# pragma warning (disable : 4113 4133 4047 )
|
||||||
# define GPA( a ) (gl_active ? (void*)GetProcAddress(glw_state.hinstOpenGL, #a) : (void*)(&no ## a))
|
# define GPA( a ) (gl_enabled ? (void*)GetProcAddress(hinstOpenGL, #a) : (void*)(&no ## a))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** QGL_Init
|
** QGL_Init
|
||||||
|
|
@ -747,17 +751,19 @@ void QGL_Shutdown( void )
|
||||||
*/
|
*/
|
||||||
qboolean QGL_Init( const char *dllname )
|
qboolean QGL_Init( const char *dllname )
|
||||||
{
|
{
|
||||||
assert( glw_state.hinstOpenGL == 0 );
|
if (gl_enabled) {
|
||||||
|
assert( hinstOpenGL == 0 );
|
||||||
|
|
||||||
ri.Printf( PRINT_ALL, "...initializing QGL\n" );
|
ri.Printf( PRINT_ALL, "...initializing QGL\n" );
|
||||||
ri.Printf( PRINT_ALL, "...calling LoadLibrary('%s'): ", dllname );
|
ri.Printf( PRINT_ALL, "...calling LoadLibrary('%s'): ", dllname );
|
||||||
|
|
||||||
if ( ( glw_state.hinstOpenGL = LoadLibrary( dllname ) ) == 0 )
|
if ( ( hinstOpenGL = LoadLibrary( dllname ) ) == 0 )
|
||||||
{
|
{
|
||||||
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" );
|
||||||
|
}
|
||||||
|
|
||||||
qglAlphaFunc = dllAlphaFunc = (decltype(dllAlphaFunc))GPA(glAlphaFunc);
|
qglAlphaFunc = dllAlphaFunc = (decltype(dllAlphaFunc))GPA(glAlphaFunc);
|
||||||
qglBegin = dllBegin = (decltype(dllBegin))GPA(glBegin);
|
qglBegin = dllBegin = (decltype(dllBegin))GPA(glBegin);
|
||||||
|
|
@ -823,8 +829,10 @@ qboolean QGL_Init( const char *dllname )
|
||||||
qglLockArraysEXT = 0;
|
qglLockArraysEXT = 0;
|
||||||
qglUnlockArraysEXT = 0;
|
qglUnlockArraysEXT = 0;
|
||||||
|
|
||||||
|
if (gl_enabled) {
|
||||||
// check logging
|
// check logging
|
||||||
QGL_EnableLogging( (qboolean) r_logFile->integer );
|
QGL_EnableLogging( (qboolean) r_logFile->integer );
|
||||||
|
}
|
||||||
|
|
||||||
return qtrue;
|
return qtrue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ void GL_Bind( image_t *image ) {
|
||||||
qglBindTexture (GL_TEXTURE_2D, texnum);
|
qglBindTexture (GL_TEXTURE_2D, texnum);
|
||||||
|
|
||||||
// VULKAN
|
// VULKAN
|
||||||
if (vk_active) {
|
if (vk.active) {
|
||||||
VkDescriptorSet set = vk_resources.images[final_image->index].descriptor_set;
|
VkDescriptorSet set = vk_resources.images[final_image->index].descriptor_set;
|
||||||
vk_resources.current_descriptor_sets[glState.currenttmu] = set;
|
vk_resources.current_descriptor_sets[glState.currenttmu] = set;
|
||||||
}
|
}
|
||||||
|
|
@ -711,7 +711,7 @@ void RE_UploadCinematic (int w, int h, int cols, int rows, const byte *data, int
|
||||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
|
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
|
||||||
|
|
||||||
// VULKAN
|
// VULKAN
|
||||||
if (vk_active) {
|
if (vk.active) {
|
||||||
Vk_Image& image = vk_resources.images[tr.scratchImage[client]->index];
|
Vk_Image& image = vk_resources.images[tr.scratchImage[client]->index];
|
||||||
vkDestroyImage(vk.device, image.handle, nullptr);
|
vkDestroyImage(vk.device, image.handle, nullptr);
|
||||||
vkDestroyImageView(vk.device, image.view, nullptr);
|
vkDestroyImageView(vk.device, image.view, nullptr);
|
||||||
|
|
@ -727,7 +727,7 @@ void RE_UploadCinematic (int w, int h, int cols, int rows, const byte *data, int
|
||||||
qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data );
|
qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data );
|
||||||
|
|
||||||
// VULKAN
|
// VULKAN
|
||||||
if (vk_active) {
|
if (vk.active) {
|
||||||
const Vk_Image& image = vk_resources.images[tr.scratchImage[client]->index];
|
const Vk_Image& image = vk_resources.images[tr.scratchImage[client]->index];
|
||||||
vk_upload_image_data(image.handle, cols, rows, false, data);
|
vk_upload_image_data(image.handle, cols, rows, false, data);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,7 @@ void GL_TextureMode( const char *string ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// VULKAN
|
// VULKAN
|
||||||
if (vk_active) {
|
if (vk.active) {
|
||||||
VK_CHECK(vkDeviceWaitIdle(vk.device));
|
VK_CHECK(vkDeviceWaitIdle(vk.device));
|
||||||
for ( i = 0 ; i < tr.numImages ; i++ ) {
|
for ( i = 0 ; i < tr.numImages ; i++ ) {
|
||||||
image_t* glt = tr.images[i];
|
image_t* glt = tr.images[i];
|
||||||
|
|
@ -722,7 +722,7 @@ static void Upload32( unsigned *data,
|
||||||
done:
|
done:
|
||||||
|
|
||||||
// VULKAN
|
// VULKAN
|
||||||
if (vk_active) {
|
if (vk.active) {
|
||||||
image = vk_create_image(*pUploadWidth, *pUploadHeight, miplevel + 1, repeat_texture);
|
image = vk_create_image(*pUploadWidth, *pUploadHeight, miplevel + 1, repeat_texture);
|
||||||
vk_upload_image_data(image.handle, *pUploadWidth, *pUploadHeight, mipmap == qtrue, mipmap_buffer);
|
vk_upload_image_data(image.handle, *pUploadWidth, *pUploadHeight, mipmap == qtrue, mipmap_buffer);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,6 @@ glstate_t glState;
|
||||||
// VULKAN
|
// VULKAN
|
||||||
Vk_Instance vk;
|
Vk_Instance vk;
|
||||||
Vk_Resources vk_resources;
|
Vk_Resources vk_resources;
|
||||||
bool gl_active;
|
|
||||||
bool vk_active;
|
|
||||||
|
|
||||||
static void GfxInfo_f( void );
|
static void GfxInfo_f( void );
|
||||||
|
|
||||||
|
|
@ -178,14 +176,9 @@ static void AssertCvarRange( cvar_t *cv, float minVal, float maxVal, qboolean sh
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** InitOpenGL
|
** This function is responsible for initializing a valid OpenGL/Vulkan subsystem.
|
||||||
**
|
|
||||||
** This function is responsible for initializing a valid OpenGL subsystem. This
|
|
||||||
** is done by calling GLimp_Init (which gives us a working OGL subsystem) then
|
|
||||||
** setting variables, checking GL constants, and reporting the gfx system config
|
|
||||||
** to the user.
|
|
||||||
*/
|
*/
|
||||||
static void InitOpenGL( void )
|
static void InitRenderAPI( void )
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// initialize OS specific portions of the renderer
|
// initialize OS specific portions of the renderer
|
||||||
|
|
@ -200,8 +193,15 @@ static void InitOpenGL( void )
|
||||||
//
|
//
|
||||||
if ( glConfig.vidWidth == 0 )
|
if ( glConfig.vidWidth == 0 )
|
||||||
{
|
{
|
||||||
|
if (gl_enabled)
|
||||||
GLimp_Init();
|
GLimp_Init();
|
||||||
|
|
||||||
|
// VULKAN
|
||||||
|
if (vk_enabled) {
|
||||||
|
vk_imp_init();
|
||||||
|
vk_initialize();
|
||||||
|
}
|
||||||
|
|
||||||
// OpenGL driver constants
|
// OpenGL driver constants
|
||||||
GLint temp;
|
GLint temp;
|
||||||
qglGetIntegerv( GL_MAX_TEXTURE_SIZE, &temp );
|
qglGetIntegerv( GL_MAX_TEXTURE_SIZE, &temp );
|
||||||
|
|
@ -930,6 +930,7 @@ void R_Init( void ) {
|
||||||
Com_Memset( &tr, 0, sizeof( tr ) );
|
Com_Memset( &tr, 0, sizeof( tr ) );
|
||||||
Com_Memset( &backEnd, 0, sizeof( backEnd ) );
|
Com_Memset( &backEnd, 0, sizeof( backEnd ) );
|
||||||
Com_Memset( &tess, 0, sizeof( tess ) );
|
Com_Memset( &tess, 0, sizeof( tess ) );
|
||||||
|
Com_Memset( &vk_resources, 0, sizeof( vk_resources ) );
|
||||||
|
|
||||||
if ( (intptr_t)tess.xyz & 15 ) {
|
if ( (intptr_t)tess.xyz & 15 ) {
|
||||||
Com_Printf( "WARNING: tess.xyz not 16 byte aligned\n" );
|
Com_Printf( "WARNING: tess.xyz not 16 byte aligned\n" );
|
||||||
|
|
@ -991,10 +992,7 @@ void R_Init( void ) {
|
||||||
}
|
}
|
||||||
R_ToggleSmpFrame();
|
R_ToggleSmpFrame();
|
||||||
|
|
||||||
gl_active = (r_renderAPI->integer == 0 || r_renderAPICompareWindow->integer > 0);
|
InitRenderAPI();
|
||||||
vk_active = (r_renderAPI->integer > 0 || r_renderAPICompareWindow->integer > 0);
|
|
||||||
|
|
||||||
InitOpenGL();
|
|
||||||
|
|
||||||
R_InitImages();
|
R_InitImages();
|
||||||
|
|
||||||
|
|
@ -1032,13 +1030,6 @@ void RE_Shutdown( qboolean destroyWindow ) {
|
||||||
ri.Cmd_RemoveCommand( "modelist" );
|
ri.Cmd_RemoveCommand( "modelist" );
|
||||||
ri.Cmd_RemoveCommand( "shaderstate" );
|
ri.Cmd_RemoveCommand( "shaderstate" );
|
||||||
|
|
||||||
// VULKAN
|
|
||||||
if (vk_active) {
|
|
||||||
vk_destroy_resources();
|
|
||||||
if (destroyWindow)
|
|
||||||
vk_destroy_instance();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( tr.registered ) {
|
if ( tr.registered ) {
|
||||||
R_SyncRenderThread();
|
R_SyncRenderThread();
|
||||||
R_ShutdownCommandBuffers();
|
R_ShutdownCommandBuffers();
|
||||||
|
|
@ -1052,6 +1043,15 @@ void RE_Shutdown( qboolean destroyWindow ) {
|
||||||
GLimp_Shutdown();
|
GLimp_Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VULKAN
|
||||||
|
if (vk.active) {
|
||||||
|
vk_release_resources();
|
||||||
|
if (destroyWindow) {
|
||||||
|
vk_shutdown();
|
||||||
|
vk_imp_shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tr.registered = qfalse;
|
tr.registered = qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -942,8 +942,6 @@ extern glstate_t glState; // outside of TR since it shouldn't be cleared during
|
||||||
// VULKAN
|
// VULKAN
|
||||||
extern Vk_Instance vk; // shouldn't be cleared during ref re-init
|
extern Vk_Instance vk; // shouldn't be cleared during ref re-init
|
||||||
extern Vk_Resources vk_resources; // this data is cleared during ref re-init
|
extern Vk_Resources vk_resources; // this data is cleared during ref re-init
|
||||||
extern bool gl_active;
|
|
||||||
extern bool vk_active;
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -1197,13 +1195,15 @@ IMPLEMENTATION SPECIFIC FUNCTIONS
|
||||||
void GLimp_Init( void );
|
void GLimp_Init( void );
|
||||||
void GLimp_Shutdown( void );
|
void GLimp_Shutdown( void );
|
||||||
void GLimp_EndFrame( void );
|
void GLimp_EndFrame( void );
|
||||||
|
void GLimp_LogComment( char *comment );
|
||||||
|
|
||||||
qboolean GLimp_SpawnRenderThread( void (*function)( void ) );
|
qboolean GLimp_SpawnRenderThread( void (*function)( void ) );
|
||||||
void *GLimp_RendererSleep( void );
|
void *GLimp_RendererSleep( void );
|
||||||
void GLimp_FrontEndSleep( void );
|
void GLimp_FrontEndSleep( void );
|
||||||
void GLimp_WakeRenderer( void *data );
|
void GLimp_WakeRenderer( void *data );
|
||||||
|
|
||||||
void GLimp_LogComment( char *comment );
|
void vk_imp_init();
|
||||||
|
void vk_imp_shutdown();
|
||||||
|
|
||||||
// NOTE TTimo linux works with float gamma value, not the gamma table
|
// NOTE TTimo linux works with float gamma value, not the gamma table
|
||||||
// the params won't be used, getting the r_gamma cvar directly
|
// the params won't be used, getting the r_gamma cvar directly
|
||||||
|
|
@ -1422,6 +1422,9 @@ void RB_CalcDiffuseColor( unsigned char *colors );
|
||||||
|
|
||||||
void myGlMultMatrix( const float *a, const float *b, float *out );
|
void myGlMultMatrix( const float *a, const float *b, float *out );
|
||||||
|
|
||||||
|
#define gl_enabled (r_renderAPI->integer == 0 || r_renderAPICompareWindow->integer)
|
||||||
|
#define vk_enabled (r_renderAPI->integer != 0 || r_renderAPICompareWindow->integer)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============================================================
|
=============================================================
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -362,7 +362,7 @@ static void ProjectDlightTexture( void ) {
|
||||||
backEnd.pc.c_dlightIndexes += numIndexes;
|
backEnd.pc.c_dlightIndexes += numIndexes;
|
||||||
|
|
||||||
// VULKAN
|
// VULKAN
|
||||||
if (vk_active) {
|
if (vk.active) {
|
||||||
VkPipeline pipeline = vk.dlight_pipelines[dl->additive > 0 ? 1 : 0][tess.shader->cullType][tess.shader->polygonOffset];
|
VkPipeline pipeline = vk.dlight_pipelines[dl->additive > 0 ? 1 : 0][tess.shader->cullType][tess.shader->polygonOffset];
|
||||||
vk_bind_stage_specific_resources(pipeline, false, false);
|
vk_bind_stage_specific_resources(pipeline, false, false);
|
||||||
vkCmdDrawIndexed(vk.command_buffer, tess.numIndexes, 1, 0, 0, 0);
|
vkCmdDrawIndexed(vk.command_buffer, tess.numIndexes, 1, 0, 0, 0);
|
||||||
|
|
@ -408,7 +408,7 @@ static void RB_FogPass( void ) {
|
||||||
R_DrawElements( tess.numIndexes, tess.indexes );
|
R_DrawElements( tess.numIndexes, tess.indexes );
|
||||||
|
|
||||||
// VULKAN
|
// VULKAN
|
||||||
if (vk_active) {
|
if (vk.active) {
|
||||||
assert(tess.shader->fogPass > 0);
|
assert(tess.shader->fogPass > 0);
|
||||||
VkPipeline pipeline = vk.fog_pipelines[tess.shader->fogPass - 1][tess.shader->cullType][tess.shader->polygonOffset];
|
VkPipeline pipeline = vk.fog_pipelines[tess.shader->fogPass - 1][tess.shader->cullType][tess.shader->polygonOffset];
|
||||||
vk_bind_stage_specific_resources(pipeline, false, false);
|
vk_bind_stage_specific_resources(pipeline, false, false);
|
||||||
|
|
@ -767,7 +767,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
|
||||||
}
|
}
|
||||||
|
|
||||||
// VULKAN
|
// VULKAN
|
||||||
if (vk_active) {
|
if (vk.active) {
|
||||||
VkPipeline pipeline = pStage->vk_pipeline;
|
VkPipeline pipeline = pStage->vk_pipeline;
|
||||||
if (backEnd.viewParms.isMirror)
|
if (backEnd.viewParms.isMirror)
|
||||||
pipeline = pStage->vk_mirror_pipeline;
|
pipeline = pStage->vk_mirror_pipeline;
|
||||||
|
|
|
||||||
|
|
@ -2161,7 +2161,7 @@ static shader_t *FinishShader( void ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// VULKAN: create pipelines for each shader stage
|
// VULKAN: create pipelines for each shader stage
|
||||||
if (vk_active) {
|
if (vk.active) {
|
||||||
Vk_Pipeline_Def def;
|
Vk_Pipeline_Def def;
|
||||||
def.face_culling = shader.cullType;
|
def.face_culling = shader.cullType;
|
||||||
def.polygon_offset = (shader.polygonOffset == qtrue);
|
def.polygon_offset = (shader.polygonOffset == qtrue);
|
||||||
|
|
|
||||||
|
|
@ -451,7 +451,7 @@ static void DrawSkyBox( shader_t *shader )
|
||||||
sky_maxs_subd );
|
sky_maxs_subd );
|
||||||
|
|
||||||
// VULKAN: draw skybox side
|
// VULKAN: draw skybox side
|
||||||
if (vk_active) {
|
if (vk.active) {
|
||||||
VkDescriptorSet set = vk_resources.images[shader->sky.outerbox[sky_texorder[i]]->index].descriptor_set;
|
VkDescriptorSet set = vk_resources.images[shader->sky.outerbox[sky_texorder[i]]->index].descriptor_set;
|
||||||
vk_resources.current_descriptor_sets[0] = set;
|
vk_resources.current_descriptor_sets[0] = set;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,33 +95,6 @@ static uint32_t select_queue_family(VkPhysicalDevice physical_device, VkSurfaceK
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VkInstance create_instance() {
|
|
||||||
uint32_t count = 0;
|
|
||||||
VK_CHECK(vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr));
|
|
||||||
|
|
||||||
std::vector<VkExtensionProperties> extension_properties(count);
|
|
||||||
VK_CHECK(vkEnumerateInstanceExtensionProperties(nullptr, &count, extension_properties.data()));
|
|
||||||
|
|
||||||
for (auto name : instance_extensions) {
|
|
||||||
if (!is_extension_available(extension_properties, name))
|
|
||||||
ri.Error(ERR_FATAL, "Vulkan error: required instance extension is not available: %s", name);
|
|
||||||
}
|
|
||||||
|
|
||||||
VkInstanceCreateInfo desc;
|
|
||||||
desc.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
|
||||||
desc.pNext = nullptr;
|
|
||||||
desc.flags = 0;
|
|
||||||
desc.pApplicationInfo = nullptr;
|
|
||||||
desc.enabledLayerCount = 0;
|
|
||||||
desc.ppEnabledLayerNames = nullptr;
|
|
||||||
desc.enabledExtensionCount = static_cast<uint32_t>(instance_extensions.size());
|
|
||||||
desc.ppEnabledExtensionNames = instance_extensions.data();
|
|
||||||
|
|
||||||
VkInstance instance;
|
|
||||||
VK_CHECK(vkCreateInstance(&desc, nullptr, &instance));
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VkPhysicalDevice select_physical_device(VkInstance instance) {
|
static VkPhysicalDevice select_physical_device(VkInstance instance) {
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
VK_CHECK(vkEnumeratePhysicalDevices(instance, &count, nullptr));
|
VK_CHECK(vkEnumeratePhysicalDevices(instance, &count, nullptr));
|
||||||
|
|
@ -517,10 +490,34 @@ static void ensure_staging_buffer_allocation(VkDeviceSize size) {
|
||||||
|
|
||||||
VkPipeline create_pipeline(const Vk_Pipeline_Def&);
|
VkPipeline create_pipeline(const Vk_Pipeline_Def&);
|
||||||
|
|
||||||
void vk_create_instance(HWND hwnd) {
|
void vk_create_instance() {
|
||||||
|
uint32_t count = 0;
|
||||||
|
VK_CHECK(vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr));
|
||||||
|
|
||||||
|
std::vector<VkExtensionProperties> extension_properties(count);
|
||||||
|
VK_CHECK(vkEnumerateInstanceExtensionProperties(nullptr, &count, extension_properties.data()));
|
||||||
|
|
||||||
|
for (auto name : instance_extensions) {
|
||||||
|
if (!is_extension_available(extension_properties, name))
|
||||||
|
ri.Error(ERR_FATAL, "Vulkan error: required instance extension is not available: %s", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkInstanceCreateInfo desc;
|
||||||
|
desc.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
||||||
|
desc.pNext = nullptr;
|
||||||
|
desc.flags = 0;
|
||||||
|
desc.pApplicationInfo = nullptr;
|
||||||
|
desc.enabledLayerCount = 0;
|
||||||
|
desc.ppEnabledLayerNames = nullptr;
|
||||||
|
desc.enabledExtensionCount = static_cast<uint32_t>(instance_extensions.size());
|
||||||
|
desc.ppEnabledExtensionNames = instance_extensions.data();
|
||||||
|
|
||||||
|
VK_CHECK(vkCreateInstance(&desc, nullptr, &vk.instance));
|
||||||
|
}
|
||||||
|
|
||||||
|
void vk_initialize() {
|
||||||
vk_log_file = fopen("vk_dev.log", "w");
|
vk_log_file = fopen("vk_dev.log", "w");
|
||||||
|
|
||||||
vk.instance = create_instance();
|
|
||||||
vk.physical_device = select_physical_device(vk.instance);
|
vk.physical_device = select_physical_device(vk.instance);
|
||||||
|
|
||||||
VkPhysicalDeviceFeatures features;
|
VkPhysicalDeviceFeatures features;
|
||||||
|
|
@ -528,7 +525,6 @@ void vk_create_instance(HWND hwnd) {
|
||||||
if (features.shaderClipDistance == VK_FALSE)
|
if (features.shaderClipDistance == VK_FALSE)
|
||||||
ri.Error(ERR_FATAL, "vk_create_instance: shaderClipDistance feature is not supported");
|
ri.Error(ERR_FATAL, "vk_create_instance: shaderClipDistance feature is not supported");
|
||||||
|
|
||||||
vk.surface = create_surface(vk.instance, hwnd);
|
|
||||||
vk.surface_format = select_surface_format(vk.physical_device, vk.surface);
|
vk.surface_format = select_surface_format(vk.physical_device, vk.surface);
|
||||||
|
|
||||||
vk.queue_family_index = select_queue_family(vk.physical_device, vk.surface);
|
vk.queue_family_index = select_queue_family(vk.physical_device, vk.surface);
|
||||||
|
|
@ -919,9 +915,10 @@ void vk_create_instance(HWND hwnd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
vk.active = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vk_destroy_instance() {
|
void vk_shutdown() {
|
||||||
fclose(vk_log_file);
|
fclose(vk_log_file);
|
||||||
vk_log_file = nullptr;
|
vk_log_file = nullptr;
|
||||||
|
|
||||||
|
|
@ -975,7 +972,7 @@ void vk_destroy_instance() {
|
||||||
|
|
||||||
static float pipeline_create_time;
|
static float pipeline_create_time;
|
||||||
|
|
||||||
void vk_destroy_resources() {
|
void vk_release_resources() {
|
||||||
vkDeviceWaitIdle(vk.device);
|
vkDeviceWaitIdle(vk.device);
|
||||||
auto& res = vk_resources;
|
auto& res = vk_resources;
|
||||||
|
|
||||||
|
|
@ -1620,7 +1617,7 @@ VkPipeline vk_find_pipeline(const Vk_Pipeline_Def& def) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void vk_clear_attachments(bool clear_stencil, bool fast_sky) {
|
void vk_clear_attachments(bool clear_stencil, bool fast_sky) {
|
||||||
if (!vk_active)
|
if (!vk.active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!vk_resources.dirty_attachments && !fast_sky)
|
if (!vk_resources.dirty_attachments && !fast_sky)
|
||||||
|
|
@ -1755,7 +1752,7 @@ static void get_mvp_transform(float* mvp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void vk_bind_resources_shared_between_stages() {
|
void vk_bind_resources_shared_between_stages() {
|
||||||
if (!vk_active) return;
|
if (!vk.active) return;
|
||||||
|
|
||||||
// xyz
|
// xyz
|
||||||
{
|
{
|
||||||
|
|
@ -1888,7 +1885,7 @@ void vk_bind_stage_specific_resources(VkPipeline pipeline, bool multitexture, bo
|
||||||
}
|
}
|
||||||
|
|
||||||
void vk_begin_frame() {
|
void vk_begin_frame() {
|
||||||
if (!vk_active)
|
if (!vk.active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (r_logFile->integer)
|
if (r_logFile->integer)
|
||||||
|
|
@ -1931,7 +1928,7 @@ void vk_begin_frame() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void vk_end_frame() {
|
void vk_end_frame() {
|
||||||
if (!vk_active)
|
if (!vk.active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (r_logFile->integer)
|
if (r_logFile->integer)
|
||||||
|
|
|
||||||
|
|
@ -54,9 +54,20 @@ struct Vk_Image {
|
||||||
//
|
//
|
||||||
// Initialization.
|
// Initialization.
|
||||||
//
|
//
|
||||||
void vk_create_instance(HWND hwnd); // initializes VK_Instance
|
|
||||||
void vk_destroy_instance(); // destroys Vk_Instance resources
|
// Creates VkInstance and stores it as Vk_Instance::instance.
|
||||||
void vk_destroy_resources(); // destroys Vk_Resources resources
|
void vk_create_instance();
|
||||||
|
|
||||||
|
// Initializes VK_Instance structure.
|
||||||
|
// After calling this function we get fully functional vulkan subsystem.
|
||||||
|
void vk_initialize();
|
||||||
|
|
||||||
|
// Shutdown vulkan subsystem by releasing resources acquired by Vk_Instance.
|
||||||
|
void vk_shutdown();
|
||||||
|
|
||||||
|
// Releases vulkan resources allocated during program execution.
|
||||||
|
// This effectively puts vulkan subsystem into initial state (the state we have after vk_initialize call).
|
||||||
|
void vk_release_resources();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Resources allocation.
|
// Resources allocation.
|
||||||
|
|
@ -79,6 +90,7 @@ void vk_end_frame();
|
||||||
|
|
||||||
// Vulkan specific structures used by the engine.
|
// Vulkan specific structures used by the engine.
|
||||||
struct Vk_Instance {
|
struct Vk_Instance {
|
||||||
|
bool active = false;
|
||||||
VkInstance instance = VK_NULL_HANDLE;
|
VkInstance instance = VK_NULL_HANDLE;
|
||||||
VkPhysicalDevice physical_device = VK_NULL_HANDLE;
|
VkPhysicalDevice physical_device = VK_NULL_HANDLE;
|
||||||
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
VkSurfaceKHR surface = VK_NULL_HANDLE;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user