1 /* $Id: xm_line.c,v 1.12 2000/11/22 07:32:18 joukj 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.
57 static void draw_points_ANY_pixmap( GLcontext
*ctx
, const SWvertex
*vert
)
59 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
60 XMesaDisplay
*dpy
= xmesa
->xm_visual
->display
;
61 XMesaDrawable buffer
= xmesa
->xm_buffer
->buffer
;
62 XMesaGC gc
= xmesa
->xm_buffer
->gc
;
64 if (xmesa
->xm_visual
->gl_visual
->RGBAflag
) {
66 const GLubyte
*color
= vert
->color
;
67 unsigned long pixel
= xmesa_color_to_pixel( xmesa
,
71 XMesaSetForeground( dpy
, gc
, pixel
);
72 x
= (GLint
) vert
->win
[0];
73 y
= FLIP( xmesa
->xm_buffer
, (GLint
) vert
->win
[1] );
74 XMesaDrawPoint( dpy
, buffer
, gc
, x
, y
);
77 /* Color index mode */
79 XMesaSetForeground( dpy
, gc
, vert
->index
);
80 x
= (GLint
) vert
->win
[0];
81 y
= FLIP( xmesa
->xm_buffer
, (GLint
) vert
->win
[1] );
82 XMesaDrawPoint( dpy
, buffer
, gc
, x
, y
);
88 /* Override the swrast point-selection function. Try to use one of
89 * our internal point functions, otherwise fall back to the standard
92 void xmesa_choose_point( GLcontext
*ctx
)
94 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
95 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
97 if (ctx
->RenderMode
== GL_RENDER
98 && ctx
->Point
.Size
== 1.0F
&& !ctx
->Point
.SmoothFlag
99 && swrast
->_RasterMask
== 0
100 && !ctx
->Texture
._ReallyEnabled
101 && xmesa
->xm_buffer
->buffer
!= XIMAGE
) {
102 swrast
->Point
= draw_points_ANY_pixmap
;
105 _swrast_choose_point( ctx
);
111 /**********************************************************************/
112 /*** Line rendering ***/
113 /**********************************************************************/
117 * Draw a flat-shaded, PF_TRUECOLOR line into an XImage.
119 static void flat_TRUECOLOR_line( GLcontext
*ctx
,
120 const SWvertex
*vert0
, const SWvertex
*vert1
)
122 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
123 const GLubyte
*color
= vert0
->color
;
124 XMesaImage
*img
= xmesa
->xm_buffer
->backimage
;
126 PACK_TRUECOLOR( pixel
, color
[0], color
[1], color
[2] );
130 #define PLOT(X,Y) XMesaPutPixel( img, X, FLIP(xmesa->xm_buffer, Y), pixel );
132 #include "swrast/s_linetemp.h"
138 * Draw a flat-shaded, PF_8A8B8G8R line into an XImage.
140 static void flat_8A8B8G8R_line( GLcontext
*ctx
,
141 const SWvertex
*vert0
, const SWvertex
*vert1
)
143 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
144 const GLubyte
*color
= vert0
->color
;
145 GLuint pixel
= PACK_8B8G8R( color
[0], color
[1], color
[2] );
147 #define PIXEL_TYPE GLuint
148 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
149 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(xmesa->xm_buffer,X,Y)
151 #define PLOT(X,Y) *pixelPtr = pixel;
153 #include "swrast/s_linetemp.h"
158 * Draw a flat-shaded, PF_8R8G8B line into an XImage.
160 static void flat_8R8G8B_line( GLcontext
*ctx
,
161 const SWvertex
*vert0
, const SWvertex
*vert1
)
163 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
164 const GLubyte
*color
= vert0
->color
;
165 GLuint pixel
= PACK_8R8G8B( color
[0], color
[1], color
[2] );
167 #define PIXEL_TYPE GLuint
168 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
169 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(xmesa->xm_buffer,X,Y)
171 #define PLOT(X,Y) *pixelPtr = pixel;
173 #include "swrast/s_linetemp.h"
178 * Draw a flat-shaded, PF_8R8G8B24 line into an XImage.
180 static void flat_8R8G8B24_line( GLcontext
*ctx
,
181 const SWvertex
*vert0
, const SWvertex
*vert1
)
183 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
184 const GLubyte
*color
= vert0
->color
;
186 #define PIXEL_TYPE bgr_t
187 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
188 #define PIXEL_ADDRESS(X,Y) PIXELADDR3(xmesa->xm_buffer,X,Y)
190 #define PLOT(X,Y) { \
191 pixelPtr->r = color[RCOMP]; \
192 pixelPtr->g = color[GCOMP]; \
193 pixelPtr->b = color[BCOMP]; \
196 #include "swrast/s_linetemp.h"
201 * Draw a flat-shaded, PF_5R6G5B line into an XImage.
203 static void flat_5R6G5B_line( GLcontext
*ctx
,
204 const SWvertex
*vert0
, const SWvertex
*vert1
)
206 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
207 const GLubyte
*color
= vert0
->color
;
208 GLushort pixel
= PACK_5R6G5B( color
[0], color
[1], color
[2] );
210 #define PIXEL_TYPE GLushort
211 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
212 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y)
214 #define PLOT(X,Y) *pixelPtr = pixel;
216 #include "swrast/s_linetemp.h"
221 * Draw a flat-shaded, PF_DITHER_5R6G5B line into an XImage.
223 static void flat_DITHER_5R6G5B_line( GLcontext
*ctx
,
224 const SWvertex
*vert0
, const SWvertex
*vert1
)
226 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
227 const GLubyte
*color
= vert0
->color
;
229 #define PIXEL_TYPE GLushort
230 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
231 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y)
233 #define PLOT(X,Y) PACK_TRUEDITHER( *pixelPtr, X, Y, color[0], color[1], color[2] );
235 #include "swrast/s_linetemp.h"
241 * Draw a flat-shaded, PF_DITHER 8-bit line into an XImage.
243 static void flat_DITHER8_line( GLcontext
*ctx
,
244 const SWvertex
*vert0
, const SWvertex
*vert1
)
246 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
247 const GLubyte
*color
= vert0
->color
;
248 GLint r
= color
[0], g
= color
[1], b
= color
[2];
252 #define PIXEL_TYPE GLubyte
253 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
254 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
256 #define PLOT(X,Y) *pixelPtr = DITHER(X,Y,r,g,b);
258 #include "swrast/s_linetemp.h"
263 * Draw a flat-shaded, PF_LOOKUP 8-bit line into an XImage.
265 static void flat_LOOKUP8_line( GLcontext
*ctx
,
266 const SWvertex
*vert0
, const SWvertex
*vert1
)
268 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
269 const GLubyte
*color
= vert0
->color
;
272 pixel
= (GLubyte
) LOOKUP( color
[0], color
[1], color
[2] );
274 #define PIXEL_TYPE GLubyte
275 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
276 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
278 #define PLOT(X,Y) *pixelPtr = pixel;
280 #include "swrast/s_linetemp.h"
285 * Draw a flat-shaded, PF_HPCR line into an XImage.
287 static void flat_HPCR_line( GLcontext
*ctx
,
288 const SWvertex
*vert0
, const SWvertex
*vert1
)
290 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
291 const GLubyte
*color
= vert0
->color
;
292 GLint r
= color
[0], g
= color
[1], b
= color
[2];
295 #define PIXEL_TYPE GLubyte
296 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
297 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
299 #define PLOT(X,Y) *pixelPtr = (GLubyte) DITHER_HPCR(X,Y,r,g,b);
301 #include "swrast/s_linetemp.h"
307 * Draw a flat-shaded, Z-less, PF_TRUECOLOR line into an XImage.
309 static void flat_TRUECOLOR_z_line( GLcontext
*ctx
,
310 const SWvertex
*vert0
, const SWvertex
*vert1
)
312 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
313 const GLubyte
*color
= vert0
->color
;
314 XMesaImage
*img
= xmesa
->xm_buffer
->backimage
;
316 PACK_TRUECOLOR( pixel
, color
[0], color
[1], color
[2] );
320 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
325 XMesaPutPixel( img, X, FLIP(xmesa->xm_buffer, Y), pixel ); \
328 #include "swrast/s_linetemp.h"
333 * Draw a flat-shaded, Z-less, PF_8A8B8G8R line into an XImage.
335 static void flat_8A8B8G8R_z_line( GLcontext
*ctx
,
336 const SWvertex
*vert0
, const SWvertex
*vert1
)
338 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
339 const GLubyte
*color
= vert0
->color
;
340 GLuint pixel
= PACK_8B8G8R( color
[0], color
[1], color
[2] );
343 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
344 #define PIXEL_TYPE GLuint
345 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
346 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(xmesa->xm_buffer,X,Y)
354 #include "swrast/s_linetemp.h"
359 * Draw a flat-shaded, Z-less, PF_8R8G8B line into an XImage.
361 static void flat_8R8G8B_z_line( GLcontext
*ctx
,
362 const SWvertex
*vert0
, const SWvertex
*vert1
)
364 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
365 const GLubyte
*color
= vert0
->color
;
366 GLuint pixel
= PACK_8R8G8B( color
[0], color
[1], color
[2] );
369 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
370 #define PIXEL_TYPE GLuint
371 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
372 #define PIXEL_ADDRESS(X,Y) PIXELADDR4(xmesa->xm_buffer,X,Y)
380 #include "swrast/s_linetemp.h"
385 * Draw a flat-shaded, Z-less, PF_8R8G8B24 line into an XImage.
387 static void flat_8R8G8B24_z_line( GLcontext
*ctx
,
388 const SWvertex
*vert0
, const SWvertex
*vert1
)
390 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
391 const GLubyte
*color
= vert0
->color
;
394 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
395 #define PIXEL_TYPE bgr_t
396 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
397 #define PIXEL_ADDRESS(X,Y) PIXELADDR3(xmesa->xm_buffer,X,Y)
402 pixelPtr->r = color[RCOMP]; \
403 pixelPtr->g = color[GCOMP]; \
404 pixelPtr->b = color[BCOMP]; \
407 #include "swrast/s_linetemp.h"
412 * Draw a flat-shaded, Z-less, PF_5R6G5B line into an XImage.
414 static void flat_5R6G5B_z_line( GLcontext
*ctx
,
415 const SWvertex
*vert0
, const SWvertex
*vert1
)
417 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
418 const GLubyte
*color
= vert0
->color
;
419 GLushort pixel
= PACK_5R6G5B( color
[0], color
[1], color
[2] );
422 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
423 #define PIXEL_TYPE GLushort
424 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
425 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y)
432 #include "swrast/s_linetemp.h"
437 * Draw a flat-shaded, Z-less, PF_DITHER_5R6G5B line into an XImage.
439 static void flat_DITHER_5R6G5B_z_line( GLcontext
*ctx
,
440 const SWvertex
*vert0
, const SWvertex
*vert1
)
442 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
443 const GLubyte
*color
= vert0
->color
;
446 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
447 #define PIXEL_TYPE GLushort
448 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
449 #define PIXEL_ADDRESS(X,Y) PIXELADDR2(xmesa->xm_buffer,X,Y)
454 PACK_TRUEDITHER(*pixelPtr, X, Y, color[0], color[1], color[2]); \
456 #include "swrast/s_linetemp.h"
461 * Draw a flat-shaded, Z-less, PF_DITHER 8-bit line into an XImage.
463 static void flat_DITHER8_z_line( GLcontext
*ctx
,
464 const SWvertex
*vert0
, const SWvertex
*vert1
)
466 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
467 const GLubyte
*color
= vert0
->color
;
468 GLint r
= color
[0], g
= color
[1], b
= color
[2];
473 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
474 #define PIXEL_TYPE GLubyte
475 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
476 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
481 *pixelPtr = (GLubyte) DITHER( X, Y, r, g, b); \
483 #include "swrast/s_linetemp.h"
488 * Draw a flat-shaded, Z-less, PF_LOOKUP 8-bit line into an XImage.
490 static void flat_LOOKUP8_z_line( GLcontext
*ctx
,
491 const SWvertex
*vert0
, const SWvertex
*vert1
)
493 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
494 const GLubyte
*color
= vert0
->color
;
497 pixel
= (GLubyte
) LOOKUP( color
[0], color
[1], color
[2] );
500 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
501 #define PIXEL_TYPE GLubyte
502 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
503 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
511 #include "swrast/s_linetemp.h"
516 * Draw a flat-shaded, Z-less, PF_HPCR line into an XImage.
518 static void flat_HPCR_z_line( GLcontext
*ctx
,
519 const SWvertex
*vert0
, const SWvertex
*vert1
)
521 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
522 const GLubyte
*color
= vert0
->color
;
523 GLint r
= color
[0], g
= color
[1], b
= color
[2];
527 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
528 #define PIXEL_TYPE GLubyte
529 #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
530 #define PIXEL_ADDRESS(X,Y) PIXELADDR1(xmesa->xm_buffer,X,Y)
535 *pixelPtr = (GLubyte) DITHER_HPCR( X, Y, r, g, b); \
538 #include "swrast/s_linetemp.h"
542 static swrast_line_func
get_line_func( GLcontext
*ctx
)
544 XMesaContext xmesa
= (XMesaContext
) ctx
->DriverCtx
;
545 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
546 int depth
= GET_VISUAL_DEPTH(xmesa
->xm_visual
);
548 (void) DitherValues
; /* silence unused var warning */
549 (void) kernel1
; /* silence unused var warning */
551 if (ctx
->RenderMode
!= GL_RENDER
) return (swrast_line_func
) NULL
;
552 if (ctx
->Line
.SmoothFlag
) return (swrast_line_func
) NULL
;
553 if (ctx
->Texture
._ReallyEnabled
) return (swrast_line_func
) NULL
;
554 if (ctx
->Light
.ShadeModel
!= GL_FLAT
) return (swrast_line_func
) NULL
;
555 if (ctx
->Line
.StippleFlag
) return (swrast_line_func
) NULL
;
557 if (xmesa
->xm_buffer
->buffer
==XIMAGE
558 && swrast
->_RasterMask
==DEPTH_BIT
559 && ctx
->Depth
.Func
==GL_LESS
560 && ctx
->Depth
.Mask
==GL_TRUE
561 && ctx
->Visual
.DepthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
562 && ctx
->Line
.Width
==1.0F
) {
563 switch (xmesa
->pixelformat
) {
565 return flat_TRUECOLOR_z_line
;
567 return flat_8A8B8G8R_z_line
;
569 return flat_8R8G8B_z_line
;
571 return flat_8R8G8B24_z_line
;
573 return flat_5R6G5B_z_line
;
574 case PF_DITHER_5R6G5B
:
575 return flat_DITHER_5R6G5B_z_line
;
577 return (depth
==8) ? flat_DITHER8_z_line
: (swrast_line_func
) NULL
;
579 return (depth
==8) ? flat_LOOKUP8_z_line
: (swrast_line_func
) NULL
;
581 return flat_HPCR_z_line
;
583 return (swrast_line_func
)NULL
;
586 if (xmesa
->xm_buffer
->buffer
==XIMAGE
587 && swrast
->_RasterMask
==0
588 && ctx
->Line
.Width
==1.0F
) {
589 switch (xmesa
->pixelformat
) {
591 return flat_TRUECOLOR_line
;
593 return flat_8A8B8G8R_line
;
595 return flat_8R8G8B_line
;
597 return flat_8R8G8B24_line
;
599 return flat_5R6G5B_line
;
600 case PF_DITHER_5R6G5B
:
601 return flat_DITHER_5R6G5B_line
;
603 return (depth
==8) ? flat_DITHER8_line
: (swrast_line_func
) NULL
;
605 return (depth
==8) ? flat_LOOKUP8_line
: (swrast_line_func
) NULL
;
607 return flat_HPCR_line
;
609 return (swrast_line_func
)NULL
;
613 return (swrast_line_func
) NULL
;
616 /* Override for the swrast line-selection function. Try to use one
617 * of our internal line functions, otherwise fall back to the
618 * standard swrast functions.
620 void xmesa_choose_line( GLcontext
*ctx
)
622 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
624 if (!(swrast
->Line
= get_line_func( ctx
)))
625 _swrast_choose_line( ctx
);
629 #define XMESA_NEW_POINT (_NEW_POINT | \
631 _SWRAST_NEW_RASTERMASK)
633 #define XMESA_NEW_LINE (_NEW_LINE | \
638 _SWRAST_NEW_RASTERMASK)
640 #define XMESA_NEW_TRIANGLE (_NEW_POLYGON | \
645 _SWRAST_NEW_RASTERMASK)
648 /* Extend the software rasterizer with our line/point/triangle
651 void xmesa_register_swrast_functions( GLcontext
*ctx
)
653 SWcontext
*swrast
= SWRAST_CONTEXT( ctx
);
655 swrast
->choose_point
= xmesa_choose_point
;
656 swrast
->choose_line
= xmesa_choose_line
;
657 swrast
->choose_triangle
= xmesa_choose_triangle
;
659 swrast
->invalidate_point
|= XMESA_NEW_POINT
;
660 swrast
->invalidate_line
|= XMESA_NEW_LINE
;
661 swrast
->invalidate_triangle
|= XMESA_NEW_TRIANGLE
;