X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fx11%2Ffakeglx.c;h=1587df66bcd48f1ce8e8db76427d1cc30826326b;hb=a8ec5dac3c8c564b1c405798f7703e0d8e650f2d;hp=5a830dc0cc000a2264786fdd78e3552033019d64;hpb=69e3c8b323d5bbbc0b9a228f7dd0bffa3c5df6c8;p=mesa.git diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c index 5a830dc0cc0..1587df66bcd 100644 --- a/src/mesa/drivers/x11/fakeglx.c +++ b/src/mesa/drivers/x11/fakeglx.c @@ -1,10 +1,8 @@ -/* $Id: fakeglx.c,v 1.76 2002/11/14 16:14:56 brianp Exp $ */ - /* * Mesa 3-D graphics library - * Version: 5.1 + * Version: 7.1 * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -49,11 +47,14 @@ #include "config.h" #include "macros.h" #include "imports.h" -#include "mmath.h" #include "mtypes.h" +#include "version.h" #include "xfonts.h" #include "xmesaP.h" +#ifdef __VMS +#define _mesa_sprintf sprintf +#endif /* This indicates the client-side GLX API and GLX encoder version. */ #define CLIENT_MAJOR_VERSION 1 @@ -66,7 +67,7 @@ #define SERVER_MINOR_VERSION 4 /* This is appended onto the glXGetClient/ServerString version strings. */ -#define MESA_GLX_VERSION "Mesa 5.1" +#define MESA_GLX_VERSION "Mesa " MESA_VERSION_STRING /* Who implemented this GLX? */ #define VENDOR "Brian Paul" @@ -77,23 +78,12 @@ "GLX_MESA_pixmap_colormap " \ "GLX_MESA_release_buffers " \ "GLX_ARB_get_proc_address " \ + "GLX_EXT_texture_from_pixmap " \ "GLX_EXT_visual_info " \ "GLX_EXT_visual_rating " \ - "GLX_SGI_video_sync " \ + /*"GLX_SGI_video_sync "*/ \ "GLX_SGIX_fbconfig " \ - "GLX_SGIX_pbuffer" - - -/* Silence compiler warnings */ -extern void Fake_glXDummyFunc( void ); -void Fake_glXDummyFunc( void ) -{ - (void) kernel8; - (void) DitherValues; - (void) HPCR_DRGB; - (void) kernel1; -} - + "GLX_SGIX_pbuffer " /* * Our fake GLX context will contain a "real" GLX context and an XMesa context. @@ -119,8 +109,7 @@ struct fake_glx_context { #define DONT_CARE -1 -#define MAX_VISUALS 100 -static XMesaVisual VisualTable[MAX_VISUALS]; +static XMesaVisual *VisualTable = NULL; static int NumVisuals = 0; @@ -150,11 +139,11 @@ typedef struct _OverlayInfo { - /* * Test if the given XVisualInfo is usable for Mesa rendering. */ -static GLboolean is_usable_visual( XVisualInfo *vinfo ) +static GLboolean +is_usable_visual( XVisualInfo *vinfo ) { switch (vinfo->CLASS) { case StaticGray: @@ -182,25 +171,22 @@ static GLboolean is_usable_visual( XVisualInfo *vinfo ) -/* - * Return the level (overlay, normal, underlay) of a given XVisualInfo. - * Input: dpy - the X display - * vinfo - the XVisualInfo to test - * Return: level of the visual: - * 0 = normal planes - * >0 = overlay planes - * <0 = underlay planes +/** + * Get an array OverlayInfo records for specified screen. + * \param dpy the display + * \param screen screen number + * \param numOverlays returns numver of OverlayInfo records + * \return pointer to OverlayInfo array, free with XFree() */ -static int level_of_visual( Display *dpy, XVisualInfo *vinfo ) +static OverlayInfo * +GetOverlayInfo(Display *dpy, int screen, int *numOverlays) { Atom overlayVisualsAtom; - OverlayInfo *overlay_info = NULL; - int numOverlaysPerScreen; - Status status; Atom actualType; - int actualFormat; + Status status; + unsigned char *ovInfo; unsigned long sizeData, bytesLeft; - int i; + int actualFormat; /* * The SERVER_OVERLAY_VISUALS property on the root window contains @@ -211,25 +197,50 @@ static int level_of_visual( Display *dpy, XVisualInfo *vinfo ) return 0; } - status = XGetWindowProperty(dpy, RootWindow( dpy, vinfo->screen ), + status = XGetWindowProperty(dpy, RootWindow(dpy, screen), overlayVisualsAtom, 0L, (long) 10000, False, overlayVisualsAtom, &actualType, &actualFormat, &sizeData, &bytesLeft, - (unsigned char **) &overlay_info ); + &ovInfo); if (status != Success || actualType != overlayVisualsAtom || actualFormat != 32 || sizeData < 4) { /* something went wrong */ - XFree((void *) overlay_info); + XFree((void *) ovInfo); + *numOverlays = 0; + return NULL; + } + + *numOverlays = sizeData / 4; + return (OverlayInfo *) ovInfo; +} + + + +/** + * Return the level (overlay, normal, underlay) of a given XVisualInfo. + * Input: dpy - the X display + * vinfo - the XVisualInfo to test + * Return: level of the visual: + * 0 = normal planes + * >0 = overlay planes + * <0 = underlay planes + */ +static int +level_of_visual( Display *dpy, XVisualInfo *vinfo ) +{ + OverlayInfo *overlay_info; + int numOverlaysPerScreen, i; + + overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen); + if (!overlay_info) { return 0; } /* search the overlay visual list for the visual ID of interest */ - numOverlaysPerScreen = (int) (sizeData / 4); - for (i=0;ioverlay_visual==vinfo->visualid) { + for (i = 0; i < numOverlaysPerScreen; i++) { + const OverlayInfo *ov = overlay_info + i; + if (ov->overlay_visual == vinfo->visualid) { /* found the visual */ if (/*ov->transparent_type==1 &&*/ ov->layer!=0) { int level = ov->layer; @@ -262,7 +273,7 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo, GLint depth_size, GLint stencil_size, GLint accumRedSize, GLint accumGreenSize, GLint accumBlueSize, GLint accumAlphaSize, - GLint level ) + GLint level, GLint numAuxBuffers ) { GLboolean ximageFlag = GL_TRUE; XMesaVisual xmvis; @@ -292,11 +303,16 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo, else comparePointers = GL_FALSE; + /* Force the visual to have an alpha channel */ + if (rgbFlag && _mesa_getenv("MESA_GLX_FORCE_ALPHA")) + alphaFlag = GL_TRUE; + /* First check if a matching visual is already in the list */ for (i=0; idisplay == dpy - && v->level == level + && v->mesa_visual.level == level + && v->mesa_visual.numAuxBuffers == numAuxBuffers && v->ximage_flag == ximageFlag && v->mesa_visual.rgbMode == rgbFlag && v->mesa_visual.doubleBufferMode == dbFlag @@ -318,11 +334,6 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo, /* Create a new visual and add it to the list. */ - if (NumVisuals >= MAX_VISUALS) { - _mesa_problem(NULL, "GLX Error: maximum number of visuals exceeded"); - return NULL; - } - xmvis = XMesaCreateVisual( dpy, vinfo, rgbFlag, alphaFlag, dbFlag, stereoFlag, ximageFlag, depth_size, stencil_size, @@ -334,14 +345,59 @@ save_glx_visual( Display *dpy, XVisualInfo *vinfo, * if we need to search for it in find_glx_visual(). */ xmvis->vishandle = vinfo; + /* Allocate more space for additional visual */ + VisualTable = (XMesaVisual *) _mesa_realloc( VisualTable, + sizeof(XMesaVisual) * NumVisuals, + sizeof(XMesaVisual) * (NumVisuals + 1)); /* add xmvis to the list */ VisualTable[NumVisuals] = xmvis; NumVisuals++; + /* XXX minor hack, because XMesaCreateVisual doesn't support an + * aux buffers parameter. + */ + xmvis->mesa_visual.numAuxBuffers = numAuxBuffers; } return xmvis; } +/** + * Return the default number of bits for the Z buffer. + * If defined, use the MESA_GLX_DEPTH_BITS env var value. + * Otherwise, use the DEFAULT_SOFTWARE_DEPTH_BITS constant. + * XXX probably do the same thing for stencil, accum, etc. + */ +static GLint +default_depth_bits(void) +{ + int zBits; + const char *zEnv = _mesa_getenv("MESA_GLX_DEPTH_BITS"); + if (zEnv) + zBits = _mesa_atoi(zEnv); + else + zBits = DEFAULT_SOFTWARE_DEPTH_BITS; + return zBits; +} + +static GLint +default_alpha_bits(void) +{ + int aBits; + const char *aEnv = _mesa_getenv("MESA_GLX_ALPHA_BITS"); + if (aEnv) + aBits = _mesa_atoi(aEnv); + else + aBits = 0; + return aBits; +} + +static GLint +default_accum_bits(void) +{ + return 16; +} + + /* * Create a GLX visual from a regular XVisualInfo. @@ -355,6 +411,9 @@ static XMesaVisual create_glx_visual( Display *dpy, XVisualInfo *visinfo ) { int vislevel; + GLint zBits = default_depth_bits(); + GLint accBits = default_accum_bits(); + GLboolean alphaFlag = default_alpha_bits() > 0; vislevel = level_of_visual( dpy, visinfo ); if (vislevel) { @@ -367,7 +426,8 @@ create_glx_visual( Display *dpy, XVisualInfo *visinfo ) 0, /* depth bits */ 0, /* stencil bits */ 0,0,0,0, /* accum bits */ - vislevel /* level */ + vislevel, /* level */ + 0 /* numAux */ ); } else if (is_usable_visual( visinfo )) { @@ -378,13 +438,11 @@ create_glx_visual( Display *dpy, XVisualInfo *visinfo ) GL_FALSE, /* alpha */ GL_TRUE, /* double */ GL_FALSE, /* stereo */ - DEFAULT_SOFTWARE_DEPTH_BITS, - 8 * sizeof(GLstencil), - 0 * sizeof(GLaccum), /* r */ - 0 * sizeof(GLaccum), /* g */ - 0 * sizeof(GLaccum), /* b */ - 0 * sizeof(GLaccum), /* a */ - 0 /* level */ + zBits, + STENCIL_BITS, + 0, 0, 0, 0, /* accum bits */ + 0, /* level */ + 0 /* numAux */ ); } else { @@ -393,16 +451,17 @@ create_glx_visual( Display *dpy, XVisualInfo *visinfo ) /* can be done? They should use glXChooseVisual(). */ return save_glx_visual( dpy, visinfo, GL_TRUE, /* rgb */ - GL_FALSE, /* alpha */ + alphaFlag, /* alpha */ GL_TRUE, /* double */ GL_FALSE, /* stereo */ - DEFAULT_SOFTWARE_DEPTH_BITS, - 8 * sizeof(GLstencil), - 8 * sizeof(GLaccum), /* r */ - 8 * sizeof(GLaccum), /* g */ - 8 * sizeof(GLaccum), /* b */ - 8 * sizeof(GLaccum), /* a */ - 0 /* level */ + zBits, + STENCIL_BITS, + accBits, /* r */ + accBits, /* g */ + accBits, /* b */ + accBits, /* a */ + 0, /* level */ + 0 /* numAux */ ); } } @@ -442,54 +501,29 @@ find_glx_visual( Display *dpy, XVisualInfo *vinfo ) -/* +/** * Return the transparent pixel value for a GLX visual. * Input: glxvis - the glx_visual * Return: a pixel value or -1 if no transparent pixel */ -static int transparent_pixel( XMesaVisual glxvis ) +static int +transparent_pixel( XMesaVisual glxvis ) { Display *dpy = glxvis->display; XVisualInfo *vinfo = glxvis->visinfo; - Atom overlayVisualsAtom; - OverlayInfo *overlay_info = NULL; - int numOverlaysPerScreen; - Status status; - Atom actualType; - int actualFormat; - unsigned long sizeData, bytesLeft; - int i; - - /* - * The SERVER_OVERLAY_VISUALS property on the root window contains - * a list of overlay visuals. Get that list now. - */ - overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True); - if (overlayVisualsAtom == None) { - return -1; - } - - status = XGetWindowProperty(dpy, RootWindow( dpy, vinfo->screen ), - overlayVisualsAtom, 0L, (long) 10000, False, - overlayVisualsAtom, &actualType, &actualFormat, - &sizeData, &bytesLeft, - (unsigned char **) &overlay_info ); + OverlayInfo *overlay_info; + int numOverlaysPerScreen, i; - if (status != Success || actualType != overlayVisualsAtom || - actualFormat != 32 || sizeData < 4) { - /* something went wrong */ - XFree((void *) overlay_info); + overlay_info = GetOverlayInfo(dpy, vinfo->screen, &numOverlaysPerScreen); + if (!overlay_info) { return -1; } - /* search the overlay visual list for the visual ID of interest */ - numOverlaysPerScreen = (int) (sizeData / 4); - for (i=0;ioverlay_visual==vinfo->visualid) { + for (i = 0; i < numOverlaysPerScreen; i++) { + const OverlayInfo *ov = overlay_info + i; + if (ov->overlay_visual == vinfo->visualid) { /* found it! */ - if (ov->transparent_type==0) { + if (ov->transparent_type == 0) { /* type 0 indicates no transparency */ XFree((void *) overlay_info); return -1; @@ -509,11 +543,11 @@ static int transparent_pixel( XMesaVisual glxvis ) -/* +/** * Try to get an X visual which matches the given arguments. */ -static XVisualInfo *get_visual( Display *dpy, int scr, - unsigned int depth, int xclass ) +static XVisualInfo * +get_visual( Display *dpy, int scr, unsigned int depth, int xclass ) { XVisualInfo temp, *vis; long mask; @@ -566,7 +600,8 @@ static XVisualInfo *get_visual( Display *dpy, int scr, * varname - the name of the environment variable * Return: an XVisualInfo pointer to NULL if error. */ -static XVisualInfo *get_env_visual(Display *dpy, int scr, const char *varname) +static XVisualInfo * +get_env_visual(Display *dpy, int scr, const char *varname) { char value[100], type[100]; int depth, xclass = -1; @@ -611,9 +646,9 @@ static XVisualInfo *get_env_visual(Display *dpy, int scr, const char *varname) * preferred_class - preferred GLX visual class or DONT_CARE * Return: pointer to an XVisualInfo or NULL. */ -static XVisualInfo *choose_x_visual( Display *dpy, int screen, - GLboolean rgba, int min_depth, - int preferred_class ) +static XVisualInfo * +choose_x_visual( Display *dpy, int screen, GLboolean rgba, int min_depth, + int preferred_class ) { XVisualInfo *vis; int xclass, visclass = 0; @@ -781,20 +816,13 @@ static XVisualInfo *choose_x_visual( Display *dpy, int screen, * preferred_class - preferred GLX visual class or DONT_CARE * Return: pointer to an XVisualInfo or NULL. */ -static XVisualInfo *choose_x_overlay_visual( Display *dpy, int scr, - GLboolean rgbFlag, - int level, int trans_type, - int trans_value, - int min_depth, - int preferred_class ) +static XVisualInfo * +choose_x_overlay_visual( Display *dpy, int scr, GLboolean rgbFlag, + int level, int trans_type, int trans_value, + int min_depth, int preferred_class ) { - Atom overlayVisualsAtom; OverlayInfo *overlay_info; int numOverlaysPerScreen; - Status status; - Atom actualType; - int actualFormat; - unsigned long sizeData, bytesLeft; int i; XVisualInfo *deepvis; int deepest; @@ -811,24 +839,8 @@ static XVisualInfo *choose_x_overlay_visual( Display *dpy, int scr, default: preferred_class = DONT_CARE; } - /* - * The SERVER_OVERLAY_VISUALS property on the root window contains - * a list of overlay visuals. Get that list now. - */ - overlayVisualsAtom = XInternAtom(dpy,"SERVER_OVERLAY_VISUALS", True); - if (overlayVisualsAtom == (Atom) None) { - return NULL; - } - - status = XGetWindowProperty(dpy, RootWindow( dpy, scr ), - overlayVisualsAtom, 0L, (long) 10000, False, - overlayVisualsAtom, &actualType, &actualFormat, - &sizeData, &bytesLeft, - (unsigned char **) &overlay_info ); - - if (status != Success || actualType != overlayVisualsAtom || - actualFormat != 32 || sizeData < 4) { - /* something went wrong */ + overlay_info = GetOverlayInfo(dpy, scr, &numOverlaysPerScreen); + if (!overlay_info) { return NULL; } @@ -836,12 +848,10 @@ static XVisualInfo *choose_x_overlay_visual( Display *dpy, int scr, deepest = min_depth; deepvis = NULL; - numOverlaysPerScreen = (int) (sizeData / 4); - for (i=0;ilayer!=level) { /* failed overlay level criteria */ @@ -906,18 +916,101 @@ static XVisualInfo *choose_x_overlay_visual( Display *dpy, int scr, } +/**********************************************************************/ +/*** Display-related functions ***/ +/**********************************************************************/ + + +/** + * Free all XMesaVisuals which are associated with the given display. + */ +static void +destroy_visuals_on_display(Display *dpy) +{ + int i; + for (i = 0; i < NumVisuals; i++) { + if (VisualTable[i]->display == dpy) { + /* remove this visual */ + int j; + free(VisualTable[i]); + for (j = i; j < NumVisuals - 1; j++) + VisualTable[j] = VisualTable[j + 1]; + NumVisuals--; + } + } +} + + +/** + * Called from XCloseDisplay() to let us free our display-related data. + */ +static int +close_display_callback(Display *dpy, XExtCodes *codes) +{ + destroy_visuals_on_display(dpy); + xmesa_destroy_buffers_on_display(dpy); + return 0; +} + + +/** + * Look for the named extension on given display and return a pointer + * to the _XExtension data, or NULL if extension not found. + */ +static _XExtension * +lookup_extension(Display *dpy, const char *extName) +{ + _XExtension *ext; + for (ext = dpy->ext_procs; ext; ext = ext->next) { + if (ext->name && strcmp(ext->name, extName) == 0) { + return ext; + } + } + return NULL; +} + + +/** + * Whenever we're given a new Display pointer, call this function to + * register our close_display_callback function. + */ +static void +register_with_display(Display *dpy) +{ + const char *extName = "MesaGLX"; + _XExtension *ext; + + ext = lookup_extension(dpy, extName); + if (!ext) { + XExtCodes *c = XAddExtension(dpy); + ext = dpy->ext_procs; /* new extension is at head of list */ + assert(c->extension == ext->codes.extension); + ext->name = _mesa_strdup(extName); + ext->close_display = close_display_callback; + } +} + + /**********************************************************************/ /*** Begin Fake GLX API Functions ***/ /**********************************************************************/ -static XMesaVisual choose_visual( Display *dpy, int screen, const int *list ) +/** + * Helper used by glXChooseVisual and glXChooseFBConfig. + * The fbConfig parameter must be GL_FALSE for the former and GL_TRUE for + * the later. + * In either case, the attribute list is terminated with the value 'None'. + */ +static XMesaVisual +choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) { + const GLboolean rgbModeDefault = fbConfig; const int *parselist; XVisualInfo *vis; int min_ci = 0; int min_red=0, min_green=0, min_blue=0; - GLboolean rgb_flag = GL_FALSE; + GLboolean rgb_flag = rgbModeDefault; GLboolean alpha_flag = GL_FALSE; GLboolean double_flag = GL_FALSE; GLboolean stereo_flag = GL_FALSE; @@ -933,6 +1026,8 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list ) int trans_value = DONT_CARE; GLint caveat = DONT_CARE; XMesaVisual xmvis = NULL; + int desiredVisualID = -1; + int numAux = 0; parselist = list; @@ -940,8 +1035,14 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list ) switch (*parselist) { case GLX_USE_GL: - /* ignore */ - parselist++; + if (fbConfig) { + /* invalid token */ + return NULL; + } + else { + /* skip */ + parselist++; + } break; case GLX_BUFFER_SIZE: parselist++; @@ -952,20 +1053,38 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list ) level = *parselist++; break; case GLX_RGBA: - rgb_flag = GL_TRUE; - parselist++; + if (fbConfig) { + /* invalid token */ + return NULL; + } + else { + rgb_flag = GL_TRUE; + parselist++; + } break; case GLX_DOUBLEBUFFER: - double_flag = GL_TRUE; - parselist++; + parselist++; + if (fbConfig) { + double_flag = *parselist++; + } + else { + double_flag = GL_TRUE; + } break; case GLX_STEREO: - stereo_flag = GL_TRUE; - return NULL; + parselist++; + if (fbConfig) { + stereo_flag = *parselist++; + } + else { + stereo_flag = GL_TRUE; + } + return NULL; /* stereo not supported */ case GLX_AUX_BUFFERS: - /* ignore */ - parselist++; parselist++; + numAux = *parselist++; + if (numAux > MAX_AUX_BUFFERS) + return NULL; break; case GLX_RED_SIZE: parselist++; @@ -983,7 +1102,7 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list ) parselist++; { GLint size = *parselist++; - alpha_flag = size>0 ? 1 : 0; + alpha_flag = size ? GL_TRUE : GL_FALSE; } break; case GLX_DEPTH_SIZE: @@ -1069,6 +1188,8 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list ) * FBConfig attribs. */ case GLX_RENDER_TYPE: + if (!fbConfig) + return NULL; parselist++; if (*parselist == GLX_RGBA_BIT) { rgb_flag = GL_TRUE; @@ -1082,14 +1203,53 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list ) parselist++; break; case GLX_DRAWABLE_TYPE: + if (!fbConfig) + return NULL; parselist++; if (*parselist & ~(GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT)) { return NULL; /* bad bit */ } parselist++; break; + case GLX_FBCONFIG_ID: + if (!fbConfig) + return NULL; + parselist++; + desiredVisualID = *parselist++; + break; + case GLX_X_RENDERABLE: + if (!fbConfig) + return NULL; + parselist += 2; + /* ignore */ + break; + +#ifdef GLX_EXT_texture_from_pixmap + case GLX_BIND_TO_TEXTURE_RGB_EXT: + parselist++; /*skip*/ + break; + case GLX_BIND_TO_TEXTURE_RGBA_EXT: + parselist++; /*skip*/ + break; + case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: + parselist++; /*skip*/ + break; + case GLX_BIND_TO_TEXTURE_TARGETS_EXT: + parselist++; + if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT | + GLX_TEXTURE_2D_BIT_EXT | + GLX_TEXTURE_RECTANGLE_BIT_EXT)) { + /* invalid bit */ + return NULL; + } + break; + case GLX_Y_INVERTED_EXT: + parselist++; /*skip*/ + break; +#endif case None: + /* end of list */ break; default: @@ -1100,6 +1260,8 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list ) } } + (void) caveat; + /* * Since we're only simulating the GLX extension this function will never * find any real GL visuals. Instead, all we can do is try to find an RGB @@ -1107,7 +1269,24 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list ) * double buffering, depth buffer, etc. will be associated with the X * visual and stored in the VisualTable[]. */ - if (level==0) { + if (desiredVisualID != -1) { + /* try to get a specific visual, by visualID */ + XVisualInfo temp; + int n; + temp.visualid = desiredVisualID; + temp.screen = screen; + vis = XGetVisualInfo(dpy, VisualIDMask | VisualScreenMask, &temp, &n); + if (vis) { + /* give the visual some useful GLX attributes */ + double_flag = GL_TRUE; + if (vis->depth > 8) + rgb_flag = GL_TRUE; + depth_size = default_depth_bits(); + stencil_size = STENCIL_BITS; + /* XXX accum??? */ + } + } + else if (level==0) { /* normal color planes */ if (rgb_flag) { /* Get an RGB visual */ @@ -1150,27 +1329,32 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list ) * return 16 to maintain performance with earlier versions of Mesa. */ if (depth_size > 24) - depth_size = 31; /* 32 causes int overflow problems */ + depth_size = 32; else if (depth_size > 16) depth_size = 24; - else if (depth_size > 0) - depth_size = DEFAULT_SOFTWARE_DEPTH_BITS; /*16*/ + else if (depth_size > 0) { + depth_size = default_depth_bits(); + } + + if (!alpha_flag) { + alpha_flag = default_alpha_bits() > 0; + } /* we only support one size of stencil and accum buffers. */ if (stencil_size > 0) stencil_size = STENCIL_BITS; if (accumRedSize > 0 || accumGreenSize > 0 || accumBlueSize > 0 || accumAlphaSize > 0) { - accumRedSize = ACCUM_BITS; - accumGreenSize = ACCUM_BITS; - accumBlueSize = ACCUM_BITS; - accumAlphaSize = alpha_flag ? ACCUM_BITS : 0; + accumRedSize = + accumGreenSize = + accumBlueSize = default_accum_bits(); + accumAlphaSize = alpha_flag ? accumRedSize : 0; } xmvis = save_glx_visual( dpy, vis, rgb_flag, alpha_flag, double_flag, stereo_flag, depth_size, stencil_size, accumRedSize, accumGreenSize, - accumBlueSize, accumAlphaSize, level ); + accumBlueSize, accumAlphaSize, level, numAux ); } return xmvis; @@ -1180,13 +1364,18 @@ static XMesaVisual choose_visual( Display *dpy, int screen, const int *list ) static XVisualInfo * Fake_glXChooseVisual( Display *dpy, int screen, int *list ) { - XMesaVisual xmvis = choose_visual(dpy, screen, list); + XMesaVisual xmvis; + + /* register ourselves as an extension on this display */ + register_with_display(dpy); + + xmvis = choose_visual(dpy, screen, list, GL_FALSE); if (xmvis) { #if 0 return xmvis->vishandle; #else /* create a new vishandle - the cached one may be stale */ - xmvis->vishandle = _mesa_malloc(sizeof(XVisualInfo)); + xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo)); if (xmvis->vishandle) { _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo)); } @@ -1214,7 +1403,9 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, return 0; /* deallocate unused windows/buffers */ +#if 0 XMesaGarbageCollect(); +#endif xmvis = find_glx_visual( dpy, visinfo ); if (!xmvis) { @@ -1222,7 +1413,7 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, xmvis = create_glx_visual( dpy, visinfo ); if (!xmvis) { /* unusable visual */ - FREE(glxCtx); + _mesa_free(glxCtx); return NULL; } } @@ -1230,7 +1421,7 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, glxCtx->xmesaContext = XMesaCreateContext(xmvis, shareCtx ? shareCtx->xmesaContext : NULL); if (!glxCtx->xmesaContext) { - FREE(glxCtx); + _mesa_free(glxCtx); return NULL; } @@ -1274,11 +1465,14 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, } if (!drawBuffer) { /* drawable must be a new window! */ - drawBuffer = XMesaCreateWindowBuffer2( xmctx->xm_visual, draw, xmctx); + drawBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, draw ); if (!drawBuffer) { /* Out of memory, or context/drawable depth mismatch */ return False; } +#ifdef FX + FXcreateContext( xmctx->xm_visual, draw, xmctx, drawBuffer ); +#endif } /* Find the XMesaBuffer which corresponds to the GLXDrawable 'read' */ @@ -1291,12 +1485,14 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, } if (!readBuffer) { /* drawable must be a new window! */ - readBuffer = XMesaCreateWindowBuffer2(glxCtx->xmesaContext->xm_visual, - read, xmctx); + readBuffer = XMesaCreateWindowBuffer( xmctx->xm_visual, read ); if (!readBuffer) { /* Out of memory, or context/drawable depth mismatch */ return False; } +#ifdef FX + FXcreateContext( xmctx->xm_visual, read, xmctx, readBuffer ); +#endif } MakeCurrent_PrevContext = ctx; @@ -1309,11 +1505,7 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) { ((__GLXcontext *) ctx)->currentDpy = dpy; ((__GLXcontext *) ctx)->currentDrawable = draw; -#ifndef GLX_BUILT_IN_XMESA ((__GLXcontext *) ctx)->currentReadable = read; -#else - __glXSetCurrentContext(ctx); -#endif return True; } else { @@ -1328,9 +1520,6 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, MakeCurrent_PrevReadable = 0; MakeCurrent_PrevDrawBuffer = 0; MakeCurrent_PrevReadBuffer = 0; -#ifdef GLX_BUILT_IN_XMESA - /* XXX bind dummy context with __glXSetCurrentContext(ctx); */ -#endif return True; } else { @@ -1342,7 +1531,6 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw, } - static Bool Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ) { @@ -1350,7 +1538,6 @@ Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx ) } - static GLXPixmap Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap ) { @@ -1370,7 +1557,7 @@ Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap ) if (!b) { return 0; } - return b->frontbuffer; + return b->frontxrb->pixmap; } @@ -1396,7 +1583,7 @@ Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo, if (!b) { return 0; } - return b->frontbuffer; + return b->frontxrb->pixmap; } @@ -1413,7 +1600,6 @@ Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap ) } - static void Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, unsigned long mask ) @@ -1423,11 +1609,13 @@ Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst, XMesaContext xm_src = fakeSrc->xmesaContext; XMesaContext xm_dst = fakeDst->xmesaContext; (void) dpy; - _mesa_copy_context( xm_src->gl_ctx, xm_dst->gl_ctx, (GLuint) mask ); + if (MakeCurrent_PrevContext == src) { + _mesa_Flush(); + } + _mesa_copy_context( &(xm_src->mesa), &(xm_dst->mesa), (GLuint) mask ); } - static Bool Fake_glXQueryExtension( Display *dpy, int *errorb, int *event ) { @@ -1459,10 +1647,10 @@ Fake_glXDestroyContext( Display *dpy, GLXContext ctx ) MakeCurrent_PrevReadBuffer = 0; XMesaDestroyContext( glxCtx->xmesaContext ); XMesaGarbageCollect(); + _mesa_free(glxCtx); } - static Bool Fake_glXIsDirect( Display *dpy, GLXContext ctx ) { @@ -1482,7 +1670,8 @@ Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable ) XMesaSwapBuffers(buffer); } else if (_mesa_getenv("MESA_DEBUG")) { - _mesa_warning(NULL, "Mesa: glXSwapBuffers: invalid drawable\n"); + _mesa_warning(NULL, "glXSwapBuffers: invalid drawable 0x%x\n", + (int) drawable); } } @@ -1504,7 +1693,6 @@ Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, } - static Bool Fake_glXQueryVersion( Display *dpy, int *maj, int *min ) { @@ -1517,7 +1705,6 @@ Fake_glXQueryVersion( Display *dpy, int *maj, int *min ) } - /* * Query the GLX attributes of the given XVisualInfo. */ @@ -1527,15 +1714,19 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) ASSERT(xmvis); switch(attrib) { case GLX_USE_GL: + if (fbconfig) + return GLX_BAD_ATTRIBUTE; *value = (int) True; return 0; case GLX_BUFFER_SIZE: *value = xmvis->visinfo->depth; return 0; case GLX_LEVEL: - *value = xmvis->level; + *value = xmvis->mesa_visual.level; return 0; case GLX_RGBA: + if (fbconfig) + return GLX_BAD_ATTRIBUTE; if (xmvis->mesa_visual.rgbMode) { *value = True; } @@ -1550,7 +1741,7 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) *value = (int) xmvis->mesa_visual.stereoMode; return 0; case GLX_AUX_BUFFERS: - *value = (int) False; + *value = xmvis->mesa_visual.numAuxBuffers; return 0; case GLX_RED_SIZE: *value = xmvis->mesa_visual.redBits; @@ -1597,11 +1788,11 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) } return 0; case GLX_TRANSPARENT_TYPE_EXT: - if (xmvis->level==0) { + if (xmvis->mesa_visual.level==0) { /* normal planes */ *value = GLX_NONE_EXT; } - else if (xmvis->level>0) { + else if (xmvis->mesa_visual.level>0) { /* overlay */ if (xmvis->mesa_visual.rgbMode) { *value = GLX_TRANSPARENT_RGB_EXT; @@ -1610,7 +1801,7 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) *value = GLX_TRANSPARENT_INDEX_EXT; } } - else if (xmvis->level<0) { + else if (xmvis->mesa_visual.level<0) { /* underlay */ *value = GLX_NONE_EXT; } @@ -1642,8 +1833,8 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) */ case GLX_VISUAL_CAVEAT_EXT: /* test for zero, just in case */ - if (xmvis->VisualCaveat > 0) - *value = xmvis->VisualCaveat; + if (xmvis->mesa_visual.visualRating > 0) + *value = xmvis->mesa_visual.visualRating; else *value = GLX_NONE_EXT; return 0; @@ -1712,6 +1903,27 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) *value = xmvis->visinfo->visualid; break; +#ifdef GLX_EXT_texture_from_pixmap + case GLX_BIND_TO_TEXTURE_RGB_EXT: + *value = True; /*XXX*/ + break; + case GLX_BIND_TO_TEXTURE_RGBA_EXT: + /* XXX review */ + *value = xmvis->mesa_visual.alphaBits > 0 ? True : False; + break; + case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: + *value = True; /*XXX*/ + break; + case GLX_BIND_TO_TEXTURE_TARGETS_EXT: + *value = (GLX_TEXTURE_1D_BIT_EXT | + GLX_TEXTURE_2D_BIT_EXT | + GLX_TEXTURE_RECTANGLE_BIT_EXT); /*XXX*/ + break; + case GLX_Y_INVERTED_EXT: + *value = True; /*XXX*/ + break; +#endif + default: return GLX_BAD_ATTRIBUTE; } @@ -1724,6 +1936,9 @@ Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo, int attrib, int *value ) { XMesaVisual xmvis; + int k; + if (!dpy || !visinfo) + return GLX_BAD_ATTRIBUTE; xmvis = find_glx_visual( dpy, visinfo ); if (!xmvis) { @@ -1741,7 +1956,8 @@ Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo, } } - return get_config(xmvis, attrib, value, GL_FALSE); + k = get_config(xmvis, attrib, value, GL_FALSE); + return k; } @@ -1841,28 +2057,6 @@ Fake_glXGetClientString( Display *dpy, int name ) */ -static GLXFBConfig * -Fake_glXChooseFBConfig( Display *dpy, int screen, - const int *attribList, int *nitems ) -{ - XMesaVisual xmvis = choose_visual(dpy, screen, attribList); - if (xmvis) { - GLXFBConfig *config = _mesa_malloc(sizeof(XMesaVisual)); - if (!config) { - *nitems = 0; - return NULL; - } - *nitems = 1; - config[0] = (GLXFBConfig) xmvis; - return (GLXFBConfig *) config; - } - else { - *nitems = 0; - return NULL; - } -} - - static int Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, int attribute, int *value ) @@ -1890,7 +2084,7 @@ Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements ) visuals = XGetVisualInfo(dpy, visMask, &visTemplate, nelements); if (*nelements > 0) { XMesaVisual *results; - results = _mesa_malloc(*nelements * sizeof(XMesaVisual)); + results = (XMesaVisual *) _mesa_malloc(*nelements * sizeof(XMesaVisual)); if (!results) { *nelements = 0; return NULL; @@ -1904,6 +2098,35 @@ Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements ) } +static GLXFBConfig * +Fake_glXChooseFBConfig( Display *dpy, int screen, + const int *attribList, int *nitems ) +{ + XMesaVisual xmvis; + + if (!attribList || !attribList[0]) { + /* return list of all configs (per GLX_SGIX_fbconfig spec) */ + return Fake_glXGetFBConfigs(dpy, screen, nitems); + } + + xmvis = choose_visual(dpy, screen, attribList, GL_TRUE); + if (xmvis) { + GLXFBConfig *config = (GLXFBConfig *) _mesa_malloc(sizeof(XMesaVisual)); + if (!config) { + *nitems = 0; + return NULL; + } + *nitems = 1; + config[0] = (GLXFBConfig) xmvis; + return (GLXFBConfig *) config; + } + else { + *nitems = 0; + return NULL; + } +} + + static XVisualInfo * Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) { @@ -1913,7 +2136,7 @@ Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) return xmvis->vishandle; #else /* create a new vishandle - the cached one may be stale */ - xmvis->vishandle = _mesa_malloc(sizeof(XVisualInfo)); + xmvis->vishandle = (XVisualInfo *) _mesa_malloc(sizeof(XVisualInfo)); if (xmvis->vishandle) { _mesa_memcpy(xmvis->vishandle, xmvis->visinfo, sizeof(XVisualInfo)); } @@ -1930,9 +2153,21 @@ static GLXWindow Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, const int *attribList ) { + XMesaVisual xmvis = (XMesaVisual) config; + XMesaBuffer xmbuf; + if (!xmvis) + return 0; + + xmbuf = XMesaCreateWindowBuffer(xmvis, win); + if (!xmbuf) + return 0; + +#ifdef FX + /* XXX this will segfault if actually called */ + FXcreateContext(xmvis, win, NULL, xmbuf); +#endif + (void) dpy; - (void) config; - (void) win; (void) attribList; /* Ignored in GLX 1.3 */ return win; /* A hack for now */ @@ -1956,16 +2191,102 @@ Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, { XMesaVisual v = (XMesaVisual) config; XMesaBuffer b; - - (void) dpy; - (void) config; - (void) pixmap; - (void) attribList; /* Ignored in GLX 1.3 */ + const int *attr; + int target = 0, format = 0, mipmap = 0; + int value; if (!dpy || !config || !pixmap) return 0; - b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); + for (attr = attribList; *attr; attr++) { + switch (*attr) { + case GLX_TEXTURE_FORMAT_EXT: + attr++; + switch (*attr) { + case GLX_TEXTURE_FORMAT_NONE_EXT: + case GLX_TEXTURE_FORMAT_RGB_EXT: + case GLX_TEXTURE_FORMAT_RGBA_EXT: + format = *attr; + break; + default: + /* error */ + return 0; + } + break; + case GLX_TEXTURE_TARGET_EXT: + attr++; + switch (*attr) { + case GLX_TEXTURE_1D_EXT: + case GLX_TEXTURE_2D_EXT: + case GLX_TEXTURE_RECTANGLE_EXT: + target = *attr; + break; + default: + /* error */ + return 0; + } + break; + case GLX_MIPMAP_TEXTURE_EXT: + attr++; + if (*attr) + mipmap = 1; + break; + default: + /* error */ + return 0; + } + } + + if (format == GLX_TEXTURE_FORMAT_RGB_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_RGB_EXT, + &value, GL_TRUE) != Success + || !value) { + return 0; /* error! */ + } + } + else if (format == GLX_TEXTURE_FORMAT_RGBA_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_RGBA_EXT, + &value, GL_TRUE) != Success + || !value) { + return 0; /* error! */ + } + } + if (mipmap) { + if (get_config(v, GLX_BIND_TO_MIPMAP_TEXTURE_EXT, + &value, GL_TRUE) != Success + || !value) { + return 0; /* error! */ + } + } + if (target == GLX_TEXTURE_1D_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, + &value, GL_TRUE) != Success + || (value & GLX_TEXTURE_1D_BIT_EXT) == 0) { + return 0; /* error! */ + } + } + else if (target == GLX_TEXTURE_2D_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, + &value, GL_TRUE) != Success + || (value & GLX_TEXTURE_2D_BIT_EXT) == 0) { + return 0; /* error! */ + } + } + if (target == GLX_TEXTURE_RECTANGLE_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, + &value, GL_TRUE) != Success + || (value & GLX_TEXTURE_RECTANGLE_BIT_EXT) == 0) { + return 0; /* error! */ + } + } + + if (format || target || mipmap) { + /* texture from pixmap */ + b = XMesaCreatePixmapTextureBuffer(v, pixmap, 0, format, target, mipmap); + } + else { + b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); + } if (!b) { return 0; } @@ -2019,6 +2340,10 @@ Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config, } } + /* not used at this time */ + (void) useLargest; + (void) preserveContents; + if (width == 0 || height == 0) return 0; @@ -2026,7 +2351,10 @@ Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config, /* A GLXPbuffer handle must be an X Drawable because that's what * glXMakeCurrent takes. */ - return (GLXPbuffer) xmbuf->frontbuffer; + if (xmbuf) + return (GLXPbuffer) xmbuf->frontxrb->pixmap; + else + return 0; } @@ -2050,22 +2378,34 @@ Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, switch (attribute) { case GLX_WIDTH: - *value = xmbuf->width; + *value = xmbuf->mesa_buffer.Width; break; case GLX_HEIGHT: - *value = xmbuf->height; + *value = xmbuf->mesa_buffer.Height; break; case GLX_PRESERVED_CONTENTS: *value = True; break; case GLX_LARGEST_PBUFFER: - *value = xmbuf->width * xmbuf->height; + *value = xmbuf->mesa_buffer.Width * xmbuf->mesa_buffer.Height; break; case GLX_FBCONFIG_ID: *value = xmbuf->xm_visual->visinfo->visualid; return; +#ifdef GLX_EXT_texture_from_pixmap + case GLX_TEXTURE_FORMAT_EXT: + *value = xmbuf->TextureFormat; + break; + case GLX_TEXTURE_TARGET_EXT: + *value = xmbuf->TextureTarget; + break; + case GLX_MIPMAP_TEXTURE_EXT: + *value = xmbuf->TextureMipmap; + break; +#endif + default: - return; /* GLX_BAD_ATTRIBUTE? */ + return; /* raise BadValue error */ } } @@ -2092,7 +2432,7 @@ Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config, glxCtx->xmesaContext = XMesaCreateContext(xmvis, shareCtx ? shareCtx->xmesaContext : NULL); if (!glxCtx->xmesaContext) { - FREE(glxCtx); + _mesa_free(glxCtx); return NULL; } @@ -2171,19 +2511,26 @@ Fake_glXSwapIntervalSGI(int interval) /*** GLX_SGI_video_sync ***/ +static unsigned int FrameCounter = 0; + static int Fake_glXGetVideoSyncSGI(unsigned int *count) { - (void) count; + /* this is a bogus implementation */ + *count = FrameCounter++; return 0; } static int Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) { - (void) divisor; - (void) remainder; - (void) count; + if (divisor <= 0 || remainder < 0) + return GLX_BAD_VALUE; + /* this is a bogus implementation */ + FrameCounter++; + while (FrameCounter % divisor != remainder) + FrameCounter++; + *count = FrameCounter; return 0; } @@ -2287,7 +2634,7 @@ Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixm { XMesaVisual xmvis = (XMesaVisual) config; XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0); - return xmbuf->frontbuffer; /* need to return an X ID */ + return xmbuf->frontxrb->pixmap; /* need to return an X ID */ } @@ -2308,7 +2655,7 @@ Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int re glxCtx->xmesaContext = XMesaCreateContext(xmvis, shareCtx ? shareCtx->xmesaContext : NULL); if (!glxCtx->xmesaContext) { - FREE(glxCtx); + _mesa_free(glxCtx); return NULL; } @@ -2358,7 +2705,7 @@ Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, (void) dpy; - for (attrib = attribList; *attrib; attrib++) { + for (attrib = attribList; attrib && *attrib; attrib++) { switch (*attrib) { case GLX_PRESERVED_CONTENTS_SGIX: attrib++; @@ -2373,11 +2720,15 @@ Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, } } + /* not used at this time */ + (void) useLargest; + (void) preserveContents; + xmbuf = XMesaCreatePBuffer( xmvis, 0, width, height); /* A GLXPbuffer handle must be an X Drawable because that's what * glXMakeCurrent takes. */ - return (GLXPbuffer) xmbuf->frontbuffer; + return (GLXPbuffer) xmbuf->frontxrb->pixmap; } @@ -2406,13 +2757,13 @@ Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, un *value = True; break; case GLX_LARGEST_PBUFFER_SGIX: - *value = xmbuf->width * xmbuf->height; + *value = xmbuf->mesa_buffer.Width * xmbuf->mesa_buffer.Height; break; case GLX_WIDTH_SGIX: - *value = xmbuf->width; + *value = xmbuf->mesa_buffer.Width; break; case GLX_HEIGHT_SGIX: - *value = xmbuf->height; + *value = xmbuf->mesa_buffer.Height; break; case GLX_EVENT_MASK_SGIX: *value = 0; /* XXX might be wrong */ @@ -2615,7 +2966,7 @@ Fake_glXSet3DfxModeMESA( int mode ) -/*** AGP memory allocation ***/ +/*** GLX_NV_vertex_array range ***/ static void * Fake_glXAllocateMemoryNV( GLsizei size, GLfloat readFrequency, @@ -2637,9 +2988,49 @@ Fake_glXFreeMemoryNV( GLvoid *pointer ) } +/*** GLX_MESA_agp_offset ***/ +static GLuint +Fake_glXGetAGPOffsetMESA( const GLvoid *pointer ) +{ + (void) pointer; + return ~0; +} + + +/*** GLX_EXT_texture_from_pixmap ***/ + +static void +Fake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, + const int *attrib_list) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, drawable); + if (b) + XMesaBindTexImage(dpy, b, buffer, attrib_list); +} + +static void +Fake_glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, drawable); + if (b) + XMesaReleaseTexImage(dpy, b, buffer); +} + + +/* silence warning */ extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); -struct _glxapi_table *_mesa_GetGLXDispatchTable(void) + + +/** + * Create a new GLX API dispatch table with its function pointers + * initialized to point to Mesa's "fake" GLX API functions. + * Note: there's a similar function (_real_GetGLXDispatchTable) that + * returns a new dispatch table with all pointers initalized to point + * to "real" GLX functions (which understand GLX wire protocol, etc). + */ +struct _glxapi_table * +_mesa_GetGLXDispatchTable(void) { static struct _glxapi_table glx; @@ -2775,9 +3166,16 @@ struct _glxapi_table *_mesa_GetGLXDispatchTable(void) /*** GLX_MESA_set_3dfx_mode ***/ glx.Set3DfxModeMESA = Fake_glXSet3DfxModeMESA; - /*** GLX AGP memory allocation ***/ + /*** GLX_NV_vertex_array_range ***/ glx.AllocateMemoryNV = Fake_glXAllocateMemoryNV; glx.FreeMemoryNV = Fake_glXFreeMemoryNV; + /*** GLX_MESA_agp_offset ***/ + glx.GetAGPOffsetMESA = Fake_glXGetAGPOffsetMESA; + + /*** GLX_EXT_texture_from_pixmap ***/ + glx.BindTexImageEXT = Fake_glXBindTexImageEXT; + glx.ReleaseTexImageEXT = Fake_glXReleaseTexImageEXT; + return &glx; }