Blob Blame History Raw
From b9968515cc960ec7a95e32f63339eb7fd952bffc Mon Sep 17 00:00:00 2001
From: Adam Jackson <ajax@redhat.com>
Date: Wed, 16 Mar 2016 11:38:13 -0400
Subject: [PATCH xserver] glx: Implement GLX_EXT_libglvnd (v2.1)

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.

v2: Use xnf* allocators when parsing options (Eric and Emil)
v2.1: Backport to 1.18 (ajax)

Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
Signed-off-by: Adam Jackson <ajax@redhat.com>
(cherry picked from commit b08526eecf1e165ed9ec2e6b571a5a616a9b696e)
---
 glx/extension_string.c       |  1 +
 glx/extension_string.h       |  1 +
 glx/glxcmds.c                | 10 ++++++++++
 glx/glxdri2.c                | 25 +++++++++++++++++++++++++
 glx/glxdriswrast.c           |  4 ++++
 glx/glxscreens.c             |  1 +
 glx/glxscreens.h             |  2 ++
 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 616c793..d729ccf 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), Y, },
     { 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 561faeb..904e5f6 100644
--- a/glx/glxcmds.c
+++ b/glx/glxcmds.c
@@ -2443,6 +2443,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)
 {
@@ -2475,6 +2479,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 58e60b9..cabc655 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -943,6 +943,15 @@ initializeExtensions(__GLXDRIscreen * 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)
 {
@@ -950,6 +959,8 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
     __GLXDRIscreen *screen;
     size_t buffer_size;
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+    const char *glvnd = NULL;
+    OptionInfoPtr options;
 
     screen = calloc(1, sizeof *screen);
     if (screen == NULL)
@@ -995,6 +1006,20 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
                                                GLX_PIXMAP_BIT |
                                                GLX_PBUFFER_BIT);
 
+    options = xnfalloc(sizeof(GLXOptions));
+    memcpy(options, GLXOptions, sizeof(GLXOptions));
+    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+    glvnd = xf86GetOptValString(options, GLXOPT_VENDOR_LIBRARY);
+    if (glvnd)
+        screen->base.glvnd = xnfstrdup(glvnd);
+    free(options);
+
+    if (!screen->base.glvnd)
+        screen->base.glvnd = strdup("mesa");
+
+    if (screen->base.glvnd)
+        __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_libglvnd");
+
     __glXScreenInit(&screen->base, pScreen);
 
     /* The first call simply determines the length of the extension string.
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
index 924067c..0c5b784 100644
--- a/glx/glxdriswrast.c
+++ b/glx/glxdriswrast.c
@@ -487,6 +487,10 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
                                                GLX_PIXMAP_BIT |
                                                GLX_PBUFFER_BIT);
 
+#if !defined(XQUARTZ) && !defined(WIN32)
+    screen->base.glvnd = strdup("mesa");
+    __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_libglvnd");
+#endif
     __glXScreenInit(&screen->base, pScreen);
 
     /* The first call simply determines the length of the extension string.
diff --git a/glx/glxscreens.c b/glx/glxscreens.c
index b0ad3b7..8d6b076 100644
--- a/glx/glxscreens.c
+++ b/glx/glxscreens.c
@@ -418,6 +418,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 a905877..b1df222 100644
--- a/glx/glxscreens.h
+++ b/glx/glxscreens.h
@@ -154,6 +154,8 @@ struct __GLXscreen {
     unsigned GLXminor;
     /*@} */
 
+    char *glvnd;
+
     Bool (*CloseScreen) (ScreenPtr pScreen);
 };
 
diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man
index e33114d..13ee191 100644
--- a/hw/xfree86/man/xorg.conf.man
+++ b/hw/xfree86/man/xorg.conf.man
@@ -2028,6 +2028,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.7.4