mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-24 08:30:16 +00:00
Add experimental support for separate HW contexts.
This commit is contained in:
parent
71cdc3b6ba
commit
f658112756
@ -40,7 +40,7 @@ static unsigned g_screen;
|
||||
static XIM g_xim;
|
||||
static XIC g_xic;
|
||||
|
||||
static GLXContext g_ctx;
|
||||
static GLXContext g_ctx, g_hw_ctx;
|
||||
static GLXFBConfig g_fbc;
|
||||
static unsigned g_major;
|
||||
static unsigned g_minor;
|
||||
@ -413,11 +413,15 @@ 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);
|
||||
}
|
||||
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_ctx)
|
||||
if (!g_ctx || !g_hw_ctx)
|
||||
{
|
||||
RARCH_ERR("[GLX]: Failed to create new context.\n");
|
||||
goto error;
|
||||
@ -500,8 +504,10 @@ static void gfx_ctx_destroy(void *data)
|
||||
glXMakeContextCurrent(g_dpy, None, None, NULL);
|
||||
if (!driver.video_cache_context)
|
||||
{
|
||||
glXDestroyContext(g_dpy, g_hw_ctx);
|
||||
glXDestroyContext(g_dpy, g_ctx);
|
||||
g_ctx = NULL;
|
||||
g_hw_ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -596,6 +602,13 @@ 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;
|
||||
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 = {
|
||||
gfx_ctx_init,
|
||||
gfx_ctx_destroy,
|
||||
@ -617,5 +630,7 @@ const gfx_ctx_driver_t gfx_ctx_glx = {
|
||||
#endif
|
||||
gfx_ctx_show_mouse,
|
||||
"glx",
|
||||
|
||||
gfx_ctx_bind_hw_render,
|
||||
};
|
||||
|
||||
|
@ -103,6 +103,9 @@ typedef struct gfx_ctx_driver
|
||||
|
||||
// Human readable string.
|
||||
const char *ident;
|
||||
|
||||
// Optional. Binds HW-render offscreen context.
|
||||
void (*bind_hw_render)(void *data, bool enable);
|
||||
} gfx_ctx_driver_t;
|
||||
|
||||
extern const gfx_ctx_driver_t gfx_ctx_sdl_gl;
|
||||
|
43
gfx/gl.c
43
gfx/gl.c
@ -631,15 +631,23 @@ void gl_init_fbo(void *data, unsigned width, unsigned height)
|
||||
#ifndef HAVE_GCMGL
|
||||
static void gl_deinit_hw_render(gl_t *gl)
|
||||
{
|
||||
context_bind_hw_render(gl, true);
|
||||
|
||||
if (gl->hw_render_fbo_init)
|
||||
glDeleteFramebuffers(gl->textures, gl->hw_render_fbo);
|
||||
if (gl->hw_render_depth_init)
|
||||
glDeleteRenderbuffers(gl->textures, gl->hw_render_depth);
|
||||
gl->hw_render_fbo_init = false;
|
||||
|
||||
context_bind_hw_render(gl, false);
|
||||
}
|
||||
|
||||
static bool gl_init_hw_render(gl_t *gl, unsigned width, unsigned height)
|
||||
{
|
||||
// We can only share texture objects through contexts.
|
||||
// FBOs are "abstract" objects and are not shared.
|
||||
context_bind_hw_render(gl, true);
|
||||
|
||||
unsigned i;
|
||||
RARCH_LOG("[GL]: Initializing HW render (%u x %u).\n", width, height);
|
||||
GLint max_fbo_size = 0;
|
||||
@ -720,6 +728,8 @@ static bool gl_init_hw_render(gl_t *gl, unsigned width, unsigned height)
|
||||
|
||||
gl_bind_backbuffer();
|
||||
gl->hw_render_fbo_init = true;
|
||||
|
||||
context_bind_hw_render(gl, false);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@ -1385,6 +1395,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
|
||||
RARCH_PERFORMANCE_START(frame_run);
|
||||
|
||||
gl_t *gl = (gl_t*)data;
|
||||
context_bind_hw_render(gl, false);
|
||||
|
||||
#ifndef HAVE_OPENGLES
|
||||
if (gl->core_context)
|
||||
@ -1574,6 +1585,8 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei
|
||||
glBindVertexArray(0);
|
||||
#endif
|
||||
|
||||
context_bind_hw_render(gl, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1599,6 +1612,7 @@ static void gl_free(void *data)
|
||||
#endif
|
||||
|
||||
gl_t *gl = (gl_t*)data;
|
||||
context_bind_hw_render(gl, false);
|
||||
|
||||
#ifdef HAVE_GL_SYNC
|
||||
if (gl->have_sync)
|
||||
@ -1674,7 +1688,9 @@ static void gl_set_nonblock_state(void *data, bool state)
|
||||
RARCH_LOG("GL VSync => %s\n", state ? "off" : "on");
|
||||
|
||||
gl_t *gl = (gl_t*)data;
|
||||
context_bind_hw_render(gl, false);
|
||||
context_swap_interval_func(gl, state ? 0 : g_settings.video.swap_interval);
|
||||
context_bind_hw_render(gl, true);
|
||||
}
|
||||
|
||||
static bool resolve_extensions(gl_t *gl)
|
||||
@ -2113,7 +2129,14 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
g_extern.system.hw_render_callback.context_type == RETRO_HW_CONTEXT_OPENGL_CORE;
|
||||
#endif
|
||||
if (gl->hw_render_use)
|
||||
{
|
||||
gl->textures = 1; // All on GPU, no need to excessively create textures.
|
||||
#ifdef GL_DEBUG
|
||||
context_set_hw_render(true);
|
||||
gl_begin_debug(gl);
|
||||
context_set_hw_render(false);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
gl->white_color_ptr = white_color;
|
||||
|
||||
@ -2224,6 +2247,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context_bind_hw_render(gl, true);
|
||||
return gl;
|
||||
}
|
||||
|
||||
@ -2254,6 +2278,7 @@ static void gl_update_tex_filter_frame(gl_t *gl)
|
||||
{
|
||||
unsigned i;
|
||||
bool smooth = false;
|
||||
context_bind_hw_render(gl, false);
|
||||
if (!gl_shader_filter_type(gl, 1, &smooth))
|
||||
smooth = g_settings.video.smooth;
|
||||
GLenum wrap_mode = gl_wrap_type_to_enum(gl_shader_wrap_type(gl, 1));
|
||||
@ -2278,12 +2303,14 @@ static void gl_update_tex_filter_frame(gl_t *gl)
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);
|
||||
context_bind_hw_render(gl, true);
|
||||
}
|
||||
|
||||
#if defined(HAVE_GLSL) || defined(HAVE_CG)
|
||||
static bool gl_set_shader(void *data, enum rarch_shader_type type, const char *path)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
context_bind_hw_render(gl, false);
|
||||
|
||||
if (type == RARCH_SHADER_NONE)
|
||||
return false;
|
||||
@ -2312,6 +2339,7 @@ static bool gl_set_shader(void *data, enum rarch_shader_type type, const char *p
|
||||
if (!gl->shader)
|
||||
{
|
||||
RARCH_ERR("[GL]: Cannot find shader core for path: %s.\n", path);
|
||||
context_bind_hw_render(gl, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2326,6 +2354,7 @@ static bool gl_set_shader(void *data, enum rarch_shader_type type, const char *p
|
||||
bool ret = gl->shader->init(gl, NULL);
|
||||
if (!ret)
|
||||
gl->shader = NULL;
|
||||
context_bind_hw_render(gl, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2366,6 +2395,7 @@ static bool gl_set_shader(void *data, enum rarch_shader_type type, const char *p
|
||||
// Apparently need to set viewport for passes when we aren't using FBOs.
|
||||
gl_set_shader_viewport(gl, 0);
|
||||
gl_set_shader_viewport(gl, 1);
|
||||
context_bind_hw_render(gl, true);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@ -2387,6 +2417,7 @@ static void gl_viewport_info(void *data, struct rarch_viewport *vp)
|
||||
static bool gl_read_viewport(void *data, uint8_t *buffer)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
context_bind_hw_render(gl, false);
|
||||
|
||||
RARCH_PERFORMANCE_INIT(read_viewport);
|
||||
RARCH_PERFORMANCE_START(read_viewport);
|
||||
@ -2423,6 +2454,7 @@ static bool gl_read_viewport(void *data, uint8_t *buffer)
|
||||
if (!gl->readback_buffer_screenshot)
|
||||
{
|
||||
RARCH_PERFORMANCE_STOP(read_viewport);
|
||||
context_bind_hw_render(gl, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2443,6 +2475,7 @@ static bool gl_read_viewport(void *data, uint8_t *buffer)
|
||||
}
|
||||
|
||||
RARCH_PERFORMANCE_STOP(read_viewport);
|
||||
context_bind_hw_render(gl, true);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@ -2471,11 +2504,15 @@ static bool gl_overlay_load(void *data, const struct texture_image *images, unsi
|
||||
{
|
||||
unsigned i;
|
||||
gl_t *gl = (gl_t*)data;
|
||||
context_bind_hw_render(gl, false);
|
||||
|
||||
gl_free_overlay(gl);
|
||||
gl->overlay = (struct gl_overlay_data*)calloc(num_images, sizeof(*gl->overlay));
|
||||
if (!gl->overlay)
|
||||
{
|
||||
context_bind_hw_render(gl, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
gl->overlays = num_images;
|
||||
|
||||
@ -2499,6 +2536,7 @@ static bool gl_overlay_load(void *data, const struct texture_image *images, unsi
|
||||
gl->overlay[i].alpha_mod = 1.0f;
|
||||
}
|
||||
|
||||
context_bind_hw_render(gl, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2658,6 +2696,7 @@ static void gl_set_texture_frame(void *data,
|
||||
float alpha)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
context_bind_hw_render(gl, false);
|
||||
|
||||
if (!gl->rgui_texture)
|
||||
{
|
||||
@ -2692,6 +2731,7 @@ static void gl_set_texture_frame(void *data,
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]);
|
||||
context_bind_hw_render(gl, true);
|
||||
}
|
||||
|
||||
static void gl_set_texture_enable(void *data, bool state, bool full_screen)
|
||||
@ -2711,10 +2751,12 @@ static void gl_apply_state_changes(void *data)
|
||||
static void gl_set_osd_msg(void *data, const char *msg, void *userdata)
|
||||
{
|
||||
gl_t *gl = (gl_t*)data;
|
||||
context_bind_hw_render(gl, false);
|
||||
font_params_t *params = (font_params_t*)userdata;
|
||||
|
||||
if (gl->font_ctx)
|
||||
gl->font_ctx->render_msg(gl, msg, params);
|
||||
context_bind_hw_render(gl, true);
|
||||
}
|
||||
|
||||
static void gl_show_mouse(void *data, bool state)
|
||||
@ -2782,4 +2824,3 @@ const video_driver_t video_gl = {
|
||||
gl_get_poke_interface,
|
||||
};
|
||||
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
||||
#define context_swap_buffers_func(gl) gl->ctx_driver->swap_buffers(gl)
|
||||
#define context_swap_interval_func(gl, var) gl->ctx_driver->swap_interval(gl, var)
|
||||
#define context_has_focus_func(gl) gl->ctx_driver->has_focus(gl)
|
||||
#define context_bind_hw_render(gl, enable) if (gl->hw_render_use && gl->ctx_driver->bind_hw_render) gl->ctx_driver->bind_hw_render(gl, enable)
|
||||
#define context_check_window_func(gl, quit, resize, width, height, frame_count) \
|
||||
gl->ctx_driver->check_window(gl, quit, resize, width, height, frame_count)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user