[PATCH xserver 13/13] glx: Implement GLX_EXT_libglvnd

Adam Jackson ajax at redhat.com
Wed Mar 23 22:46:55 UTC 2016


For the dri2 backend, we depend on xfree86 already, so we can walk the
options for the screen looking for a vendor string from xorg.conf.  For
the swrast backend we don't have that luxury, so just say mesa.  This
extension isn't really meaningful on Windows or OSX yet (since libglvnd
isn't really functional there yet), so on those platforms we don't say
anything and return BadValue for the token from QueryServerString.

Signed-off-by: Adam Jackson <ajax at redhat.com>
---
 glx/extension_string.c       |  1 +
 glx/extension_string.h       |  1 +
 glx/glxcmds.c                | 10 ++++++++++
 glx/glxdri2.c                | 24 ++++++++++++++++++++++++
 glx/glxdriswrast.c           |  3 +++
 glx/glxscreens.c             |  4 ++++
 glx/glxscreens.h             |  1 +
 hw/xfree86/man/xorg.conf.man |  6 ++++++
 8 files changed, 50 insertions(+)

diff --git a/glx/extension_string.c b/glx/extension_string.c
index 7e74090..d1da481 100644
--- a/glx/extension_string.c
+++ b/glx/extension_string.c
@@ -85,6 +85,7 @@ static const struct extension_info known_glx_extensions[] = {
     { GLX(EXT_fbconfig_packed_float),   VER(0,0), N, },
     { 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_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 425a805..a10d710 100644
--- a/glx/extension_string.h
+++ b/glx/extension_string.h
@@ -47,6 +47,7 @@ enum {
     EXT_create_context_es2_profile_bit,
     EXT_fbconfig_packed_float_bit,
     EXT_import_context_bit,
+    EXT_libglvnd_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 4693e68..0f0b714 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -2444,6 +2444,10 @@ __glXDisp_QueryExtensionsString(__GLXclientState * cl, GLbyte * pc)
     return Success;
 }
 
+#ifndef GLX_VENDOR_NAMES_EXT
+#define GLX_VENDOR_NAMES_EXT 0x20F6
+#endif
+
 int
 __glXDisp_QueryServerString(__GLXclientState * cl, GLbyte * pc)
 {
@@ -2471,6 +2475,12 @@ __glXDisp_QueryServerString(__GLXclientState * cl, GLbyte * pc)
     case GLX_EXTENSIONS:
         ptr = pGlxScreen->GLXextensions;
         break;
+    case GLX_VENDOR_NAMES_EXT:
+        if (pGlxScreen->glvnd) {
+            ptr = pGlxScreen->glvnd;
+            break;
+        }
+        /* else fall through */
     default:
         return BadValue;
     }
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 15253d1..a3ea273 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -934,12 +934,23 @@ initializeExtensions(__GLXscreen * screen)
 /* white lie */
 extern glx_func_ptr glXGetProcAddressARB(const char *);
 
+enum {
+    GLXOPT_VENDOR_LIBRARY,
+};
+
+static const OptionInfoRec GLXOptions[] = {
+    { GLXOPT_VENDOR_LIBRARY, "GlxVendorLibrary", OPTV_STRING, {0}, FALSE },
+    { -1, NULL, OPTV_NONE, {0}, FALSE },
+};
+
 static __GLXscreen *
 __glXDRIscreenProbe(ScreenPtr pScreen)
 {
     const char *driverName, *deviceName;
     __GLXDRIscreen *screen;
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+    const char *glvnd = NULL;
+    OptionInfoPtr options;
 
     screen = calloc(1, sizeof *screen);
     if (screen == NULL)
@@ -985,6 +996,19 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
                                                GLX_PIXMAP_BIT |
                                                GLX_PBUFFER_BIT);
 
+    options = malloc(sizeof(GLXOptions));
+    if (options) {
+        memcpy(options, GLXOptions, sizeof(GLXOptions));
+        xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+        glvnd = xf86GetOptValString(options, GLXOPT_VENDOR_LIBRARY);
+        if (glvnd)
+            screen->base.glvnd = strdup(glvnd);
+        free(options);
+    }
+
+    if (!screen->base.glvnd)
+        screen->base.glvnd = strdup("mesa");
+
     __glXScreenInit(&screen->base, pScreen);
 
     screen->enterVT = pScrn->EnterVT;
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index 0b5122f..1e46d97 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -487,6 +487,9 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
                                                GLX_PIXMAP_BIT |
                                                GLX_PBUFFER_BIT);
 
+#if !defined(XQUARTZ) && !defined(WIN32)
+    screen->base.glvnd = strdup("mesa");
+#endif
     __glXScreenInit(&screen->base, pScreen);
 
     __glXsetGetProcAddress(glXGetProcAddressARB);
diff --git a/glx/glxscreens.c b/glx/glxscreens.c
index 7e083cf..536c0c4 100644
--- a/glx/glxscreens.c
+++ b/glx/glxscreens.c
@@ -384,6 +384,9 @@ __glXScreenInit(__GLXscreen * pGlxScreen, ScreenPtr pScreen)
 
     dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey, pGlxScreen);
 
+    if (pGlxScreen->glvnd)
+        __glXEnableExtension(pGlxScreen->glx_enable_bits, "GLX_EXT_libglvnd");
+
     i = __glXGetExtensionString(pGlxScreen->glx_enable_bits, NULL);
     if (i > 0) {
         pGlxScreen->GLXextensions = xnfalloc(i);
@@ -396,6 +399,7 @@ __glXScreenInit(__GLXscreen * pGlxScreen, ScreenPtr pScreen)
 void
 __glXScreenDestroy(__GLXscreen * screen)
 {
+    free(screen->glvnd);
     free(screen->GLXextensions);
     free(screen->GLextensions);
     free(screen->visuals);
diff --git a/glx/glxscreens.h b/glx/glxscreens.h
index c63fb56..15196fa 100644
--- a/glx/glxscreens.h
+++ b/glx/glxscreens.h
@@ -143,6 +143,7 @@ struct __GLXscreen {
 
     char *GLextensions;
     char *GLXextensions;
+    char *glvnd;
     unsigned char glx_enable_bits[__GLX_EXT_BYTES];
 
     Bool (*CloseScreen) (ScreenPtr pScreen);
diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man
index d794df4..8c4aeb5 100644
--- a/hw/xfree86/man/xorg.conf.man
+++ b/hw/xfree86/man/xorg.conf.man
@@ -2039,6 +2039,12 @@ Note that disabling an operation will have no effect if the operation is
 not accelerated (whether due to lack of support in the hardware or in the
 driver).
 .TP 7
+.BI "Option \*qGlxVendorLibrary\*q \*q" string \*q
+This option specifies a space-separated list of OpenGL vendor libraries to
+use for the screen. This may be used to select an alternate implementation
+for development, debugging, or alternate feature sets.
+Default: mesa.
+.TP 7
 .BI "Option \*qInitPrimary\*q \*q" boolean \*q
 Use the Int10 module to initialize the primary graphics card.
 Normally, only secondary cards are soft-booted using the Int10 module, as the
-- 
2.5.0



More information about the xorg-devel mailing list