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