mirror of
https://github.com/libretro/RetroArch
synced 2025-03-28 19:20:35 +00:00
opengl: loop through highest available versions to find a working one, only do hwapi check on glx/wgl for now
This commit is contained in:
parent
22a62363b3
commit
7479245875
@ -242,7 +242,7 @@ static void create_gl_context(HWND hwnd, bool *quit)
|
||||
|
||||
if (core_context || debug)
|
||||
{
|
||||
int attribs[16];
|
||||
int attribs[16] = {0};
|
||||
int *aptr = attribs;
|
||||
|
||||
if (core_context)
|
||||
@ -274,29 +274,71 @@ static void create_gl_context(HWND hwnd, bool *quit)
|
||||
if (!pcreate_context)
|
||||
pcreate_context = (wglCreateContextAttribsProc)gfx_ctx_wgl_get_proc_address("wglCreateContextAttribsARB");
|
||||
|
||||
/* In order to support the core info "required_hw_api" field correctly, we should try to init the highest available
|
||||
* version GL context possible. This means trying successively lower versions until it works, because GL has
|
||||
* no facility for determining the highest possible supported version.
|
||||
*/
|
||||
if (pcreate_context)
|
||||
{
|
||||
HGLRC context = pcreate_context(win32_hdc, NULL, attribs);
|
||||
int i;
|
||||
int gl_versions[][2] = {{4, 6}, {4, 3}, {4, 0}, {3, 3}, {3, 2}, {0, 0}};
|
||||
int gl_version_rows = ARRAY_SIZE(gl_versions);
|
||||
int (*versions)[2];
|
||||
int version_rows = 0;
|
||||
HGLRC context = NULL;
|
||||
|
||||
if (context)
|
||||
{
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
wglDeleteContext(win32_hrc);
|
||||
win32_hrc = context;
|
||||
if (!wglMakeCurrent(win32_hdc, win32_hrc))
|
||||
*quit = true;
|
||||
}
|
||||
else
|
||||
RARCH_ERR("[WGL]: Failed to create core context. Falling back to legacy context.\n");
|
||||
versions = gl_versions;
|
||||
version_rows = gl_version_rows;
|
||||
|
||||
if (win32_use_hw_ctx)
|
||||
/* try each version, starting with the highest first */
|
||||
for (i = 0; i < version_rows; i++)
|
||||
{
|
||||
win32_hw_hrc = pcreate_context(win32_hdc, context, attribs);
|
||||
if (!win32_hw_hrc)
|
||||
if (versions[i][0] == 0 && versions[i][1] == 0)
|
||||
{
|
||||
RARCH_ERR("[WGL]: Failed to create shared context.\n");
|
||||
*quit = true;
|
||||
/* use the actual requested version last */
|
||||
versions[i][0] = win32_major;
|
||||
versions[i][1] = win32_minor;
|
||||
}
|
||||
|
||||
attribs[1] = versions[i][0];
|
||||
attribs[3] = versions[i][1];
|
||||
|
||||
context = pcreate_context(win32_hdc, NULL, attribs);
|
||||
|
||||
if (context)
|
||||
{
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
wglDeleteContext(win32_hrc);
|
||||
win32_hrc = context;
|
||||
|
||||
if (!wglMakeCurrent(win32_hdc, win32_hrc))
|
||||
{
|
||||
*quit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
continue;
|
||||
|
||||
if (win32_use_hw_ctx)
|
||||
{
|
||||
win32_hw_hrc = pcreate_context(win32_hdc, context, attribs);
|
||||
|
||||
if (!win32_hw_hrc)
|
||||
{
|
||||
RARCH_ERR("[WGL]: Failed to create shared context.\n");
|
||||
*quit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!context)
|
||||
{
|
||||
RARCH_ERR("[WGL]: Failed to create core context. Falling back to legacy context.\n");
|
||||
*quit = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -725,7 +767,7 @@ static bool gfx_ctx_wgl_suppress_screensaver(void *data, bool enable)
|
||||
}
|
||||
|
||||
static bool gfx_ctx_wgl_get_metrics(void *data,
|
||||
enum display_metric_types type, float *value)
|
||||
enum display_metric_types type, float *value)
|
||||
{
|
||||
return win32_get_metrics(data, type, value);
|
||||
}
|
||||
|
@ -176,6 +176,19 @@ static int GLXExtensionSupported(Display *dpy, const char *extension)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int x_gl_version_error_handler(Display *dpy, XErrorEvent *event)
|
||||
{
|
||||
(void)dpy;
|
||||
|
||||
if (event->error_code == BadMatch && event->request_code == 151 && event->minor_code == 34)
|
||||
{
|
||||
RARCH_WARN("[GLX]: Version %d.%d not supported, trying a lower version.\n", g_major, g_minor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int x_nul_handler(Display *dpy, XErrorEvent *event)
|
||||
{
|
||||
(void)dpy;
|
||||
@ -816,7 +829,7 @@ static bool gfx_ctx_x_set_video_mode(void *data,
|
||||
{
|
||||
if (x->g_core_es || x->g_debug)
|
||||
{
|
||||
int attribs[16];
|
||||
int attribs[16] = {0};
|
||||
int *aptr = attribs;
|
||||
|
||||
if (x->g_core_es)
|
||||
@ -848,18 +861,75 @@ static bool gfx_ctx_x_set_video_mode(void *data,
|
||||
}
|
||||
|
||||
*aptr = None;
|
||||
x->g_ctx = glx_create_context_attribs(g_x11_dpy,
|
||||
x->g_fbc, NULL, True, attribs);
|
||||
|
||||
if (x->g_use_hw_ctx)
|
||||
/* silently ignore failures when requesting GL versions that are too high */
|
||||
old_handler = XSetErrorHandler(x_gl_version_error_handler);
|
||||
|
||||
/* In order to support the core info "required_hw_api" field correctly, we should try to init the highest available
|
||||
* version GL context possible. This means trying successively lower versions until it works, because GL has
|
||||
* no facility for determining the highest possible supported version.
|
||||
*/
|
||||
{
|
||||
RARCH_LOG("[GLX]: Creating shared HW context.\n");
|
||||
x->g_hw_ctx = glx_create_context_attribs(g_x11_dpy,
|
||||
x->g_fbc, x->g_ctx, True, attribs);
|
||||
int i;
|
||||
int gl_versions[][2] = {{4, 6}, {4, 3}, {4, 0}, {3, 3}, {3, 2}, {0, 0}};
|
||||
#ifdef HAVE_OPENGLES3
|
||||
int gles_versions[][2] = {{3, 2}, {3, 1}, {3, 0}, {0, 0}};
|
||||
#else
|
||||
int gles_versions[][2] = {{2, 1}, {2, 0}, {1, 1}, {1, 0}, {0, 0}};
|
||||
#endif
|
||||
int gl_version_rows = ARRAY_SIZE(gl_versions);
|
||||
int gles_version_rows = ARRAY_SIZE(gles_versions);
|
||||
int (*versions)[2];
|
||||
int version_rows = 0;
|
||||
|
||||
if (!x->g_hw_ctx)
|
||||
RARCH_ERR("[GLX]: Failed to create new shared context.\n");
|
||||
if (x_api == GFX_CTX_OPENGL_API)
|
||||
{
|
||||
versions = gl_versions;
|
||||
version_rows = gl_version_rows;
|
||||
}
|
||||
else if (x_api == GFX_CTX_OPENGL_ES_API)
|
||||
{
|
||||
versions = gles_versions;
|
||||
version_rows = gles_version_rows;
|
||||
}
|
||||
|
||||
/* try each version, starting with the highest first */
|
||||
for (i = 0; i < version_rows; i++)
|
||||
{
|
||||
if (versions[i][0] == 0 && versions[i][1] == 0)
|
||||
{
|
||||
/* use the actual requested version last */
|
||||
versions[i][0] = g_major;
|
||||
versions[i][1] = g_minor;
|
||||
}
|
||||
|
||||
attribs[1] = versions[i][0];
|
||||
attribs[3] = versions[i][1];
|
||||
|
||||
x->g_ctx = glx_create_context_attribs(g_x11_dpy,
|
||||
x->g_fbc, NULL, True, attribs);
|
||||
|
||||
if (!x->g_ctx)
|
||||
continue;
|
||||
|
||||
if (x->g_use_hw_ctx)
|
||||
{
|
||||
RARCH_LOG("[GLX]: Creating shared HW context.\n");
|
||||
x->g_hw_ctx = glx_create_context_attribs(g_x11_dpy,
|
||||
x->g_fbc, x->g_ctx, True, attribs);
|
||||
|
||||
if (!x->g_hw_ctx)
|
||||
RARCH_ERR("[GLX]: Failed to create new shared context.\n");
|
||||
}
|
||||
|
||||
g_major = versions[i][0];
|
||||
g_minor = versions[i][1];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XSetErrorHandler(old_handler);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -584,33 +584,46 @@ static void content_load_init_wrap(
|
||||
**/
|
||||
static bool content_load(content_ctx_info_t *info)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned i = 0;
|
||||
int rarch_argc = 0;
|
||||
char *rarch_argv[MAX_ARGS] = {NULL};
|
||||
char *argv_copy [MAX_ARGS] = {NULL};
|
||||
char **rarch_argv_ptr = (char**)info->argv;
|
||||
int *rarch_argc_ptr = (int*)&info->argc;
|
||||
struct rarch_main_wrap *wrap_args;
|
||||
core_info_t core_info = {0};
|
||||
core_info_list_t *core_info_list = NULL;
|
||||
struct rarch_main_wrap *wrap_args = NULL;
|
||||
core_info_t core_info = {0};
|
||||
core_info_list_t *core_info_list = NULL;
|
||||
gfx_ctx_ident_t ident_info = {0};
|
||||
|
||||
core_info_get_list(&core_info_list);
|
||||
video_context_driver_get_ident(&ident_info);
|
||||
|
||||
if (core_info_list)
|
||||
/* only check for supported hw api on X11/GLX and Windows since that is where it is currently implemented */
|
||||
#ifdef HAVE_X11
|
||||
if (!string_is_empty(ident_info.ident) && string_is_equal(ident_info.ident, "x"))
|
||||
#else
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
if (!string_is_empty(ident_info.ident) && string_is_equal(ident_info.ident, "wgl"))
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
if (core_info_list_get_info(core_info_list, &core_info, path_get(RARCH_PATH_CORE)))
|
||||
core_info_get_list(&core_info_list);
|
||||
|
||||
if (core_info_list)
|
||||
{
|
||||
if (!core_info_hw_api_supported(&core_info))
|
||||
if (core_info_list_get_info(core_info_list, &core_info, path_get(RARCH_PATH_CORE)))
|
||||
{
|
||||
RARCH_ERR("This core is not compatible with the current video driver.\n");
|
||||
runloop_msg_queue_push(
|
||||
msg_hash_to_str(MSG_INCOMPATIBLE_CORE_FOR_VIDEO_DRIVER),
|
||||
100, 250, true, NULL,
|
||||
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||
return false;
|
||||
if (!core_info_hw_api_supported(&core_info))
|
||||
{
|
||||
RARCH_ERR("This core is not compatible with the current video driver.\n");
|
||||
runloop_msg_queue_push(
|
||||
msg_hash_to_str(MSG_INCOMPATIBLE_CORE_FOR_VIDEO_DRIVER),
|
||||
100, 250, true, NULL,
|
||||
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
RARCH_LOG("This core is compatible with the current video driver.\n");
|
||||
}
|
||||
else
|
||||
RARCH_LOG("This core is compatible with the current video driver.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user