X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fx11%2Fxm_dd.c;h=c8546236fbf3644b222a96e16149e7ddab152265;hb=a10ba38df7ac80e36db15aaae9f78e7223b2bfae;hp=4afc81484a092124ed5fc1d2845cfe84805dc408;hpb=65a66f5bc37383c00423c21baf8ba9d6771e0259;p=mesa.git diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c index 4afc81484a0..c8546236fbf 100644 --- a/src/mesa/drivers/x11/xm_dd.c +++ b/src/mesa/drivers/x11/xm_dd.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.3 + * Version: 6.5.2 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2006 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"), @@ -23,6 +23,11 @@ */ +/** + * \file xm_dd.h + * General device driver functions for Xlib driver. + */ + #include "glxheader.h" #include "bufferobj.h" #include "buffers.h" @@ -31,6 +36,7 @@ #include "depth.h" #include "drawpix.h" #include "extensions.h" +#include "framebuffer.h" #include "macros.h" #include "image.h" #include "imports.h" @@ -41,19 +47,12 @@ #include "texstore.h" #include "texformat.h" #include "xmesaP.h" -#include "array_cache/acache.h" #include "swrast/swrast.h" -#include "swrast/s_auxbuffer.h" #include "swrast/s_context.h" -#include "swrast/s_alphabuf.h" #include "swrast_setup/swrast_setup.h" #include "tnl/tnl.h" #include "tnl/t_context.h" -#ifdef XFree86Server -#include -#endif - /* @@ -90,41 +89,6 @@ const int xmesa_kernel1[16] = { }; -/* - * Return the size (width, height) of the X window for the given GLframebuffer. - * Output: width - width of buffer in pixels. - * height - height of buffer in pixels. - */ -static void -get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) -{ - /* We can do this cast because the first field in the XMesaBuffer - * struct is a GLframebuffer struct. If this weren't true, we'd - * need a pointer from the GLframebuffer to the XMesaBuffer. - */ - const XMesaBuffer xmBuffer = (XMesaBuffer) buffer; - unsigned int winwidth, winheight; -#ifdef XFree86Server - /* XFree86 GLX renderer */ - winwidth = MIN2(xmBuffer->frontbuffer->width, MAX_WIDTH); - winheight = MIN2(xmBuffer->frontbuffer->height, MAX_HEIGHT); -#else - Window root; - int winx, winy; - unsigned int bw, d; - - _glthread_LOCK_MUTEX(_xmesa_lock); - XSync(xmBuffer->xm_visual->display, 0); /* added for Chromium */ - XGetGeometry( xmBuffer->xm_visual->display, xmBuffer->frontbuffer, &root, - &winx, &winy, &winwidth, &winheight, &bw, &d ); - _glthread_UNLOCK_MUTEX(_xmesa_lock); -#endif - - *width = winwidth; - *height = winheight; -} - - static void finish_or_flush( GLcontext *ctx ) { @@ -141,87 +105,40 @@ finish_or_flush( GLcontext *ctx ) } - -/* - * This chooses the color buffer for reading and writing spans, points, - * lines, and triangles. - */ -void -xmesa_set_buffer( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit ) -{ - /* We can make this cast since the XMesaBuffer wraps GLframebuffer. - * GLframebuffer is the first member in a XMesaBuffer struct. - */ - XMesaBuffer target = (XMesaBuffer) buffer; - const XMesaContext xmesa = XMESA_CONTEXT(ctx); - - /* This assignment tells the span/point/line/triangle functions - * which XMesaBuffer to use. - */ - xmesa->xm_buffer = target; - - /* - * Now determine front vs back color buffer. - */ - if (bufferBit == DD_FRONT_LEFT_BIT) { - target->buffer = target->frontbuffer; - xmesa_update_span_funcs(ctx); - } - else if (bufferBit == DD_BACK_LEFT_BIT) { - ASSERT(target->db_state); - if (target->backpixmap) { - /* back buffer is a pixmap */ - target->buffer = (XMesaDrawable) target->backpixmap; - } - else if (target->backimage) { - /* back buffer is an XImage */ - target->buffer = None; - } - else { - /* No back buffer!!!! Must be out of memory, use front buffer */ - target->buffer = target->frontbuffer; - } - xmesa_update_span_funcs(ctx); - } - else if (bufferBit & (DD_AUX0_BIT | DD_AUX1_BIT | DD_AUX2_BIT | DD_AUX3_BIT)) { - _swrast_use_aux_buffer(ctx, buffer, bufferBit); - } - else { - _mesa_problem(ctx, "invalid buffer 0x%x in set_buffer() in xm_dd.c"); - return; - } -} - - - static void clear_index( GLcontext *ctx, GLuint index ) { - const XMesaContext xmesa = XMESA_CONTEXT(ctx); - xmesa->clearpixel = (unsigned long) index; - XMesaSetForeground( xmesa->display, xmesa->xm_draw_buffer->cleargc, - (unsigned long) index ); + if (ctx->DrawBuffer->Name == 0) { + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + xmesa->clearpixel = (unsigned long) index; + XMesaSetForeground( xmesa->display, xmbuf->cleargc, (unsigned long) index ); + } } static void clear_color( GLcontext *ctx, const GLfloat color[4] ) { - const XMesaContext xmesa = XMESA_CONTEXT(ctx); - CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color[0]); - CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color[1]); - CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color[2]); - CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color[3]); - xmesa->clearpixel = xmesa_color_to_pixel( xmesa, - xmesa->clearcolor[0], - xmesa->clearcolor[1], - xmesa->clearcolor[2], - xmesa->clearcolor[3], - xmesa->xm_visual->undithered_pf ); - _glthread_LOCK_MUTEX(_xmesa_lock); - XMesaSetForeground( xmesa->display, xmesa->xm_draw_buffer->cleargc, - xmesa->clearpixel ); - _glthread_UNLOCK_MUTEX(_xmesa_lock); + if (ctx->DrawBuffer->Name == 0) { + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color[3]); + xmesa->clearpixel = xmesa_color_to_pixel( ctx, + xmesa->clearcolor[0], + xmesa->clearcolor[1], + xmesa->clearcolor[2], + xmesa->clearcolor[3], + xmesa->xm_visual->undithered_pf ); + _glthread_LOCK_MUTEX(_xmesa_lock); + XMesaSetForeground( xmesa->display, xmbuf->cleargc, + xmesa->clearpixel ); + _glthread_UNLOCK_MUTEX(_xmesa_lock); + } } @@ -231,7 +148,9 @@ static void index_mask( GLcontext *ctx, GLuint mask ) { const XMesaContext xmesa = XMESA_CONTEXT(ctx); - if (xmesa->xm_draw_buffer->buffer != XIMAGE) { + XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + /* not sure this conditional is really needed */ + if (xmbuf->backxrb && xmbuf->backxrb->pixmap) { unsigned long m; if (mask==0xffffffff) { m = ((unsigned long)~0L); @@ -239,8 +158,8 @@ index_mask( GLcontext *ctx, GLuint mask ) else { m = (unsigned long) mask; } - XMesaSetPlaneMask( xmesa->display, xmesa->xm_draw_buffer->cleargc, m ); - XMesaSetPlaneMask( xmesa->display, xmesa->xm_draw_buffer->gc, m ); + XMesaSetPlaneMask( xmesa->display, xmbuf->cleargc, m ); + XMesaSetPlaneMask( xmesa->display, xmbuf->gc, m ); } } @@ -251,9 +170,15 @@ color_mask(GLcontext *ctx, GLboolean rmask, GLboolean gmask, GLboolean bmask, GLboolean amask) { const XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaBuffer xmbuf; const int xclass = xmesa->xm_visual->mesa_visual.visualType; (void) amask; + if (ctx->DrawBuffer->Name != 0) + return; + + xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) { unsigned long m; if (rmask && gmask && bmask) { @@ -265,8 +190,8 @@ color_mask(GLcontext *ctx, if (gmask) m |= GET_GREENMASK(xmesa->xm_visual); if (bmask) m |= GET_BLUEMASK(xmesa->xm_visual); } - XMesaSetPlaneMask( xmesa->display, xmesa->xm_draw_buffer->cleargc, m ); - XMesaSetPlaneMask( xmesa->display, xmesa->xm_draw_buffer->gc, m ); + XMesaSetPlaneMask( xmesa->display, xmbuf->cleargc, m ); + XMesaSetPlaneMask( xmesa->display, xmbuf->gc, m ); } } @@ -277,164 +202,79 @@ color_mask(GLcontext *ctx, /**********************************************************************/ +/** + * Clear the front or back color buffer, if it's implemented with a pixmap. + */ static void -clear_front_pixmap( GLcontext *ctx, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) -{ - const XMesaContext xmesa = XMESA_CONTEXT(ctx); - if (all) { - XMesaFillRectangle( xmesa->display, xmesa->xm_draw_buffer->frontbuffer, - xmesa->xm_draw_buffer->cleargc, - 0, 0, - xmesa->xm_draw_buffer->mesa_buffer.Width + 1, - xmesa->xm_draw_buffer->mesa_buffer.Height + 1 ); - } - else { - XMesaFillRectangle( xmesa->display, xmesa->xm_draw_buffer->frontbuffer, - xmesa->xm_draw_buffer->cleargc, - x, xmesa->xm_draw_buffer->mesa_buffer.Height - y - height, - width, height ); - } -} - - -static void -clear_back_pixmap( GLcontext *ctx, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +clear_pixmap(GLcontext *ctx, struct xmesa_renderbuffer *xrb, + GLint x, GLint y, GLint width, GLint height) { const XMesaContext xmesa = XMESA_CONTEXT(ctx); - if (all) { - XMesaFillRectangle( xmesa->display, xmesa->xm_draw_buffer->backpixmap, - xmesa->xm_draw_buffer->cleargc, - 0, 0, - xmesa->xm_draw_buffer->mesa_buffer.Width + 1, - xmesa->xm_draw_buffer->mesa_buffer.Height + 1 ); - } - else { - XMesaFillRectangle( xmesa->display, xmesa->xm_draw_buffer->backpixmap, - xmesa->xm_draw_buffer->cleargc, - x, xmesa->xm_draw_buffer->mesa_buffer.Height - y - height, - width, height ); - } + XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + + assert(xmbuf); + assert(xrb->pixmap); + assert(xmesa); + assert(xmesa->display); + assert(xrb->pixmap); + assert(xmbuf->cleargc); + + XMesaFillRectangle( xmesa->display, xrb->pixmap, xmbuf->cleargc, + x, xrb->Base.Height - y - height, + width, height ); } static void -clear_8bit_ximage( GLcontext *ctx, GLboolean all, +clear_8bit_ximage( GLcontext *ctx, struct xmesa_renderbuffer *xrb, GLint x, GLint y, GLint width, GLint height ) { const XMesaContext xmesa = XMESA_CONTEXT(ctx); - if (all) { - size_t n = xmesa->xm_draw_buffer->backimage->bytes_per_line - * xmesa->xm_draw_buffer->backimage->height; - MEMSET( xmesa->xm_draw_buffer->backimage->data, xmesa->clearpixel, n ); - } - else { - GLint i; - for (i=0;ixm_draw_buffer, x, y+i ); - MEMSET( ptr, xmesa->clearpixel, width ); - } + GLint i; + for (i = 0; i < height; i++) { + GLubyte *ptr = PIXEL_ADDR1(xrb, x, y + i); + MEMSET( ptr, xmesa->clearpixel, width ); } } static void -clear_HPCR_ximage( GLcontext *ctx, GLboolean all, +clear_HPCR_ximage( GLcontext *ctx, struct xmesa_renderbuffer *xrb, GLint x, GLint y, GLint width, GLint height ) { const XMesaContext xmesa = XMESA_CONTEXT(ctx); - if (all) { - GLint i, c16 = (xmesa->xm_draw_buffer->backimage->bytes_per_line>>4)<<4; - GLubyte *ptr = (GLubyte *)xmesa->xm_draw_buffer->backimage->data; - for (i=0; ixm_draw_buffer->backimage->height; i++) { - GLint j; - GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0]; - if (i&1) { - sptr += 16; - } - for (j=0; jxm_draw_buffer->backimage->bytes_per_line; j++) { - *ptr = sptr[j&15]; - ptr++; - } + GLint i; + for (i = y; i < y + height; i++) { + GLubyte *ptr = PIXEL_ADDR1( xrb, x, i ); + int j; + const GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0]; + if (i & 1) { + sptr += 16; } - } - else { - GLint i; - for (i=y; ixm_draw_buffer, x, i ); - int j; - GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0]; - if (i&1) { - sptr += 16; - } - for (j=x; jclearpixel; + GLuint pixel = (GLuint) xmesa->clearpixel; + GLint i, j; + if (xmesa->swapbytes) { pixel = ((pixel >> 8) & 0x00ff) | ((pixel << 8) & 0xff00); } - if (all) { - register GLuint n; - register GLuint *ptr4 = (GLuint *) xmesa->xm_draw_buffer->backimage->data; - if ((pixel & 0xff) == ((pixel >> 8) & 0xff)) { - /* low and high bytes are equal so use memset() */ - n = xmesa->xm_draw_buffer->backimage->bytes_per_line - * xmesa->xm_draw_buffer->mesa_buffer.Height; - MEMSET( ptr4, pixel & 0xff, n ); - } - else { - pixel = pixel | (pixel<<16); - n = xmesa->xm_draw_buffer->backimage->bytes_per_line - * xmesa->xm_draw_buffer->mesa_buffer.Height / 4; - do { - *ptr4++ = pixel; - n--; - } while (n!=0); - - if ((xmesa->xm_draw_buffer->backimage->bytes_per_line * - xmesa->xm_draw_buffer->mesa_buffer.Height) & 0x2) - *(GLushort *)ptr4 = pixel & 0xffff; - } - } - else { - register int i, j; - for (j=0;jxm_draw_buffer, x, y+j ); - for (i=0;i */ static void -clear_24bit_ximage( GLcontext *ctx, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +clear_24bit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb, + GLint x, GLint y, GLint width, GLint height) { const XMesaContext xmesa = XMESA_CONTEXT(ctx); const GLubyte r = xmesa->clearcolor[0]; const GLubyte g = xmesa->clearcolor[1]; const GLubyte b = xmesa->clearcolor[2]; -#if 0 /* See below */ - register GLuint clearPixel; - if (xmesa->swapbytes) { - clearPixel = (b << 16) | (g << 8) | r; - } - else { - clearPixel = (r << 16) | (g << 8) | b; - } -#endif - if (all) { - if (r==g && g==b) { - /* same value for all three components (gray) */ - const GLint w3 = xmesa->xm_draw_buffer->mesa_buffer.Width * 3; - const GLint h = xmesa->xm_draw_buffer->mesa_buffer.Height; - GLint i; - for (i = 0; i < h; i++) { - bgr_t *ptr3 = PIXELADDR3(xmesa->xm_draw_buffer, 0, i); - MEMSET(ptr3, r, w3); - } - } - else { - /* the usual case */ - const GLint w = xmesa->xm_draw_buffer->mesa_buffer.Width; - const GLint h = xmesa->xm_draw_buffer->mesa_buffer.Height; - GLint i, j; - for (i = 0; i < h; i++) { - bgr_t *ptr3 = PIXELADDR3(xmesa->xm_draw_buffer, 0, i); - for (j = 0; j < w; j++) { - ptr3->r = r; - ptr3->g = g; - ptr3->b = b; - ptr3++; - } - } -#if 0 /* this code doesn't work for all window widths */ - register GLuint *ptr4 = (GLuint *) ptr3; - register GLuint px; - GLuint pixel4[3]; - register GLuint *p = pixel4; - pixel4[0] = clearPixel | (clearPixel << 24); - pixel4[1] = (clearPixel << 16) | (clearPixel >> 8); - pixel4[2] = (clearPixel << 8) | (clearPixel >> 16); - switch (3 & (int)(ptr3 - (bgr_t*) ptr4)){ - case 0: - break; - case 1: - px = *ptr4 & 0x00ffffff; - px |= pixel4[0] & 0xff000000; - *ptr4++ = px; - px = *ptr4 & 0xffff0000; - px |= pixel4[2] & 0x0000ffff; - *ptr4 = px; - if (0 == --n) - break; - case 2: - px = *ptr4 & 0x0000fffff; - px |= pixel4[1] & 0xffff0000; - *ptr4++ = px; - px = *ptr4 & 0xffffff00; - px |= pixel4[2] & 0x000000ff; - *ptr4 = px; - if (0 == --n) - break; - case 3: - px = *ptr4 & 0x000000ff; - px |= pixel4[2] & 0xffffff00; - *ptr4++ = px; - --n; - break; - } - while (n > 3) { - p = pixel4; - *ptr4++ = *p++; - *ptr4++ = *p++; - *ptr4++ = *p++; - n -= 4; - } - switch (n) { - case 3: - p = pixel4; - *ptr4++ = *p++; - *ptr4++ = *p++; - px = *ptr4 & 0xffffff00; - px |= clearPixel & 0xff; - *ptr4 = px; - break; - case 2: - p = pixel4; - *ptr4++ = *p++; - px = *ptr4 & 0xffff0000; - px |= *p & 0xffff; - *ptr4 = px; - break; - case 1: - px = *ptr4 & 0xff000000; - px |= *p & 0xffffff; - *ptr4 = px; - break; - case 0: - break; - } -#endif + if (r == g && g == b) { + /* same value for all three components (gray) */ + GLint j; + for (j = 0; j < height; j++) { + bgr_t *ptr3 = PIXEL_ADDR3(xrb, x, y + j); + MEMSET(ptr3, r, 3 * width); } } else { - /* only clear subrect of color buffer */ - if (r==g && g==b) { - /* same value for all three components (gray) */ - GLint j; - for (j=0;jxm_draw_buffer, x, y+j ); - MEMSET(ptr3, r, 3 * width); + /* non-gray clear color */ + GLint i, j; + for (j = 0; j < height; j++) { + bgr_t *ptr3 = PIXEL_ADDR3(xrb, x, y + j); + for (i = 0; i < width; i++) { + ptr3->r = r; + ptr3->g = g; + ptr3->b = b; + ptr3++; } } - else { - /* non-gray clear color */ - GLint i, j; - for (j = 0; j < height; j++) { - bgr_t *ptr3 = PIXELADDR3( xmesa->xm_draw_buffer, x, y+j ); - for (i = 0; i < width; i++) { - ptr3->r = r; - ptr3->g = g; - ptr3->b = b; - ptr3++; - } - } -#if 0 /* this code might not always (seems ptr3 always == ptr4) */ - GLint j; - GLuint pixel4[3]; - pixel4[0] = clearPixel | (clearPixel << 24); - pixel4[1] = (clearPixel << 16) | (clearPixel >> 8); - pixel4[2] = (clearPixel << 8) | (clearPixel >> 16); - for (j=0;jxm_draw_buffer, x, y+j ); - register GLuint *ptr4 = (GLuint *)ptr3; - register GLuint *p, px; - GLuint w = width; - switch (3 & (int)(ptr3 - (bgr_t*) ptr4)){ - case 0: - break; - case 1: - px = *ptr4 & 0x00ffffff; - px |= pixel4[0] & 0xff000000; - *ptr4++ = px; - px = *ptr4 & 0xffff0000; - px |= pixel4[2] & 0x0000ffff; - *ptr4 = px; - if (0 == --w) - break; - case 2: - px = *ptr4 & 0x0000fffff; - px |= pixel4[1] & 0xffff0000; - *ptr4++ = px; - px = *ptr4 & 0xffffff00; - px |= pixel4[2] & 0x000000ff; - *ptr4 = px; - if (0 == --w) - break; - case 3: - px = *ptr4 & 0x000000ff; - px |= pixel4[2] & 0xffffff00; - *ptr4++ = px; - --w; - break; - } - while (w > 3){ - p = pixel4; - *ptr4++ = *p++; - *ptr4++ = *p++; - *ptr4++ = *p++; - w -= 4; - } - switch (w) { - case 3: - p = pixel4; - *ptr4++ = *p++; - *ptr4++ = *p++; - px = *ptr4 & 0xffffff00; - px |= *p & 0xff; - *ptr4 = px; - break; - case 2: - p = pixel4; - *ptr4++ = *p++; - px = *ptr4 & 0xffff0000; - px |= *p & 0xffff; - *ptr4 = px; - break; - case 1: - px = *ptr4 & 0xff000000; - px |= pixel4[0] & 0xffffff; - *ptr4 = px; - break; - case 0: - break; - } - } -#endif - } } } static void -clear_32bit_ximage( GLcontext *ctx, GLboolean all, - GLint x, GLint y, GLint width, GLint height ) +clear_32bit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb, + GLint x, GLint y, GLint width, GLint height) { const XMesaContext xmesa = XMESA_CONTEXT(ctx); register GLuint pixel = (GLuint) xmesa->clearpixel; + + if (!xrb->ximage) + return; + if (xmesa->swapbytes) { pixel = ((pixel >> 24) & 0x000000ff) | ((pixel >> 8) & 0x0000ff00) | ((pixel << 8) & 0x00ff0000) | ((pixel << 24) & 0xff000000); } - if (all) { - register GLint n = xmesa->xm_draw_buffer->mesa_buffer.Width - * xmesa->xm_draw_buffer->mesa_buffer.Height; - register GLuint *ptr4 = (GLuint *) xmesa->xm_draw_buffer->backimage->data; - if (pixel==0) { - MEMSET( ptr4, pixel, 4*n ); + + if (width == xrb->Base.Width && height == xrb->Base.Height) { + /* clearing whole buffer */ + const GLuint n = xrb->Base.Width * xrb->Base.Height; + GLuint *ptr4 = (GLuint *) xrb->ximage->data; + if (pixel == 0) { + /* common case */ + _mesa_memset(ptr4, pixel, 4 * n); } else { - do { - *ptr4++ = pixel; - n--; - } while (n!=0); + GLuint i; + for (i = 0; i < n; i++) + ptr4[i] = pixel; } } else { - register int i, j; - for (j=0;jxm_draw_buffer, x, y+j ); - for (i=0;ixm_draw_buffer->backimage; - register int i, j; - - /* We can ignore 'all' here - x, y, width, height are always right */ - (void) all; + XMesaImage *img = xrb->ximage; + GLint i, j; /* TODO: optimize this */ - y = FLIP(xmesa->xm_draw_buffer, y); + y = YFLIP(xrb, y); for (j = 0; j < height; j++) { for (i = 0; i < width; i++) { XMesaPutPixel(img, x+i, y-j, xmesa->clearpixel); @@ -714,81 +378,46 @@ clear_nbit_ximage( GLcontext *ctx, GLboolean all, static void -clear_buffers( GLcontext *ctx, GLbitfield mask, - GLboolean all, GLint x, GLint y, GLint width, GLint height ) +clear_buffers(GLcontext *ctx, GLbitfield buffers) { - const XMesaContext xmesa = XMESA_CONTEXT(ctx); - const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask; - - if ((mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) && - xmesa->xm_draw_buffer->mesa_buffer.UseSoftwareAlphaBuffers && - ctx->Color.ColorMask[ACOMP]) { - _swrast_clear_alpha_buffers(ctx); - } - - /* we can't handle color or index masking */ - if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) { - if (mask & DD_FRONT_LEFT_BIT) { - ASSERT(xmesa->xm_draw_buffer->front_clear_func); - (*xmesa->xm_draw_buffer->front_clear_func)( ctx, all, x, y, width, height ); - mask &= ~DD_FRONT_LEFT_BIT; - } - if (mask & DD_BACK_LEFT_BIT) { - ASSERT(xmesa->xm_draw_buffer->back_clear_func); - (*xmesa->xm_draw_buffer->back_clear_func)( ctx, all, x, y, width, height ); - mask &= ~DD_BACK_LEFT_BIT; + if (ctx->DrawBuffer->Name == 0) { + /* this is a window system framebuffer */ + const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask; + XMesaBuffer b = XMESA_BUFFER(ctx->DrawBuffer); + const GLint x = ctx->DrawBuffer->_Xmin; + const GLint y = ctx->DrawBuffer->_Ymin; + const GLint width = ctx->DrawBuffer->_Xmax - x; + const GLint height = ctx->DrawBuffer->_Ymax - y; + + /* we can't handle color or index masking */ + if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) { + if (buffers & BUFFER_BIT_FRONT_LEFT) { + /* clear front color buffer */ + struct gl_renderbuffer *frontRb + = ctx->DrawBuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; + if (b->frontxrb == xmesa_renderbuffer(frontRb)) { + /* renderbuffer is not wrapped - great! */ + b->frontxrb->clearFunc(ctx, b->frontxrb, x, y, width, height); + buffers &= ~BUFFER_BIT_FRONT_LEFT; + } + else { + /* we can't directly clear an alpha-wrapped color buffer */ + } + } + if (buffers & BUFFER_BIT_BACK_LEFT) { + /* clear back color buffer */ + struct gl_renderbuffer *backRb + = ctx->DrawBuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer; + if (b->backxrb == xmesa_renderbuffer(backRb)) { + /* renderbuffer is not wrapped - great! */ + b->backxrb->clearFunc(ctx, b->backxrb, x, y, width, height); + buffers &= ~BUFFER_BIT_BACK_LEFT; + } + } } } - - if (mask) - _swrast_Clear( ctx, mask, all, x, y, width, height ); -} - - -/* - * When we detect that the user has resized the window this function will - * get called. Here we'll reallocate the back buffer, depth buffer, - * stencil buffer etc. to match the new window size. - * The buffer->Width and buffer->Height values will indicate the new size. - */ -void -xmesa_resize_buffers( GLframebuffer *buffer ) -{ - int height = (int) buffer->Height; - /* We can do this cast because the first field in the XMesaBuffer - * struct is a GLframebuffer struct. If this weren't true, we'd - * need a pointer from the GLframebuffer to the XMesaBuffer. - */ - XMesaBuffer xmBuffer = (XMesaBuffer) buffer; - - xmesa_alloc_back_buffer( xmBuffer ); - - /* Needed by FLIP macro */ - xmBuffer->bottom = height - 1; - - if (xmBuffer->backimage) { - /* Needed by PIXELADDR1 macro */ - xmBuffer->ximage_width1 = xmBuffer->backimage->bytes_per_line; - xmBuffer->ximage_origin1 = (GLubyte *) xmBuffer->backimage->data - + xmBuffer->ximage_width1 * (height-1); - - /* Needed by PIXELADDR2 macro */ - xmBuffer->ximage_width2 = xmBuffer->backimage->bytes_per_line / 2; - xmBuffer->ximage_origin2 = (GLushort *) xmBuffer->backimage->data - + xmBuffer->ximage_width2 * (height-1); - - /* Needed by PIXELADDR3 macro */ - xmBuffer->ximage_width3 = xmBuffer->backimage->bytes_per_line; - xmBuffer->ximage_origin3 = (GLubyte *) xmBuffer->backimage->data - + xmBuffer->ximage_width3 * (height-1); - - /* Needed by PIXELADDR4 macro */ - xmBuffer->ximage_width4 = xmBuffer->backimage->width; - xmBuffer->ximage_origin4 = (GLuint *) xmBuffer->backimage->data - + xmBuffer->ximage_width4 * (height-1); - } - - _swrast_alloc_buffers( buffer ); + if (buffers) + _swrast_Clear(ctx, buffers); } @@ -807,34 +436,37 @@ xmesa_DrawPixels_8R8G8B( GLcontext *ctx, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels ) { - const XMesaContext xmesa = XMESA_CONTEXT(ctx); const SWcontext *swrast = SWRAST_CONTEXT( ctx ); - XMesaDisplay *dpy = xmesa->xm_visual->display; - const XMesaDrawable buffer = xmesa->xm_draw_buffer->buffer; - const XMesaGC gc = xmesa->xm_draw_buffer->gc; - - ASSERT(dpy); - ASSERT(gc); - ASSERT(xmesa->xm_visual->dithered_pf == PF_8R8G8B); - ASSERT(xmesa->xm_visual->undithered_pf == PF_8R8G8B); + struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0][0]; + struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb->Wrapped); if (swrast->NewState) _swrast_validate_derived( ctx ); - if (buffer && /* buffer != 0 means it's a Window or Pixmap */ + if (ctx->DrawBuffer->Name == 0 && format == GL_BGRA && type == GL_UNSIGNED_BYTE && (swrast->_RasterMask & ~CLIP_BIT) == 0 && /* no blend, z-test, etc */ ctx->_ImageTransferState == 0 && /* no color tables, scale/bias, etc */ ctx->Pixel.ZoomX == 1.0 && /* no zooming */ - ctx->Pixel.ZoomY == 1.0) { + ctx->Pixel.ZoomY == 1.0 && + xrb->pixmap && + xrb->Base.AlphaBits == 0) + { + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + XMesaDisplay *dpy = xmesa->xm_visual->display; + const XMesaGC gc = xmbuf->gc; int dstX = x; int dstY = y; int w = width; int h = height; - int srcX = unpack->SkipPixels; - int srcY = unpack->SkipRows; - int rowLength = unpack->RowLength ? unpack->RowLength : width; + struct gl_pixelstore_attrib clippedUnpack = *unpack; + + ASSERT(xmesa->xm_visual->dithered_pf == PF_8R8G8B); + ASSERT(xmesa->xm_visual->undithered_pf == PF_8R8G8B); + ASSERT(dpy); + ASSERT(gc); if (unpack->BufferObj->Name) { /* unpack from PBO */ @@ -858,11 +490,14 @@ xmesa_DrawPixels_8R8G8B( GLcontext *ctx, pixels = ADD_POINTERS(buf, pixels); } - if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &srcX, &srcY)) { + if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &clippedUnpack)) { /* This is a little tricky since all coordinates up to now have * been in the OpenGL bottom-to-top orientation. X is top-to-bottom * so we have to carefully compute the Y coordinates/addresses here. */ + int srcX = clippedUnpack.SkipPixels; + int srcY = clippedUnpack.SkipRows; + int rowLength = clippedUnpack.RowLength; XMesaImage ximage; MEMSET(&ximage, 0, sizeof(XMesaImage)); ximage.width = width; @@ -879,8 +514,8 @@ xmesa_DrawPixels_8R8G8B( GLcontext *ctx, ximage.bits_per_pixel = 32; /* it seems we don't need to set the ximage.red/green/blue_mask fields */ /* flip Y axis for dest position */ - dstY = FLIP(xmesa->xm_draw_buffer, dstY) - h + 1; - XPutImage(dpy, buffer, gc, &ximage, 0, 0, dstX, dstY, w, h); + dstY = YFLIP(xrb, dstY) - h + 1; + XPutImage(dpy, xrb->pixmap, gc, &ximage, 0, 0, dstX, dstY, w, h); } if (unpack->BufferObj->Name) { @@ -910,11 +545,13 @@ xmesa_DrawPixels_5R6G5B( GLcontext *ctx, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels ) { + struct xmesa_renderbuffer *xrb + = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped); const XMesaContext xmesa = XMESA_CONTEXT(ctx); const SWcontext *swrast = SWRAST_CONTEXT( ctx ); XMesaDisplay *dpy = xmesa->xm_visual->display; - const XMesaDrawable buffer = xmesa->xm_draw_buffer->buffer; - const XMesaGC gc = xmesa->xm_draw_buffer->gc; + XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + const XMesaGC gc = xmbuf->gc; ASSERT(dpy); ASSERT(gc); @@ -923,7 +560,7 @@ xmesa_DrawPixels_5R6G5B( GLcontext *ctx, if (swrast->NewState) _swrast_validate_derived( ctx ); - if (buffer && /* buffer != 0 means it's a Window or Pixmap */ + if (xrb->pixmap && format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 && !ctx->Color.DitherFlag && /* no dithering */ @@ -935,9 +572,7 @@ xmesa_DrawPixels_5R6G5B( GLcontext *ctx, int dstY = y; int w = width; int h = height; - int srcX = unpack->SkipPixels; - int srcY = unpack->SkipRows; - int rowLength = unpack->RowLength ? unpack->RowLength : width; + struct gl_pixelstore_attrib clippedUnpack = *unpack; if (unpack->BufferObj->Name) { /* unpack from PBO */ @@ -961,11 +596,14 @@ xmesa_DrawPixels_5R6G5B( GLcontext *ctx, pixels = ADD_POINTERS(buf, pixels); } - if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &srcX, &srcY)) { + if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &clippedUnpack)) { /* This is a little tricky since all coordinates up to now have * been in the OpenGL bottom-to-top orientation. X is top-to-bottom * so we have to carefully compute the Y coordinates/addresses here. */ + int srcX = clippedUnpack.SkipPixels; + int srcY = clippedUnpack.SkipRows; + int rowLength = clippedUnpack.RowLength; XMesaImage ximage; MEMSET(&ximage, 0, sizeof(XMesaImage)); ximage.width = width; @@ -982,8 +620,8 @@ xmesa_DrawPixels_5R6G5B( GLcontext *ctx, ximage.bits_per_pixel = 16; /* it seems we don't need to set the ximage.red/green/blue_mask fields */ /* flip Y axis for dest position */ - dstY = FLIP(xmesa->xm_draw_buffer, dstY) - h + 1; - XPutImage(dpy, buffer, gc, &ximage, 0, 0, dstX, dstY, w, h); + dstY = YFLIP(xrb, dstY) - h + 1; + XPutImage(dpy, xrb->pixmap, gc, &ximage, 0, 0, dstX, dstY, w, h); } if (unpack->BufferObj->Name) { @@ -1013,9 +651,11 @@ xmesa_CopyPixels( GLcontext *ctx, const XMesaContext xmesa = XMESA_CONTEXT(ctx); const SWcontext *swrast = SWRAST_CONTEXT( ctx ); XMesaDisplay *dpy = xmesa->xm_visual->display; - const XMesaDrawable drawBuffer = xmesa->xm_draw_buffer->buffer; - const XMesaDrawable readBuffer = xmesa->xm_read_buffer->buffer; - const XMesaGC gc = xmesa->xm_draw_buffer->gc; + const XMesaGC gc = ((XMesaBuffer) ctx->DrawBuffer)->gc; + struct xmesa_renderbuffer *srcXrb + = xmesa_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer->Wrapped); + struct xmesa_renderbuffer *dstXrb + = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped); ASSERT(dpy); ASSERT(gc); @@ -1025,8 +665,8 @@ xmesa_CopyPixels( GLcontext *ctx, if (ctx->Color.DrawBuffer[0] == GL_FRONT && ctx->Pixel.ReadBuffer == GL_FRONT && - drawBuffer && /* buffer != 0 means it's a Window or Pixmap */ - readBuffer && + srcXrb->pixmap && + dstXrb->pixmap && type == GL_COLOR && (swrast->_RasterMask & ~CLIP_BIT) == 0 && /* no blend, z-test, etc */ ctx->_ImageTransferState == 0 && /* no color tables, scale/bias, etc */ @@ -1035,9 +675,9 @@ xmesa_CopyPixels( GLcontext *ctx, /* Note: we don't do any special clipping work here. We could, * but X will do it for us. */ - srcy = FLIP(xmesa->xm_read_buffer, srcy) - height + 1; - desty = FLIP(xmesa->xm_draw_buffer, desty) - height + 1; - XCopyArea(dpy, readBuffer, drawBuffer, gc, + srcy = YFLIP(srcXrb, srcy) - height + 1; + desty = YFLIP(dstXrb, desty) - height + 1; + XCopyArea(dpy, srcXrb->pixmap, dstXrb->pixmap, gc, srcx, srcy, width, height, destx, desty); } else { @@ -1097,52 +737,163 @@ enable( GLcontext *ctx, GLenum pname, GLboolean state ) } -void xmesa_update_state( GLcontext *ctx, GLuint new_state ) +static void +clear_color_HPCR_ximage( GLcontext *ctx, const GLfloat color[4] ) +{ + int i; + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color[3]); + + if (color[0] == 0.0 && color[1] == 0.0 && color[2] == 0.0) { + /* black is black */ + MEMSET( xmesa->xm_visual->hpcr_clear_ximage_pattern, 0x0 , + sizeof(xmesa->xm_visual->hpcr_clear_ximage_pattern)); + } + else { + /* build clear pattern */ + for (i=0; i<16; i++) { + xmesa->xm_visual->hpcr_clear_ximage_pattern[0][i] = + DITHER_HPCR(i, 0, + xmesa->clearcolor[0], + xmesa->clearcolor[1], + xmesa->clearcolor[2]); + xmesa->xm_visual->hpcr_clear_ximage_pattern[1][i] = + DITHER_HPCR(i, 1, + xmesa->clearcolor[0], + xmesa->clearcolor[1], + xmesa->clearcolor[2]); + } + } +} + + +static void +clear_color_HPCR_pixmap( GLcontext *ctx, const GLfloat color[4] ) { + int i; const XMesaContext xmesa = XMESA_CONTEXT(ctx); - /* Propogate statechange information to swrast and swrast_setup + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color[3]); + + if (color[0] == 0.0 && color[1] == 0.0 && color[2] == 0.0) { + /* black is black */ + for (i=0; i<16; i++) { + XMesaPutPixel(xmesa->xm_visual->hpcr_clear_ximage, i, 0, 0); + XMesaPutPixel(xmesa->xm_visual->hpcr_clear_ximage, i, 1, 0); + } + } + else { + for (i=0; i<16; i++) { + XMesaPutPixel(xmesa->xm_visual->hpcr_clear_ximage, i, 0, + DITHER_HPCR(i, 0, + xmesa->clearcolor[0], + xmesa->clearcolor[1], + xmesa->clearcolor[2])); + XMesaPutPixel(xmesa->xm_visual->hpcr_clear_ximage, i, 1, + DITHER_HPCR(i, 1, + xmesa->clearcolor[0], + xmesa->clearcolor[1], + xmesa->clearcolor[2])); + } + } + /* change tile pixmap content */ + XMesaPutImage(xmesa->display, + (XMesaDrawable)xmesa->xm_visual->hpcr_clear_pixmap, + XMESA_BUFFER(ctx->DrawBuffer)->cleargc, + xmesa->xm_visual->hpcr_clear_ximage, 0, 0, 0, 0, 16, 2); +} + + +/** + * Called when the driver should update its state, based on the new_state + * flags. + */ +void +xmesa_update_state( GLcontext *ctx, GLbitfield new_state ) +{ + const XMesaContext xmesa = XMESA_CONTEXT(ctx); + + /* Propagate statechange information to swrast and swrast_setup * modules. The X11 driver has no internal GL-dependent state. */ _swrast_InvalidateState( ctx, new_state ); - _ac_InvalidateState( ctx, new_state ); _tnl_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); _swsetup_InvalidateState( ctx, new_state ); + if (ctx->DrawBuffer->Name != 0) + return; - /* setup pointers to front and back buffer clear functions */ - xmesa->xm_draw_buffer->front_clear_func = clear_front_pixmap; - if (xmesa->xm_draw_buffer->backpixmap != XIMAGE) { - xmesa->xm_draw_buffer->back_clear_func = clear_back_pixmap; - } - else if (sizeof(GLushort)!=2 || sizeof(GLuint)!=4) { - xmesa->xm_draw_buffer->back_clear_func = clear_nbit_ximage; - } - else switch (xmesa->xm_visual->BitsPerPixel) { - case 8: - if (xmesa->xm_visual->hpcr_clear_flag) { - xmesa->xm_draw_buffer->back_clear_func = clear_HPCR_ximage; + /* + * GL_DITHER, GL_READ/DRAW_BUFFER, buffer binding state, etc. effect + * renderbuffer span/clear funcs. + */ + if (new_state & (_NEW_COLOR | _NEW_PIXEL | _NEW_BUFFERS)) { + XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); + struct xmesa_renderbuffer *front_xrb, *back_xrb; + + front_xrb = xmbuf->frontxrb; + if (front_xrb) { + xmesa_set_renderbuffer_funcs(front_xrb, xmesa->pixelformat, + xmesa->xm_visual->BitsPerPixel); + front_xrb->clearFunc = clear_pixmap; } - else { - xmesa->xm_draw_buffer->back_clear_func = clear_8bit_ximage; + + back_xrb = xmbuf->backxrb; + if (back_xrb) { + xmesa_set_renderbuffer_funcs(back_xrb, xmesa->pixelformat, + xmesa->xm_visual->BitsPerPixel); + if (xmbuf->backxrb->pixmap) { + back_xrb->clearFunc = clear_pixmap; + } + else { + switch (xmesa->xm_visual->BitsPerPixel) { + case 8: + if (xmesa->xm_visual->hpcr_clear_flag) { + back_xrb->clearFunc = clear_HPCR_ximage; + } + else { + back_xrb->clearFunc = clear_8bit_ximage; + } + break; + case 16: + back_xrb->clearFunc = clear_16bit_ximage; + break; + case 24: + back_xrb->clearFunc = clear_24bit_ximage; + break; + case 32: + back_xrb->clearFunc = clear_32bit_ximage; + break; + default: + back_xrb->clearFunc = clear_nbit_ximage; + break; + } + } } - break; - case 16: - xmesa->xm_draw_buffer->back_clear_func = clear_16bit_ximage; - break; - case 24: - xmesa->xm_draw_buffer->back_clear_func = clear_24bit_ximage; - break; - case 32: - xmesa->xm_draw_buffer->back_clear_func = clear_32bit_ximage; - break; - default: - xmesa->xm_draw_buffer->back_clear_func = clear_nbit_ximage; - break; } - if (ctx->Color._DrawDestMask[0] & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT)) { - xmesa_update_span_funcs(ctx); + if (xmesa->xm_visual->hpcr_clear_flag) { + /* this depends on whether we're drawing to the front or back buffer */ + /* XXX FIX THIS! */ +#if 0 + if (pixmap) { + ctx->Driver.ClearColor = clear_color_HPCR_pixmap; + } + else { + ctx->Driver.ClearColor = clear_color_HPCR_ximage; + } +#else + (void) clear_color_HPCR_pixmap; + (void) clear_color_HPCR_ximage; +#endif } } @@ -1206,20 +957,99 @@ choose_tex_format( GLcontext *ctx, GLint internalFormat, /** * Called by glViewport. * This is a good time for us to poll the current X window size and adjust - * our ancillary (back color, depth, stencil, etc) buffers to match the - * current window size. Remember, we have no opportunity to respond to - * conventional X Resize/StructureNotify events since the X driver has no - * event loop. Thus, we poll. + * our renderbuffers to match the current window size. + * Remember, we have no opportunity to respond to conventional + * X Resize/StructureNotify events since the X driver has no event loop. + * Thus, we poll. * Note that this trick isn't fool-proof. If the application never calls * glViewport, our notion of the current window size may be incorrect. + * That problem led to the GLX_MESA_resize_buffers extension. */ static void xmesa_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) { - _mesa_ResizeBuffersMESA(); + XMesaContext xmctx = XMESA_CONTEXT(ctx); + XMesaBuffer xmdrawbuf = XMESA_BUFFER(ctx->WinSysDrawBuffer); + XMesaBuffer xmreadbuf = XMESA_BUFFER(ctx->WinSysReadBuffer); + xmesa_check_and_update_buffer_size(xmctx, xmdrawbuf); + xmesa_check_and_update_buffer_size(xmctx, xmreadbuf); + (void) x; + (void) y; + (void) w; + (void) h; +} + + +#if ENABLE_EXT_timer_query + +/* + * The GL_EXT_timer_query extension is not enabled for the XServer + * indirect renderer. Not sure about how/if wrapping of gettimeofday() + * is done, etc. + */ + +struct xmesa_query_object +{ + struct gl_query_object Base; + struct timeval StartTime; +}; + + +static struct gl_query_object * +xmesa_new_query_object(GLcontext *ctx, GLuint id) +{ + struct xmesa_query_object *q = CALLOC_STRUCT(xmesa_query_object); + if (q) { + q->Base.Id = id; + q->Base.Ready = GL_TRUE; + } + return &q->Base; +} + + +static void +xmesa_begin_query(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + if (target == GL_TIME_ELAPSED_EXT) { + struct xmesa_query_object *xq = (struct xmesa_query_object *) q; + (void) gettimeofday(&xq->StartTime, NULL); + } } +/** + * Return the difference between the two given times in microseconds. + */ +#ifdef __VMS +#define suseconds_t unsigned int +#endif +static GLuint64EXT +time_diff(const struct timeval *t0, const struct timeval *t1) +{ + GLuint64EXT seconds0 = t0->tv_sec & 0xff; /* 0 .. 255 seconds */ + GLuint64EXT seconds1 = t1->tv_sec & 0xff; /* 0 .. 255 seconds */ + GLuint64EXT nanosec0 = (seconds0 * 1000000 + t0->tv_usec) * 1000; + GLuint64EXT nanosec1 = (seconds1 * 1000000 + t1->tv_usec) * 1000; + return nanosec1 - nanosec0; +} + + +static void +xmesa_end_query(GLcontext *ctx, GLenum target, struct gl_query_object *q) +{ + if (target == GL_TIME_ELAPSED_EXT) { + struct xmesa_query_object *xq = (struct xmesa_query_object *) q; + struct timeval endTime; + (void) gettimeofday(&endTime, NULL); + /* result is in nanoseconds! */ + q->Result = time_diff(&xq->StartTime, &endTime); + } + q->Ready = GL_TRUE; +} + +#endif /* ENABLE_timer_query */ + + /** * Initialize the device driver function table with the functions * we implement in this driver. @@ -1230,7 +1060,7 @@ xmesa_init_driver_functions( XMesaVisual xmvisual, { driver->GetString = get_string; driver->UpdateState = xmesa_update_state; - driver->GetBufferSize = get_buffer_size; + driver->GetBufferSize = NULL; /* OBSOLETE */ driver->Flush = finish_or_flush; driver->Finish = finish_or_flush; driver->ClearIndex = clear_index; @@ -1239,7 +1069,6 @@ xmesa_init_driver_functions( XMesaVisual xmvisual, driver->ColorMask = color_mask; driver->Enable = enable; driver->Clear = clear_buffers; - driver->ResizeBuffers = xmesa_resize_buffers; driver->Viewport = xmesa_viewport; #ifndef XFree86Server driver->CopyPixels = xmesa_CopyPixels; @@ -1252,11 +1081,17 @@ xmesa_init_driver_functions( XMesaVisual xmvisual, } #endif driver->TestProxyTexImage = test_proxy_teximage; -#if SWTC +#if ENABLE_EXT_texure_compression_s3tc driver->ChooseTextureFormat = choose_tex_format; #else (void) choose_tex_format; #endif + +#if ENABLE_EXT_timer_query + driver->NewQueryObject = xmesa_new_query_object; + driver->BeginQuery = xmesa_begin_query; + driver->EndQuery = xmesa_end_query; +#endif } @@ -1279,21 +1114,21 @@ xmesa_init_driver_functions( XMesaVisual xmvisual, _SWRAST_NEW_RASTERMASK) -/* Extend the software rasterizer with our line/point/triangle +/** + * Extend the software rasterizer with our line/point/triangle * functions. + * Called during context creation only. */ void xmesa_register_swrast_functions( GLcontext *ctx ) { SWcontext *swrast = SWRAST_CONTEXT( ctx ); - struct swrast_device_driver *dd = _swrast_GetDeviceDriverReference(ctx); - - dd->SetBuffer = xmesa_set_buffer; swrast->choose_point = xmesa_choose_point; swrast->choose_line = xmesa_choose_line; swrast->choose_triangle = xmesa_choose_triangle; - swrast->invalidate_point |= XMESA_NEW_POINT; - swrast->invalidate_line |= XMESA_NEW_LINE; - swrast->invalidate_triangle |= XMESA_NEW_TRIANGLE; + /* XXX these lines have no net effect. Remove??? */ + swrast->InvalidatePointMask |= XMESA_NEW_POINT; + swrast->InvalidateLineMask |= XMESA_NEW_LINE; + swrast->InvalidateTriangleMask |= XMESA_NEW_TRIANGLE; }