2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
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.
33 #include "glxheader.h"
39 /* Internal swrast includes:
41 #include "swrast/s_depth.h"
42 #include "swrast/s_points.h"
43 #include "swrast/s_lines.h"
44 #include "swrast/s_context.h"
47 /**********************************************************************/
48 /*** Point rendering ***/
49 /**********************************************************************/
53 * Render an array of points into a pixmap, any pixel format.
56 /* XXX don't use this, it doesn't dither correctly */
57 static void draw_points_ANY_pixmap( GLcontext
*ctx
, const SWvertex
*vert
)
59 XMesaContext xmesa
= XMESA_CONTEXT(ctx
);
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
->mesa_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
= YFLIP( xrb
, (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
= YFLIP( xrb
, (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
)
95 XMesaContext xmesa
= XMESA_CONTEXT(ctx
);
96 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
98 if (ctx
->RenderMode
== GL_RENDER
99 && ctx
->Point
.Size
== 1.0F
&& !ctx
->Point
.SmoothFlag
100 && swrast
->_RasterMask
== 0
101 && !ctx
->Texture
._EnabledUnits
102 && xmesa
->xm_buffer
->buffer
!= XIMAGE
) {
103 swrast
->Point
= draw_points_ANY_pixmap
;
106 _swrast_choose_point( ctx
);
109 _swrast_choose_point( ctx
);
115 /**********************************************************************/
116 /*** Line rendering ***/
117 /**********************************************************************/
120 #define GET_XRB(XRB) struct xmesa_renderbuffer *XRB = \
121 (struct xmesa_renderbuffer *) ctx->DrawBuffer->_ColorDrawBuffers[0][0]->Wrapped
125 * Draw a flat-shaded, PF_TRUECOLOR line into an XImage.
127 #define NAME flat_TRUECOLOR_line
129 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
131 const GLubyte *color = vert1->color; \
132 unsigned long pixel; \
133 PACK_TRUECOLOR( pixel, color[0], color[1], color[2] );
135 #define PLOT(X,Y) XMesaPutPixel(xrb->ximage, X, YFLIP(xrb, Y), pixel );
136 #include "swrast/s_linetemp.h"
141 * Draw a flat-shaded, PF_8A8B8G8R line into an XImage.
143 #define NAME flat_8A8B8G8R_line
146 const GLubyte *color = vert1->color; \
147 GLuint pixel = PACK_8B8G8R( color[0], color[1], color[2] );
148 #define PIXEL_TYPE GLuint
149 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
150 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
152 #define PLOT(X,Y) *pixelPtr = pixel;
153 #include "swrast/s_linetemp.h"
158 * Draw a flat-shaded, PF_8A8R8G8B line into an XImage.
160 #define NAME flat_8A8R8G8B_line
163 const GLubyte *color = vert1->color; \
164 GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] );
165 #define PIXEL_TYPE GLuint
166 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
167 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
169 #define PLOT(X,Y) *pixelPtr = pixel;
170 #include "swrast/s_linetemp.h"
175 * Draw a flat-shaded, PF_8R8G8B line into an XImage.
177 #define NAME flat_8R8G8B_line
180 const GLubyte *color = vert1->color; \
181 GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] );
182 #define PIXEL_TYPE GLuint
183 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
184 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
186 #define PLOT(X,Y) *pixelPtr = pixel;
187 #include "swrast/s_linetemp.h"
192 * Draw a flat-shaded, PF_8R8G8B24 line into an XImage.
194 #define NAME flat_8R8G8B24_line
197 const GLubyte *color = vert1->color;
198 #define PIXEL_TYPE bgr_t
199 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
200 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X, Y)
202 #define PLOT(X,Y) { \
203 pixelPtr->r = color[RCOMP]; \
204 pixelPtr->g = color[GCOMP]; \
205 pixelPtr->b = color[BCOMP]; \
207 #include "swrast/s_linetemp.h"
212 * Draw a flat-shaded, PF_5R6G5B line into an XImage.
214 #define NAME flat_5R6G5B_line
217 const GLubyte *color = vert1->color; \
218 GLushort pixel = PACK_5R6G5B( color[0], color[1], color[2] );
219 #define PIXEL_TYPE GLushort
220 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
221 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y)
223 #define PLOT(X,Y) *pixelPtr = pixel;
224 #include "swrast/s_linetemp.h"
229 * Draw a flat-shaded, PF_DITHER_5R6G5B line into an XImage.
231 #define NAME flat_DITHER_5R6G5B_line
234 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
235 const GLubyte *color = vert1->color;
236 #define PIXEL_TYPE GLushort
237 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
238 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y)
240 #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 #define NAME flat_DITHER8_line
252 const GLubyte *color = vert1->color; \
253 GLint r = color[0], g = color[1], b = color[2]; \
255 #define PIXEL_TYPE GLubyte
256 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
257 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X, Y)
259 #define PLOT(X,Y) *pixelPtr = DITHER(X,Y,r,g,b);
260 #include "swrast/s_linetemp.h"
265 * Draw a flat-shaded, PF_LOOKUP 8-bit line into an XImage.
267 #define NAME flat_LOOKUP8_line
270 const GLubyte *color = vert1->color; \
273 pixel = (GLubyte) LOOKUP( color[0], color[1], color[2] );
274 #define PIXEL_TYPE GLubyte
275 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
276 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X,Y)
278 #define PLOT(X,Y) *pixelPtr = pixel;
279 #include "swrast/s_linetemp.h"
284 * Draw a flat-shaded, PF_HPCR line into an XImage.
286 #define NAME flat_HPCR_line
289 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
290 const GLubyte *color = vert1->color; \
291 GLint r = color[0], g = color[1], b = color[2];
292 #define PIXEL_TYPE GLubyte
293 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
294 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X,Y)
296 #define PLOT(X,Y) *pixelPtr = (GLubyte) DITHER_HPCR(X,Y,r,g,b);
297 #include "swrast/s_linetemp.h"
303 * Draw a flat-shaded, Z-less, PF_TRUECOLOR line into an XImage.
305 #define NAME flat_TRUECOLOR_z_line
308 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
309 const GLubyte *color = vert1->color; \
310 unsigned long pixel; \
311 PACK_TRUECOLOR( pixel, color[0], color[1], color[2] );
313 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
318 XMesaPutPixel(xrb->ximage, X, YFLIP(xrb, Y), pixel); \
320 #include "swrast/s_linetemp.h"
325 * Draw a flat-shaded, Z-less, PF_8A8B8G8R line into an XImage.
327 #define NAME flat_8A8B8G8R_z_line
330 const GLubyte *color = vert1->color; \
331 GLuint pixel = PACK_8B8G8R( color[0], color[1], color[2] );
333 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
334 #define PIXEL_TYPE GLuint
335 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
336 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X,Y)
343 #include "swrast/s_linetemp.h"
348 * Draw a flat-shaded, Z-less, PF_8A8R8G8B line into an XImage.
350 #define NAME flat_8A8R8G8B_z_line
353 const GLubyte *color = vert1->color; \
354 GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] );
356 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
357 #define PIXEL_TYPE GLuint
358 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
359 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X,Y)
366 #include "swrast/s_linetemp.h"
371 * Draw a flat-shaded, Z-less, PF_8R8G8B line into an XImage.
373 #define NAME flat_8R8G8B_z_line
376 const GLubyte *color = vert1->color; \
377 GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] );
379 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
380 #define PIXEL_TYPE GLuint
381 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
382 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X,Y)
389 #include "swrast/s_linetemp.h"
394 * Draw a flat-shaded, Z-less, PF_8R8G8B24 line into an XImage.
396 #define NAME flat_8R8G8B24_z_line
399 const GLubyte *color = vert1->color;
401 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
402 #define PIXEL_TYPE bgr_t
403 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
404 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X,Y)
409 pixelPtr->r = color[RCOMP]; \
410 pixelPtr->g = color[GCOMP]; \
411 pixelPtr->b = color[BCOMP]; \
413 #include "swrast/s_linetemp.h"
418 * Draw a flat-shaded, Z-less, PF_5R6G5B line into an XImage.
420 #define NAME flat_5R6G5B_z_line
423 const GLubyte *color = vert1->color; \
424 GLushort pixel = PACK_5R6G5B( color[0], color[1], color[2] );
426 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
427 #define PIXEL_TYPE GLushort
428 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
429 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X,Y)
436 #include "swrast/s_linetemp.h"
441 * Draw a flat-shaded, Z-less, PF_DITHER_5R6G5B line into an XImage.
443 #define NAME flat_DITHER_5R6G5B_z_line
446 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
447 const GLubyte *color = vert1->color;
449 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
450 #define PIXEL_TYPE GLushort
451 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
452 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X,Y)
457 PACK_TRUEDITHER(*pixelPtr, X, Y, color[0], color[1], color[2]); \
459 #include "swrast/s_linetemp.h"
464 * Draw a flat-shaded, Z-less, PF_DITHER 8-bit line into an XImage.
466 #define NAME flat_DITHER8_z_line
469 const GLubyte *color = vert1->color; \
470 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 (xrb->ximage->bytes_per_line)
476 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, 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 #define NAME flat_LOOKUP8_z_line
493 const GLubyte *color = vert1->color; \
496 pixel = (GLubyte) LOOKUP( color[0], color[1], color[2] );
498 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
499 #define PIXEL_TYPE GLubyte
500 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
501 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X,Y)
508 #include "swrast/s_linetemp.h"
513 * Draw a flat-shaded, Z-less, PF_HPCR line into an XImage.
515 #define NAME flat_HPCR_z_line
518 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
519 const GLubyte *color = vert1->color; \
520 GLint r = color[0], g = color[1], b = color[2];
522 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
523 #define PIXEL_TYPE GLubyte
524 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
525 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR1(xrb, X,Y)
530 *pixelPtr = (GLubyte) DITHER_HPCR( X, Y, r, g, b); \
532 #include "swrast/s_linetemp.h"
536 #ifndef XFree86Server
538 * Draw fast, XOR line with XDrawLine in front color buffer.
539 * WARNING: this isn't fully OpenGL conformant because different pixels
540 * will be hit versus using the other line functions.
541 * Don't use the code in X server GLcore module since we need a wrapper
542 * for the XSetLineAttributes() function call.
545 xor_line(GLcontext
*ctx
, const SWvertex
*vert0
, const SWvertex
*vert1
)
547 XMesaContext xmesa
= XMESA_CONTEXT(ctx
);
548 XMesaDisplay
*dpy
= xmesa
->xm_visual
->display
;
549 XMesaGC gc
= xmesa
->xm_buffer
->gc
;
550 struct xmesa_renderbuffer
*xrb
= (struct xmesa_renderbuffer
*)
551 ctx
->DrawBuffer
->_ColorDrawBuffers
[0][0];
552 unsigned long pixel
= xmesa_color_to_pixel(ctx
,
553 vert1
->color
[0], vert1
->color
[1],
554 vert1
->color
[2], vert1
->color
[3],
556 int x0
= (int) vert0
->win
[0];
557 int y0
= YFLIP(xrb
, (GLint
) vert0
->win
[1]);
558 int x1
= (int) vert1
->win
[0];
559 int y1
= YFLIP(xrb
, (GLint
) vert1
->win
[1]);
560 XMesaSetForeground(dpy
, gc
, pixel
);
561 XMesaSetFunction(dpy
, gc
, GXxor
);
562 XSetLineAttributes(dpy
, gc
, (int) ctx
->Line
.Width
,
563 LineSolid
, CapButt
, JoinMiter
);
564 XDrawLine(dpy
, xrb
->pixmap
, gc
, x0
, y0
, x1
, y1
);
565 XMesaSetFunction(dpy
, gc
, GXcopy
); /* this gc is used elsewhere */
567 #endif /* XFree86Server */
571 * Return pointer to line drawing function, or NULL if we should use a
574 static swrast_line_func
575 get_line_func(GLcontext
*ctx
)
577 XMesaContext xmesa
= XMESA_CONTEXT(ctx
);
578 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
579 int depth
= GET_VISUAL_DEPTH(xmesa
->xm_visual
);
582 if ((ctx
->DrawBuffer
->_ColorDrawBufferMask
[0]
583 & (BUFFER_BIT_FRONT_LEFT
| BUFFER_BIT_BACK_LEFT
)) == 0)
584 return (swrast_line_func
) NULL
;
585 if (ctx
->RenderMode
!= GL_RENDER
) return (swrast_line_func
) NULL
;
586 if (ctx
->Line
.SmoothFlag
) return (swrast_line_func
) NULL
;
587 if (ctx
->Texture
._EnabledUnits
) return (swrast_line_func
) NULL
;
588 if (ctx
->Light
.ShadeModel
!= GL_FLAT
) return (swrast_line_func
) NULL
;
589 if (ctx
->Line
.StippleFlag
) return (swrast_line_func
) NULL
;
590 if (swrast
->_RasterMask
& MULTI_DRAW_BIT
) return (swrast_line_func
) NULL
;
593 && swrast
->_RasterMask
==DEPTH_BIT
594 && ctx
->Depth
.Func
==GL_LESS
595 && ctx
->Depth
.Mask
==GL_TRUE
596 && ctx
->Visual
.depthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
597 && ctx
->Line
.Width
==1.0F
) {
598 switch (xmesa
->pixelformat
) {
600 return flat_TRUECOLOR_z_line
;
602 return flat_8A8B8G8R_z_line
;
604 return flat_8A8R8G8B_z_line
;
606 return flat_8R8G8B_z_line
;
608 return flat_8R8G8B24_z_line
;
610 return flat_5R6G5B_z_line
;
611 case PF_Dither_5R6G5B
:
612 return flat_DITHER_5R6G5B_z_line
;
614 return (depth
==8) ? flat_DITHER8_z_line
: (swrast_line_func
) NULL
;
616 return (depth
==8) ? flat_LOOKUP8_z_line
: (swrast_line_func
) NULL
;
618 return flat_HPCR_z_line
;
620 return (swrast_line_func
)NULL
;
624 && swrast
->_RasterMask
==0
625 && ctx
->Line
.Width
==1.0F
) {
626 switch (xmesa
->pixelformat
) {
628 return flat_TRUECOLOR_line
;
630 return flat_8A8B8G8R_line
;
632 return flat_8A8R8G8B_line
;
634 return flat_8R8G8B_line
;
636 return flat_8R8G8B24_line
;
638 return flat_5R6G5B_line
;
639 case PF_Dither_5R6G5B
:
640 return flat_DITHER_5R6G5B_line
;
642 return (depth
==8) ? flat_DITHER8_line
: (swrast_line_func
) NULL
;
644 return (depth
==8) ? flat_LOOKUP8_line
: (swrast_line_func
) NULL
;
646 return flat_HPCR_line
;
648 return (swrast_line_func
)NULL
;
652 #ifndef XFree86Server
653 if (ctx
->DrawBuffer
->_NumColorDrawBuffers
[0] == 1
654 && ctx
->DrawBuffer
->_ColorDrawBufferMask
[0] == BUFFER_BIT_FRONT_LEFT
655 && swrast
->_RasterMask
== LOGIC_OP_BIT
656 && ctx
->Color
.LogicOp
== GL_XOR
657 && !ctx
->Line
.StippleFlag
658 && !ctx
->Line
.SmoothFlag
) {
661 #endif /* XFree86Server */
663 return (swrast_line_func
) NULL
;
668 * Override for the swrast line-selection function. Try to use one
669 * of our internal line functions, otherwise fall back to the
670 * standard swrast functions.
673 xmesa_choose_line(GLcontext
*ctx
)
675 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
677 if (!(swrast
->Line
= get_line_func( ctx
)))
678 _swrast_choose_line( ctx
);