(WIN32/Vulkan) Refresh rate fixes + cleanups

This commit is contained in:
sonninnos 2021-08-12 18:33:58 +03:00
parent 013dd30bde
commit 11b0667e72
3 changed files with 45 additions and 16 deletions

View File

@ -307,6 +307,7 @@ bool g_win32_restore_desktop = false;
bool g_win32_inited = false; bool g_win32_inited = false;
unsigned g_win32_resize_width = 0; unsigned g_win32_resize_width = 0;
unsigned g_win32_resize_height = 0; unsigned g_win32_resize_height = 0;
float g_win32_refresh_rate = 0;
ui_window_win32_t main_window; ui_window_win32_t main_window;
/* TODO/FIXME - static globals */ /* TODO/FIXME - static globals */
@ -2255,6 +2256,7 @@ bool win32_set_video_mode(void *data,
mon_rect = current_mon.rcMonitor; mon_rect = current_mon.rcMonitor;
g_win32_resize_width = width; g_win32_resize_width = width;
g_win32_resize_height = height; g_win32_resize_height = height;
g_win32_refresh_rate = settings->floats.video_refresh_rate;
win32_set_style(&current_mon, &hm_to_use, &width, &height, win32_set_style(&current_mon, &hm_to_use, &width, &height,
fullscreen, windowed_full, &rect, &mon_rect, &style); fullscreen, windowed_full, &rect, &mon_rect, &style);

View File

@ -47,6 +47,7 @@ RETRO_BEGIN_DECLS
#if !defined(_XBOX) #if !defined(_XBOX)
extern unsigned g_win32_resize_width; extern unsigned g_win32_resize_width;
extern unsigned g_win32_resize_height; extern unsigned g_win32_resize_height;
extern float g_win32_refresh_rate;
extern bool g_win32_inited; extern bool g_win32_inited;
extern bool g_win32_restore_desktop; extern bool g_win32_restore_desktop;
extern ui_window_win32_t main_window; extern ui_window_win32_t main_window;

View File

@ -16,7 +16,7 @@
#include <math.h> #include <math.h>
/* Win32/WGL context. */ /* Win32/Vulkan context. */
/* necessary for mingw32 multimon defines: */ /* necessary for mingw32 multimon defines: */
#ifndef _WIN32_WINNT #ifndef _WIN32_WINNT
@ -57,7 +57,7 @@ typedef struct gfx_ctx_w_vk_data
/* TODO/FIXME - static globals */ /* TODO/FIXME - static globals */
static gfx_ctx_vulkan_data_t win32_vk; static gfx_ctx_vulkan_data_t win32_vk;
static void *dinput_vk_wgl = NULL; static void *dinput_vk = NULL;
static int win32_vk_interval = 0; static int win32_vk_interval = 0;
void create_vk_context(HWND hwnd, bool *quit) void create_vk_context(HWND hwnd, bool *quit)
@ -94,10 +94,32 @@ static void gfx_ctx_w_vk_swap_interval(void *data, int interval)
static void gfx_ctx_w_vk_check_window(void *data, bool *quit, static void gfx_ctx_w_vk_check_window(void *data, bool *quit,
bool *resize, unsigned *width, unsigned *height) bool *resize, unsigned *width, unsigned *height)
{ {
settings_t *settings = config_get_ptr();
float refresh_rate = settings->floats.video_refresh_rate;
win32_check_window(NULL, quit, resize, width, height); win32_check_window(NULL, quit, resize, width, height);
if (win32_vk.need_new_swapchain) if (win32_vk.need_new_swapchain)
*resize = true; *resize = true;
/* Trigger video driver init when changing refresh rate
* in fullscreen while dimensions stay the same.
* Otherwise display refresh rate will not stay at the designated rate.
* All other change combinations work however:
* - windowed works always
* - fullscreen works when dimensions and rate changes
* Bigger than zero difference required in order to prevent
* constant reinit when adjusting rate option in 0.001 increments.
*/
if (win32_vk.fullscreen && g_win32_refresh_rate &&
g_win32_refresh_rate != refresh_rate &&
abs(g_win32_refresh_rate - refresh_rate) > 0 &&
g_win32_resize_width == *width &&
g_win32_resize_height == *height)
{
g_win32_refresh_rate = settings->floats.video_refresh_rate;
command_event(CMD_EVENT_REINIT, NULL);
}
} }
static void gfx_ctx_w_vk_swap_buffers(void *data) static void gfx_ctx_w_vk_swap_buffers(void *data)
@ -119,7 +141,7 @@ static bool gfx_ctx_w_vk_set_resize(void *data,
{ {
if (!vulkan_create_swapchain(&win32_vk, width, height, win32_vk_interval)) if (!vulkan_create_swapchain(&win32_vk, width, height, win32_vk_interval))
{ {
RARCH_ERR("[Win32/Vulkan]: Failed to update swapchain.\n"); RARCH_ERR("[Vulkan]: Failed to update swapchain.\n");
return false; return false;
} }
@ -177,7 +199,7 @@ static void gfx_ctx_w_vk_get_video_size(void *data,
static void gfx_ctx_w_vk_destroy(void *data) static void gfx_ctx_w_vk_destroy(void *data)
{ {
HWND window = win32_get_window(); HWND window = win32_get_window();
gfx_ctx_w_vk_data_t *wgl = (gfx_ctx_w_vk_data_t*)data; gfx_ctx_w_vk_data_t *vk = (gfx_ctx_w_vk_data_t*)data;
vulkan_context_destroy(&win32_vk, win32_vk.vk_surface != VK_NULL_HANDLE); vulkan_context_destroy(&win32_vk, win32_vk.vk_surface != VK_NULL_HANDLE);
if (win32_vk.context.queue_lock) if (win32_vk.context.queue_lock)
@ -196,8 +218,8 @@ static void gfx_ctx_w_vk_destroy(void *data)
g_win32_restore_desktop = false; g_win32_restore_desktop = false;
} }
if (wgl) if (vk)
free(wgl); free(vk);
g_win32_inited = false; g_win32_inited = false;
} }
@ -205,9 +227,9 @@ static void gfx_ctx_w_vk_destroy(void *data)
static void *gfx_ctx_w_vk_init(void *video_driver) static void *gfx_ctx_w_vk_init(void *video_driver)
{ {
WNDCLASSEX wndclass = {0}; WNDCLASSEX wndclass = {0};
gfx_ctx_w_vk_data_t *wgl = (gfx_ctx_w_vk_data_t*)calloc(1, sizeof(*wgl)); gfx_ctx_w_vk_data_t *vk = (gfx_ctx_w_vk_data_t*)calloc(1, sizeof(*vk));
if (!wgl) if (!vk)
return NULL; return NULL;
if (g_win32_inited) if (g_win32_inited)
@ -234,11 +256,11 @@ static void *gfx_ctx_w_vk_init(void *video_driver)
if (!vulkan_context_init(&win32_vk, VULKAN_WSI_WIN32)) if (!vulkan_context_init(&win32_vk, VULKAN_WSI_WIN32))
goto error; goto error;
return wgl; return vk;
error: error:
if (wgl) if (vk)
free(wgl); free(vk);
return NULL; return NULL;
} }
@ -250,9 +272,13 @@ static bool gfx_ctx_w_vk_set_video_mode(void *data,
if (!win32_set_video_mode(NULL, width, height, fullscreen)) if (!win32_set_video_mode(NULL, width, height, fullscreen))
{ {
RARCH_ERR("[WGL]: win32_set_video_mode failed.\n"); RARCH_ERR("[Vulkan]: win32_set_video_mode failed.\n");
goto error; goto error;
} }
else
/* Create a new swapchain in order to prevent fullscreen
* emulated mailbox crash caused by refresh rate change */
vulkan_create_swapchain(&win32_vk, width, height, win32_vk_interval);
gfx_ctx_w_vk_swap_interval(data, win32_vk_interval); gfx_ctx_w_vk_swap_interval(data, win32_vk_interval);
return true; return true;
@ -279,7 +305,7 @@ static void gfx_ctx_w_vk_input_driver(void *data,
if (*input_data) if (*input_data)
{ {
*input = &input_winraw; *input = &input_winraw;
dinput_vk_wgl = NULL; dinput_vk = NULL;
return; return;
} }
} }
@ -287,9 +313,9 @@ static void gfx_ctx_w_vk_input_driver(void *data,
#endif #endif
#ifdef HAVE_DINPUT #ifdef HAVE_DINPUT
dinput_vk_wgl = input_driver_init_wrap(&input_dinput, joypad_name); dinput_vk = input_driver_init_wrap(&input_dinput, joypad_name);
*input = dinput_vk_wgl ? &input_dinput : NULL; *input = dinput_vk ? &input_dinput : NULL;
*input_data = dinput_vk_wgl; *input_data = dinput_vk;
#endif #endif
} }