1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
5 *
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:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
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.
23 */
24
25
26 /*
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.
30 */
31
32
33 #include "glxheader.h"
34 #include "main/macros.h"
35 #include "main/mtypes.h"
36 #include "xmesaP.h"
37
38 /* Internal swrast includes:
39 */
40 #include "swrast/s_depth.h"
41 #include "swrast/s_points.h"
42 #include "swrast/s_lines.h"
43 #include "swrast/s_context.h"
44
45
46 /**********************************************************************/
47 /*** Point rendering ***/
48 /**********************************************************************/
49
50
51 /*
52 * Render an array of points into a pixmap, any pixel format.
53 */
54 #if 000
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 )
57 {
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;
62
63 if (xmesa->xm_visual->mesa_visual.RGBAflag) {
64 register int x, y;
65 const GLubyte *color = vert->color;
66 unsigned long pixel = xmesa_color_to_pixel( xmesa,
67 color[0], color[1],
68 color[2], color[3],
69 xmesa->pixelformat);
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);
74 }
75 else {
76 /* Color index mode */
77 register int x, y;
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);
82 }
83 }
84 #endif
85
86
87 /* Override the swrast point-selection function. Try to use one of
88 * our internal point functions, otherwise fall back to the standard
89 * swrast functions.
90 */
xmesa_choose_point(struct gl_context * ctx)91 void xmesa_choose_point( struct gl_context *ctx )
92 {
93 #if 0
94 XMesaContext xmesa = XMESA_CONTEXT(ctx);
95 SWcontext *swrast = SWRAST_CONTEXT(ctx);
96
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;
103 }
104 else {
105 _swrast_choose_point( ctx );
106 }
107 #else
108 _swrast_choose_point( ctx );
109 #endif
110 }
111
112
113
114 /**********************************************************************/
115 /*** Line rendering ***/
116 /**********************************************************************/
117
118
119 #if CHAN_BITS == 8
120
121
122 #define GET_XRB(XRB) struct xmesa_renderbuffer *XRB = \
123 xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0])
124
125
126 /*
127 * Draw a flat-shaded, PF_TRUECOLOR line into an XImage.
128 */
129 #define NAME flat_TRUECOLOR_line
130 #define SETUP_CODE \
131 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
132 GET_XRB(xrb); \
133 const GLubyte *color = vert1->color; \
134 unsigned long pixel; \
135 PACK_TRUECOLOR( pixel, color[0], color[1], color[2] );
136 #define CLIP_HACK 1
137 #define PLOT(X,Y) XMesaPutPixel(xrb->ximage, X, YFLIP(xrb, Y), pixel );
138 #include "swrast/s_linetemp.h"
139
140
141
142 /*
143 * Draw a flat-shaded, PF_8A8B8G8R line into an XImage.
144 */
145 #define NAME flat_8A8B8G8R_line
146 #define SETUP_CODE \
147 GET_XRB(xrb); \
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)
153 #define CLIP_HACK 1
154 #define PLOT(X,Y) *pixelPtr = pixel;
155 #include "swrast/s_linetemp.h"
156
157
158
159 /*
160 * Draw a flat-shaded, PF_8A8R8G8B line into an XImage.
161 */
162 #define NAME flat_8A8R8G8B_line
163 #define SETUP_CODE \
164 GET_XRB(xrb); \
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)
170 #define CLIP_HACK 1
171 #define PLOT(X,Y) *pixelPtr = pixel;
172 #include "swrast/s_linetemp.h"
173
174
175
176 /*
177 * Draw a flat-shaded, PF_8R8G8B line into an XImage.
178 */
179 #define NAME flat_8R8G8B_line
180 #define SETUP_CODE \
181 GET_XRB(xrb); \
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)
187 #define CLIP_HACK 1
188 #define PLOT(X,Y) *pixelPtr = pixel;
189 #include "swrast/s_linetemp.h"
190
191
192
193 /*
194 * Draw a flat-shaded, PF_8R8G8B24 line into an XImage.
195 */
196 #define NAME flat_8R8G8B24_line
197 #define SETUP_CODE \
198 GET_XRB(xrb); \
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)
203 #define CLIP_HACK 1
204 #define PLOT(X,Y) { \
205 pixelPtr->r = color[RCOMP]; \
206 pixelPtr->g = color[GCOMP]; \
207 pixelPtr->b = color[BCOMP]; \
208 }
209 #include "swrast/s_linetemp.h"
210
211
212
213 /*
214 * Draw a flat-shaded, PF_5R6G5B line into an XImage.
215 */
216 #define NAME flat_5R6G5B_line
217 #define SETUP_CODE \
218 GET_XRB(xrb); \
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)
224 #define CLIP_HACK 1
225 #define PLOT(X,Y) *pixelPtr = pixel;
226 #include "swrast/s_linetemp.h"
227
228
229
230 /*
231 * Draw a flat-shaded, PF_DITHER_5R6G5B line into an XImage.
232 */
233 #define NAME flat_DITHER_5R6G5B_line
234 #define SETUP_CODE \
235 GET_XRB(xrb); \
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)
241 #define CLIP_HACK 1
242 #define PLOT(X,Y) PACK_TRUEDITHER( *pixelPtr, X, Y, color[0], color[1], color[2] );
243 #include "swrast/s_linetemp.h"
244
245
246
247 /*
248 * Draw a flat-shaded, Z-less, PF_TRUECOLOR line into an XImage.
249 */
250 #define NAME flat_TRUECOLOR_z_line
251 #define SETUP_CODE \
252 GET_XRB(xrb); \
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] );
257 #define INTERP_Z 1
258 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
259 #define CLIP_HACK 1
260 #define PLOT(X,Y) \
261 if (Z < *zPtr) { \
262 *zPtr = Z; \
263 XMesaPutPixel(xrb->ximage, X, YFLIP(xrb, Y), pixel); \
264 }
265 #include "swrast/s_linetemp.h"
266
267
268
269 /*
270 * Draw a flat-shaded, Z-less, PF_8A8B8G8R line into an XImage.
271 */
272 #define NAME flat_8A8B8G8R_z_line
273 #define SETUP_CODE \
274 GET_XRB(xrb); \
275 const GLubyte *color = vert1->color; \
276 GLuint pixel = PACK_8A8B8G8R(color[0], color[1], color[2], color[3]);
277 #define INTERP_Z 1
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)
282 #define CLIP_HACK 1
283 #define PLOT(X,Y) \
284 if (Z < *zPtr) { \
285 *zPtr = Z; \
286 *pixelPtr = pixel; \
287 }
288 #include "swrast/s_linetemp.h"
289
290
291
292 /*
293 * Draw a flat-shaded, Z-less, PF_8A8R8G8B line into an XImage.
294 */
295 #define NAME flat_8A8R8G8B_z_line
296 #define SETUP_CODE \
297 GET_XRB(xrb); \
298 const GLubyte *color = vert1->color; \
299 GLuint pixel = PACK_8A8R8G8B(color[0], color[1], color[2], color[3]);
300 #define INTERP_Z 1
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)
305 #define CLIP_HACK 1
306 #define PLOT(X,Y) \
307 if (Z < *zPtr) { \
308 *zPtr = Z; \
309 *pixelPtr = pixel; \
310 }
311 #include "swrast/s_linetemp.h"
312
313
314
315 /*
316 * Draw a flat-shaded, Z-less, PF_8R8G8B line into an XImage.
317 */
318 #define NAME flat_8R8G8B_z_line
319 #define SETUP_CODE \
320 GET_XRB(xrb); \
321 const GLubyte *color = vert1->color; \
322 GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] );
323 #define INTERP_Z 1
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)
328 #define CLIP_HACK 1
329 #define PLOT(X,Y) \
330 if (Z < *zPtr) { \
331 *zPtr = Z; \
332 *pixelPtr = pixel; \
333 }
334 #include "swrast/s_linetemp.h"
335
336
337
338 /*
339 * Draw a flat-shaded, Z-less, PF_8R8G8B24 line into an XImage.
340 */
341 #define NAME flat_8R8G8B24_z_line
342 #define SETUP_CODE \
343 GET_XRB(xrb); \
344 const GLubyte *color = vert1->color;
345 #define INTERP_Z 1
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)
350 #define CLIP_HACK 1
351 #define PLOT(X,Y) \
352 if (Z < *zPtr) { \
353 *zPtr = Z; \
354 pixelPtr->r = color[RCOMP]; \
355 pixelPtr->g = color[GCOMP]; \
356 pixelPtr->b = color[BCOMP]; \
357 }
358 #include "swrast/s_linetemp.h"
359
360
361
362 /*
363 * Draw a flat-shaded, Z-less, PF_5R6G5B line into an XImage.
364 */
365 #define NAME flat_5R6G5B_z_line
366 #define SETUP_CODE \
367 GET_XRB(xrb); \
368 const GLubyte *color = vert1->color; \
369 GLushort pixel = PACK_5R6G5B( color[0], color[1], color[2] );
370 #define INTERP_Z 1
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)
375 #define CLIP_HACK 1
376 #define PLOT(X,Y) \
377 if (Z < *zPtr) { \
378 *zPtr = Z; \
379 *pixelPtr = pixel; \
380 }
381 #include "swrast/s_linetemp.h"
382
383
384
385 /*
386 * Draw a flat-shaded, Z-less, PF_DITHER_5R6G5B line into an XImage.
387 */
388 #define NAME flat_DITHER_5R6G5B_z_line
389 #define SETUP_CODE \
390 GET_XRB(xrb); \
391 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
392 const GLubyte *color = vert1->color;
393 #define INTERP_Z 1
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)
398 #define CLIP_HACK 1
399 #define PLOT(X,Y) \
400 if (Z < *zPtr) { \
401 *zPtr = Z; \
402 PACK_TRUEDITHER(*pixelPtr, X, Y, color[0], color[1], color[2]); \
403 }
404 #include "swrast/s_linetemp.h"
405
406
407
408 /**
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.
414 */
415 static void
xor_line(struct gl_context * ctx,const SWvertex * vert0,const SWvertex * vert1)416 xor_line(struct gl_context *ctx, const SWvertex *vert0, const SWvertex *vert1)
417 {
418 XMesaContext xmesa = XMESA_CONTEXT(ctx);
419 XMesaDisplay *dpy = xmesa->xm_visual->display;
420 XMesaGC gc = xmesa->xm_buffer->gc;
421 GET_XRB(xrb);
422 unsigned long pixel = xmesa_color_to_pixel(ctx,
423 vert1->color[0], vert1->color[1],
424 vert1->color[2], vert1->color[3],
425 xmesa->pixelformat);
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 */
436 }
437
438
439 #endif /* CHAN_BITS == 8 */
440
441
442 /**
443 * Return pointer to line drawing function, or NULL if we should use a
444 * swrast fallback.
445 */
446 static swrast_line_func
get_line_func(struct gl_context * ctx)447 get_line_func(struct gl_context *ctx)
448 {
449 #if CHAN_BITS == 8
450 SWcontext *swrast = SWRAST_CONTEXT(ctx);
451 XMesaContext xmesa = XMESA_CONTEXT(ctx);
452 const struct xmesa_renderbuffer *xrb;
453
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;
463
464 xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
465
466 if (xrb->ximage
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) {
473 case PF_Truecolor:
474 return flat_TRUECOLOR_z_line;
475 case PF_8A8B8G8R:
476 return flat_8A8B8G8R_z_line;
477 case PF_8A8R8G8B:
478 return flat_8A8R8G8B_z_line;
479 case PF_8R8G8B:
480 return flat_8R8G8B_z_line;
481 case PF_8R8G8B24:
482 return flat_8R8G8B24_z_line;
483 case PF_5R6G5B:
484 return flat_5R6G5B_z_line;
485 case PF_Dither_5R6G5B:
486 return flat_DITHER_5R6G5B_z_line;
487 default:
488 return (swrast_line_func)NULL;
489 }
490 }
491 if (xrb->ximage
492 && swrast->_RasterMask==0
493 && ctx->Line.Width==1.0F) {
494 switch (xmesa->pixelformat) {
495 case PF_Truecolor:
496 return flat_TRUECOLOR_line;
497 case PF_8A8B8G8R:
498 return flat_8A8B8G8R_line;
499 case PF_8A8R8G8B:
500 return flat_8A8R8G8B_line;
501 case PF_8R8G8B:
502 return flat_8R8G8B_line;
503 case PF_8R8G8B24:
504 return flat_8R8G8B24_line;
505 case PF_5R6G5B:
506 return flat_5R6G5B_line;
507 case PF_Dither_5R6G5B:
508 return flat_DITHER_5R6G5B_line;
509 default:
510 return (swrast_line_func)NULL;
511 }
512 }
513
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) {
520 return xor_line;
521 }
522
523 #endif /* CHAN_BITS == 8 */
524 return (swrast_line_func) NULL;
525 }
526
527
528 /**
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.
532 */
533 void
xmesa_choose_line(struct gl_context * ctx)534 xmesa_choose_line(struct gl_context *ctx)
535 {
536 SWcontext *swrast = SWRAST_CONTEXT(ctx);
537
538 if (!(swrast->Line = get_line_func( ctx )))
539 _swrast_choose_line( ctx );
540 }
541