Vulkan: Attempt Windows backend support.

Completely bind since I cannot test myself, but compiles.
This commit is contained in:
Hans-Kristian Arntzen 2016-03-29 00:45:36 +02:00
parent 72f65396c7
commit 8ade7fb274
5 changed files with 203 additions and 31 deletions

View File

@ -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.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
surf_info.flags = 0; surf_info.flags = 0;
surf_info.hinstance = display; surf_info.hinstance = *(const HINSTANCE*)display;
surf_info.hwnd = surface; surf_info.hwnd = *(const HWND*)surface;
if (VKFUNC(vkCreateWin32SurfaceKHR)(vk->context.instance, if (VKFUNC(vkCreateWin32SurfaceKHR)(vk->context.instance,
&surf_info, NULL, &vk->vk_surface) != VK_SUCCESS) &surf_info, NULL, &vk->vk_surface) != VK_SUCCESS)

View File

@ -48,6 +48,10 @@
#include "../../libretro_vulkan.h" #include "../../libretro_vulkan.h"
#include "../drivers_shader/shader_vulkan.h" #include "../drivers_shader/shader_vulkan.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct vulkan_filter_chain vulkan_filter_chain_t; typedef struct vulkan_filter_chain vulkan_filter_chain_t;
enum vk_texture_type enum vk_texture_type
@ -503,5 +507,9 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk,
unsigned width, unsigned height, unsigned width, unsigned height,
unsigned swap_interval); unsigned swap_interval);
#ifdef __cplusplus
}
#endif
#endif #endif

View File

@ -258,7 +258,7 @@ LRESULT CALLBACK WndProcGL(HWND hwnd, UINT message,
return ret; return ret;
break; break;
case WM_CREATE: case WM_CREATE:
create_gl_context(hwnd, &g_quit); create_graphics_context(hwnd, &g_quit);
return 0; return 0;
} }

View File

@ -47,7 +47,7 @@ void win32_monitor_get_info(void);
void win32_monitor_info(void *data, void *hm_data, unsigned *mon_id); 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); bool win32_shader_dlg_init(void);
void shader_dlg_show(HWND parent_hwnd); void shader_dlg_show(HWND parent_hwnd);

View File

@ -39,6 +39,10 @@
#include "../common/gl_common.h" #include "../common/gl_common.h"
#include "../common/win32_common.h" #include "../common/win32_common.h"
#ifdef HAVE_VULKAN
#include "../common/vulkan_common.h"
#endif
#ifndef WGL_CONTEXT_MAJOR_VERSION_ARB #ifndef WGL_CONTEXT_MAJOR_VERSION_ARB
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#endif #endif
@ -71,8 +75,13 @@ static HGLRC g_hrc;
static HGLRC g_hw_hrc; static HGLRC g_hw_hrc;
static HDC g_hdc; static HDC g_hdc;
#ifdef HAVE_VULKAN
static gfx_ctx_vulkan_data_t g_vk;
#endif
static unsigned g_major; static unsigned g_major;
static unsigned g_minor; static unsigned g_minor;
static enum gfx_ctx_api g_api;
static unsigned g_interval; static unsigned g_interval;
@ -95,7 +104,7 @@ static void setup_pixel_format(HDC hdc)
SetPixelFormat(hdc, ChoosePixelFormat(hdc, &pfd), &pfd); 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; bool core_context;
struct retro_hw_render_callback *hwr = NULL; 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; void *dinput_wgl;
static void gfx_ctx_wgl_swap_interval(void *data, unsigned interval) 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; (void)data;
g_interval = interval; g_interval = interval;
if (!g_hrc) switch (g_api)
return; {
if (!p_swap_interval) case GFX_CTX_OPENGL_API:
return; #ifdef HAVE_OPENGL
if (!g_hrc)
return;
if (!p_swap_interval)
return;
RARCH_LOG("[WGL]: wglSwapInterval(%u)\n", g_interval); RARCH_LOG("[WGL]: wglSwapInterval(%u)\n", g_interval);
if (!p_swap_interval(g_interval)) if (!p_swap_interval(g_interval))
RARCH_WARN("[WGL]: wglSwapInterval() failed.\n"); 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, static void gfx_ctx_wgl_check_window(void *data, bool *quit,
bool *resize, unsigned *width, unsigned *height, unsigned frame_count) bool *resize, unsigned *width, unsigned *height, unsigned frame_count)
{ {
win32_check_window(quit, resize, width, height); 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) static void gfx_ctx_wgl_swap_buffers(void *data)
{ {
(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, 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)data;
(void)width; (void)width;
(void)height; (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; return false;
} }
@ -314,6 +429,16 @@ static void *gfx_ctx_wgl_init(void *video_driver)
if (!win32_window_init(&wndclass, true, NULL)) if (!win32_window_init(&wndclass, true, NULL))
return 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"; return (void*)"wgl";
} }
@ -323,19 +448,39 @@ static void gfx_ctx_wgl_destroy(void *data)
(void)data; (void)data;
if (g_hrc) switch (g_api)
{ {
glFinish(); case GFX_CTX_OPENGL_API:
wglMakeCurrent(NULL, NULL); #ifdef HAVE_OPENGL
if (g_hrc)
{
glFinish();
wglMakeCurrent(NULL, NULL);
if (!video_driver_ctl(RARCH_DISPLAY_CTL_IS_VIDEO_CACHE_CONTEXT, NULL)) if (!video_driver_ctl(RARCH_DISPLAY_CTL_IS_VIDEO_CACHE_CONTEXT, NULL))
{ {
if (g_hw_hrc) if (g_hw_hrc)
wglDeleteContext(g_hw_hrc); wglDeleteContext(g_hw_hrc);
wglDeleteContext(g_hrc); wglDeleteContext(g_hrc);
g_hrc = NULL; g_hrc = NULL;
g_hw_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) 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)) if (!win32_set_video_mode(NULL, width, height, fullscreen))
goto error; goto error;
p_swap_interval = (BOOL (APIENTRY *)(int)) switch (g_api)
wglGetProcAddress("wglSwapIntervalEXT"); {
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; return true;
@ -430,8 +582,9 @@ static bool gfx_ctx_wgl_bind_api(void *data,
g_major = major; g_major = major;
g_minor = minor; 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) 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) 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) if (g_hdc)
wglMakeCurrent(g_hdc, enable ? g_hw_hrc : g_hrc); 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 = { const gfx_ctx_driver_t gfx_ctx_wgl = {