Add OPENGLES3 context support in libretro GL.

This commit is contained in:
Themaister 2013-12-13 14:19:25 +01:00
parent ec16902923
commit 6031590cd3
8 changed files with 83 additions and 20 deletions

View File

@ -232,7 +232,7 @@ ifeq ($(HAVE_OPENGL), 1)
ifeq ($(HAVE_GLES), 1)
LIBS += -lGLESv2
DEFINES += -DHAVE_OPENGLES -DHAVE_OPENGLES2
DEFINES += -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_OPENGLES3
OBJ += gfx/glsym/glsym_es2.o
else
DEFINES += -DHAVE_GL_SYNC

View File

@ -698,7 +698,11 @@ bool rarch_environment_cb(unsigned cmd, void *data)
#if defined(HAVE_OPENGLES2)
case RETRO_HW_CONTEXT_OPENGLES2:
RARCH_LOG("Requesting OpenGLES2 context.\n");
#if defined(HAVE_OPENGLES3)
case RETRO_HW_CONTEXT_OPENGLES3:
#endif
RARCH_LOG("Requesting OpenGLES%u context.\n",
cb->context_type == RETRO_HW_CONTEXT_OPENGLES2 ? 2 : 3);
break;
case RETRO_HW_CONTEXT_OPENGL:
@ -707,7 +711,9 @@ bool rarch_environment_cb(unsigned cmd, void *data)
return false;
#elif defined(HAVE_OPENGL)
case RETRO_HW_CONTEXT_OPENGLES2:
RARCH_ERR("Requesting OpenGLES2 context, but RetroArch is compiled against OpenGL. Cannot use HW context.\n");
case RETRO_HW_CONTEXT_OPENGLES3:
RARCH_ERR("Requesting OpenGLES%u context, but RetroArch is compiled against OpenGL. Cannot use HW context.\n",
cb->context_type == RETRO_HW_CONTEXT_OPENGLES2 ? 2 : 3);
return false;
case RETRO_HW_CONTEXT_OPENGL:

View File

