2 * Mesa 3-D graphics library
4 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
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:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
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.
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"
34 #include "main/macros.h"
35 #include "main/mtypes.h"
38 /* Internal swrast includes:
40 #include "swrast/s_depth.h"
41 #include "swrast/s_points.h"
42 #include "swrast/s_lines.h"
43 #include "swrast/s_context.h"
46 /**********************************************************************/
47 /*** Point rendering ***/
48 /**********************************************************************/
52 * Render an array of points into a pixmap, any pixel format.
55 /* XXX don't use this, it doesn't dither correctly */
56 static void draw_points_ANY_pixmap( struct gl_context
*ctx
, const SWvertex
*vert
)
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
;
63 if (xmesa
->xm_visual
->mesa_visual
.RGBAflag
) {
65 const GLubyte
*color
= vert
->color
;
66 unsigned long pixel
= xmesa_color_to_pixel( xmesa
,
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
);
76 /* Color index mode */
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
);
87 /* Override the swrast point-selection function. Try to use one of
88 * our internal point functions, otherwise fall back to the standard
91 void xmesa_choose_point( struct gl_context
*ctx
)
94 XMesaContext xmesa
= XMESA_CONTEXT(ctx
);
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
._MaxEnabledTexImageUnit
== -1
101 && xmesa
->xm_buffer
->buffer
!= XIMAGE
) {
102 swrast
->Point
= draw_points_ANY_pixmap
;
105 _swrast_choose_point( ctx
);
108 _swrast_choose_point( ctx
);
114 /**********************************************************************/
115 /*** Line rendering ***/
116 /**********************************************************************/
122 #define GET_XRB(XRB) struct xmesa_renderbuffer *XRB = \
123 xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0])
127 * Draw a flat-shaded, PF_TRUECOLOR line into an XImage.
129 #define NAME flat_TRUECOLOR_line
131 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
133 const GLubyte *color = vert1->color; \
134 unsigned long pixel; \
135 PACK_TRUECOLOR( pixel, color[0], color[1], color[2] );
137 #define PLOT(X,Y) XMesaPutPixel(xrb->ximage, X, YFLIP(xrb, Y), pixel );
138 #include "swrast/s_linetemp.h"
143 * Draw a flat-shaded, PF_8A8B8G8R line into an XImage.
145 #define NAME flat_8A8B8G8R_line
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)
154 #define PLOT(X,Y) *pixelPtr = pixel;
155 #include "swrast/s_linetemp.h"
160 * Draw a flat-shaded, PF_8A8R8G8B line into an XImage.
162 #define NAME flat_8A8R8G8B_line
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)
171 #define PLOT(X,Y) *pixelPtr = pixel;
172 #include "swrast/s_linetemp.h"
177 * Draw a flat-shaded, PF_8R8G8B line into an XImage.
179 #define NAME flat_8R8G8B_line
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)
188 #define PLOT(X,Y) *pixelPtr = pixel;
189 #include "swrast/s_linetemp.h"
194 * Draw a flat-shaded, PF_8R8G8B24 line into an XImage.
196 #define NAME flat_8R8G8B24_line
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)
204 #define PLOT(X,Y) { \
205 pixelPtr->r = color[RCOMP]; \
206 pixelPtr->g = color[GCOMP]; \
207 pixelPtr->b = color[BCOMP]; \
209 #include "swrast/s_linetemp.h"
214 * Draw a flat-shaded, PF_5R6G5B line into an XImage.
216 #define NAME flat_5R6G5B_line
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)
225 #define PLOT(X,Y) *pixelPtr = pixel;
226 #include "swrast/s_linetemp.h"
231 * Draw a flat-shaded, PF_DITHER_5R6G5B line into an XImage.
233 #define NAME flat_DITHER_5R6G5B_line
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)
242 #define PLOT(X,Y) PACK_TRUEDITHER( *pixelPtr, X, Y, color[0], color[1], color[2] );
243 #include "swrast/s_linetemp.h"
248 * Draw a flat-shaded, Z-less, PF_TRUECOLOR line into an XImage.
250 #define NAME flat_TRUECOLOR_z_line
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] );
258 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
263 XMesaPutPixel(xrb->ximage, X, YFLIP(xrb, Y), pixel); \
265 #include "swrast/s_linetemp.h"
270 * Draw a flat-shaded, Z-less, PF_8A8B8G8R line into an XImage.
272 #define NAME flat_8A8B8G8R_z_line
275 const GLubyte *color = vert1->color; \
276 GLuint pixel = PACK_8A8B8G8R(color[0], color[1], color[2], color[3]);
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)
288 #include "swrast/s_linetemp.h"
293 * Draw a flat-shaded, Z-less, PF_8A8R8G8B line into an XImage.
295 #define NAME flat_8A8R8G8B_z_line
298 const GLubyte *color = vert1->color; \
299 GLuint pixel = PACK_8A8R8G8B(color[0], color[1], color[2], color[3]);
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)
311 #include "swrast/s_linetemp.h"
316 * Draw a flat-shaded, Z-less, PF_8R8G8B line into an XImage.
318 #define NAME flat_8R8G8B_z_line
321 const GLubyte *color = vert1->color; \
322 GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] );
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)
334 #include "swrast/s_linetemp.h"
339 * Draw a flat-shaded, Z-less, PF_8R8G8B24 line into an XImage.
341 #define NAME flat_8R8G8B24_z_line
344 const GLubyte *color = vert1->color;
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)
354 pixelPtr->r = color[RCOMP]; \
355 pixelPtr->g = color[GCOMP]; \
356 pixelPtr->b = color[BCOMP]; \
358 #include "swrast/s_linetemp.h"
363 * Draw a flat-shaded, Z-less, PF_5R6G5B line into an XImage.
365 #define NAME flat_5R6G5B_z_line
368 const GLubyte *color = vert1->color; \
369 GLushort pixel = PACK_5R6G5B( color[0], color[1], color[2] );
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)
381 #include "swrast/s_linetemp.h"
386 * Draw a flat-shaded, Z-less, PF_DITHER_5R6G5B line into an XImage.
388 #define NAME flat_DITHER_5R6G5B_z_line
391 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
392 const GLubyte *color = vert1->color;
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)
402 PACK_TRUEDITHER(*pixelPtr, X, Y, color[0], color[1], color[2]); \
404 #include "swrast/s_linetemp.h"
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.
416 xor_line(struct gl_context
*ctx
, const SWvertex
*vert0
, const SWvertex
*vert1
)
418 XMesaContext xmesa
= XMESA_CONTEXT(ctx
);
419 XMesaDisplay
*dpy
= xmesa
->xm_visual
->display
;
420 XMesaGC gc
= xmesa
->xm_buffer
->gc
;
422 unsigned long pixel
= xmesa_color_to_pixel(ctx
,
423 vert1
->color
[0], vert1
->color
[1],
424 vert1
->color
[2], vert1
->color
[3],
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 */
439 #endif /* CHAN_BITS == 8 */
443 * Return pointer to line drawing function, or NULL if we should use a
446 static swrast_line_func
447 get_line_func(struct gl_context
*ctx
)
450 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
451 XMesaContext xmesa
= XMESA_CONTEXT(ctx
);
452 const struct xmesa_renderbuffer
*xrb
;
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
;
464 xrb
= xmesa_renderbuffer(ctx
->DrawBuffer
->_ColorDrawBuffers
[0]);
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
) {
474 return flat_TRUECOLOR_z_line
;
476 return flat_8A8B8G8R_z_line
;
478 return flat_8A8R8G8B_z_line
;
480 return flat_8R8G8B_z_line
;
482 return flat_8R8G8B24_z_line
;
484 return flat_5R6G5B_z_line
;
485 case PF_Dither_5R6G5B
:
486 return flat_DITHER_5R6G5B_z_line
;
488 return (swrast_line_func
)NULL
;
492 && swrast
->_RasterMask
==0
493 && ctx
->Line
.Width
==1.0F
) {
494 switch (xmesa
->pixelformat
) {
496 return flat_TRUECOLOR_line
;
498 return flat_8A8B8G8R_line
;
500 return flat_8A8R8G8B_line
;
502 return flat_8R8G8B_line
;
504 return flat_8R8G8B24_line
;
506 return flat_5R6G5B_line
;
507 case PF_Dither_5R6G5B
:
508 return flat_DITHER_5R6G5B_line
;
510 return (swrast_line_func
)NULL
;
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
) {
523 #endif /* CHAN_BITS == 8 */
524 return (swrast_line_func
) NULL
;
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.
534 xmesa_choose_line(struct gl_context
*ctx
)
536 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
538 if (!(swrast
->Line
= get_line_func( ctx
)))
539 _swrast_choose_line( ctx
);