[PATCH] glx: add GLX_ARB_create_context_no_error support

Grigori Goronzy greg at chown.ath.cx
Thu Aug 3 18:07:20 UTC 2017


Add the necessary bits to parse the attribute, convert the value
to DRI context flags where needed and enforce the rules outlined in
the specification.
---
 glx/createcontext.c    | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 glx/extension_string.c |  1 +
 glx/extension_string.h |  1 +
 glx/glxcontext.h       |  5 +++++
 glx/glxdri2.c          | 29 +++++++++++++++++++++++++++++
 glx/glxext.h           |  3 +++
 6 files changed, 86 insertions(+)

diff --git a/glx/createcontext.c b/glx/createcontext.c
index 068b35f..91f449e 100644
--- a/glx/createcontext.c
+++ b/glx/createcontext.c
@@ -90,6 +90,9 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
 #ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB
     uint32_t flush = GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB;
 #endif
+#ifdef __DRI2_NO_ERROR
+    uint32_t no_error = 0;
+#endif
     __GLXcontext *ctx = NULL;
     __GLXcontext *shareCtx = NULL;
     __GLXscreen *glxScreen;
@@ -165,6 +168,20 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
             client->errorValue = shareCtx->pGlxScreen->pScreen->myNum;
             return BadMatch;
         }
+
+        /* The GLX_ARB_create_context_no_error spec says:
+         *
+         *     "BadMatch is generated if the value of
+         *     GLX_CONTEXT_OPENGL_NO_ERROR_ARB used to create <share_context>
+         *     does not match the value of GLX_CONTEXT_OPENGL_NO_ERROR_ARB
+         *     for the context being created."
+         */
+#ifdef __DRI2_NO_ERROR
+        if (!!shareCtx->noError != !!no_error) {
+            client->errorValue = req->shareList;
+            return BadMatch;
+        }
+#endif
     }
 
     for (i = 0; i < req->numAttribs; i++) {
@@ -206,6 +223,12 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
             break;
 #endif
 
+#ifdef __DRI2_NO_ERROR
+        case GLX_CONTEXT_OPENGL_NO_ERROR_ARB:
+            no_error = attribs[2 * i + 1];
+            break;
+#endif
+
         default:
             if (!req->isDirect)
                 return BadValue;
@@ -213,6 +236,27 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
         }
     }
 
+    /* The GLX_ARB_create_context_no_error spec says:
+     *
+     *     "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."
+     */
+#ifdef __DRI2_NO_ERROR
+    if (no_error && ((flags & GLX_CONTEXT_DEBUG_BIT_ARB) ||
+                     (flags & GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB)))
+        return BadMatch;
+#endif
+
+    /* The KHR_no_error spec says:
+     *
+     *     "Requires OpenGL ES 2.0 or OpenGL 2.0."
+     */
+#ifdef __DRI2_NO_ERROR
+    if (no_error && major_version < 2)
+        return BadMatch;
+#endif
+
     /* The GLX_ARB_create_context spec says:
      *
      *     "If attributes GLX_CONTEXT_MAJOR_VERSION_ARB and
@@ -318,6 +362,9 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
     ctx->share_id = req->shareList;
     ctx->idExists = True;
     ctx->isDirect = req->isDirect;
+#ifdef __DRI2_NO_ERROR
+    ctx->noError = no_error;
+#endif
     ctx->renderMode = GL_RENDER;
     ctx->resetNotificationStrategy = reset;
 #ifdef GLX_CONTEXT_RELEASE_BEHAVIOR_ARB
diff --git a/glx/extension_string.c b/glx/extension_string.c
index d1da481..bd662e6 100644
--- a/glx/extension_string.c
+++ b/glx/extension_string.c
@@ -74,6 +74,7 @@ static const struct extension_info known_glx_extensions[] = {
     /* *INDENT-OFF* */
     { GLX(ARB_context_flush_control),   VER(0,0), N, },
     { GLX(ARB_create_context),          VER(0,0), N, },
+    { GLX(ARB_create_context_no_error), VER(1,4), N, },
     { GLX(ARB_create_context_profile),  VER(0,0), N, },
     { GLX(ARB_create_context_robustness), VER(0,0), N, },
     { GLX(ARB_fbconfig_float),          VER(0,0), N, },
