diff options
author | idr <idr> | 2004-06-09 17:28:43 +0000 |
---|---|---|
committer | idr <idr> | 2004-06-09 17:28:43 +0000 |
commit | d39737e5f4ebc582167f529526ae842dce829bbf (patch) | |
tree | cb594e8ed2fff398c66f318f7ae71410ddf9aeeb | |
parent | 3d96c1b380e06a8d1221abacf9933fbbe41ea8dc (diff) |
Initial pass at SGIX_pbuffer support. This support is for indirect
rendering ONLY. It was tested with Mesa's pbdemo and an Nvidia driver.
Both the SGIX and GLX 1.3 protocol seemed to work.
-rw-r--r-- | xc/lib/GL/glx/Imakefile | 6 | ||||
-rw-r--r-- | xc/lib/GL/glx/glx_pbuffer.c | 556 | ||||
-rw-r--r-- | xc/lib/GL/glx/glxcmds.c | 118 | ||||
-rw-r--r-- | xc/lib/GL/glx/glxextensions.c | 2 |
4 files changed, 561 insertions, 121 deletions
diff --git a/xc/lib/GL/glx/Imakefile b/xc/lib/GL/glx/Imakefile index 2c33a0e4b..5cf65fd10 100644 --- a/xc/lib/GL/glx/Imakefile +++ b/xc/lib/GL/glx/Imakefile @@ -71,7 +71,8 @@ LinkSourceFile(glapi_sparc.S, $(MESASRCDIR)/src/mesa/sparc) single2.c \ singlepix.c \ vertarr.c \ - xfont.c + xfont.c \ + glx_pbuffer.c GLX_OBJS = \ clientattrib.o \ @@ -95,7 +96,8 @@ LinkSourceFile(glapi_sparc.S, $(MESASRCDIR)/src/mesa/sparc) single2.o \ singlepix.o \ vertarr.o \ - xfont.o + xfont.o \ + glx_pbuffer.o GLX_DEFS = GlxDefines VidModeExtensionDefines diff --git a/xc/lib/GL/glx/glx_pbuffer.c b/xc/lib/GL/glx/glx_pbuffer.c new file mode 100644 index 000000000..f1288f173 --- /dev/null +++ b/xc/lib/GL/glx/glx_pbuffer.c @@ -0,0 +1,556 @@ +/* + * (C) Copyright IBM Corporation 2004 + * 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"), + * to deal in the Software without restriction, including without limitation + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/** + * \file glx_pbuffer.c + * Implementation of pbuffer related functions. + * + * \author Ian Romanick <idr@us.ibm.com> + */ + +#include <inttypes.h> +#include "glxclient.h" +#include <extutil.h> +#include <Xext.h> +#include <assert.h> +#include <string.h> +#include "glapi.h" +#include "glxextensions.h" +#include "glcontextmodes.h" + +#ifdef IN_DOXYGEN +#define GLX_PREFIX(x) x +#endif /* IN_DOXYGEN */ + +static void ChangeDrawableAttribute( Display * dpy, GLXDrawable drawable, + const CARD32 * attribs, size_t num_attribs ); + +static void DestroyPbuffer( Display * dpy, GLXDrawable drawable ); + +static GLXDrawable CreatePbuffer( Display *dpy, + const __GLcontextModes * fbconfig, unsigned int width, unsigned int height, + const int *attrib_list, GLboolean size_in_attribs ); + +static int GetDrawableAttribute( Display *dpy, GLXDrawable drawable, + int attribute, unsigned int *value ); + + +/** + * Change a drawable's attribute. + * + * This function is used to implement \c glXSelectEvent and + * \c glXSelectEventSGIX. + * + * \note + * This function dynamically determines whether to use the SGIX_pbuffer + * version of the protocol or the GLX 1.3 version of the protocol. + * + * \todo + * This function needs to be modified to work with direct-rendering drivers. + */ +static void +ChangeDrawableAttribute( Display * dpy, GLXDrawable drawable, + const CARD32 * attribs, size_t num_attribs ) +{ + __GLXdisplayPrivate *priv = __glXInitialize(dpy); + CARD32 * output; + + + if ( (dpy == NULL) || (drawable == 0) ) { + return; + } + + + LockDisplay(dpy); + + if ( (priv->majorVersion > 1) || (priv->minorVersion >= 3) ) { + xGLXChangeDrawableAttributesReq *req; + + GetReqExtra( GLXChangeDrawableAttributes, 8 + (8 * num_attribs), req ); + output = (CARD32 *) (req + 1); + + req->reqType = __glXSetupForCommand(dpy); + req->glxCode = X_GLXChangeDrawableAttributes; + req->drawable = drawable; + req->numAttribs = (CARD32) num_attribs; + } + else { + xGLXVendorPrivateWithReplyReq *vpreq; + + GetReqExtra( GLXVendorPrivateWithReply, 4 + (8 * num_attribs), vpreq ); + output = (CARD32 *) (vpreq + 1); + + vpreq->reqType = __glXSetupForCommand(dpy); + vpreq->glxCode = X_GLXVendorPrivateWithReply; + vpreq->vendorCode = X_GLXvop_ChangeDrawableAttributesSGIX; + + output[0] = (CARD32) drawable; + output++; + } + + (void) memcpy( output, attribs, sizeof( CARD32 ) * 2 * num_attribs ); + + UnlockDisplay(dpy); + SyncHandle(); + + return; +} + + +/** + * Destroy a pbuffer. + * + * This function is used to implement \c glXDestroyPbuffer and + * \c glXDestroyGLXPbufferSGIX. + * + * \note + * This function dynamically determines whether to use the SGIX_pbuffer + * version of the protocol or the GLX 1.3 version of the protocol. + * + * \todo + * This function needs to be modified to work with direct-rendering drivers. + */ +static void +DestroyPbuffer( Display * dpy, GLXDrawable drawable ) +{ + __GLXdisplayPrivate *priv = __glXInitialize(dpy); + + if ( (dpy == NULL) || (drawable == 0) ) { + return; + } + + + LockDisplay(dpy); + + if ( (priv->majorVersion > 1) || (priv->minorVersion >= 3) ) { + xGLXDestroyPbufferReq * req; + + GetReqExtra( GLXDestroyPbuffer, 4, req ); + req->reqType = __glXSetupForCommand(dpy); + req->glxCode = X_GLXDestroyPbuffer; + req->pbuffer = (GLXPbuffer) drawable; + } + else { + xGLXVendorPrivateWithReplyReq *vpreq; + CARD32 * data; + + GetReqExtra( GLXVendorPrivateWithReply, 4, vpreq ); + data = (CARD32 *) (vpreq + 1); + + data[0] = (CARD32) drawable; + + vpreq->reqType = __glXSetupForCommand(dpy); + vpreq->glxCode = X_GLXVendorPrivateWithReply; + vpreq->vendorCode = X_GLXvop_DestroyGLXPbufferSGIX; + } + + UnlockDisplay(dpy); + SyncHandle(); + + return; +} + + +/** + * Get a drawable's attribute. + * + * This function is used to implement \c glXGetSelectedEvent and + * \c glXGetSelectedEventSGIX. + * + * \note + * This function dynamically determines whether to use the SGIX_pbuffer + * version of the protocol or the GLX 1.3 version of the protocol. + * + * \todo + * The number of attributes returned is likely to be small, probably less than + * 10. Given that, this routine should try to use an array on the stack to + * capture the reply rather than always calling Xmalloc. + * + * \todo + * This function needs to be modified to work with direct-rendering drivers. + */ +static int +GetDrawableAttribute( Display *dpy, GLXDrawable drawable, + int attribute, unsigned int *value ) +{ + __GLXdisplayPrivate *priv = __glXInitialize(dpy); + xGLXGetDrawableAttributesReply reply; + CARD32 * data; + unsigned int length; + unsigned int i; + unsigned int num_attributes; + GLboolean use_glx_1_3 = ((priv->majorVersion > 1) + || (priv->minorVersion >= 3)); + + + if ( (dpy == NULL) || (drawable == 0) ) { + return 0; + } + + + LockDisplay(dpy); + + if ( use_glx_1_3 ) { + xGLXGetDrawableAttributesReq *req; + + GetReqExtra( GLXGetDrawableAttributes, 4, req ); + req->reqType = __glXSetupForCommand(dpy); + req->glxCode = X_GLXGetDrawableAttributes; + req->drawable = drawable; + } + else { + xGLXVendorPrivateWithReplyReq *vpreq; + + GetReqExtra( GLXVendorPrivateWithReply, 4, vpreq ); + data = (CARD32 *) (vpreq + 1); + data[0] = (CARD32) drawable; + + vpreq->reqType = __glXSetupForCommand(dpy); + vpreq->glxCode = X_GLXVendorPrivateWithReply; + vpreq->vendorCode = X_GLXvop_GetDrawableAttributesSGIX; + } + + _XReply(dpy, (xReply*) &reply, 0, False); + + length = reply.length; + num_attributes = (use_glx_1_3) ? reply.numAttribs : length / 2; + data = (CARD32 *) Xmalloc( length * sizeof(CARD32) ); + if ( data == NULL ) { + /* Throw data on the floor */ + _XEatData(dpy, length); + } else { + _XRead(dpy, (char *)data, length * sizeof(CARD32) ); + } + + UnlockDisplay(dpy); + SyncHandle(); + + + /* Search the set of returned attributes for the attribute requested by + * the caller. + */ + + for ( i = 0 ; i < num_attributes ; i++ ) { + if ( data[i*2] == attribute ) { + *value = data[ (i*2) + 1 ]; + break; + } + } + + Xfree( data ); + + return 0; +} + + +/** + * Create a non-pbuffer GLX drawable. + * + * \todo + * This function needs to be modified to work with direct-rendering drivers. + */ +static GLXDrawable +CreateDrawable( Display *dpy, const __GLcontextModes * fbconfig, + Drawable drawable, const int *attrib_list, + CARD8 glxCode ) +{ + xGLXCreateWindowReq * req; + CARD32 * data; + unsigned int i; + + + for ( i = 0 ; attrib_list[i * 2] != None ; i++ ) + /* empty */ ; + + LockDisplay(dpy); + GetReqExtra( GLXCreateWindow, 20 + (8 * i), req ); + data = (CARD32 *) (req + 1); + + req->reqType = __glXSetupForCommand(dpy); + req->glxCode = glxCode; + req->screen = (CARD32) fbconfig->screen; + req->fbconfig = fbconfig->fbconfigID; + req->window = (GLXPbuffer) drawable; + req->numAttribs = (CARD32) i; + + UnlockDisplay(dpy); + SyncHandle(); + + return drawable; +} + + +/** + * Destroy a non-pbuffer GLX drawable. + * + * \todo + * This function needs to be modified to work with direct-rendering drivers. + */ +static void +DestroyDrawable( Display * dpy, GLXDrawable drawable, CARD32 glxCode ) +{ + xGLXDestroyPbufferReq * req; + + if ( (dpy == NULL) || (drawable == 0) ) { + return; + } + + + LockDisplay(dpy); + + GetReqExtra( GLXDestroyPbuffer, 4, req ); + req->reqType = __glXSetupForCommand(dpy); + req->glxCode = glxCode; + req->pbuffer = (GLXPbuffer) drawable; + + UnlockDisplay(dpy); + SyncHandle(); + + return; +} + + +/** + * Create a pbuffer. + * + * This function is used to implement \c glXCreatePbuffer and + * \c glXCreateGLXPbufferSGIX. + * + * \note + * This function dynamically determines whether to use the SGIX_pbuffer + * version of the protocol or the GLX 1.3 version of the protocol. + * + * \todo + * This function needs to be modified to work with direct-rendering drivers. + */ +static GLXDrawable +CreatePbuffer( Display *dpy, const __GLcontextModes * fbconfig, + unsigned int width, unsigned int height, + const int *attrib_list, GLboolean size_in_attribs ) +{ + __GLXdisplayPrivate *priv = __glXInitialize(dpy); + GLXDrawable id = 0; + CARD32 * data; + unsigned int i; + + + for ( i = 0 ; attrib_list[i * 2] != None ; i++ ) + /* empty */ ; + + + LockDisplay(dpy); + id = XAllocID(dpy); + + if ( (priv->majorVersion > 1) || (priv->minorVersion >= 3) ) { + xGLXCreatePbufferReq * req; + unsigned int extra = (size_in_attribs) ? 0 : 2; + + GetReqExtra( GLXCreatePbuffer, (8 * (i + extra)), req ); + data = (CARD32 *) (req + 1); + + req->reqType = __glXSetupForCommand(dpy); + req->glxCode = X_GLXCreatePbuffer; + req->screen = (CARD32) fbconfig->screen; + req->fbconfig = fbconfig->fbconfigID; + req->pbuffer = (GLXPbuffer) id; + req->numAttribs = (CARD32) (i + extra); + + if ( ! size_in_attribs ) { + data[(2 * i) + 0] = GLX_PBUFFER_WIDTH; + data[(2 * i) + 1] = width; + data[(2 * i) + 2] = GLX_PBUFFER_HEIGHT; + data[(2 * i) + 3] = height; + data += 4; + } + } + else { + xGLXVendorPrivateReq *vpreq; + + GetReqExtra( GLXVendorPrivate, 20 + (8 * i), vpreq ); + data = (CARD32 *) (vpreq + 1); + + vpreq->reqType = __glXSetupForCommand(dpy); + vpreq->glxCode = X_GLXVendorPrivate; + vpreq->vendorCode = X_GLXvop_CreateGLXPbufferSGIX; + + data[0] = (CARD32) fbconfig->screen; + data[1] = (CARD32) fbconfig->fbconfigID; + data[2] = (CARD32) id; + data[3] = (CARD32) width; + data[4] = (CARD32) height; + data += 5; + } + + (void) memcpy( data, attrib_list, sizeof(CARD32) * 2 * i ); + + UnlockDisplay(dpy); + SyncHandle(); + + return id; +} + + +/** + * Create a new pbuffer. + */ +GLXPbufferSGIX +GLX_PREFIX(glXCreateGLXPbufferSGIX)(Display *dpy, GLXFBConfigSGIX config, + unsigned int width, unsigned int height, + int *attrib_list) +{ + return (GLXPbufferSGIX) CreatePbuffer( dpy, (__GLcontextModes *) config, + width, height, + attrib_list, GL_FALSE ); +} + + +/** + * Create a new pbuffer. + */ +GLXPbuffer +GLX_PREFIX(glXCreatePbuffer)(Display *dpy, GLXFBConfig config, + const int *attrib_list) +{ + return (GLXPbuffer) CreatePbuffer( dpy, (__GLcontextModes *) config, + 0, 0, + attrib_list, GL_TRUE ); +} + + +/** + * Destroy an existing pbuffer. + */ +void +GLX_PREFIX(glXDestroyPbuffer)(Display *dpy, GLXPbuffer pbuf) +{ + DestroyPbuffer( dpy, pbuf ); +} + + +/** + * Query an attribute of a drawable. + */ +void +GLX_PREFIX(glXQueryDrawable)(Display *dpy, GLXDrawable drawable, + int attribute, unsigned int *value) +{ + GetDrawableAttribute( dpy, drawable, attribute, value ); +} + + +/** + * Query an attribute of a pbuffer. + */ +int +GLX_PREFIX(glXQueryGLXPbufferSGIX)(Display *dpy, GLXPbufferSGIX drawable, + int attribute, unsigned int *value) +{ + return GetDrawableAttribute( dpy, drawable, attribute, value ); +} + + +/** + * Select the event mask for a drawable. + */ +void +GLX_PREFIX(glXSelectEvent)(Display *dpy, GLXDrawable drawable, + unsigned long mask) +{ + CARD32 attribs[2]; + + attribs[0] = (CARD32) GLX_EVENT_MASK; + attribs[1] = (CARD32) mask; + + ChangeDrawableAttribute( dpy, drawable, attribs, 1 ); +} + + +/** + * Get the selected event mask for a drawable. + */ +void +GLX_PREFIX(glXGetSelectedEvent)(Display *dpy, GLXDrawable drawable, + unsigned long *mask) +{ + unsigned int value; + + + /* The non-sense with value is required because on LP64 platforms + * sizeof(unsigned int) != sizeof(unsigned long). On little-endian + * we could just type-cast the pointer, but why? + */ + + GetDrawableAttribute( dpy, drawable, GLX_EVENT_MASK_SGIX, & value ); + *mask = value; +} + + +GLXPixmap +GLX_PREFIX(glXCreatePixmap)( Display *dpy, GLXFBConfig config, Pixmap pixmap, + const int *attrib_list ) +{ + return CreateDrawable( dpy, (__GLcontextModes *) config, + (Drawable) pixmap, attrib_list, + X_GLXCreatePixmap ); +} + + +GLXWindow +GLX_PREFIX(glXCreateWindow)( Display *dpy, GLXFBConfig config, Window win, + const int *attrib_list ) +{ + return CreateDrawable( dpy, (__GLcontextModes *) config, + (Drawable) win, attrib_list, + X_GLXCreateWindow ); +} + + +void +GLX_PREFIX(glXDestroyPixmap)(Display *dpy, GLXPixmap pixmap) +{ + DestroyDrawable( dpy, (GLXDrawable) pixmap, X_GLXDestroyPixmap ); +} + + +void +GLX_PREFIX(glXDestroyWindow)(Display *dpy, GLXWindow win) +{ + DestroyDrawable( dpy, (GLXDrawable) win, X_GLXDestroyWindow ); +} + + +GLX_ALIAS(void, glXDestroyGLXPbufferSGIX, + (Display *dpy, GLXPbufferSGIX pbuf), + (dpy, pbuf), + glXDestroyPbuffer) + +GLX_ALIAS(void, glXSelectEventSGIX, + (Display *dpy, GLXDrawable drawable, unsigned long mask), + (dpy, drawable, mask), + glXSelectEvent) + +GLX_ALIAS(void, glXGetSelectedEventSGIX, + (Display *dpy, GLXDrawable drawable, unsigned long *mask), + (dpy, drawable, mask), + glXGetSelectedEvent) diff --git a/xc/lib/GL/glx/glxcmds.c b/xc/lib/GL/glx/glxcmds.c index d62520879..6ac7e06b7 100644 --- a/xc/lib/GL/glx/glxcmds.c +++ b/xc/lib/GL/glx/glxcmds.c @@ -1864,56 +1864,6 @@ GLXContext GLX_PREFIX(glXCreateNewContext)(Display *dpy, GLXFBConfig config, int } -GLXPbuffer GLX_PREFIX(glXCreatePbuffer)(Display *dpy, GLXFBConfig config, const int *attribList) -{ - (void) dpy; - (void) config; - (void) attribList; - return 0; -} - - -GLXPixmap GLX_PREFIX(glXCreatePixmap)(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList) -{ - (void) dpy; - (void) config; - (void) pixmap; - (void) attribList; - return 0; -} - - -GLXWindow GLX_PREFIX(glXCreateWindow)(Display *dpy, GLXFBConfig config, Window win, const int *attribList) -{ - (void) dpy; - (void) config; - (void) win; - (void) attribList; - return 0; -} - - -void GLX_PREFIX(glXDestroyPbuffer)(Display *dpy, GLXPbuffer pbuf) -{ - (void) dpy; - (void) pbuf; -} - - -void GLX_PREFIX(glXDestroyPixmap)(Display *dpy, GLXPixmap pixmap) -{ - (void) dpy; - (void) pixmap; -} - - -void GLX_PREFIX(glXDestroyWindow)(Display *dpy, GLXWindow window) -{ - (void) dpy; - (void) window; -} - - GLXDrawable GLX_PREFIX(glXGetCurrentReadDrawable)(void) { GLXContext gc = __glXGetCurrentContext(); @@ -1970,14 +1920,6 @@ int GLX_PREFIX(glXGetFBConfigAttrib)(Display *dpy, GLXFBConfig config, int attri } -void GLX_PREFIX(glXGetSelectedEvent)(Display *dpy, GLXDrawable drawable, unsigned long *mask) -{ - (void) dpy; - (void) drawable; - (void) mask; -} - - XVisualInfo *GLX_PREFIX(glXGetVisualFromFBConfig)(Display *dpy, GLXFBConfig config) { XVisualInfo visualTemplate; @@ -2002,23 +1944,6 @@ int GLX_PREFIX(glXQueryContext)(Display *dpy, GLXContext ctx, int attribute, int } -void GLX_PREFIX(glXQueryDrawable)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value) -{ - (void) dpy; - (void) draw; - (void) attribute; - (void) value; -} - - -void GLX_PREFIX(glXSelectEvent)(Display *dpy, GLXDrawable drawable, unsigned long mask) -{ - (void) dpy; - (void) drawable; - (void) mask; -} - - /* ** GLX_SGI_make_current_read */ @@ -2444,49 +2369,6 @@ GLXFBConfigSGIX GLX_PREFIX(glXGetFBConfigFromVisualSGIX)(Display *dpy, XVisualIn /* -** GLX_SGIX_pbuffer -*/ -GLXPbufferSGIX GLX_PREFIX(glXCreateGLXPbufferSGIX)(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list) -{ - (void) dpy; - (void) config; - (void) width; - (void) height; - (void) attrib_list; - return 0; -} - -void GLX_PREFIX(glXDestroyGLXPbufferSGIX)(Display *dpy, GLXPbufferSGIX pbuf) -{ - (void) dpy; - (void) pbuf; -} - -int GLX_PREFIX(glXQueryGLXPbufferSGIX)(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) -{ - (void) dpy; - (void) pbuf; - (void) attribute; - (void) value; - return 0; -} - -void GLX_PREFIX(glXSelectEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long mask) -{ - (void) dpy; - (void) drawable; - (void) mask; -} - -void GLX_PREFIX(glXGetSelectedEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long *mask) -{ - (void) dpy; - (void) drawable; - (void) mask; -} - - -/* ** GLX_SGI_cushion */ void GLX_PREFIX(glXCushionSGI)(Display *dpy, Window win, float cushion) diff --git a/xc/lib/GL/glx/glxextensions.c b/xc/lib/GL/glx/glxextensions.c index c6e95d724..59598be6c 100644 --- a/xc/lib/GL/glx/glxextensions.c +++ b/xc/lib/GL/glx/glxextensions.c @@ -94,7 +94,7 @@ static const struct { { GLX(SGIS_multisample), VER(0,0), Y, Y, N, N }, { GLX(SGIX_dm_buffer), VER(0,0), N, N, N, N }, { GLX(SGIX_fbconfig), VER(1,3), Y, N, N, N }, - { GLX(SGIX_pbuffer), VER(1,3), N, N, N, N }, + { GLX(SGIX_pbuffer), VER(1,3), Y, N, N, N }, { GLX(SGIX_swap_barrier), VER(0,0), N, N, N, N }, { GLX(SGIX_swap_group), VER(0,0), N, N, N, N }, { GLX(SGIX_video_resize), VER(0,0), N, N, N, N }, |