1 /* 2 * Mesa 3-D graphics library 3 * Version: 6.5 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 /* 27 * This file contains "accelerated" point, line, and triangle functions. 28 * It should be fairly easy to write new special-purpose point, line or 29 * triangle functions and hook them into this module. 30 */ 31 32 33 #include "glxheader.h" 34 #include "main/macros.h" 35 #include "main/mtypes.h" 36 #include "xmesaP.h" 37 38 /* Internal swrast includes: 39 */ 40 #include "swrast/s_depth.h" 41 #include "swrast/s_points.h" 42 #include "swrast/s_lines.h" 43 #include "swrast/s_context.h" 44 45 46 /**********************************************************************/ 47 /*** Point rendering ***/ 48 /**********************************************************************/ 49 50 51 /* 52 * Render an array of points into a pixmap, any pixel format. 53 */ 54 #if 000 55 /* XXX don't use this, it doesn't dither correctly */ 56 static void draw_points_ANY_pixmap( struct gl_context *ctx, const SWvertex *vert ) 57 { 58 XMesaContext xmesa = XMESA_CONTEXT(ctx); 59 XMesaDisplay *dpy = xmesa->xm_visual->display; 60 XMesaDrawable buffer = xmesa->xm_buffer->buffer; 61 XMesaGC gc = xmesa->xm_buffer->gc; 62 63 if (xmesa->xm_visual->mesa_visual.RGBAflag) { 64 register int x, y; 65 const GLubyte *color = vert->color; 66 unsigned long pixel = xmesa_color_to_pixel( xmesa, 67 color[0], color[1], 68 color[2], color[3], 69 xmesa->pixelformat); 70 XMesaSetForeground( dpy, gc, pixel ); 71 x = (GLint) vert->win[0]; 72 y = YFLIP( xrb, (GLint) vert->win[1] ); 73 XMesaDrawPoint( dpy, buffer, gc, x, y); 74 } 75 else { 76 /* Color index mode */ 77 register int x, y; 78 XMesaSetForeground( dpy, gc, vert->index ); 79 x = (GLint) vert->win[0]; 80 y = YFLIP( xrb, (GLint) vert->win[1] ); 81 XMesaDrawPoint( dpy, buffer, gc, x, y); 82 } 83 } 84 #endif 85 86 87 /* Override the swrast point-selection function. Try to use one of 88 * our internal point functions, otherwise fall back to the standard 89 * swrast functions. 90 */ 91 void xmesa_choose_point( struct gl_context *ctx ) 92 { 93 #if 0 94 XMesaContext xmesa = XMESA_CONTEXT(ctx); 95 SWcontext *swrast = SWRAST_CONTEXT(ctx); 96 97 if (ctx->RenderMode == GL_RENDER 98 && ctx->Point.Size == 1.0F && !ctx->Point.SmoothFlag 99 && swrast->_RasterMask == 0 100 && !ctx->Texture._EnabledUnits 101 && xmesa->xm_buffer->buffer != XIMAGE) { 102 swrast->Point = draw_points_ANY_pixmap; 103 } 104 else { 105 _swrast_choose_point( ctx ); 106 } 107 #else 108 _swrast_choose_point( ctx ); 109 #endif 110 } 111 112 113 114 /**********************************************************************/ 115 /*** Line rendering ***/ 116 /**********************************************************************/ 117 118 119 #if CHAN_BITS == 8 120 121 122 #define GET_XRB(XRB) struct xmesa_renderbuffer *XRB = \ 123 xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]) 124 125 126 /* 127 * Draw a flat-shaded, PF_TRUECOLOR line into an XImage. 128 */ 129 #define NAME flat_TRUECOLOR_line 130 #define SETUP_CODE \ 131 XMesaContext xmesa = XMESA_CONTEXT(ctx); \ 132 GET_XRB(xrb); \ 133 const GLubyte *color = vert1->color; \ 134 unsigned long pixel; \ 135 PACK_TRUECOLOR( pixel, color[0], color[1], color[2] ); 136 #define CLIP_HACK 1 137 #define PLOT(X,Y) XMesaPutPixel(xrb->ximage, X, YFLIP(xrb, Y), pixel ); 138 #include "swrast/s_linetemp.h" 139 140 141 142 /* 143 * Draw a flat-shaded, PF_8A8B8G8R line into an XImage. 144 */ 145 #define NAME flat_8A8B8G8R_line 146 #define SETUP_CODE \ 147 GET_XRB(xrb); \ 148 const GLubyte *color = vert1->color; \ 149 GLuint pixel = PACK_8A8B8G8R(color[0], color[1], color[2], color[3]); 150 #define PIXEL_TYPE GLuint 151 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line) 152 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y) 153 #define CLIP_HACK 1 154 #define PLOT(X,Y) *pixelPtr = pixel; 155 #include "swrast/s_linetemp.h" 156 157 158 159 /* 160 * Draw a flat-shaded, PF_8A8R8G8B line into an XImage. 161 */ 162 #define NAME flat_8A8R8G8B_line 163 #define SETUP_CODE \ 164 GET_XRB(xrb); \ 165 const GLubyte *color = vert1->color; \ 166 GLuint pixel = PACK_8A8R8G8B(color[0], color[1], color[2], color[3]); 167 #define PIXEL_TYPE GLuint 168 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line) 169 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y) 170 #define CLIP_HACK 1 171 #define PLOT(X,Y) *pixelPtr = pixel; 172 #include "swrast/s_linetemp.h" 173 174 175 176 /* 177 * Draw a flat-shaded, PF_8R8G8B line into an XImage. 178 */ 179 #define NAME flat_8R8G8B_line 180 #define SETUP_CODE \ 181 GET_XRB(xrb); \ 182 const GLubyte *color = vert1->color; \ 183 GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] ); 184 #define PIXEL_TYPE GLuint 185 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line) 186 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y) 187 #define CLIP_HACK 1 188 #define PLOT(X,Y) *pixelPtr = pixel; 189 #include "swrast/s_linetemp.h" 190 191 192 193 /* 194 * Draw a flat-shaded, PF_8R8G8B24 line into an XImage. 195 */ 196 #define NAME flat_8R8G8B24_line 197 #define SETUP_CODE \ 198 GET_XRB(xrb); \ 199 const GLubyte *color = vert1->color; 200 #define PIXEL_TYPE bgr_t 201 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line) 202 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X, Y) 203 #define CLIP_HACK 1 204 #define PLOT(X,Y) { \ 205 pixelPtr->r = color[RCOMP]; \ 206 pixelPtr->g = color[GCOMP]; \ 207 pixelPtr->b = color[BCOMP]; \ 208 } 209 #include "swrast/s_linetemp.h" 210 211 212 213 /* 214 * Draw a flat-shaded, PF_5R6G5B line into an XImage. 215 */ 216 #define NAME flat_5R6G5B_line 217 #define SETUP_CODE \ 218 GET_XRB(xrb); \ 219 const GLubyte *color = vert1->color; \ 220 GLushort pixel = PACK_5R6G5B( color[0], color[1], color[2] ); 221 #define PIXEL_TYPE GLushort 222 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line) 223 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y) 224 #define CLIP_HACK 1 225 #define PLOT(X,Y) *pixelPtr = pixel; 226 #include "swrast/s_linetemp.h" 227 228 229 230 /* 231 * Draw a flat-shaded, PF_DITHER_5R6G5B line into an XImage. 232 */ 233 #define NAME flat_DITHER_5R6G5B_line 234 #define SETUP_CODE \ 235 GET_XRB(xrb); \ 236 XMesaContext xmesa = XMESA_CONTEXT(ctx); \ 237 const GLubyte *color = vert1->color; 238 #define PIXEL_TYPE GLushort 239 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line) 240 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y) 241 #define CLIP_HACK 1 242 #define PLOT(X,Y) PACK_TRUEDITHER( *pixelPtr, X, Y, color[0], color[1], color[2] ); 243 #include "swrast/s_linetemp.h" 244 245 246 247 /* 248 * Draw a flat-shaded, Z-less, PF_TRUECOLOR line into an XImage. 249 */ 250 #define NAME flat_TRUECOLOR_z_line 251 #define SETUP_CODE \ 252 GET_XRB(xrb); \ 253 XMesaContext xmesa = XMESA_CONTEXT(ctx); \ 254 const GLubyte *color = vert1->color; \ 255 unsigned long pixel; \ 256 PACK_TRUECOLOR( pixel, color[0], color[1], color[2] ); 257 #define INTERP_Z 1 258 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE 259 #define CLIP_HACK 1 260 #define PLOT(X,Y) \ 261 if (Z < *zPtr) { \ 262 *zPtr = Z; \ 263 XMesaPutPixel(xrb->ximage, X, YFLIP(xrb, Y), pixel); \ 264 } 265 #include "swrast/s_linetemp.h" 266 267 268 269 /* 270 * Draw a flat-shaded, Z-less, PF_8A8B8G8R line into an XImage. 271 */ 272 #define NAME flat_8A8B8G8R_z_line 273 #define SETUP_CODE \ 274 GET_XRB(xrb); \ 275 const GLubyte *color = vert1->color; \ 276 GLuint pixel = PACK_8A8B8G8R(color[0], color[1], color[2], color[3]); 277 #define INTERP_Z 1 278 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE 279 #define PIXEL_TYPE GLuint 280 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line) 281 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X,Y) 282 #define CLIP_HACK 1 283 #define PLOT(X,Y) \ 284 if (Z < *zPtr) { \ 285 *zPtr = Z; \ 286 *pixelPtr = pixel; \ 287 } 288 #include "swrast/s_linetemp.h" 289 290 291 292 /* 293 * Draw a flat-shaded, Z-less, PF_8A8R8G8B line into an XImage. 294 */ 295 #define NAME flat_8A8R8G8B_z_line 296 #define SETUP_CODE \ 297 GET_XRB(xrb); \ 298 const GLubyte *color = vert1->color; \ 299 GLuint pixel = PACK_8A8R8G8B(color[0], color[1], color[2], color[3]); 300 #define INTERP_Z 1 301 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE 302 #define PIXEL_TYPE GLuint 303 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line) 304 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X,Y) 305 #define CLIP_HACK 1 306 #define PLOT(X,Y) \ 307 if (Z < *zPtr) { \ 308 *zPtr = Z; \ 309 *pixelPtr = pixel; \ 310 } 311 #include "swrast/s_linetemp.h" 312 313 314 315 /* 316 * Draw a flat-shaded, Z-less, PF_8R8G8B line into an XImage. 317 */ 318 #define NAME flat_8R8G8B_z_line 319 #define SETUP_CODE \ 320 GET_XRB(xrb); \ 321 const GLubyte *color = vert1->color; \ 322 GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] ); 323 #define INTERP_Z 1 324 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE 325 #define PIXEL_TYPE GLuint 326 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line) 327 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X,Y) 328 #define CLIP_HACK 1 329 #define PLOT(X,Y) \ 330 if (Z < *zPtr) { \ 331 *zPtr = Z; \ 332 *pixelPtr = pixel; \ 333 } 334 #include "swrast/s_linetemp.h" 335 336 337 338 /* 339 * Draw a flat-shaded, Z-less, PF_8R8G8B24 line into an XImage. 340 */ 341 #define NAME flat_8R8G8B24_z_line 342 #define SETUP_CODE \ 343 GET_XRB(xrb); \ 344 const GLubyte *color = vert1->color; 345 #define INTERP_Z 1 346 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE 347 #define PIXEL_TYPE bgr_t 348 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line) 349 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X,Y) 350 #define CLIP_HACK 1 351 #define PLOT(X,Y) \ 352 if (Z < *zPtr) { \ 353 *zPtr = Z; \ 354 pixelPtr->r = color[RCOMP]; \ 355 pixelPtr->g = color[GCOMP]; \ 356 pixelPtr->b = color[BCOMP]; \ 357 } 358 #include "swrast/s_linetemp.h" 359 360 361 362 /* 363 * Draw a flat-shaded, Z-less, PF_5R6G5B line into an XImage. 364 */ 365 #define NAME flat_5R6G5B_z_line 366 #define SETUP_CODE \ 367 GET_XRB(xrb); \ 368 const GLubyte *color = vert1->color; \ 369 GLushort pixel = PACK_5R6G5B( color[0], color[1], color[2] ); 370 #define INTERP_Z 1 371 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE 372 #define PIXEL_TYPE GLushort 373 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line) 374 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X,Y) 375 #define CLIP_HACK 1 376 #define PLOT(X,Y) \ 377 if (Z < *zPtr) { \ 378 *zPtr = Z; \ 379 *pixelPtr = pixel; \ 380 } 381 #include "swrast/s_linetemp.h" 382 383 384 385 /* 386 * Draw a flat-shaded, Z-less, PF_DITHER_5R6G5B line into an XImage. 387 */ 388 #define NAME flat_DITHER_5R6G5B_z_line 389 #define SETUP_CODE \ 390 GET_XRB(xrb); \ 391 XMesaContext xmesa = XMESA_CONTEXT(ctx); \ 392 const GLubyte *color = vert1->color; 393 #define INTERP_Z 1 394 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE 395 #define PIXEL_TYPE GLushort 396 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line) 397 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X,Y) 398 #define CLIP_HACK 1 399 #define PLOT(X,Y) \ 400 if (Z < *zPtr) { \ 401 *zPtr = Z; \ 402 PACK_TRUEDITHER(*pixelPtr, X, Y, color[0], color[1], color[2]); \ 403 } 404 #include "swrast/s_linetemp.h" 405 406 407 408 /** 409 * Draw fast, XOR line with XDrawLine in front color buffer. 410 * WARNING: this isn't fully OpenGL conformant because different pixels 411 * will be hit versus using the other line functions. 412 * Don't use the code in X server GLcore module since we need a wrapper 413 * for the XSetLineAttributes() function call. 414 */ 415 static void 416 xor_line(struct gl_context *ctx, const SWvertex *vert0, const SWvertex *vert1) 417 { 418 XMesaContext xmesa = XMESA_CONTEXT(ctx); 419 XMesaDisplay *dpy = xmesa->xm_visual->display; 420 XMesaGC gc = xmesa->xm_buffer->gc; 421 GET_XRB(xrb); 422 unsigned long pixel = xmesa_color_to_pixel(ctx, 423 vert1->color[0], vert1->color[1], 424 vert1->color[2], vert1->color[3], 425 xmesa->pixelformat); 426 int x0 = (GLint) vert0->attrib[FRAG_ATTRIB_WPOS][0]; 427 int y0 = YFLIP(xrb, (GLint) vert0->attrib[FRAG_ATTRIB_WPOS][1]); 428 int x1 = (GLint) vert1->attrib[FRAG_ATTRIB_WPOS][0]; 429 int y1 = YFLIP(xrb, (GLint) vert1->attrib[FRAG_ATTRIB_WPOS][1]); 430 XMesaSetForeground(dpy, gc, pixel); 431 XMesaSetFunction(dpy, gc, GXxor); 432 XSetLineAttributes(dpy, gc, (int) ctx->Line.Width, 433 LineSolid, CapButt, JoinMiter); 434 XDrawLine(dpy, xrb->pixmap, gc, x0, y0, x1, y1); 435 XMesaSetFunction(dpy, gc, GXcopy); /* this gc is used elsewhere */ 436 } 437 438 439 #endif /* CHAN_BITS == 8 */ 440 441 442 /** 443 * Return pointer to line drawing function, or NULL if we should use a 444 * swrast fallback. 445 */ 446 static swrast_line_func 447 get_line_func(struct gl_context *ctx) 448 { 449 #if CHAN_BITS == 8 450 SWcontext *swrast = SWRAST_CONTEXT(ctx); 451 XMesaContext xmesa = XMESA_CONTEXT(ctx); 452 const struct xmesa_renderbuffer *xrb; 453 454 if ((ctx->DrawBuffer->_ColorDrawBufferIndexes[0] != BUFFER_BIT_FRONT_LEFT) && 455 (ctx->DrawBuffer->_ColorDrawBufferIndexes[0] != BUFFER_BIT_BACK_LEFT)) 456 return (swrast_line_func) NULL; 457 if (ctx->RenderMode != GL_RENDER) return (swrast_line_func) NULL; 458 if (ctx->Line.SmoothFlag) return (swrast_line_func) NULL; 459 if (ctx->Texture._EnabledUnits) return (swrast_line_func) NULL; 460 if (ctx->Light.ShadeModel != GL_FLAT) return (swrast_line_func) NULL; 461 if (ctx->Line.StippleFlag) return (swrast_line_func) NULL; 462 if (swrast->_RasterMask & MULTI_DRAW_BIT) return (swrast_line_func) NULL; 463 464 xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]); 465 466 if (xrb->ximage 467 && swrast->_RasterMask==DEPTH_BIT 468 && ctx->Depth.Func==GL_LESS 469 && ctx->Depth.Mask==GL_TRUE 470 && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS 471 && ctx->Line.Width==1.0F) { 472 switch (xmesa->pixelformat) { 473 case PF_Truecolor: 474 return flat_TRUECOLOR_z_line; 475 case PF_8A8B8G8R: 476 return flat_8A8B8G8R_z_line; 477 case PF_8A8R8G8B: 478 return flat_8A8R8G8B_z_line; 479 case PF_8R8G8B: 480 return flat_8R8G8B_z_line; 481 case PF_8R8G8B24: 482 return flat_8R8G8B24_z_line; 483 case PF_5R6G5B: 484 return flat_5R6G5B_z_line; 485 case PF_Dither_5R6G5B: 486 return flat_DITHER_5R6G5B_z_line; 487 default: 488 return (swrast_line_func)NULL; 489 } 490 } 491 if (xrb->ximage 492 && swrast->_RasterMask==0 493 && ctx->Line.Width==1.0F) { 494 switch (xmesa->pixelformat) { 495 case PF_Truecolor: 496 return flat_TRUECOLOR_line; 497 case PF_8A8B8G8R: 498 return flat_8A8B8G8R_line; 499 case PF_8A8R8G8B: 500 return flat_8A8R8G8B_line; 501 case PF_8R8G8B: 502 return flat_8R8G8B_line; 503 case PF_8R8G8B24: 504 return flat_8R8G8B24_line; 505 case PF_5R6G5B: 506 return flat_5R6G5B_line; 507 case PF_Dither_5R6G5B: 508 return flat_DITHER_5R6G5B_line; 509 default: 510 return (swrast_line_func)NULL; 511 } 512 } 513 514 if (ctx->DrawBuffer->_NumColorDrawBuffers == 1 515 && ctx->DrawBuffer->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT 516 && swrast->_RasterMask == LOGIC_OP_BIT 517 && ctx->Color.LogicOp == GL_XOR 518 && !ctx->Line.StippleFlag 519 && !ctx->Line.SmoothFlag) { 520 return xor_line; 521 } 522 523 #endif /* CHAN_BITS == 8 */ 524 return (swrast_line_func) NULL; 525 } 526 527 528 /** 529 * Override for the swrast line-selection function. Try to use one 530 * of our internal line functions, otherwise fall back to the 531 * standard swrast functions. 532 */ 533 void 534 xmesa_choose_line(struct gl_context *ctx) 535 { 536 SWcontext *swrast = SWRAST_CONTEXT(ctx); 537 538 if (!(swrast->Line = get_line_func( ctx ))) 539 _swrast_choose_line( ctx ); 540 } 541