xserver: Branch 'master' - 3 commits

Adam Jackson ajax at kemper.freedesktop.org
Tue Dec 5 21:36:51 UTC 2017


 glx/createcontext.c      |   20 ++++++++++++++---
 glx/extension_string.c   |    1 
 glx/extension_string.h   |    1 
 glx/glxcmds.c            |   55 +++++++++++++++++++++++++++++++++++++++--------
 glx/glxdri2.c            |   14 ++++++-----
 glx/glxdriswrast.c       |    9 +++++--
 hw/xquartz/GL/indirect.c |    2 -
 7 files changed, 81 insertions(+), 21 deletions(-)

New commits:
commit a4c1e290824d0e40191ad26019b705f61c11e113
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Nov 14 15:15:03 2017 -0500

    glx: Implement GLX_EXT_no_config_context (v2)
    
    Only enabled for the DRI backends at the moment. In principle WGL/CGL
    could support this - it's sort of implied by GL 3.0 support - but in
    practice their implementations back GLX drawables with native drawables
    (and not anonymous FBOs), so they would need either a corresponding
    window system binding extension or significant implementation work.
    
    v2: Require that the two screen numbers match, per v4 of spec.
    
    Khronos: https://github.com/KhronosGroup/OpenGL-Registry/pull/102
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glx/createcontext.c b/glx/createcontext.c
index 1216f9412..76316db67 100644
--- a/glx/createcontext.c
+++ b/glx/createcontext.c
@@ -93,7 +93,7 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
     __GLXcontext *ctx = NULL;
     __GLXcontext *shareCtx = NULL;
     __GLXscreen *glxScreen;
-    __GLXconfig *config;
+    __GLXconfig *config = NULL;
     int err;
 
     /* The GLX_ARB_create_context_robustness spec says:
@@ -136,8 +136,10 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
     if (!validGlxScreen(client, req->screen, &glxScreen, &err))
         return __glXError(GLXBadFBConfig);
 
-    if (!validGlxFBConfig(client, glxScreen, req->fbconfig, &config, &err))
-        return __glXError(GLXBadFBConfig);
+    if (req->fbconfig) {
+        if (!validGlxFBConfig(client, glxScreen, req->fbconfig, &config, &err))
+            return __glXError(GLXBadFBConfig);
+    }
 
     /* Validate the context with which the new context should share resources.
      */
@@ -182,6 +184,9 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
             break;
 
         case GLX_RENDER_TYPE:
+            /* Not valid for GLX_EXT_no_config_context */
+            if (!req->fbconfig)
+                return BadValue;
             render_type = attribs[2 * i + 1];
             break;
 
@@ -206,6 +211,15 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
             break;
 #endif
 
+        case GLX_SCREEN:
+            /* Only valid for GLX_EXT_no_config_context */
+            if (req->fbconfig)
+                return BadValue;
+            /* Must match the value in the request header */
+            if (attribs[2 * i + 1] != req->screen)
+                return BadValue;
+            break;
+
         default:
             if (!req->isDirect)
                 return BadValue;
