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(
|
||||
0,
|
||||
MAIN_WINDOW_CLASS_NAME,
|
||||
"Quake 3: Arena",
|
||||
window_name,
|
||||
stylebits,
|
||||
x, y, w, h,
|
||||
NULL,
|
||||
|
|
@ -431,7 +445,7 @@ static HWND create_main_window(int width, int height, qboolean fullscreen)
|
|||
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
|
||||
|
|
@ -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_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;
|
||||
int x, y;
|
||||
|
||||
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
|
||||
// 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 );
|
||||
}
|
||||
|
||||
// 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];
|
||||
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(
|
||||
0,
|
||||
|
|
@ -726,7 +766,7 @@ void GLimp_Init( void )
|
|||
SetFocus(g_wv.hWnd);
|
||||
WG_CheckHardwareGamma();
|
||||
} 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)) {
|
||||
|
|
@ -831,16 +871,14 @@ void vk_imp_init() {
|
|||
// Create window.
|
||||
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 = g_wv.hWnd_vulkan;
|
||||
SetForegroundWindow(g_wv.hWnd);
|
||||
SetFocus(g_wv.hWnd);
|
||||
WG_CheckHardwareGamma();
|
||||
|
||||
g_wv.hWnd_dx = create_twin_window(glConfig.vidWidth, glConfig.vidHeight, true);
|
||||
} 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;
|
||||
|
||||
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.
|
||||
// Reset them the same way as we do in opengl mode.
|
||||
QGL_Shutdown();
|
||||
|
|
@ -899,6 +927,58 @@ void vk_imp_create_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
|
||||
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_vulkan;
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ static void InitRenderAPI( void )
|
|||
if ( glConfig.vidWidth == 0 )
|
||||
{
|
||||
// OpenGL
|
||||
if (r_renderAPI->integer == 0 || r_twinMode->integer) {
|
||||
if (r_renderAPI->integer == 0 || (r_twinMode->integer&1)) {
|
||||
GLimp_Init();
|
||||
|
||||
GLint temp;
|
||||
|
|
@ -202,10 +202,14 @@ static void InitRenderAPI( void )
|
|||
}
|
||||
|
||||
// VULKAN
|
||||
// DX12
|
||||
if (r_renderAPI->integer != 0 || r_twinMode->integer) {
|
||||
if (r_renderAPI->integer == 1 || (r_twinMode->integer&2)) {
|
||||
vk_imp_init();
|
||||
vk_initialize();
|
||||
}
|
||||
|
||||
// DX12
|
||||
if (r_renderAPI->integer == 2 || (r_twinMode->integer&4)) {
|
||||
dx_imp_init();
|
||||
dx_initialize();
|
||||
}
|
||||
}
|
||||
|
|
@ -373,9 +377,9 @@ void RB_TakeScreenshot( int x, int y, int width, int height, char *fileName ) {
|
|||
|
||||
if (r_renderAPI->integer == 0) {
|
||||
qglReadPixels( x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer+18 );
|
||||
} else {
|
||||
// VULKAN
|
||||
} else if (r_renderAPI->integer == 1) { // VULKAN
|
||||
byte* buffer2 = (byte*) ri.Hunk_AllocateTempMemory(glConfig.vidWidth*glConfig.vidHeight*4);
|
||||
|
||||
vk_read_pixels(buffer2);
|
||||
|
||||
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) {
|
||||
qglReadPixels( x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer );
|
||||
} else {
|
||||
// VULKAN
|
||||
} else if (r_renderAPI->integer == 1) { // VULKAN
|
||||
vk_read_pixels(buffer);
|
||||
}
|
||||
|
||||
|
|
@ -557,8 +560,7 @@ void R_LevelShot( void ) {
|
|||
|
||||
if (r_renderAPI->integer == 0) {
|
||||
qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_RGB, GL_UNSIGNED_BYTE, source );
|
||||
} else {
|
||||
// VULKAN
|
||||
} else if (r_renderAPI->integer == 1) { // VULKAN
|
||||
byte* buffer2 = (byte*) ri.Hunk_AllocateTempMemory(glConfig.vidWidth*glConfig.vidHeight*4);
|
||||
vk_read_pixels(buffer2);
|
||||
|
||||
|
|
@ -1121,16 +1123,22 @@ void RE_Shutdown( qboolean destroyWindow ) {
|
|||
|
||||
// VULKAN
|
||||
if (vk.active) {
|
||||
dx_release_resources();
|
||||
vk_release_resources();
|
||||
if (destroyWindow) {
|
||||
dx_shutdown();
|
||||
|
||||
vk_shutdown();
|
||||
vk_imp_shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
// DX12
|
||||
if (dx.active) {
|
||||
dx_release_resources();
|
||||
if (destroyWindow) {
|
||||
dx_shutdown();
|
||||
dx_imp_shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
tr.registered = qfalse;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -949,11 +949,16 @@ extern Dx_World dx_world; // this data is cleared during ref re-init
|
|||
//
|
||||
// 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.
|
||||
// The first window uses rendering API specified by r_renderAPI,
|
||||
// the second window uses rendering API corresponding to (1 - r_renderAPI).
|
||||
extern cvar_t *r_twinMode; // Allows to render the same frame in different windows using different graphics APIs.
|
||||
// This cvar specifies a bitmask that determines which APIs.
|
||||
// 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_railCoreWidth;
|
||||
|
|
@ -1204,6 +1209,9 @@ void vk_imp_init();
|
|||
void vk_imp_shutdown();
|
||||
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
|
||||
// the params won't be used, getting the r_gamma cvar directly
|
||||
void GLimp_SetGamma( unsigned char red[256],
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user