1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 5848b8605Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the "Software"), 8848b8605Smrg * to deal in the Software without restriction, including without limitation 9848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 11848b8605Smrg * Software is furnished to do so, subject to the following conditions: 12848b8605Smrg * 13848b8605Smrg * The above copyright notice and this permission notice shall be included 14848b8605Smrg * in all copies or substantial portions of the Software. 15848b8605Smrg * 16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 23848b8605Smrg */ 24848b8605Smrg 25848b8605Smrg 26848b8605Smrg/** 27848b8605Smrg * \file xm_dd.h 28848b8605Smrg * General device driver functions for Xlib driver. 29848b8605Smrg */ 30848b8605Smrg 31848b8605Smrg#include "glxheader.h" 32848b8605Smrg#include "main/bufferobj.h" 33848b8605Smrg#include "main/context.h" 34848b8605Smrg#include "main/colormac.h" 35848b8605Smrg#include "main/fbobject.h" 36b8e80941Smrg#include "main/framebuffer.h" 37848b8605Smrg#include "main/macros.h" 38848b8605Smrg#include "main/mipmap.h" 39848b8605Smrg#include "main/image.h" 40848b8605Smrg#include "main/imports.h" 41848b8605Smrg#include "main/mtypes.h" 42848b8605Smrg#include "main/pbo.h" 43848b8605Smrg#include "main/texformat.h" 44848b8605Smrg#include "swrast/swrast.h" 45848b8605Smrg#include "swrast/s_context.h" 46848b8605Smrg#include "swrast_setup/swrast_setup.h" 47848b8605Smrg#include "tnl/tnl.h" 48848b8605Smrg#include "tnl/t_context.h" 49848b8605Smrg#include "drivers/common/meta.h" 50848b8605Smrg#include "xmesaP.h" 51848b8605Smrg 52848b8605Smrg 53848b8605Smrgstatic void 54848b8605Smrgfinish_or_flush( struct gl_context *ctx ) 55848b8605Smrg{ 56848b8605Smrg const XMesaContext xmesa = XMESA_CONTEXT(ctx); 57848b8605Smrg if (xmesa) { 58848b8605Smrg mtx_lock(&_xmesa_lock); 59848b8605Smrg XSync( xmesa->display, False ); 60848b8605Smrg mtx_unlock(&_xmesa_lock); 61848b8605Smrg } 62848b8605Smrg} 63848b8605Smrg 64848b8605Smrg 65848b8605Smrg/* Implements glColorMask() */ 66848b8605Smrgstatic void 67848b8605Smrgcolor_mask(struct gl_context *ctx, 68848b8605Smrg GLboolean rmask, GLboolean gmask, GLboolean bmask, GLboolean amask) 69848b8605Smrg{ 70848b8605Smrg const XMesaContext xmesa = XMESA_CONTEXT(ctx); 71848b8605Smrg XMesaBuffer xmbuf; 72848b8605Smrg const int xclass = xmesa->xm_visual->visualType; 73848b8605Smrg (void) amask; 74848b8605Smrg 75848b8605Smrg if (_mesa_is_user_fbo(ctx->DrawBuffer)) 76848b8605Smrg return; 77848b8605Smrg 78848b8605Smrg xmbuf = XMESA_BUFFER(ctx->DrawBuffer); 79848b8605Smrg 80848b8605Smrg if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) { 81848b8605Smrg unsigned long m; 82848b8605Smrg if (rmask && gmask && bmask) { 83848b8605Smrg m = ((unsigned long)~0L); 84848b8605Smrg } 85848b8605Smrg else { 86848b8605Smrg m = 0; 87848b8605Smrg if (rmask) m |= GET_REDMASK(xmesa->xm_visual); 88848b8605Smrg if (gmask) m |= GET_GREENMASK(xmesa->xm_visual); 89848b8605Smrg if (bmask) m |= GET_BLUEMASK(xmesa->xm_visual); 90848b8605Smrg } 91848b8605Smrg XMesaSetPlaneMask( xmesa->display, xmbuf->cleargc, m ); 92848b8605Smrg } 93848b8605Smrg} 94848b8605Smrg 95848b8605Smrg 96848b8605Smrg 97848b8605Smrg/**********************************************************************/ 98848b8605Smrg/*** glClear implementations ***/ 99848b8605Smrg/**********************************************************************/ 100848b8605Smrg 101848b8605Smrg 102848b8605Smrg/** 103848b8605Smrg * Clear the front or back color buffer, if it's implemented with a pixmap. 104848b8605Smrg */ 105848b8605Smrgstatic void 106848b8605Smrgclear_pixmap(struct gl_context *ctx, struct xmesa_renderbuffer *xrb, 107848b8605Smrg GLint x, GLint y, GLint width, GLint height) 108848b8605Smrg{ 109848b8605Smrg const XMesaContext xmesa = XMESA_CONTEXT(ctx); 110848b8605Smrg XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); 111848b8605Smrg 112848b8605Smrg assert(xmbuf); 113848b8605Smrg assert(xrb->pixmap); 114848b8605Smrg assert(xmesa); 115848b8605Smrg assert(xmesa->display); 116848b8605Smrg assert(xrb->pixmap); 117848b8605Smrg assert(xmbuf->cleargc); 118848b8605Smrg 119848b8605Smrg XMesaFillRectangle( xmesa->display, xrb->pixmap, xmbuf->cleargc, 120848b8605Smrg x, xrb->Base.Base.Height - y - height, 121848b8605Smrg width, height ); 122848b8605Smrg} 123848b8605Smrg 124848b8605Smrg 125848b8605Smrgstatic void 126848b8605Smrgclear_16bit_ximage( struct gl_context *ctx, struct xmesa_renderbuffer *xrb, 127848b8605Smrg GLint x, GLint y, GLint width, GLint height) 128848b8605Smrg{ 129848b8605Smrg const XMesaContext xmesa = XMESA_CONTEXT(ctx); 130848b8605Smrg GLuint pixel = (GLuint) xmesa->clearpixel; 131848b8605Smrg GLint i, j; 132848b8605Smrg 133848b8605Smrg if (xmesa->swapbytes) { 134848b8605Smrg pixel = ((pixel >> 8) & 0x00ff) | ((pixel << 8) & 0xff00); 135848b8605Smrg } 136848b8605Smrg 137848b8605Smrg for (j = 0; j < height; j++) { 138848b8605Smrg GLushort *ptr2 = PIXEL_ADDR2(xrb, x, y + j); 139848b8605Smrg for (i = 0; i < width; i++) { 140848b8605Smrg ptr2[i] = pixel; 141848b8605Smrg } 142848b8605Smrg } 143848b8605Smrg} 144848b8605Smrg 145848b8605Smrg 146848b8605Smrg/* Optimized code provided by Nozomi Ytow <noz@xfree86.org> */ 147848b8605Smrgstatic void 148848b8605Smrgclear_24bit_ximage(struct gl_context *ctx, struct xmesa_renderbuffer *xrb, 149848b8605Smrg GLint x, GLint y, GLint width, GLint height) 150848b8605Smrg{ 151848b8605Smrg const XMesaContext xmesa = XMESA_CONTEXT(ctx); 152848b8605Smrg const GLubyte r = xmesa->clearcolor[0]; 153848b8605Smrg const GLubyte g = xmesa->clearcolor[1]; 154848b8605Smrg const GLubyte b = xmesa->clearcolor[2]; 155848b8605Smrg 156848b8605Smrg if (r == g && g == b) { 157848b8605Smrg /* same value for all three components (gray) */ 158848b8605Smrg GLint j; 159848b8605Smrg for (j = 0; j < height; j++) { 160848b8605Smrg bgr_t *ptr3 = PIXEL_ADDR3(xrb, x, y + j); 161848b8605Smrg memset(ptr3, r, 3 * width); 162848b8605Smrg } 163848b8605Smrg } 164848b8605Smrg else { 165848b8605Smrg /* non-gray clear color */ 166848b8605Smrg GLint i, j; 167848b8605Smrg for (j = 0; j < height; j++) { 168848b8605Smrg bgr_t *ptr3 = PIXEL_ADDR3(xrb, x, y + j); 169848b8605Smrg for (i = 0; i < width; i++) { 170848b8605Smrg ptr3->r = r; 171848b8605Smrg ptr3->g = g; 172848b8605Smrg ptr3->b = b; 173848b8605Smrg ptr3++; 174848b8605Smrg } 175848b8605Smrg } 176848b8605Smrg } 177848b8605Smrg} 178848b8605Smrg 179848b8605Smrg 180848b8605Smrgstatic void 181848b8605Smrgclear_32bit_ximage(struct gl_context *ctx, struct xmesa_renderbuffer *xrb, 182848b8605Smrg GLint x, GLint y, GLint width, GLint height) 183848b8605Smrg{ 184848b8605Smrg const XMesaContext xmesa = XMESA_CONTEXT(ctx); 185848b8605Smrg register GLuint pixel = (GLuint) xmesa->clearpixel; 186848b8605Smrg 187848b8605Smrg if (!xrb->ximage) 188848b8605Smrg return; 189848b8605Smrg 190848b8605Smrg if (xmesa->swapbytes) { 191848b8605Smrg pixel = ((pixel >> 24) & 0x000000ff) 192848b8605Smrg | ((pixel >> 8) & 0x0000ff00) 193848b8605Smrg | ((pixel << 8) & 0x00ff0000) 194848b8605Smrg | ((pixel << 24) & 0xff000000); 195848b8605Smrg } 196848b8605Smrg 197848b8605Smrg if (width == xrb->Base.Base.Width && height == xrb->Base.Base.Height) { 198848b8605Smrg /* clearing whole buffer */ 199848b8605Smrg const GLuint n = xrb->Base.Base.Width * xrb->Base.Base.Height; 200848b8605Smrg GLuint *ptr4 = (GLuint *) xrb->ximage->data; 201848b8605Smrg if (pixel == 0) { 202848b8605Smrg /* common case */ 203848b8605Smrg memset(ptr4, pixel, 4 * n); 204848b8605Smrg } 205848b8605Smrg else { 206848b8605Smrg GLuint i; 207848b8605Smrg for (i = 0; i < n; i++) 208848b8605Smrg ptr4[i] = pixel; 209848b8605Smrg } 210848b8605Smrg } 211848b8605Smrg else { 212848b8605Smrg /* clearing scissored region */ 213848b8605Smrg GLint i, j; 214848b8605Smrg for (j = 0; j < height; j++) { 215848b8605Smrg GLuint *ptr4 = PIXEL_ADDR4(xrb, x, y + j); 216848b8605Smrg for (i = 0; i < width; i++) { 217848b8605Smrg ptr4[i] = pixel; 218848b8605Smrg } 219848b8605Smrg } 220848b8605Smrg } 221848b8605Smrg} 222848b8605Smrg 223848b8605Smrg 224848b8605Smrgstatic void 225848b8605Smrgclear_nbit_ximage(struct gl_context *ctx, struct xmesa_renderbuffer *xrb, 226848b8605Smrg GLint x, GLint y, GLint width, GLint height) 227848b8605Smrg{ 228848b8605Smrg const XMesaContext xmesa = XMESA_CONTEXT(ctx); 229848b8605Smrg XMesaImage *img = xrb->ximage; 230848b8605Smrg GLint i, j; 231848b8605Smrg 232848b8605Smrg /* TODO: optimize this */ 233848b8605Smrg y = YFLIP(xrb, y); 234848b8605Smrg for (j = 0; j < height; j++) { 235848b8605Smrg for (i = 0; i < width; i++) { 236848b8605Smrg XMesaPutPixel(img, x+i, y-j, xmesa->clearpixel); 237848b8605Smrg } 238848b8605Smrg } 239848b8605Smrg} 240848b8605Smrg 241848b8605Smrg 242848b8605Smrg 243848b8605Smrgstatic void 244848b8605Smrgclear_buffers(struct gl_context *ctx, GLbitfield buffers) 245848b8605Smrg{ 246848b8605Smrg if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) { 247848b8605Smrg /* this is a window system framebuffer */ 248848b8605Smrg const XMesaContext xmesa = XMESA_CONTEXT(ctx); 249848b8605Smrg XMesaBuffer b = XMESA_BUFFER(ctx->DrawBuffer); 250848b8605Smrg const GLint x = ctx->DrawBuffer->_Xmin; 251848b8605Smrg const GLint y = ctx->DrawBuffer->_Ymin; 252848b8605Smrg const GLint width = ctx->DrawBuffer->_Xmax - x; 253848b8605Smrg const GLint height = ctx->DrawBuffer->_Ymax - y; 254848b8605Smrg 255848b8605Smrg _mesa_unclamped_float_rgba_to_ubyte(xmesa->clearcolor, 256848b8605Smrg ctx->Color.ClearColor.f); 257848b8605Smrg xmesa->clearpixel = xmesa_color_to_pixel(ctx, 258848b8605Smrg xmesa->clearcolor[0], 259848b8605Smrg xmesa->clearcolor[1], 260848b8605Smrg xmesa->clearcolor[2], 261848b8605Smrg xmesa->clearcolor[3], 262848b8605Smrg xmesa->xm_visual->undithered_pf); 263848b8605Smrg XMesaSetForeground(xmesa->display, b->cleargc, xmesa->clearpixel); 264848b8605Smrg 265848b8605Smrg /* we can't handle color or index masking */ 266b8e80941Smrg if (GET_COLORMASK(ctx->Color.ColorMask, 0) == 0xf && 267b8e80941Smrg ctx->Color.IndexMask == 0xffffffff) { 268848b8605Smrg if (buffers & BUFFER_BIT_FRONT_LEFT) { 269848b8605Smrg /* clear front color buffer */ 270848b8605Smrg struct gl_renderbuffer *frontRb 271848b8605Smrg = ctx->DrawBuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; 272848b8605Smrg if (b->frontxrb == xmesa_renderbuffer(frontRb)) { 273848b8605Smrg /* renderbuffer is not wrapped - great! */ 274848b8605Smrg b->frontxrb->clearFunc(ctx, b->frontxrb, x, y, width, height); 275848b8605Smrg buffers &= ~BUFFER_BIT_FRONT_LEFT; 276848b8605Smrg } 277848b8605Smrg else { 278848b8605Smrg /* we can't directly clear an alpha-wrapped color buffer */ 279848b8605Smrg } 280848b8605Smrg } 281848b8605Smrg if (buffers & BUFFER_BIT_BACK_LEFT) { 282848b8605Smrg /* clear back color buffer */ 283848b8605Smrg struct gl_renderbuffer *backRb 284848b8605Smrg = ctx->DrawBuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer; 285848b8605Smrg if (b->backxrb == xmesa_renderbuffer(backRb)) { 286848b8605Smrg /* renderbuffer is not wrapped - great! */ 287848b8605Smrg b->backxrb->clearFunc(ctx, b->backxrb, x, y, width, height); 288848b8605Smrg buffers &= ~BUFFER_BIT_BACK_LEFT; 289848b8605Smrg } 290848b8605Smrg } 291848b8605Smrg } 292848b8605Smrg } 293848b8605Smrg if (buffers) 294848b8605Smrg _swrast_Clear(ctx, buffers); 295848b8605Smrg} 296848b8605Smrg 297848b8605Smrg 298848b8605Smrg/* XXX these functions haven't been tested in the Xserver environment */ 299848b8605Smrg 300848b8605Smrg 301848b8605Smrg/** 302848b8605Smrg * Check if we can do an optimized glDrawPixels into an 8R8G8B visual. 303848b8605Smrg */ 304848b8605Smrgstatic GLboolean 305848b8605Smrgcan_do_DrawPixels_8R8G8B(struct gl_context *ctx, GLenum format, GLenum type) 306848b8605Smrg{ 307848b8605Smrg if (format == GL_BGRA && 308848b8605Smrg type == GL_UNSIGNED_BYTE && 309848b8605Smrg ctx->DrawBuffer && 310848b8605Smrg _mesa_is_winsys_fbo(ctx->DrawBuffer) && 311848b8605Smrg ctx->Pixel.ZoomX == 1.0 && /* no zooming */ 312848b8605Smrg ctx->Pixel.ZoomY == 1.0 && 313848b8605Smrg ctx->_ImageTransferState == 0 /* no color tables, scale/bias, etc */) { 314848b8605Smrg const SWcontext *swrast = SWRAST_CONTEXT(ctx); 315848b8605Smrg 316848b8605Smrg if (swrast->NewState) 317848b8605Smrg _swrast_validate_derived( ctx ); 318848b8605Smrg 319848b8605Smrg if ((swrast->_RasterMask & ~CLIP_BIT) == 0) /* no blend, z-test, etc */ { 320848b8605Smrg struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; 321848b8605Smrg if (rb) { 322848b8605Smrg struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb); 323848b8605Smrg if (xrb && 324848b8605Smrg xrb->pixmap && /* drawing to pixmap or window */ 325848b8605Smrg _mesa_get_format_bits(xrb->Base.Base.Format, GL_ALPHA_BITS) == 0) { 326848b8605Smrg return GL_TRUE; 327848b8605Smrg } 328848b8605Smrg } 329848b8605Smrg } 330848b8605Smrg } 331848b8605Smrg return GL_FALSE; 332848b8605Smrg} 333848b8605Smrg 334848b8605Smrg 335848b8605Smrg/** 336848b8605Smrg * This function implements glDrawPixels() with an XPutImage call when 337848b8605Smrg * drawing to the front buffer (X Window drawable). 338848b8605Smrg * The image format must be GL_BGRA to match the PF_8R8G8B pixel format. 339848b8605Smrg */ 340848b8605Smrgstatic void 341848b8605Smrgxmesa_DrawPixels_8R8G8B( struct gl_context *ctx, 342848b8605Smrg GLint x, GLint y, GLsizei width, GLsizei height, 343848b8605Smrg GLenum format, GLenum type, 344848b8605Smrg const struct gl_pixelstore_attrib *unpack, 345848b8605Smrg const GLvoid *pixels ) 346848b8605Smrg{ 347848b8605Smrg if (can_do_DrawPixels_8R8G8B(ctx, format, type)) { 348848b8605Smrg const SWcontext *swrast = SWRAST_CONTEXT( ctx ); 349848b8605Smrg struct gl_pixelstore_attrib clippedUnpack = *unpack; 350848b8605Smrg int dstX = x; 351848b8605Smrg int dstY = y; 352848b8605Smrg int w = width; 353848b8605Smrg int h = height; 354848b8605Smrg 355848b8605Smrg if (swrast->NewState) 356848b8605Smrg _swrast_validate_derived( ctx ); 357848b8605Smrg 358848b8605Smrg if (_mesa_is_bufferobj(unpack->BufferObj)) { 359848b8605Smrg /* unpack from PBO */ 360848b8605Smrg GLubyte *buf; 361848b8605Smrg if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, 362848b8605Smrg format, type, INT_MAX, pixels)) { 363848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 364848b8605Smrg "glDrawPixels(invalid PBO access)"); 365848b8605Smrg return; 366848b8605Smrg } 367848b8605Smrg buf = (GLubyte *) ctx->Driver.MapBufferRange(ctx, 0, 368848b8605Smrg unpack->BufferObj->Size, 369848b8605Smrg GL_MAP_READ_BIT, 370848b8605Smrg unpack->BufferObj, 371848b8605Smrg MAP_INTERNAL); 372848b8605Smrg if (!buf) { 373848b8605Smrg return; /* error */ 374848b8605Smrg } 375848b8605Smrg pixels = ADD_POINTERS(buf, pixels); 376848b8605Smrg } 377848b8605Smrg 378848b8605Smrg if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &clippedUnpack)) { 379848b8605Smrg const XMesaContext xmesa = XMESA_CONTEXT(ctx); 380848b8605Smrg XMesaDisplay *dpy = xmesa->xm_visual->display; 381848b8605Smrg XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); 382848b8605Smrg const XMesaGC gc = xmbuf->cleargc; /* effected by glColorMask */ 383848b8605Smrg struct xmesa_renderbuffer *xrb 384848b8605Smrg = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]); 385848b8605Smrg const int srcX = clippedUnpack.SkipPixels; 386848b8605Smrg const int srcY = clippedUnpack.SkipRows; 387848b8605Smrg const int rowLength = clippedUnpack.RowLength; 388848b8605Smrg XMesaImage ximage; 389848b8605Smrg 390b8e80941Smrg assert(xmesa->xm_visual->dithered_pf == PF_8R8G8B); 391b8e80941Smrg assert(xmesa->xm_visual->undithered_pf == PF_8R8G8B); 392b8e80941Smrg assert(dpy); 393b8e80941Smrg assert(gc); 394848b8605Smrg 395848b8605Smrg /* This is a little tricky since all coordinates up to now have 396848b8605Smrg * been in the OpenGL bottom-to-top orientation. X is top-to-bottom 397848b8605Smrg * so we have to carefully compute the Y coordinates/addresses here. 398848b8605Smrg */ 399848b8605Smrg memset(&ximage, 0, sizeof(XMesaImage)); 400848b8605Smrg ximage.width = width; 401848b8605Smrg ximage.height = height; 402848b8605Smrg ximage.format = ZPixmap; 403848b8605Smrg ximage.data = (char *) pixels 404848b8605Smrg + ((srcY + h - 1) * rowLength + srcX) * 4; 405848b8605Smrg ximage.byte_order = LSBFirst; 406848b8605Smrg ximage.bitmap_unit = 32; 407848b8605Smrg ximage.bitmap_bit_order = LSBFirst; 408848b8605Smrg ximage.bitmap_pad = 32; 409848b8605Smrg ximage.depth = 32; 410848b8605Smrg ximage.bits_per_pixel = 32; 411848b8605Smrg ximage.bytes_per_line = -rowLength * 4; /* negative to flip image */ 412848b8605Smrg /* it seems we don't need to set the ximage.red/green/blue_mask fields */ 413848b8605Smrg /* flip Y axis for dest position */ 414848b8605Smrg dstY = YFLIP(xrb, dstY) - h + 1; 415848b8605Smrg XPutImage(dpy, xrb->pixmap, gc, &ximage, 0, 0, dstX, dstY, w, h); 416848b8605Smrg } 417848b8605Smrg 418848b8605Smrg if (_mesa_is_bufferobj(unpack->BufferObj)) { 419848b8605Smrg ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj, MAP_INTERNAL); 420848b8605Smrg } 421848b8605Smrg } 422848b8605Smrg else { 423848b8605Smrg /* software fallback */ 424848b8605Smrg _swrast_DrawPixels(ctx, x, y, width, height, 425848b8605Smrg format, type, unpack, pixels); 426848b8605Smrg } 427848b8605Smrg} 428848b8605Smrg 429848b8605Smrg 430848b8605Smrg 431848b8605Smrg/** 432848b8605Smrg * Check if we can do an optimized glDrawPixels into an 5R6G5B visual. 433848b8605Smrg */ 434848b8605Smrgstatic GLboolean 435848b8605Smrgcan_do_DrawPixels_5R6G5B(struct gl_context *ctx, GLenum format, GLenum type) 436848b8605Smrg{ 437848b8605Smrg if (format == GL_RGB && 438848b8605Smrg type == GL_UNSIGNED_SHORT_5_6_5 && 439848b8605Smrg !ctx->Color.DitherFlag && /* no dithering */ 440848b8605Smrg ctx->DrawBuffer && 441848b8605Smrg _mesa_is_winsys_fbo(ctx->DrawBuffer) && 442848b8605Smrg ctx->Pixel.ZoomX == 1.0 && /* no zooming */ 443848b8605Smrg ctx->Pixel.ZoomY == 1.0 && 444848b8605Smrg ctx->_ImageTransferState == 0 /* no color tables, scale/bias, etc */) { 445848b8605Smrg const SWcontext *swrast = SWRAST_CONTEXT(ctx); 446848b8605Smrg 447848b8605Smrg if (swrast->NewState) 448848b8605Smrg _swrast_validate_derived( ctx ); 449848b8605Smrg 450848b8605Smrg if ((swrast->_RasterMask & ~CLIP_BIT) == 0) /* no blend, z-test, etc */ { 451848b8605Smrg struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; 452848b8605Smrg if (rb) { 453848b8605Smrg struct xmesa_renderbuffer *xrb = xmesa_renderbuffer(rb); 454848b8605Smrg if (xrb && 455848b8605Smrg xrb->pixmap && /* drawing to pixmap or window */ 456848b8605Smrg _mesa_get_format_bits(xrb->Base.Base.Format, GL_ALPHA_BITS) == 0) { 457848b8605Smrg return GL_TRUE; 458848b8605Smrg } 459848b8605Smrg } 460848b8605Smrg } 461848b8605Smrg } 462848b8605Smrg return GL_FALSE; 463848b8605Smrg} 464848b8605Smrg 465848b8605Smrg 466848b8605Smrg/** 467848b8605Smrg * This function implements glDrawPixels() with an XPutImage call when 468848b8605Smrg * drawing to the front buffer (X Window drawable). The image format 469848b8605Smrg * must be GL_RGB and image type must be GL_UNSIGNED_SHORT_5_6_5 to 470848b8605Smrg * match the PF_5R6G5B pixel format. 471848b8605Smrg */ 472848b8605Smrgstatic void 473848b8605Smrgxmesa_DrawPixels_5R6G5B( struct gl_context *ctx, 474848b8605Smrg GLint x, GLint y, GLsizei width, GLsizei height, 475848b8605Smrg GLenum format, GLenum type, 476848b8605Smrg const struct gl_pixelstore_attrib *unpack, 477848b8605Smrg const GLvoid *pixels ) 478848b8605Smrg{ 479848b8605Smrg if (can_do_DrawPixels_5R6G5B(ctx, format, type)) { 480848b8605Smrg const SWcontext *swrast = SWRAST_CONTEXT( ctx ); 481848b8605Smrg struct gl_pixelstore_attrib clippedUnpack = *unpack; 482848b8605Smrg int dstX = x; 483848b8605Smrg int dstY = y; 484848b8605Smrg int w = width; 485848b8605Smrg int h = height; 486848b8605Smrg 487848b8605Smrg if (swrast->NewState) 488848b8605Smrg _swrast_validate_derived( ctx ); 489848b8605Smrg 490848b8605Smrg if (_mesa_is_bufferobj(unpack->BufferObj)) { 491848b8605Smrg /* unpack from PBO */ 492848b8605Smrg GLubyte *buf; 493848b8605Smrg if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, 494848b8605Smrg format, type, INT_MAX, pixels)) { 495848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 496848b8605Smrg "glDrawPixels(invalid PBO access)"); 497848b8605Smrg return; 498848b8605Smrg } 499848b8605Smrg buf = (GLubyte *) ctx->Driver.MapBufferRange(ctx, 0, 500848b8605Smrg unpack->BufferObj->Size, 501848b8605Smrg GL_MAP_READ_BIT, 502848b8605Smrg unpack->BufferObj, 503848b8605Smrg MAP_INTERNAL); 504848b8605Smrg if (!buf) { 505848b8605Smrg return; /* error */ 506848b8605Smrg } 507848b8605Smrg pixels = ADD_POINTERS(buf, pixels); 508848b8605Smrg } 509848b8605Smrg 510848b8605Smrg if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &clippedUnpack)) { 511848b8605Smrg const XMesaContext xmesa = XMESA_CONTEXT(ctx); 512848b8605Smrg XMesaDisplay *dpy = xmesa->xm_visual->display; 513848b8605Smrg XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); 514848b8605Smrg const XMesaGC gc = xmbuf->cleargc; /* effected by glColorMask */ 515848b8605Smrg struct xmesa_renderbuffer *xrb 516848b8605Smrg = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]); 517848b8605Smrg const int srcX = clippedUnpack.SkipPixels; 518848b8605Smrg const int srcY = clippedUnpack.SkipRows; 519848b8605Smrg const int rowLength = clippedUnpack.RowLength; 520848b8605Smrg XMesaImage ximage; 521848b8605Smrg 522b8e80941Smrg assert(xmesa->xm_visual->undithered_pf == PF_5R6G5B); 523b8e80941Smrg assert(dpy); 524b8e80941Smrg assert(gc); 525848b8605Smrg 526848b8605Smrg /* This is a little tricky since all coordinates up to now have 527848b8605Smrg * been in the OpenGL bottom-to-top orientation. X is top-to-bottom 528848b8605Smrg * so we have to carefully compute the Y coordinates/addresses here. 529848b8605Smrg */ 530848b8605Smrg memset(&ximage, 0, sizeof(XMesaImage)); 531848b8605Smrg ximage.width = width; 532848b8605Smrg ximage.height = height; 533848b8605Smrg ximage.format = ZPixmap; 534848b8605Smrg ximage.data = (char *) pixels 535848b8605Smrg + ((srcY + h - 1) * rowLength + srcX) * 2; 536848b8605Smrg ximage.byte_order = LSBFirst; 537848b8605Smrg ximage.bitmap_unit = 16; 538848b8605Smrg ximage.bitmap_bit_order = LSBFirst; 539848b8605Smrg ximage.bitmap_pad = 16; 540848b8605Smrg ximage.depth = 16; 541848b8605Smrg ximage.bits_per_pixel = 16; 542848b8605Smrg ximage.bytes_per_line = -rowLength * 2; /* negative to flip image */ 543848b8605Smrg /* it seems we don't need to set the ximage.red/green/blue_mask fields */ 544848b8605Smrg /* flip Y axis for dest position */ 545848b8605Smrg dstY = YFLIP(xrb, dstY) - h + 1; 546848b8605Smrg XPutImage(dpy, xrb->pixmap, gc, &ximage, 0, 0, dstX, dstY, w, h); 547848b8605Smrg } 548848b8605Smrg 549848b8605Smrg if (unpack->BufferObj->Name) { 550848b8605Smrg ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj, MAP_INTERNAL); 551848b8605Smrg } 552848b8605Smrg } 553848b8605Smrg else { 554848b8605Smrg /* software fallback */ 555848b8605Smrg _swrast_DrawPixels(ctx, x, y, width, height, 556848b8605Smrg format, type, unpack, pixels); 557848b8605Smrg } 558848b8605Smrg} 559848b8605Smrg 560848b8605Smrg 561848b8605Smrg/** 562848b8605Smrg * Determine if we can do an optimized glCopyPixels. 563848b8605Smrg */ 564848b8605Smrgstatic GLboolean 565848b8605Smrgcan_do_CopyPixels(struct gl_context *ctx, GLenum type) 566848b8605Smrg{ 567848b8605Smrg if (type == GL_COLOR && 568848b8605Smrg ctx->_ImageTransferState == 0 && /* no color tables, scale/bias, etc */ 569848b8605Smrg ctx->Pixel.ZoomX == 1.0 && /* no zooming */ 570848b8605Smrg ctx->Pixel.ZoomY == 1.0 && 571848b8605Smrg ctx->Color.DrawBuffer[0] == GL_FRONT && /* copy to front buf */ 572848b8605Smrg ctx->Pixel.ReadBuffer == GL_FRONT && /* copy from front buf */ 573848b8605Smrg ctx->ReadBuffer->_ColorReadBuffer && 574848b8605Smrg ctx->DrawBuffer->_ColorDrawBuffers[0]) { 575848b8605Smrg const SWcontext *swrast = SWRAST_CONTEXT( ctx ); 576848b8605Smrg 577848b8605Smrg if (swrast->NewState) 578848b8605Smrg _swrast_validate_derived( ctx ); 579848b8605Smrg 580848b8605Smrg if ((swrast->_RasterMask & ~CLIP_BIT) == 0x0 && 581848b8605Smrg ctx->ReadBuffer && 582848b8605Smrg ctx->ReadBuffer->_ColorReadBuffer && 583848b8605Smrg ctx->DrawBuffer && 584848b8605Smrg ctx->DrawBuffer->_ColorDrawBuffers[0]) { 585848b8605Smrg struct xmesa_renderbuffer *srcXrb 586848b8605Smrg = xmesa_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); 587848b8605Smrg struct xmesa_renderbuffer *dstXrb 588848b8605Smrg = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]); 589848b8605Smrg if (srcXrb->pixmap && dstXrb->pixmap) { 590848b8605Smrg return GL_TRUE; 591848b8605Smrg } 592848b8605Smrg } 593848b8605Smrg } 594848b8605Smrg return GL_FALSE; 595848b8605Smrg} 596848b8605Smrg 597848b8605Smrg 598848b8605Smrg/** 599848b8605Smrg * Implement glCopyPixels for the front color buffer (or back buffer Pixmap) 600848b8605Smrg * for the color buffer. Don't support zooming, pixel transfer, etc. 601848b8605Smrg * We do support copying from one window to another, ala glXMakeCurrentRead. 602848b8605Smrg */ 603848b8605Smrgstatic void 604848b8605Smrgxmesa_CopyPixels( struct gl_context *ctx, 605848b8605Smrg GLint srcx, GLint srcy, GLsizei width, GLsizei height, 606848b8605Smrg GLint destx, GLint desty, GLenum type ) 607848b8605Smrg{ 608848b8605Smrg if (can_do_CopyPixels(ctx, type)) { 609848b8605Smrg const XMesaContext xmesa = XMESA_CONTEXT(ctx); 610848b8605Smrg XMesaDisplay *dpy = xmesa->xm_visual->display; 611848b8605Smrg XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); 612848b8605Smrg const XMesaGC gc = xmbuf->cleargc; /* effected by glColorMask */ 613848b8605Smrg struct xmesa_renderbuffer *srcXrb 614848b8605Smrg = xmesa_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer); 615848b8605Smrg struct xmesa_renderbuffer *dstXrb 616848b8605Smrg = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]); 617848b8605Smrg 618b8e80941Smrg assert(dpy); 619b8e80941Smrg assert(gc); 620848b8605Smrg 621848b8605Smrg /* Note: we don't do any special clipping work here. We could, 622848b8605Smrg * but X will do it for us. 623848b8605Smrg */ 624848b8605Smrg srcy = YFLIP(srcXrb, srcy) - height + 1; 625848b8605Smrg desty = YFLIP(dstXrb, desty) - height + 1; 626848b8605Smrg XCopyArea(dpy, srcXrb->pixmap, dstXrb->pixmap, gc, 627848b8605Smrg srcx, srcy, width, height, destx, desty); 628848b8605Smrg } 629848b8605Smrg else { 630848b8605Smrg _swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type ); 631848b8605Smrg } 632848b8605Smrg} 633848b8605Smrg 634848b8605Smrg 635848b8605Smrg 636848b8605Smrg 637848b8605Smrg/* 638848b8605Smrg * Every driver should implement a GetString function in order to 639848b8605Smrg * return a meaningful GL_RENDERER string. 640848b8605Smrg */ 641848b8605Smrgstatic const GLubyte * 642848b8605Smrgget_string( struct gl_context *ctx, GLenum name ) 643848b8605Smrg{ 644848b8605Smrg (void) ctx; 645848b8605Smrg switch (name) { 646848b8605Smrg case GL_RENDERER: 647848b8605Smrg return (const GLubyte *) "Mesa X11"; 648848b8605Smrg case GL_VENDOR: 649848b8605Smrg return NULL; 650848b8605Smrg default: 651848b8605Smrg return NULL; 652848b8605Smrg } 653848b8605Smrg} 654848b8605Smrg 655848b8605Smrg 656848b8605Smrg/* 657848b8605Smrg * We implement the glEnable function only because we care about 658848b8605Smrg * dither enable/disable. 659848b8605Smrg */ 660848b8605Smrgstatic void 661848b8605Smrgenable( struct gl_context *ctx, GLenum pname, GLboolean state ) 662848b8605Smrg{ 663848b8605Smrg const XMesaContext xmesa = XMESA_CONTEXT(ctx); 664848b8605Smrg 665848b8605Smrg switch (pname) { 666848b8605Smrg case GL_DITHER: 667848b8605Smrg if (state) 668848b8605Smrg xmesa->pixelformat = xmesa->xm_visual->dithered_pf; 669848b8605Smrg else 670848b8605Smrg xmesa->pixelformat = xmesa->xm_visual->undithered_pf; 671848b8605Smrg break; 672848b8605Smrg default: 673848b8605Smrg ; /* silence compiler warning */ 674848b8605Smrg } 675848b8605Smrg} 676848b8605Smrg 677848b8605Smrg 678848b8605Smrg/** 679848b8605Smrg * Called when the driver should update its state, based on the new_state 680848b8605Smrg * flags. 681848b8605Smrg */ 682b8e80941Smrgstatic void 683b8e80941Smrgxmesa_update_state(struct gl_context *ctx) 684848b8605Smrg{ 685b8e80941Smrg GLbitfield new_state = ctx->NewState; 686848b8605Smrg const XMesaContext xmesa = XMESA_CONTEXT(ctx); 687848b8605Smrg 688b8e80941Smrg if (new_state & (_NEW_SCISSOR | _NEW_BUFFERS | _NEW_VIEWPORT)) 689b8e80941Smrg _mesa_update_draw_buffer_bounds(ctx, ctx->DrawBuffer); 690b8e80941Smrg 691848b8605Smrg /* Propagate statechange information to swrast and swrast_setup 692848b8605Smrg * modules. The X11 driver has no internal GL-dependent state. 693848b8605Smrg */ 694848b8605Smrg _swrast_InvalidateState( ctx, new_state ); 695848b8605Smrg _tnl_InvalidateState( ctx, new_state ); 696848b8605Smrg _swsetup_InvalidateState( ctx, new_state ); 697848b8605Smrg 698848b8605Smrg if (_mesa_is_user_fbo(ctx->DrawBuffer)) 699848b8605Smrg return; 700848b8605Smrg 701848b8605Smrg /* 702848b8605Smrg * GL_DITHER, GL_READ/DRAW_BUFFER, buffer binding state, etc. effect 703848b8605Smrg * renderbuffer span/clear funcs. 704848b8605Smrg * Check _NEW_COLOR to detect dither enable/disable. 705848b8605Smrg */ 706848b8605Smrg if (new_state & (_NEW_COLOR | _NEW_BUFFERS)) { 707848b8605Smrg XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); 708848b8605Smrg struct xmesa_renderbuffer *front_xrb, *back_xrb; 709848b8605Smrg 710848b8605Smrg front_xrb = xmbuf->frontxrb; 711848b8605Smrg if (front_xrb) { 712848b8605Smrg front_xrb->clearFunc = clear_pixmap; 713848b8605Smrg } 714848b8605Smrg 715848b8605Smrg back_xrb = xmbuf->backxrb; 716848b8605Smrg if (back_xrb) { 717848b8605Smrg if (xmbuf->backxrb->pixmap) { 718848b8605Smrg back_xrb->clearFunc = clear_pixmap; 719848b8605Smrg } 720848b8605Smrg else { 721848b8605Smrg switch (xmesa->xm_visual->BitsPerPixel) { 722848b8605Smrg case 16: 723848b8605Smrg back_xrb->clearFunc = clear_16bit_ximage; 724848b8605Smrg break; 725848b8605Smrg case 24: 726848b8605Smrg back_xrb->clearFunc = clear_24bit_ximage; 727848b8605Smrg break; 728848b8605Smrg case 32: 729848b8605Smrg back_xrb->clearFunc = clear_32bit_ximage; 730848b8605Smrg break; 731848b8605Smrg default: 732848b8605Smrg back_xrb->clearFunc = clear_nbit_ximage; 733848b8605Smrg break; 734848b8605Smrg } 735848b8605Smrg } 736848b8605Smrg } 737848b8605Smrg } 738848b8605Smrg} 739848b8605Smrg 740848b8605Smrg 741848b8605Smrg/** 742848b8605Smrg * Called by glViewport. 743848b8605Smrg * This is a good time for us to poll the current X window size and adjust 744848b8605Smrg * our renderbuffers to match the current window size. 745848b8605Smrg * Remember, we have no opportunity to respond to conventional 746848b8605Smrg * X Resize/StructureNotify events since the X driver has no event loop. 747848b8605Smrg * Thus, we poll. 748848b8605Smrg * Note that this trick isn't fool-proof. If the application never calls 749848b8605Smrg * glViewport, our notion of the current window size may be incorrect. 750848b8605Smrg * That problem led to the GLX_MESA_resize_buffers extension. 751848b8605Smrg */ 752848b8605Smrgstatic void 753848b8605Smrgxmesa_viewport(struct gl_context *ctx) 754848b8605Smrg{ 755848b8605Smrg XMesaContext xmctx = XMESA_CONTEXT(ctx); 756848b8605Smrg XMesaBuffer xmdrawbuf = XMESA_BUFFER(ctx->WinSysDrawBuffer); 757848b8605Smrg XMesaBuffer xmreadbuf = XMESA_BUFFER(ctx->WinSysReadBuffer); 758848b8605Smrg xmesa_check_and_update_buffer_size(xmctx, xmdrawbuf); 759848b8605Smrg xmesa_check_and_update_buffer_size(xmctx, xmreadbuf); 760848b8605Smrg} 761848b8605Smrg 762848b8605Smrg 763848b8605Smrg#if ENABLE_EXT_timer_query 764848b8605Smrg 765848b8605Smrg/* 766848b8605Smrg * The GL_EXT_timer_query extension is not enabled for the XServer 767848b8605Smrg * indirect renderer. Not sure about how/if wrapping of gettimeofday() 768848b8605Smrg * is done, etc. 769848b8605Smrg */ 770848b8605Smrg 771848b8605Smrgstruct xmesa_query_object 772848b8605Smrg{ 773848b8605Smrg struct gl_query_object Base; 774848b8605Smrg struct timeval StartTime; 775848b8605Smrg}; 776848b8605Smrg 777848b8605Smrg 778848b8605Smrgstatic struct gl_query_object * 779848b8605Smrgxmesa_new_query_object(struct gl_context *ctx, GLuint id) 780848b8605Smrg{ 781848b8605Smrg struct xmesa_query_object *q = CALLOC_STRUCT(xmesa_query_object); 782848b8605Smrg if (q) { 783848b8605Smrg q->Base.Id = id; 784848b8605Smrg q->Base.Ready = GL_TRUE; 785848b8605Smrg } 786848b8605Smrg return &q->Base; 787848b8605Smrg} 788848b8605Smrg 789848b8605Smrg 790848b8605Smrgstatic void 791848b8605Smrgxmesa_begin_query(struct gl_context *ctx, struct gl_query_object *q) 792848b8605Smrg{ 793848b8605Smrg if (q->Target == GL_TIME_ELAPSED_EXT) { 794848b8605Smrg struct xmesa_query_object *xq = (struct xmesa_query_object *) q; 795848b8605Smrg (void) gettimeofday(&xq->StartTime, NULL); 796848b8605Smrg } 797848b8605Smrg} 798848b8605Smrg 799848b8605Smrg 800848b8605Smrg/** 801848b8605Smrg * Return the difference between the two given times in microseconds. 802848b8605Smrg */ 803848b8605Smrgstatic GLuint64EXT 804848b8605Smrgtime_diff(const struct timeval *t0, const struct timeval *t1) 805848b8605Smrg{ 806848b8605Smrg GLuint64EXT seconds0 = t0->tv_sec & 0xff; /* 0 .. 255 seconds */ 807848b8605Smrg GLuint64EXT seconds1 = t1->tv_sec & 0xff; /* 0 .. 255 seconds */ 808848b8605Smrg GLuint64EXT nanosec0 = (seconds0 * 1000000 + t0->tv_usec) * 1000; 809848b8605Smrg GLuint64EXT nanosec1 = (seconds1 * 1000000 + t1->tv_usec) * 1000; 810848b8605Smrg return nanosec1 - nanosec0; 811848b8605Smrg} 812848b8605Smrg 813848b8605Smrg 814848b8605Smrgstatic void 815848b8605Smrgxmesa_end_query(struct gl_context *ctx, struct gl_query_object *q) 816848b8605Smrg{ 817848b8605Smrg if (q->Target == GL_TIME_ELAPSED_EXT) { 818848b8605Smrg struct xmesa_query_object *xq = (struct xmesa_query_object *) q; 819848b8605Smrg struct timeval endTime; 820848b8605Smrg (void) gettimeofday(&endTime, NULL); 821848b8605Smrg /* result is in nanoseconds! */ 822848b8605Smrg q->Result = time_diff(&xq->StartTime, &endTime); 823848b8605Smrg } 824848b8605Smrg q->Ready = GL_TRUE; 825848b8605Smrg} 826848b8605Smrg 827848b8605Smrg#endif /* ENABLE_timer_query */ 828848b8605Smrg 829848b8605Smrg 830848b8605Smrg/** 831848b8605Smrg * Initialize the device driver function table with the functions 832848b8605Smrg * we implement in this driver. 833848b8605Smrg */ 834848b8605Smrgvoid 835848b8605Smrgxmesa_init_driver_functions( XMesaVisual xmvisual, 836848b8605Smrg struct dd_function_table *driver ) 837848b8605Smrg{ 838848b8605Smrg driver->GetString = get_string; 839848b8605Smrg driver->UpdateState = xmesa_update_state; 840848b8605Smrg driver->Flush = finish_or_flush; 841848b8605Smrg driver->Finish = finish_or_flush; 842848b8605Smrg driver->ColorMask = color_mask; 843848b8605Smrg driver->Enable = enable; 844848b8605Smrg driver->Viewport = xmesa_viewport; 845848b8605Smrg if (TEST_META_FUNCS) { 846848b8605Smrg driver->Clear = _mesa_meta_Clear; 847848b8605Smrg driver->CopyPixels = _mesa_meta_CopyPixels; 848848b8605Smrg driver->BlitFramebuffer = _mesa_meta_and_swrast_BlitFramebuffer; 849848b8605Smrg driver->DrawPixels = _mesa_meta_DrawPixels; 850848b8605Smrg driver->Bitmap = _mesa_meta_Bitmap; 851848b8605Smrg } 852848b8605Smrg else { 853848b8605Smrg driver->Clear = clear_buffers; 854848b8605Smrg driver->CopyPixels = xmesa_CopyPixels; 855848b8605Smrg if (xmvisual->undithered_pf == PF_8R8G8B && 856848b8605Smrg xmvisual->dithered_pf == PF_8R8G8B && 857848b8605Smrg xmvisual->BitsPerPixel == 32) { 858848b8605Smrg driver->DrawPixels = xmesa_DrawPixels_8R8G8B; 859848b8605Smrg } 860848b8605Smrg else if (xmvisual->undithered_pf == PF_5R6G5B) { 861848b8605Smrg driver->DrawPixels = xmesa_DrawPixels_5R6G5B; 862848b8605Smrg } 863848b8605Smrg } 864848b8605Smrg 865848b8605Smrg driver->MapRenderbuffer = xmesa_MapRenderbuffer; 866848b8605Smrg driver->UnmapRenderbuffer = xmesa_UnmapRenderbuffer; 867848b8605Smrg 868848b8605Smrg driver->GenerateMipmap = _mesa_generate_mipmap; 869848b8605Smrg 870848b8605Smrg#if ENABLE_EXT_timer_query 871848b8605Smrg driver->NewQueryObject = xmesa_new_query_object; 872848b8605Smrg driver->BeginQuery = xmesa_begin_query; 873848b8605Smrg driver->EndQuery = xmesa_end_query; 874848b8605Smrg#endif 875848b8605Smrg} 876848b8605Smrg 877848b8605Smrg 878848b8605Smrg#define XMESA_NEW_POINT (_NEW_POINT | \ 879848b8605Smrg _NEW_RENDERMODE | \ 880848b8605Smrg _SWRAST_NEW_RASTERMASK) 881848b8605Smrg 882848b8605Smrg#define XMESA_NEW_LINE (_NEW_LINE | \ 883848b8605Smrg _NEW_TEXTURE | \ 884848b8605Smrg _NEW_LIGHT | \ 885848b8605Smrg _NEW_DEPTH | \ 886848b8605Smrg _NEW_RENDERMODE | \ 887848b8605Smrg _SWRAST_NEW_RASTERMASK) 888848b8605Smrg 889848b8605Smrg#define XMESA_NEW_TRIANGLE (_NEW_POLYGON | \ 890848b8605Smrg _NEW_TEXTURE | \ 891848b8605Smrg _NEW_LIGHT | \ 892848b8605Smrg _NEW_DEPTH | \ 893848b8605Smrg _NEW_RENDERMODE | \ 894848b8605Smrg _SWRAST_NEW_RASTERMASK) 895848b8605Smrg 896848b8605Smrg 897848b8605Smrg/** 898848b8605Smrg * Extend the software rasterizer with our line/point/triangle 899848b8605Smrg * functions. 900848b8605Smrg * Called during context creation only. 901848b8605Smrg */ 902848b8605Smrgvoid xmesa_register_swrast_functions( struct gl_context *ctx ) 903848b8605Smrg{ 904848b8605Smrg SWcontext *swrast = SWRAST_CONTEXT( ctx ); 905848b8605Smrg 906848b8605Smrg swrast->choose_point = xmesa_choose_point; 907848b8605Smrg swrast->choose_line = xmesa_choose_line; 908848b8605Smrg swrast->choose_triangle = xmesa_choose_triangle; 909848b8605Smrg 910848b8605Smrg /* XXX these lines have no net effect. Remove??? */ 911848b8605Smrg swrast->InvalidatePointMask |= XMESA_NEW_POINT; 912848b8605Smrg swrast->InvalidateLineMask |= XMESA_NEW_LINE; 913848b8605Smrg swrast->InvalidateTriangleMask |= XMESA_NEW_TRIANGLE; 914848b8605Smrg} 915