diff --git a/glx/extension_string.c b/glx/extension_string.c
index d1da4815c..102f9dd42 100644
--- a/glx/extension_string.c
+++ b/glx/extension_string.c
@@ -86,6 +86,7 @@ static const struct extension_info known_glx_extensions[] = {
     { GLX(EXT_framebuffer_sRGB),        VER(0,0), N, },
     { GLX(EXT_import_context),          VER(0,0), Y, },
     { GLX(EXT_libglvnd),                VER(0,0), N, },
+    { GLX(EXT_no_config_context),       VER(0,0), N, },
     { GLX(EXT_stereo_tree),             VER(0,0), N, },
     { GLX(EXT_texture_from_pixmap),     VER(0,0), N, },
     { GLX(EXT_visual_info),             VER(0,0), Y, },
diff --git a/glx/extension_string.h b/glx/extension_string.h
index a10d7108a..f049f5840 100644
--- a/glx/extension_string.h
+++ b/glx/extension_string.h
@@ -48,6 +48,7 @@ enum {
     EXT_fbconfig_packed_float_bit,
     EXT_import_context_bit,
     EXT_libglvnd_bit,
+    EXT_no_config_context_bit,
     EXT_stereo_tree_bit,
     EXT_texture_from_pixmap_bit,
     EXT_visual_info_bit,
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 9c005c717..2ebf4a350 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -1770,13 +1770,13 @@ DoQueryContext(__GLXclientState * cl, GLXContextID gcId)
     sendBuf[0] = GLX_SHARE_CONTEXT_EXT;
     sendBuf[1] = (int) (ctx->share_id);
     sendBuf[2] = GLX_VISUAL_ID_EXT;
-    sendBuf[3] = (int) (ctx->config->visualID);
+    sendBuf[3] = (int) (ctx->config ? ctx->config->visualID : 0);
     sendBuf[4] = GLX_SCREEN_EXT;
     sendBuf[5] = (int) (ctx->pGlxScreen->pScreen->myNum);
     sendBuf[6] = GLX_FBCONFIG_ID;
-    sendBuf[7] = (int) (ctx->config->fbconfigID);
+    sendBuf[7] = (int) (ctx->config ? ctx->config->fbconfigID : 0);
     sendBuf[8] = GLX_RENDER_TYPE;
-    sendBuf[9] = (int) (ctx->config->renderType);
+    sendBuf[9] = (int) (ctx->config ? ctx->config->renderType : GLX_DONT_CARE);
 
     if (client->swapped) {
         int length = reply.length;
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 2c542bfdf..2e24b56e6 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -441,6 +441,7 @@ create_driver_context(__GLXDRIcontext * context,
                       int *error)
 {
     context->driContext = NULL;
+    const __DRIconfig *driConfig = config ? config->driConfig : NULL;
 
     if (screen->dri2->base.version >= 3) {
         uint32_t ctx_attribs[4 * 2];
@@ -483,10 +484,8 @@ create_driver_context(__GLXDRIcontext * context,
         }
 
         context->driContext =
-            (*screen->dri2->createContextAttribs)(screen->driScreen,
-                                                  api,
-                                                  config->driConfig,
-                                                  driShare,
+            (*screen->dri2->createContextAttribs)(screen->driScreen, api,
+                                                  driConfig, driShare,
                                                   num_ctx_attribs / 2,
                                                   ctx_attribs,
                                                   &dri_err,
@@ -522,8 +521,7 @@ create_driver_context(__GLXDRIcontext * context,
     }
 
     context->driContext =
-        (*screen->dri2->createNewContext) (screen->driScreen,
-                                           config->driConfig,
+        (*screen->dri2->createNewContext) (screen->driScreen, driConfig,
                                            driShare, context);
 }
 
@@ -831,6 +829,9 @@ initializeExtensions(__GLXscreen * screen)
     __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer");
     LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
 
+    __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_no_config_context");
+    LogMessage(X_INFO, "AIGLX: enabled GLX_EXT_no_config_context\n");
+
     if (dri->dri2->base.version >= 3) {
         __glXEnableExtension(screen->glx_enable_bits,
                              "GLX_ARB_create_context");
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index c000d6cfb..adc97df93 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -211,6 +211,7 @@ __glXDRIscreenCreateContext(__GLXscreen * baseScreen,
     __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
     __GLXDRIcontext *context, *shareContext;
     __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
+    const __DRIconfig *driConfig = config ? config->driConfig : NULL;
     const __DRIcoreExtension *core = screen->core;
     __DRIcontext *driShare;
 
@@ -240,8 +241,8 @@ __glXDRIscreenCreateContext(__GLXscreen * baseScreen,
     context->base.releaseTexImage = __glXDRIreleaseTexImage;
 
     context->driContext =
-        (*core->createNewContext) (screen->driScreen,
-                                   config->driConfig, driShare, context);
+        (*core->createNewContext) (screen->driScreen, driConfig, driShare,
+                                   context);
 
     return &context->base;
 }
@@ -352,6 +353,9 @@ initializeExtensions(__GLXscreen * screen)
     __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer");
     LogMessage(X_INFO, "IGLX: enabled GLX_MESA_copy_sub_buffer\n");
 
+    __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_no_config_context");
+    LogMessage(X_INFO, "IGLX: enabled GLX_EXT_no_config_context\n");
+
     if (dri->swrast->base.version >= 3) {
         __glXEnableExtension(screen->glx_enable_bits,
                              "GLX_ARB_create_context");
commit f0fffa926a5771e0e604fe9a48178b0514ca5d41
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Nov 14 15:15:02 2017 -0500

    glx: Prepare __glXGetDrawable for no-config contexts
    
    Any proper (GLX 1.3) drawable will already have a bound config, but if
    we're doing the GLX 1.2 thing of making a Window current, we need to
    infer the config from the window's Visual.
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 6dda5a6d0..9c005c717 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -474,6 +474,18 @@ StartUsingContext(__GLXclientState * cl, __GLXcontext * glxc)
     glxc->currentClient = cl->client;
 }
 
+static __GLXconfig *
+inferConfigForWindow(__GLXscreen *pGlxScreen, WindowPtr pWin)
+{
+    int i, vid = wVisual(pWin);
+
+    for (i = 0; i < pGlxScreen->numVisuals; i++)
+        if (pGlxScreen->visuals[i]->visualID == vid)
+            return pGlxScreen->visuals[i];
+
+    return NULL;
+}
+
 /**
  * This is a helper function to handle the legacy (pre GLX 1.3) cases
  * where passing an X window to glXMakeCurrent is valid.  Given a
@@ -486,11 +498,15 @@ __glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client,
 {
     DrawablePtr pDraw;
     __GLXdrawable *pGlxDraw;
+    __GLXconfig *config;
+    __GLXscreen *pGlxScreen;
     int rc;
 
     if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
                          DixWriteAccess, &pGlxDraw, &rc)) {
-        if (glxc != NULL && pGlxDraw->config != glxc->config) {
+        if (glxc != NULL &&
+            glxc->config != NULL &&
+            glxc->config != pGlxDraw->config) {
             client->errorValue = drawId;
             *error = BadMatch;
             return NULL;
@@ -518,19 +534,35 @@ __glXGetDrawable(__GLXcontext * glxc, GLXDrawable drawId, ClientPtr client,
         return NULL;
     }
 
-    if (pDraw->pScreen != glxc->pGlxScreen->pScreen) {
+    pGlxScreen = glxc->pGlxScreen;
+    if (pDraw->pScreen != pGlxScreen->pScreen) {
         client->errorValue = pDraw->pScreen->myNum;
         *error = BadMatch;
         return NULL;
     }
 
-    if (!validGlxFBConfigForWindow(client, glxc->config, pDraw, error))
+    config = glxc->config;
+    if (!config)
+        config = inferConfigForWindow(pGlxScreen, (WindowPtr)pDraw);
+    if (!config) {
+        /*
+         * If we get here, we've tried to bind a no-config context to a
+         * window without a corresponding fbconfig, presumably because
+         * we don't support GL on it (PseudoColor perhaps). From GLX Section
+         * 3.3.7 "Rendering Contexts":
+         *
+         * "If draw or read are not compatible with ctx a BadMatch error
+         * is generated."
+         */
+        *error = BadMatch;
+        return NULL;
+    }
+
+    if (!validGlxFBConfigForWindow(client, config, pDraw, error))
         return NULL;
 
-    pGlxDraw = glxc->pGlxScreen->createDrawable(client, glxc->pGlxScreen,
-                                                pDraw, drawId,
-                                                GLX_DRAWABLE_WINDOW,
-                                                drawId, glxc->config);
+    pGlxDraw = pGlxScreen->createDrawable(client, pGlxScreen, pDraw, drawId,
+                                          GLX_DRAWABLE_WINDOW, drawId, config);
     if (!pGlxDraw) {
 	*error = BadAlloc;
 	return NULL;
commit 5d667df6ea1634191a26f9a7c26bc883701d62b0
Author: Adam Jackson <ajax at redhat.com>
Date:   Tue Nov 14 15:15:01 2017 -0500

    glx: Fix glXQueryContext for GLX_FBCONFIG_ID and GLX_RENDER_TYPE (v2)
    
    Just never filled in, oops. Seems to have gone unnoticed because
    normally glXQueryContext simply returns the values filled in by the
    client library when the context was created. The only path by which you
    normally get to a GLXQueryContext request is glXImportContext, and then
    only if the context is already indirect.
    
    However, that's a statement about Mesa's libGL (and anything else that
    inherited that bit of the SGI SI more or less intact). Nothing prevents
    a mischeivous client from issuing that request of a direct context, and
    if they did we'd be in trouble because we never bothered to preserve the
    associated fbconfig in the context state, so we'd crash looking up
    GLX_VISUAL_ID_EXT. So let's fix that too.
    
    v2: Fixed missing preservation of the config in DRI2 (Eric Anholt)
    
    Signed-off-by: Adam Jackson <ajax at redhat.com>
    Reviewed-by: Eric Anholt <eric at anholt.net>

diff --git a/glx/glxcmds.c b/glx/glxcmds.c
index 061acb793..6dda5a6d0 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -215,6 +215,7 @@ __glXdirectContextCreate(__GLXscreen * screen,
     if (context == NULL)
         return NULL;
 
+    context->config = modes;
     context->destroy = __glXdirectContextDestroy;
     context->loseCurrent = __glXdirectContextLoseCurrent;
 
@@ -1718,7 +1719,7 @@ DoQueryContext(__GLXclientState * cl, GLXContextID gcId)
     ClientPtr client = cl->client;
     __GLXcontext *ctx;
     xGLXQueryContextInfoEXTReply reply;
-    int nProps = 3;
+    int nProps = 5;
     int sendBuf[nProps * 2];
     int nReplyBytes;
     int err;
@@ -1740,6 +1741,10 @@ DoQueryContext(__GLXclientState * cl, GLXContextID gcId)
     sendBuf[3] = (int) (ctx->config->visualID);
     sendBuf[4] = GLX_SCREEN_EXT;
     sendBuf[5] = (int) (ctx->pGlxScreen->pScreen->myNum);
+    sendBuf[6] = GLX_FBCONFIG_ID;
+    sendBuf[7] = (int) (ctx->config->fbconfigID);
+    sendBuf[8] = GLX_RENDER_TYPE;
+    sendBuf[9] = (int) (ctx->config->renderType);
 
     if (client->swapped) {
         int length = reply.length;
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 8f5aab0c2..2c542bfdf 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -552,6 +552,7 @@ __glXDRIscreenCreateContext(__GLXscreen * baseScreen,
         return NULL;
     }
 
+    context->base.config = glxConfig;
     context->base.destroy = __glXDRIcontextDestroy;
     context->base.makeCurrent = __glXDRIcontextMakeCurrent;
     context->base.loseCurrent = __glXDRIcontextLoseCurrent;
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index 5b1f3d1fc..c000d6cfb 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -231,6 +231,7 @@ __glXDRIscreenCreateContext(__GLXscreen * baseScreen,
     if (context == NULL)
         return NULL;
 
+    context->base.config = glxConfig;
     context->base.destroy = __glXDRIcontextDestroy;
     context->base.makeCurrent = __glXDRIcontextMakeCurrent;
     context->base.loseCurrent = __glXDRIcontextLoseCurrent;
diff --git a/hw/xquartz/GL/indirect.c b/hw/xquartz/GL/indirect.c
index 2d88ef284..6738946ff 100644
--- a/hw/xquartz/GL/indirect.c
+++ b/hw/xquartz/GL/indirect.c
@@ -156,7 +156,7 @@ __glXAquaScreenCreateContext(__GLXscreen *screen,
     memset(context, 0, sizeof *context);
 
     context->base.pGlxScreen = screen;
-
+    context->base.config = conf;
     context->base.destroy = __glXAquaContextDestroy;
     context->base.makeCurrent = __glXAquaContextMakeCurrent;
     context->base.loseCurrent = __glXAquaContextLoseCurrent;


More information about the xorg-commit mailing list