egl: Add EGL_KHR_create_context_no_error support
authorGrigori Goronzy <greg@chown.ath.cx>
Thu, 29 Jun 2017 00:44:03 +0000 (02:44 +0200)
committerGrigori Goronzy <greg@chown.ath.cx>
Fri, 14 Jul 2017 19:23:44 +0000 (21:23 +0200)
This only adds the EGL side, needs to be plumbed into Mesa frontend.

v2: Add check for extension availability.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
src/egl/drivers/dri2/egl_dri2.c
src/egl/drivers/dri2/egl_dri2.h
src/egl/main/eglapi.c
src/egl/main/eglcontext.c
src/egl/main/eglcontext.h
src/egl/main/egldisplay.h

index 5bf36bf..f632ebe 100644 (file)
@@ -428,6 +428,7 @@ static const struct dri2_extension_match swrast_core_extensions[] = {
 
 static const struct dri2_extension_match optional_core_extensions[] = {
    { __DRI2_ROBUSTNESS, 1, offsetof(struct dri2_egl_display, robustness) },
+   { __DRI2_NO_ERROR, 1, offsetof(struct dri2_egl_display, no_error) },
    { __DRI2_CONFIG_QUERY, 1, offsetof(struct dri2_egl_display, config) },
    { __DRI2_FENCE, 1, offsetof(struct dri2_egl_display, fence) },
    { __DRI2_RENDERER_QUERY, 1, offsetof(struct dri2_egl_display, rendererQuery) },
@@ -665,6 +666,9 @@ dri2_setup_screen(_EGLDisplay *disp)
          disp->Extensions.EXT_create_context_robustness = EGL_TRUE;
    }
 
+   if (dri2_dpy->no_error)
+      disp->Extensions.KHR_create_context_no_error = EGL_TRUE;
+
    if (dri2_dpy->fence) {
       disp->Extensions.KHR_fence_sync = EGL_TRUE;
       disp->Extensions.KHR_wait_sync = EGL_TRUE;
@@ -1057,7 +1061,7 @@ dri2_fill_context_attribs(struct dri2_egl_context *dri2_ctx,
    ctx_attribs[pos++] = __DRI_CTX_ATTRIB_MINOR_VERSION;
    ctx_attribs[pos++] = dri2_ctx->base.ClientMinorVersion;
 
-   if (dri2_ctx->base.Flags != 0) {
+   if (dri2_ctx->base.Flags != 0 || dri2_ctx->base.NoError) {
       /* If the implementation doesn't support the __DRI2_ROBUSTNESS
        * extension, don't even try to send it the robust-access flag.
        * It may explode.  Instead, generate the required EGL error here.
@@ -1069,7 +1073,8 @@ dri2_fill_context_attribs(struct dri2_egl_context *dri2_ctx,
       }
 
       ctx_attribs[pos++] = __DRI_CTX_ATTRIB_FLAGS;
-      ctx_attribs[pos++] = dri2_ctx->base.Flags;
+      ctx_attribs[pos++] = dri2_ctx->base.Flags |
+            dri2_ctx->base.NoError ? __DRI_CTX_FLAG_NO_ERROR : 0;
    }
 
    if (dri2_ctx->base.ResetNotificationStrategy != EGL_NO_RESET_NOTIFICATION_KHR) {
@@ -1132,6 +1137,17 @@ dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
       goto cleanup;
    }
 
+   /* The EGL_KHR_create_context_no_error spec says:
+    *
+    *    "BAD_MATCH is generated if the value of EGL_CONTEXT_OPENGL_NO_ERROR_KHR
+    *    used to create <share_context> does not match the value of
+    *    EGL_CONTEXT_OPENGL_NO_ERROR_KHR for the context being created."
+    */
+   if (share_list && share_list->NoError != dri2_ctx->base.NoError) {
+      _eglError(EGL_BAD_MATCH, "eglCreateContext");
+      goto cleanup;
+   }
+
    switch (dri2_ctx->base.ClientAPI) {
    case EGL_OPENGL_ES_API:
       switch (dri2_ctx->base.ClientMajorVersion) {
index 4a5cf8e..5b3e93a 100644 (file)
@@ -170,6 +170,7 @@ struct dri2_egl_display
    const __DRItexBufferExtension  *tex_buffer;
    const __DRIimageExtension      *image;
    const __DRIrobustnessExtension *robustness;
+   const __DRInoErrorExtension    *no_error;
    const __DRI2configQueryExtension *config;
    const __DRI2fenceExtension *fence;
    const __DRI2rendererQueryExtension *rendererQuery;
index 9b899d8..000368a 100644 (file)
@@ -494,6 +494,7 @@ _eglCreateExtensionsString(_EGLDisplay *dpy)
    _EGL_CHECK_EXTENSION(KHR_cl_event2);
    _EGL_CHECK_EXTENSION(KHR_config_attribs);
    _EGL_CHECK_EXTENSION(KHR_create_context);
+   _EGL_CHECK_EXTENSION(KHR_create_context_no_error);
    _EGL_CHECK_EXTENSION(KHR_fence_sync);
    _EGL_CHECK_EXTENSION(KHR_get_all_proc_addresses);
    _EGL_CHECK_EXTENSION(KHR_gl_colorspace);
index df8b45c..1a8e9bd 100644 (file)
@@ -312,6 +312,37 @@ _eglParseContextAttribList(_EGLContext *ctx, _EGLDisplay *dpy,
             ctx->Flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
          break;
 
+      case EGL_CONTEXT_OPENGL_NO_ERROR_KHR:
+         if (dpy->Version < 14 ||
+             !dpy->Extensions.KHR_create_context_no_error) {
+            err = EGL_BAD_ATTRIBUTE;
+            break;
+         }
+
+         /* The KHR_no_error spec only applies against OpenGL 2.0+ and
+          * OpenGL ES 2.0+
+          */
+         if ((api != EGL_OPENGL_API && api != EGL_OPENGL_ES_API) ||
+             ctx->ClientMajorVersion < 2) {
+            err = EGL_BAD_ATTRIBUTE;
+            break;
+         }
+
+         /* The EGL_KHR_create_context_no_error spec says:
+          *
+          *    "BAD_MATCH is generated if the EGL_CONTEXT_OPENGL_NO_ERROR_KHR is TRUE at
+          *    the same time as a debug or robustness context is specified."
+          */
+         if (ctx->Flags & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR ||
+             ctx->Flags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) {
+            err = EGL_BAD_MATCH;
+            break;
+         }
+
+         /* Canonicalize value to EGL_TRUE/EGL_FALSE definitions */
+         ctx->NoError = !!val;
+         break;
+
       default:
          err = EGL_BAD_ATTRIBUTE;
          break;
index f2fe806..0667622 100644 (file)
@@ -62,6 +62,7 @@ struct _egl_context
    EGLint Flags;
    EGLint Profile;
    EGLint ResetNotificationStrategy;
+   EGLBoolean NoError;
 
    /* The real render buffer when a window surface is bound */
    EGLint WindowRenderBuffer;
index a13ff5b..3d5a445 100644 (file)
@@ -122,6 +122,7 @@ struct _egl_extensions
    EGLBoolean KHR_reusable_sync;
    EGLBoolean KHR_surfaceless_context;
    EGLBoolean KHR_wait_sync;
+   EGLBoolean KHR_create_context_no_error;
 
    EGLBoolean MESA_drm_image;
    EGLBoolean MESA_image_dma_buf_export;