mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-24 08:30:16 +00:00
Add HW context support to X/EGL and KMS/EGL.
This commit is contained in:
parent
f658112756
commit
105872a42c
@ -47,6 +47,8 @@
|
||||
#include <sys/poll.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
static bool g_use_hw_ctx;
|
||||
static EGLContext g_egl_hw_ctx;
|
||||
static EGLContext g_egl_ctx;
|
||||
static EGLSurface g_egl_surf;
|
||||
static EGLDisplay g_egl_dpy;
|
||||
@ -593,9 +595,19 @@ static bool gfx_ctx_set_video_mode(void *data,
|
||||
goto error;
|
||||
|
||||
g_egl_ctx = eglCreateContext(g_egl_dpy, g_config, EGL_NO_CONTEXT, (g_api == GFX_CTX_OPENGL_ES_API) ? gles_context_attribs : NULL);
|
||||
if (!g_egl_ctx)
|
||||
if (g_egl_ctx == EGL_NO_CONTEXT)
|
||||
goto error;
|
||||
|
||||
if (g_use_hw_ctx)
|
||||
{
|
||||
g_egl_hw_ctx = eglCreateContext(g_egl_dpy, g_config, g_egl_ctx,
|
||||
(g_api == GFX_CTX_OPENGL_ES_API) ? gles_context_attribs : NULL);
|
||||
RARCH_LOG("[KMS/EGL]: Created shared context: %p.\n", (void*)g_egl_hw_ctx);
|
||||
|
||||
if (g_egl_hw_ctx == EGL_NO_CONTEXT)
|
||||
goto error;
|
||||
}
|
||||
|
||||
g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_config, (EGLNativeWindowType)g_gbm_surface, NULL);
|
||||
if (!g_egl_surf)
|
||||
goto error;
|
||||
@ -636,6 +648,9 @@ void gfx_ctx_destroy(void *data)
|
||||
eglDestroyContext(g_egl_dpy, g_egl_ctx);
|
||||
}
|
||||
|
||||
if (g_egl_hw_ctx)
|
||||
eglDestroyContext(g_egl_dpy, g_egl_hw_ctx);
|
||||
|
||||
if (g_egl_surf)
|
||||
eglDestroySurface(g_egl_dpy, g_egl_surf);
|
||||
eglTerminate(g_egl_dpy);
|
||||
@ -717,6 +732,14 @@ static bool gfx_ctx_bind_api(void *data, enum gfx_ctx_api api, unsigned major, u
|
||||
}
|
||||
}
|
||||
|
||||
static void gfx_ctx_bind_hw_render(void *data, bool enable)
|
||||
{
|
||||
(void)data;
|
||||
g_use_hw_ctx = enable;
|
||||
if (g_egl_dpy)
|
||||
eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, enable ? g_egl_hw_ctx : g_egl_ctx);
|
||||
}
|
||||
|
||||
const gfx_ctx_driver_t gfx_ctx_drm_egl = {
|
||||
gfx_ctx_init,
|
||||
gfx_ctx_destroy,
|
||||
@ -736,5 +759,6 @@ const gfx_ctx_driver_t gfx_ctx_drm_egl = {
|
||||
NULL,
|
||||
NULL,
|
||||
"kms-egl",
|
||||
gfx_ctx_bind_hw_render,
|
||||
};
|
||||
|
||||
|
@ -40,6 +40,7 @@ static unsigned g_screen;
|
||||
static XIM g_xim;
|
||||
static XIC g_xic;
|
||||
|
||||
static bool g_use_hw_ctx;
|
||||
static GLXContext g_ctx, g_hw_ctx;
|
||||
static GLXFBConfig g_fbc;
|
||||
static unsigned g_major;
|
||||
@ -413,15 +414,26 @@ static bool gfx_ctx_set_video_mode(void *data,
|
||||
|
||||
*aptr = None;
|
||||
g_ctx = glx_create_context_attribs(g_dpy, g_fbc, NULL, True, attribs);
|
||||
g_hw_ctx = glx_create_context_attribs(g_dpy, g_fbc, g_ctx, True, attribs);
|
||||
if (g_use_hw_ctx)
|
||||
{
|
||||
RARCH_LOG("[GLX]: Creating shared HW context.\n");
|
||||
g_hw_ctx = glx_create_context_attribs(g_dpy, g_fbc, g_ctx, True, attribs);
|
||||
if (!g_hw_ctx)
|
||||
RARCH_ERR("[GLX]: Failed to create new shared context.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_ctx = glXCreateNewContext(g_dpy, g_fbc, GLX_RGBA_TYPE, 0, True);
|
||||
g_hw_ctx = glXCreateNewContext(g_dpy, g_fbc, GLX_RGBA_TYPE, g_ctx, True);
|
||||
if (g_use_hw_ctx)
|
||||
{
|
||||
g_hw_ctx = glXCreateNewContext(g_dpy, g_fbc, GLX_RGBA_TYPE, g_ctx, True);
|
||||
if (!g_hw_ctx)
|
||||
RARCH_ERR("[GLX]: Failed to create new shared context.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!g_ctx || !g_hw_ctx)
|
||||
if (!g_ctx)
|
||||
{
|
||||
RARCH_ERR("[GLX]: Failed to create new context.\n");
|
||||
goto error;
|
||||
@ -504,7 +516,8 @@ static void gfx_ctx_destroy(void *data)
|
||||
glXMakeContextCurrent(g_dpy, None, None, NULL);
|
||||
if (!driver.video_cache_context)
|
||||
{
|
||||
glXDestroyContext(g_dpy, g_hw_ctx);
|
||||
if (g_hw_ctx)
|
||||
glXDestroyContext(g_dpy, g_hw_ctx);
|
||||
glXDestroyContext(g_dpy, g_ctx);
|
||||
g_ctx = NULL;
|
||||
g_hw_ctx = NULL;
|
||||
@ -605,8 +618,13 @@ static void gfx_ctx_show_mouse(void *data, bool state)
|
||||
static void gfx_ctx_bind_hw_render(void *data, bool enable)
|
||||
{
|
||||
(void)data;
|
||||
RARCH_LOG("[GLX]: Binding context (%s): %p\n", enable ? "RetroArch" : "HW render", enable ? (void*)g_hw_ctx : (void*)g_ctx);
|
||||
glXMakeContextCurrent(g_dpy, g_glx_win, g_glx_win, enable ? g_hw_ctx : g_ctx);
|
||||
g_use_hw_ctx = enable;
|
||||
|
||||
if (g_dpy)
|
||||
{
|
||||
//RARCH_LOG("[GLX]: Binding context (%s): %p\n", enable ? "RetroArch" : "HW render", enable ? (void*)g_hw_ctx : (void*)g_ctx);
|
||||
glXMakeContextCurrent(g_dpy, g_glx_win, g_glx_win, enable ? g_hw_ctx : g_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
const gfx_ctx_driver_t gfx_ctx_glx = {
|
||||
|
@ -41,6 +41,8 @@ static unsigned g_screen;
|
||||
static XIM g_xim;
|
||||
static XIC g_xic;
|
||||
|
||||
static bool g_use_hw_ctx;
|
||||
static EGLContext g_egl_hw_ctx;
|
||||
static EGLContext g_egl_ctx;
|
||||
static EGLSurface g_egl_surf;
|
||||
static EGLDisplay g_egl_dpy;
|
||||
@ -422,10 +424,19 @@ static bool gfx_ctx_set_video_mode(void *data,
|
||||
(g_api == GFX_CTX_OPENGL_ES_API) ? egl_ctx_gles_attribs : NULL);
|
||||
|
||||
RARCH_LOG("[X/EGL]: Created context: %p.\n", (void*)g_egl_ctx);
|
||||
|
||||
if (!g_egl_ctx)
|
||||
if (g_egl_ctx == EGL_NO_CONTEXT)
|
||||
goto error;
|
||||
|
||||
if (g_use_hw_ctx)
|
||||
{
|
||||
g_egl_hw_ctx = eglCreateContext(g_egl_dpy, g_config, g_egl_ctx,
|
||||
(g_api == GFX_CTX_OPENGL_ES_API) ? egl_ctx_gles_attribs : NULL);
|
||||
RARCH_LOG("[X/EGL]: Created shared context: %p.\n", (void*)g_egl_hw_ctx);
|
||||
|
||||
if (g_egl_hw_ctx == EGL_NO_CONTEXT)
|
||||
goto error;
|
||||
}
|
||||
|
||||
g_egl_surf = eglCreateWindowSurface(g_egl_dpy, g_config, (EGLNativeWindowType)g_win, NULL);
|
||||
if (!g_egl_surf)
|
||||
goto error;
|
||||
@ -513,6 +524,9 @@ static void gfx_ctx_destroy(void *data)
|
||||
eglDestroyContext(g_egl_dpy, g_egl_ctx);
|
||||
}
|
||||
|
||||
if (g_egl_hw_ctx)
|
||||
eglDestroyContext(g_egl_dpy, g_egl_hw_ctx);
|
||||
|
||||
if (g_egl_surf)
|
||||
eglDestroySurface(g_egl_dpy, g_egl_surf);
|
||||
eglTerminate(g_egl_dpy);
|
||||
@ -622,6 +636,14 @@ static void gfx_ctx_show_mouse(void *data, bool state)
|
||||
x11_show_mouse(g_dpy, g_win, state);
|
||||
}
|
||||
|
||||
static void gfx_ctx_bind_hw_render(void *data, bool enable)
|
||||
{
|
||||
(void)data;
|
||||
g_use_hw_ctx = enable;
|
||||
if (g_egl_dpy)
|
||||
eglMakeCurrent(g_egl_dpy, g_egl_surf, g_egl_surf, enable ? g_egl_hw_ctx : g_egl_ctx);
|
||||
}
|
||||
|
||||
const gfx_ctx_driver_t gfx_ctx_x_egl = {
|
||||
gfx_ctx_init,
|
||||
gfx_ctx_destroy,
|
||||
@ -641,5 +663,6 @@ const gfx_ctx_driver_t gfx_ctx_x_egl = {
|
||||
NULL,
|
||||
gfx_ctx_show_mouse,
|
||||
"x-egl",
|
||||
gfx_ctx_bind_hw_render,
|
||||
};
|
||||
|
||||
|
@ -1405,7 +1405,7 @@ static const gfx_ctx_driver_t *d3d_get_context(void)
|
||||
major = 9;
|
||||
#endif
|
||||
minor = 0;
|
||||
return gfx_ctx_init_first(driver.video_data, api, major, minor);
|
||||
return gfx_ctx_init_first(driver.video_data, api, major, minor, false);
|
||||
}
|
||||
|
||||
static void *d3d_init(const video_info_t *info, const input_driver_t **input,
|
||||
|
@ -71,13 +71,15 @@ const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const gfx_ctx_driver_t *gfx_ctx_init_first(void *data, enum gfx_ctx_api api, unsigned major, unsigned minor)
|
||||
const gfx_ctx_driver_t *gfx_ctx_init_first(void *data, enum gfx_ctx_api api, unsigned major, unsigned minor, bool hw_render_ctx)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; gfx_ctx_drivers[i]; i++)
|
||||
{
|
||||
if (gfx_ctx_drivers[i]->bind_api(data, api, major, minor))
|
||||
{
|
||||
if (gfx_ctx_drivers[i]->bind_hw_render)
|
||||
gfx_ctx_drivers[i]->bind_hw_render(data, hw_render_ctx);
|
||||
if (gfx_ctx_drivers[i]->init(data))
|
||||
return gfx_ctx_drivers[i];
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ extern const gfx_ctx_driver_t gfx_ctx_emscripten;
|
||||
extern const gfx_ctx_driver_t gfx_ctx_null;
|
||||
|
||||
const gfx_ctx_driver_t *gfx_ctx_find_driver(const char *ident); // Finds driver with ident. Does not initialize.
|
||||
const gfx_ctx_driver_t *gfx_ctx_init_first(void *data, enum gfx_ctx_api api, unsigned major, unsigned minor); // Finds first suitable driver and initializes.
|
||||
const gfx_ctx_driver_t *gfx_ctx_init_first(void *data, enum gfx_ctx_api api, unsigned major, unsigned minor, bool hw_render_ctx); // Finds first suitable driver and initializes.
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
6
gfx/gl.c
6
gfx/gl.c
@ -1927,6 +1927,10 @@ static const gfx_ctx_driver_t *gl_get_context(gl_t *gl)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Enables or disables offscreen HW context.
|
||||
if (ctx->bind_hw_render)
|
||||
ctx->bind_hw_render(gl, cb->context_type != RETRO_HW_CONTEXT_NONE);
|
||||
|
||||
if (!ctx->init(gl))
|
||||
{
|
||||
RARCH_ERR("Failed to init GL context: %s.\n", ctx->ident);
|
||||
@ -1942,7 +1946,7 @@ static const gfx_ctx_driver_t *gl_get_context(gl_t *gl)
|
||||
return ctx;
|
||||
}
|
||||
else
|
||||
return gfx_ctx_init_first(gl, api, major, minor);
|
||||
return gfx_ctx_init_first(gl, api, major, minor, cb->context_type != RETRO_HW_CONTEXT_NONE);
|
||||
}
|
||||
|
||||
#ifdef GL_DEBUG
|
||||
|
2
gfx/vg.c
2
gfx/vg.c
@ -87,7 +87,7 @@ static void *vg_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
if (!vg)
|
||||
return NULL;
|
||||
|
||||
vg->driver = gfx_ctx_init_first(vg, GFX_CTX_OPENVG_API, 0, 0);
|
||||
vg->driver = gfx_ctx_init_first(vg, GFX_CTX_OPENVG_API, 0, 0, false);
|
||||
|
||||
if (!vg->driver)
|
||||
{
|
||||
|
@ -299,7 +299,7 @@ static const gfx_ctx_driver_t *d3d_get_context(void *data)
|
||||
major = 9;
|
||||
#endif
|
||||
minor = 0;
|
||||
return gfx_ctx_init_first(d3d, api, major, minor);
|
||||
return gfx_ctx_init_first(d3d, api, major, minor, false);
|
||||
}
|
||||
|
||||
static bool d3d_init_base(void *data, const video_info_t *info)
|
||||
|
Loading…
Reference in New Issue
Block a user