1 /* $Id: xm_line.c,v 1.13 2000/12/13 16:24:40 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 * This file contains "accelerated" point, line, and triangle functions.
30 * It should be fairly easy to write new special-purpose point, line or
31 * triangle functions and hook them into this module.
35 #include "glxheader.h"
41 /* Internal swrast includes:
43 #include "swrast/s_depth.h"
44 #include "swrast/s_points.h"
45 #include "swrast/s_lines.h"
46 #include "swrast/s_context.h"
49 /**********************************************************************/
50 /*** Point rendering ***/
51 /**********************************************************************/
55 * Render an array of points into a pixmap, any pixel format.
58 /* XXX don't use this, it doesn't dither correctly */
59 static void draw_points_ANY_pixmap( GLcontext
*ctx
, const SWvertex
*vert
)
61 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
62 XMesaDisplay
*dpy
= xmesa
->xm_visual
->display
;
63 XMesaDrawable buffer
= xmesa
->xm_buffer
->buffer
;
64 XMesaGC gc
= xmesa
->xm_buffer
->gc
;
66 if (xmesa
->xm_visual
->gl_visual
->RGBAflag
) {
68 const GLubyte
*color
= vert
->color
;
69 unsigned long pixel
= xmesa_color_to_pixel( xmesa
,
73 XMesaSetForeground( dpy
, gc
, pixel
);
74 x
= (GLint
) vert
->win
[0];
75 y
= FLIP( xmesa
->xm_buffer
, (GLint
) vert
->win
[1] );
76 XMesaDrawPoint( dpy
, buffer
, gc
, x
, y
);
79 /* Color index mode */
81 XMesaSetForeground( dpy
, gc
, vert
->index
);
82 x
= (GLint
) vert
->win
[0];
83 y
= FLIP( xmesa
->xm_buffer
, (GLint
) vert
->win
[1] );
84 XMesaDrawPoint( dpy
, buffer
, gc
, x
, y
);
90 /* Override the swrast point-selection function. Try to use one of
91 * our internal point functions, otherwise fall back to the standard
94 void xmesa_choose_point( GLcontext
*ctx
)
97 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
98 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
100 if (ctx
->RenderMode
== GL_RENDER
101 && ctx
->Point
.Size
== 1.0F
&& !ctx
->Point
.SmoothFlag
102 && swrast
->_RasterMask
== 0
103 && !ctx
->Texture
._ReallyEnabled
104 && xmesa
->xm_buffer
->buffer
!= XIMAGE
) {
105 swrast
->Point
= draw_points_ANY_pixmap
;
108 _swrast_choose_point( ctx
);
111 _swrast_choose_point( ctx
);
117 /**********************************************************************/
118 /*** Line rendering ***/
119 /**********************************************************************/
123 * Draw a flat-shaded, PF_TRUECOLOR line into an XImage.
125 static void flat_TRUECOLOR_line( GLcontext
*ctx
,
126 const SWvertex
*vert0
, const SWvertex
*vert1
)
128 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
129 const GLubyte
*color
= vert0
->color
;
130 XMesaImage
*img
= xmesa
->xm_buffer
->backimage
;
132 PACK_TRUECOLOR( pixel
, color
[0], color
[1], color
[2] );
136 #define PLOT(X,Y) XMesaPutPixel( img, X, FLIP(xmesa->xm_buffer, Y), pixel );
138 #include "swrast/s_linetemp.h"
144 * Draw a flat-shaded, PF_8A8B8G8R line into an XImage.
146 static void flat_8A8B8G8R_line( GLcontext
*ctx
,
147 const SWvertex
*vert0
, const SWvertex
*vert1
)
149 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
150 const GLubyte
*color
= vert0
->color
;
151 GLuint pixel
= PACK_8B8G8R( color
[0], color
[1], color
[2] );
153 #define PIXEL_TYPE GLuint
154 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
155 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(xmesa->xm_buffer,X,Y)
157 #define PLOT(X,Y) *pixelPtr = pixel;
159 #include "swrast/s_linetemp.h"
164 * Draw a flat-shaded, PF_8R8G8B line into an XImage.
166 static void flat_8R8G8B_line( GLcontext
*ctx
,
167 const SWvertex
*vert0
, const SWvertex
*vert1
)
169 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
170 const GLubyte
*color
= vert0
->color
;
171 GLuint pixel
= PACK_8R8G8B( color
[0], color
[1], color
[2] );
173 #define PIXEL_TYPE GLuint
174 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
175 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(xmesa->xm_buffer,X,Y)
177 #define PLOT(X,Y) *pixelPtr = pixel;
179 #include "swrast/s_linetemp.h"
184 * Draw a flat-shaded, PF_8R8G8B24 line into an XImage.
186 static void flat_8R8G8B24_line( GLcontext
*ctx
,
187 const SWvertex
*vert0
, const SWvertex
*vert1
)
189 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
190 const GLubyte
*color
= vert0
->color
;
192 #define PIXEL_TYPE bgr_t
193 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
194 #define PIXEL_ADDRESS(X,Y) PIXELADDR3(xmesa->xm_buffer,X,Y)
196 #define PLOT(X,Y) { \
197 pixelPtr->r = color[RCOMP]; \
198 pixelPtr->g = color[GCOMP]; \
199 pixelPtr->b = color[BCOMP]; \
202 #include "swrast/s_linetemp.h"
207 * Draw a flat-shaded, PF_5R6G5B line into an XImage.
209 static void flat_5R6G5B_line( GLcontext
*ctx
,
210 const SWvertex
*vert0
, const SWvertex
*vert1
)
212 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
213 const GLubyte
*color
= vert0
->color
;
214 GLushort pixel
= PACK_5R6G5B( color
[0], color
[1], color
[2] );
216 #define PIXEL_TYPE GLushort
217 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
218 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y)
220 #define PLOT(X,Y) *pixelPtr = pixel;
222 #include "swrast/s_linetemp.h"
227 * Draw a flat-shaded, PF_DITHER_5R6G5B line into an XImage.
229 static void flat_DITHER_5R6G5B_line( GLcontext
*ctx
,
230 const SWvertex
*vert0
, const SWvertex
*vert1
)
232 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
233 const GLubyte
*color
= vert0
->color
;
235 #define PIXEL_TYPE GLushort
236 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
237 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y)
239 #define PLOT(X,Y) PACK_TRUEDITHER( *pixelPtr, X, Y, color[0], color[1], color[2] );
241 #include "swrast/s_linetemp.h"
247 * Draw a flat-shaded, PF_DITHER 8-bit line into an XImage.
249 static void flat_DITHER8_line( GLcontext
*ctx
,
250 const SWvertex
*vert0
, const SWvertex
*vert1
)
252 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
253 const GLubyte
*color
= vert0
->color
;
254 GLint r
= color
[0], g
= color
[1], b
= color
[2];
258 #define PIXEL_TYPE GLubyte
259 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
260 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
262 #define PLOT(X,Y) *pixelPtr = DITHER(X,Y,r,g,b);
264 #include "swrast/s_linetemp.h"
269 * Draw a flat-shaded, PF_LOOKUP 8-bit line into an XImage.
271 static void flat_LOOKUP8_line( GLcontext
*ctx
,
272 const SWvertex
*vert0
, const SWvertex
*vert1
)
274 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
275 const GLubyte
*color
= vert0
->color
;
278 pixel
= (GLubyte
) LOOKUP( color
[0], color
[1], color
[2] );
280 #define PIXEL_TYPE GLubyte
281 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
282 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
284 #define PLOT(X,Y) *pixelPtr = pixel;
286 #include "swrast/s_linetemp.h"
291 * Draw a flat-shaded, PF_HPCR line into an XImage.
293 static void flat_HPCR_line( GLcontext
*ctx
,
294 const SWvertex
*vert0
, const SWvertex
*vert1
)
296 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
297 const GLubyte
*color
= vert0
->color
;
298 GLint r
= color
[0], g
= color
[1], b
= color
[2];
301 #define PIXEL_TYPE GLubyte
302 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
303 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
305 #define PLOT(X,Y) *pixelPtr = (GLubyte) DITHER_HPCR(X,Y,r,g,b);
307 #include "swrast/s_linetemp.h"
313 * Draw a flat-shaded, Z-less, PF_TRUECOLOR line into an XImage.
315 static void flat_TRUECOLOR_z_line( GLcontext
*ctx
,
316 const SWvertex
*vert0
, const SWvertex
*vert1
)
318 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
319 const GLubyte
*color
= vert0
->color
;
320 XMesaImage
*img
= xmesa
->xm_buffer
->backimage
;
322 PACK_TRUECOLOR( pixel
, color
[0], color
[1], color
[2] );
326 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
331 XMesaPutPixel( img, X, FLIP(xmesa->xm_buffer, Y), pixel ); \
334 #include "swrast/s_linetemp.h"
339 * Draw a flat-shaded, Z-less, PF_8A8B8G8R line into an XImage.
341 static void flat_8A8B8G8R_z_line( GLcontext
*ctx
,
342 const SWvertex
*vert0
, const SWvertex
*vert1
)
344 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
345 const GLubyte
*color
= vert0
->color
;
346 GLuint pixel
= PACK_8B8G8R( color
[0], color
[1], color
[2] );
349 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
350 #define PIXEL_TYPE GLuint
351 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
352 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(xmesa->xm_buffer,X,Y)
360 #include "swrast/s_linetemp.h"
365 * Draw a flat-shaded, Z-less, PF_8R8G8B line into an XImage.
367 static void flat_8R8G8B_z_line( GLcontext
*ctx
,
368 const SWvertex
*vert0
, const SWvertex
*vert1
)
370 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
371 const GLubyte
*color
= vert0
->color
;
372 GLuint pixel
= PACK_8R8G8B( color
[0], color
[1], color
[2] );
375 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
376 #define PIXEL_TYPE GLuint
377 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
378 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(xmesa->xm_buffer,X,Y)
386 #include "swrast/s_linetemp.h"
391 * Draw a flat-shaded, Z-less, PF_8R8G8B24 line into an XImage.
393 static void flat_8R8G8B24_z_line( GLcontext
*ctx
,
394 const SWvertex
*vert0
, const SWvertex
*vert1
)
396 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
397 const GLubyte
*color
= vert0
->color
;
400 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
401 #define PIXEL_TYPE bgr_t
402 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
403 #define PIXEL_ADDRESS(X,Y) PIXELADDR3(xmesa->xm_buffer,X,Y)
408 pixelPtr->r = color[RCOMP]; \
409 pixelPtr->g = color[GCOMP]; \
410 pixelPtr->b = color[BCOMP]; \
413 #include "swrast/s_linetemp.h"
418 * Draw a flat-shaded, Z-less, PF_5R6G5B line into an XImage.
420 static void flat_5R6G5B_z_line( GLcontext
*ctx
,
421 const SWvertex
*vert0
, const SWvertex
*vert1
)
423 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
424 const GLubyte
*color
= vert0
->color
;
425 GLushort pixel
= PACK_5R6G5B( color
[0], color
[1], color
[2] );
428 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
429 #define PIXEL_TYPE GLushort
430 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
431 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y)
438 #include "swrast/s_linetemp.h"
443 * Draw a flat-shaded, Z-less, PF_DITHER_5R6G5B line into an XImage.
445 static void flat_DITHER_5R6G5B_z_line( GLcontext
*ctx
,
446 const SWvertex
*vert0
, const SWvertex
*vert1
)
448 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
449 const GLubyte
*color
= vert0
->color
;
452 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
453 #define PIXEL_TYPE GLushort
454 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
455 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y)
460 PACK_TRUEDITHER(*pixelPtr, X, Y, color[0], color[1], color[2]); \
462 #include "swrast/s_linetemp.h"
467 * Draw a flat-shaded, Z-less, PF_DITHER 8-bit line into an XImage.
469 static void flat_DITHER8_z_line( GLcontext
*ctx
,
470 const SWvertex
*vert0
, const SWvertex
*vert1
)
472 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
473 const GLubyte
*color
= vert0
->color
;
474 GLint r
= color
[0], g
= color
[1], b
= color
[2];
479 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
480 #define PIXEL_TYPE GLubyte
481 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
482 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
487 *pixelPtr = (GLubyte) DITHER( X, Y, r, g, b); \
489 #include "swrast/s_linetemp.h"
494 * Draw a flat-shaded, Z-less, PF_LOOKUP 8-bit line into an XImage.
496 static void flat_LOOKUP8_z_line( GLcontext
*ctx
,
497 const SWvertex
*vert0
, const SWvertex
*vert1
)
499 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
500 const GLubyte
*color
= vert0
->color
;
503 pixel
= (GLubyte
) LOOKUP( color
[0], color
[1], color
[2] );
506 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
507 #define PIXEL_TYPE GLubyte
508 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
509 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
517 #include "swrast/s_linetemp.h"
522 * Draw a flat-shaded, Z-less, PF_HPCR line into an XImage.
524 static void flat_HPCR_z_line( GLcontext
*ctx
,
525 const SWvertex
*vert0
, const SWvertex
*vert1
)
527 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
528 const GLubyte
*color
= vert0
->color
;
529 GLint r
= color
[0], g
= color
[1], b
= color
[2];
533 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
534 #define PIXEL_TYPE GLubyte
535 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
536 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
541 *pixelPtr = (GLubyte) DITHER_HPCR( X, Y, r, g, b); \
544 #include "swrast/s_linetemp.h"
548 static swrast_line_func
get_line_func( GLcontext
*ctx
)
550 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
551 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
552 int depth
= GET_VISUAL_DEPTH(xmesa
->xm_visual
);
554 (void) DitherValues
; /* silence unused var warning */
555 (void) kernel1
; /* silence unused var warning */
557 if (ctx
->RenderMode
!= GL_RENDER
) return (swrast_line_func
) NULL
;
558 if (ctx
->Line
.SmoothFlag
) return (swrast_line_func
) NULL
;
559 if (ctx
->Texture
._ReallyEnabled
) return (swrast_line_func
) NULL
;
560 if (ctx
->Light
.ShadeModel
!= GL_FLAT
) return (swrast_line_func
) NULL
;
561 if (ctx
->Line
.StippleFlag
) return (swrast_line_func
) NULL
;
563 if (xmesa
->xm_buffer
->buffer
==XIMAGE
564 && swrast
->_RasterMask
==DEPTH_BIT
565 && ctx
->Depth
.Func
==GL_LESS
566 && ctx
->Depth
.Mask
==GL_TRUE
567 && ctx
->Visual
.DepthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
568 && ctx
->Line
.Width
==1.0F
) {
569 switch (xmesa
->pixelformat
) {
571 return flat_TRUECOLOR_z_line
;
573 return flat_8A8B8G8R_z_line
;
575 return flat_8R8G8B_z_line
;
577 return flat_8R8G8B24_z_line
;
579 return flat_5R6G5B_z_line
;
580 case PF_DITHER_5R6G5B
:
581 return flat_DITHER_5R6G5B_z_line
;
583 return (depth
==8) ? flat_DITHER8_z_line
: (swrast_line_func
) NULL
;
585 return (depth
==8) ? flat_LOOKUP8_z_line
: (swrast_line_func
) NULL
;
587 return flat_HPCR_z_line
;
589 return (swrast_line_func
)NULL
;
592 if (xmesa
->xm_buffer
->buffer
==XIMAGE
593 && swrast
->_RasterMask
==0
594 && ctx
->Line
.Width
==1.0F
) {
595 switch (xmesa
->pixelformat
) {
597 return flat_TRUECOLOR_line
;
599 return flat_8A8B8G8R_line
;
601 return flat_8R8G8B_line
;
603 return flat_8R8G8B24_line
;
605 return flat_5R6G5B_line
;
606 case PF_DITHER_5R6G5B
:
607 return flat_DITHER_5R6G5B_line
;
609 return (depth
==8) ? flat_DITHER8_line
: (swrast_line_func
) NULL
;
611 return (depth
==8) ? flat_LOOKUP8_line
: (swrast_line_func
) NULL
;
613 return flat_HPCR_line
;
615 return (swrast_line_func
)NULL
;
619 return (swrast_line_func
) NULL
;
622 /* Override for the swrast line-selection function. Try to use one
623 * of our internal line functions, otherwise fall back to the
624 * standard swrast functions.
626 void xmesa_choose_line( GLcontext
*ctx
)
628 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
630 if (!(swrast
->Line
= get_line_func( ctx
)))
631 _swrast_choose_line( ctx
);
635 #define XMESA_NEW_POINT (_NEW_POINT | \
637 _SWRAST_NEW_RASTERMASK)
639 #define XMESA_NEW_LINE (_NEW_LINE | \
644 _SWRAST_NEW_RASTERMASK)
646 #define XMESA_NEW_TRIANGLE (_NEW_POLYGON | \
651 _SWRAST_NEW_RASTERMASK)
654 /* Extend the software rasterizer with our line/point/triangle
657 void xmesa_register_swrast_functions( GLcontext
*ctx
)
659 SWcontext
*swrast
= SWRAST_CONTEXT( ctx
);
661 swrast
->choose_point
= xmesa_choose_point
;
662 swrast
->choose_line
= xmesa_choose_line
;
663 swrast
->choose_triangle
= xmesa_choose_triangle
;
665 swrast
->invalidate_point
|= XMESA_NEW_POINT
;
666 swrast
->invalidate_line
|= XMESA_NEW_LINE
;
667 swrast
->invalidate_triangle
|= XMESA_NEW_TRIANGLE
;