1 /* $Id: xm_line.c,v 1.18 2001/09/12 03:32:29 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"
42 /* Internal swrast includes:
44 #include "swrast/s_depth.h"
45 #include "swrast/s_points.h"
46 #include "swrast/s_lines.h"
47 #include "swrast/s_context.h"
50 /**********************************************************************/
51 /*** Point rendering ***/
52 /**********************************************************************/
56 * Render an array of points into a pixmap, any pixel format.
59 /* XXX don't use this, it doesn't dither correctly */
60 static void draw_points_ANY_pixmap( GLcontext
*ctx
, const SWvertex
*vert
)
62 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
63 XMesaDisplay
*dpy
= xmesa
->xm_visual
->display
;
64 XMesaDrawable buffer
= xmesa
->xm_buffer
->buffer
;
65 XMesaGC gc
= xmesa
->xm_buffer
->gc
;
67 if (xmesa
->xm_visual
->mesa_visual
.RGBAflag
) {
69 const GLubyte
*color
= vert
->color
;
70 unsigned long pixel
= xmesa_color_to_pixel( xmesa
,
74 XMesaSetForeground( dpy
, gc
, pixel
);
75 x
= (GLint
) vert
->win
[0];
76 y
= FLIP( xmesa
->xm_buffer
, (GLint
) vert
->win
[1] );
77 XMesaDrawPoint( dpy
, buffer
, gc
, x
, y
);
80 /* Color index mode */
82 XMesaSetForeground( dpy
, gc
, vert
->index
);
83 x
= (GLint
) vert
->win
[0];
84 y
= FLIP( xmesa
->xm_buffer
, (GLint
) vert
->win
[1] );
85 XMesaDrawPoint( dpy
, buffer
, gc
, x
, y
);
91 /* Override the swrast point-selection function. Try to use one of
92 * our internal point functions, otherwise fall back to the standard
95 void xmesa_choose_point( GLcontext
*ctx
)
98 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
99 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
101 if (ctx
->RenderMode
== GL_RENDER
102 && ctx
->Point
.Size
== 1.0F
&& !ctx
->Point
.SmoothFlag
103 && swrast
->_RasterMask
== 0
104 && !ctx
->Texture
._ReallyEnabled
105 && xmesa
->xm_buffer
->buffer
!= XIMAGE
) {
106 swrast
->Point
= draw_points_ANY_pixmap
;
109 _swrast_choose_point( ctx
);
112 _swrast_choose_point( ctx
);
118 /**********************************************************************/
119 /*** Line rendering ***/
120 /**********************************************************************/
124 * Draw a flat-shaded, PF_TRUECOLOR line into an XImage.
126 static void flat_TRUECOLOR_line( GLcontext
*ctx
,
127 const SWvertex
*vert0
, const SWvertex
*vert1
)
129 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
130 const GLubyte
*color
= vert1
->color
;
131 XMesaImage
*img
= xmesa
->xm_buffer
->backimage
;
133 PACK_TRUECOLOR( pixel
, color
[0], color
[1], color
[2] );
137 #define PLOT(X,Y) XMesaPutPixel( img, X, FLIP(xmesa->xm_buffer, Y), pixel );
139 #include "swrast/s_linetemp.h"
145 * Draw a flat-shaded, PF_8A8B8G8R line into an XImage.
147 static void flat_8A8B8G8R_line( GLcontext
*ctx
,
148 const SWvertex
*vert0
, const SWvertex
*vert1
)
150 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
151 const GLubyte
*color
= vert1
->color
;
152 GLuint pixel
= PACK_8B8G8R( color
[0], color
[1], color
[2] );
154 #define PIXEL_TYPE GLuint
155 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
156 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(xmesa->xm_buffer,X,Y)
158 #define PLOT(X,Y) *pixelPtr = pixel;
160 #include "swrast/s_linetemp.h"
165 * Draw a flat-shaded, PF_8R8G8B line into an XImage.
167 static void flat_8R8G8B_line( GLcontext
*ctx
,
168 const SWvertex
*vert0
, const SWvertex
*vert1
)
170 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
171 const GLubyte
*color
= vert1
->color
;
172 GLuint pixel
= PACK_8R8G8B( color
[0], color
[1], color
[2] );
174 #define PIXEL_TYPE GLuint
175 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
176 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(xmesa->xm_buffer,X,Y)
178 #define PLOT(X,Y) *pixelPtr = pixel;
180 #include "swrast/s_linetemp.h"
185 * Draw a flat-shaded, PF_8R8G8B24 line into an XImage.
187 static void flat_8R8G8B24_line( GLcontext
*ctx
,
188 const SWvertex
*vert0
, const SWvertex
*vert1
)
190 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
191 const GLubyte
*color
= vert1
->color
;
193 #define PIXEL_TYPE bgr_t
194 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
195 #define PIXEL_ADDRESS(X,Y) PIXELADDR3(xmesa->xm_buffer,X,Y)
197 #define PLOT(X,Y) { \
198 pixelPtr->r = color[RCOMP]; \
199 pixelPtr->g = color[GCOMP]; \
200 pixelPtr->b = color[BCOMP]; \
203 #include "swrast/s_linetemp.h"
208 * Draw a flat-shaded, PF_5R6G5B line into an XImage.
210 static void flat_5R6G5B_line( GLcontext
*ctx
,
211 const SWvertex
*vert0
, const SWvertex
*vert1
)
213 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
214 const GLubyte
*color
= vert1
->color
;
215 GLushort pixel
= PACK_5R6G5B( color
[0], color
[1], color
[2] );
217 #define PIXEL_TYPE GLushort
218 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
219 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y)
221 #define PLOT(X,Y) *pixelPtr = pixel;
223 #include "swrast/s_linetemp.h"
228 * Draw a flat-shaded, PF_DITHER_5R6G5B line into an XImage.
230 static void flat_DITHER_5R6G5B_line( GLcontext
*ctx
,
231 const SWvertex
*vert0
, const SWvertex
*vert1
)
233 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
234 const GLubyte
*color
= vert1
->color
;
236 #define PIXEL_TYPE GLushort
237 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
238 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y)
240 #define PLOT(X,Y) PACK_TRUEDITHER( *pixelPtr, X, Y, color[0], color[1], color[2] );
242 #include "swrast/s_linetemp.h"
248 * Draw a flat-shaded, PF_DITHER 8-bit line into an XImage.
250 static void flat_DITHER8_line( GLcontext
*ctx
,
251 const SWvertex
*vert0
, const SWvertex
*vert1
)
253 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
254 const GLubyte
*color
= vert1
->color
;
255 GLint r
= color
[0], g
= color
[1], b
= color
[2];
259 #define PIXEL_TYPE GLubyte
260 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
261 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
263 #define PLOT(X,Y) *pixelPtr = DITHER(X,Y,r,g,b);
265 #include "swrast/s_linetemp.h"
270 * Draw a flat-shaded, PF_LOOKUP 8-bit line into an XImage.
272 static void flat_LOOKUP8_line( GLcontext
*ctx
,
273 const SWvertex
*vert0
, const SWvertex
*vert1
)
275 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
276 const GLubyte
*color
= vert1
->color
;
279 pixel
= (GLubyte
) LOOKUP( color
[0], color
[1], color
[2] );
281 #define PIXEL_TYPE GLubyte
282 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
283 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
285 #define PLOT(X,Y) *pixelPtr = pixel;
287 #include "swrast/s_linetemp.h"
292 * Draw a flat-shaded, PF_HPCR line into an XImage.
294 static void flat_HPCR_line( GLcontext
*ctx
,
295 const SWvertex
*vert0
, const SWvertex
*vert1
)
297 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
298 const GLubyte
*color
= vert1
->color
;
299 GLint r
= color
[0], g
= color
[1], b
= color
[2];
302 #define PIXEL_TYPE GLubyte
303 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
304 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
306 #define PLOT(X,Y) *pixelPtr = (GLubyte) DITHER_HPCR(X,Y,r,g,b);
308 #include "swrast/s_linetemp.h"
314 * Draw a flat-shaded, Z-less, PF_TRUECOLOR line into an XImage.
316 static void flat_TRUECOLOR_z_line( GLcontext
*ctx
,
317 const SWvertex
*vert0
, const SWvertex
*vert1
)
319 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
320 const GLubyte
*color
= vert1
->color
;
321 XMesaImage
*img
= xmesa
->xm_buffer
->backimage
;
323 PACK_TRUECOLOR( pixel
, color
[0], color
[1], color
[2] );
327 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
332 XMesaPutPixel( img, X, FLIP(xmesa->xm_buffer, Y), pixel ); \
335 #include "swrast/s_linetemp.h"
340 * Draw a flat-shaded, Z-less, PF_8A8B8G8R line into an XImage.
342 static void flat_8A8B8G8R_z_line( GLcontext
*ctx
,
343 const SWvertex
*vert0
, const SWvertex
*vert1
)
345 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
346 const GLubyte
*color
= vert1
->color
;
347 GLuint pixel
= PACK_8B8G8R( color
[0], color
[1], color
[2] );
350 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
351 #define PIXEL_TYPE GLuint
352 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
353 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(xmesa->xm_buffer,X,Y)
361 #include "swrast/s_linetemp.h"
366 * Draw a flat-shaded, Z-less, PF_8R8G8B line into an XImage.
368 static void flat_8R8G8B_z_line( GLcontext
*ctx
,
369 const SWvertex
*vert0
, const SWvertex
*vert1
)
371 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
372 const GLubyte
*color
= vert1
->color
;
373 GLuint pixel
= PACK_8R8G8B( color
[0], color
[1], color
[2] );
376 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
377 #define PIXEL_TYPE GLuint
378 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
379 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(xmesa->xm_buffer,X,Y)
387 #include "swrast/s_linetemp.h"
392 * Draw a flat-shaded, Z-less, PF_8R8G8B24 line into an XImage.
394 static void flat_8R8G8B24_z_line( GLcontext
*ctx
,
395 const SWvertex
*vert0
, const SWvertex
*vert1
)
397 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
398 const GLubyte
*color
= vert1
->color
;
401 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
402 #define PIXEL_TYPE bgr_t
403 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
404 #define PIXEL_ADDRESS(X,Y) PIXELADDR3(xmesa->xm_buffer,X,Y)
409 pixelPtr->r = color[RCOMP]; \
410 pixelPtr->g = color[GCOMP]; \
411 pixelPtr->b = color[BCOMP]; \
414 #include "swrast/s_linetemp.h"
419 * Draw a flat-shaded, Z-less, PF_5R6G5B line into an XImage.
421 static void flat_5R6G5B_z_line( GLcontext
*ctx
,
422 const SWvertex
*vert0
, const SWvertex
*vert1
)
424 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
425 const GLubyte
*color
= vert1
->color
;
426 GLushort pixel
= PACK_5R6G5B( color
[0], color
[1], color
[2] );
429 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
430 #define PIXEL_TYPE GLushort
431 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
432 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y)
439 #include "swrast/s_linetemp.h"
444 * Draw a flat-shaded, Z-less, PF_DITHER_5R6G5B line into an XImage.
446 static void flat_DITHER_5R6G5B_z_line( GLcontext
*ctx
,
447 const SWvertex
*vert0
, const SWvertex
*vert1
)
449 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
450 const GLubyte
*color
= vert1
->color
;
453 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
454 #define PIXEL_TYPE GLushort
455 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
456 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y)
461 PACK_TRUEDITHER(*pixelPtr, X, Y, color[0], color[1], color[2]); \
463 #include "swrast/s_linetemp.h"
468 * Draw a flat-shaded, Z-less, PF_DITHER 8-bit line into an XImage.
470 static void flat_DITHER8_z_line( GLcontext
*ctx
,
471 const SWvertex
*vert0
, const SWvertex
*vert1
)
473 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
474 const GLubyte
*color
= vert1
->color
;
475 GLint r
= color
[0], g
= color
[1], b
= color
[2];
480 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
481 #define PIXEL_TYPE GLubyte
482 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
483 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
488 *pixelPtr = (GLubyte) DITHER( X, Y, r, g, b); \
490 #include "swrast/s_linetemp.h"
495 * Draw a flat-shaded, Z-less, PF_LOOKUP 8-bit line into an XImage.
497 static void flat_LOOKUP8_z_line( GLcontext
*ctx
,
498 const SWvertex
*vert0
, const SWvertex
*vert1
)
500 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
501 const GLubyte
*color
= vert1
->color
;
504 pixel
= (GLubyte
) LOOKUP( color
[0], color
[1], color
[2] );
507 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
508 #define PIXEL_TYPE GLubyte
509 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
510 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
518 #include "swrast/s_linetemp.h"
523 * Draw a flat-shaded, Z-less, PF_HPCR line into an XImage.
525 static void flat_HPCR_z_line( GLcontext
*ctx
,
526 const SWvertex
*vert0
, const SWvertex
*vert1
)
528 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
529 const GLubyte
*color
= vert1
->color
;
530 GLint r
= color
[0], g
= color
[1], b
= color
[2];
534 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
535 #define PIXEL_TYPE GLubyte
536 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
537 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
542 *pixelPtr = (GLubyte) DITHER_HPCR( X, Y, r, g, b); \
545 #include "swrast/s_linetemp.h"
549 static swrast_line_func
get_line_func( GLcontext
*ctx
)
551 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
552 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
553 int depth
= GET_VISUAL_DEPTH(xmesa
->xm_visual
);
555 (void) DitherValues
; /* silence unused var warning */
556 (void) kernel1
; /* silence unused var warning */
558 if (ctx
->RenderMode
!= GL_RENDER
) return (swrast_line_func
) NULL
;
559 if (ctx
->Line
.SmoothFlag
) return (swrast_line_func
) NULL
;
560 if (ctx
->Texture
._ReallyEnabled
) return (swrast_line_func
) NULL
;
561 if (ctx
->Light
.ShadeModel
!= GL_FLAT
) return (swrast_line_func
) NULL
;
562 if (ctx
->Line
.StippleFlag
) return (swrast_line_func
) NULL
;
564 if (xmesa
->xm_buffer
->buffer
==XIMAGE
565 && swrast
->_RasterMask
==DEPTH_BIT
566 && ctx
->Depth
.Func
==GL_LESS
567 && ctx
->Depth
.Mask
==GL_TRUE
568 && ctx
->Visual
.depthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
569 && ctx
->Line
.Width
==1.0F
) {
570 switch (xmesa
->pixelformat
) {
572 return flat_TRUECOLOR_z_line
;
574 return flat_8A8B8G8R_z_line
;
576 return flat_8R8G8B_z_line
;
578 return flat_8R8G8B24_z_line
;
580 return flat_5R6G5B_z_line
;
581 case PF_DITHER_5R6G5B
:
582 return flat_DITHER_5R6G5B_z_line
;
584 return (depth
==8) ? flat_DITHER8_z_line
: (swrast_line_func
) NULL
;
586 return (depth
==8) ? flat_LOOKUP8_z_line
: (swrast_line_func
) NULL
;
588 return flat_HPCR_z_line
;
590 return (swrast_line_func
)NULL
;
593 if (xmesa
->xm_buffer
->buffer
==XIMAGE
594 && swrast
->_RasterMask
==0
595 && ctx
->Line
.Width
==1.0F
) {
596 switch (xmesa
->pixelformat
) {
598 return flat_TRUECOLOR_line
;
600 return flat_8A8B8G8R_line
;
602 return flat_8R8G8B_line
;
604 return flat_8R8G8B24_line
;
606 return flat_5R6G5B_line
;
607 case PF_DITHER_5R6G5B
:
608 return flat_DITHER_5R6G5B_line
;
610 return (depth
==8) ? flat_DITHER8_line
: (swrast_line_func
) NULL
;
612 return (depth
==8) ? flat_LOOKUP8_line
: (swrast_line_func
) NULL
;
614 return flat_HPCR_line
;
616 return (swrast_line_func
)NULL
;
620 return (swrast_line_func
) NULL
;
623 /* Override for the swrast line-selection function. Try to use one
624 * of our internal line functions, otherwise fall back to the
625 * standard swrast functions.
627 void xmesa_choose_line( GLcontext
*ctx
)
629 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
631 if (!(swrast
->Line
= get_line_func( ctx
)))
632 _swrast_choose_line( ctx
);