Here's the latest version of my GLX changes. It includes all the stuff that was in the last version, but all of the client-side support is in place for GLX_SGI_make_current_read. The interesting thing is that, because of the way I refectored glXMakeCurrent, glXMakeCurrentReadSGI, and glXMakeContextCurrent, there's not very much more code in glxext.c (only about 55 lines).
I also fixed a problem with the GLX extension string when the rendering screen was not direct capable (i.e., a remote display).
The problem with HP_occlusion_test persists. :(
I don't plan to do anything else with these changes until *after* I return from vacation. I'll be back on the 23rd of June. I will be around for the #dri-devel chat on the 9th, however.
Please use that week as an opportunity to put the patch through its paces. I know there are few code paths that aren't fully tested. I'd like to commit the patch sometime shortly after I return.
This is my final patch before I leave for vacation. It includes *all* of the client-side support for SGI_make_current_read. The only driver that is updated in this patch is mga. If the attached patch to glxgears is used, SGI_make_current_read is used (even if it's not exported).
I won't be answering any e-mail until after the 23rd of June as I will be on vacation. If anything, please update some of the other drivers to support the case where the read drawable and the write drawable are not the same. I have to make just a few changes in the mga driver to support this case. I didn't have time to look at any of the other drivers.
Index: include/GL/glxproto.h =================================================================== RCS file: /cvsroot/dri/xc/xc/include/GL/glxproto.h,v retrieving revision 1.9 diff -u -d -r1.9 glxproto.h --- include/GL/glxproto.h 30 Apr 2003 01:50:34 -0000 1.9 +++ include/GL/glxproto.h 9 Jun 2003 22:07:07 -0000 @@ -942,6 +942,21 @@ #define sz_xGLXQueryContextInfoEXTReply 32 /* +** glXMakeCurrentReadSGI request +*/ +typedef struct GLXMakeCurrentReadSGI { + CARD8 reqType; + CARD8 glxCode; + CARD16 length B16; + CARD32 vendorCode B32; /* vendor-specific opcode */ + GLXContextTag oldContextTag B32; + GLXDrawable drawable B32; + GLXDrawable readable B32; + GLXContextID context B32; +} xGLXMakeCurrentReadSGIReq; +#define sz_xGLXMakeCurrentReadSGIReq 24 + +/* ** glXGetFBConfigsSGIX request */ typedef struct GLXGetFBConfigsSGIX { Index: lib/GL/dri/dri_util.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/dri/dri_util.c,v retrieving revision 1.14 diff -u -d -r1.14 dri_util.c --- lib/GL/dri/dri_util.c 26 May 2003 22:10:49 -0000 1.14 +++ lib/GL/dri/dri_util.c 9 Jun 2003 22:07:07 -0000 @@ -259,9 +259,9 @@ * * \param dpy the display handle. * \param scrn the screen number. - * \param draw drawable. + * \param draw Current drawing drawable. + * \param read Current reading drawable. * \param gc context. - * \param will_rebind not used. * * \return GL_TRUE on success, or GL_FALSE on failure. * @@ -270,25 +270,27 @@ * __DRIdrawablePrivateRec::refcount which must be non-zero for a successful * return. * - * While casting the opaque private pointers associated with the parameters into their - * respective real types it also assures they are not null. + * While casting the opaque private pointers associated with the parameters + * into their respective real types it also assures they are not null. */ -static Bool driUnbindContext(Display *dpy, int scrn, - GLXDrawable draw, GLXContext gc, - int will_rebind) +static Bool driUnbindContext2(Display *dpy, int scrn, + GLXDrawable draw, GLXDrawable read, + GLXContext gc) { __DRIscreen *pDRIScreen; __DRIdrawable *pdraw; + __DRIdrawable *pread; __DRIcontextPrivate *pcp; __DRIscreenPrivate *psp; __DRIdrawablePrivate *pdp; + __DRIdrawablePrivate *prp; /* ** Assume error checking is done properly in glXMakeCurrent before - ** calling driUnbindContext. + ** calling driUnbindContext2. */ - if (gc == NULL || draw == None) { + if (gc == NULL || draw == None || read == None) { /* ERROR!!! */ return GL_FALSE; } @@ -310,25 +312,37 @@ } pdp = (__DRIdrawablePrivate *)pdraw->private; - /* Don't leave fullscreen mode if the - drawable will be rebound in the next - step -- this avoids a protocol - request. */ - if (!will_rebind && psp->fullscreen) { - psp->DriverAPI.CloseFullScreen(pcp); - XF86DRICloseFullScreen(dpy, scrn, draw); - psp->fullscreen = NULL; + pread = __driFindDrawable(psp->drawHash, read); + if (!pread) { + /* ERROR!!! */ + return GL_FALSE; } + prp = (__DRIdrawablePrivate *)pread->private; + /* Let driver unbind drawable from context */ (*psp->DriverAPI.UnbindContext)(pcp); + if (pdp->refcount == 0) { /* ERROR!!! */ return GL_FALSE; - } else if (--pdp->refcount == 0) { + } + + pdp->refcount--; + + if (prp != pdp) { + if (prp->refcount == 0) { + /* ERROR!!! */ + return GL_FALSE; + } + + prp->refcount--; + } + #if 0 - /* + if (pdp->refcount == 0) { + /* ** NOT_DONE: When a drawable is unbound from one direct ** rendering context and then bound to another, we do not want ** to destroy the drawable data structure each time only to @@ -351,8 +365,8 @@ __driRemoveDrawable(psp->drawHash, pdraw); (*pdraw->destroyDrawable)(dpy, pdraw->private); Xfree(pdraw); -#endif } +#endif /* XXX this is disabled so that if we call SwapBuffers on an unbound * window we can determine the last context bound to the window and @@ -384,8 +398,6 @@ __DRIdrawablePrivate *prp; __DRIscreenPrivate *psp; __DRIcontextPrivate *pcp; - static Bool envchecked = False; - static Bool checkfullscreen = False; /* ** Assume error checking is done properly in glXMakeCurrent before @@ -474,6 +486,9 @@ pcp->driDrawablePriv = pdp; pdp->driContextPriv = pcp; pdp->refcount++; + if ( pdp != prp ) { + prp->refcount++; + } /* ** Now that we have a context associated with this drawable, we can @@ -490,75 +505,19 @@ /* Call device-specific MakeCurrent */ (*psp->DriverAPI.MakeCurrent)(pcp, pdp, prp); - /* Check for the potential to enter an automatic full-screen mode. - This may need to be moved up. */ - if (!envchecked) { - checkfullscreen = driFeatureOn("LIBGL_DRI_AUTOFULLSCREEN"); - envchecked = GL_TRUE; - } - if (checkfullscreen && pdp->numClipRects == 1) { - /* If there is valid information in the SAREA, we can use it to - avoid a protocol request. The only time when the SAREA - information won't be valid will be initially, so in the worst - case, we'll make one protocol request that we could have - avoided. */ - int try = 1; - int clw = pdp->pClipRects[0].x2 - pdp->pClipRects[0].x1; - int clh = pdp->pClipRects[0].y2 - pdp->pClipRects[0].y1; - -#if 0 - /* Useful client-side debugging message */ - fprintf(stderr, - "********************************************\n" - "********************************************\n" - "********************************************\n" - "%d @ %d,%d,%d,%d\n" - "frame %d,%d,%d,%d\n" - "win %d,%d,%d,%d\n" - "fs = %p pdp = %p sarea = %d\n" - "********************************************\n" - "********************************************\n" - "********************************************\n", - pdp->numClipRects, - pdp->pClipRects[0].x1, - pdp->pClipRects[0].y1, - pdp->pClipRects[0].x2, - pdp->pClipRects[0].y2, - psp->pSAREA->frame.x, - psp->pSAREA->frame.y, - psp->pSAREA->frame.width, - psp->pSAREA->frame.height, - pdp->x, pdp->y, pdp->w, pdp->h, - psp->fullscreen, pdp, psp->pSAREA->frame.fullscreen); -#endif - - - if (pdp->x != pdp->pClipRects[0].x1 - || pdp->y != pdp->pClipRects[0].y1 - || pdp->w != clw - || pdp->h != clh) try = 0; + return GL_TRUE; +} - if (try && psp->pSAREA->frame.width && psp->pSAREA->frame.height) { - if (pdp->x != psp->pSAREA->frame.x - || pdp->y != psp->pSAREA->frame.y - || pdp->w != psp->pSAREA->frame.width - || pdp->h != psp->pSAREA->frame.height) try = 0; - } - if (try) { - if (psp->fullscreen && !psp->pSAREA->frame.fullscreen) { - /* Server has closed fullscreen mode */ - __driUtilMessage("server closed fullscreen mode\n"); - psp->fullscreen = NULL; - } - if (XF86DRIOpenFullScreen(dpy, scrn, draw)) { - psp->fullscreen = pdp; - psp->DriverAPI.OpenFullScreen(pcp); - } - } - } - - return GL_TRUE; +/* + * Simply call bind with the same GLXDrawable for the read and draw buffers. + */ +static Bool driUnbindContext(Display *dpy, int scrn, + GLXDrawable draw, GLXContext gc, + int will_rebind) +{ + (void) will_rebind; + return driUnbindContext2( dpy, scrn, draw, draw, gc ); } @@ -1013,6 +972,10 @@ pctx->destroyContext = driDestroyContext; pctx->bindContext = driBindContext; pctx->unbindContext = driUnbindContext; + if ( driCompareGLXAPIVersion( 200300606 ) >= 0 ) { + pctx->bindContext2 = driBindContext2; + pctx->unbindContext2 = driUnbindContext2; + } __driGarbageCollectDrawables(pcp->driScreenPriv->drawHash); Index: lib/GL/glx/compsize.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/glx/compsize.c,v retrieving revision 1.6 diff -u -d -r1.6 compsize.c --- lib/GL/glx/compsize.c 25 Nov 2002 19:57:48 -0000 1.6 +++ lib/GL/glx/compsize.c 9 Jun 2003 22:07:07 -0000 @@ -38,6 +38,139 @@ #include "size.h" +/* +** Return the number of elements per group of a specified format +*/ +GLint __glElementsPerGroup(GLenum format, GLenum type) +{ + /* + ** To make row length computation valid for image extraction, + ** packed pixel types assume elements per group equals one. + */ + switch(type) { + case GL_UNSIGNED_BYTE_3_3_2: + case GL_UNSIGNED_BYTE_2_3_3_REV: + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + case GL_UNSIGNED_SHORT_8_8_APPLE: + case GL_UNSIGNED_SHORT_8_8_REV_APPLE: + case GL_UNSIGNED_SHORT_15_1_MESA: + case GL_UNSIGNED_SHORT_1_15_REV_MESA: + case GL_UNSIGNED_INT_8_8_8_8: + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + case GL_UNSIGNED_INT_24_8_NV: + case GL_UNSIGNED_INT_24_8_MESA: + case GL_UNSIGNED_INT_8_24_REV_MESA: + return 1; + default: + break; + } + + switch(format) { + case GL_RGB: + case GL_BGR: + return 3; + case GL_422_EXT: + case GL_422_REV_EXT: + case GL_422_AVERAGE_EXT: + case GL_422_REV_AVERAGE_EXT: + case GL_LUMINANCE_ALPHA: + return 2; + case GL_RGBA: + case GL_BGRA: + case GL_ABGR_EXT: + return 4; + case GL_COLOR_INDEX: + case GL_STENCIL_INDEX: + case GL_DEPTH_COMPONENT: + case GL_RED: + case GL_GREEN: + case GL_BLUE: + case GL_ALPHA: + case GL_LUMINANCE: + case GL_INTENSITY: + return 1; + default: + return 0; + } +} + +/* +** Return the number of bytes per element, based on the element type (other +** than GL_BITMAP). +*/ +GLint __glBytesPerElement(GLenum type) +{ + switch(type) { + case GL_UNSIGNED_SHORT: + case GL_SHORT: + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + case GL_UNSIGNED_SHORT_8_8_APPLE: + case GL_UNSIGNED_SHORT_8_8_REV_APPLE: + case GL_UNSIGNED_SHORT_15_1_MESA: + case GL_UNSIGNED_SHORT_1_15_REV_MESA: + return 2; + case GL_UNSIGNED_BYTE: + case GL_BYTE: + case GL_UNSIGNED_BYTE_3_3_2: + case GL_UNSIGNED_BYTE_2_3_3_REV: + return 1; + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + case GL_UNSIGNED_INT_8_8_8_8: + case GL_UNSIGNED_INT_8_8_8_8_REV: + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + case GL_UNSIGNED_INT_24_8_NV: + case GL_UNSIGNED_INT_24_8_MESA: + case GL_UNSIGNED_INT_8_24_REV_MESA: + return 4; + default: + return 0; + } +} + +/* +** Compute memory required for internal packed array of data of given type +** and format. +*/ +GLint __glImageSize(GLsizei width, GLsizei height, GLsizei depth, + GLenum format, GLenum type) +{ + int bytes_per_row; + int components; + + if (width < 0 || height < 0 || depth < 0) { + return 0; + } + /* + ** Zero is returned if either format or type are invalid. + */ + components = __glElementsPerGroup(format,type); + if (type == GL_BITMAP) { + if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX) { + bytes_per_row = (width + 7) >> 3; + } else { + return 0; + } + } else { + bytes_per_row = __glBytesPerElement(type) * width; + } + return bytes_per_row * height * depth * components; +} + GLint __glFogiv_size(GLenum pname) { switch (pname) { @@ -47,6 +180,8 @@ case GL_FOG_MODE: return 1; case GL_FOG_INDEX: return 1; case GL_FOG_START: return 1; + case GL_FOG_DISTANCE_MODE_NV: return 1; + case GL_FOG_OFFSET_VALUE_SGIX: return 1; default: return 0; } @@ -81,82 +216,7 @@ GLint __glDrawPixels_size(GLenum format, GLenum type, GLsizei w, GLsizei h) { - GLint elements, esize; - - switch (format) { - case GL_COLOR_INDEX: - case GL_STENCIL_INDEX: - case GL_DEPTH_COMPONENT: - elements = 1; - break; - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_INTENSITY: - elements = 1; - break; - case GL_LUMINANCE_ALPHA: - elements = 2; - break; - case GL_RGB: - case GL_BGR: - elements = 3; - break; - case GL_RGBA: - case GL_BGRA: - case GL_ABGR_EXT: - elements = 4; - break; - default: - return 0; - } - switch (type) { - case GL_BITMAP: - if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX) { - return (h * ((w+7)/8)); - } else { - return 0; - } - case GL_BYTE: - case GL_UNSIGNED_BYTE: - esize = 1; - break; - case GL_UNSIGNED_BYTE_3_3_2: - case GL_UNSIGNED_BYTE_2_3_3_REV: - esize = 1; - elements = 1; - break; - case GL_SHORT: - case GL_UNSIGNED_SHORT: - esize = 2; - break; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_5_6_5_REV: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - esize = 2; - elements = 1; - break; - case GL_INT: - case GL_UNSIGNED_INT: - case GL_FLOAT: - esize = 4; - break; - case GL_UNSIGNED_INT_8_8_8_8: - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_INT_10_10_10_2: - case GL_UNSIGNED_INT_2_10_10_10_REV: - esize = 4; - elements = 1; - break; - default: - return 0; - } - return (elements * esize * w * h); + return __glImageSize( w, h, 1, format, type ); } GLint __glBitmap_size(GLsizei w, GLsizei h) @@ -190,25 +250,45 @@ GLint __glTexParameterfv_size(GLenum e) { switch (e) { + case GL_TEXTURE_BORDER_COLOR: + return 4; + case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: case GL_TEXTURE_WRAP_R: case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MAG_FILTER: - return 1; - case GL_TEXTURE_BORDER_COLOR: - return 4; case GL_TEXTURE_PRIORITY: - return 1; + case GL_TEXTURE_RESIDENT: + + /* GL_SGIS_texture_lod / GL_EXT_texture_lod / GL 1.2 */ case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MAX_LOD: case GL_TEXTURE_BASE_LEVEL: case GL_TEXTURE_MAX_LEVEL: + + /* GL_SGIX_texture_lod_bias */ + case GL_TEXTURE_LOD_BIAS_S_SGIX: + case GL_TEXTURE_LOD_BIAS_T_SGIX: + case GL_TEXTURE_LOD_BIAS_R_SGIX: + + /* GL_ARB_shadow / GL 1.4 */ + case GL_TEXTURE_COMPARE_MODE: + case GL_TEXTURE_COMPARE_FUNC: + + /* GL_SGIX_shadow_ambient / GL_ARB_shadow_ambient */ + case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: + + /* GL_SGIX_shadow */ + case GL_TEXTURE_COMPARE_SGIX: + case GL_TEXTURE_COMPARE_OPERATOR_SGIX: + + /* GL_SGIX_texture_coordinate_clamp */ + case GL_TEXTURE_MAX_CLAMP_S_SGIX: + case GL_TEXTURE_MAX_CLAMP_T_SGIX: + case GL_TEXTURE_MAX_CLAMP_R_SGIX: return 1; - case GL_TEXTURE_COMPARE_MODE_ARB: /* GL_ARB_shadow */ - case GL_TEXTURE_COMPARE_FUNC_ARB: /* GL_ARB_shadow */ - case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: /* GL_ARB_shadow_ambient */ - return 1; + default: return 0; } @@ -243,7 +323,7 @@ case GL_OPERAND2_ALPHA_EXT: case GL_RGB_SCALE_EXT: case GL_ALPHA_SCALE: - /* GL_EXT_texture_lod */ + /* GL_EXT_texture_lod_bias */ case GL_TEXTURE_LOD_BIAS_EXT: return 1; default: @@ -258,245 +338,18 @@ GLint __glTexImage1D_size(GLenum format, GLenum type, GLsizei w) { - GLint elements, esize; - - if (w < 0) return 0; - switch (format) { - case GL_COLOR_INDEX: - elements = 1; - break; - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_INTENSITY: - case GL_DEPTH_COMPONENT: - elements = 1; - break; - case GL_LUMINANCE_ALPHA: - elements = 2; - break; - case GL_RGB: - case GL_BGR: - elements = 3; - break; - case GL_RGBA: - case GL_BGRA: - case GL_ABGR_EXT: - elements = 4; - break; - default: - return 0; - } - switch (type) { - case GL_BITMAP: - if (format == GL_COLOR_INDEX) { - return (w+7)/8; - } else { - return 0; - } - case GL_BYTE: - case GL_UNSIGNED_BYTE: - esize = 1; - break; - case GL_UNSIGNED_BYTE_3_3_2: - case GL_UNSIGNED_BYTE_2_3_3_REV: - esize = 1; - elements = 1; - break; - case GL_SHORT: - case GL_UNSIGNED_SHORT: - esize = 2; - break; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_5_6_5_REV: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - esize = 2; - elements = 1; - break; - case GL_INT: - case GL_UNSIGNED_INT: - case GL_FLOAT: - esize = 4; - break; - case GL_UNSIGNED_INT_8_8_8_8: - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_INT_10_10_10_2: - case GL_UNSIGNED_INT_2_10_10_10_REV: - esize = 4; - elements = 1; - break; - default: - return 0; - } - return (elements * esize * w); + return __glImageSize( w, 1, 1, format, type ); } GLint __glTexImage2D_size(GLenum format, GLenum type, GLsizei w, GLsizei h) { - GLint elements, esize; - - if (w < 0) return 0; - if (h < 0) return 0; - switch (format) { - case GL_COLOR_INDEX: - elements = 1; - break; - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_INTENSITY: - case GL_DEPTH_COMPONENT: - elements = 1; - break; - case GL_LUMINANCE_ALPHA: - elements = 2; - break; - case GL_RGB: - case GL_BGR: - elements = 3; - break; - case GL_RGBA: - case GL_BGRA: - case GL_ABGR_EXT: - elements = 4; - break; - default: - return 0; - } - switch (type) { - case GL_BITMAP: - if (format == GL_COLOR_INDEX) { - return (h * ((w+7)/8)); - } else { - return 0; - } - case GL_BYTE: - case GL_UNSIGNED_BYTE: - esize = 1; - break; - case GL_UNSIGNED_BYTE_3_3_2: - case GL_UNSIGNED_BYTE_2_3_3_REV: - esize = 1; - elements = 1; - break; - case GL_SHORT: - case GL_UNSIGNED_SHORT: - esize = 2; - break; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_5_6_5_REV: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - esize = 2; - elements = 1; - break; - case GL_INT: - case GL_UNSIGNED_INT: - case GL_FLOAT: - esize = 4; - break; - case GL_UNSIGNED_INT_8_8_8_8: - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_INT_10_10_10_2: - case GL_UNSIGNED_INT_2_10_10_10_REV: - esize = 4; - elements = 1; - break; - default: - return 0; - } - return (elements * esize * w * h); + return __glImageSize( w, h, 1, format, type ); } GLint __glTexImage3D_size(GLenum format, GLenum type, GLsizei w, GLsizei h, GLsizei d) { - GLint elements, esize; - - if (w < 0) return 0; - if (h < 0) return 0; - if (d < 0) return 0; - switch (format) { - case GL_COLOR_INDEX: - elements = 1; - break; - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_INTENSITY: - elements = 1; - break; - case GL_LUMINANCE_ALPHA: - elements = 2; - break; - case GL_RGB: - case GL_BGR: - elements = 3; - break; - case GL_RGBA: - case GL_BGRA: - case GL_ABGR_EXT: - elements = 4; - break; - default: - return 0; - } - switch (type) { - case GL_BITMAP: - if (format == GL_COLOR_INDEX) { - return (d * (h * ((w+7)/8))); - } else { - return 0; - } - case GL_BYTE: - case GL_UNSIGNED_BYTE: - esize = 1; - break; - case GL_UNSIGNED_BYTE_3_3_2: - case GL_UNSIGNED_BYTE_2_3_3_REV: - esize = 1; - elements = 1; - break; - case GL_SHORT: - case GL_UNSIGNED_SHORT: - esize = 2; - break; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_5_6_5_REV: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - esize = 2; - elements = 1; - break; - case GL_INT: - case GL_UNSIGNED_INT: - case GL_FLOAT: - esize = 4; - break; - case GL_UNSIGNED_INT_8_8_8_8: - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_INT_10_10_10_2: - case GL_UNSIGNED_INT_2_10_10_10_REV: - esize = 4; - elements = 1; - break; - default: - return 0; - } - return (elements * esize * w * h * d); + return __glImageSize( w, h, d, format, type ); } GLint __glLightfv_size(GLenum pname) Index: lib/GL/glx/glxclient.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/glx/glxclient.h,v retrieving revision 1.28 diff -u -d -r1.28 glxclient.h --- lib/GL/glx/glxclient.h 21 May 2003 17:32:05 -0000 1.28 +++ lib/GL/glx/glxclient.h 9 Jun 2003 22:07:07 -0000 @@ -181,8 +181,6 @@ /* ** Method to bind a DRI drawable to a DRI graphics context. - ** XXX in the future, also pass a 'read' GLXDrawable for - ** glXMakeCurrentReadSGI() and GLX 1.3's glXMakeContextCurrent(). */ Bool (*bindContext)(Display *dpy, int scrn, GLXDrawable draw, GLXContext gc); @@ -199,6 +197,22 @@ ** screen used to create this context. Never dereferenced in libGL. */ void *private; + + /* + ** Added with internal API version "20030606". + ** + ** Method to bind a DRI drawable to a DRI graphics context. + */ + Bool (*bindContext2)(Display *dpy, int scrn, GLXDrawable draw, + GLXDrawable read, GLXContext gc); + + /* + ** Added with internal API version "20030606". + ** + ** Method to unbind a DRI drawable to a DRI graphics context. + */ + Bool (*unbindContext2)(Display *dpy, int scrn, GLXDrawable draw, + GLXDrawable read, GLXContext gc); }; /* @@ -492,7 +506,7 @@ /* ** The current drawable for this context. Will be None if this - ** context is not current to any drawable. + ** context is not current to any drawable. currentReadable is below. */ GLXDrawable currentDrawable; @@ -532,6 +546,14 @@ ** Added with internal API version "20030317". */ GLXFBConfigID fbconfigID; + + /* + ** Added with internal API version "20030606". + ** + ** The current read-drawable for this context. Will be None if this + ** context is not current to any drawable. + */ + GLXDrawable currentReadable; }; #define __glXSetError(gc,code) \ @@ -693,6 +715,14 @@ /* Return the size, in bytes, of some pixel data */ extern GLint __glImageSize(GLint, GLint, GLint, GLenum, GLenum); + +/* Return the number of elements per group of a specified format*/ +extern GLint __glElementsPerGroup(GLenum format, GLenum type); + +/* Return the number of bytes per element, based on the element type (other +** than GL_BITMAP). +*/ +extern GLint __glBytesPerElement(GLenum type); /* Return the k value for a given map target */ extern GLint __glEvalComputeK(GLenum); Index: lib/GL/glx/glxcmds.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/glx/glxcmds.c,v retrieving revision 1.41 diff -u -d -r1.41 glxcmds.c --- lib/GL/glx/glxcmds.c 21 May 2003 17:32:06 -0000 1.41 +++ lib/GL/glx/glxcmds.c 9 Jun 2003 22:07:07 -0000 @@ -52,6 +52,7 @@ const char __glXGLClientExtensions[] = "GL_ARB_depth_texture " "GL_ARB_imaging " + "GL_ARB_multisample " "GL_ARB_multitexture " "GL_ARB_point_parameters " "GL_ARB_shadow " @@ -72,6 +73,7 @@ "GL_EXT_blend_logic_op " "GL_EXT_blend_minmax " "GL_EXT_blend_subtract " + "GL_EXT_clip_volume_hint " "GL_EXT_copy_texture " "GL_EXT_draw_range_elements " "GL_EXT_fog_coord " @@ -81,28 +83,131 @@ "GL_EXT_rescale_normal " "GL_EXT_secondary_color " "GL_EXT_separate_specular_color " + "GL_EXT_shadow_funcs " "GL_EXT_stencil_two_side " "GL_EXT_stencil_wrap " "GL_EXT_subtexture " "GL_EXT_texture " "GL_EXT_texture3D " + "GL_EXT_texture_edge_clamp " "GL_EXT_texture_env_add " "GL_EXT_texture_env_combine " "GL_EXT_texture_env_dot3 " + "GL_EXT_texture_filter_anisotropic " + "GL_EXT_texture_lod " "GL_EXT_texture_lod_bias " "GL_EXT_texture_object " + "GL_EXT_texture_rectangle " "GL_EXT_vertex_array " + "GL_APPLE_packed_pixels " + "GL_APPLE_ycbcr_422 " + "GL_ATI_texture_env_combine3 " + "GL_ATI_texture_float " + "GL_ATI_texture_mirror_once " + "GL_ATIX_texture_env_combine3 " + "GL_HP_convolution_border_modes " + "GL_HP_occlusion_test " + "GL_IBM_cull_vertex " + "GL_IBM_pixel_filter_hint " + "GL_IBM_rasterpos_clip " + "GL_IBM_texture_clamp_nodraw " "GL_IBM_texture_mirrored_repeat " + "GL_MESA_pack_invert " + "GL_MESA_ycbcr_texture " "GL_NV_blend_square " + "GL_NV_copy_depth_to_color " + "GL_NV_depth_clamp " + "GL_NV_fog_distance " + "GL_NV_light_max_exponent " + "GL_NV_multisample_filter_hint " + "GL_NV_texgen_reflection " + "GL_NV_texture_rectangle " + "GL_SGIS_generate_mipmap " "GL_SGIS_multisample " "GL_SGIS_texture_border_clamp " "GL_SGIS_texture_edge_clamp " - "GL_SGIS_generate_mipmap " + "GL_SGIS_texture_lod " + "GL_SGIX_blend_alpha_minmax " + "GL_SGIX_clipmap " + "GL_SGIX_depth_texture " + "GL_SGIX_fog_offset " + "GL_SGIX_shadow " + "GL_SGIX_shadow_ambient " + "GL_SGIX_texture_coordinate_clamp " + "GL_SGIX_texture_lod_bias " + "GL_SGIX_texture_range " + "GL_SGIX_vertex_preclip " + "GL_SGIX_vertex_preclip_hint " + "GL_SGIX_ycrcb " + "GL_SUN_convolution_border_modes " + "GL_SUN_slice_accum " ; static const char __glXGLXClientVendorName[] = "SGI"; static const char __glXGLXClientVersion[] = "1.2"; +static void * DriverCreateContextWrapper( __GLXscreenConfigs *psc, + Display *dpy, XVisualInfo *vis, void *shared, __DRIcontext *ctx, + __GLXFBConfig *fbconfig ); + +static Bool dummyBindContext2( Display *dpy, int scrn, + GLXDrawable draw, GLXDrawable read, GLXContext gc ); + +static Bool dummyUnbindContext2( Display *dpy, int scrn, + GLXDrawable draw, GLXDrawable read, GLXContext gc ); + +/****************************************************************************/ + +static Bool dummyBindContext2( Display *dpy, int scrn, + GLXDrawable draw, GLXDrawable read, + GLXContext gc ) +{ + assert( draw == read ); + return (*gc->driContext.bindContext)( dpy, scrn, draw, gc ); +} + +static Bool dummyUnbindContext2( Display *dpy, int scrn, + GLXDrawable draw, GLXDrawable read, + GLXContext gc ) +{ + assert( draw == read ); + return (*gc->driContext.unbindContext)( dpy, scrn, draw, gc, GL_FALSE ); +} + + +/****************************************************************************/ +/** + * Wrap the call to the driver's \c createContext function. + * + * The \c createContext function is wrapped because not all drivers support + * the "new" \c unbindContext2 and \c bindContext2 interfaces. libGL should + * not have to check to see which functions the driver supports. Instead, + * if either function is not supported it is wrapped. The wrappers test to + * make sure that both drawables are the same and pass control to the old + * interface. + */ + +static void * DriverCreateContextWrapper( __GLXscreenConfigs *psc, + Display *dpy, XVisualInfo *vis, void *shared, + __DRIcontext *ctx, __GLXFBConfig *fbconfig ) +{ + void * ctx_priv; + + ctx_priv = (*psc->driScreen.createContext)(dpy, vis, shared, ctx, + fbconfig); + if ( ctx_priv != NULL ) { + if ( ctx->unbindContext2 == NULL ) { + ctx->unbindContext2 = dummyUnbindContext2; + } + + if ( ctx->bindContext2 == NULL ) { + ctx->bindContext2 = dummyBindContext2; + } + } + + return ctx_priv; +} + /****************************************************************************/ /** * Get the write __DRIdrawable bound to the specificed GLXContext @@ -114,7 +219,7 @@ */ static __DRIdrawable * -GetDRIDrawable( GLXContext gc ) +GetDRIDrawable( GLXContext gc, GLXDrawable drawable ) { #ifdef GLX_DIRECT_RENDERING __DRIdrawable *pdraw = NULL; @@ -130,7 +235,7 @@ ** not bound to a direct rendering context. */ pdraw = (*psc->driScreen.getDrawable)(gc->currentDpy, - gc->currentDrawable, + drawable, psc->driScreen.private); } } @@ -138,6 +243,7 @@ return pdraw; #else + (void) gc; return NULL; #endif } @@ -258,8 +364,8 @@ void *shared = (shareList ? shareList->driContext.private : NULL); gc->driContext.private = - (*psc->driScreen.createContext)(dpy, vis, shared, - &gc->driContext, NULL); + DriverCreateContextWrapper( psc, dpy, vis, shared, + &gc->driContext, NULL ); if (gc->driContext.private) { gc->isDirect = GL_TRUE; gc->screen = vis->screen; @@ -647,24 +753,11 @@ GLXContextTag tag; CARD8 opcode; #ifdef GLX_DIRECT_RENDERING - __GLXdisplayPrivate *priv; - __DRIdrawable *pdraw; + __DRIdrawable *pdraw = GetDRIDrawable( gc, drawable ); - priv = __glXInitialize(dpy); - if (priv->driDisplay.private) { - __GLXscreenConfigs *psc = &priv->screenConfigs[gc->screen]; - if (psc && psc->driScreen.private) { - /* - ** getDrawable returning NULL implies that the drawable is - ** not bound to a direct rendering context. - */ - pdraw = (*psc->driScreen.getDrawable)(dpy, drawable, - psc->driScreen.private); - if (pdraw) { - (*pdraw->swapBuffers)(dpy, pdraw->private); - return; - } - } + if ( pdraw != NULL ) { + (*pdraw->swapBuffers)(dpy, pdraw->private); + return; } #endif @@ -677,7 +770,8 @@ ** The calling thread may or may not have a current context. If it ** does, send the context tag so the server can do a flush. */ - if ((dpy == gc->currentDpy) && (drawable == gc->currentDrawable)) { + if ((dpy == gc->currentDpy) && + ((drawable == gc->currentDrawable) || (drawable == gc->currentReadable)) ) { tag = gc->currentContextTag; } else { tag = 0; @@ -769,20 +863,22 @@ case GLX_TRANSPARENT_INDEX_VALUE_EXT: *value_return = pConfig->transparentIndex; return Success; - case GLX_X_VISUAL_TYPE_EXT: + case GLX_X_VISUAL_TYPE: switch(pConfig->class) { case TrueColor: - *value_return = GLX_TRUE_COLOR_EXT; break; + *value_return = GLX_TRUE_COLOR; break; case DirectColor: - *value_return = GLX_DIRECT_COLOR_EXT; break; + *value_return = GLX_DIRECT_COLOR; break; case PseudoColor: - *value_return = GLX_PSEUDO_COLOR_EXT; break; + *value_return = GLX_PSEUDO_COLOR; break; case StaticColor: - *value_return = GLX_STATIC_COLOR_EXT; break; + *value_return = GLX_STATIC_COLOR; break; case GrayScale: - *value_return = GLX_GRAY_SCALE_EXT; break; + *value_return = GLX_GRAY_SCALE; break; case StaticGray: - *value_return = GLX_STATIC_GRAY_EXT; break; + *value_return = GLX_STATIC_GRAY; break; + default: + *value_return = GLX_NONE; break; } return Success; case GLX_VISUAL_CAVEAT_EXT: @@ -1330,7 +1426,15 @@ screen, GLX_EXTENSIONS); } - psc->effectiveGLXexts = (char *) __glXGetUsableExtensions(psc->serverGLXexts); +#ifdef GLX_DIRECT_RENDERING + psc->effectiveGLXexts = (char *) __glXGetUsableExtensions(psc->serverGLXexts, + (priv->driDisplay.private != NULL), + priv->minorVersion); +#else + psc->effectiveGLXexts = (char *) __glXGetUsableExtensions(psc->serverGLXexts, + GL_FALSE, + priv->minorVersion); +#endif } return psc->effectiveGLXexts; @@ -1638,9 +1742,8 @@ void *shared = (shareList ? shareList->driContext.private : NULL); gc->driContext.private = - (*psc->driScreen.createContext)(dpy, NULL, shared, - &gc->driContext, - fbconfig); + DriverCreateContextWrapper( psc, dpy, NULL, shared, + &gc->driContext, fbconfig ); if (gc->driContext.private) { gc->isDirect = GL_TRUE; gc->screen = fbconfig->screen; @@ -1720,10 +1823,10 @@ } -GLXDrawable glXGetCurrentReadDrawable(void) +GLXDrawable GLX_PREFIX(glXGetCurrentReadDrawable)(void) { GLXContext gc = __glXGetCurrentContext(); - return gc->currentDrawable; + return gc->currentReadable; } @@ -1796,16 +1899,6 @@ } -Bool GLX_PREFIX(glXMakeContextCurrent)(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) -{ - (void) dpy; - (void) draw; - (void) read; - (void) ctx; - return 0; -} - - int GLX_PREFIX(glXQueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value) { (void) dpy; @@ -1833,6 +1926,7 @@ } +#if 0 /* ** GLX_SGI_make_current_read */ @@ -1844,11 +1938,12 @@ (void) ctx; return False; } +#endif GLXDrawable glXGetCurrentReadDrawableSGI(void) { GLXContext gc = __glXGetCurrentContext(); - return gc->currentDrawable; + return gc->currentReadable; } @@ -1873,7 +1968,7 @@ #ifdef GLX_DIRECT_RENDERING if ( gc->isDirect && __glXExtensionBitIsEnabled( SGI_swap_control_bit ) ) { - __DRIdrawable *pdraw = GetDRIDrawable( gc ); + __DRIdrawable *pdraw = GetDRIDrawable( gc, gc->currentDrawable ); if ( pdraw != NULL ) { pdraw->swap_interval = interval; @@ -1913,7 +2008,7 @@ { #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); - __DRIdrawable *pdraw = GetDRIDrawable( gc ); + __DRIdrawable *pdraw = GetDRIDrawable( gc, gc->currentDrawable ); if ( pdraw == NULL ) { return GLX_BAD_CONTEXT; @@ -1938,7 +2033,7 @@ { #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); - __DRIdrawable *pdraw = GetDRIDrawable( gc ); + __DRIdrawable *pdraw = GetDRIDrawable( gc, gc->currentDrawable ); if ( pdraw && __glXExtensionBitIsEnabled( MESA_swap_control_bit ) ) { @@ -2026,7 +2121,7 @@ int status = GLX_BAD_CONTEXT; #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); - __DRIdrawable *pdraw = GetDRIDrawable( gc ); + __DRIdrawable *pdraw = GetDRIDrawable( gc, drawable ); if ( (pdraw != NULL ) && (pdraw->queryFrameTracking != NULL) && __glXExtensionBitIsEnabled( MESA_swap_frame_usage_bit ) ) { @@ -2053,7 +2148,7 @@ int status = GLX_BAD_CONTEXT; #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); - __DRIdrawable *pdraw = GetDRIDrawable( gc ); + __DRIdrawable *pdraw = GetDRIDrawable( gc, drawable ); if ( (pdraw != NULL ) && (pdraw->queryFrameTracking != NULL) && __glXExtensionBitIsEnabled( MESA_swap_frame_usage_bit ) ) { @@ -2112,7 +2207,7 @@ { #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); - __DRIdrawable *pdraw = GetDRIDrawable( gc ); + __DRIdrawable *pdraw = GetDRIDrawable( gc, gc->currentDrawable ); if ( divisor <= 0 || remainder < 0 ) return GLX_BAD_VALUE; @@ -2237,9 +2332,8 @@ void *shared = (shareList ? shareList->driContext.private : NULL); gc->driContext.private = - (*psc->driScreen.createContext)(dpy, NULL, shared, - &gc->driContext, - fbconfig); + DriverCreateContextWrapper( psc, dpy, NULL, shared, + &gc->driContext, fbconfig ); if (gc->driContext.private) { gc->isDirect = GL_TRUE; gc->screen = fbconfig->screen; @@ -2598,7 +2692,7 @@ { #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); - __DRIdrawable *pdraw = GetDRIDrawable( gc ); + __DRIdrawable *pdraw = GetDRIDrawable( gc, drawable ); /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE * error", but it also says "It [glXSwapBuffersMscOML] will return a value @@ -2632,7 +2726,7 @@ { #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); - __DRIdrawable *pdraw = GetDRIDrawable( gc ); + __DRIdrawable *pdraw = GetDRIDrawable( gc, drawable ); int ret; /* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE @@ -2673,7 +2767,7 @@ { #ifdef GLX_DIRECT_RENDERING GLXContext gc = __glXGetCurrentContext(); - __DRIdrawable *pdraw = GetDRIDrawable( gc ); + __DRIdrawable *pdraw = GetDRIDrawable( gc, drawable ); int ret; /* The OML_sync_control spec says this should "generate a GLX_BAD_VALUE @@ -3159,8 +3253,9 @@ * GLX_MESA_swap_frame_usage, GLX_OML_swap_method, * GLX_{ARB,SGIS}_multisample, and * GLX_SGIX_visual_select_group. + * 20030606 - Added support for GLX_SGI_make_current_read. */ - return 20030317; + return 20030606; } Index: lib/GL/glx/glxext.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/glx/glxext.c,v retrieving revision 1.28 diff -u -d -r1.28 glxext.c --- lib/GL/glx/glxext.c 13 May 2003 13:48:21 -0000 1.28 +++ lib/GL/glx/glxext.c 9 Jun 2003 22:07:07 -0000 @@ -58,6 +58,9 @@ void __glXDumpDrawBuffer(__GLXcontext *ctx); #endif +static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw, + GLXDrawable read, GLXContext gc); + /* ** We setup some dummy structures here so that the API can be used ** even if no context is current. @@ -674,12 +677,6 @@ fb_req->reqType = priv->majorOpcode; fb_req->glxCode = X_GLXGetFBConfigs; fb_req->screen = i; - if (_XReply(dpy, (xReply*) &reply, 0, False)) { - /* Something is busted. Punt. */ - UnlockDisplay(dpy); - FreeScreenConfigs(priv); - return GL_FALSE; - } break; case 2: @@ -690,12 +687,6 @@ sgi_req->glxCode = X_GLXVendorPrivateWithReply; sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX; sgi_req->screen = i; - if (_XReply(dpy, (xReply*) &reply, 0, False)) { - /* Something is busted. Punt. */ - UnlockDisplay(dpy); - FreeScreenConfigs(priv); - return GL_FALSE; - } break; case 3: @@ -703,15 +694,16 @@ req->reqType = priv->majorOpcode; req->glxCode = X_GLXGetVisualConfigs; req->screen = i; - if (!_XReply(dpy, (xReply*) &reply, 0, False)) { - /* Something is busted. Punt. */ - UnlockDisplay(dpy); - FreeScreenConfigs(priv); - return GL_FALSE; - } break; } + if (!_XReply(dpy, (xReply*) &reply, 0, False)) { + /* Something is busted. Punt. */ + UnlockDisplay(dpy); + FreeScreenConfigs(priv); + return GL_FALSE; + } + UnlockDisplay(dpy); if (!reply.numVisuals) { /* This screen does not support GL rendering */ @@ -745,9 +737,11 @@ } /* Allocate memory for the properties, if needed */ - prop_size = (supported_request == 3) - ? nprops * __GLX_SIZE_INT32 - : nprops * __GLX_SIZE_INT32 * 2; + if ( supported_request != 3 ) { + nprops *= 2; + } + + prop_size = nprops * __GLX_SIZE_INT32; if (prop_size <= sizeof(buf)) { props = buf; @@ -1091,17 +1085,82 @@ /************************************************************************/ +static Bool SendMakeCurrentRequest( Display *dpy, CARD8 opcode, + GLXContextID gc, GLXContextTag old_gc, GLXDrawable draw, GLXDrawable read, + xGLXMakeCurrentReply * reply ); + +static Bool SendMakeCurrentRequest( Display *dpy, CARD8 opcode, + GLXContextID gc_id, GLXContextTag gc_tag, + GLXDrawable draw, GLXDrawable read, + xGLXMakeCurrentReply * reply ) +{ + opcode = __glXSetupForCommand(dpy); + if (!opcode) { + return GL_FALSE; + } + + LockDisplay(dpy); + if ( draw == read ) { + xGLXMakeCurrentReq *req; + + GetReq(GLXMakeCurrent,req); + req->reqType = opcode; + req->glxCode = X_GLXMakeCurrent; + req->drawable = draw; + req->context = gc_id; + req->oldContextTag = gc_tag; + } + else { + __GLXdisplayPrivate *priv = __glXInitialize(dpy); + + /* If the server can support the GLX 1.3 version, we should + * perfer that. Not only that, some servers support GLX 1.3 but + * not the SGI extension. + */ + + if ( (priv->majorVersion > 1) || (priv->minorVersion >= 3) ) { + xGLXMakeContextCurrentReq *req; + + GetReq(GLXMakeContextCurrent,req); + req->reqType = opcode; + req->glxCode = X_GLXMakeContextCurrent; + req->drawable = draw; + req->readdrawable = read; + req->context = gc_id; + req->oldContextTag = gc_tag; + } + else { + xGLXVendorPrivateWithReplyReq *vpreq; + xGLXMakeCurrentReadSGIReq *req; + + GetReqExtra(GLXVendorPrivateWithReply, + sz_xGLXMakeCurrentReadSGIReq-sz_xGLXVendorPrivateWithReplyReq,vpreq); + req = (xGLXMakeCurrentReadSGIReq *)vpreq; + req->reqType = opcode; + req->glxCode = X_GLXVendorPrivateWithReply; + req->vendorCode = X_GLXvop_MakeCurrentReadSGI; + req->drawable = draw; + req->readable = read; + req->context = gc_id; + req->oldContextTag = gc_tag; + } + } + + return _XReply(dpy, (xReply*) reply, 0, False); +} + + /* ** Make a particular context current. ** NOTE: this is in this file so that it can access dummyContext. */ -Bool GLX_PREFIX(glXMakeCurrent)(Display *dpy, GLXDrawable draw, GLXContext gc) +static Bool MakeContextCurrent(Display *dpy, + GLXDrawable draw, GLXDrawable read, + GLXContext gc) { - xGLXMakeCurrentReq *req; xGLXMakeCurrentReply reply; GLXContext oldGC; CARD8 opcode, oldOpcode; - Display *dpyTmp; Bool sentRequestToOldDpy = False; Bool bindReturnValue = True; @@ -1109,6 +1168,7 @@ if (!opcode) { return GL_FALSE; } + /* ** Make sure that the new context has a nonzero ID. In the request, ** a zero context ID is used only to mean that we bind to no current @@ -1119,6 +1179,11 @@ } oldGC = __glXGetCurrentContext(); + oldOpcode = (gc == oldGC) ? opcode : __glXSetupForCommand(dpy); + if (!oldOpcode) { + return GL_FALSE; + } + if ((dpy != oldGC->currentDpy || (gc && gc->isDirect)) && !oldGC->isDirect && oldGC != &dummyContext) { /* @@ -1129,35 +1194,15 @@ ** unbind the previous context. */ sentRequestToOldDpy = True; - dpyTmp = dpy; - - if (dpy != oldGC->currentDpy) { - /* - ** The GetReq macro uses "dpy", so we have to save and - ** restore later. - */ - dpy = oldGC->currentDpy; - oldOpcode = __glXSetupForCommand(dpy); - if (!oldOpcode) { - return GL_FALSE; - } - } else { - oldOpcode = opcode; - } - LockDisplay(dpy); - GetReq(GLXMakeCurrent,req); - req->reqType = oldOpcode; - req->glxCode = X_GLXMakeCurrent; - req->drawable = None; - req->context = None; - req->oldContextTag = oldGC->currentContextTag; - if (!_XReply(dpy, (xReply*) &reply, 0, False)) { + if ( ! SendMakeCurrentRequest( oldGC->currentDpy, oldOpcode, None, + oldGC->currentContextTag, None, None, + &reply ) ) { /* The make current failed. Just return GL_FALSE. */ UnlockDisplay(dpy); SyncHandle(); return GL_FALSE; } - dpy = dpyTmp; + oldGC->currentContextTag = 0; } @@ -1165,13 +1210,11 @@ /* Unbind the old direct rendering context */ if (oldGC->isDirect) { if (oldGC->driContext.private) { - int will_rebind = (gc && gc->isDirect - && draw == oldGC->currentDrawable); - if (!(*oldGC->driContext.unbindContext)(oldGC->currentDpy, - oldGC->screen, - oldGC->currentDrawable, - oldGC, - will_rebind)) { + if (!(*oldGC->driContext.unbindContext2)(oldGC->currentDpy, + oldGC->screen, + oldGC->currentDrawable, + oldGC->currentReadable, + oldGC)) { /* The make current failed. Just return GL_FALSE. */ return GL_FALSE; } @@ -1183,21 +1226,18 @@ if (gc && gc->isDirect) { if (gc->driContext.private) { bindReturnValue = - (*gc->driContext.bindContext)(dpy, gc->screen, draw, gc); + (*gc->driContext.bindContext2)(dpy, gc->screen, draw, read, gc); } } else { #endif _glapi_check_multithread(); /* Send a glXMakeCurrent request to bind the new context. */ LockDisplay(dpy); - GetReq(GLXMakeCurrent,req); - req->reqType = opcode; - req->glxCode = X_GLXMakeCurrent; - req->drawable = draw; - req->context = gc ? gc->xid : None; - req->oldContextTag = oldGC->currentContextTag; - bindReturnValue = _XReply(dpy, (xReply*) &reply, 0, False); - UnlockDisplay(dpy); + + bindReturnValue = SendMakeCurrentRequest( dpy, opcode, + gc ? gc->xid : None, + oldGC->currentContextTag, + draw, read, &reply ); #ifdef GLX_DIRECT_RENDERING } #endif @@ -1213,10 +1253,11 @@ /* If the old context was direct rendering, then re-bind to it. */ if (oldGC->isDirect) { if (oldGC->driContext.private) { - if (!(*oldGC->driContext.bindContext)(oldGC->currentDpy, - oldGC->screen, - oldGC->currentDrawable, - oldGC)) { + if (!(*oldGC->driContext.bindContext2)(oldGC->currentDpy, + oldGC->screen, + oldGC->currentDrawable, + oldGC->currentReadable, + oldGC)) { /* ** The request failed; this cannot happen with the ** current API. If in the future the API is @@ -1237,20 +1278,10 @@ ** drawable. */ if (sentRequestToOldDpy) { - if (dpy != oldGC->currentDpy) { - dpy = oldGC->currentDpy; - oldOpcode = __glXSetupForCommand(dpy); - } else { - oldOpcode = opcode; - } - LockDisplay(dpy); - GetReq(GLXMakeCurrent,req); - req->reqType = oldOpcode; - req->glxCode = X_GLXMakeCurrent; - req->drawable = oldGC->currentDrawable; - req->context = oldGC->xid; - req->oldContextTag = 0; - if (!_XReply(dpy, (xReply*) &reply, 0, False)) { + if ( !SendMakeCurrentRequest( oldGC->currentDpy, oldOpcode, + oldGC->xid, 0, + oldGC->currentDrawable, + oldGC->currentReadable, &reply ) ) { UnlockDisplay(dpy); SyncHandle(); /* @@ -1280,11 +1311,13 @@ ** NULL and not the dummy. */ gc->currentDrawable = draw; + gc->currentReadable = read; } else { if (oldGC != &dummyContext) { /* Old current context is no longer current to anybody */ oldGC->currentDpy = 0; oldGC->currentDrawable = None; + oldGC->currentReadable = None; oldGC->currentContextTag = 0; if (oldGC->xid == None) { @@ -1322,6 +1355,7 @@ #endif gc->currentDpy = dpy; gc->currentDrawable = draw; + gc->currentReadable = read; #ifdef GLX_DIRECT_RENDERING if (gc->isDirect) reply.contextTag = -1; #endif @@ -1336,6 +1370,23 @@ __glXUnlock(); return GL_TRUE; } + + +Bool GLX_PREFIX(glXMakeCurrent)(Display *dpy, GLXDrawable draw, GLXContext gc) +{ + return MakeContextCurrent( dpy, draw, draw, gc ); +} + +Bool GLX_PREFIX(glXMakeCurrentReadSGI)(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext gc) +{ + return MakeContextCurrent( dpy, draw, read, gc ); +} + +Bool GLX_PREFIX(glXMakeContextCurrent)(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext gc) +{ + return MakeContextCurrent( dpy, draw, read, gc ); +} + #ifdef DEBUG void __glXDumpDrawBuffer(__GLXcontext *ctx) Index: lib/GL/glx/glxextensions.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/glx/glxextensions.c,v retrieving revision 1.3 diff -u -d -r1.3 glxextensions.c --- lib/GL/glx/glxextensions.c 3 May 2003 05:19:30 -0000 1.3 +++ lib/GL/glx/glxextensions.c 9 Jun 2003 22:07:07 -0000 @@ -98,7 +98,7 @@ { GLX(OML_swap_method), VER(0,0), Y, N, N, N }, { GLX(OML_sync_control), VER(0,0), Y, N, N, Y }, { GLX(SGI_cushion), VER(0,0), N, N, N, N }, - { GLX(SGI_make_current_read), VER(1,3), N, N, N, N }, + { GLX(SGI_make_current_read), VER(1,3), Y, N, N, N }, { GLX(SGI_swap_control), VER(0,0), Y, N, N, N }, { GLX(SGI_video_sync), VER(0,0), Y, N, N, Y }, { GLX(SGIS_blended_overlay), VER(0,0), N, N, N, N }, @@ -448,10 +448,16 @@ /** * Get the list of application usable extensions. * + * \param server_string GLX extension string supplied by + * the X-server + * \param display_is_direct_capable True if the display is capable of + * direct rendering. * \returns A pointer to the string. */ char * -__glXGetUsableExtensions( const char * server_string ) +__glXGetUsableExtensions( const char * server_string, + GLboolean display_is_direct_capable, + int minor_version ) { unsigned char server_support[8]; unsigned char usable[8]; @@ -460,15 +466,35 @@ __glXExtensionsCtr(); __glXProcessServerString( server_string, server_support ); + + /* This is a hack. Some servers support GLX 1.3 but don't export + * SGI_make_current_read. This libGL supports SGI_make_current_read but + * doesn't have full GLX 1.3 support. Until GLX 1.3 is fully supported + * this hack is done to export the functionality to applications. + */ + + if ( minor_version >= 3 ) { + SET_BIT( server_support, SGI_make_current_read_bit ); + } + + /* An extension is supported if the client-side (i.e., libGL) supports * it and the "server" supports it. In this case that means that either * the true server supports it or it is only for direct-rendering and * the direct rendering driver supports it. */ - for ( i = 0 ; i < 8 ; i++ ) { - usable[i] = (client_support[i] & client_only[i]) - | (client_support[i] & (direct_support[i] & server_support[i])) - | (client_support[i] & (direct_support[i] & direct_only[i])); + if ( display_is_direct_capable ) { + for ( i = 0 ; i < 8 ; i++ ) { + usable[i] = (client_support[i] & client_only[i]) + | (client_support[i] & (direct_support[i] & server_support[i])) + | (client_support[i] & (direct_support[i] & direct_only[i])); + } + } + else { + for ( i = 0 ; i < 8 ; i++ ) { + usable[i] = (client_support[i] & client_only[i]) + | (client_support[i] & server_support[i]); + } } return __glXGetStringFromTable( usable ); Index: lib/GL/glx/glxextensions.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/glx/glxextensions.h,v retrieving revision 1.2 diff -u -d -r1.2 glxextensions.h --- lib/GL/glx/glxextensions.h 30 Apr 2003 01:50:35 -0000 1.2 +++ lib/GL/glx/glxextensions.h 9 Jun 2003 22:07:07 -0000 @@ -71,7 +71,8 @@ extern GLboolean __glXExtensionBitIsEnabled( unsigned bit ); extern const char * __glXGetClientExtensions( void ); -extern char * __glXGetUsableExtensions( const char * server_string ); +extern char * __glXGetUsableExtensions( const char * server_string, + GLboolean display_is_direct_capable, int server_minor_version ); extern void __glXAddExtension( GLboolean enabled, const char * name, GLboolean client_side ); extern void __glXEnableExtension( const char * name, GLboolean force_client ); Index: lib/GL/glx/pixel.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/glx/pixel.c,v retrieving revision 1.10 diff -u -d -r1.10 pixel.c --- lib/GL/glx/pixel.c 25 Mar 2003 12:53:44 -0000 1.10 +++ lib/GL/glx/pixel.c 9 Jun 2003 22:07:07 -0000 @@ -79,120 +79,6 @@ 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, }; -/* -** Return the number of elements per group of a specified format -*/ -static GLint ElementsPerGroup(GLenum format, GLenum type) -{ - /* - ** To make row length computation valid for image extraction, - ** packed pixel types assume elements per group equals one. - */ - switch(type) { - case GL_UNSIGNED_BYTE_3_3_2: - case GL_UNSIGNED_BYTE_2_3_3_REV: - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_5_6_5_REV: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - case GL_UNSIGNED_INT_8_8_8_8: - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_INT_10_10_10_2: - case GL_UNSIGNED_INT_2_10_10_10_REV: - return 1; - default: - break; - } - - switch(format) { - case GL_RGB: - case GL_BGR: - return 3; - case GL_LUMINANCE_ALPHA: - return 2; - case GL_RGBA: - case GL_BGRA: - case GL_ABGR_EXT: - return 4; - case GL_COLOR_INDEX: - case GL_STENCIL_INDEX: - case GL_DEPTH_COMPONENT: - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_INTENSITY: - return 1; - default: - return 0; - } -} - -/* -** Return the number of bytes per element, based on the element type (other -** than GL_BITMAP). -*/ -static GLint BytesPerElement(GLenum type) -{ - switch(type) { - case GL_UNSIGNED_SHORT: - case GL_SHORT: - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_5_6_5_REV: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - return 2; - case GL_UNSIGNED_BYTE: - case GL_BYTE: - case GL_UNSIGNED_BYTE_3_3_2: - case GL_UNSIGNED_BYTE_2_3_3_REV: - return 1; - case GL_INT: - case GL_UNSIGNED_INT: - case GL_FLOAT: - case GL_UNSIGNED_INT_8_8_8_8: - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_INT_10_10_10_2: - case GL_UNSIGNED_INT_2_10_10_10_REV: - return 4; - default: - return 0; - } -} - -/* -** Compute memory required for internal packed array of data of given type -** and format. -*/ -GLint __glImageSize(GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type) -{ - int bytes_per_row; - int components; - - if (width < 0 || height < 0 || depth < 0) { - return 0; - } - /* - ** Zero is returned if either format or type are invalid. - */ - components = ElementsPerGroup(format,type); - if (type == GL_BITMAP) { - if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX) { - bytes_per_row = (width + 7) >> 3; - } else { - return 0; - } - } else { - bytes_per_row = BytesPerElement(type) * width; - } - return bytes_per_row * height * depth * components; -} /* ** Copy bitmap data from clients packed memory applying unpacking modes as the @@ -218,7 +104,7 @@ } else { groupsPerRow = width; } - components = ElementsPerGroup(format,GL_BITMAP); + components = __glElementsPerGroup(format,GL_BITMAP); rowSize = (groupsPerRow * components + 7) >> 3; padding = (rowSize % alignment); if (padding) { @@ -294,7 +180,7 @@ if (type == GL_BITMAP) { FillBitmap(gc, width, height, format, userdata, newimage); } else { - components = ElementsPerGroup(format,type); + components = __glElementsPerGroup(format,type); if (rowLength > 0) { groupsPerRow = rowLength; } else { @@ -306,7 +192,7 @@ rowsPerImage = height; } - elementSize = BytesPerElement(type); + elementSize = __glBytesPerElement(type); groupSize = elementSize * components; if (elementSize == 1) swapBytes = 0; @@ -409,7 +295,7 @@ GLint writeMask, i; GLubyte writeByte; - components = ElementsPerGroup(format,GL_BITMAP); + components = __glElementsPerGroup(format,GL_BITMAP); if (rowLength > 0) { groupsPerRow = rowLength; } else { @@ -522,7 +408,7 @@ if (type == GL_BITMAP) { EmptyBitmap(gc, width, height, format, sourceImage, userdata); } else { - components = ElementsPerGroup(format,type); + components = __glElementsPerGroup(format,type); if (rowLength > 0) { groupsPerRow = rowLength; } else { @@ -533,7 +419,7 @@ } else { rowsPerImage = height; } - elementSize = BytesPerElement(type); + elementSize = __glBytesPerElement(type); groupSize = elementSize * components; rowSize = groupsPerRow * groupSize; padding = (rowSize % alignment); Index: lib/GL/glx/render2.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/glx/render2.c,v retrieving revision 1.5 diff -u -d -r1.5 render2.c --- lib/GL/glx/render2.c 30 Apr 2003 01:50:36 -0000 1.5 +++ lib/GL/glx/render2.c 9 Jun 2003 22:07:07 -0000 @@ -426,28 +426,6 @@ __GLX_LOAD_VARIABLES(); if (!gc->currentDpy) return; - switch (cap) { -#if 0 - case GL_VERTEX_ARRAY_EXT: - gc->state.vertArray.vertex.enable = GL_TRUE; - return; - case GL_NORMAL_ARRAY_EXT: - gc->state.vertArray.normal.enable = GL_TRUE; - return; - case GL_COLOR_ARRAY_EXT: - gc->state.vertArray.color.enable = GL_TRUE; - return; - case GL_INDEX_ARRAY_EXT: - gc->state.vertArray.index.enable = GL_TRUE; - return; - case GL_TEXTURE_COORD_ARRAY_EXT: - gc->state.vertArray.texCoord[gc->state.vertArray.activeTexture].enable = GL_TRUE; - return; - case GL_EDGE_FLAG_ARRAY_EXT: - gc->state.vertArray.edgeFlag.enable = GL_TRUE; - return; -#endif - } __GLX_BEGIN(X_GLrop_Enable,8); __GLX_PUT_LONG(4,cap); __GLX_END(8); @@ -460,28 +438,6 @@ __GLX_LOAD_VARIABLES(); if (!gc->currentDpy) return; - switch (cap) { -#if 0 - case GL_VERTEX_ARRAY_EXT: - gc->state.vertArray.vertex.enable = GL_FALSE; - return; - case GL_NORMAL_ARRAY_EXT: - gc->state.vertArray.normal.enable = GL_FALSE; - return; - case GL_COLOR_ARRAY_EXT: - gc->state.vertArray.color.enable = GL_FALSE; - return; - case GL_INDEX_ARRAY_EXT: - gc->state.vertArray.index.enable = GL_FALSE; - return; - case GL_TEXTURE_COORD_ARRAY_EXT: - gc->state.vertArray.texCoord[gc->state.vertArray.activeTexture].enable = GL_FALSE; - return; - case GL_EDGE_FLAG_ARRAY_EXT: - gc->state.vertArray.edgeFlag.enable = GL_FALSE; - return; -#endif - } __GLX_BEGIN(X_GLrop_Disable,8); __GLX_PUT_LONG(4,cap); __GLX_END(8); Index: lib/GL/mesa/src/drv/mga/mga_xmesa.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v retrieving revision 1.53 diff -u -d -r1.53 mga_xmesa.c --- lib/GL/mesa/src/drv/mga/mga_xmesa.c 27 May 2003 20:49:32 -0000 1.53 +++ lib/GL/mesa/src/drv/mga/mga_xmesa.c 9 Jun 2003 22:07:07 -0000 @@ -587,13 +587,7 @@ } static GLboolean -mgaOpenFullScreen(__DRIcontextPrivate *driContextPriv) -{ - return GL_TRUE; -} - -static GLboolean -mgaCloseFullScreen(__DRIcontextPrivate *driContextPriv) +mgaOpenCloseFullScreen(__DRIcontextPrivate *driContextPriv) { return GL_TRUE; } @@ -615,6 +609,7 @@ if (mmesa->driDrawable != driDrawPriv) { mmesa->driDrawable = driDrawPriv; + mmesa->driReadable = driReadPriv; mmesa->dirty = ~0; mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK); } @@ -680,8 +675,8 @@ .SwapBuffers = mgaSwapBuffers, .MakeCurrent = mgaMakeCurrent, .UnbindContext = mgaUnbindContext, - .OpenFullScreen = mgaOpenFullScreen, - .CloseFullScreen = mgaCloseFullScreen, + .OpenFullScreen = mgaOpenCloseFullScreen, + .CloseFullScreen = mgaOpenCloseFullScreen, .GetSwapInfo = getSwapInfo, .GetMSC = driGetMSC32, .WaitForMSC = driWaitForMSC32, @@ -718,6 +713,13 @@ glXGetProcAddress( "__glXEnableExtension" ); if ( glx_enable_extension != NULL ) { + /* Technically speaking, SGI_make_current_read wasn't added to libGL + * until version 20030606. Enabling it here (regardless of the + * libGL API version) is safe. + */ + + (*glx_enable_extension)( "GLX_SGI_make_current_read", GL_FALSE ); + (*glx_enable_extension)( "GLX_SGI_swap_control", GL_FALSE ); (*glx_enable_extension)( "GLX_SGI_video_sync", GL_FALSE ); (*glx_enable_extension)( "GLX_MESA_swap_control", GL_FALSE ); Index: lib/GL/mesa/src/drv/mga/mgacontext.h =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mgacontext.h,v retrieving revision 1.24 diff -u -d -r1.24 mgacontext.h --- lib/GL/mesa/src/drv/mga/mgacontext.h 20 May 2003 22:54:31 -0000 1.24 +++ lib/GL/mesa/src/drv/mga/mgacontext.h 9 Jun 2003 22:07:07 -0000 @@ -297,6 +297,7 @@ drmLock *driHwLock; int driFd; __DRIdrawablePrivate *driDrawable; + __DRIdrawablePrivate *driReadable; __DRIscreenPrivate *driScreen; struct mga_screen_private_s *mgaScreen; MGASAREAPrivPtr sarea; Index: lib/GL/mesa/src/drv/mga/mgaspan.c =================================================================== RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/mga/mgaspan.c,v retrieving revision 1.31 diff -u -d -r1.31 mgaspan.c --- lib/GL/mesa/src/drv/mga/mgaspan.c 30 Apr 2003 01:50:42 -0000 1.31 +++ lib/GL/mesa/src/drv/mga/mgaspan.c 9 Jun 2003 22:07:07 -0000 @@ -38,14 +38,15 @@ #define LOCAL_VARS \ __DRIdrawablePrivate *dPriv = mmesa->driDrawable; \ + __DRIdrawablePrivate *rPriv = mmesa->driReadable; \ mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; \ __DRIscreenPrivate *sPriv = mmesa->driScreen; \ GLuint pitch = mgaScreen->frontPitch; \ GLuint height = dPriv->h; \ char *read_buf = (char *)(sPriv->pFB + \ mmesa->readOffset + \ - dPriv->x * mgaScreen->cpp + \ - dPriv->y * pitch); \ + rPriv->x * mgaScreen->cpp + \ + rPriv->y * pitch); \ char *buf = (char *)(sPriv->pFB + \ mmesa->drawOffset + \ dPriv->x * mgaScreen->cpp + \ @@ -57,6 +58,7 @@ #define LOCAL_DEPTH_VARS \ __DRIdrawablePrivate *dPriv = mmesa->driDrawable; \ + __DRIdrawablePrivate *rPriv = mmesa->driReadable; \ mgaScreenPrivate *mgaScreen = mmesa->mgaScreen; \ __DRIscreenPrivate *sPriv = mmesa->driScreen; \ GLuint pitch = mgaScreen->frontPitch; \ @@ -64,7 +66,12 @@ char *buf = (char *)(sPriv->pFB + \ mgaScreen->depthOffset + \ dPriv->x * mgaScreen->cpp + \ - dPriv->y * pitch) + dPriv->y * pitch); \ + char *read_buf = (char *)(sPriv->pFB + \ + mgaScreen->depthOffset + \ + rPriv->x * mgaScreen->cpp + \ + rPriv->y * pitch); \ + (void) read_buf; (void) buf #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS @@ -181,7 +188,7 @@ *(GLushort *)(buf + _x*2 + _y*pitch) = d; #define READ_DEPTH( d, _x, _y ) \ - d = *(GLushort *)(buf + _x*2 + _y*pitch); + d = *(GLushort *)(read_buf + _x*2 + _y*pitch); #define TAG(x) mga##x##_16 #include "depthtmp.h" @@ -195,7 +202,7 @@ *(GLuint *)(buf + _x*4 + _y*pitch) = d; #define READ_DEPTH( d, _x, _y ) \ - d = *(GLuint *)(buf + _x*4 + _y*pitch); + d = *(GLuint *)(read_buf + _x*4 + _y*pitch); #define TAG(x) mga##x##_32 #include "depthtmp.h" @@ -212,7 +219,7 @@ } #define READ_DEPTH( d, _x, _y ) { \ - d = (*(GLuint *)(buf + _x*4 + _y*pitch) & ~0xff) >> 8; \ + d = (*(GLuint *)(read_buf + _x*4 + _y*pitch) & ~0xff) >> 8; \ } #define TAG(x) mga##x##_24_8 @@ -226,7 +233,7 @@ } #define READ_STENCIL( d, _x, _y ) \ - d = *(GLuint *)(buf + _x*4 + _y*pitch) & 0xff; + d = *(GLuint *)(read_buf + _x*4 + _y*pitch) & 0xff; #define TAG(x) mga##x##_24_8 #include "stenciltmp.h" Index: programs/Xserver/GL/glx/glxscreens.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/GL/glx/glxscreens.c,v retrieving revision 1.11 diff -u -d -r1.11 glxscreens.c --- programs/Xserver/GL/glx/glxscreens.c 30 Apr 2003 01:50:58 -0000 1.11 +++ programs/Xserver/GL/glx/glxscreens.c 9 Jun 2003 22:07:08 -0000 @@ -69,6 +69,7 @@ "GL_EXT_blend_logic_op " "GL_EXT_blend_minmax " "GL_EXT_blend_subtract " + "GL_EXT_clip_volume_hint " "GL_EXT_copy_texture " "GL_EXT_draw_range_elements " "GL_EXT_fog_coord " @@ -78,22 +79,38 @@ "GL_EXT_rescale_normal " "GL_EXT_secondary_color " "GL_EXT_separate_specular_color " + "GL_EXT_shadow_funcs " "GL_EXT_stencil_two_side " "GL_EXT_stencil_wrap " "GL_EXT_subtexture " "GL_EXT_texture " "GL_EXT_texture3D " + "GL_EXT_texture_edge_clamp " "GL_EXT_texture_env_add " "GL_EXT_texture_env_combine " "GL_EXT_texture_env_dot3 " + "GL_EXT_texture_lod " "GL_EXT_texture_lod_bias " "GL_EXT_texture_object " + "GL_EXT_texture_rectangle " "GL_EXT_vertex_array " + "GL_APPLE_packed_pixels " + "GL_ATI_texture_mirror_once " + "GL_ATI_texture_env_combine3 " + "GL_HP_occlusion_test " "GL_IBM_texture_mirrored_repeat " + "GL_MESA_pack_invert " + "GL_MESA_ycbcr_texture " "GL_NV_blend_square " + "GL_NV_texgen_reflection " + "GL_NV_texture_rectangle " + "GL_SGIS_generate_mipmap " "GL_SGIS_texture_border_clamp " "GL_SGIS_texture_edge_clamp " - "GL_SGIS_generate_mipmap " + "GL_SGIS_texture_lod " + "GL_SGIX_depth_texture " + "GL_SGIX_shadow " + "GL_SGIX_shadow_ambient " ; /* Index: programs/Xserver/GL/glx/rensize.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/GL/glx/rensize.c,v retrieving revision 1.7 diff -u -d -r1.7 rensize.c --- programs/Xserver/GL/glx/rensize.c 25 Nov 2002 19:58:40 -0000 1.7 +++ programs/Xserver/GL/glx/rensize.c 9 Jun 2003 22:07:08 -0000 @@ -267,109 +267,8 @@ int __glXImageSize( GLenum format, GLenum type, GLsizei w, GLsizei h, GLint rowLength, GLint skipRows, GLint alignment ) { - GLint bytesPerElement, elementsPerGroup, groupsPerRow; - GLint groupSize, rowSize, padding; - - if (w < 0 || h < 0 || - (type == GL_BITMAP && - (format != GL_COLOR_INDEX && format != GL_STENCIL_INDEX))) { - return -1; - } - if (w==0 || h==0) return 0; - - if (type == GL_BITMAP) { - if (rowLength > 0) { - groupsPerRow = rowLength; - } else { - groupsPerRow = w; - } - rowSize = (groupsPerRow + 7) >> 3; - padding = (rowSize % alignment); - if (padding) { - rowSize += alignment - padding; - } - return ((h + skipRows) * rowSize); - } else { - switch(format) { - case GL_COLOR_INDEX: - case GL_STENCIL_INDEX: - case GL_DEPTH_COMPONENT: - elementsPerGroup = 1; - break; - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_INTENSITY: - elementsPerGroup = 1; - break; - case GL_LUMINANCE_ALPHA: - elementsPerGroup = 2; - break; - case GL_RGB: - case GL_BGR: - elementsPerGroup = 3; - break; - case GL_RGBA: - case GL_BGRA: - case GL_ABGR_EXT: - elementsPerGroup = 4; - break; - default: - return -1; - } - switch(type) { - case GL_UNSIGNED_BYTE: - case GL_BYTE: - bytesPerElement = 1; - break; - case GL_UNSIGNED_BYTE_3_3_2: - case GL_UNSIGNED_BYTE_2_3_3_REV: - bytesPerElement = 1; - elementsPerGroup = 1; - break; - case GL_UNSIGNED_SHORT: - case GL_SHORT: - bytesPerElement = 2; - break; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_5_6_5_REV: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - bytesPerElement = 2; - elementsPerGroup = 1; - break; - case GL_INT: - case GL_UNSIGNED_INT: - case GL_FLOAT: - bytesPerElement = 4; - break; - case GL_UNSIGNED_INT_8_8_8_8: - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_INT_10_10_10_2: - case GL_UNSIGNED_INT_2_10_10_10_REV: - bytesPerElement = 4; - elementsPerGroup = 1; - break; - default: - return -1; - } - groupSize = bytesPerElement * elementsPerGroup; - if (rowLength > 0) { - groupsPerRow = rowLength; - } else { - groupsPerRow = w; - } - rowSize = groupsPerRow * groupSize; - padding = (rowSize % alignment); - if (padding) { - rowSize += alignment - padding; - } - return ((h + skipRows) * rowSize); - } + return __glXImage3DSize( format, type, w, h, 1, 0, rowLength, + 0, skipRows, alignment ); } /* XXX @@ -406,8 +305,6 @@ case GL_COLOR_INDEX: case GL_STENCIL_INDEX: case GL_DEPTH_COMPONENT: - elementsPerGroup = 1; - break; case GL_RED: case GL_GREEN: case GL_BLUE: @@ -416,6 +313,13 @@ case GL_INTENSITY: elementsPerGroup = 1; break; + case GL_422_EXT: + case GL_422_REV_EXT: + case GL_422_AVERAGE_EXT: + case GL_422_REV_AVERAGE_EXT: + case GL_DEPTH_STENCIL_NV: + case GL_DEPTH_STENCIL_MESA: + case GL_YCBCR_MESA: case GL_LUMINANCE_ALPHA: elementsPerGroup = 2; break; @@ -451,6 +355,10 @@ case GL_UNSIGNED_SHORT_4_4_4_4_REV: case GL_UNSIGNED_SHORT_5_5_5_1: case GL_UNSIGNED_SHORT_1_5_5_5_REV: + case GL_UNSIGNED_SHORT_8_8_APPLE: + case GL_UNSIGNED_SHORT_8_8_REV_APPLE: + case GL_UNSIGNED_SHORT_15_1_MESA: + case GL_UNSIGNED_SHORT_1_15_REV_MESA: bytesPerElement = 2; elementsPerGroup = 1; break; @@ -463,6 +371,9 @@ case GL_UNSIGNED_INT_8_8_8_8_REV: case GL_UNSIGNED_INT_10_10_10_2: case GL_UNSIGNED_INT_2_10_10_10_REV: + case GL_UNSIGNED_INT_24_8_NV: + case GL_UNSIGNED_INT_24_8_MESA: + case GL_UNSIGNED_INT_8_24_REV_MESA: bytesPerElement = 4; elementsPerGroup = 1; break; Index: programs/Xserver/GL/glx/singlesize.c =================================================================== RCS file: /cvsroot/dri/xc/xc/programs/Xserver/GL/glx/singlesize.c,v retrieving revision 1.6 diff -u -d -r1.6 singlesize.c --- programs/Xserver/GL/glx/singlesize.c 25 Nov 2002 19:58:41 -0000 1.6 +++ programs/Xserver/GL/glx/singlesize.c 9 Jun 2003 22:07:08 -0000 @@ -46,101 +46,7 @@ GLint __glReadPixels_size(GLenum format, GLenum type, GLint w, GLint h) { - GLint elements, esize; - GLint rowsize, padding; - - if (w < 0 || h < 0) { - return -1; - } - switch (format) { - case GL_COLOR_INDEX: - case GL_STENCIL_INDEX: - case GL_DEPTH_COMPONENT: - elements = 1; - break; - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_INTENSITY: - elements = 1; - break; - case GL_LUMINANCE_ALPHA: - elements = 2; - break; - case GL_RGB: - case GL_BGR: - elements = 3; - break; - case GL_RGBA: - case GL_BGRA: - case GL_ABGR_EXT: - elements = 4; - break; - default: - return -1; - } - /* - ** According to the GLX protocol, each row must be padded to a multiple of - ** 4 bytes. 4 bytes also happens to be the default alignment in the pixel - ** store modes of the GL. - */ - switch (type) { - case GL_BITMAP: - if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX) { - rowsize = ((w * elements)+7)/8; - padding = rowsize % 4; - if (padding) { - rowsize += 4 - padding; - } - return (rowsize * h); - } else { - return -1; - } - case GL_BYTE: - case GL_UNSIGNED_BYTE: - esize = 1; - break; - case GL_UNSIGNED_BYTE_3_3_2: - case GL_UNSIGNED_BYTE_2_3_3_REV: - esize = 1; - elements = 1; - break; - case GL_SHORT: - case GL_UNSIGNED_SHORT: - esize = 2; - break; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_5_6_5_REV: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - esize = 2; - elements = 1; - break; - case GL_INT: - case GL_UNSIGNED_INT: - case GL_FLOAT: - esize = 4; - break; - case GL_UNSIGNED_INT_8_8_8_8: - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_INT_10_10_10_2: - case GL_UNSIGNED_INT_2_10_10_10_REV: - esize = 4; - elements = 1; - break; - default: - return -1; - } - rowsize = w * elements * esize; - padding = rowsize % 4; - if (padding) { - rowsize += 4 - padding; - } - return (rowsize * h); + return __glXImage3DSize( format, type, w, h, 1, 0, 0, 0, 0, 4 ); } GLint __glGetTexEnvfv_size(GLenum pname) @@ -207,27 +113,43 @@ GLint __glGetTexParameterfv_size(GLenum pname) { switch (pname) { + case GL_TEXTURE_BORDER_COLOR: + return 4; + case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: case GL_TEXTURE_WRAP_R: - return 1; case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MAG_FILTER: - return 1; - case GL_TEXTURE_BORDER_COLOR: - return 4; case GL_TEXTURE_PRIORITY: - return 1; case GL_TEXTURE_RESIDENT: - return 1; + + /* GL_SGIS_texture_lod / GL_EXT_texture_lod / GL 1.2 */ case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MAX_LOD: case GL_TEXTURE_BASE_LEVEL: case GL_TEXTURE_MAX_LEVEL: - return 1; - case GL_TEXTURE_COMPARE_MODE_ARB: /* GL_ARB_shadow */ - case GL_TEXTURE_COMPARE_FUNC_ARB: /* GL_ARB_shadow */ - case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: /* GL_ARB_shadow_ambient */ + + /* GL_SGIX_texture_lod_bias */ + case GL_TEXTURE_LOD_BIAS_S_SGIX: + case GL_TEXTURE_LOD_BIAS_T_SGIX: + case GL_TEXTURE_LOD_BIAS_R_SGIX: + + /* GL_ARB_shadow / GL 1.4 */ + case GL_TEXTURE_COMPARE_MODE: + case GL_TEXTURE_COMPARE_FUNC: + + /* GL_SGIX_shadow_ambient / GL_ARB_shadow_ambient */ + case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: + + /* GL_SGIX_shadow */ + case GL_TEXTURE_COMPARE_SGIX: + case GL_TEXTURE_COMPARE_OPERATOR_SGIX: + + /* GL_SGIX_texture_coordinate_clamp */ + case GL_TEXTURE_MAX_CLAMP_S_SGIX: + case GL_TEXTURE_MAX_CLAMP_T_SGIX: + case GL_TEXTURE_MAX_CLAMP_R_SGIX: return 1; default: @@ -915,6 +837,15 @@ case GL_TEXTURE_BINDING_CUBE_MAP_ARB: case GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB: return 1; + case GL_OCCLUSION_TEST_RESULT_HP: + case GL_OCCLUSION_TEST_HP: + return 1; + case GL_PACK_INVERT_MESA: + return 1; + case GL_CULL_VERTEX_IBM: + return 1; + case GL_RASTER_POSITION_UNCLIPPED_IBM: + return 1; default: return -1; } @@ -968,83 +899,8 @@ GLint __glGetTexImage_size(GLenum target, GLint level, GLenum format, GLenum type, GLint width, GLint height, GLint depth) { - GLint elements, esize; - GLint padding, rowsize; - - switch (format) { - case GL_RGBA: - case GL_BGRA: - case GL_ABGR_EXT: - elements = 4; - break; - case GL_RGB: - case GL_BGR: - elements = 3; - break; - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_INTENSITY: - case GL_DEPTH_COMPONENT: - elements = 1; - break; - case GL_LUMINANCE_ALPHA: - elements = 2; - break; - default: - return -1; - } - switch (type) { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - esize = 1; - break; - case GL_UNSIGNED_BYTE_3_3_2: - case GL_UNSIGNED_BYTE_2_3_3_REV: - esize = 1; - elements = 1; - break; - case GL_SHORT: - case GL_UNSIGNED_SHORT: - esize = 2; - break; - case GL_UNSIGNED_SHORT_5_6_5: - case GL_UNSIGNED_SHORT_5_6_5_REV: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - esize = 2; - elements = 1; - break; - case GL_INT: - case GL_UNSIGNED_INT: - case GL_FLOAT: - esize = 4; - break; - case GL_UNSIGNED_INT_8_8_8_8: - case GL_UNSIGNED_INT_8_8_8_8_REV: - case GL_UNSIGNED_INT_10_10_10_2: - case GL_UNSIGNED_INT_2_10_10_10_REV: - esize = 4; - elements = 1; - break; - default: - return -1; - } - /* - ** According to the GLX protocol, each row must be padded to a multiple of - ** 4 bytes. 4 bytes also happens to be the default alignment in the pixel - ** store modes of the GL. - */ - rowsize = width * elements * esize; - padding = rowsize % 4; - if (padding) { - rowsize += 4 - padding; - } - return (rowsize * height * depth); + return __glXImage3DSize( format, type, width, height, depth, + 0, 0, 0, 0, 4 ); } GLint __glGetConvolutionParameteriv_size(GLenum pname)
Index: glxgears.c =================================================================== RCS file: /cvsroot/mesa3d/Mesa/xdemos/glxgears.c,v retrieving revision 1.7 diff -u -d -r1.7 glxgears.c --- glxgears.c 30 May 2003 18:41:38 -0000 1.7 +++ glxgears.c 9 Jun 2003 22:06:20 -0000 @@ -48,6 +48,8 @@ #include <GL/gl.h> #include <GL/glx.h> +#include <assert.h> + #ifndef GLX_MESA_swap_control typedef GLint ( * PFNGLXSWAPINTERVALMESAPROC) (unsigned interval); typedef GLint ( * PFNGLXGETSWAPINTERVALMESAPROC) ( void ); @@ -112,7 +114,9 @@ static GLint gear1, gear2, gear3; static GLfloat angle = 0.0; +static GLboolean has_GLX_1_3 = GL_FALSE; static GLboolean has_OML_sync_control = GL_FALSE; +static GLboolean has_SGI_make_current_read = GL_FALSE; static GLboolean has_SGI_swap_control = GL_FALSE; static GLboolean has_MESA_swap_control = GL_FALSE; static GLboolean has_MESA_swap_frame_usage = GL_FALSE; @@ -352,9 +356,74 @@ } +static void +draw2( Display * dpy, Window * win, GLXContext ctx ) +{ + GLboolean result; + + if ( has_GLX_1_3 ) { + result = glXMakeContextCurrent(dpy, win[1], win[0], ctx); + } + else if ( has_SGI_make_current_read ) { + result = glXMakeCurrentReadSGI(dpy, win[1], win[0], ctx); + } + else { + result = glXMakeCurrent(dpy, win[0], ctx); + } + + /* FIXME: If this fails, how can the app determine why it failed? */ + assert( result ); + + glBindTexture( GL_TEXTURE_2D, 1 ); + glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, 300, 300 ); + + if ( ! (has_GLX_1_3 || has_SGI_make_current_read) ) { + result = glXMakeCurrent(dpy, win[1], ctx); + assert( result ); + } + + glBindTexture( GL_TEXTURE_2D, 1 ); + + glDisable(GL_CULL_FACE); + glDisable(GL_LIGHTING); + glDisable(GL_LIGHT0); + glDisable(GL_DEPTH_TEST); + glEnable(GL_TEXTURE_2D); + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glTranslatef(0.5, 0.5, 0.0); + glRotatef(angle, 0, 0, 1); + glTranslatef(-0.5, -0.5, 0.0); + glMatrixMode(GL_MODELVIEW); + + glBegin(GL_POLYGON); + + glTexCoord2f( 0.0, 0.0 ); + glVertex2f( -5.0, -5.0 ); + + glTexCoord2f( 0.0, 0.0 ); + glVertex2f( 5.0, -5.0 ); + + glTexCoord2f( 1.0, 1.0 ); + glVertex2f( 5.0, 5.0 ); + + glTexCoord2f( 0.0, 1.0 ); + glVertex2f( -5.0, 5.0 ); + + glEnd(); + + glDisable(GL_TEXTURE_2D); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_DEPTH_TEST); +} + + /* new window size or exposure */ static void -reshape(int width, int height) +reshape(Window win, int width, int height) { aspect = (GLfloat) height / (GLfloat) width; @@ -371,7 +440,7 @@ static void -init(void) +init(GLboolean create_texture_object) { static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 }; static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 }; @@ -404,6 +473,21 @@ glEndList(); glEnable(GL_NORMALIZE); + + + /* Initialize the texture object so that glCopyTexSubImage2D can be used + * to update its contents. + */ + + if ( create_texture_object ) { + glBindTexture(GL_TEXTURE_2D, 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 512, 512, 0, GL_RGB, GL_BYTE, + NULL); + } } @@ -414,7 +498,8 @@ static void make_window( Display *dpy, const char *name, int x, int y, int width, int height, - Window *winRet, GLXContext *ctxRet) + Window *winRet, GLXContext *ctxRet, + GLboolean two_windows ) { int attrib[] = { GLX_RGBA, GLX_RED_SIZE, 1, @@ -427,9 +512,8 @@ XSetWindowAttributes attr; unsigned long mask; Window root; - Window win; - GLXContext ctx; XVisualInfo *visinfo; + XSizeHints sizehints; scrnum = DefaultScreen( dpy ); root = RootWindow( dpy, scrnum ); @@ -447,51 +531,72 @@ attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; - win = XCreateWindow( dpy, root, 0, 0, width, height, - 0, visinfo->depth, InputOutput, - visinfo->visual, mask, &attr ); + winRet[0] = XCreateWindow( dpy, root, 0, 0, width, height, + 0, visinfo->depth, InputOutput, + visinfo->visual, mask, &attr ); /* set hints and properties */ - { - XSizeHints sizehints; - sizehints.x = x; + sizehints.x = x; + sizehints.y = y; + sizehints.width = width; + sizehints.height = height; + sizehints.flags = USSize | USPosition; + XSetNormalHints(dpy, winRet[0], &sizehints); + XSetStandardProperties(dpy, winRet[0], name, name, + None, (char **)NULL, 0, &sizehints); + + if ( two_windows ) { + /* window attributes */ + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone); + attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + winRet[1] = XCreateWindow( dpy, root, 0, 0, width, height, + 0, visinfo->depth, InputOutput, + visinfo->visual, mask, &attr ); + + /* set hints and properties */ + sizehints.x = x + width + 10; sizehints.y = y; sizehints.width = width; sizehints.height = height; sizehints.flags = USSize | USPosition; - XSetNormalHints(dpy, win, &sizehints); - XSetStandardProperties(dpy, win, name, name, - None, (char **)NULL, 0, &sizehints); + XSetNormalHints(dpy, winRet[1], &sizehints); + XSetStandardProperties(dpy, winRet[1], "second window", "2nd win", + None, (char **)NULL, 0, &sizehints); + } + else { + winRet[1] = None; } - ctx = glXCreateContext( dpy, visinfo, NULL, True ); - if (!ctx) { + ctxRet[0] = glXCreateContext( dpy, visinfo, NULL, True ); + if (! ctxRet[0] ) { printf("Error: glXCreateContext failed\n"); exit(1); } XFree(visinfo); - - *winRet = win; - *ctxRet = ctx; } static void -event_loop(Display *dpy, Window win) +event_loop(Display *dpy, Window *win, GLXContext ctx) { float frame_usage = 0.0; while (1) { while (XPending(dpy) > 0) { - XEvent event; - XNextEvent(dpy, &event); + XEvent event; + XNextEvent(dpy, &event); switch (event.type) { case Expose: /* we'll redraw below */ break; case ConfigureNotify: - reshape(event.xconfigure.width, event.xconfigure.height); + reshape(event.xany.window, + event.xconfigure.width, event.xconfigure.height); break; case KeyPress: { @@ -525,15 +630,21 @@ /* next frame */ angle += 2.0; + glXMakeCurrent(dpy, win[0], ctx); draw(); if ( get_frame_usage != NULL ) { GLfloat temp; - (*get_frame_usage)( dpy, win, & temp ); + (*get_frame_usage)( dpy, win[0], & temp ); frame_usage += temp; } - glXSwapBuffers(dpy, win); + if ( win[1] != None ) { + draw2( dpy, win, ctx ); + glXSwapBuffers(dpy, win[1]); + } + + glXSwapBuffers(dpy, win[0]); /* calc framerate */ { @@ -699,16 +810,19 @@ main(int argc, char *argv[]) { Display *dpy; - Window win; + Window win[2]; GLXContext ctx; char *dpyName = ":0"; int swap_interval = 1; GLboolean do_swap_interval = GL_FALSE; GLboolean force_get_rate = GL_FALSE; GLboolean printInfo = GL_FALSE; + GLboolean use_two_windows = GL_FALSE; int i; PFNGLXSWAPINTERVALMESAPROC set_swap_interval = NULL; PFNGLXGETSWAPINTERVALMESAPROC get_swap_interval = NULL; + GLint major; + GLint minor; for (i = 1; i < argc; i++) { @@ -727,13 +841,16 @@ else if (strcmp(argv[i], "-forcegetrate") == 0) { /* This option was put in because some DRI drivers don't support the * full GLX_OML_sync_control extension, but they do support - * glXGetMscRateOML. + * glXGetMscRateOML. */ force_get_rate = GL_TRUE; } else if (strcmp(argv[i], "-ztrick") == 0) { use_ztrick = GL_TRUE; } + else if (strcmp(argv[i], "-twowindow") == 0) { + use_two_windows = GL_TRUE; + } else if (strcmp(argv[i], "-help") == 0) { printf("Usage:\n"); printf(" gears [options]\n"); @@ -743,6 +860,12 @@ printf(" -info Display GL information\n"); printf(" -swap N Swap no more than once per N vertical refreshes\n"); printf(" -forcegetrate Try to use glXGetMscRateOML function\n"); + printf(" -ztrick Use the Quake 2 / Half-Life style \"Z-trick\" to\n" + " avoid calling glClear. For testing only. Does not\n" + " speed-up gears!\n" ); + printf(" -twowindow Use two windows to test using one window as a texture\n" + " for the other window. Tests GLX 1.3 and / or\n" + " SGI_make_current_read.\n" ); return 0; } } @@ -753,16 +876,20 @@ return -1; } - make_window(dpy, "glxgears", 0, 0, 300, 300, &win, &ctx); - XMapWindow(dpy, win); - glXMakeCurrent(dpy, win, ctx); + make_window(dpy, "glxgears", 0, 0, 300, 300, win, &ctx, use_two_windows); + glXMakeCurrent( dpy, win[0], ctx ); make_extension_table( (char *) glXQueryExtensionsString(dpy,DefaultScreen(dpy)) ); has_OML_sync_control = is_extension_supported( "GLX_OML_sync_control" ); + has_SGI_make_current_read = is_extension_supported( "GLX_SGI_make_current_read" ); +has_SGI_make_current_read = GL_TRUE; has_SGI_swap_control = is_extension_supported( "GLX_SGI_swap_control" ); has_MESA_swap_control = is_extension_supported( "GLX_MESA_swap_control" ); has_MESA_swap_frame_usage = is_extension_supported( "GLX_MESA_swap_frame_usage" ); + glXQueryVersion( dpy, & major, & minor ); + has_GLX_1_3 = (major > 1) || ((major == 1) && (minor >= 3)); + if ( has_MESA_swap_control ) { set_swap_interval = (PFNGLXSWAPINTERVALMESAPROC) glXGetProcAddressARB( (const GLubyte *) "glXSwapIntervalMESA" ); get_swap_interval = (PFNGLXGETSWAPINTERVALMESAPROC) glXGetProcAddressARB( (const GLubyte *) "glXGetSwapIntervalMESA" ); @@ -786,6 +913,16 @@ show_refresh_rate( dpy ); } + if ( has_GLX_1_3 ) { + printf( "Using glXMakeContextCurrent.\n" ); + } + else if ( has_SGI_make_current_read ) { + printf( "Using glXMakeCurrentReadSGI.\n" ); + } + else { + printf( "Using glXMakeCurrent.\n" ); + } + if ( get_swap_interval != NULL ) { printf("Default swap interval = %d\n", (*get_swap_interval)() ); } @@ -812,12 +949,21 @@ } } - init(); + if ( win[1] != None ) { + XMapWindow(dpy, win[1]); + } - event_loop(dpy, win); + XMapWindow(dpy, win[0]); + glXMakeCurrent(dpy, win[0], ctx); + init( use_two_windows ); + + event_loop(dpy, win, ctx); glXDestroyContext(dpy, ctx); - XDestroyWindow(dpy, win); + XDestroyWindow(dpy, win[0]); + if ( win[1] != None ) { + XDestroyWindow(dpy, win[1]); + } XCloseDisplay(dpy); return 0;