From cbca370d76f4dd8f4e436cd6307b82736b365c7b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 17 Jul 2020 04:28:26 +0200 Subject: [PATCH] Split up wgl_ctx.c into two files - GL and Vulkan --- Makefile.common | 3 + gfx/drivers_context/w_vk_ctx.c | 352 +++++++++++++++++++++++++++++++++ gfx/drivers_context/wgl_ctx.c | 151 +------------- griffin/griffin.c | 3 + retroarch.c | 64 +++++- retroarch.h | 1 + 6 files changed, 424 insertions(+), 150 deletions(-) create mode 100644 gfx/drivers_context/w_vk_ctx.c diff --git a/Makefile.common b/Makefile.common index 0cec67afc1..ff13b416e8 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1659,6 +1659,9 @@ endif ifeq ($(WANT_WGL), 1) OBJ += gfx/drivers_context/wgl_ctx.o + ifeq ($(HAVE_VULKAN),1) + OBJ += gfx/drivers_context/w_vk_ctx.o + endif LIBS += -lcomctl32 endif diff --git a/gfx/drivers_context/w_vk_ctx.c b/gfx/drivers_context/w_vk_ctx.c new file mode 100644 index 0000000000..61dbf01423 --- /dev/null +++ b/gfx/drivers_context/w_vk_ctx.c @@ -0,0 +1,352 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include + +/* Win32/WGL context. */ + +/* necessary for mingw32 multimon defines: */ +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0500 //_WIN32_WINNT_WIN2K +#endif + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#ifdef HAVE_CONFIG_H +#include "../../config.h" +#endif + +#include "../../configuration.h" +#include "../../dynamic.h" +#include "../../retroarch.h" +#include "../../verbosity.h" +#include "../../frontend/frontend_driver.h" + +#include "../common/win32_common.h" + +#include "../common/vulkan_common.h" + +/* TODO/FIXME - static globals */ +static gfx_ctx_vulkan_data_t win32_vk; + +static void *dinput_vk_wgl = NULL; + +static int win32_vk_interval = 0; +static enum gfx_ctx_api win32_vk_api = GFX_CTX_NONE; + +typedef struct gfx_ctx_cgl_data +{ + void *empty; +} gfx_ctx_w_vk_data_t; + +void create_vk_context(HWND hwnd, bool *quit) +{ + RECT rect; + HINSTANCE instance; + unsigned width = 0; + unsigned height = 0; + + GetClientRect(hwnd, &rect); + + instance = GetModuleHandle(NULL); + width = rect.right - rect.left; + height = rect.bottom - rect.top; + + if (!vulkan_surface_create(&win32_vk, VULKAN_WSI_WIN32, + &instance, &hwnd, + width, height, win32_vk_interval)) + *quit = true; + + g_win32_inited = true; +} + +static void gfx_ctx_w_vk_swap_interval(void *data, int interval) +{ + if (win32_vk_interval != interval) + { + win32_vk_interval = interval; + if (win32_vk.swapchain) + win32_vk.need_new_swapchain = true; + } +} + +static void gfx_ctx_w_vk_check_window(void *data, bool *quit, + bool *resize, unsigned *width, unsigned *height) +{ + win32_check_window(quit, resize, width, height); + + if (win32_vk.need_new_swapchain) + *resize = true; +} + +static void gfx_ctx_w_vk_swap_buffers(void *data) +{ + vulkan_present(&win32_vk, win32_vk.context.current_swapchain_index); + vulkan_acquire_next_image(&win32_vk); +} + +static bool gfx_ctx_w_vk_set_resize(void *data, + unsigned width, unsigned height) +{ + if (!vulkan_create_swapchain(&win32_vk, width, height, win32_vk_interval)) + { + RARCH_ERR("[Win32/Vulkan]: Failed to update swapchain.\n"); + return false; + } + + if (win32_vk.created_new_swapchain) + vulkan_acquire_next_image(&win32_vk); + win32_vk.context.invalid_swapchain = true; + win32_vk.need_new_swapchain = false; + + return false; +} + +static void gfx_ctx_w_vk_update_title(void *data) +{ + char title[128]; + + title[0] = '\0'; + + video_driver_get_window_title(title, sizeof(title)); + + if (title[0]) + { + const ui_window_t *window = ui_companion_driver_get_window_ptr(); + + if (window) + window->set_title(&main_window, title); + } +} + +static void gfx_ctx_w_vk_get_video_size(void *data, + unsigned *width, unsigned *height) +{ + HWND window = win32_get_window(); + + (void)data; + + if (!window) + { + RECT mon_rect; + MONITORINFOEX current_mon; + unsigned mon_id = 0; + HMONITOR hm_to_use = NULL; + + win32_monitor_info(¤t_mon, &hm_to_use, &mon_id); + mon_rect = current_mon.rcMonitor; + *width = mon_rect.right - mon_rect.left; + *height = mon_rect.bottom - mon_rect.top; + } + else + { + *width = g_win32_resize_width; + *height = g_win32_resize_height; + } +} + +static void gfx_ctx_w_vk_destroy(void *data) +{ + HWND window = win32_get_window(); + gfx_ctx_w_vk_data_t *wgl = (gfx_ctx_w_vk_data_t*)data; + + vulkan_context_destroy(&win32_vk, win32_vk.vk_surface != VK_NULL_HANDLE); + if (win32_vk.context.queue_lock) + slock_free(win32_vk.context.queue_lock); + memset(&win32_vk, 0, sizeof(win32_vk)); + + if (window) + { + win32_monitor_from_window(); + win32_destroy_window(); + } + + if (g_win32_restore_desktop) + { + win32_monitor_get_info(); + g_win32_restore_desktop = false; + } + + if (wgl) + free(wgl); + + g_win32_inited = false; +} + +static void *gfx_ctx_w_vk_init(void *video_driver) +{ + WNDCLASSEX wndclass = {0}; + gfx_ctx_w_vk_data_t *wgl = (gfx_ctx_w_vk_data_t*)calloc(1, sizeof(*wgl)); + + if (!wgl) + return NULL; + + if (g_win32_inited) + gfx_ctx_w_vk_destroy(NULL); + + win32_window_reset(); + win32_monitor_init(); + + wndclass.lpfnWndProc = WndProcVK; + if (!win32_window_init(&wndclass, true, NULL)) + goto error; + + if (!vulkan_context_init(&win32_vk, VULKAN_WSI_WIN32)) + goto error; + + return wgl; + +error: + if (wgl) + free(wgl); + return NULL; +} + +static bool gfx_ctx_w_vk_set_video_mode(void *data, + unsigned width, unsigned height, + bool fullscreen) +{ + win32_vk.fullscreen = fullscreen; + + if (!win32_set_video_mode(NULL, width, height, fullscreen)) + { + RARCH_ERR("[WGL]: win32_set_video_mode failed.\n"); + goto error; + } + + gfx_ctx_w_vk_swap_interval(data, win32_vk_interval); + return true; + +error: + gfx_ctx_w_vk_destroy(data); + return false; +} + +static void gfx_ctx_w_vk_input_driver(void *data, + const char *joypad_name, + input_driver_t **input, void **input_data) +{ + settings_t *settings = config_get_ptr(); + +#if _WIN32_WINNT >= 0x0501 +#ifdef HAVE_WINRAWINPUT + const char *input_driver = settings->arrays.input_driver; + + /* winraw only available since XP */ + if (string_is_equal(input_driver, "raw")) + { + *input_data = input_winraw.init(joypad_name); + if (*input_data) + { + *input = &input_winraw; + dinput_vk_wgl = NULL; + return; + } + } +#endif +#endif + +#ifdef HAVE_DINPUT + dinput_vk_wgl = input_dinput.init(joypad_name); + *input = dinput_vk_wgl ? &input_dinput : NULL; + *input_data = dinput_vk_wgl; +#endif +} + +static enum gfx_ctx_api gfx_ctx_w_vk_get_api(void *data) { return win32_vk_api; } + +static bool gfx_ctx_w_vk_bind_api(void *data, + enum gfx_ctx_api api, unsigned major, unsigned minor) +{ + win32_vk_api = api; + + if (api == GFX_CTX_VULKAN_API) + return true; + return false; +} + +static void gfx_ctx_w_vk_bind_hw_render(void *data, bool enable) { } + +static void *gfx_ctx_w_vk_get_context_data(void *data) +{ + (void)data; + return &win32_vk.context; +} + +static uint32_t gfx_ctx_w_vk_get_flags(void *data) +{ + uint32_t flags = 0; +#if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS) + BIT32_SET(flags, GFX_CTX_FLAGS_SHADERS_SLANG); +#endif + return flags; +} + +static void gfx_ctx_w_vk_set_flags(void *data, uint32_t flags) { } + +static void gfx_ctx_w_vk_get_video_output_size(void *data, + unsigned *width, unsigned *height) +{ + win32_get_video_output_size(width, height); +} + +static void gfx_ctx_w_vk_get_video_output_prev(void *data) { } + +static void gfx_ctx_w_vk_get_video_output_next(void *data) { } + +const gfx_ctx_driver_t gfx_ctx_w_vk = { + gfx_ctx_w_vk_init, + gfx_ctx_w_vk_destroy, + gfx_ctx_w_vk_get_api, + gfx_ctx_w_vk_bind_api, + gfx_ctx_w_vk_swap_interval, + gfx_ctx_w_vk_set_video_mode, + gfx_ctx_w_vk_get_video_size, + win32_get_refresh_rate, + gfx_ctx_w_vk_get_video_output_size, + gfx_ctx_w_vk_get_video_output_prev, + gfx_ctx_w_vk_get_video_output_next, + win32_get_metrics, + NULL, + gfx_ctx_w_vk_update_title, + gfx_ctx_w_vk_check_window, + gfx_ctx_w_vk_set_resize, + win32_has_focus, + win32_suppress_screensaver, + true, /* has_windowed */ + gfx_ctx_w_vk_swap_buffers, + gfx_ctx_w_vk_input_driver, + NULL, + NULL, + NULL, + win32_show_cursor, + "w_vk", + gfx_ctx_w_vk_get_flags, + gfx_ctx_w_vk_set_flags, + gfx_ctx_w_vk_bind_hw_render, + gfx_ctx_w_vk_get_context_data, + NULL +}; diff --git a/gfx/drivers_context/wgl_ctx.c b/gfx/drivers_context/wgl_ctx.c index 91986778cd..1d7aa77db7 100644 --- a/gfx/drivers_context/wgl_ctx.c +++ b/gfx/drivers_context/wgl_ctx.c @@ -62,11 +62,7 @@ #include "../common/gl1_common.h" #endif -#ifdef HAVE_VULKAN -#include "../common/vulkan_common.h" -#endif - -#if defined(HAVE_OPENGL) || defined(HAVE_OPENGL1) || defined(HAVE_OPENGL_CORE) || defined(HAVE_VULKAN) +#if defined(HAVE_OPENGL) || defined(HAVE_OPENGL1) || defined(HAVE_OPENGL_CORE) #ifndef WGL_CONTEXT_MAJOR_VERSION_ARB #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 #endif @@ -102,9 +98,6 @@ static bool win32_use_hw_ctx = false; static bool win32_core_hw_context_enable = false; static bool wgl_adaptive_vsync = false; -#ifdef HAVE_VULKAN -static gfx_ctx_vulkan_data_t win32_vk; -#endif #ifdef HAVE_EGL static egl_ctx_data_t win32_egl; #endif @@ -450,29 +443,6 @@ void create_graphics_context(HWND hwnd, bool *quit) } } -void create_vk_context(HWND hwnd, bool *quit) -{ -#ifdef HAVE_VULKAN - RECT rect; - HINSTANCE instance; - unsigned width = 0; - unsigned height = 0; - - GetClientRect(hwnd, &rect); - - instance = GetModuleHandle(NULL); - width = rect.right - rect.left; - height = rect.bottom - rect.top; - - if (!vulkan_surface_create(&win32_vk, VULKAN_WSI_WIN32, - &instance, &hwnd, - width, height, win32_interval)) - *quit = true; - - g_win32_inited = true; -#endif -} - static void gfx_ctx_wgl_swap_interval(void *data, int interval) { (void)data; @@ -501,17 +471,6 @@ static void gfx_ctx_wgl_swap_interval(void *data, int interval) #endif break; - case GFX_CTX_VULKAN_API: -#ifdef HAVE_VULKAN - if (win32_interval != interval) - { - win32_interval = interval; - if (win32_vk.swapchain) - win32_vk.need_new_swapchain = true; - } -#endif - break; - case GFX_CTX_NONE: default: win32_interval = interval; @@ -523,20 +482,6 @@ static void gfx_ctx_wgl_check_window(void *data, bool *quit, bool *resize, unsigned *width, unsigned *height) { win32_check_window(quit, resize, width, height); - - switch (win32_api) - { - case GFX_CTX_VULKAN_API: -#ifdef HAVE_VULKAN - if (win32_vk.need_new_swapchain) - *resize = true; -#endif - break; - - case GFX_CTX_NONE: - default: - break; - } } static void gfx_ctx_wgl_swap_buffers(void *data) @@ -548,12 +493,6 @@ static void gfx_ctx_wgl_swap_buffers(void *data) case GFX_CTX_OPENGL_API: SwapBuffers(win32_hdc); break; - case GFX_CTX_VULKAN_API: -#ifdef HAVE_VULKAN - vulkan_present(&win32_vk, win32_vk.context.current_swapchain_index); - vulkan_acquire_next_image(&win32_vk); -#endif - break; case GFX_CTX_OPENGL_ES_API: #if defined(HAVE_EGL) egl_swap_buffers(&win32_egl); @@ -566,36 +505,7 @@ static void gfx_ctx_wgl_swap_buffers(void *data) } static bool gfx_ctx_wgl_set_resize(void *data, - unsigned width, unsigned height) -{ - (void)data; - (void)width; - (void)height; - - switch (win32_api) - { - case GFX_CTX_VULKAN_API: -#ifdef HAVE_VULKAN - if (!vulkan_create_swapchain(&win32_vk, width, height, win32_interval)) - { - RARCH_ERR("[Win32/Vulkan]: Failed to update swapchain.\n"); - return false; - } - - if (win32_vk.created_new_swapchain) - vulkan_acquire_next_image(&win32_vk); - win32_vk.context.invalid_swapchain = true; - win32_vk.need_new_swapchain = false; -#endif - break; - - case GFX_CTX_NONE: - default: - break; - } - - return false; -} + unsigned width, unsigned height) { return false; } static void gfx_ctx_wgl_update_title(void *data) { @@ -666,15 +576,6 @@ static void gfx_ctx_wgl_destroy(void *data) #endif break; - case GFX_CTX_VULKAN_API: -#ifdef HAVE_VULKAN - vulkan_context_destroy(&win32_vk, win32_vk.vk_surface != VK_NULL_HANDLE); - if (win32_vk.context.queue_lock) - slock_free(win32_vk.context.queue_lock); - memset(&win32_vk, 0, sizeof(win32_vk)); -#endif - break; - case GFX_CTX_OPENGL_ES_API: #ifdef HAVE_EGL egl_destroy(&win32_egl); @@ -742,32 +643,11 @@ static void *gfx_ctx_wgl_init(void *video_driver) win32_window_reset(); win32_monitor_init(); - switch (win32_api) - { - case GFX_CTX_VULKAN_API: - wndclass.lpfnWndProc = WndProcVK; - break; - default: - wndclass.lpfnWndProc = WndProcWGL; - break; - } + wndclass.lpfnWndProc = WndProcWGL; if (!win32_window_init(&wndclass, true, NULL)) goto error; - switch (win32_api) - { - case GFX_CTX_VULKAN_API: -#ifdef HAVE_VULKAN - if (!vulkan_context_init(&win32_vk, VULKAN_WSI_WIN32)) - goto error; -#endif - break; - case GFX_CTX_NONE: - default: - break; - } - return wgl; error: @@ -780,10 +660,6 @@ static bool gfx_ctx_wgl_set_video_mode(void *data, unsigned width, unsigned height, bool fullscreen) { -#ifdef HAVE_VULKAN - win32_vk.fullscreen = fullscreen; -#endif - if (!win32_set_video_mode(NULL, width, height, fullscreen)) { RARCH_ERR("[WGL]: win32_set_video_mode failed.\n"); @@ -861,10 +737,6 @@ static bool gfx_ctx_wgl_bind_api(void *data, if (api == GFX_CTX_OPENGL_ES_API) return true; #endif -#if defined(HAVE_VULKAN) - if (api == GFX_CTX_VULKAN_API) - return true; -#endif return false; } @@ -899,14 +771,6 @@ static void gfx_ctx_wgl_bind_hw_render(void *data, bool enable) } } -#ifdef HAVE_VULKAN -static void *gfx_ctx_wgl_get_context_data(void *data) -{ - (void)data; - return &win32_vk.context; -} -#endif - static uint32_t gfx_ctx_wgl_get_flags(void *data) { uint32_t flags = 0; @@ -939,11 +803,6 @@ static uint32_t gfx_ctx_wgl_get_flags(void *data) } break; - case GFX_CTX_VULKAN_API: -#if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS) - BIT32_SET(flags, GFX_CTX_FLAGS_SHADERS_SLANG); -#endif - break; case GFX_CTX_OPENGL_ES_API: #if defined(HAVE_SLANG) && defined(HAVE_SPIRV_CROSS) @@ -1026,10 +885,6 @@ const gfx_ctx_driver_t gfx_ctx_wgl = { gfx_ctx_wgl_get_flags, gfx_ctx_wgl_set_flags, gfx_ctx_wgl_bind_hw_render, -#ifdef HAVE_VULKAN - gfx_ctx_wgl_get_context_data, -#else NULL, -#endif NULL }; diff --git a/griffin/griffin.c b/griffin/griffin.c index a94a3db079..f5b538f2fc 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -230,6 +230,9 @@ VIDEO CONTEXT #if defined(HAVE_OPENGL) || defined(HAVE_OPENGL1) || defined(HAVE_VULKAN) || defined(HAVE_OPENGLES) #include "../gfx/drivers_context/wgl_ctx.c" #endif +#if defined(HAVE_VULKAN) +#include "../gfx/drivers_context/w_vk_ctx.c" +#endif #include "../gfx/display_servers/dispserv_win32.c" diff --git a/retroarch.c b/retroarch.c index c7123c2d4b..899b013b5b 100644 --- a/retroarch.c +++ b/retroarch.c @@ -575,6 +575,14 @@ static const video_driver_t *video_drivers[] = { NULL, }; +static const gfx_ctx_driver_t *gfx_ctx_vk_drivers[] = { +#if defined(_WIN32) && !defined(__WINRT__) && (defined(HAVE_VULKAN)) + &gfx_ctx_w_vk, +#endif + &gfx_ctx_null, + NULL +}; + static const gfx_ctx_driver_t *gfx_ctx_gl_drivers[] = { #if defined(ORBIS) &orbis_ctx, @@ -600,7 +608,7 @@ static const gfx_ctx_driver_t *gfx_ctx_gl_drivers[] = { #if defined(HAVE_OPENDINGUX_FBDEV) &gfx_ctx_opendingux_fbdev, #endif -#if defined(_WIN32) && !defined(__WINRT__) && (defined(HAVE_OPENGL) || defined(HAVE_OPENGL1) || defined(HAVE_OPENGL_CORE) || defined(HAVE_VULKAN)) +#if defined(_WIN32) && !defined(__WINRT__) && (defined(HAVE_OPENGL) || defined(HAVE_OPENGL1) || defined(HAVE_OPENGL_CORE)) &gfx_ctx_wgl, #endif #if defined(__WINRT__) && defined(HAVE_OPENGLES) @@ -33031,6 +33039,51 @@ static const gfx_ctx_driver_t *video_context_driver_init( return ctx; } +static const gfx_ctx_driver_t *vk_context_driver_init_first(void *data, + const char *ident, enum gfx_ctx_api api, unsigned major, + unsigned minor, bool hw_render_ctx, void **ctx_data) +{ + unsigned j; + struct rarch_state *p_rarch = &rarch_st; + int i = -1; + + for (j = 0; gfx_ctx_vk_drivers[j]; j++) + { + if (string_is_equal_noncase(ident, gfx_ctx_vk_drivers[j]->ident)) + { + i = j; + break; + } + } + + if (i >= 0) + { + const gfx_ctx_driver_t *ctx = video_context_driver_init(data, + gfx_ctx_vk_drivers[i], ident, + api, major, minor, hw_render_ctx, ctx_data); + if (ctx) + { + p_rarch->video_context_data = *ctx_data; + return ctx; + } + } + + for (i = 0; gfx_ctx_vk_drivers[i]; i++) + { + const gfx_ctx_driver_t *ctx = + video_context_driver_init(data, gfx_ctx_vk_drivers[i], ident, + api, major, minor, hw_render_ctx, ctx_data); + + if (ctx) + { + p_rarch->video_context_data = *ctx_data; + return ctx; + } + } + + return NULL; +} + static const gfx_ctx_driver_t *gl_context_driver_init_first(void *data, const char *ident, enum gfx_ctx_api api, unsigned major, unsigned minor, bool hw_render_ctx, void **ctx_data) @@ -33096,10 +33149,17 @@ const gfx_ctx_driver_t *video_context_driver_init_first(void *data, { switch (api) { + case GFX_CTX_VULKAN_API: + { + const gfx_ctx_driver_t *ptr = vk_context_driver_init_first( + data, ident, api, major, minor, hw_render_ctx, ctx_data); + if (ptr && !string_is_equal(ptr->ident, "null")) + return ptr; + /* fall-through if no valid driver was found */ + } case GFX_CTX_OPENGL_API: case GFX_CTX_OPENGL_ES_API: case GFX_CTX_OPENVG_API: - case GFX_CTX_VULKAN_API: case GFX_CTX_METAL_API: return gl_context_driver_init_first(data, ident, api, major, minor, hw_render_ctx, ctx_data); diff --git a/retroarch.h b/retroarch.h index a7ab2972a3..a94a65fcc8 100644 --- a/retroarch.h +++ b/retroarch.h @@ -1893,6 +1893,7 @@ extern const gfx_ctx_driver_t gfx_ctx_mali_fbdev; extern const gfx_ctx_driver_t gfx_ctx_vivante_fbdev; extern const gfx_ctx_driver_t gfx_ctx_android; extern const gfx_ctx_driver_t gfx_ctx_ps3; +extern const gfx_ctx_driver_t gfx_ctx_w_vk; extern const gfx_ctx_driver_t gfx_ctx_wgl; extern const gfx_ctx_driver_t gfx_ctx_videocore; extern const gfx_ctx_driver_t gfx_ctx_qnx;