[Mesa-dev] [PATCH 1/2] glx/dri: Attempt to fix GLX_OML_swap_method

Thomas Hellstrom thellstrom at vmware.com
Tue Aug 8 06:48:35 UTC 2017


The current implementation was suffering from the following problems:
1) The driGetConfigAttribIndex function was not returning any value for
the driconfig swapMethod.
2) The X server GLX code is using the value obtained from
the AIGLX dri driver driGetConfigAttribIndex to populate its GLX fbconfig.
3) The client side GLX code was assuming fbconfig and driconfig match
regardless of whether there actually was a swapMethod match.
4) We were using GLX tokens in the dri code.
5) dri3 does currently not support GLX_SWAP_COPY_OML, even if that's
advertized by the gallium dri2 state tracker.

Attempt to fix 1-4. Some highlights:

Because of 1) in combination with 2), if the X server uses an AIGLX dri driver
that doesn't have this fix, the GLX transmitted fbconfig swapMethod value will
be bogus. So if we, on the client side detect a bogus value, change it to
GLX_SWAP_UNDEFINED_OML.

We define new __DRI_ATTRIB_XXX tokens for the swap method to fix 4).
But due to 2) they need to take the same values as the GLX tokens.

Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
---
 include/GL/internal/dri_interface.h           | 17 ++++++++++++++++-
 src/gallium/state_trackers/dri/dri_screen.c   |  3 ++-
 src/glx/dri_common.c                          | 17 ++++++++++++++---
 src/glx/glxext.c                              | 12 +++++++++++-
 src/mesa/drivers/dri/common/dri_util.c        |  2 +-
 src/mesa/drivers/dri/common/utils.c           |  8 ++------
 src/mesa/drivers/dri/i915/intel_screen.c      |  2 +-
 src/mesa/drivers/dri/i965/intel_screen.c      |  2 +-
 src/mesa/drivers/dri/nouveau/nouveau_screen.c |  2 +-
 src/mesa/drivers/dri/radeon/radeon_screen.c   |  6 ++----
 src/mesa/drivers/dri/swrast/swrast.c          |  2 +-
 11 files changed, 52 insertions(+), 21 deletions(-)

diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index f676ac5..2cbd738 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -724,11 +724,26 @@ struct __DRIuseInvalidateExtensionRec {
 #define __DRI_ATTRIB_TEXTURE_2D_BIT		0x02
 #define __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT	0x04
 
+/* __DRI_ATTRIB_SWAP_METHOD */
+/* Note that with the exception of __DRI_ATTRIB_SWAP_NONE, we need to define
+ * the same tokens as GLX. This is because old and current X servers will
+ * transmit the driconf value grabbed from the AIGLX driver untranslated as
+ * the GLX fbconfig value. __DRI_ATTRIB_SWAP_NONE is only used by dri drivers
+ * to signal to the dri core that the driconfig is single-buffer.
+ */
+#define __DRI_ATTRIB_SWAP_NONE                  0x0000
+#define __DRI_ATTRIB_SWAP_EXCHANGE              0x8061
+#define __DRI_ATTRIB_SWAP_COPY                  0x8062
+#define __DRI_ATTRIB_SWAP_UNDEFINED             0x8063
+
 /**
  * This extension defines the core DRI functionality.
+ *
+ * Version >= 2 indicates that getConfigAttrib with __DRI_ATTRIB_SWAP_METHOD
+ * returns a reliable value.
  */
 #define __DRI_CORE "DRI_Core"
-#define __DRI_CORE_VERSION 1
+#define __DRI_CORE_VERSION 2
 
 struct __DRIcoreExtensionRec {
     __DRIextension base;
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index 406e97d..1d9f441 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -156,7 +156,8 @@ dri_fill_in_modes(struct dri_screen *screen)
    boolean mixed_color_depth;
 
    static const GLenum back_buffer_modes[] = {
-      GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
+      __DRI_ATTRIB_SWAP_NONE, __DRI_ATTRIB_SWAP_UNDEFINED,
+      __DRI_ATTRIB_SWAP_COPY
    };
 
    if (driQueryOptionb(&screen->dev->option_cache, "always_have_depth_buffer")) {
diff --git a/src/glx/dri_common.c b/src/glx/dri_common.c
index 854733a..e2bbd48 100644
--- a/src/glx/dri_common.c
+++ b/src/glx/dri_common.c
@@ -242,10 +242,8 @@ static const struct
       __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
       __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
       __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
-#if 0
       __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
-#endif
-__ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
+      __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
       __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
       __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE,
                      bindToMipmapTexture),
@@ -319,6 +317,19 @@ driConfigEqual(const __DRIcoreExtension *core,
             return GL_FALSE;
          break;
 
+      case __DRI_ATTRIB_SWAP_METHOD:
+         if (value == __DRI_ATTRIB_SWAP_EXCHANGE)
+            glxValue = GLX_SWAP_EXCHANGE_OML;
+         else if (value == __DRI_ATTRIB_SWAP_COPY)
+            glxValue = GLX_SWAP_COPY_OML;
+         else
+            glxValue = GLX_SWAP_UNDEFINED_OML;
+
+         if (!scalarEqual(config, attrib, glxValue))
+            return GL_FALSE;
+
+         break;
+
       default:
          if (!scalarEqual(config, attrib, value))
             return GL_FALSE;
diff --git a/src/glx/glxext.c b/src/glx/glxext.c
index 9ef7ff5..9cbe334 100644
--- a/src/glx/glxext.c
+++ b/src/glx/glxext.c
@@ -524,7 +524,17 @@ __glXInitializeVisualConfigFromTags(struct glx_config * config, int count,
          config->visualSelectGroup = *bp++;
          break;
       case GLX_SWAP_METHOD_OML:
-         config->swapMethod = *bp++;
+         if (*bp == GLX_SWAP_UNDEFINED_OML ||
+             *bp == GLX_SWAP_COPY_OML ||
+             *bp == GLX_SWAP_EXCHANGE_OML) {
+            config->swapMethod = *bp++;
+         } else {
+            /* X servers with old HW drivers may return any value here, so
+             * assume GLX_SWAP_METHOD_UNDEFINED.
+             */
+            config->swapMethod = GLX_SWAP_UNDEFINED_OML;
+            bp++;
+         }
          break;
 #endif
       case GLX_SAMPLE_BUFFERS_SGIS:
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index 39ecaf0..31a3040 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -767,7 +767,7 @@ driSwapBuffers(__DRIdrawable *pdp)
 
 /** Core interface */
 const __DRIcoreExtension driCoreExtension = {
-    .base = { __DRI_CORE, 1 },
+    .base = { __DRI_CORE, 2 },
 
     .createNewScreen            = NULL,
     .destroyScreen              = driDestroyScreen,
diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c
index c37d446..c79ed6e 100644
--- a/src/mesa/drivers/dri/common/utils.c
+++ b/src/mesa/drivers/dri/common/utils.c
@@ -284,8 +284,9 @@ driCreateConfigs(mesa_format format,
 		    modes->transparentIndex = GLX_DONT_CARE;
 		    modes->rgbMode = GL_TRUE;
 
-		    if ( db_modes[i] == GLX_NONE ) {
+		    if ( db_modes[i] == __DRI_ATTRIB_SWAP_NONE ) {
 		    	modes->doubleBufferMode = GL_FALSE;
+                        modes->swapMethod = __DRI_ATTRIB_SWAP_UNDEFINED;
 		    }
 		    else {
 		    	modes->doubleBufferMode = GL_TRUE;
@@ -403,7 +404,6 @@ static const struct { unsigned int attrib, offset; } attribMap[] = {
      * so the iterator includes them though.*/
     __ATTRIB(__DRI_ATTRIB_RENDER_TYPE,			level),
     __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT,		level),
-    __ATTRIB(__DRI_ATTRIB_SWAP_METHOD,			level)
 };
 
 
@@ -428,10 +428,6 @@ driGetConfigAttribIndex(const __DRIconfig *config,
 	else
 	    *value = 0;
 	break;
-    case __DRI_ATTRIB_SWAP_METHOD:
-        /* XXX no return value??? */
-	break;
-
     default:
         /* any other int-sized field */
 	*value = *(unsigned int *)
diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c
index 367a734..6e32ac2 100644
--- a/src/mesa/drivers/dri/i915/intel_screen.c
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
@@ -1060,7 +1060,7 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
 
    /* GLX_SWAP_COPY_OML is not supported due to page flipping. */
    static const GLenum back_buffer_modes[] = {
-       GLX_SWAP_UNDEFINED_OML, GLX_NONE,
+      __DRI_ATTRIB_SWAP_UNDEFINED, __DRI_ATTRIB_SWAP_NONE
    };
 
    static const uint8_t singlesample_samples[1] = {0};
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index ec07cf0..452f0d1 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -1774,7 +1774,7 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
 
    /* GLX_SWAP_COPY_OML is not supported due to page flipping. */
    static const GLenum back_buffer_modes[] = {
-       GLX_SWAP_UNDEFINED_OML, GLX_NONE,
+      __DRI_ATTRIB_SWAP_UNDEFINED, __DRI_ATTRIB_SWAP_NONE
    };
 
    static const uint8_t singlesample_samples[1] = {0};
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
index 65caec2..95b3469 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
@@ -65,7 +65,7 @@ nouveau_get_configs(uint32_t chipset)
 	};
 
 	const GLenum back_buffer_modes[] = {
-		GLX_NONE, GLX_SWAP_UNDEFINED_OML
+		__DRI_ATTRIB_SWAP_NONE, __DRI_ATTRIB_SWAP_UNDEFINED
 	};
 
 	for (i = 0; i < ARRAY_SIZE(formats); i++) {
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index a2061e5..750a654 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -770,11 +770,9 @@ __DRIconfig **radeonInitScreen2(__DRIscreen *psp)
       MESA_FORMAT_B8G8R8X8_UNORM,
       MESA_FORMAT_B8G8R8A8_UNORM
    };
-   /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
-    * support pageflipping at all.
-    */
+
    static const GLenum back_buffer_modes[] = {
-     GLX_NONE, GLX_SWAP_UNDEFINED_OML, /*, GLX_SWAP_COPY_OML*/
+      __DRI_ATTRIB_SWAP_NONE, __DRI_ATTRIB_SWAP_UNDEFINED
    };
    uint8_t depth_bits[4], stencil_bits[4], msaa_samples_array[1];
    int color;
diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c
index 7de90d3..45d8279 100644
--- a/src/mesa/drivers/dri/swrast/swrast.c
+++ b/src/mesa/drivers/dri/swrast/swrast.c
@@ -227,7 +227,7 @@ swrastFillInModes(__DRIscreen *psp,
      * support pageflipping at all.
      */
     static const GLenum back_buffer_modes[] = {
-	GLX_NONE, GLX_SWAP_UNDEFINED_OML
+	__DRI_ATTRIB_SWAP_NONE, __DRI_ATTRIB_SWAP_UNDEFINED
     };
 
     uint8_t depth_bits_array[4];
-- 
2.7.4



More information about the mesa-dev mailing list