Merge branch 'glsl-to-tgsi'
[mesa.git] / src / gallium / state_trackers / glx / xlib / glx_api.c
index eb8d6a1933397b3295f5e6bf2afc1ab85c7a40cb..a7aafd846cdfbe700b81b392fab5a8559f6f2380 100644 (file)
 #include "GL/glx.h"
 
 #include "xm_api.h"
-#include "main/context.h"
-#include "main/macros.h"
-#include "main/imports.h"
-#include "main/version.h"
 
 
 /* This indicates the client-side GLX API and GLX encoder version. */
@@ -50,9 +46,6 @@
 #define SERVER_MAJOR_VERSION 1
 #define SERVER_MINOR_VERSION 4
 
-/* This is appended onto the glXGetClient/ServerString version strings. */
-#define MESA_GLX_VERSION "Mesa " MESA_VERSION_STRING
-
 /* Who implemented this GLX? */
 #define VENDOR "Brian Paul"
 
@@ -603,8 +596,8 @@ destroy_visuals_on_display(Display *dpy)
 static int
 close_display_callback(Display *dpy, XExtCodes *codes)
 {
-   destroy_visuals_on_display(dpy);
    xmesa_destroy_buffers_on_display(dpy);
+   destroy_visuals_on_display(dpy);
    return 0;
 }
 
@@ -871,16 +864,19 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
             parselist++;
             break;
          case GLX_FBCONFIG_ID:
+         case GLX_VISUAL_ID:
             if (!fbConfig)
                return NULL;
             parselist++;
             desiredVisualID = *parselist++;
             break;
          case GLX_X_RENDERABLE:
+         case GLX_MAX_PBUFFER_WIDTH:
+         case GLX_MAX_PBUFFER_HEIGHT:
+         case GLX_MAX_PBUFFER_PIXELS:
             if (!fbConfig)
-               return NULL;
-            parselist += 2;
-            /* ignore */
+               return NULL; /* invalid config option */
+            parselist += 2; /* ignore the parameter */
             break;
 
 #ifdef GLX_EXT_texture_from_pixmap
@@ -1025,15 +1021,18 @@ glXChooseVisual( Display *dpy, int screen, int *list )
 }
 
 
