From 8ade7fb2743c81cd827f7d17a4695eec0619e8a5 Mon Sep 17 00:00:00 2001 From: Hans-Kristian Arntzen Date: Tue, 29 Mar 2016 00:45:36 +0200 Subject: [PATCH] Vulkan: Attempt Windows backend support. Completely bind since I cannot test myself, but compiles. --- gfx/common/vulkan_common.c | 4 +- gfx/common/vulkan_common.h | 8 ++ gfx/common/win32_common.cpp | 2 +- gfx/common/win32_common.h | 2 +- gfx/drivers_context/wgl_ctx.cpp | 218 ++++++++++++++++++++++++++++---- 5 files changed, 203 insertions(+), 31 deletions(-) diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c index dcddc15823..cea1d2cfc4 100644 --- a/gfx/common/vulkan_common.c +++ b/gfx/common/vulkan_common.c @@ -1481,8 +1481,8 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk, surf_info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; surf_info.flags = 0; - surf_info.hinstance = display; - surf_info.hwnd = surface; + surf_info.hinstance = *(const HINSTANCE*)display; + surf_info.hwnd = *(const HWND*)surface; if (VKFUNC(vkCreateWin32SurfaceKHR)(vk->context.instance, &surf_info, NULL, &vk->vk_surface) != VK_SUCCESS) diff --git a/gfx/common/vulkan_common.h b/gfx/common/vulkan_common.h index 6a46bb84d1..6a5b0629c7 100644 --- a/gfx/common/vulkan_common.h +++ b/gfx/common/vulkan_common.h @@ -48,6 +48,10 @@ #include "../../libretro_vulkan.h" #include "../drivers_shader/shader_vulkan.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct vulkan_filter_chain vulkan_filter_chain_t; enum vk_texture_type @@ -503,5 +507,9 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk, unsigned width, unsigned height, unsigned swap_interval); +#ifdef __cplusplus +} +#endif + #endif diff --git a/gfx/common/win32_common.cpp b/gfx/common/win32_common.cpp index 3110071eff..a9e3a24a7e 100644 --- a/gfx/common/win32_common.cpp +++ b/gfx/common/win32_common.cpp @@ -258,7 +258,7 @@ LRESULT CALLBACK WndProcGL(HWND hwnd, UINT message, return ret; break; case WM_CREATE: - create_gl_context(hwnd, &g_quit); + create_graphics_context(hwnd, &g_quit); return 0; } diff --git a/gfx/common/win32_common.h b/gfx/common/win32_common.h index 99661115c2..741e70e506 100644 --- a/gfx/common/win32_common.h +++ b/gfx/common/win32_common.h @@ -47,7 +47,7 @@ void win32_monitor_get_info(void); void win32_monitor_info(void *data, void *hm_data, unsigned *mon_id); -void create_gl_context(HWND hwnd, bool *quit); +void create_graphics_context(HWND hwnd, bool *quit); bool win32_shader_dlg_init(void); void shader_dlg_show(HWND parent_hwnd); diff --git a/gfx/drivers_context/wgl_ctx.cpp b/gfx/drivers_context/wgl_ctx.cpp index b088e5dc9e..c75f282b2c 100644 --- a/gfx/drivers_context/wgl_ctx.cpp +++ b/gfx/drivers_context/wgl_ctx.cpp @@ -39,6 +39,10 @@ #include "../common/gl_common.h" #include "../common/win32_common.h" +#ifdef HAVE_VULKAN +#include "../common/vulkan_common.h" +#endif + #ifndef WGL_CONTEXT_MAJOR_VERSION_ARB #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 #endif @@ -71,8 +75,13 @@ static HGLRC g_hrc; static HGLRC g_hw_hrc; static HDC g_hdc; +#ifdef HAVE_VULKAN +static gfx_ctx_vulkan_data_t g_vk; +#endif + static unsigned g_major; static unsigned g_minor; +static enum gfx_ctx_api g_api; static unsigned g_interval; @@ -95,7 +104,7 @@ static void setup_pixel_format(HDC hdc) SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd); } -void create_gl_context(HWND hwnd, bool *quit) +static void create_gl_context(HWND hwnd, bool *quit) { bool core_context; struct retro_hw_render_callback *hwr = NULL; @@ -219,6 +228,36 @@ void create_gl_context(HWND hwnd, bool *quit) } } +void create_graphics_context(HWND hwnd, bool *quit) +{ + switch (g_api) + { + case GFX_CTX_OPENGL_API: + create_gl_context(hwnd, quit); + break; + + case GFX_CTX_VULKAN_API: + { +#ifdef HAVE_VULKAN + RECT rect; + unsigned width = rect.right - rect.left; + unsigned height = rect.bottom - rect.top; + GetClientRect(hwnd, &rect); + HINSTANCE instance = GetModuleHandle(NULL); + if (!vulkan_surface_create(&g_vk, VULKAN_WSI_WIN32, + &instance, &hwnd, + width, height, g_interval)) + *quit = true; + break; +#endif + } + + case GFX_CTX_NONE: + default: + break; + } +} + void *dinput_wgl; static void gfx_ctx_wgl_swap_interval(void *data, unsigned interval) @@ -226,26 +265,81 @@ static void gfx_ctx_wgl_swap_interval(void *data, unsigned interval) (void)data; g_interval = interval; - if (!g_hrc) - return; - if (!p_swap_interval) - return; + switch (g_api) + { + case GFX_CTX_OPENGL_API: +#ifdef HAVE_OPENGL + if (!g_hrc) + return; + if (!p_swap_interval) + return; - RARCH_LOG("[WGL]: wglSwapInterval(%u)\n", g_interval); - if (!p_swap_interval(g_interval)) - RARCH_WARN("[WGL]: wglSwapInterval() failed.\n"); + RARCH_LOG("[WGL]: wglSwapInterval(%u)\n", g_interval); + if (!p_swap_interval(g_interval)) + RARCH_WARN("[WGL]: wglSwapInterval() failed.\n"); +#endif + break; + + case GFX_CTX_VULKAN_API: +#ifdef HAVE_VULKAN + if (g_interval != interval) + { + g_interval = interval; + if (g_vk.swapchain) + g_vk.need_new_swapchain = true; + } +#endif + break; + + case GFX_CTX_NONE: + default: + break; + } } static void gfx_ctx_wgl_check_window(void *data, bool *quit, bool *resize, unsigned *width, unsigned *height, unsigned frame_count) { win32_check_window(quit, resize, width, height); + + switch (g_api) + { + case GFX_CTX_VULKAN_API: +#ifdef HAVE_VULKAN + if (g_vk.need_new_swapchain) + *resize = true; +#endif + break; + + case GFX_CTX_NONE: + default: + break; + } } static void gfx_ctx_wgl_swap_buffers(void *data) { (void)data; - SwapBuffers(g_hdc); + + switch (g_api) + { + case GFX_CTX_OPENGL_API: +#ifdef HAVE_OPENGL + SwapBuffers(g_hdc); + break; +#endif + + case GFX_CTX_VULKAN_API: +#ifdef HAVE_VULKAN + vulkan_present(&g_vk, g_vk.context.current_swapchain_index); + vulkan_acquire_next_image(&g_vk); +#endif + break; + + case GFX_CTX_NONE: + default: + break; + } } static bool gfx_ctx_wgl_set_resize(void *data, @@ -254,6 +348,27 @@ static bool gfx_ctx_wgl_set_resize(void *data, (void)data; (void)width; (void)height; + + switch (g_api) + { + case GFX_CTX_VULKAN_API: +#ifdef HAVE_VULKAN + if (!vulkan_create_swapchain(&g_vk, width, height, g_interval)) + { + RARCH_ERR("[Win32/Vulkan]: Failed to update swapchain.\n"); + return false; + } + + g_vk.context.invalid_swapchain = true; + g_vk.need_new_swapchain = false; +#endif + break; + + case GFX_CTX_NONE: + default: + break; + } + return false; } @@ -314,6 +429,16 @@ static void *gfx_ctx_wgl_init(void *video_driver) if (!win32_window_init(&wndclass, true, NULL)) return NULL; + switch (g_api) + { + case GFX_CTX_VULKAN_API: +#ifdef HAVE_VULKAN + if (!vulkan_context_init(&g_vk, VULKAN_WSI_WIN32)) + return NULL; +#endif + break; + } + return (void*)"wgl"; } @@ -323,19 +448,39 @@ static void gfx_ctx_wgl_destroy(void *data) (void)data; - if (g_hrc) + switch (g_api) { - glFinish(); - wglMakeCurrent(NULL, NULL); + case GFX_CTX_OPENGL_API: +#ifdef HAVE_OPENGL + if (g_hrc) + { + glFinish(); + wglMakeCurrent(NULL, NULL); - if (!video_driver_ctl(RARCH_DISPLAY_CTL_IS_VIDEO_CACHE_CONTEXT, NULL)) - { - if (g_hw_hrc) - wglDeleteContext(g_hw_hrc); - wglDeleteContext(g_hrc); - g_hrc = NULL; - g_hw_hrc = NULL; - } + if (!video_driver_ctl(RARCH_DISPLAY_CTL_IS_VIDEO_CACHE_CONTEXT, NULL)) + { + if (g_hw_hrc) + wglDeleteContext(g_hw_hrc); + wglDeleteContext(g_hrc); + g_hrc = NULL; + g_hw_hrc = NULL; + } + } +#endif + break; + + case GFX_CTX_VULKAN_API: +#ifdef HAVE_VULKAN + vulkan_context_destroy(&g_vk, g_vk.vk_surface != VK_NULL_HANDLE); + if (g_vk.context.queue_lock) + slock_free(g_vk.context.queue_lock); + memset(&g_vk, 0, sizeof(g_vk)); +#endif + break; + + case GFX_CTX_NONE: + default: + break; } if (window && g_hdc) @@ -368,10 +513,17 @@ static bool gfx_ctx_wgl_set_video_mode(void *data, if (!win32_set_video_mode(NULL, width, height, fullscreen)) goto error; - p_swap_interval = (BOOL (APIENTRY *)(int)) - wglGetProcAddress("wglSwapIntervalEXT"); + switch (g_api) + { + case GFX_CTX_OPENGL_API: +#ifdef HAVE_OPENGL + p_swap_interval = (BOOL (APIENTRY *)(int)) + wglGetProcAddress("wglSwapIntervalEXT"); - gfx_ctx_wgl_swap_interval(data, g_interval); + gfx_ctx_wgl_swap_interval(data, g_interval); +#endif + break; + } return true; @@ -430,8 +582,9 @@ static bool gfx_ctx_wgl_bind_api(void *data, g_major = major; g_minor = minor; + g_api = api; - return api == GFX_CTX_OPENGL_API; + return api == GFX_CTX_OPENGL_API || api == GFX_CTX_VULKAN_API; } static void gfx_ctx_wgl_show_mouse(void *data, bool state) @@ -442,10 +595,21 @@ static void gfx_ctx_wgl_show_mouse(void *data, bool state) static void gfx_ctx_wgl_bind_hw_render(void *data, bool enable) { - g_use_hw_ctx = enable; + switch (g_api) + { + case GFX_CTX_OPENGL_API: +#ifdef HAVE_OPENGL + g_use_hw_ctx = enable; - if (g_hdc) - wglMakeCurrent(g_hdc, enable ? g_hw_hrc : g_hrc); + if (g_hdc) + wglMakeCurrent(g_hdc, enable ? g_hw_hrc : g_hrc); +#endif + break; + + case GFX_CTX_NONE: + default: + break; + } } const gfx_ctx_driver_t gfx_ctx_wgl = {