xm_dd.c revision ef8244df1a195f227b1cdf2f944b7fd7a9917adf
1/* 2 * Mesa 3-D graphics library 3 * Version: 6.5.1 4 * 5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 26#include "glxheader.h" 27#include "bufferobj.h" 28#include "buffers.h" 29#include "context.h" 30#include "colormac.h" 31#include "depth.h" 32#include "drawpix.h" 33#include "extensions.h" 34#include "framebuffer.h" 35#include "macros.h" 36#include "image.h" 37#include "imports.h" 38#include "mtypes.h" 39#include "state.h" 40#include "texobj.h" 41#include "teximage.h" 42#include "texstore.h" 43#include "texformat.h" 44#include "xmesaP.h" 45#include "array_cache/acache.h" 46#include "swrast/swrast.h" 47#include "swrast/s_context.h" 48#include "swrast_setup/swrast_setup.h" 49#include "tnl/tnl.h" 50#include "tnl/t_context.h" 51 52#ifdef XFree86Server 53#include <GL/glxtokens.h> 54#endif 55 56 57 58/* 59 * Dithering kernels and lookup tables. 60 */ 61 62const int xmesa_kernel8[DITH_DY * DITH_DX] = { 63 0 * MAXC, 8 * MAXC, 2 * MAXC, 10 * MAXC, 64 12 * MAXC, 4 * MAXC, 14 * MAXC, 6 * MAXC, 65 3 * MAXC, 11 * MAXC, 1 * MAXC, 9 * MAXC, 66 15 * MAXC, 7 * MAXC, 13 * MAXC, 5 * MAXC, 67}; 68 69const short xmesa_HPCR_DRGB[3][2][16] = { 70 { 71 { 16, -4, 1,-11, 14, -6, 3, -9, 15, -5, 2,-10, 13, -7, 4, -8}, 72 {-15, 5, 0, 12,-13, 7, -2, 10,-14, 6, -1, 11,-12, 8, -3, 9} 73 }, 74 { 75 {-11, 15, -7, 3, -8, 14, -4, 2,-10, 16, -6, 4, -9, 13, -5, 1}, 76 { 12,-14, 8, -2, 9,-13, 5, -1, 11,-15, 7, -3, 10,-12, 6, 0} 77 }, 78 { 79 { 6,-18, 26,-14, 2,-22, 30,-10, 8,-16, 28,-12, 4,-20, 32, -8}, 80 { -4, 20,-24, 16, 0, 24,-28, 12, -6, 18,-26, 14, -2, 22,-30, 10} 81 } 82}; 83 84const int xmesa_kernel1[16] = { 85 0*47, 9*47, 4*47, 12*47, /* 47 = (255*3)/16 */ 86 6*47, 2*47, 14*47, 8*47, 87 10*47, 1*47, 5*47, 11*47, 88 7*47, 13*47, 3*47, 15*47 89}; 90 91 92/* 93 * Return the size (width, height) of the X window for the given GLframebuffer. 94 * Output: width - width of buffer in pixels. 95 * height - height of buffer in pixels. 96 */ 97static void 98get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height ) 99{ 100 /* We can do this cast because the first field in the XMesaBuffer 101 * struct is a GLframebuffer struct. If this weren't true, we'd 102 * need a pointer from the GLframebuffer to the XMesaBuffer. 103 */ 104 const XMesaBuffer xmBuffer = (XMesaBuffer) buffer; 105 unsigned int winwidth, winheight; 106#ifdef XFree86Server 107 /* XFree86 GLX renderer */ 108 winwidth = MIN2(xmBuffer->frontxrb->drawable->width, MAX_WIDTH); 109 winheight = MIN2(xmBuffer->frontxrb->drawable->height, MAX_HEIGHT); 110#else 111 Window root; 112 Status stat; 113 int winx, winy; 114 unsigned int bw, d; 115 116 _glthread_LOCK_MUTEX(_xmesa_lock); 117 XSync(xmBuffer->xm_visual->display, 0); /* added for Chromium */ 118 119 stat = XGetGeometry( xmBuffer->xm_visual->display, xmBuffer->frontxrb->pixmap, 120 &root, &winx, &winy, &winwidth, &winheight, &bw, &d ); 121 _glthread_UNLOCK_MUTEX(_xmesa_lock); 122 123 if (!stat) { 124 /* probably querying a window that's recently been destroyed */ 125 _mesa_warning(NULL, "XGetGeometry failed!\n"); 126 *width = *height = 1; 127 return; 128 } 129#endif 130 131 *width = winwidth; 132 *height = winheight; 133} 134 135 136static void 137finish_or_flush( GLcontext *ctx ) 138{ 139#ifdef XFree86Server 140 /* NOT_NEEDED */ 141#else 142 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 143 if (xmesa) { 144 _glthread_LOCK_MUTEX(_xmesa_lock); 145 XSync( xmesa->display, False ); 146 _glthread_UNLOCK_MUTEX(_xmesa_lock); 147 } 148#endif 149} 150 151 152static void 153clear_index( GLcontext *ctx, GLuint index ) 154{ 155 if (ctx->DrawBuffer->Name == 0) { 156 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 157 XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); 158 xmesa->clearpixel = (unsigned long) index; 159 XMesaSetForeground( xmesa->display, xmbuf->cleargc, (unsigned long) index ); 160 } 161} 162 163 164static void 165clear_color( GLcontext *ctx, const GLfloat color[4] ) 166{ 167 if (ctx->DrawBuffer->Name == 0) { 168 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 169 XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); 170 171 CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color[0]); 172 CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color[1]); 173 CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color[2]); 174 CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color[3]); 175 xmesa->clearpixel = xmesa_color_to_pixel( ctx, 176 xmesa->clearcolor[0], 177 xmesa->clearcolor[1], 178 xmesa->clearcolor[2], 179 xmesa->clearcolor[3], 180 xmesa->xm_visual->undithered_pf ); 181 _glthread_LOCK_MUTEX(_xmesa_lock); 182 XMesaSetForeground( xmesa->display, xmbuf->cleargc, 183 xmesa->clearpixel ); 184 _glthread_UNLOCK_MUTEX(_xmesa_lock); 185 } 186} 187 188 189 190/* Set index mask ala glIndexMask */ 191static void 192index_mask( GLcontext *ctx, GLuint mask ) 193{ 194 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 195 XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); 196 /* not sure this conditional is really needed */ 197 if (xmbuf->backxrb && xmbuf->backxrb->pixmap) { 198 unsigned long m; 199 if (mask==0xffffffff) { 200 m = ((unsigned long)~0L); 201 } 202 else { 203 m = (unsigned long) mask; 204 } 205 XMesaSetPlaneMask( xmesa->display, xmbuf->cleargc, m ); 206 XMesaSetPlaneMask( xmesa->display, xmbuf->gc, m ); 207 } 208} 209 210 211/* Implements glColorMask() */ 212static void 213color_mask(GLcontext *ctx, 214 GLboolean rmask, GLboolean gmask, GLboolean bmask, GLboolean amask) 215{ 216 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 217 XMesaBuffer xmbuf; 218 const int xclass = xmesa->xm_visual->mesa_visual.visualType; 219 (void) amask; 220 221 if (ctx->DrawBuffer->Name != 0) 222 return; 223 224 xmbuf = XMESA_BUFFER(ctx->DrawBuffer); 225 226 if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) { 227 unsigned long m; 228 if (rmask && gmask && bmask) { 229 m = ((unsigned long)~0L); 230 } 231 else { 232 m = 0; 233 if (rmask) m |= GET_REDMASK(xmesa->xm_visual); 234 if (gmask) m |= GET_GREENMASK(xmesa->xm_visual); 235 if (bmask) m |= GET_BLUEMASK(xmesa->xm_visual); 236 } 237 XMesaSetPlaneMask( xmesa->display, xmbuf->cleargc, m ); 238 XMesaSetPlaneMask( xmesa->display, xmbuf->gc, m ); 239 } 240} 241 242 243 244/**********************************************************************/ 245/*** glClear implementations ***/ 246/**********************************************************************/ 247 248 249/** 250 * Clear the front or back color buffer, if it's implemented with a pixmap. 251 */ 252static void 253clear_pixmap(GLcontext *ctx, struct xmesa_renderbuffer *xrb, GLboolean all, 254 GLint x, GLint y, GLint width, GLint height) 255{ 256 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 257 XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); 258 259 assert(xmbuf); 260 assert(xrb->pixmap); 261 assert(xmesa); 262 assert(xmesa->display); 263 assert(xrb->pixmap); 264 assert(xmbuf->cleargc); 265 266 if (all) { 267 XMesaFillRectangle( xmesa->display, xrb->pixmap, xmbuf->cleargc, 268 0, 0, xrb->Base.Width + 1, xrb->Base.Height + 1 ); 269 } 270 else { 271 XMesaFillRectangle( xmesa->display, xrb->pixmap, xmbuf->cleargc, 272 x, xrb->Base.Height - y - height, 273 width, height ); 274 } 275} 276 277 278static void 279clear_8bit_ximage( GLcontext *ctx, struct xmesa_renderbuffer *xrb, 280 GLboolean all, GLint x, GLint y, GLint width, GLint height ) 281{ 282 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 283 284 if (all) { 285 const size_t n = xrb->ximage->bytes_per_line * xrb->Base.Height; 286 MEMSET( xrb->ximage->data, xmesa->clearpixel, n ); 287 } 288 else { 289 GLint i; 290 for (i=0;i<height;i++) { 291 GLubyte *ptr = PIXEL_ADDR1(xrb, x, y + i); 292 MEMSET( ptr, xmesa->clearpixel, width ); 293 } 294 } 295} 296 297 298static void 299clear_HPCR_ximage( GLcontext *ctx, struct xmesa_renderbuffer *xrb, 300 GLboolean all, GLint x, GLint y, GLint width, GLint height ) 301{ 302 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 303 304 if (all) { 305 const GLuint c16 = xrb->ximage->bytes_per_line & ~0xf; 306 GLuint i; 307 GLubyte *ptr = (GLubyte *) xrb->ximage->data; 308 for (i = 0; i < xrb->Base.Height; i++) { 309 GLuint j; 310 const GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0]; 311 if (i&1) { 312 sptr += 16; 313 } 314 for (j=0; j<c16; j+=16) { 315 ptr[0] = sptr[0]; 316 ptr[1] = sptr[1]; 317 ptr[2] = sptr[2]; 318 ptr[3] = sptr[3]; 319 ptr[4] = sptr[4]; 320 ptr[5] = sptr[5]; 321 ptr[6] = sptr[6]; 322 ptr[7] = sptr[7]; 323 ptr[8] = sptr[8]; 324 ptr[9] = sptr[9]; 325 ptr[10] = sptr[10]; 326 ptr[11] = sptr[11]; 327 ptr[12] = sptr[12]; 328 ptr[13] = sptr[13]; 329 ptr[14] = sptr[14]; 330 ptr[15] = sptr[15]; 331 ptr += 16; 332 } 333 for (; j < (GLuint) xrb->ximage->bytes_per_line; j++) { 334 *ptr = sptr[j&15]; 335 ptr++; 336 } 337 } 338 } 339 else { 340 GLint i; 341 for (i=y; i<y+height; i++) { 342 GLubyte *ptr = PIXEL_ADDR1( xrb, x, i ); 343 int j; 344 const GLubyte *sptr = xmesa->xm_visual->hpcr_clear_ximage_pattern[0]; 345 if (i&1) { 346 sptr += 16; 347 } 348 for (j=x; j<x+width; j++) { 349 *ptr = sptr[j&15]; 350 ptr++; 351 } 352 } 353 } 354} 355 356 357static void 358clear_16bit_ximage( GLcontext *ctx, struct xmesa_renderbuffer *xrb, 359 GLboolean all, GLint x, GLint y, GLint width, GLint height) 360{ 361 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 362 register GLuint pixel = (GLuint) xmesa->clearpixel; 363 364 if (xmesa->swapbytes) { 365 pixel = ((pixel >> 8) & 0x00ff) | ((pixel << 8) & 0xff00); 366 } 367 368 if (all) { 369 GLuint *ptr4 = (GLuint *) xrb->ximage->data; 370 if ((pixel & 0xff) == ((pixel >> 8) & 0xff)) { 371 /* low and high bytes are equal so use memset() */ 372 const GLuint n = xrb->ximage->bytes_per_line * xrb->Base.Height; 373 MEMSET( ptr4, pixel & 0xff, n ); 374 } 375 else { 376 const GLuint n = xrb->ximage->bytes_per_line * xrb->Base.Height / 4; 377 GLuint i; 378 pixel = pixel | (pixel<<16); 379 for (i = 0; i < n; i++) { 380 ptr4[i] = pixel; 381 } 382 ptr4 += n; 383 /* might be one last GLushort to set */ 384 if ((xrb->ximage->bytes_per_line * xrb->Base.Height) & 0x2) 385 *(GLushort *)ptr4 = pixel & 0xffff; 386 } 387 } 388 else { 389 GLint i, j; 390 for (j=0;j<height;j++) { 391 GLushort *ptr2 = PIXEL_ADDR2(xrb, x, y + j); 392 for (i=0;i<width;i++) { 393 *ptr2++ = pixel; 394 } 395 } 396 } 397} 398 399 400/* Optimized code provided by Nozomi Ytow <noz@xfree86.org> */ 401static void 402clear_24bit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb, 403 GLboolean all, GLint x, GLint y, GLint width, GLint height) 404{ 405 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 406 const GLubyte r = xmesa->clearcolor[0]; 407 const GLubyte g = xmesa->clearcolor[1]; 408 const GLubyte b = xmesa->clearcolor[2]; 409 410 if (all) { 411 if (r == g && g == b) { 412 /* same value for all three components (gray) */ 413 const GLint w3 = xrb->Base.Width * 3; 414 const GLint h = xrb->Base.Height; 415 GLint i; 416 for (i = 0; i < h; i++) { 417 bgr_t *ptr3 = PIXEL_ADDR3(xrb, 0, i); 418 MEMSET(ptr3, r, w3); 419 } 420 } 421 else { 422 /* the usual case */ 423 const GLint w = xrb->Base.Width; 424 const GLint h = xrb->Base.Height; 425 GLint i, j; 426 for (i = 0; i < h; i++) { 427 bgr_t *ptr3 = PIXEL_ADDR3(xrb, 0, i); 428 for (j = 0; j < w; j++) { 429 ptr3->r = r; 430 ptr3->g = g; 431 ptr3->b = b; 432 ptr3++; 433 } 434 } 435 } 436 } 437 else { 438 /* only clear subrect of color buffer */ 439 if (r == g && g == b) { 440 /* same value for all three components (gray) */ 441 GLint j; 442 for (j=0;j<height;j++) { 443 bgr_t *ptr3 = PIXEL_ADDR3(xrb, x, y + j); 444 MEMSET(ptr3, r, 3 * width); 445 } 446 } 447 else { 448 /* non-gray clear color */ 449 GLint i, j; 450 for (j = 0; j < height; j++) { 451 bgr_t *ptr3 = PIXEL_ADDR3(xrb, x, y + j); 452 for (i = 0; i < width; i++) { 453 ptr3->r = r; 454 ptr3->g = g; 455 ptr3->b = b; 456 ptr3++; 457 } 458 } 459 } 460 } 461} 462 463 464static void 465clear_32bit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb, 466 GLboolean all, GLint x, GLint y, GLint width, GLint height) 467{ 468 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 469 register GLuint pixel = (GLuint) xmesa->clearpixel; 470 471 if (!xrb->ximage) 472 return; 473 474 if (xmesa->swapbytes) { 475 pixel = ((pixel >> 24) & 0x000000ff) 476 | ((pixel >> 8) & 0x0000ff00) 477 | ((pixel << 8) & 0x00ff0000) 478 | ((pixel << 24) & 0xff000000); 479 } 480 481 if (all) { 482 const GLuint n = xrb->Base.Width * xrb->Base.Height; 483 GLuint *ptr4 = (GLuint *) xrb->ximage->data; 484 if (pixel == 0) { 485 _mesa_memset(ptr4, pixel, 4 * n); 486 } 487 else { 488 GLuint i; 489 for (i = 0; i < n; i++) 490 ptr4[i] = pixel; 491 } 492 } 493 else { 494 GLint i, j; 495 for (j = 0; j < height; j++) { 496 GLuint *ptr4 = PIXEL_ADDR4(xrb, x, y + j); 497 for (i = 0; i < width; i++) { 498 ptr4[i] = pixel; 499 } 500 } 501 } 502} 503 504 505static void 506clear_nbit_ximage(GLcontext *ctx, struct xmesa_renderbuffer *xrb, 507 GLboolean all, GLint x, GLint y, GLint width, GLint height) 508{ 509 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 510 XMesaImage *img = xrb->ximage; 511 GLint i, j; 512 513 /* We can ignore 'all' here - x, y, width, height are always right */ 514 (void) all; 515 516 /* TODO: optimize this */ 517 y = YFLIP(xrb, y); 518 for (j = 0; j < height; j++) { 519 for (i = 0; i < width; i++) { 520 XMesaPutPixel(img, x+i, y-j, xmesa->clearpixel); 521 } 522 } 523} 524 525 526 527static void 528clear_buffers( GLcontext *ctx, GLbitfield mask, 529 GLboolean all, GLint x, GLint y, GLint width, GLint height ) 530{ 531 if (ctx->DrawBuffer->Name == 0) { 532 /* this is a window system framebuffer */ 533 const GLuint *colorMask = (GLuint *) &ctx->Color.ColorMask; 534 XMesaBuffer b = XMESA_BUFFER(ctx->DrawBuffer); 535 536 /* we can't handle color or index masking */ 537 if (*colorMask == 0xffffffff && ctx->Color.IndexMask == 0xffffffff) { 538 if (mask & BUFFER_BIT_FRONT_LEFT) { 539 /* clear front color buffer */ 540 struct gl_renderbuffer *frontRb 541 = ctx->DrawBuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer; 542 if (b->frontxrb == xmesa_renderbuffer(frontRb)) { 543 /* renderbuffer is not wrapped - great! */ 544 b->frontxrb->clearFunc(ctx, b->frontxrb, all, x, y, 545 width, height); 546 mask &= ~BUFFER_BIT_FRONT_LEFT; 547 } 548 else { 549 /* we can't directly clear an alpha-wrapped color buffer */ 550 } 551 } 552 if (mask & BUFFER_BIT_BACK_LEFT) { 553 /* clear back color buffer */ 554 struct gl_renderbuffer *backRb 555 = ctx->DrawBuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer; 556 if (b->backxrb == xmesa_renderbuffer(backRb)) { 557 /* renderbuffer is not wrapped - great! */ 558 b->backxrb->clearFunc(ctx, b->backxrb, all, x, y, 559 width, height); 560 mask &= ~BUFFER_BIT_BACK_LEFT; 561 } 562 } 563 } 564 } 565 if (mask) 566 _swrast_Clear( ctx, mask, all, x, y, width, height ); 567} 568 569 570/** 571 * Called by ctx->Driver.ResizeBuffers() 572 * Resize the front/back colorbuffers to match the latest window size. 573 */ 574void 575xmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer, 576 GLuint width, GLuint height) 577{ 578 /* We can do this cast because the first field in the XMesaBuffer 579 * struct is a GLframebuffer struct. If this weren't true, we'd 580 * need a pointer from the GLframebuffer to the XMesaBuffer. 581 */ 582 XMesaBuffer xmBuffer = (XMesaBuffer) buffer; 583 584 xmesa_alloc_back_buffer(xmBuffer, width, height); 585 586 _mesa_resize_framebuffer(ctx, buffer, width, height); 587} 588 589 590#ifndef XFree86Server 591/* XXX this was never tested in the Xserver environment */ 592 593/** 594 * This function implements glDrawPixels() with an XPutImage call when 595 * drawing to the front buffer (X Window drawable). 596 * The image format must be GL_BGRA to match the PF_8R8G8B pixel format. 597 */ 598static void 599xmesa_DrawPixels_8R8G8B( GLcontext *ctx, 600 GLint x, GLint y, GLsizei width, GLsizei height, 601 GLenum format, GLenum type, 602 const struct gl_pixelstore_attrib *unpack, 603 const GLvoid *pixels ) 604{ 605 struct xmesa_renderbuffer *xrb 606 = (struct xmesa_renderbuffer *) ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped; 607 608 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 609 const SWcontext *swrast = SWRAST_CONTEXT( ctx ); 610 XMesaDisplay *dpy = xmesa->xm_visual->display; 611 XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); 612 const XMesaGC gc = xmbuf->gc; 613 614 ASSERT(dpy); 615 ASSERT(gc); 616 ASSERT(xmesa->xm_visual->dithered_pf == PF_8R8G8B); 617 ASSERT(xmesa->xm_visual->undithered_pf == PF_8R8G8B); 618 619 if (swrast->NewState) 620 _swrast_validate_derived( ctx ); 621 622 if (xrb->pixmap && 623 xrb->Base.AlphaBits == 0 && 624 format == GL_BGRA && 625 type == GL_UNSIGNED_BYTE && 626 (swrast->_RasterMask & ~CLIP_BIT) == 0 && /* no blend, z-test, etc */ 627 ctx->_ImageTransferState == 0 && /* no color tables, scale/bias, etc */ 628 ctx->Pixel.ZoomX == 1.0 && /* no zooming */ 629 ctx->Pixel.ZoomY == 1.0) { 630 int dstX = x; 631 int dstY = y; 632 int w = width; 633 int h = height; 634 struct gl_pixelstore_attrib clippedUnpack = *unpack; 635 636 if (unpack->BufferObj->Name) { 637 /* unpack from PBO */ 638 GLubyte *buf; 639 if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, 640 format, type, pixels)) { 641 _mesa_error(ctx, GL_INVALID_OPERATION, 642 "glDrawPixels(invalid PBO access)"); 643 return; 644 } 645 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, 646 GL_PIXEL_UNPACK_BUFFER_EXT, 647 GL_READ_ONLY_ARB, 648 unpack->BufferObj); 649 if (!buf) { 650 /* buffer is already mapped - that's an error */ 651 _mesa_error(ctx, GL_INVALID_OPERATION, 652 "glDrawPixels(PBO is mapped)"); 653 return; 654 } 655 pixels = ADD_POINTERS(buf, pixels); 656 } 657 658 if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &clippedUnpack)) { 659 /* This is a little tricky since all coordinates up to now have 660 * been in the OpenGL bottom-to-top orientation. X is top-to-bottom 661 * so we have to carefully compute the Y coordinates/addresses here. 662 */ 663 int srcX = clippedUnpack.SkipPixels; 664 int srcY = clippedUnpack.SkipRows; 665 int rowLength = clippedUnpack.RowLength; 666 XMesaImage ximage; 667 MEMSET(&ximage, 0, sizeof(XMesaImage)); 668 ximage.width = width; 669 ximage.height = height; 670 ximage.format = ZPixmap; 671 ximage.data = (char *) pixels 672 + ((srcY + h - 1) * rowLength + srcX) * 4; 673 ximage.byte_order = LSBFirst; 674 ximage.bitmap_unit = 32; 675 ximage.bitmap_bit_order = LSBFirst; 676 ximage.bitmap_pad = 32; 677 ximage.depth = 24; 678 ximage.bytes_per_line = -rowLength * 4; /* negative to flip image */ 679 ximage.bits_per_pixel = 32; 680 /* it seems we don't need to set the ximage.red/green/blue_mask fields */ 681 /* flip Y axis for dest position */ 682 dstY = YFLIP(xrb, dstY) - h + 1; 683 XPutImage(dpy, xrb->pixmap, gc, &ximage, 0, 0, dstX, dstY, w, h); 684 } 685 686 if (unpack->BufferObj->Name) { 687 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, 688 unpack->BufferObj); 689 } 690 } 691 else { 692 /* software fallback */ 693 _swrast_DrawPixels(ctx, x, y, width, height, 694 format, type, unpack, pixels); 695 } 696} 697 698 699 700/** 701 * This function implements glDrawPixels() with an XPutImage call when 702 * drawing to the front buffer (X Window drawable). The image format 703 * must be GL_RGB and image type must be GL_UNSIGNED_SHORT_5_6_5 to 704 * match the PF_5R6G5B pixel format. 705 */ 706static void 707xmesa_DrawPixels_5R6G5B( GLcontext *ctx, 708 GLint x, GLint y, GLsizei width, GLsizei height, 709 GLenum format, GLenum type, 710 const struct gl_pixelstore_attrib *unpack, 711 const GLvoid *pixels ) 712{ 713 struct xmesa_renderbuffer *xrb 714 = (struct xmesa_renderbuffer *) ctx->DrawBuffer->_ColorDrawBuffers[0][0]; 715 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 716 const SWcontext *swrast = SWRAST_CONTEXT( ctx ); 717 XMesaDisplay *dpy = xmesa->xm_visual->display; 718 XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); 719 const XMesaGC gc = xmbuf->gc; 720 721 ASSERT(dpy); 722 ASSERT(gc); 723 ASSERT(xmesa->xm_visual->undithered_pf == PF_5R6G5B); 724 725 if (swrast->NewState) 726 _swrast_validate_derived( ctx ); 727 728 if (xrb->pixmap && 729 format == GL_RGB && 730 type == GL_UNSIGNED_SHORT_5_6_5 && 731 !ctx->Color.DitherFlag && /* no dithering */ 732 (swrast->_RasterMask & ~CLIP_BIT) == 0 && /* no blend, z-test, etc */ 733 ctx->_ImageTransferState == 0 && /* no color tables, scale/bias, etc */ 734 ctx->Pixel.ZoomX == 1.0 && /* no zooming */ 735 ctx->Pixel.ZoomY == 1.0) { 736 int dstX = x; 737 int dstY = y; 738 int w = width; 739 int h = height; 740 struct gl_pixelstore_attrib clippedUnpack = *unpack; 741 742 if (unpack->BufferObj->Name) { 743 /* unpack from PBO */ 744 GLubyte *buf; 745 if (!_mesa_validate_pbo_access(2, unpack, width, height, 1, 746 format, type, pixels)) { 747 _mesa_error(ctx, GL_INVALID_OPERATION, 748 "glDrawPixels(invalid PBO access)"); 749 return; 750 } 751 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, 752 GL_PIXEL_UNPACK_BUFFER_EXT, 753 GL_READ_ONLY_ARB, 754 unpack->BufferObj); 755 if (!buf) { 756 /* buffer is already mapped - that's an error */ 757 _mesa_error(ctx, GL_INVALID_OPERATION, 758 "glDrawPixels(PBO is mapped)"); 759 return; 760 } 761 pixels = ADD_POINTERS(buf, pixels); 762 } 763 764 if (_mesa_clip_drawpixels(ctx, &dstX, &dstY, &w, &h, &clippedUnpack)) { 765 /* This is a little tricky since all coordinates up to now have 766 * been in the OpenGL bottom-to-top orientation. X is top-to-bottom 767 * so we have to carefully compute the Y coordinates/addresses here. 768 */ 769 int srcX = clippedUnpack.SkipPixels; 770 int srcY = clippedUnpack.SkipRows; 771 int rowLength = clippedUnpack.RowLength; 772 XMesaImage ximage; 773 MEMSET(&ximage, 0, sizeof(XMesaImage)); 774 ximage.width = width; 775 ximage.height = height; 776 ximage.format = ZPixmap; 777 ximage.data = (char *) pixels 778 + ((srcY + h - 1) * rowLength + srcX) * 2; 779 ximage.byte_order = LSBFirst; 780 ximage.bitmap_unit = 16; 781 ximage.bitmap_bit_order = LSBFirst; 782 ximage.bitmap_pad = 16; 783 ximage.depth = 16; 784 ximage.bytes_per_line = -rowLength * 2; /* negative to flip image */ 785 ximage.bits_per_pixel = 16; 786 /* it seems we don't need to set the ximage.red/green/blue_mask fields */ 787 /* flip Y axis for dest position */ 788 dstY = YFLIP(xrb, dstY) - h + 1; 789 XPutImage(dpy, xrb->pixmap, gc, &ximage, 0, 0, dstX, dstY, w, h); 790 } 791 792 if (unpack->BufferObj->Name) { 793 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT, 794 unpack->BufferObj); 795 } 796 } 797 else { 798 /* software fallback */ 799 _swrast_DrawPixels(ctx, x, y, width, height, 800 format, type, unpack, pixels); 801 } 802} 803 804 805 806/** 807 * Implement glCopyPixels for the front color buffer (or back buffer Pixmap) 808 * for the color buffer. Don't support zooming, pixel transfer, etc. 809 * We do support copying from one window to another, ala glXMakeCurrentRead. 810 */ 811static void 812xmesa_CopyPixels( GLcontext *ctx, 813 GLint srcx, GLint srcy, GLsizei width, GLsizei height, 814 GLint destx, GLint desty, GLenum type ) 815{ 816 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 817 const SWcontext *swrast = SWRAST_CONTEXT( ctx ); 818 XMesaDisplay *dpy = xmesa->xm_visual->display; 819 const XMesaGC gc = ((XMesaBuffer) ctx->DrawBuffer)->gc; 820 struct xmesa_renderbuffer *srcXrb = (struct xmesa_renderbuffer *) 821 ctx->ReadBuffer->_ColorReadBuffer; 822 struct xmesa_renderbuffer *dstXrb = (struct xmesa_renderbuffer *) 823 ctx->DrawBuffer->_ColorDrawBuffers[0][0]; 824 825 ASSERT(dpy); 826 ASSERT(gc); 827 828 if (swrast->NewState) 829 _swrast_validate_derived( ctx ); 830 831 if (ctx->Color.DrawBuffer[0] == GL_FRONT && 832 ctx->Pixel.ReadBuffer == GL_FRONT && 833 srcXrb->pixmap && 834 dstXrb->pixmap && 835 type == GL_COLOR && 836 (swrast->_RasterMask & ~CLIP_BIT) == 0 && /* no blend, z-test, etc */ 837 ctx->_ImageTransferState == 0 && /* no color tables, scale/bias, etc */ 838 ctx->Pixel.ZoomX == 1.0 && /* no zooming */ 839 ctx->Pixel.ZoomY == 1.0) { 840 /* Note: we don't do any special clipping work here. We could, 841 * but X will do it for us. 842 */ 843 srcy = YFLIP(srcXrb, srcy) - height + 1; 844 desty = YFLIP(dstXrb, desty) - height + 1; 845 XCopyArea(dpy, srcXrb->pixmap, dstXrb->pixmap, gc, 846 srcx, srcy, width, height, destx, desty); 847 } 848 else { 849 _swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type ); 850 } 851} 852#endif /* XFree86Server */ 853 854 855 856/* 857 * Every driver should implement a GetString function in order to 858 * return a meaningful GL_RENDERER string. 859 */ 860static const GLubyte * 861get_string( GLcontext *ctx, GLenum name ) 862{ 863 (void) ctx; 864 switch (name) { 865 case GL_RENDERER: 866#ifdef XFree86Server 867 return (const GLubyte *) "Mesa GLX Indirect"; 868#else 869 return (const GLubyte *) "Mesa X11"; 870#endif 871 case GL_VENDOR: 872#ifdef XFree86Server 873 return (const GLubyte *) "Mesa project: www.mesa3d.org"; 874#else 875 return NULL; 876#endif 877 default: 878 return NULL; 879 } 880} 881 882 883/* 884 * We implement the glEnable function only because we care about 885 * dither enable/disable. 886 */ 887static void 888enable( GLcontext *ctx, GLenum pname, GLboolean state ) 889{ 890 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 891 892 switch (pname) { 893 case GL_DITHER: 894 if (state) 895 xmesa->pixelformat = xmesa->xm_visual->dithered_pf; 896 else 897 xmesa->pixelformat = xmesa->xm_visual->undithered_pf; 898 break; 899 default: 900 ; /* silence compiler warning */ 901 } 902} 903 904 905static void 906clear_color_HPCR_ximage( GLcontext *ctx, const GLfloat color[4] ) 907{ 908 int i; 909 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 910 911 CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color[0]); 912 CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color[1]); 913 CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color[2]); 914 CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color[3]); 915 916 if (color[0] == 0.0 && color[1] == 0.0 && color[2] == 0.0) { 917 /* black is black */ 918 MEMSET( xmesa->xm_visual->hpcr_clear_ximage_pattern, 0x0 , 919 sizeof(xmesa->xm_visual->hpcr_clear_ximage_pattern)); 920 } 921 else { 922 /* build clear pattern */ 923 for (i=0; i<16; i++) { 924 xmesa->xm_visual->hpcr_clear_ximage_pattern[0][i] = 925 DITHER_HPCR(i, 0, 926 xmesa->clearcolor[0], 927 xmesa->clearcolor[1], 928 xmesa->clearcolor[2]); 929 xmesa->xm_visual->hpcr_clear_ximage_pattern[1][i] = 930 DITHER_HPCR(i, 1, 931 xmesa->clearcolor[0], 932 xmesa->clearcolor[1], 933 xmesa->clearcolor[2]); 934 } 935 } 936} 937 938 939static void 940clear_color_HPCR_pixmap( GLcontext *ctx, const GLfloat color[4] ) 941{ 942 int i; 943 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 944 945 CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[0], color[0]); 946 CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[1], color[1]); 947 CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[2], color[2]); 948 CLAMPED_FLOAT_TO_UBYTE(xmesa->clearcolor[3], color[3]); 949 950 if (color[0] == 0.0 && color[1] == 0.0 && color[2] == 0.0) { 951 /* black is black */ 952 for (i=0; i<16; i++) { 953 XMesaPutPixel(xmesa->xm_visual->hpcr_clear_ximage, i, 0, 0); 954 XMesaPutPixel(xmesa->xm_visual->hpcr_clear_ximage, i, 1, 0); 955 } 956 } 957 else { 958 for (i=0; i<16; i++) { 959 XMesaPutPixel(xmesa->xm_visual->hpcr_clear_ximage, i, 0, 960 DITHER_HPCR(i, 0, 961 xmesa->clearcolor[0], 962 xmesa->clearcolor[1], 963 xmesa->clearcolor[2])); 964 XMesaPutPixel(xmesa->xm_visual->hpcr_clear_ximage, i, 1, 965 DITHER_HPCR(i, 1, 966 xmesa->clearcolor[0], 967 xmesa->clearcolor[1], 968 xmesa->clearcolor[2])); 969 } 970 } 971 /* change tile pixmap content */ 972 XMesaPutImage(xmesa->display, 973 (XMesaDrawable)xmesa->xm_visual->hpcr_clear_pixmap, 974 XMESA_BUFFER(ctx->DrawBuffer)->cleargc, 975 xmesa->xm_visual->hpcr_clear_ximage, 0, 0, 0, 0, 16, 2); 976} 977 978 979/** 980 * Called when the driver should update its state, based on the new_state 981 * flags. 982 */ 983void 984xmesa_update_state( GLcontext *ctx, GLbitfield new_state ) 985{ 986 const XMesaContext xmesa = XMESA_CONTEXT(ctx); 987 988 /* Propagate statechange information to swrast and swrast_setup 989 * modules. The X11 driver has no internal GL-dependent state. 990 */ 991 _swrast_InvalidateState( ctx, new_state ); 992 _ac_InvalidateState( ctx, new_state ); 993 _tnl_InvalidateState( ctx, new_state ); 994 _swsetup_InvalidateState( ctx, new_state ); 995 996 if (ctx->DrawBuffer->Name != 0) 997 return; 998 999 /* 1000 * GL_DITHER, GL_READ/DRAW_BUFFER, buffer binding state, etc. effect 1001 * renderbuffer span/clear funcs. 1002 */ 1003 if (new_state & (_NEW_COLOR | _NEW_PIXEL | _NEW_BUFFERS)) { 1004 XMesaBuffer xmbuf = XMESA_BUFFER(ctx->DrawBuffer); 1005 struct xmesa_renderbuffer *front_xrb, *back_xrb; 1006 1007 front_xrb = xmbuf->frontxrb; 1008 if (front_xrb) { 1009 xmesa_set_renderbuffer_funcs(front_xrb, xmesa->pixelformat, 1010 xmesa->xm_visual->BitsPerPixel); 1011 front_xrb->clearFunc = clear_pixmap; 1012 } 1013 1014 back_xrb = xmbuf->backxrb; 1015 if (back_xrb) { 1016 xmesa_set_renderbuffer_funcs(back_xrb, xmesa->pixelformat, 1017 xmesa->xm_visual->BitsPerPixel); 1018 if (xmbuf->backxrb->pixmap) { 1019 back_xrb->clearFunc = clear_pixmap; 1020 } 1021 else { 1022 switch (xmesa->xm_visual->BitsPerPixel) { 1023 case 8: 1024 if (xmesa->xm_visual->hpcr_clear_flag) { 1025 back_xrb->clearFunc = clear_HPCR_ximage; 1026 } 1027 else { 1028 back_xrb->clearFunc = clear_8bit_ximage; 1029 } 1030 break; 1031 case 16: 1032 back_xrb->clearFunc = clear_16bit_ximage; 1033 break; 1034 case 24: 1035 back_xrb->clearFunc = clear_24bit_ximage; 1036 break; 1037 case 32: 1038 back_xrb->clearFunc = clear_32bit_ximage; 1039 break; 1040 default: 1041 back_xrb->clearFunc = clear_nbit_ximage; 1042 break; 1043 } 1044 } 1045 } 1046 } 1047 1048 if (xmesa->xm_visual->hpcr_clear_flag) { 1049 /* this depends on whether we're drawing to the front or back buffer */ 1050 /* XXX FIX THIS! */ 1051#if 0 1052 if (pixmap) { 1053 ctx->Driver.ClearColor = clear_color_HPCR_pixmap; 1054 } 1055 else { 1056 ctx->Driver.ClearColor = clear_color_HPCR_ximage; 1057 } 1058#else 1059 (void) clear_color_HPCR_pixmap; 1060 (void) clear_color_HPCR_ximage; 1061#endif 1062 } 1063} 1064 1065 1066 1067/** 1068 * Called via ctx->Driver.TestProxyTeximage(). Normally, we'd just use 1069 * the _mesa_test_proxy_teximage() fallback function, but we're going to 1070 * special-case the 3D texture case to allow textures up to 512x512x32 1071 * texels. 1072 */ 1073static GLboolean 1074test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, 1075 GLint internalFormat, GLenum format, GLenum type, 1076 GLint width, GLint height, GLint depth, GLint border) 1077{ 1078 if (target == GL_PROXY_TEXTURE_3D) { 1079 /* special case for 3D textures */ 1080 if (width * height * depth > 512 * 512 * 64 || 1081 width < 2 * border || 1082 (!ctx->Extensions.ARB_texture_non_power_of_two && 1083 _mesa_bitcount(width - 2 * border) != 1) || 1084 height < 2 * border || 1085 (!ctx->Extensions.ARB_texture_non_power_of_two && 1086 _mesa_bitcount(height - 2 * border) != 1) || 1087 depth < 2 * border || 1088 (!ctx->Extensions.ARB_texture_non_power_of_two && 1089 _mesa_bitcount(depth - 2 * border) != 1)) { 1090 /* Bad size, or too many texels */ 1091 return GL_FALSE; 1092 } 1093 return GL_TRUE; 1094 } 1095 else { 1096 /* use the fallback routine for 1D, 2D, cube and rect targets */ 1097 return _mesa_test_proxy_teximage(ctx, target, level, internalFormat, 1098 format, type, width, height, depth, 1099 border); 1100 } 1101} 1102 1103 1104/** 1105 * In SW, we don't really compress GL_COMPRESSED_RGB[A] textures! 1106 */ 1107static const struct gl_texture_format * 1108choose_tex_format( GLcontext *ctx, GLint internalFormat, 1109 GLenum format, GLenum type ) 1110{ 1111 switch (internalFormat) { 1112 case GL_COMPRESSED_RGB_ARB: 1113 return &_mesa_texformat_rgb; 1114 case GL_COMPRESSED_RGBA_ARB: 1115 return &_mesa_texformat_rgba; 1116 default: 1117 return _mesa_choose_tex_format(ctx, internalFormat, format, type); 1118 } 1119} 1120 1121 1122/** 1123 * Get the current drawing (and reading) window's size and update the 1124 * corresponding gl_framebuffer(s) if needed. 1125 */ 1126static void 1127update_framebuffer_size(GLcontext *ctx) 1128{ 1129 struct gl_framebuffer *fb = ctx->WinSysDrawBuffer; 1130 GLuint newWidth, newHeight; 1131 get_buffer_size(fb, &newWidth, &newHeight); 1132 if (newWidth != fb->Width || newHeight != fb->Height) { 1133 xmesa_resize_buffers(ctx, fb, newWidth, newHeight); 1134 } 1135 1136 if (ctx->WinSysReadBuffer != ctx->WinSysDrawBuffer) { 1137 /* Update readbuffer's size */ 1138 struct gl_framebuffer *fb = ctx->WinSysReadBuffer; 1139 GLuint newWidth, newHeight; 1140 get_buffer_size(fb, &newWidth, &newHeight); 1141 if (newWidth != fb->Width || newHeight != fb->Height) { 1142 xmesa_resize_buffers(ctx, fb, newWidth, newHeight); 1143 ctx->NewState |= _NEW_BUFFERS; 1144 } 1145 } 1146} 1147 1148 1149/** 1150 * Called by glViewport. 1151 * This is a good time for us to poll the current X window size and adjust 1152 * our renderbuffers to match the current window size. 1153 * Remember, we have no opportunity to respond to conventional 1154 * X Resize/StructureNotify events since the X driver has no event loop. 1155 * Thus, we poll. 1156 * Note that this trick isn't fool-proof. If the application never calls 1157 * glViewport, our notion of the current window size may be incorrect. 1158 * That problem led to the GLX_MESA_resize_buffers extension. 1159 */ 1160static void 1161xmesa_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) 1162{ 1163 (void) x; 1164 (void) y; 1165 (void) w; 1166 (void) h; 1167 update_framebuffer_size(ctx); 1168} 1169 1170 1171#if ENABLE_EXT_timer_query 1172 1173/* 1174 * The GL_EXT_timer_query extension is not enabled for the XServer 1175 * indirect renderer. Not sure about how/if wrapping of gettimeofday() 1176 * is done, etc. 1177 */ 1178 1179struct xmesa_query_object 1180{ 1181 struct gl_query_object Base; 1182 struct timeval StartTime; 1183}; 1184 1185 1186static struct gl_query_object * 1187xmesa_new_query_object(GLcontext *ctx, GLuint id) 1188{ 1189 struct xmesa_query_object *q = CALLOC_STRUCT(xmesa_query_object); 1190 if (q) { 1191 q->Base.Id = id; 1192 q->Base.Ready = GL_TRUE; 1193 } 1194 return &q->Base; 1195} 1196 1197 1198static void 1199xmesa_begin_query(GLcontext *ctx, GLenum target, struct gl_query_object *q) 1200{ 1201 if (target == GL_TIME_ELAPSED_EXT) { 1202 struct xmesa_query_object *xq = (struct xmesa_query_object *) q; 1203 (void) gettimeofday(&xq->StartTime, NULL); 1204 } 1205} 1206 1207 1208/** 1209 * Return the difference between the two given times in microseconds. 1210 */ 1211#ifdef __VMS 1212#define suseconds_t unsigned int 1213#endif 1214static GLuint64EXT 1215time_diff(const struct timeval *t0, const struct timeval *t1) 1216{ 1217 GLuint64EXT seconds0 = t0->tv_sec & 0xff; /* 0 .. 255 seconds */ 1218 GLuint64EXT seconds1 = t1->tv_sec & 0xff; /* 0 .. 255 seconds */ 1219 GLuint64EXT nanosec0 = (seconds0 * 1000000 + t0->tv_usec) * 1000; 1220 GLuint64EXT nanosec1 = (seconds1 * 1000000 + t1->tv_usec) * 1000; 1221 return nanosec1 - nanosec0; 1222} 1223 1224 1225static void 1226xmesa_end_query(GLcontext *ctx, GLenum target, struct gl_query_object *q) 1227{ 1228 if (target == GL_TIME_ELAPSED_EXT) { 1229 struct xmesa_query_object *xq = (struct xmesa_query_object *) q; 1230 struct timeval endTime; 1231 (void) gettimeofday(&endTime, NULL); 1232 /* result is in nanoseconds! */ 1233 q->Result = time_diff(&xq->StartTime, &endTime); 1234 } 1235 q->Ready = GL_TRUE; 1236} 1237 1238#endif /* ENABLE_timer_query */ 1239 1240 1241/** 1242 * Initialize the device driver function table with the functions 1243 * we implement in this driver. 1244 */ 1245void 1246xmesa_init_driver_functions( XMesaVisual xmvisual, 1247 struct dd_function_table *driver ) 1248{ 1249 driver->GetString = get_string; 1250 driver->UpdateState = xmesa_update_state; 1251 driver->GetBufferSize = get_buffer_size; 1252 driver->Flush = finish_or_flush; 1253 driver->Finish = finish_or_flush; 1254 driver->ClearIndex = clear_index; 1255 driver->ClearColor = clear_color; 1256 driver->IndexMask = index_mask; 1257 driver->ColorMask = color_mask; 1258 driver->Enable = enable; 1259 driver->Clear = clear_buffers; 1260 driver->ResizeBuffers = xmesa_resize_buffers; 1261 driver->Viewport = xmesa_viewport; 1262#ifndef XFree86Server 1263 driver->CopyPixels = xmesa_CopyPixels; 1264 if (xmvisual->undithered_pf == PF_8R8G8B && 1265 xmvisual->dithered_pf == PF_8R8G8B) { 1266 driver->DrawPixels = xmesa_DrawPixels_8R8G8B; 1267 } 1268 else if (xmvisual->undithered_pf == PF_5R6G5B) { 1269 driver->DrawPixels = xmesa_DrawPixels_5R6G5B; 1270 } 1271#endif 1272 driver->TestProxyTexImage = test_proxy_teximage; 1273#if ENABLE_EXT_texure_compression_s3tc 1274 driver->ChooseTextureFormat = choose_tex_format; 1275#else 1276 (void) choose_tex_format; 1277#endif 1278 1279#if ENABLE_EXT_timer_query 1280 driver->NewQueryObject = xmesa_new_query_object; 1281 driver->BeginQuery = xmesa_begin_query; 1282 driver->EndQuery = xmesa_end_query; 1283#endif 1284} 1285 1286 1287#define XMESA_NEW_POINT (_NEW_POINT | \ 1288 _NEW_RENDERMODE | \ 1289 _SWRAST_NEW_RASTERMASK) 1290 1291#define XMESA_NEW_LINE (_NEW_LINE | \ 1292 _NEW_TEXTURE | \ 1293 _NEW_LIGHT | \ 1294 _NEW_DEPTH | \ 1295 _NEW_RENDERMODE | \ 1296 _SWRAST_NEW_RASTERMASK) 1297 1298#define XMESA_NEW_TRIANGLE (_NEW_POLYGON | \ 1299 _NEW_TEXTURE | \ 1300 _NEW_LIGHT | \ 1301 _NEW_DEPTH | \ 1302 _NEW_RENDERMODE | \ 1303 _SWRAST_NEW_RASTERMASK) 1304 1305 1306/** 1307 * Extend the software rasterizer with our line/point/triangle 1308 * functions. 1309 * Called during context creation only. 1310 */ 1311void xmesa_register_swrast_functions( GLcontext *ctx ) 1312{ 1313 SWcontext *swrast = SWRAST_CONTEXT( ctx ); 1314 1315 swrast->choose_point = xmesa_choose_point; 1316 swrast->choose_line = xmesa_choose_line; 1317 swrast->choose_triangle = xmesa_choose_triangle; 1318 1319 /* XXX these lines have no net effect. Remove??? */ 1320 swrast->InvalidatePointMask |= XMESA_NEW_POINT; 1321 swrast->InvalidateLineMask |= XMESA_NEW_LINE; 1322 swrast->InvalidateTriangleMask |= XMESA_NEW_TRIANGLE; 1323} 1324