DX12: added dx12 support to r_renderAPI/r_twinMode cvars.
This commit is contained in:
parent
2610ef131e
commit
c326ac6e3b
|
|
@ -409,10 +409,24 @@ static HWND create_main_window(int width, int height, qboolean fullscreen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char window_name[1024];
|
||||||
|
if (r_twinMode->integer == 0) {
|
||||||
|
strcpy(window_name, MAIN_WINDOW_CLASS_NAME);
|
||||||
|
} else {
|
||||||
|
const char* api_name = "invalid-render-api";
|
||||||
|
if (r_renderAPI->integer == 0)
|
||||||
|
api_name = "OpenGL";
|
||||||
|
else if (r_renderAPI->integer == 1)
|
||||||
|
api_name = "Vulkan";
|
||||||
|
else if (r_renderAPI->integer == 2)
|
||||||
|
api_name = "DX12";
|
||||||
|
sprintf(window_name, "%s [%s]", MAIN_WINDOW_CLASS_NAME, api_name);
|
||||||
|
}
|
||||||
|
|
||||||
HWND hwnd = CreateWindowEx(
|
HWND hwnd = CreateWindowEx(
|
||||||
0,
|
0,
|
||||||
MAIN_WINDOW_CLASS_NAME,
|
MAIN_WINDOW_CLASS_NAME,
|
||||||
"Quake 3: Arena",
|
window_name,
|
||||||
stylebits,
|
stylebits,
|
||||||
x, y, w, h,
|
x, y, w, h,
|
||||||
NULL,
|
NULL,
|
||||||
|
|
@ -431,7 +445,7 @@ static HWND create_main_window(int width, int height, qboolean fullscreen)
|
||||||
return hwnd;
|
return hwnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HWND create_twin_window(int width, int height, bool dx_window)
|
static HWND create_twin_window(int width, int height, int render_api)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// register the window class if necessary
|
// register the window class if necessary
|
||||||
|
|
@ -478,8 +492,27 @@ static HWND create_twin_window(int width, int height, bool dx_window)
|
||||||
|
|
||||||
cvar_t* vid_xpos = ri.Cvar_Get ("vid_xpos", "", 0);
|
cvar_t* vid_xpos = ri.Cvar_Get ("vid_xpos", "", 0);
|
||||||
cvar_t* vid_ypos = ri.Cvar_Get ("vid_ypos", "", 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 x, y;
|
||||||
int y = vid_ypos->integer;
|
|
||||||
|
bool show_three_windows = (r_twinMode->integer | (1 << r_renderAPI->integer)) == 7;
|
||||||
|
|
||||||
|
if (!show_three_windows) { // two windows
|
||||||
|
x = vid_xpos->integer + width + 5; // offset to the right of the main window
|
||||||
|
y = vid_ypos->integer;
|
||||||
|
} else { // three windows
|
||||||
|
bool first_twin_window =
|
||||||
|
(r_renderAPI->integer > 0 && render_api == 0) ||
|
||||||
|
(r_renderAPI->integer == 0 && render_api == 1);
|
||||||
|
|
||||||
|
if (first_twin_window) {
|
||||||
|
x = vid_xpos->integer + width + 5;
|
||||||
|
y = vid_ypos->integer;
|
||||||
|
} else {
|
||||||
|
x = vid_xpos->integer + 2*width + 10;
|
||||||
|
y = vid_ypos->integer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// adjust window coordinates if necessary
|
// adjust window coordinates if necessary
|
||||||
// so that the window is completely on screen
|
// so that the window is completely on screen
|
||||||
|
|
@ -499,10 +532,17 @@ static HWND create_twin_window(int width, int height, bool dx_window)
|
||||||
y = ( desktop_height - h );
|
y = ( desktop_height - h );
|
||||||
}
|
}
|
||||||
|
|
||||||
// If r_renderAPI = 0 (OpenGL) then twin window uses Vulkan API.
|
|
||||||
// If r_renderAPI = 1 (Vulkan) then twin window uses OpenGL API.
|
|
||||||
char window_name[1024];
|
char window_name[1024];
|
||||||
sprintf(window_name, "%s [%s]", MAIN_WINDOW_CLASS_NAME, dx_window ? "DX12" : (r_renderAPI->integer == 0 ? "Vulkan" : "OpenGL"));
|
|
||||||
|
const char* api_name = "invalid-render-api";
|
||||||
|
if (render_api == 0)
|
||||||
|
api_name = "OpenGL";
|
||||||
|
else if (render_api == 1)
|
||||||
|
api_name = "Vulkan";
|
||||||
|
else if (render_api == 2)
|
||||||
|
api_name = "DX12";
|
||||||
|
|
||||||
|
sprintf(window_name, "%s [%s]", MAIN_WINDOW_CLASS_NAME, api_name);
|
||||||
|
|
||||||
HWND hwnd = CreateWindowEx(
|
HWND hwnd = CreateWindowEx(
|
||||||
0,
|
0,
|
||||||
|
|
@ -726,7 +766,7 @@ void GLimp_Init( void )
|
||||||
SetFocus(g_wv.hWnd);
|
SetFocus(g_wv.hWnd);
|
||||||
WG_CheckHardwareGamma();
|
WG_CheckHardwareGamma();
|
||||||
} else {
|
} else {
|
||||||
g_wv.hWnd_opengl = create_twin_window(glConfig.vidWidth, glConfig.vidHeight, false);
|
g_wv.hWnd_opengl = create_twin_window(glConfig.vidWidth, glConfig.vidHeight, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GLW_InitDriver(g_wv.hWnd_opengl)) {
|
if (!GLW_InitDriver(g_wv.hWnd_opengl)) {
|
||||||
|
|
@ -831,16 +871,14 @@ void vk_imp_init() {
|
||||||
// Create window.
|
// Create window.
|
||||||
SetMode(r_mode->integer, (qboolean)r_fullscreen->integer);
|
SetMode(r_mode->integer, (qboolean)r_fullscreen->integer);
|
||||||
|
|
||||||
if (r_renderAPI->integer != 0) {
|
if (r_renderAPI->integer == 1) {
|
||||||
g_wv.hWnd_vulkan = create_main_window(glConfig.vidWidth, glConfig.vidHeight, (qboolean)r_fullscreen->integer);
|
g_wv.hWnd_vulkan = create_main_window(glConfig.vidWidth, glConfig.vidHeight, (qboolean)r_fullscreen->integer);
|
||||||
g_wv.hWnd = g_wv.hWnd_vulkan;
|
g_wv.hWnd = g_wv.hWnd_vulkan;
|
||||||
SetForegroundWindow(g_wv.hWnd);
|
SetForegroundWindow(g_wv.hWnd);
|
||||||
SetFocus(g_wv.hWnd);
|
SetFocus(g_wv.hWnd);
|
||||||
WG_CheckHardwareGamma();
|
WG_CheckHardwareGamma();
|
||||||
|
|
||||||
g_wv.hWnd_dx = create_twin_window(glConfig.vidWidth, glConfig.vidHeight, true);
|
|
||||||
} else {
|
} else {
|
||||||
g_wv.hWnd_vulkan = create_twin_window(glConfig.vidWidth, glConfig.vidHeight, false);
|
g_wv.hWnd_vulkan = create_twin_window(glConfig.vidWidth, glConfig.vidHeight, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -864,16 +902,6 @@ void vk_imp_shutdown() {
|
||||||
}
|
}
|
||||||
vkGetInstanceProcAddr = nullptr;
|
vkGetInstanceProcAddr = nullptr;
|
||||||
|
|
||||||
if (g_wv.hWnd_dx) {
|
|
||||||
ri.Printf(PRINT_ALL, "...destroying DX12 window\n");
|
|
||||||
DestroyWindow(g_wv.hWnd_dx);
|
|
||||||
|
|
||||||
if (g_wv.hWnd == g_wv.hWnd_dx) {
|
|
||||||
g_wv.hWnd_dx = NULL;
|
|
||||||
}
|
|
||||||
g_wv.hWnd_dx = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For vulkan mode we still have qgl pointers initialized with placeholder values.
|
// For vulkan mode we still have qgl pointers initialized with placeholder values.
|
||||||
// Reset them the same way as we do in opengl mode.
|
// Reset them the same way as we do in opengl mode.
|
||||||
QGL_Shutdown();
|
QGL_Shutdown();
|
||||||
|
|
@ -899,6 +927,58 @@ void vk_imp_create_surface() {
|
||||||
VK_CHECK(vkCreateWin32SurfaceKHR(vk.instance, &desc, nullptr, &vk.surface));
|
VK_CHECK(vkCreateWin32SurfaceKHR(vk.instance, &desc, nullptr, &vk.surface));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dx_imp_init() {
|
||||||
|
ri.Printf(PRINT_ALL, "Initializing DX12 subsystem\n");
|
||||||
|
|
||||||
|
// This will set qgl pointers to no-op placeholders.
|
||||||
|
if (!gl_active) {
|
||||||
|
QGL_Init(nullptr);
|
||||||
|
qglActiveTextureARB = [] (GLenum) {};
|
||||||
|
qglClientActiveTextureARB = [](GLenum) {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create window.
|
||||||
|
SetMode(r_mode->integer, (qboolean)r_fullscreen->integer);
|
||||||
|
|
||||||
|
if (r_renderAPI->integer == 2) {
|
||||||
|
g_wv.hWnd_dx = create_main_window(glConfig.vidWidth, glConfig.vidHeight, (qboolean)r_fullscreen->integer);
|
||||||
|
g_wv.hWnd = g_wv.hWnd_dx;
|
||||||
|
SetForegroundWindow(g_wv.hWnd);
|
||||||
|
SetFocus(g_wv.hWnd);
|
||||||
|
WG_CheckHardwareGamma();
|
||||||
|
} else {
|
||||||
|
g_wv.hWnd_dx = create_twin_window(glConfig.vidWidth, glConfig.vidHeight, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dx_imp_shutdown() {
|
||||||
|
ri.Printf(PRINT_ALL, "Shutting down DX12 subsystem\n");
|
||||||
|
|
||||||
|
if (g_wv.hWnd_dx) {
|
||||||
|
ri.Printf(PRINT_ALL, "...destroying DX12 window\n");
|
||||||
|
DestroyWindow(g_wv.hWnd_dx);
|
||||||
|
|
||||||
|
if (g_wv.hWnd == g_wv.hWnd_dx) {
|
||||||
|
g_wv.hWnd = NULL;
|
||||||
|
}
|
||||||
|
g_wv.hWnd_dx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For DX12 mode we still have qgl pointers initialized with placeholder values.
|
||||||
|
// 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 (log_fp) {
|
||||||
|
fclose(log_fp);
|
||||||
|
log_fp = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===========================================================
|
===========================================================
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ typedef struct
|
||||||
HINSTANCE reflib_library; // Handle to refresh DLL
|
HINSTANCE reflib_library; // Handle to refresh DLL
|
||||||
qboolean reflib_active;
|
qboolean reflib_active;
|
||||||
|
|
||||||
HWND hWnd; // main window, refers either to hWnd_opengl or to hWnd_vulkan
|
HWND hWnd; // main window, refers to one of the hWnd_XXX listed below
|
||||||
|
|
||||||
HWND hWnd_opengl;
|
HWND hWnd_opengl;
|
||||||
HWND hWnd_vulkan;
|
HWND hWnd_vulkan;
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ static void InitRenderAPI( void )
|
||||||
if ( glConfig.vidWidth == 0 )
|
if ( glConfig.vidWidth == 0 )
|
||||||
{
|
{
|
||||||
// OpenGL
|
// OpenGL
|
||||||
if (r_renderAPI->integer == 0 || r_twinMode->integer) {
|
if (r_renderAPI->integer == 0 || (r_twinMode->integer&1)) {
|
||||||
GLimp_Init();
|
GLimp_Init();
|
||||||
|
|
||||||
GLint temp;
|
GLint temp;
|
||||||
|
|
@ -202,10 +202,14 @@ static void InitRenderAPI( void )
|
||||||
}
|
}
|
||||||
|
|
||||||
// VULKAN
|
// VULKAN
|
||||||
// DX12
|
if (r_renderAPI->integer == 1 || (r_twinMode->integer&2)) {
|
||||||
if (r_renderAPI->integer != 0 || r_twinMode->integer) {
|
|
||||||
vk_imp_init();
|
vk_imp_init();
|
||||||
vk_initialize();
|
vk_initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// DX12
|
||||||
|
if (r_renderAPI->integer == 2 || (r_twinMode->integer&4)) {
|
||||||
|
dx_imp_init();
|
||||||
dx_initialize();
|
dx_initialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -373,9 +377,9 @@ void RB_TakeScreenshot( int x, int y, int width, int height, char *fileName ) {
|
||||||
|
|
||||||
if (r_renderAPI->integer == 0) {
|
if (r_renderAPI->integer == 0) {
|
||||||
qglReadPixels( x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer+18 );
|
qglReadPixels( x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer+18 );
|
||||||
} else {
|
} else if (r_renderAPI->integer == 1) { // VULKAN
|
||||||
// VULKAN
|
|
||||||
byte* buffer2 = (byte*) ri.Hunk_AllocateTempMemory(glConfig.vidWidth*glConfig.vidHeight*4);
|
byte* buffer2 = (byte*) ri.Hunk_AllocateTempMemory(glConfig.vidWidth*glConfig.vidHeight*4);
|
||||||
|
|
||||||
vk_read_pixels(buffer2);
|
vk_read_pixels(buffer2);
|
||||||
|
|
||||||
byte* buffer_ptr = buffer + 18;
|
byte* buffer_ptr = buffer + 18;
|
||||||
|
|
@ -418,8 +422,7 @@ void RB_TakeScreenshotJPEG( int x, int y, int width, int height, char *fileName
|
||||||
|
|
||||||
if (r_renderAPI->integer == 0) {
|
if (r_renderAPI->integer == 0) {
|
||||||
qglReadPixels( x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer );
|
qglReadPixels( x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer );
|
||||||
} else {
|
} else if (r_renderAPI->integer == 1) { // VULKAN
|
||||||
// VULKAN
|
|
||||||
vk_read_pixels(buffer);
|
vk_read_pixels(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -557,8 +560,7 @@ void R_LevelShot( void ) {
|
||||||
|
|
||||||
if (r_renderAPI->integer == 0) {
|
if (r_renderAPI->integer == 0) {
|
||||||
qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_RGB, GL_UNSIGNED_BYTE, source );
|
qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_RGB, GL_UNSIGNED_BYTE, source );
|
||||||
} else {
|
} else if (r_renderAPI->integer == 1) { // VULKAN
|
||||||
// VULKAN
|
|
||||||
byte* buffer2 = (byte*) ri.Hunk_AllocateTempMemory(glConfig.vidWidth*glConfig.vidHeight*4);
|
byte* buffer2 = (byte*) ri.Hunk_AllocateTempMemory(glConfig.vidWidth*glConfig.vidHeight*4);
|
||||||
vk_read_pixels(buffer2);
|
vk_read_pixels(buffer2);
|
||||||
|
|
||||||
|
|
@ -1121,16 +1123,22 @@ void RE_Shutdown( qboolean destroyWindow ) {
|
||||||
|
|
||||||
// VULKAN
|
// VULKAN
|
||||||
if (vk.active) {
|
if (vk.active) {
|
||||||
dx_release_resources();
|
|
||||||
vk_release_resources();
|
vk_release_resources();
|
||||||
if (destroyWindow) {
|
if (destroyWindow) {
|
||||||
dx_shutdown();
|
|
||||||
|
|
||||||
vk_shutdown();
|
vk_shutdown();
|
||||||
vk_imp_shutdown();
|
vk_imp_shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DX12
|
||||||
|
if (dx.active) {
|
||||||
|
dx_release_resources();
|
||||||
|
if (destroyWindow) {
|
||||||
|
dx_shutdown();
|
||||||
|
dx_imp_shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tr.registered = qfalse;
|
tr.registered = qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -949,11 +949,16 @@ extern Dx_World dx_world; // this data is cleared during ref re-init
|
||||||
//
|
//
|
||||||
// cvars
|
// cvars
|
||||||
//
|
//
|
||||||
extern cvar_t *r_renderAPI; // 3D API to use: 0 - OpenGL, 1 - Vulkan.
|
extern cvar_t *r_renderAPI; // 3D API to use: 0 - OpenGL, 1 - Vulkan, 2 - DX12
|
||||||
|
|
||||||
extern cvar_t *r_twinMode; // If enabled, renderer creates two separate windows.
|
extern cvar_t *r_twinMode; // Allows to render the same frame in different windows using different graphics APIs.
|
||||||
// The first window uses rendering API specified by r_renderAPI,
|
// This cvar specifies a bitmask that determines which APIs.
|
||||||
// the second window uses rendering API corresponding to (1 - r_renderAPI).
|
// 0 - regular rendering with single window using the graphics API specified by r_renderAPI.
|
||||||
|
// bit 0 - enables OpenGL backend
|
||||||
|
// bit 1 - enables Vulkan backend
|
||||||
|
// bit 2 - enables DX12 backend
|
||||||
|
// Combinations of the above values are allowed, for example, r_twinMode=7 creates three diffent
|
||||||
|
// windows using all the supported APIs.
|
||||||
|
|
||||||
extern cvar_t *r_railWidth;
|
extern cvar_t *r_railWidth;
|
||||||
extern cvar_t *r_railCoreWidth;
|
extern cvar_t *r_railCoreWidth;
|
||||||
|
|
@ -1204,6 +1209,9 @@ void vk_imp_init();
|
||||||
void vk_imp_shutdown();
|
void vk_imp_shutdown();
|
||||||
void vk_imp_create_surface();
|
void vk_imp_create_surface();
|
||||||
|
|
||||||
|
void dx_imp_init();
|
||||||
|
void dx_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
|
||||||
void GLimp_SetGamma( unsigned char red[256],
|
void GLimp_SetGamma( unsigned char red[256],
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user