diff options
Diffstat (limited to 'src/gallium/state_trackers/glx/xlib/xm_api.c')
-rw-r--r-- | src/gallium/state_trackers/glx/xlib/xm_api.c | 249 |
1 files changed, 101 insertions, 148 deletions
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c index fb314f3b52..f4d7133d2f 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.c +++ b/src/gallium/state_trackers/glx/xlib/xm_api.c @@ -35,10 +35,6 @@ * corner of the window. Therefore, most drawing functions in this * file have to flip Y coordinates. * - * Define USE_XSHM in the Makefile with -DUSE_XSHM if you want to compile - * in support for the MIT Shared Memory extension. If enabled, when you - * use an Ximage for the back buffer in double buffered mode, the "swap" - * operation will be faster. You must also link with -lXext. * * Byte swapping: If the Mesa host and the X display use a different * byte order then there's some trickiness to be aware of when using @@ -67,11 +63,7 @@ #include "pipe/p_screen.h" #include "pipe/p_context.h" -#include "trace/tr_screen.h" -#include "trace/tr_context.h" -#include "trace/tr_texture.h" - -#include "xm_winsys.h" +#include "xm_public.h" #include <GL/glx.h> @@ -91,7 +83,6 @@ void xmesa_set_driver( const struct xm_driver *templ ) */ pipe_mutex _xmesa_lock; -static struct pipe_screen *_screen = NULL; static struct pipe_screen *screen = NULL; @@ -111,41 +102,6 @@ static int host_byte_order( void ) } -/** - * Check if the X Shared Memory extension is available. - * Return: 0 = not available - * 1 = shared XImage support available - * 2 = shared Pixmap support available also - */ -int xmesa_check_for_xshm( Display *display ) -{ -#if defined(USE_XSHM) - int major, minor, ignore; - Bool pixmaps; - - if (getenv("SP_NO_RAST")) - return 0; - - if (getenv("MESA_NOSHM")) { - return 0; - } - - if (XQueryExtension( display, "MIT-SHM", &ignore, &ignore, &ignore )) { - if (XShmQueryVersion( display, &major, &minor, &pixmaps )==True) { - return (pixmaps==True) ? 2 : 1; - } - else { - return 0; - } - } - else { - return 0; - } -#else - /* No XSHM support */ - return 0; -#endif -} /** @@ -175,7 +131,7 @@ bits_per_pixel( XMesaVisual xmv ) /* grab the bits/pixel value */ bitsPerPixel = img->bits_per_pixel; /* free the XImage */ - _mesa_free( img->data ); + free( img->data ); img->data = NULL; XDestroyImage( img ); return bitsPerPixel; @@ -242,7 +198,7 @@ xmesa_get_window_size(Display *dpy, XMesaBuffer b, pipe_mutex_lock(_xmesa_lock); XSync(b->xm_visual->display, 0); /* added for Chromium */ - stat = get_drawable_size(dpy, b->drawable, width, height); + stat = get_drawable_size(dpy, b->ws.drawable, width, height); pipe_mutex_unlock(_xmesa_lock); if (!stat) { @@ -274,10 +230,10 @@ choose_pixel_format(XMesaVisual v) && v->BitsPerPixel == 32) { if (native_byte_order) { /* no byteswapping needed */ - return 0 /* PIXEL_FORMAT_U_A8_B8_G8_R8 */; + return PIPE_FORMAT_R8G8B8A8_UNORM; } else { - return PIPE_FORMAT_R8G8B8A8_UNORM; + return PIPE_FORMAT_A8B8G8R8_UNORM; } } else if ( GET_REDMASK(v) == 0xff0000 @@ -286,10 +242,10 @@ choose_pixel_format(XMesaVisual v) && v->BitsPerPixel == 32) { if (native_byte_order) { /* no byteswapping needed */ - return PIPE_FORMAT_A8R8G8B8_UNORM; + return PIPE_FORMAT_B8G8R8A8_UNORM; } else { - return PIPE_FORMAT_B8G8R8A8_UNORM; + return PIPE_FORMAT_A8R8G8B8_UNORM; } } else if ( GET_REDMASK(v) == 0x0000ff00 @@ -298,10 +254,10 @@ choose_pixel_format(XMesaVisual v) && v->BitsPerPixel == 32) { if (native_byte_order) { /* no byteswapping needed */ - return PIPE_FORMAT_B8G8R8A8_UNORM; + return PIPE_FORMAT_A8R8G8B8_UNORM; } else { - return PIPE_FORMAT_A8R8G8B8_UNORM; + return PIPE_FORMAT_B8G8R8A8_UNORM; } } else if ( GET_REDMASK(v) == 0xf800 @@ -310,7 +266,7 @@ choose_pixel_format(XMesaVisual v) && native_byte_order && v->BitsPerPixel == 16) { /* 5-6-5 RGB */ - return PIPE_FORMAT_R5G6B5_UNORM; + return PIPE_FORMAT_B5G6R5_UNORM; } assert(0); @@ -319,6 +275,51 @@ choose_pixel_format(XMesaVisual v) +/** + * Query the default gallium screen for a Z/Stencil format that + * at least matches the given depthBits and stencilBits. + */ +static void +xmesa_choose_z_stencil_format(int depthBits, int stencilBits, + enum pipe_format *depthFormat, + enum pipe_format *stencilFormat) +{ + const enum pipe_texture_target target = PIPE_TEXTURE_2D; + const unsigned tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL; + const unsigned geom_flags = (PIPE_TEXTURE_GEOM_NON_SQUARE | + PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO); + static enum pipe_format formats[] = { + PIPE_FORMAT_S8Z24_UNORM, + PIPE_FORMAT_Z24S8_UNORM, + PIPE_FORMAT_Z16_UNORM, + PIPE_FORMAT_Z32_UNORM + }; + int i; + + assert(screen); + + *depthFormat = *stencilFormat = PIPE_FORMAT_NONE; + + /* search for supported format */ + for (i = 0; i < Elements(formats); i++) { + if (screen->is_format_supported(screen, formats[i], + target, tex_usage, geom_flags)) { + *depthFormat = formats[i]; + break; + } + } + + if (stencilBits) { + *stencilFormat = *depthFormat; + } + + /* XXX we should check that he chosen format has at least as many bits + * as what was requested. + */ +} + + + /**********************************************************************/ /***** Linked list of XMesaBuffers *****/ /**********************************************************************/ @@ -352,7 +353,9 @@ create_xmesa_buffer(Drawable d, BufferType type, if (!b) return NULL; - b->drawable = d; + b->ws.drawable = d; + b->ws.visual = vis->visinfo->visual; + b->ws.depth = vis->visinfo->depth; b->xm_visual = vis; b->type = type; @@ -361,34 +364,9 @@ create_xmesa_buffer(Drawable d, BufferType type, /* determine PIPE_FORMATs for buffers */ colorFormat = choose_pixel_format(vis); - if (vis->mesa_visual.depthBits == 0) - depthFormat = PIPE_FORMAT_NONE; -#ifdef GALLIUM_CELL /* XXX temporary for Cell! */ - else - depthFormat = PIPE_FORMAT_S8Z24_UNORM; -#else - else if (vis->mesa_visual.depthBits <= 16) - depthFormat = PIPE_FORMAT_Z16_UNORM; - else if (vis->mesa_visual.depthBits <= 24) - depthFormat = PIPE_FORMAT_S8Z24_UNORM; - else - depthFormat = PIPE_FORMAT_Z32_UNORM; -#endif - - if (vis->mesa_visual.stencilBits == 8) { - if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) - stencilFormat = depthFormat; - else - stencilFormat = PIPE_FORMAT_S8_UNORM; - } - else { - /* no stencil */ - stencilFormat = PIPE_FORMAT_NONE; - if (depthFormat == PIPE_FORMAT_S8Z24_UNORM) { - /* use 24-bit Z, undefined stencil channel */ - depthFormat = PIPE_FORMAT_X8Z24_UNORM; - } - } + xmesa_choose_z_stencil_format(vis->mesa_visual.depthBits, + vis->mesa_visual.stencilBits, + &depthFormat, &stencilFormat); get_drawable_size(vis->display, d, &width, &height); @@ -402,18 +380,6 @@ create_xmesa_buffer(Drawable d, BufferType type, (void *) b); fb = &b->stfb->Base; - /* - * Create scratch XImage for xmesa_display_surface() - */ - b->tempImage = XCreateImage(vis->display, - vis->visinfo->visual, - vis->visinfo->depth, - ZPixmap, 0, /* format, offset */ - NULL, /* data */ - 0, 0, /* size */ - 32, /* bitmap_pad */ - 0); /* bytes_per_line */ - /* GLX_EXT_texture_from_pixmap */ b->TextureTarget = 0; b->TextureFormat = GLX_TEXTURE_FORMAT_NONE_EXT; @@ -470,16 +436,11 @@ xmesa_free_buffer(XMesaBuffer buffer) /* Since the X window for the XMesaBuffer is going away, we don't * want to dereference this pointer in the future. */ - b->drawable = 0; - - buffer->tempImage->data = NULL; - XDestroyImage(buffer->tempImage); + b->ws.drawable = 0; /* Unreference. If count = zero we'll really delete the buffer */ _mesa_reference_framebuffer(&fb, NULL); - XFreeGC(b->xm_visual->display, b->gc); - free(buffer); return; @@ -550,25 +511,10 @@ initialize_visual_and_buffer(XMesaVisual v, XMesaBuffer b, * reports bugs. */ if (_mesa_getenv("MESA_INFO")) { - _mesa_printf("X/Mesa visual = %p\n", (void *) v); - _mesa_printf("X/Mesa level = %d\n", v->mesa_visual.level); - _mesa_printf("X/Mesa depth = %d\n", v->visinfo->depth); - _mesa_printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel); - } - - if (b && window) { - /* these should have been set in create_xmesa_buffer */ - ASSERT(b->drawable == window); - - /* Setup for single/double buffering */ - if (v->mesa_visual.doubleBufferMode) { - /* Double buffered */ - b->shm = xmesa_check_for_xshm( v->display ); - } - - /* X11 graphics context */ - b->gc = XCreateGC( v->display, window, 0, NULL ); - XSetFunction( v->display, b->gc, GXcopy ); + printf("X/Mesa visual = %p\n", (void *) v); + printf("X/Mesa level = %d\n", v->mesa_visual.level); + printf("X/Mesa depth = %d\n", v->visinfo->depth); + printf("X/Mesa bits per pixel = %d\n", v->BitsPerPixel); } return GL_TRUE; @@ -653,6 +599,8 @@ XMesaVisual XMesaCreateVisual( Display *display, XMesaVisual v; GLint red_bits, green_bits, blue_bits, alpha_bits; + xmesa_init( display ); + /* For debugging only */ if (_mesa_getenv("MESA_XSYNC")) { /* This makes debugging X easier. @@ -669,16 +617,16 @@ XMesaVisual XMesaCreateVisual( Display *display, v->display = display; - /* Save a copy of the XVisualInfo struct because the user may X_mesa_free() + /* Save a copy of the XVisualInfo struct because the user may Xfree() * the struct but we may need some of the information contained in it * at a later time. */ v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo)); if (!v->visinfo) { - _mesa_free(v); + free(v); return NULL; } - MEMCPY(v->visinfo, visinfo, sizeof(*visinfo)); + memcpy(v->visinfo, visinfo, sizeof(*visinfo)); v->ximage_flag = ximage_flag; @@ -724,10 +672,9 @@ XMesaVisual XMesaCreateVisual( Display *display, } _mesa_initialize_visual( &v->mesa_visual, - rgb_flag, db_flag, stereo_flag, + db_flag, stereo_flag, red_bits, green_bits, blue_bits, alpha_bits, - v->mesa_visual.indexBits, depth_size, stencil_size, accum_red_size, accum_green_size, @@ -743,11 +690,25 @@ XMesaVisual XMesaCreateVisual( Display *display, PUBLIC void XMesaDestroyVisual( XMesaVisual v ) { - _mesa_free(v->visinfo); - _mesa_free(v); + free(v->visinfo); + free(v); } +/** + * Do one-time initializations. + */ +void +xmesa_init( Display *display ) +{ + static GLboolean firstTime = GL_TRUE; + if (firstTime) { + pipe_mutex_init(_xmesa_lock); + screen = driver.create_pipe_screen( display ); + firstTime = GL_FALSE; + } +} + /** * Create a new XMesaContext. @@ -759,18 +720,12 @@ void XMesaDestroyVisual( XMesaVisual v ) PUBLIC XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list ) { - static GLboolean firstTime = GL_TRUE; struct pipe_context *pipe = NULL; XMesaContext c; GLcontext *mesaCtx; uint pf; - if (firstTime) { - pipe_mutex_init(_xmesa_lock); - _screen = driver.create_pipe_screen(); - screen = trace_screen_create( _screen ); - firstTime = GL_FALSE; - } + xmesa_init( v->display ); /* Note: the XMesaContext contains a Mesa GLcontext struct (inheritance) */ c = (XMesaContext) CALLOC_STRUCT(xmesa_context); @@ -811,7 +766,7 @@ fail: else if (pipe) pipe->destroy(pipe); - _mesa_free(c); + free(c); return NULL; } @@ -828,7 +783,7 @@ void XMesaDestroyContext( XMesaContext c ) screen->destroy(screen); */ - _mesa_free(c); + free(c); } @@ -1065,7 +1020,8 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, c->xm_buffer = drawBuffer; c->xm_read_buffer = readBuffer; - st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb); + st_make_current(c->st, drawBuffer->stfb, readBuffer->stfb, + &drawBuffer->ws); xmesa_check_and_update_buffer_size(c, drawBuffer); if (readBuffer != drawBuffer) @@ -1076,7 +1032,7 @@ GLboolean XMesaMakeCurrent2( XMesaContext c, XMesaBuffer drawBuffer, } else { /* Detach */ - st_make_current( NULL, NULL, NULL ); + st_make_current( NULL, NULL, NULL, NULL ); } return GL_TRUE; @@ -1119,13 +1075,9 @@ void XMesaSwapBuffers( XMesaBuffer b ) st_swapbuffers(b->stfb, &frontLeftSurf, NULL); if (frontLeftSurf) { - if (_screen != screen) { - struct trace_surface *tr_surf = trace_surface( frontLeftSurf ); - struct pipe_surface *surf = tr_surf->surface; - frontLeftSurf = surf; - } - - driver.display_surface(b, frontLeftSurf); + screen->flush_frontbuffer( screen, + frontLeftSurf, + &b->ws ); } xmesa_check_and_update_buffer_size(NULL, b); @@ -1148,6 +1100,7 @@ void XMesaCopySubBuffer( XMesaBuffer b, int x, int y, int width, int height ) if (!surf_front || !surf_back) return; + assert(pipe); pipe->surface_copy(pipe, surf_front, x, y, /* dest */ surf_back, x, y, /* src */ @@ -1172,7 +1125,7 @@ XMesaBuffer XMesaFindBuffer( Display *dpy, Drawable d ) { XMesaBuffer b; for (b = XMesaBufferList; b; b = b->Next) { - if (b->drawable == d && b->xm_visual->display == dpy) { + if (b->ws.drawable == d && b->xm_visual->display == dpy) { return b; } } @@ -1206,10 +1159,10 @@ void XMesaGarbageCollect( void ) next = b->Next; if (b->xm_visual && b->xm_visual->display && - b->drawable && + b->ws.drawable && b->type == WINDOW) { XSync(b->xm_visual->display, False); - if (!window_exists( b->xm_visual->display, b->drawable )) { + if (!window_exists( b->xm_visual->display, b->ws.drawable )) { /* found a dead window, free the ancillary info */ XMesaDestroyBuffer( b ); } |