From acfd88204e886e671da97b895fd2d1ee39b61256 Mon Sep 17 00:00:00 2001 From: Grigori Goronzy Date: Thu, 3 Aug 2017 20:07:58 +0200 Subject: [PATCH] glx: add support for GLX_ARB_create_context_no_error (v3) v2: Only reject no-error contexts for too-old GL if we're actually trying to create a no-error context (Adam Jackson) v3: Fix share contexts (Adam Jackson) Reviewed-by: Adam Jackson Reviewed-by: Eric Anholt --- src/glx/dri2_glx.c | 15 ++++++++++++ src/glx/dri3_glx.c | 11 +++++++++ src/glx/dri_common.c | 52 ++++++++++++++++++++++++++++++++++++++++- src/glx/dri_common.h | 5 ++++ src/glx/drisw_glx.c | 6 +++++ src/glx/glxclient.h | 6 +++++ src/glx/glxextensions.c | 1 + src/glx/glxextensions.h | 1 + 8 files changed, 96 insertions(+), 1 deletion(-) diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c index d8c5ba25f04..d6a543c8da0 100644 --- a/src/glx/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -263,6 +263,10 @@ dri2_create_context_attribs(struct glx_screen *base, &api, &reset, &release, error)) goto error_exit; + if (!dri2_check_no_error(flags, shareList, major_ver, error)) { + goto error_exit; + } + /* Check the renderType value */ if (!validate_renderType_against_config(config_base, renderType)) goto error_exit; @@ -314,6 +318,9 @@ dri2_create_context_attribs(struct glx_screen *base, */ pcp->base.renderType = renderType; + if (flags & __DRI_CTX_FLAG_NO_ERROR) + pcp->base.noError = GL_TRUE; + pcp->driContext = (*psc->dri2->createContextAttribs) (psc->driScreen, api, @@ -1164,6 +1171,14 @@ dri2BindExtensions(struct dri2_screen *psc, struct glx_display * priv, __glXEnableDirectExtension(&psc->base, "GLX_ARB_create_context_robustness"); + /* DRI2 version 3 is also required because + * GLX_ARB_create_context_no_error requires GLX_ARB_create_context. + */ + if (psc->dri2->base.version >= 3 + && strcmp(extensions[i]->name, __DRI2_NO_ERROR) == 0) + __glXEnableDirectExtension(&psc->base, + "GLX_ARB_create_context_no_error"); + /* DRI2 version 3 is also required because GLX_MESA_query_renderer * requires GLX_ARB_create_context_profile. */ diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c index 298adc80ef1..9d023341e6b 100644 --- a/src/glx/dri3_glx.c +++ b/src/glx/dri3_glx.c @@ -259,6 +259,10 @@ dri3_create_context_attribs(struct glx_screen *base, &reset, &release, error)) goto error_exit; + if (!dri2_check_no_error(flags, shareList, major_ver, error)) { + goto error_exit; + } + /* Check the renderType value */ if (!validate_renderType_against_config(config_base, render_type)) goto error_exit; @@ -303,6 +307,9 @@ dri3_create_context_attribs(struct glx_screen *base, * GLX_CONTEXT_*_BIT values. */ ctx_attribs[num_ctx_attribs++] = flags; + + if (flags & __DRI_CTX_FLAG_NO_ERROR) + pcp->base.noError = GL_TRUE; } pcp->driContext = @@ -780,6 +787,10 @@ dri3_bind_extensions(struct dri3_screen *psc, struct glx_display * priv, __glXEnableDirectExtension(&psc->base, "GLX_ARB_create_context_robustness"); + if (strcmp(extensions[i]->name, __DRI2_NO_ERROR) == 0) + __glXEnableDirectExtension(&psc->base, + "GLX_ARB_create_context_no_error"); + if (strcmp(extensions[i]->name, __DRI2_RENDERER_QUERY) == 0) { psc->rendererQuery = (__DRI2rendererQueryExtension *) extensions[i]; __glXEnableDirectExtension(&psc->base, "GLX_MESA_query_renderer"); diff --git a/src/glx/dri_common.c b/src/glx/dri_common.c index fb8a29f0993..2db29fd6abb 100644 --- a/src/glx/dri_common.c +++ b/src/glx/dri_common.c @@ -427,6 +427,7 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs, { unsigned i; bool got_profile = false; + int no_error = 0; uint32_t profile; *major_ver = 1; @@ -459,6 +460,9 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs, case GLX_CONTEXT_FLAGS_ARB: *flags = attribs[i * 2 + 1]; break; + case GLX_CONTEXT_OPENGL_NO_ERROR_ARB: + no_error = attribs[i * 2 + 1]; + break; case GLX_CONTEXT_PROFILE_MASK_ARB: profile = attribs[i * 2 + 1]; got_profile = true; @@ -500,6 +504,10 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs, } } + if (no_error) { + *flags |= __DRI_CTX_FLAG_NO_ERROR; + } + if (!got_profile) { if (*major_ver > 3 || (*major_ver == 3 && *minor_ver >= 2)) *api = __DRI_API_OPENGL_CORE; @@ -540,7 +548,8 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs, /* Unknown flag value. */ if (*flags & ~(__DRI_CTX_FLAG_DEBUG | __DRI_CTX_FLAG_FORWARD_COMPATIBLE - | __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS)) { + | __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS + | __DRI_CTX_FLAG_NO_ERROR)) { *error = __DRI_CTX_ERROR_UNKNOWN_FLAG; return false; } @@ -565,4 +574,45 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs, return true; } +_X_HIDDEN bool +dri2_check_no_error(uint32_t flags, struct glx_context *share_context, + int major, unsigned *error) +{ + Bool noError = flags & __DRI_CTX_FLAG_NO_ERROR; + + /* The KHR_no_error specs say: + * + * Requires OpenGL ES 2.0 or OpenGL 2.0. + */ + if (noError && major < 2) { + *error = __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE; + return false; + } + + /* The GLX_ARB_create_context_no_error specs say: + * + * BadMatch is generated if the value of GLX_CONTEXT_OPENGL_NO_ERROR_ARB + * used to create does not match the value of + * GLX_CONTEXT_OPENGL_NO_ERROR_ARB for the context being created. + */ + if (share_context && !!share_context->noError != !!noError) { + *error = __DRI_CTX_ERROR_BAD_FLAG; + return false; + } + + /* The GLX_ARB_create_context_no_error specs say: + * + * BadMatch is generated if the GLX_CONTEXT_OPENGL_NO_ERROR_ARB is TRUE at + * the same time as a debug or robustness context is specified. + * + */ + if (noError && ((flags & __DRI_CTX_FLAG_DEBUG) || + (flags & __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS))) { + *error = __DRI_CTX_ERROR_BAD_FLAG; + return false; + } + + return true; +} + #endif /* GLX_DIRECT_RENDERING */ diff --git a/src/glx/dri_common.h b/src/glx/dri_common.h index 363f15bf9bb..1b74397063b 100644 --- a/src/glx/dri_common.h +++ b/src/glx/dri_common.h @@ -78,4 +78,9 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs, uint32_t *render_type, uint32_t *flags, unsigned *api, int *reset, int *release, unsigned *error); +extern bool +dri2_check_no_error(uint32_t flags, struct glx_context *share_context, + int major, unsigned *error); + + #endif /* _DRI_COMMON_H */ diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c index 48c03ca42e0..c63b097a71a 100644 --- a/src/glx/drisw_glx.c +++ b/src/glx/drisw_glx.c @@ -599,6 +599,9 @@ drisw_create_context_attribs(struct glx_screen *base, &api, &reset, &release, error)) return NULL; + if (!dri2_check_no_error(flags, shareList, major_ver, error)) + return NULL; + /* Check the renderType value */ if (!validate_renderType_against_config(config_base, renderType)) { return NULL; @@ -641,6 +644,9 @@ drisw_create_context_attribs(struct glx_screen *base, * GLX_CONTEXT_*_BIT values. */ ctx_attribs[num_ctx_attribs++] = flags; + + if (flags & __DRI_CTX_FLAG_NO_ERROR) + pcp->base.noError = GL_TRUE; } pcp->base.renderType = renderType; diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h index df51f2b8ce4..3e8274e1c3a 100644 --- a/src/glx/glxclient.h +++ b/src/glx/glxclient.h @@ -437,6 +437,12 @@ struct glx_context */ unsigned long thread_refcount; + /** + * GLX_ARB_create_context_no_error setting for this context. + * This needs to be kept here to enforce shared context rules. + */ + Bool noError; + char gl_extension_bits[__GL_EXT_BYTES]; }; diff --git a/src/glx/glxextensions.c b/src/glx/glxextensions.c index e85a8c92846..f6a7a31a219 100644 --- a/src/glx/glxextensions.c +++ b/src/glx/glxextensions.c @@ -134,6 +134,7 @@ struct extension_info static const struct extension_info known_glx_extensions[] = { { GLX(ARB_context_flush_control), VER(0,0), Y, N, N, N }, { GLX(ARB_create_context), VER(0,0), Y, N, N, N }, + { GLX(ARB_create_context_no_error), VER(1,4), Y, N, N, N }, { GLX(ARB_create_context_profile), VER(0,0), Y, N, N, N }, { GLX(ARB_create_context_robustness), VER(0,0), Y, N, N, N }, { GLX(ARB_fbconfig_float), VER(0,0), Y, Y, N, N }, diff --git a/src/glx/glxextensions.h b/src/glx/glxextensions.h index c6428d46b4d..bbdb00dd631 100644 --- a/src/glx/glxextensions.h +++ b/src/glx/glxextensions.h @@ -39,6 +39,7 @@ enum { ARB_context_flush_control_bit = 0, ARB_create_context_bit, + ARB_create_context_no_error_bit, ARB_create_context_profile_bit, ARB_create_context_robustness_bit, ARB_fbconfig_float_bit, -- 2.30.2