X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fegl%2Fmain%2Feglcontext.c;h=588f48921f2d28c177bec9e8bc4a826e0efb1910;hb=c59ad265df655a19285d813144f6b76d7f49d7fd;hp=38e195f0446444175edcfd357fc47284ef1b394b;hpb=424b1210d951c206e7c2fb8f2778acbd384eb247;p=mesa.git diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c index 38e195f0446..588f48921f2 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,175 @@ _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: + * + * "Flags are only defined for OpenGL context creation, and + * specifying a flags value other than zero for other types of + * contexts, including OpenGL ES contexts, will generate an + * error." + */ + if (api != EGL_OPENGL_API && val != 0) { + 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 != 1 && val != 2) { + + 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; } - ctx->ClientVersion = val; + + 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; + } + + if (val == EGL_TRUE) + ctx->Flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR; + break; + default: err = EGL_BAD_ATTRIBUTE; break; @@ -113,6 +270,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 +435,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; @@ -158,7 +461,6 @@ _eglInitContext(_EGLContext *ctx, _EGLDisplay *dpy, _EGLConfig *conf, } -#ifdef EGL_VERSION_1_2 static EGLint _eglQueryContextRenderBuffer(_EGLContext *ctx) { @@ -173,7 +475,6 @@ _eglQueryContextRenderBuffer(_EGLContext *ctx) rb = surf->RenderBuffer; return rb; } -#endif /* EGL_VERSION_1_2 */ EGLBoolean @@ -193,16 +494,14 @@ _eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *c, *value = c->Config->ConfigID; break; case EGL_CONTEXT_CLIENT_VERSION: - *value = c->ClientVersion; + *value = c->ClientMajorVersion; break; -#ifdef EGL_VERSION_1_2 case EGL_CONTEXT_CLIENT_TYPE: *value = c->ClientAPI; break; case EGL_RENDER_BUFFER: *value = _eglQueryContextRenderBuffer(c); break; -#endif /* EGL_VERSION_1_2 */ default: return _eglError(EGL_BAD_ATTRIBUTE, "eglQueryContext"); } @@ -248,7 +547,6 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read) _EGLThreadInfo *t = _eglGetCurrentThread(); _EGLDisplay *dpy; EGLint conflict_api; - EGLBoolean surfaceless; if (_eglIsCurrentThreadDummy()) return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent"); @@ -261,22 +559,8 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read) } dpy = ctx->Resource.Display; - switch (_eglGetContextAPIBit(ctx)) { - case EGL_OPENGL_ES_BIT: - surfaceless = dpy->Extensions.KHR_surfaceless_gles1; - break; - case EGL_OPENGL_ES2_BIT: - surfaceless = dpy->Extensions.KHR_surfaceless_gles2; - break; - case EGL_OPENGL_BIT: - surfaceless = dpy->Extensions.KHR_surfaceless_opengl; - break; - default: - surfaceless = EGL_FALSE; - break; - } - - if (!surfaceless && (draw == NULL || read == NULL)) + if (!dpy->Extensions.KHR_surfaceless_context + && (draw == NULL || read == NULL)) return _eglError(EGL_BAD_MATCH, "eglMakeCurrent"); /* @@ -304,13 +588,24 @@ _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) { -#ifdef EGL_VERSION_1_4 /* OpenGL and OpenGL ES are conflicting */ case EGL_OPENGL_ES_API: conflict_api = EGL_OPENGL_API; @@ -318,7 +613,6 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read) case EGL_OPENGL_API: conflict_api = EGL_OPENGL_ES_API; break; -#endif default: conflict_api = -1; break;