-PUBLIC GLXContext
-glXCreateContext( Display *dpy, XVisualInfo *visinfo,
-                  GLXContext share_list, Bool direct )
+/**
+ * Helper function used by other glXCreateContext functions.
+ */
+static GLXContext
+create_context(Display *dpy, XMesaVisual xmvis,
+               XMesaContext shareCtx, Bool direct,
+               unsigned major, unsigned minor,
+               unsigned profileMask, unsigned contextFlags)
 {
-   XMesaVisual xmvis;
    GLXContext glxCtx;
-   GLXContext shareCtx = share_list;
 
-   if (!dpy || !visinfo)
+   if (!dpy || !xmvis)
       return 0;
 
    glxCtx = CALLOC_STRUCT(__GLXcontextRec);
@@ -1045,19 +1044,8 @@ glXCreateContext( Display *dpy, XVisualInfo *visinfo,
    XMesaGarbageCollect();
 #endif
 
-   xmvis = find_glx_visual( dpy, visinfo );
-   if (!xmvis) {
-      /* This visual wasn't found with glXChooseVisual() */
-      xmvis = create_glx_visual( dpy, visinfo );
-      if (!xmvis) {
-         /* unusable visual */
-         free(glxCtx);
-         return NULL;
-      }
-   }
-
-   glxCtx->xmesaContext = XMesaCreateContext(xmvis,
-                                   shareCtx ? shareCtx->xmesaContext : NULL);
+   glxCtx->xmesaContext = XMesaCreateContext(xmvis, shareCtx, major, minor,
+                                             profileMask, contextFlags);
    if (!glxCtx->xmesaContext) {
       free(glxCtx);
       return NULL;
@@ -1071,6 +1059,29 @@ glXCreateContext( Display *dpy, XVisualInfo *visinfo,
 }
 
 
+PUBLIC GLXContext
+glXCreateContext( Display *dpy, XVisualInfo *visinfo,
+                  GLXContext shareCtx, Bool direct )
+{
+   XMesaVisual xmvis;
+
+   xmvis = find_glx_visual( dpy, visinfo );
+   if (!xmvis) {
+      /* This visual wasn't found with glXChooseVisual() */
+      xmvis = create_glx_visual( dpy, visinfo );
+      if (!xmvis) {
+         /* unusable visual */
+         return NULL;
+      }
+   }
+
+   return create_context(dpy, xmvis,
+                         shareCtx ? shareCtx->xmesaContext : NULL,
+                         direct,
+                         1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
+}
+
+
 /* XXX these may have to be removed due to thread-safety issues. */
 static GLXContext MakeCurrent_PrevContext = 0;
 static GLXDrawable MakeCurrent_PrevDrawable = 0;
@@ -1299,7 +1310,7 @@ glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
    XMesaContext xm_dst = dst->xmesaContext;
    (void) dpy;
    if (MakeCurrent_PrevContext == src) {
-      _mesa_Flush();
+      glFlush();
    }
    XMesaCopyContext(xm_src, xm_dst, mask);
 }
@@ -1374,8 +1385,8 @@ glXSwapBuffers( Display *dpy, GLXDrawable drawable )
 /*** GLX_MESA_copy_sub_buffer ***/
 
 PUBLIC void
-glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
-                           int x, int y, int width, int height )
+glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable,
+                     int x, int y, int width, int height)
 {
    XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
    if (buffer) {
@@ -1676,7 +1687,7 @@ glXQueryServerString( Display *dpy, int screen, int name )
 {
    static char version[1000];
    sprintf(version, "%d.%d %s",
-          SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, MESA_GLX_VERSION);
+          SERVER_MAJOR_VERSION, SERVER_MINOR_VERSION, xmesa_get_name());
 
    (void) dpy;
    (void) screen;
@@ -1701,7 +1712,7 @@ glXGetClientString( Display *dpy, int name )
 {
    static char version[1000];
    sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION,
-          CLIENT_MINOR_VERSION, MESA_GLX_VERSION);
+          CLIENT_MINOR_VERSION, xmesa_get_name());
 
    (void) dpy;
 
@@ -1725,8 +1736,8 @@ glXGetClientString( Display *dpy, int name )
 
 
 PUBLIC int
-glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
-                           int attribute, int *value )
+glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config,
+                     int attribute, int *value)
 {
    XMesaVisual v = (XMesaVisual) config;
    (void) dpy;
@@ -1770,8 +1781,8 @@ glXGetFBConfigs( Display *dpy, int screen, int *nelements )
 
 
 PUBLIC GLXFBConfig *
-glXChooseFBConfig( Display *dpy, int screen,
-                        const int *attribList, int *nitems )
+glXChooseFBConfig(Display *dpy, int screen,
+                  const int *attribList, int *nitems)
 {
    XMesaVisual xmvis;
 
@@ -1821,8 +1832,8 @@ glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
 
 
 PUBLIC GLXWindow
-glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
-                      const int *attribList )
+glXCreateWindow(Display *dpy, GLXFBConfig config, Window win,
+                const int *attribList)
 {
    XMesaVisual xmvis = (XMesaVisual) config;
    XMesaBuffer xmbuf;
@@ -1852,8 +1863,8 @@ glXDestroyWindow( Display *dpy, GLXWindow window )
 
 /* XXX untested */
 PUBLIC GLXPixmap
-glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
-                      const int *attribList )
+glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap,
+                const int *attribList)
 {
    XMesaVisual v = (XMesaVisual) config;
    XMesaBuffer b;
@@ -1972,8 +1983,7 @@ glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
 
 
 PUBLIC GLXPbuffer
-glXCreatePbuffer( Display *dpy, GLXFBConfig config,
-                       const int *attribList )
+glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList)
 {
    XMesaVisual xmvis = (XMesaVisual) config;
    XMesaBuffer xmbuf;
@@ -2045,8 +2055,8 @@ glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
 
 
 PUBLIC void
-glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
-                       unsigned int *value )
+glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute,
+                 unsigned int *value)
 {
    GLuint width, height;
    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw);
