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" triangle functions. It should be
28 * fairly easy to write new special-purpose triangle functions and hook
29 * them into this module.
30 */
31
32
33 #include <stdio.h>
34 #include "c99_math.h"
35 #include "main/mtypes.h"
36 #include "glxheader.h"
37 #include "xmesaP.h"
38
39 /* Internal swrast includes:
40 */
41 #include "swrast/s_context.h"
42 #include "swrast/s_depth.h"
43 #include "swrast/s_triangle.h"
44
45
46 #define GET_XRB(XRB) struct xmesa_renderbuffer *XRB = \
47 xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0])
48
49
50 /**********************************************************************/
51 /*** Triangle rendering ***/
52 /**********************************************************************/
53
54
55 #if CHAN_BITS == 8
56
57 /*
58 * XImage, smooth, depth-buffered, PF_TRUECOLOR triangle.
59 */
60 #define NAME smooth_TRUECOLOR_z_triangle
61 #define INTERP_Z 1
62 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
63 #define INTERP_RGB 1
64 #define SETUP_CODE \
65 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
66 GET_XRB(xrb);
67
68 #define RENDER_SPAN( span ) { \
69 GLint x = span.x, y = YFLIP(xrb, span.y); \
70 GLuint i; \
71 for (i = 0; i < span.end; i++, x++) { \
72 const DEPTH_TYPE z = FixedToDepth(span.z); \
73 if (z < zRow[i]) { \
74 unsigned long p; \
75 PACK_TRUECOLOR(p, FixedToInt(span.red), \
76 FixedToInt(span.green), FixedToInt(span.blue)); \
77 XMesaPutPixel(xrb->ximage, x, y, p); \
78 zRow[i] = z; \
79 } \
80 span.red += span.redStep; \
81 span.green += span.greenStep; \
82 span.blue += span.blueStep; \
83 span.z += span.zStep; \
84 } }
85
86 #include "swrast/s_tritemp.h"
87
88
89
90
91 /*
92 * XImage, smooth, depth-buffered, PF_8A8B8G8R triangle.
93 */
94 #define NAME smooth_8A8B8G8R_z_triangle
95 #define INTERP_Z 1
96 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
97 #define INTERP_RGB 1
98 #define INTERP_ALPHA 1
99 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
100 #define PIXEL_TYPE GLuint
101 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
102 #define SETUP_CODE \
103 GET_XRB(xrb);
104 #define RENDER_SPAN( span ) { \
105 GLuint i; \
106 for (i = 0; i < span.end; i++) { \
107 const DEPTH_TYPE z = FixedToDepth(span.z); \
108 if (z < zRow[i]) { \
109 pRow[i] = PACK_8A8B8G8R(FixedToInt(span.red), \
110 FixedToInt(span.green), FixedToInt(span.blue), \
111 FixedToInt(span.alpha)); \
112 zRow[i] = z; \
113 } \
114 span.red += span.redStep; \
115 span.green += span.greenStep; \
116 span.blue += span.blueStep; \
117 span.alpha += span.alphaStep; \
118 span.z += span.zStep; \
119 } }
120
121 #include "swrast/s_tritemp.h"
122
123
124
125 /*
126 * XImage, smooth, depth-buffered, PF_8A8R8G8B triangle.
127 */
128 #define NAME smooth_8A8R8G8B_z_triangle
129 #define INTERP_Z 1
130 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
131 #define INTERP_RGB 1
132 #define INTERP_ALPHA 1
133 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
134 #define PIXEL_TYPE GLuint
135 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
136 #define SETUP_CODE \
137 GET_XRB(xrb);
138
139 #define RENDER_SPAN( span ) { \
140 GLuint i; \
141 for (i = 0; i < span.end; i++) { \
142 const DEPTH_TYPE z = FixedToDepth(span.z); \
143 if (z < zRow[i]) { \
144 pRow[i] = PACK_8A8R8G8B(FixedToInt(span.red), \
145 FixedToInt(span.green), FixedToInt(span.blue), \
146 FixedToInt(span.alpha)); \
147 zRow[i] = z; \
148 } \
149 span.red += span.redStep; \
150 span.green += span.greenStep; \
151 span.blue += span.blueStep; \
152 span.alpha += span.alphaStep; \
153 span.z += span.zStep; \
154 } }
155
156 #include "swrast/s_tritemp.h"
157
158
159
160 /*
161 * XImage, smooth, depth-buffered, PF_8R8G8B triangle.
162 */
163 #define NAME smooth_8R8G8B_z_triangle
164 #define INTERP_Z 1
165 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
166 #define INTERP_RGB 1
167 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
168 #define PIXEL_TYPE GLuint
169 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
170 #define SETUP_CODE \
171 GET_XRB(xrb);
172
173 #define RENDER_SPAN( span ) { \
174 GLuint i; \
175 for (i = 0; i < span.end; i++) { \
176 const DEPTH_TYPE z = FixedToDepth(span.z); \
177 if (z < zRow[i]) { \
178 pRow[i] = PACK_8R8G8B(FixedToInt(span.red), \
179 FixedToInt(span.green), FixedToInt(span.blue)); \
180 zRow[i] = z; \
181 } \
182 span.red += span.redStep; \
183 span.green += span.greenStep; \
184 span.blue += span.blueStep; \
185 span.z += span.zStep; \
186 } }
187
188 #include "swrast/s_tritemp.h"
189
190
191
192 /*
193 * XImage, smooth, depth-buffered, PF_8R8G8B24 triangle.
194 */
195 #define NAME smooth_8R8G8B24_z_triangle
196 #define INTERP_Z 1
197 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
198 #define INTERP_RGB 1
199 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X, Y)
200 #define PIXEL_TYPE bgr_t
201 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
202 #define SETUP_CODE \
203 GET_XRB(xrb);
204 #define RENDER_SPAN( span ) { \
205 GLuint i; \
206 for (i = 0; i < span.end; i++) { \
207 const DEPTH_TYPE z = FixedToDepth(span.z); \
208 if (z < zRow[i]) { \
209 PIXEL_TYPE *ptr = pRow + i; \
210 ptr->r = FixedToInt(span.red); \
211 ptr->g = FixedToInt(span.green); \
212 ptr->b = FixedToInt(span.blue); \
213 zRow[i] = z; \
214 } \
215 span.red += span.redStep; \
216 span.green += span.greenStep; \
217 span.blue += span.blueStep; \
218 span.z += span.zStep; \
219 } }
220 #include "swrast/s_tritemp.h"
221
222
223
224 /*
225 * XImage, smooth, depth-buffered, PF_TRUEDITHER triangle.
226 */
227 #define NAME smooth_TRUEDITHER_z_triangle
228 #define INTERP_Z 1
229 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
230 #define INTERP_RGB 1
231 #define SETUP_CODE \
232 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
233 GET_XRB(xrb);
234 #define RENDER_SPAN( span ) { \
235 GLuint i; \
236 GLint x = span.x, y = YFLIP(xrb, span.y); \
237 for (i = 0; i < span.end; i++, x++) { \
238 const DEPTH_TYPE z = FixedToDepth(span.z); \
239 if (z < zRow[i]) { \
240 unsigned long p; \
241 PACK_TRUEDITHER(p, x, y, FixedToInt(span.red), \
242 FixedToInt(span.green), FixedToInt(span.blue)); \
243 XMesaPutPixel(xrb->ximage, x, y, p); \
244 zRow[i] = z; \
245 } \
246 span.red += span.redStep; \
247 span.green += span.greenStep; \
248 span.blue += span.blueStep; \
249 span.z += span.zStep; \
250 } }
251 #include "swrast/s_tritemp.h"
252
253
254
255 /*
256 * XImage, smooth, depth-buffered, PF_5R6G5B triangle.
257 */
258 #define NAME smooth_5R6G5B_z_triangle
259 #define INTERP_Z 1
260 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
261 #define INTERP_RGB 1
262 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y)
263 #define PIXEL_TYPE GLushort
264 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
265 #define SETUP_CODE \
266 GET_XRB(xrb);
267 #define RENDER_SPAN( span ) { \
268 GLuint i; \
269 for (i = 0; i < span.end; i++) { \
270 const DEPTH_TYPE z = FixedToDepth(span.z); \
271 if (z < zRow[i]) { \
272 pRow[i] = PACK_5R6G5B(FixedToInt(span.red), \
273 FixedToInt(span.green), FixedToInt(span.blue)); \
274 zRow[i] = z; \
275 } \
276 span.red += span.redStep; \
277 span.green += span.greenStep; \
278 span.blue += span.blueStep; \
279 span.z += span.zStep; \
280 } }
281 #include "swrast/s_tritemp.h"
282
283
284
285 /*
286 * XImage, smooth, depth-buffered, PF_DITHER_5R6G5B triangle.
287 */
288 #define NAME smooth_DITHER_5R6G5B_z_triangle
289 #define INTERP_Z 1
290 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
291 #define INTERP_RGB 1
292 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y)
293 #define PIXEL_TYPE GLushort
294 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
295 #define SETUP_CODE \
296 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
297 GET_XRB(xrb);
298 #define RENDER_SPAN( span ) { \
299 GLuint i; \
300 GLint x = span.x, y = YFLIP(xrb, span.y); \
301 for (i = 0; i < span.end; i++, x++) { \
302 const DEPTH_TYPE z = FixedToDepth(span.z); \
303 if (z < zRow[i]) { \
304 PACK_TRUEDITHER(pRow[i], x, y, FixedToInt(span.red), \
305 FixedToInt(span.green), FixedToInt(span.blue)); \
306 zRow[i] = z; \
307 } \
308 span.red += span.redStep; \
309 span.green += span.greenStep; \
310 span.blue += span.blueStep; \
311 span.z += span.zStep; \
312 } }
313 #include "swrast/s_tritemp.h"
314
315
316
317 /*
318 * XImage, flat, depth-buffered, PF_TRUECOLOR triangle.
319 */
320 #define NAME flat_TRUECOLOR_z_triangle
321 #define INTERP_Z 1
322 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
323 #define SETUP_CODE \
324 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
325 GET_XRB(xrb); \
326 XMesaImage *img = xrb->ximage; \
327 unsigned long pixel; \
328 PACK_TRUECOLOR(pixel, v2->color[0], v2->color[1], v2->color[2]);
329 #define RENDER_SPAN( span ) { \
330 GLuint i; \
331 GLint x = span.x, y = YFLIP(xrb, span.y); \
332 for (i = 0; i < span.end; i++, x++) { \
333 const DEPTH_TYPE z = FixedToDepth(span.z); \
334 if (z < zRow[i]) { \
335 XMesaPutPixel(img, x, y, pixel); \
336 zRow[i] = z; \
337 } \
338 span.z += span.zStep; \
339 } }
340 #include "swrast/s_tritemp.h"
341
342
343
344 /*
345 * XImage, flat, depth-buffered, PF_8A8B8G8R triangle.
346 */
347 #define NAME flat_8A8B8G8R_z_triangle
348 #define INTERP_Z 1
349 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
350 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
351 #define PIXEL_TYPE GLuint
352 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
353 #define SETUP_CODE \
354 GET_XRB(xrb); \
355 GLuint p = PACK_8A8B8G8R( v2->color[0], v2->color[1],\
356 v2->color[2], v2->color[3]);
357 #define RENDER_SPAN( span ) { \
358 GLuint i; \
359 for (i = 0; i < span.end; i++) { \
360 const DEPTH_TYPE z = FixedToDepth(span.z); \
361 if (z < zRow[i]) { \
362 pRow[i] = (PIXEL_TYPE) p; \
363 zRow[i] = z; \
364 } \
365 span.z += span.zStep; \
366 } }
367 #include "swrast/s_tritemp.h"
368
369
370
371 /*
372 * XImage, flat, depth-buffered, PF_8A8R8G8B triangle.
373 */
374 #define NAME flat_8A8R8G8B_z_triangle
375 #define INTERP_Z 1
376 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
377 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
378 #define PIXEL_TYPE GLuint
379 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
380 #define SETUP_CODE \
381 GET_XRB(xrb); \
382 GLuint p = PACK_8A8R8G8B(v2->color[0], v2->color[1], \
383 v2->color[2], v2->color[3]);
384 #define RENDER_SPAN( span ) { \
385 GLuint i; \
386 for (i = 0; i < span.end; i++) { \
387 const DEPTH_TYPE z = FixedToDepth(span.z); \
388 if (z < zRow[i]) { \
389 pRow[i] = (PIXEL_TYPE) p; \
390 zRow[i] = z; \
391 } \
392 span.z += span.zStep; \
393 } }
394 #include "swrast/s_tritemp.h"
395
396
397
398 /*
399 * XImage, flat, depth-buffered, PF_8R8G8B triangle.
400 */
401 #define NAME flat_8R8G8B_z_triangle
402 #define INTERP_Z 1
403 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
404 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
405 #define PIXEL_TYPE GLuint
406 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
407 #define SETUP_CODE \
408 GET_XRB(xrb); \
409 GLuint p = PACK_8R8G8B( v2->color[0], v2->color[1], v2->color[2] );
410 #define RENDER_SPAN( span ) { \
411 GLuint i; \
412 for (i = 0; i < span.end; i++) { \
413 DEPTH_TYPE z = FixedToDepth(span.z); \
414 if (z < zRow[i]) { \
415 pRow[i] = (PIXEL_TYPE) p; \
416 zRow[i] = z; \
417 } \
418 span.z += span.zStep; \
419 } }
420
421 #include "swrast/s_tritemp.h"
422
423
424
425 /*
426 * XImage, flat, depth-buffered, PF_8R8G8B24 triangle.
427 */
428 #define NAME flat_8R8G8B24_z_triangle
429 #define INTERP_Z 1
430 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
431 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X, Y)
432 #define PIXEL_TYPE bgr_t
433 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
434 #define SETUP_CODE \
435 GET_XRB(xrb); \
436 const GLubyte *color = v2->color;
437 #define RENDER_SPAN( span ) { \
438 GLuint i; \
439 for (i = 0; i < span.end; i++) { \
440 const DEPTH_TYPE z = FixedToDepth(span.z); \
441 if (z < zRow[i]) { \
442 PIXEL_TYPE *ptr = pRow + i; \
443 ptr->r = color[RCOMP]; \
444 ptr->g = color[GCOMP]; \
445 ptr->b = color[BCOMP]; \
446 zRow[i] = z; \
447 } \
448 span.z += span.zStep; \
449 } }
450 #include "swrast/s_tritemp.h"
451
452
453
454 /*
455 * XImage, flat, depth-buffered, PF_TRUEDITHER triangle.
456 */
457 #define NAME flat_TRUEDITHER_z_triangle
458 #define INTERP_Z 1
459 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
460 #define SETUP_CODE \
461 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
462 GET_XRB(xrb); \
463 XMesaImage *img = xrb->ximage;
464 #define RENDER_SPAN( span ) { \
465 GLuint i; \
466 GLint x = span.x, y = YFLIP(xrb, span.y); \
467 for (i = 0; i < span.end; i++, x++) { \
468 const DEPTH_TYPE z = FixedToDepth(span.z); \
469 if (z < zRow[i]) { \
470 unsigned long p; \
471 PACK_TRUEDITHER(p, x, y, v2->color[0], \
472 v2->color[1], v2->color[2]); \
473 XMesaPutPixel(img, x, y, p); \
474 zRow[i] = z; \
475 } \
476 span.z += span.zStep; \
477 } }
478 #include "swrast/s_tritemp.h"
479
480
481
482 /*
483 * XImage, flat, depth-buffered, PF_5R6G5B triangle.
484 */
485 #define NAME flat_5R6G5B_z_triangle
486 #define INTERP_Z 1
487 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
488 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y)
489 #define PIXEL_TYPE GLushort
490 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
491 #define SETUP_CODE \
492 GET_XRB(xrb); \
493 GLushort p = PACK_5R6G5B( v2->color[0], v2->color[1], v2->color[2] );
494 #define RENDER_SPAN( span ) { \
495 GLuint i; \
496 for (i = 0; i < span.end; i++) { \
497 const DEPTH_TYPE z = FixedToDepth(span.z); \
498 if (z < zRow[i]) { \
499 pRow[i] = (PIXEL_TYPE) p; \
500 zRow[i] = z; \
501 } \
502 span.z += span.zStep; \
503 } }
504 #include "swrast/s_tritemp.h"
505
506
507
508 /*
509 * XImage, flat, depth-buffered, PF_DITHER_5R6G5B triangle.
510 */
511 #define NAME flat_DITHER_5R6G5B_z_triangle
512 #define INTERP_Z 1
513 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
514 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y)
515 #define PIXEL_TYPE GLushort
516 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
517 #define SETUP_CODE \
518 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
519 GET_XRB(xrb); \
520 const GLubyte *color = v2->color;
521 #define RENDER_SPAN( span ) { \
522 GLuint i; \
523 GLint x = span.x, y = YFLIP(xrb, span.y); \
524 for (i = 0; i < span.end; i++, x++) { \
525 const DEPTH_TYPE z = FixedToDepth(span.z); \
526 if (z < zRow[i]) { \
527 PACK_TRUEDITHER(pRow[i], x, y, color[RCOMP], \
528 color[GCOMP], color[BCOMP]); \
529 zRow[i] = z; \
530 } \
531 span.z += span.zStep; \
532 } }
533 #include "swrast/s_tritemp.h"
534
535
536 /*
537 * XImage, smooth, NON-depth-buffered, PF_TRUECOLOR triangle.
538 */
539 #define NAME smooth_TRUECOLOR_triangle
540 #define INTERP_RGB 1
541 #define SETUP_CODE \
542 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
543 GET_XRB(xrb); \
544 XMesaImage *img = xrb->ximage;
545 #define RENDER_SPAN( span ) { \
546 GLuint i; \
547 GLint x = span.x, y = YFLIP(xrb, span.y); \
548 for (i = 0; i < span.end; i++, x++) { \
549 unsigned long p; \
550 PACK_TRUECOLOR(p, FixedToInt(span.red), \
551 FixedToInt(span.green), FixedToInt(span.blue)); \
552 XMesaPutPixel(img, x, y, p); \
553 span.red += span.redStep; \
554 span.green += span.greenStep; \
555 span.blue += span.blueStep; \
556 } }
557 #include "swrast/s_tritemp.h"
558
559
560
561 /*
562 * XImage, smooth, NON-depth-buffered, PF_8A8B8G8R triangle.
563 */
564 #define NAME smooth_8A8B8G8R_triangle
565 #define INTERP_RGB 1
566 #define INTERP_ALPHA 1
567 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
568 #define PIXEL_TYPE GLuint
569 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
570 #define SETUP_CODE \
571 GET_XRB(xrb);
572 #define RENDER_SPAN( span ) { \
573 GLuint i; \
574 for (i = 0; i < span.end; i++) { \
575 pRow[i] = PACK_8A8B8G8R(FixedToInt(span.red), \
576 FixedToInt(span.green), FixedToInt(span.blue), \
577 FixedToInt(span.alpha)); \
578 span.red += span.redStep; \
579 span.green += span.greenStep; \
580 span.blue += span.blueStep; \
581 span.alpha += span.alphaStep; \
582 } }
583 #include "swrast/s_tritemp.h"
584
585
586
587 /*
588 * XImage, smooth, NON-depth-buffered, PF_8A8R8G8B triangle.
589 */
590 #define NAME smooth_8A8R8G8B_triangle
591 #define INTERP_RGB 1
592 #define INTERP_ALPHA 1
593 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
594 #define PIXEL_TYPE GLuint
595 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
596 #define SETUP_CODE \
597 GET_XRB(xrb);
598 #define RENDER_SPAN( span ) { \
599 GLuint i; \
600 for (i = 0; i < span.end; i++) { \
601 pRow[i] = PACK_8A8R8G8B(FixedToInt(span.red), \
602 FixedToInt(span.green), FixedToInt(span.blue), \
603 FixedToInt(span.alpha)); \
604 span.red += span.redStep; \
605 span.green += span.greenStep; \
606 span.blue += span.blueStep; \
607 span.alpha += span.alphaStep; \
608 } }
609 #include "swrast/s_tritemp.h"
610
611
612
613 /*
614 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
615 */
616 #define NAME smooth_8R8G8B_triangle
617 #define INTERP_RGB 1
618 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
619 #define PIXEL_TYPE GLuint
620 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
621 #define SETUP_CODE \
622 GET_XRB(xrb);
623 #define RENDER_SPAN( span ) { \
624 GLuint i; \
625 for (i = 0; i < span.end; i++) { \
626 pRow[i] = PACK_8R8G8B(FixedToInt(span.red), \
627 FixedToInt(span.green), FixedToInt(span.blue) ); \
628 span.red += span.redStep; \
629 span.green += span.greenStep; \
630 span.blue += span.blueStep; \
631 } }
632 #include "swrast/s_tritemp.h"
633
634
635
636 /*
637 * XImage, smooth, NON-depth-buffered, PF_8R8G8B triangle.
638 */
639 #define NAME smooth_8R8G8B24_triangle
640 #define INTERP_RGB 1
641 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X, Y)
642 #define PIXEL_TYPE bgr_t
643 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
644 #define SETUP_CODE \
645 GET_XRB(xrb);
646 #define RENDER_SPAN( span ) { \
647 GLuint i; \
648 PIXEL_TYPE *pixel = pRow; \
649 for (i = 0; i < span.end; i++, pixel++) { \
650 pixel->r = FixedToInt(span.red); \
651 pixel->g = FixedToInt(span.green); \
652 pixel->b = FixedToInt(span.blue); \
653 span.red += span.redStep; \
654 span.green += span.greenStep; \
655 span.blue += span.blueStep; \
656 } }
657 #include "swrast/s_tritemp.h"
658
659
660
661 /*
662 * XImage, smooth, NON-depth-buffered, PF_TRUEDITHER triangle.
663 */
664 #define NAME smooth_TRUEDITHER_triangle
665 #define INTERP_RGB 1
666 #define SETUP_CODE \
667 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
668 GET_XRB(xrb); \
669 XMesaImage *img = xrb->ximage;
670 #define RENDER_SPAN( span ) { \
671 GLuint i; \
672 GLint x = span.x, y = YFLIP(xrb, span.y); \
673 for (i = 0; i < span.end; i++, x++) { \
674 unsigned long p; \
675 PACK_TRUEDITHER(p, x, y, FixedToInt(span.red), \
676 FixedToInt(span.green), FixedToInt(span.blue)); \
677 XMesaPutPixel(img, x, y, p ); \
678 span.red += span.redStep; \
679 span.green += span.greenStep; \
680 span.blue += span.blueStep; \
681 } }
682 #include "swrast/s_tritemp.h"
683
684
685
686 /*
687 * XImage, smooth, NON-depth-buffered, PF_5R6G5B triangle.
688 */
689 #define NAME smooth_5R6G5B_triangle
690 #define INTERP_RGB 1
691 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y)
692 #define PIXEL_TYPE GLushort
693 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
694 #define SETUP_CODE \
695 GET_XRB(xrb);
696 #define RENDER_SPAN( span ) { \
697 GLuint i; \
698 for (i = 0; i < span.end; i++) { \
699 pRow[i] = (PIXEL_TYPE) PACK_5R6G5B(FixedToInt(span.red), \
700 FixedToInt(span.green), FixedToInt(span.blue)); \
701 span.red += span.redStep; \
702 span.green += span.greenStep; \
703 span.blue += span.blueStep; \
704 } }
705 #include "swrast/s_tritemp.h"
706
707
708
709 /*
710 * XImage, smooth, NON-depth-buffered, PF_DITHER_5R6G5B triangle.
711 */
712 #define NAME smooth_DITHER_5R6G5B_triangle
713 #define INTERP_RGB 1
714 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y)
715 #define PIXEL_TYPE GLushort
716 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
717 #define SETUP_CODE \
718 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
719 GET_XRB(xrb);
720 #define RENDER_SPAN( span ) { \
721 GLuint i; \
722 GLint x = span.x, y = YFLIP(xrb, span.y); \
723 for (i = 0; i < span.end; i++, x++) { \
724 PACK_TRUEDITHER(pRow[i], x, y, FixedToInt(span.red), \
725 FixedToInt(span.green), FixedToInt(span.blue)); \
726 span.red += span.redStep; \
727 span.green += span.greenStep; \
728 span.blue += span.blueStep; \
729 } }
730 #include "swrast/s_tritemp.h"
731
732
733
734 /*
735 * XImage, flat, NON-depth-buffered, PF_TRUECOLOR triangle.
736 */
737 #define NAME flat_TRUECOLOR_triangle
738 #define SETUP_CODE \
739 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
740 GET_XRB(xrb); \
741 XMesaImage *img = xrb->ximage; \
742 unsigned long pixel; \
743 PACK_TRUECOLOR(pixel, v2->color[0], v2->color[1], v2->color[2]);
744 #define RENDER_SPAN( span ) { \
745 GLuint i; \
746 GLint x = span.x, y = YFLIP(xrb, span.y); \
747 for (i = 0; i < span.end; i++, x++) { \
748 XMesaPutPixel(img, x, y, pixel); \
749 } }
750 #include "swrast/s_tritemp.h"
751
752
753
754 /*
755 * XImage, flat, NON-depth-buffered, PF_8A8B8G8R triangle.
756 */
757 #define NAME flat_8A8B8G8R_triangle
758 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
759 #define PIXEL_TYPE GLuint
760 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
761 #define SETUP_CODE \
762 GET_XRB(xrb); \
763 unsigned long p = PACK_8B8G8R( v2->color[0], \
764 v2->color[1], v2->color[2] );
765 #define RENDER_SPAN( span ) { \
766 GLuint i; \
767 for (i = 0; i < span.end; i++) { \
768 pRow[i] = (PIXEL_TYPE) p; \
769 } }
770 #include "swrast/s_tritemp.h"
771
772
773
774 /*
775 * XImage, flat, NON-depth-buffered, PF_8A8R8G8B triangle.
776 */
777 #define NAME flat_8A8R8G8B_triangle
778 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
779 #define PIXEL_TYPE GLuint
780 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
781 #define SETUP_CODE \
782 GET_XRB(xrb); \
783 unsigned long p = PACK_8R8G8B( v2->color[0], \
784 v2->color[1], v2->color[2] );
785 #define RENDER_SPAN( span ) { \
786 GLuint i; \
787 for (i = 0; i < span.end; i++) { \
788 pRow[i] = (PIXEL_TYPE) p; \
789 } }
790 #include "swrast/s_tritemp.h"
791
792
793
794 /*
795 * XImage, flat, NON-depth-buffered, PF_8R8G8B triangle.
796 */
797 #define NAME flat_8R8G8B_triangle
798 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR4(xrb, X, Y)
799 #define PIXEL_TYPE GLuint
800 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
801 #define SETUP_CODE \
802 GET_XRB(xrb); \
803 unsigned long p = PACK_8R8G8B( v2->color[0], \
804 v2->color[1], v2->color[2] );
805 #define RENDER_SPAN( span ) { \
806 GLuint i; \
807 for (i = 0; i < span.end; i++) { \
808 pRow[i] = (PIXEL_TYPE) p; \
809 } }
810 #include "swrast/s_tritemp.h"
811
812
813
814 /*
815 * XImage, flat, NON-depth-buffered, PF_8R8G8B24 triangle.
816 */
817 #define NAME flat_8R8G8B24_triangle
818 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR3(xrb, X, Y)
819 #define PIXEL_TYPE bgr_t
820 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
821 #define SETUP_CODE \
822 GET_XRB(xrb); \
823 const GLubyte *color = v2->color;
824 #define RENDER_SPAN( span ) { \
825 GLuint i; \
826 PIXEL_TYPE *pixel = pRow; \
827 for (i = 0; i < span.end; i++, pixel++) { \
828 pixel->r = color[RCOMP]; \
829 pixel->g = color[GCOMP]; \
830 pixel->b = color[BCOMP]; \
831 } }
832 #include "swrast/s_tritemp.h"
833
834
835
836 /*
837 * XImage, flat, NON-depth-buffered, PF_TRUEDITHER triangle.
838 */
839 #define NAME flat_TRUEDITHER_triangle
840 #define SETUP_CODE \
841 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
842 GET_XRB(xrb); \
843 XMesaImage *img = xrb->ximage;
844 #define RENDER_SPAN( span ) { \
845 GLuint i; \
846 GLint x = span.x, y = YFLIP(xrb, span.y); \
847 for (i = 0; i < span.end; i++, x++) { \
848 unsigned long p; \
849 PACK_TRUEDITHER(p, x, y, v2->color[0], \
850 v2->color[1], v2->color[2] ); \
851 XMesaPutPixel(img, x, y, p); \
852 } }
853 #include "swrast/s_tritemp.h"
854
855
856
857 /*
858 * XImage, flat, NON-depth-buffered, PF_5R6G5B triangle.
859 */
860 #define NAME flat_5R6G5B_triangle
861 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y)
862 #define PIXEL_TYPE GLushort
863 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
864 #define SETUP_CODE \
865 GET_XRB(xrb); \
866 unsigned long p = PACK_5R6G5B( v2->color[0], \
867 v2->color[1], v2->color[2] );
868 #define RENDER_SPAN( span ) { \
869 GLuint i; \
870 for (i = 0; i < span.end; i++) { \
871 pRow[i] = (PIXEL_TYPE) p; \
872 } }
873 #include "swrast/s_tritemp.h"
874
875
876
877 /*
878 * XImage, flat, NON-depth-buffered, PF_DITHER_5R6G5B triangle.
879 */
880 #define NAME flat_DITHER_5R6G5B_triangle
881 #define PIXEL_ADDRESS(X,Y) PIXEL_ADDR2(xrb, X, Y)
882 #define PIXEL_TYPE GLushort
883 #define BYTES_PER_ROW (xrb->ximage->bytes_per_line)
884 #define SETUP_CODE \
885 XMesaContext xmesa = XMESA_CONTEXT(ctx); \
886 GET_XRB(xrb); \
887 const GLubyte *color = v2->color;
888 #define RENDER_SPAN( span ) { \
889 GLuint i; \
890 GLint x = span.x, y = YFLIP(xrb, span.y); \
891 for (i = 0; i < span.end; i++, x++) { \
892 PACK_TRUEDITHER(pRow[i], x, y, color[RCOMP], \
893 color[GCOMP], color[BCOMP]); \
894 } }
895 #include "swrast/s_tritemp.h"
896
897
898
899 #endif /* CHAN_BITS == 8 */
900
901
902 #if defined(DEBUG) && CHAN_BITS == 8
903 extern void _xmesa_print_triangle_func( swrast_tri_func triFunc );
_xmesa_print_triangle_func(swrast_tri_func triFunc)904 void _xmesa_print_triangle_func( swrast_tri_func triFunc )
905 {
906 printf("XMesa tri func = ");
907 if (triFunc ==smooth_TRUECOLOR_z_triangle)
908 printf("smooth_TRUECOLOR_z_triangle\n");
909 else if (triFunc ==smooth_8A8B8G8R_z_triangle)
910 printf("smooth_8A8B8G8R_z_triangle\n");
911 else if (triFunc ==smooth_8A8R8G8B_z_triangle)
912 printf("smooth_8A8R8G8B_z_triangle\n");
913 else if (triFunc ==smooth_8R8G8B_z_triangle)
914 printf("smooth_8R8G8B_z_triangle\n");
915 else if (triFunc ==smooth_8R8G8B24_z_triangle)
916 printf("smooth_8R8G8B24_z_triangle\n");
917 else if (triFunc ==smooth_TRUEDITHER_z_triangle)
918 printf("smooth_TRUEDITHER_z_triangle\n");
919 else if (triFunc ==smooth_5R6G5B_z_triangle)
920 printf("smooth_5R6G5B_z_triangle\n");
921 else if (triFunc ==smooth_DITHER_5R6G5B_z_triangle)
922 printf("smooth_DITHER_5R6G5B_z_triangle\n");
923 else if (triFunc ==flat_TRUECOLOR_z_triangle)
924 printf("flat_TRUECOLOR_z_triangle\n");
925 else if (triFunc ==flat_8A8B8G8R_z_triangle)
926 printf("flat_8A8B8G8R_z_triangle\n");
927 else if (triFunc ==flat_8A8R8G8B_z_triangle)
928 printf("flat_8A8R8G8B_z_triangle\n");
929 else if (triFunc ==flat_8R8G8B_z_triangle)
930 printf("flat_8R8G8B_z_triangle\n");
931 else if (triFunc ==flat_8R8G8B24_z_triangle)
932 printf("flat_8R8G8B24_z_triangle\n");
933 else if (triFunc ==flat_TRUEDITHER_z_triangle)
934 printf("flat_TRUEDITHER_z_triangle\n");
935 else if (triFunc ==flat_5R6G5B_z_triangle)
936 printf("flat_5R6G5B_z_triangle\n");
937 else if (triFunc ==flat_DITHER_5R6G5B_z_triangle)
938 printf("flat_DITHER_5R6G5B_z_triangle\n");
939 else if (triFunc ==smooth_TRUECOLOR_triangle)
940 printf("smooth_TRUECOLOR_triangle\n");
941 else if (triFunc ==smooth_8A8B8G8R_triangle)
942 printf("smooth_8A8B8G8R_triangle\n");
943 else if (triFunc ==smooth_8A8R8G8B_triangle)
944 printf("smooth_8A8R8G8B_triangle\n");
945 else if (triFunc ==smooth_8R8G8B_triangle)
946 printf("smooth_8R8G8B_triangle\n");
947 else if (triFunc ==smooth_8R8G8B24_triangle)
948 printf("smooth_8R8G8B24_triangle\n");
949 else if (triFunc ==smooth_TRUEDITHER_triangle)
950 printf("smooth_TRUEDITHER_triangle\n");
951 else if (triFunc ==smooth_5R6G5B_triangle)
952 printf("smooth_5R6G5B_triangle\n");
953 else if (triFunc ==smooth_DITHER_5R6G5B_triangle)
954 printf("smooth_DITHER_5R6G5B_triangle\n");
955 else if (triFunc ==flat_TRUECOLOR_triangle)
956 printf("flat_TRUECOLOR_triangle\n");
957 else if (triFunc ==flat_TRUEDITHER_triangle)
958 printf("flat_TRUEDITHER_triangle\n");
959 else if (triFunc ==flat_8A8B8G8R_triangle)
960 printf("flat_8A8B8G8R_triangle\n");
961 else if (triFunc ==flat_8A8R8G8B_triangle)
962 printf("flat_8A8R8G8B_triangle\n");
963 else if (triFunc ==flat_8R8G8B_triangle)
964 printf("flat_8R8G8B_triangle\n");
965 else if (triFunc ==flat_8R8G8B24_triangle)
966 printf("flat_8R8G8B24_triangle\n");
967 else if (triFunc ==flat_5R6G5B_triangle)
968 printf("flat_5R6G5B_triangle\n");
969 else if (triFunc ==flat_DITHER_5R6G5B_triangle)
970 printf("flat_DITHER_5R6G5B_triangle\n");
971 else
972 printf("???\n");
973 }
974 #endif
975
976
977 #ifdef DEBUG
978
979 /* record the current triangle function name */
980 static const char *triFuncName = NULL;
981
982 #define USE(triFunc) \
983 do { \
984 triFuncName = #triFunc; \
985 return triFunc; \
986 } while (0)
987
988 #else
989
990 #define USE(triFunc) return triFunc
991
992 #endif
993
994
995 /**
996 * Return pointer to line drawing function, or NULL if we should use a
997 * swrast fallback.
998 */
999 static swrast_tri_func
get_triangle_func(struct gl_context * ctx)1000 get_triangle_func(struct gl_context *ctx)
1001 {
1002 #if CHAN_BITS == 8
1003 SWcontext *swrast = SWRAST_CONTEXT(ctx);
1004 XMesaContext xmesa = XMESA_CONTEXT(ctx);
1005 const struct xmesa_renderbuffer *xrb;
1006
1007 #ifdef DEBUG
1008 triFuncName = NULL;
1009 #endif
1010
1011 /* trivial fallback tests */
1012 if ((ctx->DrawBuffer->_ColorDrawBufferIndexes[0] != BUFFER_BIT_FRONT_LEFT) &&
1013 (ctx->DrawBuffer->_ColorDrawBufferIndexes[0] != BUFFER_BIT_BACK_LEFT))
1014 return (swrast_tri_func) NULL;
1015 if (ctx->RenderMode != GL_RENDER)
1016 return (swrast_tri_func) NULL;
1017 if (ctx->Polygon.SmoothFlag)
1018 return (swrast_tri_func) NULL;
1019 if (ctx->Texture._MaxEnabledTexImageUnit != -1)
1020 return (swrast_tri_func) NULL;
1021 if (swrast->_RasterMask & MULTI_DRAW_BIT)
1022 return (swrast_tri_func) NULL;
1023 if (ctx->Polygon.CullFlag &&
1024 ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)
1025 return (swrast_tri_func) NULL;
1026
1027 xrb = xmesa_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
1028
1029 if (xrb->ximage) {
1030 if ( ctx->Light.ShadeModel==GL_SMOOTH
1031 && swrast->_RasterMask==DEPTH_BIT
1032 && ctx->Depth.Func==GL_LESS
1033 && ctx->Depth.Mask==GL_TRUE
1034 && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS
1035 && ctx->Polygon.StippleFlag==GL_FALSE) {
1036 switch (xmesa->pixelformat) {
1037 case PF_Truecolor:
1038 USE(smooth_TRUECOLOR_z_triangle);
1039 case PF_8A8B8G8R:
1040 USE(smooth_8A8B8G8R_z_triangle);
1041 case PF_8A8R8G8B:
1042 USE(smooth_8A8R8G8B_z_triangle);
1043 case PF_8R8G8B:
1044 USE(smooth_8R8G8B_z_triangle);
1045 case PF_8R8G8B24:
1046 USE(smooth_8R8G8B24_z_triangle);
1047 case PF_Dither_True:
1048 USE(smooth_TRUEDITHER_z_triangle);
1049 case PF_5R6G5B:
1050 USE(smooth_5R6G5B_z_triangle);
1051 case PF_Dither_5R6G5B:
1052 USE(smooth_DITHER_5R6G5B_z_triangle);
1053 default:
1054 return (swrast_tri_func) NULL;
1055 }
1056 }
1057 if ( ctx->Light.ShadeModel==GL_FLAT
1058 && swrast->_RasterMask==DEPTH_BIT
1059 && ctx->Depth.Func==GL_LESS
1060 && ctx->Depth.Mask==GL_TRUE
1061 && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS
1062 && ctx->Polygon.StippleFlag==GL_FALSE) {
1063 switch (xmesa->pixelformat) {
1064 case PF_Truecolor:
1065 USE(flat_TRUECOLOR_z_triangle);
1066 case PF_8A8B8G8R:
1067 USE(flat_8A8B8G8R_z_triangle);
1068 case PF_8A8R8G8B:
1069 USE(flat_8A8R8G8B_z_triangle);
1070 case PF_8R8G8B:
1071 USE(flat_8R8G8B_z_triangle);
1072 case PF_8R8G8B24:
1073 USE(flat_8R8G8B24_z_triangle);
1074 case PF_Dither_True:
1075 USE(flat_TRUEDITHER_z_triangle);
1076 case PF_5R6G5B:
1077 USE(flat_5R6G5B_z_triangle);
1078 case PF_Dither_5R6G5B:
1079 USE(flat_DITHER_5R6G5B_z_triangle);
1080 default:
1081 return (swrast_tri_func) NULL;
1082 }
1083 }
1084 if ( swrast->_RasterMask==0 /* no depth test */
1085 && ctx->Light.ShadeModel==GL_SMOOTH
1086 && ctx->Polygon.StippleFlag==GL_FALSE) {
1087 switch (xmesa->pixelformat) {
1088 case PF_Truecolor:
1089 USE(smooth_TRUECOLOR_triangle);
1090 case PF_8A8B8G8R:
1091 USE(smooth_8A8B8G8R_triangle);
1092 case PF_8A8R8G8B:
1093 USE(smooth_8A8R8G8B_triangle);
1094 case PF_8R8G8B:
1095 USE(smooth_8R8G8B_triangle);
1096 case PF_8R8G8B24:
1097 USE(smooth_8R8G8B24_triangle);
1098 case PF_Dither_True:
1099 USE(smooth_TRUEDITHER_triangle);
1100 case PF_5R6G5B:
1101 USE(smooth_5R6G5B_triangle);
1102 case PF_Dither_5R6G5B:
1103 USE(smooth_DITHER_5R6G5B_triangle);
1104 default:
1105 return (swrast_tri_func) NULL;
1106 }
1107 }
1108
1109 if ( swrast->_RasterMask==0 /* no depth test */
1110 && ctx->Light.ShadeModel==GL_FLAT
1111 && ctx->Polygon.StippleFlag==GL_FALSE) {
1112 switch (xmesa->pixelformat) {
1113 case PF_Truecolor:
1114 USE(flat_TRUECOLOR_triangle);
1115 case PF_Dither_True:
1116 USE(flat_TRUEDITHER_triangle);
1117 case PF_8A8B8G8R:
1118 USE(flat_8A8B8G8R_triangle);
1119 case PF_8A8R8G8B:
1120 USE(flat_8A8R8G8B_triangle);
1121 case PF_8R8G8B:
1122 USE(flat_8R8G8B_triangle);
1123 case PF_8R8G8B24:
1124 USE(flat_8R8G8B24_triangle);
1125 case PF_5R6G5B:
1126 USE(flat_5R6G5B_triangle);
1127 case PF_Dither_5R6G5B:
1128 USE(flat_DITHER_5R6G5B_triangle);
1129 default:
1130 return (swrast_tri_func) NULL;
1131 }
1132 }
1133 }
1134 #endif /* CHAN_BITS == 8 */
1135
1136 return (swrast_tri_func) NULL;
1137 }
1138
1139
1140 /* Override for the swrast tri-selection function. Try to use one
1141 * of our internal tri functions, otherwise fall back to the
1142 * standard swrast functions.
1143 */
xmesa_choose_triangle(struct gl_context * ctx)1144 void xmesa_choose_triangle( struct gl_context *ctx )
1145 {
1146 SWcontext *swrast = SWRAST_CONTEXT(ctx);
1147
1148 if (!(swrast->Triangle = get_triangle_func( ctx )))
1149 _swrast_choose_triangle( ctx );
1150 }
1151
1152