X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fegl%2Fmain%2Feglcontext.c;h=ae19862bc59911b5a72a5c1777252ff3ea4b3340;hb=e26a978773ba8fbff04cd2ab3342fcb02e90c06e;hp=fa6074971da29a6cb582d319eb22b6bf000375f7;hpb=b50703aea55450e04bcd8154335774786e0f253b;p=mesa.git diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c index fa6074971da..ae19862bc59 100644 --- a/src/egl/main/eglcontext.c +++ b/src/egl/main/eglcontext.c @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2008 VMware, Inc. * Copyright 2009-2010 Chia-I Wu * Copyright 2010-2011 LunarG, Inc. * All Rights Reserved. @@ -49,13 +49,16 @@ _eglGetContextAPIBit(_EGLContext *ctx) switch (ctx->ClientAPI) { case EGL_OPENGL_ES_API: - switch (ctx->ClientVersion) { + switch (ctx->ClientMajorVersion) { case 1: bit = EGL_OPENGL_ES_BIT; break; case 2: bit = EGL_OPENGL_ES2_BIT; break; + case 3: + bit = EGL_OPENGL_ES3_BIT_KHR; + break; default: break; } @@ -78,7 +81,8 @@ _eglGetContextAPIBit(_EGLContext *ctx) * Parse the list of context attributes and return the proper error code. */ static EGLint -_eglParseContextAttribList(_EGLContext *ctx, const EGLint *attrib_list) +_eglParseContextAttribList(_EGLContext *ctx, _EGLDisplay *dpy, + const EGLint *attrib_list) { EGLenum api = ctx->ClientAPI; EGLint i, err = EGL_SUCCESS; @@ -86,22 +90,214 @@ _eglParseContextAttribList(_EGLContext *ctx, const EGLint *attrib_list) if (!attrib_list) return EGL_SUCCESS; + if (api == EGL_OPENVG_API && attrib_list[0] != EGL_NONE) { + _eglLog(_EGL_DEBUG, "bad context attribute 0x%04x", attrib_list[0]); + return EGL_BAD_ATTRIBUTE; + } + for (i = 0; attrib_list[i] != EGL_NONE; i++) { EGLint attr = attrib_list[i++]; EGLint val = attrib_list[i]; switch (attr) { case EGL_CONTEXT_CLIENT_VERSION: - if (api != EGL_OPENGL_ES_API) { + /* The EGL 1.4 spec says: + * + * "attribute EGL_CONTEXT_CLIENT_VERSION is only valid when the + * current rendering API is EGL_OPENGL_ES_API" + * + * The EGL_KHR_create_context spec says: + * + * "EGL_CONTEXT_MAJOR_VERSION_KHR 0x3098 + * (this token is an alias for EGL_CONTEXT_CLIENT_VERSION)" + * + * "The values for attributes EGL_CONTEXT_MAJOR_VERSION_KHR and + * EGL_CONTEXT_MINOR_VERSION_KHR specify the requested client API + * version. They are only meaningful for OpenGL and OpenGL ES + * contexts, and specifying them for other types of contexts will + * generate an error." + */ + if ((api != EGL_OPENGL_ES_API && + (!dpy->Extensions.KHR_create_context || api != EGL_OPENGL_API))) { + err = EGL_BAD_ATTRIBUTE; + break; + } + + ctx->ClientMajorVersion = val; + break; + + case EGL_CONTEXT_MINOR_VERSION_KHR: + /* The EGL_KHR_create_context spec says: + * + * "The values for attributes EGL_CONTEXT_MAJOR_VERSION_KHR and + * EGL_CONTEXT_MINOR_VERSION_KHR specify the requested client API + * version. They are only meaningful for OpenGL and OpenGL ES + * contexts, and specifying them for other types of contexts will + * generate an error." + */ + if (!dpy->Extensions.KHR_create_context || + (api != EGL_OPENGL_ES_API && api != EGL_OPENGL_API)) { + err = EGL_BAD_ATTRIBUTE; + break; + } + + ctx->ClientMinorVersion = val; + break; + + case EGL_CONTEXT_FLAGS_KHR: + if (!dpy->Extensions.KHR_create_context) { + err = EGL_BAD_ATTRIBUTE; + break; + } + + /* The EGL_KHR_create_context spec says: + * + * "If the EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR flag bit is set in + * EGL_CONTEXT_FLAGS_KHR, then a will be created. + * [...] + * In some cases a debug context may be identical to a non-debug + * context. This bit is supported for OpenGL and OpenGL ES + * contexts." + */ + if ((val & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) && + (api != EGL_OPENGL_API && api != EGL_OPENGL_ES_API)) { + err = EGL_BAD_ATTRIBUTE; + break; + } + + /* The EGL_KHR_create_context spec says: + * + * "If the EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR flag bit + * is set in EGL_CONTEXT_FLAGS_KHR, then a + * context will be created. Forward-compatible contexts are + * defined only for OpenGL versions 3.0 and later. They must not + * support functionality marked as by that version of + * the API, while a non-forward-compatible context must support + * all functionality in that version, deprecated or not. This bit + * is supported for OpenGL contexts, and requesting a + * forward-compatible context for OpenGL versions less than 3.0 + * will generate an error." + */ + if ((val & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) && + (api != EGL_OPENGL_API || ctx->ClientMajorVersion < 3)) { + err = EGL_BAD_ATTRIBUTE; + break; + } + + /* The EGL_KHR_create_context_spec says: + * + * "If the EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR bit is set in + * EGL_CONTEXT_FLAGS_KHR, then a context supporting will be created. Robust buffer access is defined in the + * GL_ARB_robustness extension specification, and the resulting + * context must also support either the GL_ARB_robustness + * extension, or a version of OpenGL incorporating equivalent + * functionality. This bit is supported for OpenGL contexts. + */ + if ((val & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) && + (api != EGL_OPENGL_API || + !dpy->Extensions.EXT_create_context_robustness)) { + err = EGL_BAD_ATTRIBUTE; + break; + } + + ctx->Flags |= val; + break; + + case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR: + if (!dpy->Extensions.KHR_create_context) { + err = EGL_BAD_ATTRIBUTE; + break; + } + + /* The EGL_KHR_create_context spec says: + * + * "[EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR] is only meaningful for + * OpenGL contexts, and specifying it for other types of + * contexts, including OpenGL ES contexts, will generate an + * error." + */ + if (api != EGL_OPENGL_API) { + err = EGL_BAD_ATTRIBUTE; + break; + } + + ctx->Profile = val; + break; + + case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR: + /* The EGL_KHR_create_context spec says: + * + * "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR] is only + * meaningful for OpenGL contexts, and specifying it for other + * types of contexts, including OpenGL ES contexts, will generate + * an error." + */ + if (!dpy->Extensions.KHR_create_context + || api != EGL_OPENGL_API) { + err = EGL_BAD_ATTRIBUTE; + break; + } + + ctx->ResetNotificationStrategy = val; + break; + + case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT: + /* The EGL_EXT_create_context_robustness spec says: + * + * "[EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT] is only + * meaningful for OpenGL ES contexts, and specifying it for other + * types of contexts will generate an EGL_BAD_ATTRIBUTE error." + */ + if (!dpy->Extensions.EXT_create_context_robustness + || api != EGL_OPENGL_ES_API) { + err = EGL_BAD_ATTRIBUTE; + break; + } + + ctx->ResetNotificationStrategy = val; + break; + + case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT: + if (!dpy->Extensions.EXT_create_context_robustness) { + err = EGL_BAD_ATTRIBUTE; + break; + } + + if (val == EGL_TRUE) + ctx->Flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; + break; + + case EGL_CONTEXT_OPENGL_ROBUST_ACCESS: + if (dpy->Version < 15) { + err = EGL_BAD_ATTRIBUTE; + break; + } + + if (val == EGL_TRUE) + ctx->Flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR; + break; + + case EGL_CONTEXT_OPENGL_DEBUG: + if (dpy->Version < 15) { err = EGL_BAD_ATTRIBUTE; break; } - if (val != 1 && val != 2) { + + if (val == EGL_TRUE) + ctx->Flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR; + break; + + case EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE: + if (dpy->Version < 15) { err = EGL_BAD_ATTRIBUTE; break; } - ctx->ClientVersion = val; + + if (val == EGL_TRUE) + ctx->Flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; break; + default: err = EGL_BAD_ATTRIBUTE; break; @@ -113,6 +309,147 @@ _eglParseContextAttribList(_EGLContext *ctx, const EGLint *attrib_list) } } + if (api == EGL_OPENGL_API) { + /* The EGL_KHR_create_context spec says: + * + * "If the requested OpenGL version is less than 3.2, + * EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR is ignored and the + * functionality of the context is determined solely by the + * requested version." + * + * Since the value is ignored, only validate the setting if the version + * is >= 3.2. + */ + if (ctx->ClientMajorVersion >= 4 + || (ctx->ClientMajorVersion == 3 && ctx->ClientMinorVersion >= 2)) { + switch (ctx->Profile) { + case EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR: + case EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR: + break; + + default: + /* The EGL_KHR_create_context spec says: + * + * "* If an OpenGL context is requested, the requested version + * is greater than 3.2, and the value for attribute + * EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR has no bits set; has + * any bits set other than EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR + * and EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR; has + * more than one of these bits set; or if the implementation does + * not support the requested profile, then an EGL_BAD_MATCH error + * is generated." + */ + err = EGL_BAD_MATCH; + break; + } + } + + /* The EGL_KHR_create_context spec says: + * + * "* If an OpenGL context is requested and the values for + * attributes EGL_CONTEXT_MAJOR_VERSION_KHR and + * EGL_CONTEXT_MINOR_VERSION_KHR, when considered together with + * the value for attribute + * EGL_CONTEXT_FORWARD_COMPATIBLE_BIT_KHR, specify an OpenGL + * version and feature set that are not defined, than an + * EGL_BAD_MATCH error is generated. + * + * ... Thus, examples of invalid combinations of attributes + * include: + * + * - Major version < 1 or > 4 + * - Major version == 1 and minor version < 0 or > 5 + * - Major version == 2 and minor version < 0 or > 1 + * - Major version == 3 and minor version < 0 or > 2 + * - Major version == 4 and minor version < 0 or > 2 + * - Forward-compatible flag set and major version < 3" + */ + if (ctx->ClientMajorVersion < 1 || ctx->ClientMinorVersion < 0) + err = EGL_BAD_MATCH; + + switch (ctx->ClientMajorVersion) { + case 1: + if (ctx->ClientMinorVersion > 5 + || (ctx->Flags & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) != 0) + err = EGL_BAD_MATCH; + break; + + case 2: + if (ctx->ClientMinorVersion > 1 + || (ctx->Flags & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) != 0) + err = EGL_BAD_MATCH; + break; + + case 3: + /* Note: The text above is incorrect. There *is* an OpenGL 3.3! + */ + if (ctx->ClientMinorVersion > 3) + err = EGL_BAD_MATCH; + break; + + case 4: + default: + /* Don't put additional version checks here. We don't know that + * there won't be versions > 4.2. + */ + break; + } + } else if (api == EGL_OPENGL_ES_API) { + /* The EGL_KHR_create_context spec says: + * + * "* If an OpenGL ES context is requested and the values for + * attributes EGL_CONTEXT_MAJOR_VERSION_KHR and + * EGL_CONTEXT_MINOR_VERSION_KHR specify an OpenGL ES version that + * is not defined, than an EGL_BAD_MATCH error is generated. + * + * ... Examples of invalid combinations of attributes include: + * + * - Major version < 1 or > 2 + * - Major version == 1 and minor version < 0 or > 1 + * - Major version == 2 and minor version != 0 + */ + if (ctx->ClientMajorVersion < 1 || ctx->ClientMinorVersion < 0) + err = EGL_BAD_MATCH; + + switch (ctx->ClientMajorVersion) { + case 1: + if (ctx->ClientMinorVersion > 1) + err = EGL_BAD_MATCH; + break; + + case 2: + if (ctx->ClientMinorVersion > 0) + err = EGL_BAD_MATCH; + break; + + case 3: + /* Don't put additional version checks here. We don't know that + * there won't be versions > 3.0. + */ + break; + + default: + err = EGL_BAD_MATCH; + break; + } + } + + switch (ctx->ResetNotificationStrategy) { + case EGL_NO_RESET_NOTIFICATION_KHR: + case EGL_LOSE_CONTEXT_ON_RESET_KHR: + break; + + default: + err = EGL_BAD_ATTRIBUTE; + break; + } + + if ((ctx->Flags & ~(EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR + | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR + | EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR)) != 0) { + err = EGL_BAD_ATTRIBUTE; + } + return err; } @@ -137,10 +474,15 @@ _eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *conf, ctx->ClientAPI = api; ctx->Config = conf; ctx->WindowRenderBuffer = EGL_NONE; + ctx->Profile = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; - ctx->ClientVersion = 1; /* the default, per EGL spec */ + ctx->ClientMajorVersion = 1; /* the default, per EGL spec */ + ctx->ClientMinorVersion = 0; + ctx->Flags = 0; + ctx->Profile = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR; + ctx->ResetNotificationStrategy = EGL_NO_RESET_NOTIFICATION_KHR; - err = _eglParseContextAttribList(ctx, attrib_list); + err = _eglParseContextAttribList(ctx, dpy, attrib_list); if (err == EGL_SUCCESS && ctx->Config) { EGLint api_bit; @@ -191,7 +533,7 @@ _eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *c, *value = c->Config->ConfigID; break; case EGL_CONTEXT_CLIENT_VERSION: - *value = c->ClientVersion; + *value = c->ClientMajorVersion; break; case EGL_CONTEXT_CLIENT_TYPE: *value = c->ClientAPI; @@ -285,10 +627,22 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read) return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent"); } - /* simply require the configs to be equal */ - if ((draw && draw->Config != ctx->Config) || - (read && read->Config != ctx->Config)) - return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); + /* If the context has a config then it must match that of the two + * surfaces */ + if (ctx->Config) { + if ((draw && draw->Config != ctx->Config) || + (read && read->Config != ctx->Config)) + return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); + } else { + /* Otherwise we must be using the EGL_MESA_configless_context + * extension */ + assert(dpy->Extensions.MESA_configless_context); + + /* The extension doesn't permit binding draw and read buffers with + * differing contexts */ + if (draw && read && draw->Config != read->Config) + return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); + } switch (ctx->ClientAPI) { /* OpenGL and OpenGL ES are conflicting */