@ -55,6 +55,8 @@ static volatile sig_atomic_t g_quit;
static bool g_inited;
static unsigned g_interval;
static enum gfx_ctx_api g_api;
static unsigned g_major;
static unsigned g_minor;
static struct gbm_device *g_gbm_dev;
static struct gbm_surface *g_gbm_surface;
@ -393,15 +395,23 @@ static bool gfx_ctx_set_video_mode(
EGL_NONE,
};
#ifdef EGL_OPENGL_ES3_BIT_KHR
static const EGLint egl_attribs_gles3[] = {
EGL_ATTRIBS_BASE,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
EGL_NONE,
};
#endif
static const EGLint egl_attribs_vg[] = {
EGL_ATTRIBS_BASE,
EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
EGL_NONE,
};
// GLES 2.0. Don't use for any other API.
static const EGLint gles_context_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
// GLES 2.0+. Don't use for any other API.
const EGLint gles_context_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, g_major ? g_major : 2,
EGL_NONE
};
@ -412,6 +422,11 @@ static bool gfx_ctx_set_video_mode(
attrib_ptr = egl_attribs_gl;
break;
case GFX_CTX_OPENGL_ES_API:
#ifdef EGL_OPENGL_ES3_BIT_KHR
if (g_major >= 3)
attrib_ptr = egl_attribs_gles3;
else
#endif
attrib_ptr = egl_attribs_gles;
break;
case GFX_CTX_OPENVG_API:
@ -568,14 +583,18 @@ static gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol)
static bool gfx_ctx_bind_api(enum gfx_ctx_api api, unsigned major, unsigned minor)
{
(void)major;
(void)minor;
g_major = major;
g_minor = minor;
g_api = api;
switch (api)
{
case GFX_CTX_OPENGL_API:
return eglBindAPI(EGL_OPENGL_API);
case GFX_CTX_OPENGL_ES_API:
#ifndef EGL_OPENGL_ES3_BIT_KHR
if (major >= 3)
return false;
#endif
return eglBindAPI(EGL_OPENGL_ES_API);
case GFX_CTX_OPENVG_API:
return eglBindAPI(EGL_OPENVG_API);

View File

@ -53,6 +53,8 @@ static volatile sig_atomic_t g_quit;
static bool g_inited;
static unsigned g_interval;
static enum gfx_ctx_api g_api;
static unsigned g_major;
static unsigned g_minor;
static void sighandler(int sig)
{
@ -248,6 +250,14 @@ static bool gfx_ctx_init(void)
EGL_NONE,
};
#ifdef EGL_OPENGL_ES3_BIT_KHR
static const EGLint egl_attribs_gles3[] = {
EGL_ATTRIBS_BASE,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
EGL_NONE,
};
#endif
static const EGLint egl_attribs_vg[] = {
EGL_ATTRIBS_BASE,
EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
@ -261,7 +271,12 @@ static bool gfx_ctx_init(void)
attrib_ptr = egl_attribs_gl;
break;
case GFX_CTX_OPENGL_ES_API:
attrib_ptr = egl_attribs_gles;
#ifdef EGL_OPENGL_ES3_BIT_KHR
if (g_major >= 3)
attrib_ptr = egl_attribs_gles3;
else
#endif
attrib_ptr = egl_attribs_gles;
break;
case GFX_CTX_OPENVG_API:
attrib_ptr = egl_attribs_vg;
@ -390,9 +405,9 @@ static bool gfx_ctx_set_video_mode(
CWBorderPixel | CWColormap | CWEventMask | (true_full ? CWOverrideRedirect : 0), &swa);
XSetWindowBackground(g_dpy, g_win, 0);
// GLES 2.0. Don't use for any other API.
static const EGLint egl_ctx_gles_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
// GLES 2.0+. Don't use for any other API.
const EGLint egl_ctx_gles_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, g_major ? g_major : 2,
EGL_NONE,
};
@ -570,14 +585,18 @@ static gfx_ctx_proc_t gfx_ctx_get_proc_address(const char *symbol)
static bool gfx_ctx_bind_api(enum gfx_ctx_api api, unsigned major, unsigned minor)
{
(void)major;
(void)minor;
g_major = major;
g_minor = minor;
g_api = api;
switch (api)
{
case GFX_CTX_OPENGL_API:
return eglBindAPI(EGL_OPENGL_API);
case GFX_CTX_OPENGL_ES_API:
#ifndef EGL_OPENGL_ES3_BIT_KHR
if (major >= 3)
return false;
#endif
return eglBindAPI(EGL_OPENGL_ES_API);
case GFX_CTX_OPENVG_API:
return eglBindAPI(EGL_OPENVG_API);

View File

@ -1834,11 +1834,20 @@ static void gl_init_pbo_readback(void *data)
static const gfx_ctx_driver_t *gl_get_context(void)
{
unsigned major = g_extern.system.hw_render_callback.version_major;
unsigned minor = g_extern.system.hw_render_callback.version_minor;
const struct retro_hw_render_callback *cb = &g_extern.system.hw_render_callback;
unsigned major = cb->version_major;
unsigned minor = cb->version_minor;
#ifdef HAVE_OPENGLES
enum gfx_ctx_api api = GFX_CTX_OPENGL_ES_API;
const char *api_name = "OpenGL ES";
const char *api_name = "OpenGL ES 2.0";
#ifdef HAVE_OPENGLES3
if (cb->context_type == RETRO_HW_CONTEXT_OPENGLES3)
{
major = 3;
minor = 0;
api_name = "OpenGL ES 3.0";
}
#endif
#else
enum gfx_ctx_api api = GFX_CTX_OPENGL_API;
const char *api_name = "OpenGL";
@ -2047,7 +2056,9 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo
// but still need multiple textures with PREV.
gl->textures = 4;
#ifdef HAVE_FBO
#ifdef HAVE_OPENGLES2
#if defined(HAVE_OPENGLES3)
gl->hw_render_use = hw_render->context_type == RETRO_HW_CONTEXT_OPENGLES2 || hw_render->context_type == RETRO_HW_CONTEXT_OPENGLES3;
#elif defined(HAVE_OPENGLES2)
gl->hw_render_use = hw_render->context_type == RETRO_HW_CONTEXT_OPENGLES2;
#else
gl->hw_render_use = hw_render->context_type == RETRO_HW_CONTEXT_OPENGL ||

View File

@ -101,7 +101,10 @@ CFLAGS += -Wall -pedantic $(fpic)
ifeq ($(GLES), 1)
CFLAGS += -DGLES -DHAVE_OPENGLES2
LIBS += -lGLESv2
ifeq ($(GLES3), 1)
CFLAGS += -DHAVE_OPENGLES3 -DGLES3
endif
LIBS += -lGLESv2 # Still link against GLESv2 when using GLES3 API, at least on desktop Linux.
OBJECTS += ../gfx/glsym/glsym_es2.o
else
OBJECTS += ../gfx/glsym/glsym_gl.o

View File

@ -448,7 +448,11 @@ bool retro_load_game(const struct retro_game_info *info)
}
#ifdef GLES
#ifdef GLES3
hw_render.context_type = RETRO_HW_CONTEXT_OPENGLES3;
#else
hw_render.context_type = RETRO_HW_CONTEXT_OPENGLES2;
#endif
#else
#ifdef CORE
hw_render.context_type = RETRO_HW_CONTEXT_OPENGL_CORE;

View File

@ -718,9 +718,10 @@ typedef retro_proc_address_t (*retro_hw_get_proc_address_t)(const char *sym);
enum retro_hw_context_type
{
RETRO_HW_CONTEXT_NONE = 0,
RETRO_HW_CONTEXT_OPENGL, // OpenGL 2.x. Latest version available before 3.x+.
RETRO_HW_CONTEXT_OPENGL, // OpenGL 2.x. Latest version available before 3.x+. Driver can choose to use latest compatibility context.
RETRO_HW_CONTEXT_OPENGLES2, // GLES 2.0
RETRO_HW_CONTEXT_OPENGL_CORE, // Modern desktop core GL context. Use major/minor fields to set GL version.
RETRO_HW_CONTEXT_OPENGLES3, // GLES 3.0
RETRO_HW_CONTEXT_DUMMY = INT_MAX
};