xm_line.c revision c703658b3965bf2e4f3593a0d54be03e8e8b1436
1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * 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 */ 56static 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 */ 91void 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._MaxEnabledTexImageUnit == -1 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 */ 415static void 416xor_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[VARYING_SLOT_POS][0]; 427 int y0 = YFLIP(xrb, (GLint) vert0->attrib[VARYING_SLOT_POS][1]); 428 int x1 = (GLint) vert1->attrib[VARYING_SLOT_POS][0]; 429 int y1 = YFLIP(xrb, (GLint) vert1->attrib[VARYING_SLOT_POS][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 */ 446static swrast_line_func 447get_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._MaxEnabledTexImageUnit != -1) 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 */ 533void 534xmesa_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