diff --git a/glx/extension_string.h b/glx/extension_string.h
index a10d710..5d9c52a 100644
--- a/glx/extension_string.h
+++ b/glx/extension_string.h
@@ -38,6 +38,7 @@ enum {
 /*   GLX_ARB_get_proc_address is implemented on the client. */
     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,
diff --git a/glx/glxcontext.h b/glx/glxcontext.h
index 19d347f..165a3cb 100644
--- a/glx/glxcontext.h
+++ b/glx/glxcontext.h
@@ -90,6 +90,11 @@ struct __GLXcontext {
     GLboolean isDirect;
 
     /*
+     ** Whether this context uses no-error mode.
+     */
+    GLboolean noError;
+
+    /*
      ** Current rendering mode for this context.
      */
     GLenum renderMode;
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 7019442..ec46190 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -45,6 +45,7 @@
 #include "glxserver.h"
 #include "glxutil.h"
 #include "glxdricommon.h"
+#include "glxext.h"
 #include <GL/glxtokens.h>
 
 #include "extension_string.h"
@@ -53,9 +54,16 @@ typedef struct __GLXDRIscreen __GLXDRIscreen;
 typedef struct __GLXDRIcontext __GLXDRIcontext;
 typedef struct __GLXDRIdrawable __GLXDRIdrawable;
 
+#ifdef __DRI2_NO_ERROR
+#define ALL_DRI_CTX_FLAGS (__DRI_CTX_FLAG_DEBUG                         \
+                           | __DRI_CTX_FLAG_FORWARD_COMPATIBLE          \
+                           | __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS        \
+                           | __DRI_CTX_FLAG_NO_ERROR)
+#else
 #define ALL_DRI_CTX_FLAGS (__DRI_CTX_FLAG_DEBUG                         \
                            | __DRI_CTX_FLAG_FORWARD_COMPATIBLE          \
                            | __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS)
+#endif
 
 struct __GLXDRIscreen {
     __GLXscreen base;
@@ -342,6 +350,9 @@ dri2_convert_glx_attribs(__GLXDRIscreen *screen, unsigned num_attribs,
                          uint32_t *flags, int *api, int *reset, unsigned *error)
 {
     unsigned i;
+#ifdef __DRI2_NO_ERROR
+    int no_error = 0;
+#endif
 
     if (num_attribs == 0)
         return True;
@@ -402,6 +413,11 @@ dri2_convert_glx_attribs(__GLXDRIscreen *screen, unsigned num_attribs,
                 return False;
             }
             break;
+#ifdef __DRI2_NO_ERROR
+        case GLX_CONTEXT_OPENGL_NO_ERROR_ARB:
+            no_error = attribs[i * 2 + 1];
+            break;
+#endif
         default:
             /* If an unknown attribute is received, fail.
              */
@@ -410,6 +426,10 @@ dri2_convert_glx_attribs(__GLXDRIscreen *screen, unsigned num_attribs,
         }
     }
 
+    if (no_error) {
+        *flags |= __DRI_CTX_FLAG_NO_ERROR;
+    }
+
     /* Unknown flag value.
      */
     if ((*flags & ~ALL_DRI_CTX_FLAGS) != 0) {
@@ -894,6 +914,15 @@ initializeExtensions(__GLXscreen * screen)
                        "AIGLX: enabled GLX_ARB_create_context_robustness\n");
         }
 
+#ifdef __DRI2_NO_ERROR
+        if (strcmp(extensions[i]->name, __DRI2_NO_ERROR) == 0) {
+            __glXEnableExtension(screen->glx_enable_bits,
+                                 "GLX_ARB_create_context_no_error");
+            LogMessage(X_INFO,
+                        "AIGLX: enabled GLX_ARB_create_context_no_error\n");
+        }
+#endif
+
 #ifdef __DRI2_FLUSH_CONTROL
         if (strcmp(extensions[i]->name, __DRI2_FLUSH_CONTROL) == 0) {
             __glXEnableExtension(screen->glx_enable_bits,
diff --git a/glx/glxext.h b/glx/glxext.h
index cde0e15..3beeddf 100644
--- a/glx/glxext.h
+++ b/glx/glxext.h
@@ -50,6 +50,9 @@
 #ifndef GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT
 #define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT   0x20B1
 #endif
+#ifndef GLX_CONTEXT_OPENGL_NO_ERROR_ARB
+#define GLX_CONTEXT_OPENGL_NO_ERROR_ARB    0x31B3
+#endif
 
 extern void __glXFlushContextCache(void);
 
-- 
2.7.4



More information about the xorg-devel mailing list