0deee42
From b9968515cc960ec7a95e32f63339eb7fd952bffc Mon Sep 17 00:00:00 2001
0deee42
From: Adam Jackson <ajax@redhat.com>
0deee42
Date: Wed, 16 Mar 2016 11:38:13 -0400
0deee42
Subject: [PATCH xserver] glx: Implement GLX_EXT_libglvnd (v2.1)
0deee42
0deee42
For the dri2 backend, we depend on xfree86 already, so we can walk the
0deee42
options for the screen looking for a vendor string from xorg.conf.  For
0deee42
the swrast backend we don't have that luxury, so just say mesa.  This
0deee42
extension isn't really meaningful on Windows or OSX yet (since libglvnd
0deee42
isn't really functional there yet), so on those platforms we don't say
0deee42
anything and return BadValue for the token from QueryServerString.
0deee42
0deee42
v2: Use xnf* allocators when parsing options (Eric and Emil)
0deee42
v2.1: Backport to 1.18 (ajax)
0deee42
0deee42
Reviewed-by: Eric Anholt <eric@anholt.net>
0deee42
Reviewed-by: Emil Velikov <emil.velikov@collabora.com>
0deee42
Signed-off-by: Adam Jackson <ajax@redhat.com>
0deee42
(cherry picked from commit b08526eecf1e165ed9ec2e6b571a5a616a9b696e)
0deee42
---
0deee42
 glx/extension_string.c       |  1 +
0deee42
 glx/extension_string.h       |  1 +
0deee42
 glx/glxcmds.c                | 10 ++++++++++
0deee42
 glx/glxdri2.c                | 25 +++++++++++++++++++++++++
0deee42
 glx/glxdriswrast.c           |  4 ++++
0deee42
 glx/glxscreens.c             |  1 +
0deee42
 glx/glxscreens.h             |  2 ++
0deee42
 hw/xfree86/man/xorg.conf.man |  6 ++++++
0deee42
 8 files changed, 50 insertions(+)