@@ -2092,35 +2102,18 @@ glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
 
 PUBLIC GLXContext
 glXCreateNewContext( Display *dpy, GLXFBConfig config,
-                          int renderType, GLXContext shareList, Bool direct )
+                     int renderType, GLXContext shareCtx, Bool direct )
 {
-   GLXContext glxCtx;
-   GLXContext shareCtx = shareList;
    XMesaVisual xmvis = (XMesaVisual) config;
 
    if (!dpy || !config ||
        (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
       return 0;
 
-   glxCtx = CALLOC_STRUCT(__GLXcontextRec);
-   if (!glxCtx)
-      return 0;
-
-   /* deallocate unused windows/buffers */
-   XMesaGarbageCollect();
-
-   glxCtx->xmesaContext = XMesaCreateContext(xmvis,
-                                   shareCtx ? shareCtx->xmesaContext : NULL);
-   if (!glxCtx->xmesaContext) {
-      free(glxCtx);
-      return NULL;
-   }
-
-   glxCtx->isDirect = DEFAULT_DIRECT;
-   glxCtx->currentDpy = dpy;
-   glxCtx->xid = (XID) glxCtx;  /* self pointer */
-
-   return glxCtx;
+   return create_context(dpy, xmvis,
+                         shareCtx ? shareCtx->xmesaContext : NULL,
+                         direct,
+                         1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
 }
 
 
@@ -2163,8 +2156,7 @@ glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
 
 
 PUBLIC void
-glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
-                          unsigned long *mask )
+glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask)
 {
    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
    if (xmbuf)
@@ -2216,7 +2208,8 @@ glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
 /*** GLX_SGI_make_current_read ***/
 
 PUBLIC Bool
-glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
+glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read,
+                      GLXContext ctx)
 {
    return glXMakeContextCurrent( dpy, draw, read, ctx );
 }
@@ -2234,7 +2227,8 @@ glXGetCurrentReadDrawableSGI(void)
 #if defined(_VL_H)
 
 PUBLIC GLXVideoSourceSGIX
-glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode)
+glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server,
+                            VLPath path, int nodeClass, VLNode drainNode)
 {
    (void) dpy;
    (void) screen;
@@ -2280,7 +2274,8 @@ glXImportContextEXT(Display *dpy, GLXContextID contextID)
 }
 
 PUBLIC int
-glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value)
+glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,
+                       int *value)
 {
    (void) dpy;
    (void) context;
@@ -2294,20 +2289,24 @@ glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *val
 /*** GLX_SGIX_fbconfig ***/
 
 PUBLIC int
-glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
+glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config,
+                         int attribute, int *value)
 {
    return glXGetFBConfigAttrib(dpy, config, attribute, value);
 }
 
 PUBLIC GLXFBConfigSGIX *
-glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
+glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list,
+                      int *nelements)
 {
-   return (GLXFBConfig *) glXChooseFBConfig(dpy, screen, attrib_list, nelements);
+   return (GLXFBConfig *) glXChooseFBConfig(dpy, screen,
+                                            attrib_list, nelements);
 }
 
 
 PUBLIC GLXPixmap
-glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
+glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config,
+                                 Pixmap pixmap)
 {
    XMesaVisual xmvis = (XMesaVisual) config;
    XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0);
@@ -2316,31 +2315,20 @@ glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pi
 
 
 PUBLIC GLXContext
-glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
+glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config,
+                               int renderType, GLXContext shareCtx,
+                               Bool direct)
 {
    XMesaVisual xmvis = (XMesaVisual) config;
-   GLXContext glxCtx;
-   GLXContext shareCtx = share_list;
 
-   glxCtx = CALLOC_STRUCT(__GLXcontextRec);
-   if (!glxCtx)
+   if (!dpy || !config ||
+       (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
       return 0;
 
-   /* deallocate unused windows/buffers */
-   XMesaGarbageCollect();
-
-   glxCtx->xmesaContext = XMesaCreateContext(xmvis,
-                                   shareCtx ? shareCtx->xmesaContext : NULL);
-   if (!glxCtx->xmesaContext) {
-      free(glxCtx);
-      return NULL;
-   }
-
-   glxCtx->isDirect = DEFAULT_DIRECT;
-   glxCtx->currentDpy = dpy;
-   glxCtx->xid = (XID) glxCtx;  /* self pointer */
-
-   return glxCtx;
+   return create_context(dpy, xmvis,
+                         shareCtx ? shareCtx->xmesaContext : NULL,
+                         direct,
+                         1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
 }
 
 
@@ -2369,8 +2357,8 @@ glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
 
 PUBLIC GLXPbufferSGIX
 glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
-                             unsigned int width, unsigned int height,
-                             int *attribList)
+                        unsigned int width, unsigned int height,
+                        int *attribList)
 {
    XMesaVisual xmvis = (XMesaVisual) config;
    XMesaBuffer xmbuf;
@@ -2417,7 +2405,8 @@ glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
 
 
 PUBLIC int
-glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
+glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute,
+                       unsigned int *value)
 {
    const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
 
@@ -2461,7 +2450,8 @@ glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
 
 
 PUBLIC void
-glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
+glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable,
+                        unsigned long *mask)
 {
    XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
    if (xmbuf) {
@@ -2489,7 +2479,8 @@ glXCushionSGI(Display *dpy, Window win, float cushion)
 /*** GLX_SGIX_video_resize ***/
 
 PUBLIC int
-glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
+glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel,
+                           Window window)
 {
    (void) dpy;
    (void) screen;
@@ -2499,7 +2490,8 @@ glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window
 }
 
 PUBLIC int
-glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
+glXChannelRectSGIX(Display *dpy, int screen, int channel,
+                   int x, int y, int w, int h)
 {
    (void) dpy;
    (void) screen;
@@ -2512,7 +2504,8 @@ glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, i
 }
 
 PUBLIC int
-glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
+glXQueryChannelRectSGIX(Display *dpy, int screen, int channel,
+                        int *x, int *y, int *w, int *h)
 {
    (void) dpy;
    (void) screen;
@@ -2525,7 +2518,8 @@ glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, i
 }
 
 PUBLIC int
-glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
+glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel,
+                          int *dx, int *dy, int *dw, int *dh)
 {
    (void) dpy;
    (void) screen;
@@ -2553,7 +2547,8 @@ glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
 
 #if defined(_DM_BUFFER_H_)
 PUBLIC Bool
-glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
+glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer,
+                          DMparams *params, DMbuffer dmbuffer)
 {
    (void) dpy;
    (void) pbuffer;
@@ -2600,7 +2595,8 @@ glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
 /*** GLX_SUN_get_transparent_index ***/
 
 PUBLIC Status
-glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent)
+glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay,
+                          long *pTransparent)
 {
    (void) dpy;
    (void) overlay;
@@ -2646,3 +2642,98 @@ glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
    if (b)
       XMesaReleaseTexImage(dpy, b, buffer);
 }
