X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fx11%2Fxm_api.c;h=edaa71508fc5713f430278fabe50b1c6dba8fe31;hb=fd54564f78d4aeae2c39ada7502ec659c14b3eca;hp=24b19d8eb5ab819355b1a17eb1c7f75d5c9ad154;hpb=44fb5156bbda5e4fc1cd810fec5e50ac70ff39cf;p=mesa.git diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c index 24b19d8eb5a..edaa71508fc 100644 --- a/src/mesa/drivers/x11/xm_api.c +++ b/src/mesa/drivers/x11/xm_api.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.2 + * Version: 7.1 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -72,6 +72,7 @@ #include "imports.h" #include "macros.h" #include "renderbuffer.h" +#include "teximage.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "vbo/vbo.h" @@ -80,10 +81,6 @@ #include "tnl/t_pipeline.h" #include "drivers/common/driverfuncs.h" -#ifdef XFree86Server -#include -#endif - /** * Global X driver lock */ @@ -179,9 +176,7 @@ static int host_byte_order( void ) */ static int check_for_xshm( XMesaDisplay *display ) { -#if defined(XFree86Server) - return 0; -#elif defined(USE_XSHM) +#if defined(USE_XSHM) && !defined(XFree86Server) int major, minor, ignore; Bool pixmaps; @@ -301,6 +296,19 @@ static GLboolean window_exists( XMesaDisplay *dpy, Window win ) #endif +static Status +get_drawable_size(Display *dpy, Drawable d, GLuint *width, GLuint *height) +{ + Window root; + Status stat; + int xpos, ypos; + unsigned int w, h, bw, depth; + stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth); + *width = w; + *height = h; + return stat; +} + /** * Return the size of the window (or pixmap) that corresponds to the @@ -316,22 +324,14 @@ xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b, *width = MIN2(b->frontxrb->drawable->width, MAX_WIDTH); *height = MIN2(b->frontxrb->drawable->height, MAX_HEIGHT); #else - Window root; Status stat; - int xpos, ypos; - unsigned int w, h, bw, depth; _glthread_LOCK_MUTEX(_xmesa_lock); XSync(b->xm_visual->display, 0); /* added for Chromium */ - stat = XGetGeometry(dpy, b->frontxrb->pixmap, &root, &xpos, &ypos, - &w, &h, &bw, &depth); + stat = get_drawable_size(dpy, b->frontxrb->pixmap, width, height); _glthread_UNLOCK_MUTEX(_xmesa_lock); - if (stat) { - *width = w; - *height = h; - } - else { + if (!stat) { /* probably querying a window that's recently been destroyed */ _mesa_warning(NULL, "XGetGeometry failed!\n"); *width = *height = 1; @@ -437,6 +437,11 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, b->swAlpha, vis->mesa_visual.numAuxBuffers > 0 ); + /* GLX_EXT_texture_from_pixmap */ + b->TextureTarget = 0; + b->TextureFormat = GLX_TEXTURE_FORMAT_NONE_EXT; + b->TextureMipmap = 0; + /* insert buffer into linked list */ b->Next = XMesaBufferList; XMesaBufferList = b; @@ -976,42 +981,33 @@ setup_truecolor(XMesaVisual v, XMesaBuffer buffer, XMesaColormap cmap) && GET_BLUEMASK(v) ==0xff0000 && CHECK_BYTE_ORDER(v) && v->BitsPerPixel==32 - && sizeof(GLuint)==4 && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { /* common 32 bpp config used on SGI, Sun */ - v->undithered_pf = v->dithered_pf = PF_8A8B8G8R; - } - else if (GET_REDMASK(v) ==0xff0000 - && GET_GREENMASK(v)==0x00ff00 - && GET_BLUEMASK(v) ==0x0000ff - && CHECK_BYTE_ORDER(v) - && v->BitsPerPixel==32 - && sizeof(GLuint)==4 - && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { - /* common 32 bpp config used on Linux, HP, IBM */ - if (GET_VISUAL_DEPTH(v)==32) - v->undithered_pf = v->dithered_pf = PF_8A8R8G8B; - else - v->undithered_pf = v->dithered_pf = PF_8R8G8B; - } - else if (GET_REDMASK(v) ==0xff0000 - && GET_GREENMASK(v)==0x00ff00 - && GET_BLUEMASK(v) ==0x0000ff - && CHECK_BYTE_ORDER(v) - && v->BitsPerPixel==24 - && sizeof(GLuint)==4 - && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { - /* common packed 24 bpp config used on Linux */ - v->undithered_pf = v->dithered_pf = PF_8R8G8B24; + v->undithered_pf = v->dithered_pf = PF_8A8B8G8R; /* ABGR */ + } + else if (GET_REDMASK(v) == 0xff0000 + && GET_GREENMASK(v)== 0x00ff00 + && GET_BLUEMASK(v) == 0x0000ff + && CHECK_BYTE_ORDER(v) + && v->RedGamma == 1.0 && v->GreenGamma == 1.0 && v->BlueGamma == 1.0){ + if (v->BitsPerPixel==32) { + /* if 32 bpp, and visual indicates 8 bpp alpha channel */ + if (GET_VISUAL_DEPTH(v) == 32 && v->mesa_visual.alphaBits == 8) + v->undithered_pf = v->dithered_pf = PF_8A8R8G8B; /* ARGB */ + else + v->undithered_pf = v->dithered_pf = PF_8R8G8B; /* xRGB */ + } + else if (v->BitsPerPixel == 24) { + v->undithered_pf = v->dithered_pf = PF_8R8G8B24; /* RGB */ + } } else if (GET_REDMASK(v) ==0xf800 && GET_GREENMASK(v)==0x07e0 && GET_BLUEMASK(v) ==0x001f && CHECK_BYTE_ORDER(v) && v->BitsPerPixel==16 - && sizeof(GLushort)==2 && v->RedGamma==1.0 && v->GreenGamma==1.0 && v->BlueGamma==1.0) { - /* 5-6-5 color weight on common PC VGA boards */ + /* 5-6-5 RGB */ v->undithered_pf = PF_5R6G5B; v->dithered_pf = PF_Dither_5R6G5B; } @@ -1019,6 +1015,7 @@ setup_truecolor(XMesaVisual v, XMesaBuffer buffer, XMesaColormap cmap) && GET_GREENMASK(v)==0x1c && GET_BLUEMASK(v) ==0x03 && CHECK_FOR_HPCR(v)) { + /* 8-bit HP color recovery */ setup_8bit_hpcr( v ); } } @@ -1050,10 +1047,16 @@ setup_monochrome( XMesaVisual v, XMesaBuffer b ) * \return GL_TRUE=success, GL_FALSE=failure */ static GLboolean -initialize_visual_and_buffer(int client, XMesaVisual v, XMesaBuffer b, +initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b, GLboolean rgb_flag, XMesaDrawable window, XMesaColormap cmap) { + int client = 0; + +#ifdef XFree86Server + client = (window) ? CLIENT_ID(window->id) : 0; +#endif + ASSERT(!b || b->xm_visual == v); /* Save true bits/pixel */ @@ -1117,6 +1120,8 @@ initialize_visual_and_buffer(int client, XMesaVisual v, XMesaBuffer b, } if (b && window) { + char *data; + /* Do window-specific initializations */ /* these should have been set in create_xmesa_buffer */ @@ -1184,15 +1189,15 @@ initialize_visual_and_buffer(int client, XMesaVisual v, XMesaBuffer b, } /* Initialize the row buffer XImage for use in write_color_span() */ + data = (char*) MALLOC(MAX_WIDTH*4); #ifdef XFree86Server - b->rowimage = XMesaCreateImage(GET_VISUAL_DEPTH(v), MAX_WIDTH, 1, - (char *)MALLOC(MAX_WIDTH*4)); + b->rowimage = XMesaCreateImage(GET_VISUAL_DEPTH(v), MAX_WIDTH, 1, data); #else b->rowimage = XCreateImage( v->display, v->visinfo->visual, v->visinfo->depth, ZPixmap, 0, /*format, offset*/ - (char*) MALLOC(MAX_WIDTH*4), /*data*/ + data, /*data*/ MAX_WIDTH, 1, /*width, height*/ 32, /*bitmap_pad*/ 0 /*bytes_per_line*/ ); @@ -1322,6 +1327,7 @@ xmesa_convert_from_x_visual_type( int visualType ) * visualCaveat - ala the GLX extension, usually GLX_NONE * Return; a new XMesaVisual or 0 if error. */ +PUBLIC XMesaVisual XMesaCreateVisual( XMesaDisplay *display, XMesaVisualInfo visinfo, GLboolean rgb_flag, @@ -1359,11 +1365,6 @@ XMesaVisual XMesaCreateVisual( XMesaDisplay *display, return NULL; } - /* - * In the X server, NULL is passed in for the display. It will have - * to be set before using this visual. See XMesaSetVisualDisplay() - * below. - */ v->display = display; /* Save a copy of the XVisualInfo struct because the user may X_mesa_free() @@ -1425,7 +1426,10 @@ XMesaVisual XMesaCreateVisual( XMesaDisplay *display, v->mesa_visual.visualRating = visualCaveat; - (void) initialize_visual_and_buffer( 0, v, NULL, rgb_flag, 0, 0 ); + if (alpha_flag) + v->mesa_visual.alphaBits = 8; + + (void) initialize_visual_and_buffer( v, NULL, rgb_flag, 0, 0 ); { const int xclass = v->mesa_visual.visualType; @@ -1433,7 +1437,6 @@ XMesaVisual XMesaCreateVisual( XMesaDisplay *display, red_bits = _mesa_bitcount(GET_REDMASK(v)); green_bits = _mesa_bitcount(GET_GREENMASK(v)); blue_bits = _mesa_bitcount(GET_BLUEMASK(v)); - alpha_bits = 0; } else { /* this is an approximation */ @@ -1447,11 +1450,9 @@ XMesaVisual XMesaCreateVisual( XMesaDisplay *display, alpha_bits = 0; assert( red_bits + green_bits + blue_bits == GET_VISUAL_DEPTH(v) ); } + alpha_bits = v->mesa_visual.alphaBits; } - if (alpha_flag && alpha_bits == 0) - alpha_bits = 8; - _mesa_initialize_visual( &v->mesa_visual, rgb_flag, db_flag, stereo_flag, red_bits, green_bits, @@ -1469,12 +1470,7 @@ XMesaVisual XMesaCreateVisual( XMesaDisplay *display, } -void XMesaSetVisualDisplay( XMesaDisplay *dpy, XMesaVisual v ) -{ - v->display = dpy; -} - - +PUBLIC void XMesaDestroyVisual( XMesaVisual v ) { #ifndef XFree86Server @@ -1492,6 +1488,7 @@ void XMesaDestroyVisual( XMesaVisual v ) * lists or NULL if no sharing is wanted. * \return an XMesaContext or NULL if error. */ +PUBLIC XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) { static GLboolean firstTime = GL_TRUE; @@ -1575,15 +1572,15 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) +PUBLIC void XMesaDestroyContext( XMesaContext c ) { GLcontext *mesaCtx = &c->mesa; -#ifdef FX - XMesaBuffer xmbuf = XMESA_BUFFER(mesaCtx->DrawBuffer); - if (xmbuf && xmbuf->FXctx) - fxMesaDestroyContext(xmbuf->FXctx); +#ifdef FX + FXdestroyContext( XMESA_BUFFER(mesaCtx->DrawBuffer) ); #endif + _swsetup_DestroyContext( mesaCtx ); _swrast_DestroyContext( mesaCtx ); _tnl_DestroyContext( mesaCtx ); @@ -1599,44 +1596,33 @@ void XMesaDestroyContext( XMesaContext c ) * X window or pixmap. * \param v the window's XMesaVisual * \param w the window we're wrapping - * \param c context used to initialize the buffer if 3Dfx mode in use. * \return new XMesaBuffer or NULL if error */ -XMesaBuffer -XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c) +PUBLIC XMesaBuffer +XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w) { #ifndef XFree86Server XWindowAttributes attr; #endif -#ifdef FX - char *fxEnvVar; -#endif - int client = 0; XMesaBuffer b; XMesaColormap cmap; + int depth; assert(v); assert(w); - (void) c; /* Check that window depth matches visual depth */ #ifdef XFree86Server - client = CLIENT_ID(((XMesaDrawable)w)->id); - - if (GET_VISUAL_DEPTH(v) != ((XMesaDrawable)w)->depth) { - _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n", - GET_VISUAL_DEPTH(v), ((XMesaDrawable) w)->depth); - return NULL; - } + depth = ((XMesaDrawable)w)->depth; #else XGetWindowAttributes( v->display, w, &attr ); - - if (GET_VISUAL_DEPTH(v) != attr.depth) { + depth = attr.depth; +#endif + if (GET_VISUAL_DEPTH(v) != depth) { _mesa_warning(NULL, "XMesaCreateWindowBuffer: depth mismatch between visual (%d) and window (%d)!\n", - GET_VISUAL_DEPTH(v), attr.depth); + GET_VISUAL_DEPTH(v), depth); return NULL; } -#endif /* Find colormap */ #ifdef XFree86Server @@ -1657,101 +1643,16 @@ XMesaCreateWindowBuffer2(XMesaVisual v, XMesaWindow w, XMesaContext c) if (!b) return NULL; - if (!initialize_visual_and_buffer( client, v, b, v->mesa_visual.rgbMode, + if (!initialize_visual_and_buffer( v, b, v->mesa_visual.rgbMode, (XMesaDrawable) w, cmap )) { xmesa_free_buffer(b); return NULL; } -#ifdef FX - fxEnvVar = _mesa_getenv("MESA_GLX_FX"); - if (fxEnvVar) { - if (fxEnvVar[0]!='d') { - int attribs[100]; - int numAttribs = 0; - int hw; - if (v->mesa_visual.depthBits > 0) { - attribs[numAttribs++] = FXMESA_DEPTH_SIZE; - attribs[numAttribs++] = v->mesa_visual.depthBits; - } - if (v->mesa_visual.doubleBufferMode) { - attribs[numAttribs++] = FXMESA_DOUBLEBUFFER; - } - if (v->mesa_visual.accumRedBits > 0) { - attribs[numAttribs++] = FXMESA_ACCUM_SIZE; - attribs[numAttribs++] = v->mesa_visual.accumRedBits; - } - if (v->mesa_visual.stencilBits > 0) { - attribs[numAttribs++] = FXMESA_STENCIL_SIZE; - attribs[numAttribs++] = v->mesa_visual.stencilBits; - } - if (v->mesa_visual.alphaBits > 0) { - attribs[numAttribs++] = FXMESA_ALPHA_SIZE; - attribs[numAttribs++] = v->mesa_visual.alphaBits; - } - if (1) { - attribs[numAttribs++] = FXMESA_SHARE_CONTEXT; - attribs[numAttribs++] = (int) &(c->mesa); - } - attribs[numAttribs++] = FXMESA_NONE; - - /* [dBorca] we should take an envvar for `fxMesaSelectCurrentBoard'!!! */ - hw = fxMesaSelectCurrentBoard(0); - - /* if these fail, there's a new bug somewhere */ - ASSERT(b->mesa_buffer.Width > 0); - ASSERT(b->mesa_buffer.Height > 0); - - if ((hw == GR_SSTTYPE_VOODOO) || (hw == GR_SSTTYPE_Voodoo2)) { - b->FXctx = fxMesaCreateBestContext(0, b->mesa_buffer.Width, - b->mesa_buffer.Height, attribs); - if ((v->undithered_pf!=PF_Index) && (b->backxrb->ximage)) { - b->FXisHackUsable = b->FXctx ? GL_TRUE : GL_FALSE; - if (b->FXctx && (fxEnvVar[0]=='w' || fxEnvVar[0]=='W')) { - b->FXwindowHack = GL_TRUE; - FX_grSstControl(GR_CONTROL_DEACTIVATE); - } - else { - b->FXwindowHack = GL_FALSE; - } - } - } - else { - if (fxEnvVar[0]=='w' || fxEnvVar[0]=='W') - b->FXctx = fxMesaCreateContext(w, GR_RESOLUTION_NONE, - GR_REFRESH_75Hz, attribs); - else - b->FXctx = fxMesaCreateBestContext(0, b->mesa_buffer.Width, - b->mesa_buffer.Height, attribs); - b->FXisHackUsable = GL_FALSE; - b->FXwindowHack = GL_FALSE; - } - /* - fprintf(stderr, - "voodoo %d, wid %d height %d hack: usable %d active %d\n", - hw, b->mesa_buffer.Width, b->mesa_buffer.Height, - b->FXisHackUsable, b->FXwindowHack); - */ - } - } - else { - _mesa_warning(NULL, "WARNING: This Mesa Library includes the Glide driver but\n"); - _mesa_warning(NULL, " you have not defined the MESA_GLX_FX env. var.\n"); - _mesa_warning(NULL, " (check the README.3DFX file for more information).\n\n"); - _mesa_warning(NULL, " you can disable this message with a 'export MESA_GLX_FX=disable'.\n"); - } -#endif - return b; } -XMesaBuffer -XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w) -{ - return XMesaCreateWindowBuffer2( v, w, NULL ); -} - /** * Create a new XMesaBuffer from an X pixmap. @@ -1762,10 +1663,9 @@ XMesaCreateWindowBuffer(XMesaVisual v, XMesaWindow w) * \c GLX_DIRECT_COLOR visual for the pixmap * \returns new XMesaBuffer or NULL if error */ -XMesaBuffer +PUBLIC XMesaBuffer XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap) { - int client = 0; XMesaBuffer b; assert(v); @@ -1774,11 +1674,68 @@ XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap) if (!b) return NULL; -#ifdef XFree86Server - client = CLIENT_ID(((XMesaDrawable)p)->id); -#endif + if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode, + (XMesaDrawable) p, cmap)) { + xmesa_free_buffer(b); + return NULL; + } + + return b; +} + + +/** + * For GLX_EXT_texture_from_pixmap + */ +XMesaBuffer +XMesaCreatePixmapTextureBuffer(XMesaVisual v, XMesaPixmap p, + XMesaColormap cmap, + int format, int target, int mipmap) +{ + GET_CURRENT_CONTEXT(ctx); + XMesaBuffer b; + GLuint width, height; + + assert(v); - if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode, + b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap); + if (!b) + return NULL; + + /* get pixmap size, update framebuffer/renderbuffer dims */ + get_drawable_size(v->display, p, &width, &height); + _mesa_resize_framebuffer(NULL, &(b->mesa_buffer), width, height); + + if (target == 0) { + /* examine dims */ + if (ctx->Extensions.ARB_texture_non_power_of_two) { + target = GLX_TEXTURE_2D_EXT; + } + else if ( _mesa_bitcount(width) == 1 + && _mesa_bitcount(height) == 1) { + /* power of two size */ + if (height == 1) { + target = GLX_TEXTURE_1D_EXT; + } + else { + target = GLX_TEXTURE_2D_EXT; + } + } + else if (ctx->Extensions.NV_texture_rectangle) { + target = GLX_TEXTURE_RECTANGLE_EXT; + } + else { + /* non power of two textures not supported */ + XMesaDestroyBuffer(b); + return 0; + } + } + + b->TextureTarget = target; + b->TextureFormat = format; + b->TextureMipmap = mipmap; + + if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode, (XMesaDrawable) p, cmap)) { xmesa_free_buffer(b); return NULL; @@ -1793,10 +1750,7 @@ XMesaBuffer XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap, unsigned int width, unsigned int height) { -#ifdef XFree86Server - return 0; -#else - int client = 0; +#ifndef XFree86Server XMesaWindow root; XMesaDrawable drawable; /* X Pixmap Drawable */ XMesaBuffer b; @@ -1812,13 +1766,15 @@ XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap, if (!b) return NULL; - if (!initialize_visual_and_buffer(client, v, b, v->mesa_visual.rgbMode, + if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode, drawable, cmap)) { xmesa_free_buffer(b); return NULL; } return b; +#else + return 0; #endif } @@ -1827,7 +1783,7 @@ XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap, /* * Deallocate an XMesaBuffer structure and all related info. */ -void +PUBLIC void XMesaDestroyBuffer(XMesaBuffer b) { xmesa_free_buffer(b); @@ -1870,6 +1826,7 @@ GLboolean XMesaMakeCurrent( XMesaContext c, XMesaBuffer b ) /* * Bind buffer b to context c and make c the current rendering context. */ +PUBLIC GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, XMesaBuffer readBuffer ) { @@ -1877,15 +1834,6 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, if (!drawBuffer || !readBuffer) return GL_FALSE; /* must specify buffers! */ -#ifdef FX - if (drawBuffer->FXctx) { - fxMesaMakeCurrent(drawBuffer->FXctx); - - c->xm_buffer = drawBuffer; - - return GL_TRUE; - } -#endif if (&(c->mesa) == _mesa_get_current_context() && c->mesa.DrawBuffer == &drawBuffer->mesa_buffer && c->mesa.ReadBuffer == &readBuffer->mesa_buffer @@ -1896,6 +1844,11 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, c->xm_buffer = drawBuffer; +#ifdef FX + if (FXmakeCurrent( drawBuffer )) + return GL_TRUE; +#endif + /* Call this periodically to detect when the user has begun using * GL rendering from multiple threads. */ @@ -1983,9 +1936,13 @@ XMesaBuffer XMesaGetCurrentReadBuffer( void ) } +#ifdef XFree86Server +PUBLIC GLboolean XMesaForceCurrent(XMesaContext c) { if (c) { + _glapi_set_dispatch(c->mesa.CurrentDispatch); + if (&(c->mesa) != _mesa_get_current_context()) { _mesa_make_current(&c->mesa, c->mesa.DrawBuffer, c->mesa.ReadBuffer); } @@ -1997,6 +1954,7 @@ GLboolean XMesaForceCurrent(XMesaContext c) } +PUBLIC GLboolean XMesaLoseCurrent(XMesaContext c) { (void) c; @@ -2005,150 +1963,30 @@ GLboolean XMesaLoseCurrent(XMesaContext c) } -/* - * Switch 3Dfx support hack between window and full-screen mode. - */ -GLboolean XMesaSetFXmode( GLint mode ) +PUBLIC +GLboolean XMesaCopyContext( XMesaContext xm_src, XMesaContext xm_dst, GLuint mask ) { -#ifdef FX - const char *fx = _mesa_getenv("MESA_GLX_FX"); - if (fx && fx[0] != 'd') { - GET_CURRENT_CONTEXT(ctx); - GrHwConfiguration hw; - if (!FX_grSstQueryHardware(&hw)) { - /*fprintf(stderr, "!grSstQueryHardware\n");*/ - return GL_FALSE; - } - if (hw.num_sst < 1) { - /*fprintf(stderr, "hw.num_sst < 1\n");*/ - return GL_FALSE; - } - if (ctx) { - /* [dBorca] Hack alert: - * oh, this is sooo wrong: ctx above is - * really an fxMesaContext, not an XMesaContext - */ - XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); - if (mode == XMESA_FX_WINDOW) { - if (xmbuf->FXisHackUsable) { - FX_grSstControl(GR_CONTROL_DEACTIVATE); - xmbuf->FXwindowHack = GL_TRUE; - return GL_TRUE; - } - } - else if (mode == XMESA_FX_FULLSCREEN) { - FX_grSstControl(GR_CONTROL_ACTIVATE); - xmbuf->FXwindowHack = GL_FALSE; - return GL_TRUE; - } - else { - /* Error: Bad mode value */ - } - } - } - /*fprintf(stderr, "fallthrough\n");*/ -#else - (void) mode; -#endif - return GL_FALSE; + _mesa_copy_context(&xm_src->mesa, &xm_dst->mesa, mask); + return GL_TRUE; } +#endif /* XFree86Server */ - -#ifdef FX -/* - * Read image from VooDoo frame buffer into X/Mesa's back XImage. - */ -static void FXgetImage( XMesaBuffer b ) +#ifndef FX +GLboolean XMesaSetFXmode( GLint mode ) { - GET_CURRENT_CONTEXT(ctx); - static unsigned short pixbuf[MAX_WIDTH]; - GLuint x, y; - GLuint width, height; - XMesaContext xmesa = XMESA_CONTEXT(ctx); - -#ifdef XFree86Server - x = b->frontxrb->pixmap->x; - y = b->frontxrb->pixmap->y; - width = b->frontxrb->pixmap->width; - height = b->frontxrb->pixmap->height; - depth = b->frontxrb->pixmap->depth; -#else - xmesa_get_window_size(b->display, b, &width, &height); - x = y = 0; -#endif - if (b->mesa_buffer.Width != width || b->mesa_buffer.Height != height) { - b->mesa_buffer.Width = MIN2((int)width, b->FXctx->width); - b->mesa_buffer.Height = MIN2((int)height, b->FXctx->height); - if (b->mesa_buffer.Width & 1) - b->mesa_buffer.Width--; /* prevent odd width */ - } - - /* [dBorca] we're always in the right GR_COLORFORMAT... aren't we? */ - /* grLfbWriteColorFormat(GR_COLORFORMAT_ARGB); */ - if (b->xm_visual->undithered_pf==PF_5R6G5B) { - /* Special case: 16bpp RGB */ - grLfbReadRegion( GR_BUFFER_FRONTBUFFER, /* src buffer */ - 0, b->FXctx->height - b->mesa_buffer.Height, /*pos*/ - b->mesa_buffer.Width, b->mesa_buffer.Height, /* size */ - b->mesa_buffer.Width * sizeof(GLushort), /* stride */ - b->backxrb->ximage->data); /* dest buffer */ - } - else if (b->xm_visual->dithered_pf==PF_Dither - && GET_VISUAL_DEPTH(b->xm_visual)==8) { - /* Special case: 8bpp RGB */ - for (y=0;ymesa_buffer.Height;y++) { - GLubyte *ptr = (GLubyte*) b->backxrb->ximage->data - + b->backxrb->ximage->bytes_per_line * y; - XDITHER_SETUP(y); - - /* read row from 3Dfx frame buffer */ - grLfbReadRegion( GR_BUFFER_FRONTBUFFER, - 0, b->FXctx->height-(b->mesa_buffer.Height-y), - b->mesa_buffer.Width, 1, - 0, - pixbuf ); - - /* write to XImage back buffer */ - for (x=0;xmesa_buffer.Width;x++) { - GLubyte r = (pixbuf[x] & 0xf800) >> 8; - GLubyte g = (pixbuf[x] & 0x07e0) >> 3; - GLubyte b = (pixbuf[x] & 0x001f) << 3; - *ptr++ = XDITHER( x, r, g, b); - } - } - } - else { - /* General case: slow! */ - for (y=0;ymesa_buffer.Height;y++) { - /* read row from 3Dfx frame buffer */ - grLfbReadRegion( GR_BUFFER_FRONTBUFFER, - 0, b->FXctx->height-(b->mesa_buffer.Height-y), - b->mesa_buffer.Width, 1, - 0, - pixbuf ); - - /* write to XImage back buffer */ - for (x=0;xmesa_buffer.Width;x++) { - XMesaPutPixel(b->backxrb->ximage,x,y, - xmesa_color_to_pixel(ctx, - (pixbuf[x] & 0xf800) >> 8, - (pixbuf[x] & 0x07e0) >> 3, - (pixbuf[x] & 0x001f) << 3, - 0xff, - b->xm_visual->undithered_pf)); - } - } - } - /* grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); */ + (void) mode; + return GL_FALSE; } #endif + /* * Copy the back buffer to the front buffer. If there's no back buffer * this is a no-op. */ +PUBLIC void XMesaSwapBuffers( XMesaBuffer b ) { GET_CURRENT_CONTEXT(ctx); @@ -2166,16 +2004,10 @@ void XMesaSwapBuffers( XMesaBuffer b ) if (b->db_mode) { #ifdef FX - if (b->FXctx) { - fxMesaSwapBuffers(); - - if (b->FXwindowHack) - FXgetImage(b); - else - return; - } + if (FXswapBuffers(b)) + return; #endif - if (b->backxrb->ximage) { + if (b->backxrb->ximage) { /* Copy Ximage (back buf) from client memory to server window */ #if defined(USE_XSHM) && !defined(XFree86Server) if (b->shm) { @@ -2242,13 +2074,8 @@ void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height ) if (b->db_mode) { int yTop = b->mesa_buffer.Height - y - height; #ifdef FX - if (b->FXctx) { - fxMesaSwapBuffers(); - if (b->FXwindowHack) - FXgetImage(b); - else - return; - } + if (FXswapBuffers(b)) + return; #endif if (b->backxrb->ximage) { /* Copy Ximage from host's memory to server's window */ @@ -2426,15 +2253,6 @@ void XMesaGarbageCollect( void ) } -void XMesaReset( void ) -{ - while (XMesaBufferList) - XMesaDestroyBuffer(XMesaBufferList); - - XMesaBufferList = NULL; -} - - unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ) @@ -2498,7 +2316,7 @@ unsigned long XMesaDitherColor( XMesaContext xmesa, GLint x, GLint y, * This is typically called when the window size changes and we need * to reallocate the buffer's back/depth/stencil/accum buffers. */ -void +PUBLIC void XMesaResizeBuffers( XMesaBuffer b ) { GET_CURRENT_CONTEXT(ctx); @@ -2508,3 +2326,154 @@ XMesaResizeBuffers( XMesaBuffer b ) xmesa_check_and_update_buffer_size(xmctx, b); } + +static GLint +xbuffer_to_renderbuffer(int buffer) +{ + assert(MAX_AUX_BUFFERS <= 4); + + switch (buffer) { + case GLX_FRONT_LEFT_EXT: + return BUFFER_FRONT_LEFT; + case GLX_FRONT_RIGHT_EXT: + return BUFFER_FRONT_RIGHT; + case GLX_BACK_LEFT_EXT: + return BUFFER_BACK_LEFT; + case GLX_BACK_RIGHT_EXT: + return BUFFER_BACK_RIGHT; + case GLX_AUX0_EXT: + return BUFFER_AUX0; + case GLX_AUX1_EXT: + return BUFFER_AUX1; + case GLX_AUX2_EXT: + return BUFFER_AUX2; + case GLX_AUX3_EXT: + return BUFFER_AUX3; + case GLX_AUX4_EXT: + case GLX_AUX5_EXT: + case GLX_AUX6_EXT: + case GLX_AUX7_EXT: + case GLX_AUX8_EXT: + case GLX_AUX9_EXT: + default: + /* BadValue error */ + return -1; + } +} + + +PUBLIC void +XMesaBindTexImage(Display *dpy, XMesaBuffer drawable, int buffer, + const int *attrib_list) +{ +#if 0 + GET_CURRENT_CONTEXT(ctx); + const GLuint unit = ctx->Texture.CurrentUnit; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + struct gl_texture_object *texObj; +#endif + struct gl_renderbuffer *rb; + struct xmesa_renderbuffer *xrb; + GLint b; + XMesaImage *img; + GLboolean freeImg = GL_FALSE; + + b = xbuffer_to_renderbuffer(buffer); + if (b < 0) + return; + + if (drawable->TextureFormat == GLX_TEXTURE_FORMAT_NONE_EXT) + return; /* BadMatch error */ + + rb = drawable->mesa_buffer.Attachment[b].Renderbuffer; + if (!rb) { + /* invalid buffer */ + return; + } + xrb = xmesa_renderbuffer(rb); + +#if 0 + switch (drawable->TextureTarget) { + case GLX_TEXTURE_1D_EXT: + texObj = texUnit->Current1D; + break; + case GLX_TEXTURE_2D_EXT: + texObj = texUnit->Current2D; + break; + case GLX_TEXTURE_RECTANGLE_EXT: + texObj = texUnit->CurrentRect; + break; + default: + return; /* BadMatch error */ + } +#endif + + /* + * The following is a quick and simple way to implement + * BindTexImage. The better way is to write some new FetchTexel() + * functions which would extract texels from XImages. We'd still + * need to use XGetImage when texturing from a Pixmap (front buffer) + * but texturing from a back buffer (XImage) would avoid an image + * copy. + */ + + /* get XImage */ + if (xrb->pixmap) { + img = XGetImage(dpy, xrb->pixmap, 0, 0, rb->Width, rb->Height, + AllPlanes, ZPixmap ); + freeImg = GL_TRUE; + } + else if (xrb->ximage) { + img = xrb->ximage; + } + + /* store the XImage as a new texture image */ + if (img) { + GLenum format, type, intFormat; + if (img->bits_per_pixel == 32) { + format = GL_BGRA; + type = GL_UNSIGNED_BYTE; + intFormat = GL_RGBA; + } + else if (img->bits_per_pixel == 24) { + format = GL_BGR; + type = GL_UNSIGNED_BYTE; + intFormat = GL_RGB; + } + else if (img->bits_per_pixel == 16) { + format = GL_BGR; + type = GL_UNSIGNED_SHORT_5_6_5; + intFormat = GL_RGB; + } + else { + _mesa_problem(NULL, "Unexpected XImage format in XMesaBindTexImage"); + return; + } + if (drawable->TextureFormat == GLX_TEXTURE_FORMAT_RGBA_EXT) { + intFormat = GL_RGBA; + } + else if (drawable->TextureFormat == GLX_TEXTURE_FORMAT_RGB_EXT) { + intFormat = GL_RGB; + } + + _mesa_TexImage2D(GL_TEXTURE_2D, 0, intFormat, rb->Width, rb->Height, 0, + format, type, img->data); + + if (freeImg) { + XMesaDestroyImage(img); + } + } +} + + + +PUBLIC void +XMesaReleaseTexImage(Display *dpy, XMesaBuffer drawable, int buffer) +{ + const GLint b = xbuffer_to_renderbuffer(buffer); + if (b < 0) + return; + + /* no-op for now */ +} +