0deee42
0deee42
diff --git a/glx/extension_string.c b/glx/extension_string.c
0deee42
index 616c793..d729ccf 100644
0deee42
--- a/glx/extension_string.c
0deee42
+++ b/glx/extension_string.c
0deee42
@@ -85,6 +85,7 @@ static const struct extension_info known_glx_extensions[] = {
0deee42
     { GLX(EXT_fbconfig_packed_float),   VER(0,0), N, },
0deee42
     { GLX(EXT_framebuffer_sRGB),        VER(0,0), N, },
0deee42
     { GLX(EXT_import_context),          VER(0,0), Y, },
0deee42
+    { GLX(EXT_libglvnd),                VER(0,0), N, },
0deee42
     { GLX(EXT_stereo_tree),             VER(0,0), N, },
0deee42
     { GLX(EXT_texture_from_pixmap),     VER(0,0), Y, },
0deee42
     { GLX(EXT_visual_info),             VER(0,0), Y, },
0deee42
diff --git a/glx/extension_string.h b/glx/extension_string.h
0deee42
index 425a805..a10d710 100644
0deee42
--- a/glx/extension_string.h
0deee42
+++ b/glx/extension_string.h
0deee42
@@ -47,6 +47,7 @@ enum {
0deee42
     EXT_create_context_es2_profile_bit,
0deee42
     EXT_fbconfig_packed_float_bit,
0deee42
     EXT_import_context_bit,
0deee42
+    EXT_libglvnd_bit,
0deee42
     EXT_stereo_tree_bit,
0deee42
     EXT_texture_from_pixmap_bit,
0deee42
     EXT_visual_info_bit,
0deee42
diff --git a/glx/glxcmds.c b/glx/glxcmds.c
0deee42
index 561faeb..904e5f6 100644
0deee42
--- a/glx/glxcmds.c
0deee42
+++ b/glx/glxcmds.c
0deee42
@@ -2443,6 +2443,10 @@ __glXDisp_QueryExtensionsString(__GLXclientState * cl, GLbyte * pc)
0deee42
     return Success;
0deee42
 }
0deee42
 
0deee42
+#ifndef GLX_VENDOR_NAMES_EXT
0deee42
+#define GLX_VENDOR_NAMES_EXT 0x20F6
0deee42
+#endif
0deee42
+
0deee42
 int
0deee42
 __glXDisp_QueryServerString(__GLXclientState * cl, GLbyte * pc)
0deee42
 {
0deee42
@@ -2475,6 +2479,12 @@ __glXDisp_QueryServerString(__GLXclientState * cl, GLbyte * pc)
0deee42
     case GLX_EXTENSIONS:
0deee42
         ptr = pGlxScreen->GLXextensions;
0deee42
         break;
0deee42
+    case GLX_VENDOR_NAMES_EXT:
0deee42
+        if (pGlxScreen->glvnd) {
0deee42
+            ptr = pGlxScreen->glvnd;
0deee42
+            break;
0deee42
+        }
0deee42
+        /* else fall through */
0deee42
     default:
0deee42
         return BadValue;
0deee42
     }
0deee42
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
0deee42
index 58e60b9..cabc655 100644
0deee42
--- a/glx/glxdri2.c
0deee42
+++ b/glx/glxdri2.c
0deee42
@@ -943,6 +943,15 @@ initializeExtensions(__GLXDRIscreen * screen)
0deee42
 /* white lie */
0deee42
 extern glx_func_ptr glXGetProcAddressARB(const char *);
0deee42
 
0deee42
+enum {
0deee42
+    GLXOPT_VENDOR_LIBRARY,
0deee42
+};
0deee42
+
0deee42
+static const OptionInfoRec GLXOptions[] = {
0deee42
+    { GLXOPT_VENDOR_LIBRARY, "GlxVendorLibrary", OPTV_STRING, {0}, FALSE },
0deee42
+    { -1, NULL, OPTV_NONE, {0}, FALSE },
0deee42
+};
0deee42
+
0deee42
 static __GLXscreen *
0deee42
 __glXDRIscreenProbe(ScreenPtr pScreen)
0deee42
 {
0deee42
@@ -950,6 +959,8 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
0deee42
     __GLXDRIscreen *screen;
0deee42
     size_t buffer_size;
0deee42
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
0deee42
+    const char *glvnd = NULL;
0deee42
+    OptionInfoPtr options;
0deee42
 
0deee42
     screen = calloc(1, sizeof *screen);
0deee42
     if (screen == NULL)
0deee42
@@ -995,6 +1006,20 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
0deee42
                                                GLX_PIXMAP_BIT |
0deee42
                                                GLX_PBUFFER_BIT);
0deee42
 
0deee42
+    options = xnfalloc(sizeof(GLXOptions));
0deee42
+    memcpy(options, GLXOptions, sizeof(GLXOptions));
0deee42
+    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
0deee42
+    glvnd = xf86GetOptValString(options, GLXOPT_VENDOR_LIBRARY);
0deee42
+    if (glvnd)
0deee42
+        screen->base.glvnd = xnfstrdup(glvnd);
0deee42
+    free(options);
0deee42
+
0deee42
+    if (!screen->base.glvnd)
0deee42
+        screen->base.glvnd = strdup("mesa");
0deee42
+
0deee42
+    if (screen->base.glvnd)
0deee42
+        __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_libglvnd");
0deee42
+
0deee42
     __glXScreenInit(&screen->base, pScreen);
0deee42
 
0deee42
     /* The first call simply determines the length of the extension string.
0deee42
diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c
0deee42
index 924067c..0c5b784 100644
0deee42
--- a/glx/glxdriswrast.c
0deee42
+++ b/glx/glxdriswrast.c
0deee42
@@ -487,6 +487,10 @@ __glXDRIscreenProbe(ScreenPtr pScreen)
0deee42
                                                GLX_PIXMAP_BIT |
0deee42
                                                GLX_PBUFFER_BIT);
0deee42
 
0deee42
+#if !defined(XQUARTZ) && !defined(WIN32)
0deee42
+    screen->base.glvnd = strdup("mesa");
0deee42
+    __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_libglvnd");
0deee42
+#endif
0deee42
     __glXScreenInit(&screen->base, pScreen);
0deee42
 
0deee42
     /* The first call simply determines the length of the extension string.
0deee42
diff --git a/glx/glxscreens.c b/glx/glxscreens.c
0deee42
index b0ad3b7..8d6b076 100644
0deee42
--- a/glx/glxscreens.c
0deee42
+++ b/glx/glxscreens.c
0deee42
@@ -418,6 +418,7 @@ __glXScreenInit(__GLXscreen * pGlxScreen, ScreenPtr pScreen)
0deee42
 void
0deee42
 __glXScreenDestroy(__GLXscreen * screen)
0deee42
 {
0deee42
+    free(screen->glvnd);
0deee42
     free(screen->GLXextensions);
0deee42
     free(screen->GLextensions);
0deee42
     free(screen->visuals);
0deee42
diff --git a/glx/glxscreens.h b/glx/glxscreens.h
0deee42
index a905877..b1df222 100644
0deee42
--- a/glx/glxscreens.h
0deee42
+++ b/glx/glxscreens.h
0deee42
@@ -154,6 +154,8 @@ struct __GLXscreen {
0deee42
     unsigned GLXminor;
0deee42
     /*@} */
0deee42
 
0deee42
+    char *glvnd;
0deee42
+
0deee42
     Bool (*CloseScreen) (ScreenPtr pScreen);
0deee42
 };
0deee42
 
0deee42
diff --git a/hw/xfree86/man/xorg.conf.man b/hw/xfree86/man/xorg.conf.man
0deee42
index e33114d..13ee191 100644
0deee42
--- a/hw/xfree86/man/xorg.conf.man
0deee42
+++ b/hw/xfree86/man/xorg.conf.man
0deee42
@@ -2028,6 +2028,12 @@ Note that disabling an operation will have no effect if the operation is
0deee42
 not accelerated (whether due to lack of support in the hardware or in the
0deee42
 driver).
0deee42
 .TP 7
0deee42
+.BI "Option \*qGlxVendorLibrary\*q \*q" string \*q
0deee42
+This option specifies a space-separated list of OpenGL vendor libraries to
0deee42
+use for the screen. This may be used to select an alternate implementation
0deee42
+for development, debugging, or alternate feature sets.
0deee42
+Default: mesa.
0deee42
+.TP 7
0deee42
 .BI "Option \*qInitPrimary\*q \*q" boolean \*q
0deee42
 Use the Int10 module to initialize the primary graphics card.
0deee42
 Normally, only secondary cards are soft-booted using the Int10 module, as the
0deee42
-- 
0deee42
2.7.4
0deee42