Module: Mesa
Branch: main
Commit: 9c76682d803ad21c51327b981cafdaf651fc3c53
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=9c76682d803ad21c51327b981cafdaf651fc3c53

Author: Adam Jackson <[email protected]>
Date:   Wed Jul 21 18:05:12 2021 -0400

glx/dri: Use X/GLX error codes for our create_context_attribs

This has no functional change because everyone calling this is
discarding the error code, because we're relying on the server to
generate the right thing for us. But we create the direct context first
and the server isn't going to enforce everything we want it to
(supported GL versions for example). Convert out from DRI error codes to
X/GLX error codes so we can fail the right way on the client side. We're
still throwing the error away in all of the callers but that'll change
shortly.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12006>

---

 src/glx/dri2_glx.c     |  6 ++++--
 src/glx/dri3_glx.c     |  6 ++++--
 src/glx/dri_common.c   | 56 ++++++++++++++++++++++++++++++++++----------------
 src/glx/dri_common.h   |  3 +++
 src/glx/drisw_glx.c    |  4 +++-
 src/glx/glxclient.h    |  5 +++++
 src/glx/indirect_glx.c |  5 +++++
 7 files changed, 62 insertions(+), 23 deletions(-)

diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 3b0c3ccaf3e..5ca15be07d3 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -183,7 +183,7 @@ dri2_create_context_attribs(struct glx_screen *base,
        *    GLX_CONTEXT_OPENGL_NO_ERROR_ARB for the context being created.
        */
       if (!!shareList->noError != !!dca.no_error) {
-         *error = __DRI_CTX_ERROR_BAD_FLAG;
+         *error = BadMatch;
          return NULL;
       }
 
@@ -192,7 +192,7 @@ dri2_create_context_attribs(struct glx_screen *base,
 
    pcp = calloc(1, sizeof *pcp);
    if (pcp == NULL) {
-      *error = __DRI_CTX_ERROR_NO_MEMORY;
+      *error = BadAlloc;
       goto error_exit;
    }
 
@@ -244,6 +244,8 @@ dri2_create_context_attribs(struct glx_screen *base,
                                          error,
                                          pcp);
 
+   *error = dri_context_error_to_glx_error(*error);
+
    if (pcp->driContext == NULL)
       goto error_exit;
 
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index eda5364c0c7..bab21854e35 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -234,7 +234,7 @@ dri3_create_context_attribs(struct glx_screen *base,
        *    GLX_CONTEXT_OPENGL_NO_ERROR_ARB for the context being created.
        */
       if (!!shareList->noError != !!dca.no_error) {
-         *error = __DRI_CTX_ERROR_BAD_FLAG;
+         *error = BadMatch;
          return NULL;
       }
 
@@ -243,7 +243,7 @@ dri3_create_context_attribs(struct glx_screen *base,
 
    pcp = calloc(1, sizeof *pcp);
    if (pcp == NULL) {
-      *error = __DRI_CTX_ERROR_NO_MEMORY;
+      *error = BadAlloc;
       goto error_exit;
    }
 
@@ -293,6 +293,8 @@ dri3_create_context_attribs(struct glx_screen *base,
                                               error,
                                               pcp);
 
+   *error = dri_context_error_to_glx_error(*error);
+
    if (pcp->driContext == NULL)
       goto error_exit;
 
diff --git a/src/glx/dri_common.c b/src/glx/dri_common.c
index 0bd2f025ae5..3421d654b5a 100644
--- a/src/glx/dri_common.c
+++ b/src/glx/dri_common.c
@@ -516,13 +516,6 @@ dri_convert_glx_attribs(unsigned num_attribs, const 
uint32_t *attribs,
    dca->api = __DRI_API_OPENGL;
    dca->no_error = 0;
 
-   if (num_attribs == 0)
-      return __DRI_CTX_ERROR_SUCCESS;
-
-   /* This is actually an internal error, but what the heck. */
-   if (attribs == NULL)
-      return __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
-
    for (i = 0; i < num_attribs; i++) {
       switch (attribs[i * 2]) {
       case GLX_CONTEXT_MAJOR_VERSION_ARB:
@@ -552,7 +545,7 @@ dri_convert_glx_attribs(unsigned num_attribs, const 
uint32_t *attribs,
             dca->reset = __DRI_CTX_RESET_LOSE_CONTEXT;
             break;
          default:
-            return __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
+            return BadValue;
          }
          break;
       case GLX_CONTEXT_RELEASE_BEHAVIOR_ARB:
@@ -564,7 +557,7 @@ dri_convert_glx_attribs(unsigned num_attribs, const 
uint32_t *attribs,
             dca->release = __DRI_CTX_RELEASE_BEHAVIOR_FLUSH;
             break;
          default:
-            return __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
+            return BadValue;
          }
          break;
       case GLX_SCREEN:
@@ -574,7 +567,7 @@ dri_convert_glx_attribs(unsigned num_attribs, const 
uint32_t *attribs,
       default:
         /* If an unknown attribute is received, fail.
          */
-        return __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
+        return BadValue;
       }
    }
 
@@ -601,11 +594,11 @@ dri_convert_glx_attribs(unsigned num_attribs, const 
uint32_t *attribs,
       else if (dca->major_ver == 1 && dca->minor_ver < 2)
          dca->api = __DRI_API_GLES;
       else {
-         return __DRI_CTX_ERROR_BAD_API;
+         return BadValue;
       }
       break;
    default:
-      return __DRI_CTX_ERROR_BAD_API;
+      return GLXBadProfileARB;
    }
 
    /* Unknown flag value */
@@ -613,7 +606,7 @@ dri_convert_glx_attribs(unsigned num_attribs, const 
uint32_t *attribs,
                       __DRI_CTX_FLAG_FORWARD_COMPATIBLE |
                       __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS |
                       __DRI_CTX_FLAG_RESET_ISOLATION))
-      return __DRI_CTX_ERROR_UNKNOWN_FLAG;
+      return BadValue;
 
    /* There are no forward-compatible contexts before OpenGL 3.0.  The
     * GLX_ARB_create_context spec says:
@@ -622,17 +615,23 @@ dri_convert_glx_attribs(unsigned num_attribs, const 
uint32_t *attribs,
     *     3.0 and later."
     */
    if (dca->major_ver < 3 && (dca->flags & __DRI_CTX_FLAG_FORWARD_COMPATIBLE) 
!= 0)
-      return __DRI_CTX_ERROR_BAD_FLAG;
+      return BadMatch;
 
+   /* It also says:
+    *
+    *    "OpenGL contexts supporting version 3.0 or later of the API do not
+    *    support color index rendering, even if a color index <config> is
+    *    available."
+    */
    if (dca->major_ver >= 3 && dca->render_type == GLX_COLOR_INDEX_TYPE)
-      return __DRI_CTX_ERROR_BAD_FLAG;
+      return BadMatch;
 
    /* The KHR_no_error specs say:
     *
     *    Requires OpenGL ES 2.0 or OpenGL 2.0.
     */
    if (dca->no_error && dca->major_ver < 2)
-      return __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE;
+      return BadMatch;
 
    /* The GLX_ARB_create_context_no_error specs say:
     *
@@ -642,9 +641,30 @@ dri_convert_glx_attribs(unsigned num_attribs, const 
uint32_t *attribs,
     */
    if (dca->no_error && ((dca->flags & __DRI_CTX_FLAG_DEBUG) ||
                          (dca->flags & __DRI_CTX_FLAG_ROBUST_BUFFER_ACCESS)))
-      return __DRI_CTX_ERROR_BAD_FLAG;
+      return BadMatch;
 
-   return __DRI_CTX_ERROR_SUCCESS;
+   return Success;
+}
+
+unsigned
+dri_context_error_to_glx_error(unsigned error)
+{
+   if (error == __DRI_CTX_ERROR_SUCCESS)
+      return Success;
+   if (error == __DRI_CTX_ERROR_NO_MEMORY)
+      return BadAlloc;
+   else if (error == __DRI_CTX_ERROR_BAD_API)
+      return BadMatch;
+   else if (error == __DRI_CTX_ERROR_BAD_VERSION)
+      return GLXBadFBConfig;
+   else if (error == __DRI_CTX_ERROR_BAD_FLAG)
+      return BadMatch;
+   else if (error == __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE)
+      return BadValue;
+   else if (error == __DRI_CTX_ERROR_UNKNOWN_FLAG)
+      return BadValue;
+   else
+      unreachable("Impossible DRI context error");
 }
 
 struct glx_context *
diff --git a/src/glx/dri_common.h b/src/glx/dri_common.h
index 00028203293..d762308a4fb 100644
--- a/src/glx/dri_common.h
+++ b/src/glx/dri_common.h
@@ -77,6 +77,9 @@ struct dri_ctx_attribs {
    int no_error;
 };
 
+extern unsigned
+dri_context_error_to_glx_error(unsigned error);
+
 extern int
 dri_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
                         struct dri_ctx_attribs *dca);
diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c
index e1386c84fcc..cd004741f03 100644
--- a/src/glx/drisw_glx.c
+++ b/src/glx/drisw_glx.c
@@ -591,7 +591,7 @@ drisw_create_context_attribs(struct glx_screen *base,
        *    GLX_CONTEXT_OPENGL_NO_ERROR_ARB for the context being created.
        */
       if (!!shareList->noError != !!dca.no_error) {
-         *error = __DRI_CTX_ERROR_BAD_FLAG;
+         *error = BadMatch;
          return NULL;
       }
 
@@ -643,6 +643,8 @@ drisw_create_context_attribs(struct glx_screen *base,
                                         ctx_attribs,
                                         error,
                                         pcp);
+   *error = dri_context_error_to_glx_error(*error);
+
    if (pcp->driContext == NULL) {
       free(pcp);
       return NULL;
diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h
index 3b3eb07d8fe..ead33c378fe 100644
--- a/src/glx/glxclient.h
+++ b/src/glx/glxclient.h
@@ -453,6 +453,11 @@ struct glx_screen_vtable {
                                         struct glx_context *shareList,
                                         int renderType);
 
+   /* The error outparameter abuses the fact that the only possible errors are
+    * GLXBadContext (0), GLXBadFBConfig (9), GLXBadProfileARB (13), BadValue
+    * (2), BadMatch (8), and BadAlloc (11). Since those don't collide we just
+    * use them directly rather than try to offset or use a sign convention. 
+    */
    struct glx_context *(*create_context_attribs)(struct glx_screen *psc,
                                                 struct glx_config *config,
                                                 struct glx_context *shareList,
diff --git a/src/glx/indirect_glx.c b/src/glx/indirect_glx.c
index abe561f700b..16dacc35227 100644
--- a/src/glx/indirect_glx.c
+++ b/src/glx/indirect_glx.c
@@ -247,6 +247,7 @@ indirect_create_context_attribs(struct glx_screen *psc,
 
    opcode = __glXSetupForCommand(psc->dpy);
    if (!opcode) {
+      *error = BadImplementation;
       return NULL;
    }
 
@@ -269,6 +270,7 @@ indirect_create_context_attribs(struct glx_screen *psc,
    if (mask != GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB ||
        major != 1 ||
        minor > 4) {
+      *error = GLXBadFBConfig;
       return NULL;
    }
 
@@ -279,6 +281,7 @@ indirect_create_context_attribs(struct glx_screen *psc,
    /* Allocate our context record */
    gc = calloc(1, sizeof *gc);
    if (!gc) {
+      *error = BadAlloc;
       /* Out of memory */
       return NULL;
    }
@@ -291,6 +294,7 @@ indirect_create_context_attribs(struct glx_screen *psc,
 
    if (state == NULL) {
       /* Out of memory */
+      *error = BadAlloc;
       free(gc);
       return NULL;
    }
@@ -307,6 +311,7 @@ indirect_create_context_attribs(struct glx_screen *psc,
    bufSize = (XMaxRequestSize(psc->dpy) * 4) - sz_xGLXRenderReq;
    gc->buf = malloc(bufSize);
    if (!gc->buf) {
+      *error = BadAlloc;
       free(gc->client_state_private);
       free(gc);
       return NULL;

Reply via email to