+
+
+
+/*** GLX_ARB_create_context ***/
+
+GLXContext
+glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config,
+                           GLXContext shareCtx, Bool direct,
+                           const int *attrib_list)
+{
+   XMesaVisual xmvis = (XMesaVisual) config;
+   int majorVersion = 1, minorVersion = 0;
+   int contextFlags = 0x0;
+   int profileMask = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
+   int renderType = GLX_RGBA_TYPE;
+   unsigned i;
+   Bool done = False;
+   const int contextFlagsAll = (GLX_CONTEXT_DEBUG_BIT_ARB |
+                                GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB);
+
+   /* parse attrib_list */
+   for (i = 0; !done && attrib_list[i]; i++) {
+      switch (attrib_list[i]) {
+      case GLX_CONTEXT_MAJOR_VERSION_ARB:
+         majorVersion = attrib_list[++i];
+         break;
+      case GLX_CONTEXT_MINOR_VERSION_ARB:
+         minorVersion = attrib_list[++i];
+         break;
+      case GLX_CONTEXT_FLAGS_ARB:
+         contextFlags = attrib_list[++i];
+         break;
+      case GLX_CONTEXT_PROFILE_MASK_ARB:
+         profileMask = attrib_list[++i];
+         break;
+      case GLX_RENDER_TYPE:
+         renderType = attrib_list[++i];
+         break;
+      case 0:
+         /* end of list */
+         done = True;
+         break;
+      default:
+         /* bad attribute */
+         /* XXX generate BadValue X Error */
+         return NULL;
+      }
+   }
+
+   /* check contextFlags */
+   if (contextFlags & ~contextFlagsAll) {
+      return NULL; /* generate BadValue X Error */
+   }
+
+   /* check profileMask */
+   if (profileMask != GLX_CONTEXT_CORE_PROFILE_BIT_ARB &&
+       profileMask != GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) {
+      return NULL; /* generate BadValue X Error */
+   }
+
+   /* check version (generate BadMatch if bad) */
+   switch (majorVersion) {
+   case 1:
+      if (minorVersion < 0 || minorVersion > 5)
+         return NULL;
+      break;
+   case 2:
+      if (minorVersion < 0 || minorVersion > 1)
+         return NULL;
+      break;
+   case 3:
+      if (minorVersion < 0 || minorVersion > 2)
+         return NULL;
+      break;
+   case 4:
+      if (minorVersion < 0 || minorVersion > 0)
+         return NULL;
+      break;
+   default:
+      return NULL;
+   }
+
+   if ((contextFlags & GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) &&
+       majorVersion < 3)
+      return NULL; /* generate GLXBadProfileARB */
+
+   if (renderType == GLX_COLOR_INDEX_TYPE && majorVersion >= 3)
+      return NULL; /* generate BadMatch */
+
+   return create_context(dpy, xmvis,
+                         shareCtx ? shareCtx->xmesaContext : NULL,
+                         direct,
+                         majorVersion, minorVersion,
+                         profileMask, contextFlags);
+}