2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * Keith Whitwell <keith@tungstengraphics.com>
27 * Daniel Borca <dborca@users.sourceforge.net>
38 #include "nvfragprog.h"
40 #include "swrast/swrast.h"
41 #include "swrast_setup/swrast_setup.h"
42 #include "tnl/t_context.h"
43 #include "tnl/t_pipeline.h"
48 static GLboolean
fxMultipass_ColorSum (GLcontext
*ctx
, GLuint pass
);
52 * Subpixel offsets to adjust Mesa's (true) window coordinates to
53 * Glide coordinates. We need these to ensure precise rasterization.
54 * Otherwise, we'll fail a bunch of conformance tests.
56 #define TRI_X_OFFSET ( 0.0F)
57 #define TRI_Y_OFFSET ( 0.0F)
58 #define LINE_X_OFFSET ( 0.0F)
59 #define LINE_Y_OFFSET ( 0.125F)
60 #define PNT_X_OFFSET ( 0.375F)
61 #define PNT_Y_OFFSET ( 0.375F)
63 static void fxRasterPrimitive( GLcontext
*ctx
, GLenum prim
);
64 static void fxRenderPrimitive( GLcontext
*ctx
, GLenum prim
);
66 static GLenum reduced_prim
[GL_POLYGON
+1] = {
79 /***********************************************************************
80 * Macros for t_dd_tritmp.h to draw basic primitives *
81 ***********************************************************************/
83 #define TRI( a, b, c ) \
86 fxMesa->draw_tri( fxMesa, a, b, c ); \
88 grDrawTriangle( a, b, c ); \
91 #define QUAD( a, b, c, d ) \
94 fxMesa->draw_tri( fxMesa, a, b, d ); \
95 fxMesa->draw_tri( fxMesa, b, c, d ); \
102 grDrawVertexArray(GR_TRIANGLE_FAN, 4, _v_);\
103 /*grDrawTriangle( a, b, d );*/ \
104 /*grDrawTriangle( b, c, d );*/ \
108 #define LINE( v0, v1 ) \
111 fxMesa->draw_line( fxMesa, v0, v1 ); \
113 v0->x += LINE_X_OFFSET - TRI_X_OFFSET; \
114 v0->y += LINE_Y_OFFSET - TRI_Y_OFFSET; \
115 v1->x += LINE_X_OFFSET - TRI_X_OFFSET; \
116 v1->y += LINE_Y_OFFSET - TRI_Y_OFFSET; \
117 grDrawLine( v0, v1 ); \
118 v0->x -= LINE_X_OFFSET - TRI_X_OFFSET; \
119 v0->y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \
120 v1->x -= LINE_X_OFFSET - TRI_X_OFFSET; \
121 v1->y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \
125 #define POINT( v0 ) \
128 fxMesa->draw_point( fxMesa, v0 ); \
130 v0->x += PNT_X_OFFSET - TRI_X_OFFSET; \
131 v0->y += PNT_Y_OFFSET - TRI_Y_OFFSET; \
133 v0->x -= PNT_X_OFFSET - TRI_X_OFFSET; \
134 v0->y -= PNT_Y_OFFSET - TRI_Y_OFFSET; \
139 /***********************************************************************
140 * Fallback to swrast for basic primitives *
141 ***********************************************************************/
143 /* Build an SWvertex from a hardware vertex.
145 * This code is hit only when a mix of accelerated and unaccelerated
146 * primitives are being drawn, and only for the unaccelerated
150 fx_translate_vertex( GLcontext
*ctx
, const GrVertex
*src
, SWvertex
*dst
)
152 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
153 GLuint ts0
= fxMesa
->tmu_source
[0];
154 GLuint ts1
= fxMesa
->tmu_source
[1];
155 GLfloat w
= 1.0F
/ src
->oow
;
157 dst
->win
[0] = src
->x
;
158 dst
->win
[1] = src
->y
;
159 dst
->win
[2] = src
->ooz
;
160 dst
->win
[3] = src
->oow
;
163 dst
->color
[0] = src
->pargb
[2];
164 dst
->color
[1] = src
->pargb
[1];
165 dst
->color
[2] = src
->pargb
[0];
166 dst
->color
[3] = src
->pargb
[3];
168 dst
->specular
[0] = src
->pspec
[2];
169 dst
->specular
[1] = src
->pspec
[1];
170 dst
->specular
[2] = src
->pspec
[0];
171 #else /* !FX_PACKEDCOLOR */
172 dst
->color
[0] = src
->r
;
173 dst
->color
[1] = src
->g
;
174 dst
->color
[2] = src
->b
;
175 dst
->color
[3] = src
->a
;
177 dst
->specular
[0] = src
->r1
;
178 dst
->specular
[1] = src
->g1
;
179 dst
->specular
[2] = src
->g1
;
180 #endif /* !FX_PACKEDCOLOR */
182 dst
->texcoord
[ts0
][0] = fxMesa
->inv_s0scale
* src
->tmuvtx
[0].sow
* w
;
183 dst
->texcoord
[ts0
][1] = fxMesa
->inv_t0scale
* src
->tmuvtx
[0].tow
* w
;
185 if (fxMesa
->stw_hint_state
& GR_STWHINT_W_DIFF_TMU0
)
186 dst
->texcoord
[ts0
][3] = src
->tmuvtx
[0].oow
* w
;
188 dst
->texcoord
[ts0
][3] = 1.0F
;
190 if (fxMesa
->SetupIndex
& SETUP_TMU1
) {
191 dst
->texcoord
[ts1
][0] = fxMesa
->inv_s1scale
* src
->tmuvtx
[1].sow
* w
;
192 dst
->texcoord
[ts1
][1] = fxMesa
->inv_t1scale
* src
->tmuvtx
[1].tow
* w
;
194 if (fxMesa
->stw_hint_state
& GR_STWHINT_W_DIFF_TMU1
)
195 dst
->texcoord
[ts1
][3] = src
->tmuvtx
[1].oow
* w
;
197 dst
->texcoord
[ts1
][3] = 1.0F
;
200 dst
->pointSize
= src
->psize
;
205 fx_fallback_tri( fxMesaContext fxMesa
,
210 GLcontext
*ctx
= fxMesa
->glCtx
;
213 fx_translate_vertex( ctx
, v0
, &v
[0] );
214 fx_translate_vertex( ctx
, v1
, &v
[1] );
215 fx_translate_vertex( ctx
, v2
, &v
[2] );
216 _swrast_Triangle( ctx
, &v
[0], &v
[1], &v
[2] );
221 fx_fallback_line( fxMesaContext fxMesa
,
225 GLcontext
*ctx
= fxMesa
->glCtx
;
227 fx_translate_vertex( ctx
, v0
, &v
[0] );
228 fx_translate_vertex( ctx
, v1
, &v
[1] );
229 _swrast_Line( ctx
, &v
[0], &v
[1] );
234 fx_fallback_point( fxMesaContext fxMesa
,
237 GLcontext
*ctx
= fxMesa
->glCtx
;
239 fx_translate_vertex( ctx
, v0
, &v
[0] );
240 _swrast_Point( ctx
, &v
[0] );
243 /***********************************************************************
244 * Functions to draw basic primitives *
245 ***********************************************************************/
247 static void fx_print_vertex( GLcontext
*ctx
, const GrVertex
*v
)
249 fprintf(stderr
, "fx_print_vertex:\n");
251 fprintf(stderr
, "\tvertex at %p\n", (void *) v
);
253 fprintf(stderr
, "\tx %f y %f z %f oow %f\n", v
->x
, v
->y
, v
->ooz
, v
->oow
);
255 fprintf(stderr
, "\tr %d g %d b %d a %d\n", v
->pargb
[2], v
->pargb
[1], v
->pargb
[0], v
->pargb
[3]);
256 #else /* !FX_PACKEDCOLOR */
257 fprintf(stderr
, "\tr %f g %f b %f a %f\n", v
->r
, v
->g
, v
->b
, v
->a
);
258 #endif /* !FX_PACKEDCOLOR */
260 fprintf(stderr
, "\n");
263 #define DO_FALLBACK 0
265 /* Need to do clip loop at each triangle when mixing swrast and hw
266 * rendering. These functions are only used when mixed-mode rendering
269 static void fx_draw_triangle( fxMesaContext fxMesa
,
279 static void fx_draw_line( fxMesaContext fxMesa
,
283 /* No support for wide lines (avoid wide/aa line fallback).
290 static void fx_draw_point( fxMesaContext fxMesa
,
293 /* No support for wide points.
301 #define M_2PI 6.28318530717958647692528676655901
303 #define __GL_COSF cos
304 #define __GL_SINF sin
305 static void fx_draw_point_sprite ( fxMesaContext fxMesa
,
306 GrVertex
*v0
, GLfloat psize
)
308 const GLcontext
*ctx
= fxMesa
->glCtx
;
312 GLuint ts0
= fxMesa
->tmu_source
[0];
313 GLuint ts1
= fxMesa
->tmu_source
[1];
315 GLfloat u0scale
= fxMesa
->s0scale
* w
;
316 GLfloat v0scale
= fxMesa
->t0scale
* w
;
317 GLfloat u1scale
= fxMesa
->s1scale
* w
;
318 GLfloat v1scale
= fxMesa
->t1scale
* w
;
320 radius
= psize
/ 2.0F
;
326 /* point coverage? */
327 /* we don't care about culling here (see fxSetupCull) */
329 if (ctx
->Point
.SpriteOrigin
== GL_UPPER_LEFT
) {
349 if (ctx
->Point
.CoordReplace
[ts0
]) {
350 _v_
[0].tmuvtx
[0].sow
= 0;
351 _v_
[0].tmuvtx
[0].tow
= 0;
352 _v_
[1].tmuvtx
[0].sow
= u0scale
;
353 _v_
[1].tmuvtx
[0].tow
= 0;
354 _v_
[2].tmuvtx
[0].sow
= u0scale
;
355 _v_
[2].tmuvtx
[0].tow
= v0scale
;
356 _v_
[3].tmuvtx
[0].sow
= 0;
357 _v_
[3].tmuvtx
[0].tow
= v0scale
;
359 if (ctx
->Point
.CoordReplace
[ts1
]) {
360 _v_
[0].tmuvtx
[1].sow
= 0;
361 _v_
[0].tmuvtx
[1].tow
= 0;
362 _v_
[1].tmuvtx
[1].sow
= u1scale
;
363 _v_
[1].tmuvtx
[1].tow
= 0;
364 _v_
[2].tmuvtx
[1].sow
= u1scale
;
365 _v_
[2].tmuvtx
[1].tow
= v1scale
;
366 _v_
[3].tmuvtx
[1].sow
= 0;
367 _v_
[3].tmuvtx
[1].tow
= v1scale
;
370 grDrawVertexArrayContiguous(GR_TRIANGLE_FAN
, 4, _v_
, sizeof(GrVertex
));
373 static void fx_draw_point_wide ( fxMesaContext fxMesa
,
377 GLfloat ang
, radius
, oon
;
381 const GLcontext
*ctx
= fxMesa
->glCtx
;
382 const GLfloat psize
= (ctx
->_TriangleCaps
& DD_POINT_ATTEN
)
383 ? CLAMP(v0
->psize
, ctx
->Point
.MinSize
, ctx
->Point
.MaxSize
)
384 : ctx
->Point
._Size
; /* clamped */
386 if (ctx
->Point
.PointSprite
) {
387 fx_draw_point_sprite(fxMesa
, v0
, psize
);
395 radius
= psize
/ 2.0F
;
396 n
= IROUND(psize
* 2); /* radius x 4 */
398 oon
= 1.0F
/ (GLfloat
)n
;
401 /* point coverage? */
402 /* we don't care about culling here (see fxSetupCull) */
409 vtxC
.x
+= radius
* __GL_COSF(ang
);
410 vtxC
.y
+= radius
* __GL_SINF(ang
);
411 grDrawVertexArray(GR_TRIANGLE_FAN
, 3, _v_
);
412 for (i
= 2; i
<= n
; i
++) {
413 ang
= M_2PI
* i
* oon
;
414 vtxC
.x
= v0
->x
+ radius
* __GL_COSF(ang
);
415 vtxC
.y
= v0
->y
+ radius
* __GL_SINF(ang
);
416 grDrawVertexArray(GR_TRIANGLE_FAN_CONTINUE
, 1, &_v_
[2]);
420 static void fx_render_pw_verts( GLcontext
*ctx
,
425 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
426 GrVertex
*fxVB
= fxMesa
->verts
;
429 fxRenderPrimitive( ctx
, GL_POINTS
);
431 for ( ; start
< count
; start
++)
432 fx_draw_point_wide(fxMesa
, fxVB
+ start
);
435 static void fx_render_pw_elts ( GLcontext
*ctx
,
440 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
441 GrVertex
*fxVB
= fxMesa
->verts
;
442 const GLuint
* const elt
= TNL_CONTEXT(ctx
)->vb
.Elts
;
445 fxRenderPrimitive( ctx
, GL_POINTS
);
447 for ( ; start
< count
; start
++)
448 fx_draw_point_wide(fxMesa
, fxVB
+ elt
[start
]);
451 static void fx_draw_point_wide_aa ( fxMesaContext fxMesa
,
455 GLfloat ang
, radius
, oon
;
458 const GLcontext
*ctx
= fxMesa
->glCtx
;
459 const GLfloat psize
= (ctx
->_TriangleCaps
& DD_POINT_ATTEN
)
460 ? CLAMP(v0
->psize
, ctx
->Point
.MinSize
, ctx
->Point
.MaxSize
)
461 : ctx
->Point
._Size
; /* clamped */
463 if (ctx
->Point
.PointSprite
) {
464 fx_draw_point_sprite(fxMesa
, v0
, psize
);
468 radius
= psize
/ 2.0F
;
469 n
= IROUND(psize
* 2); /* radius x 4 */
471 oon
= 1.0F
/ (GLfloat
)n
;
474 /* point coverage? */
475 /* we don't care about culling here (see fxSetupCull) */
481 for (i
= 1; i
<= n
; i
++) {
482 ang
= M_2PI
* i
* oon
;
483 vtxC
.x
= v0
->x
+ radius
* __GL_COSF(ang
);
484 vtxC
.y
= v0
->y
+ radius
* __GL_SINF(ang
);
485 grAADrawTriangle( v0
, &vtxB
, &vtxC
, FXFALSE
, FXTRUE
, FXFALSE
);
486 /*grDrawTriangle( v0, &vtxB, &vtxC);*/
498 #define FX_UNFILLED_BIT 0x1
499 #define FX_OFFSET_BIT 0x2
500 #define FX_TWOSIDE_BIT 0x4
501 #define FX_FLAT_BIT 0x8
502 #define FX_TWOSTENCIL_BIT 0x10
503 #define FX_FALLBACK_BIT 0x20
504 #define FX_MAX_TRIFUNC 0x40
507 tnl_points_func points
;
509 tnl_triangle_func triangle
;
511 } rast_tab
[FX_MAX_TRIFUNC
];
513 #define DO_FALLBACK (IND & FX_FALLBACK_BIT)
514 #define DO_OFFSET (IND & FX_OFFSET_BIT)
515 #define DO_UNFILLED (IND & FX_UNFILLED_BIT)
516 #define DO_TWOSIDE (IND & FX_TWOSIDE_BIT)
517 #define DO_FLAT (IND & FX_FLAT_BIT)
518 #define DO_TWOSTENCIL (IND & FX_TWOSTENCIL_BIT)
523 #define DO_FULL_QUAD 1
527 #define HAVE_HW_FLATSHADE 0
528 #define HAVE_BACK_COLORS 0
529 #define VERTEX GrVertex
532 #define DEPTH_SCALE 1.0
533 #define UNFILLED_TRI unfilled_tri
534 #define UNFILLED_QUAD unfilled_quad
535 #define VERT_X(_v) _v->x
536 #define VERT_Y(_v) _v->y
537 #define VERT_Z(_v) _v->ooz
538 #define AREA_IS_CCW( a ) IS_NEGATIVE( a )
539 #define GET_VERTEX(e) (fxMesa->verts + e)
543 #define VERT_SET_RGBA( dst, f ) \
545 UNCLAMPED_FLOAT_TO_UBYTE(dst->pargb[2], f[0]);\
546 UNCLAMPED_FLOAT_TO_UBYTE(dst->pargb[1], f[1]);\
547 UNCLAMPED_FLOAT_TO_UBYTE(dst->pargb[0], f[2]);\
548 UNCLAMPED_FLOAT_TO_UBYTE(dst->pargb[3], f[3]);\
551 #define VERT_COPY_RGBA( v0, v1 ) \
552 *(GLuint *)&v0->pargb = *(GLuint *)&v1->pargb
554 #define VERT_SAVE_RGBA( idx ) \
555 *(GLuint *)&color[idx] = *(GLuint *)&v[idx]->pargb
557 #define VERT_RESTORE_RGBA( idx ) \
558 *(GLuint *)&v[idx]->pargb = *(GLuint *)&color[idx]
561 #define VERT_SET_SPEC( dst, f ) \
563 UNCLAMPED_FLOAT_TO_UBYTE(dst->pspec[2], f[0]);\
564 UNCLAMPED_FLOAT_TO_UBYTE(dst->pspec[1], f[1]);\
565 UNCLAMPED_FLOAT_TO_UBYTE(dst->pspec[0], f[2]);\
568 #define VERT_COPY_SPEC( v0, v1 ) \
569 *(GLuint *)&v0->pspec = *(GLuint *)&v1->pspec
571 #define VERT_SAVE_SPEC( idx ) \
572 *(GLuint *)&spec[idx] = *(GLuint *)&v[idx]->pspec
574 #define VERT_RESTORE_SPEC( idx ) \
575 *(GLuint *)&v[idx]->pspec = *(GLuint *)&spec[idx]
578 #define LOCAL_VARS(n) \
579 fxMesaContext fxMesa = FX_CONTEXT(ctx); \
580 GLubyte color[n][4], spec[n][4]; \
581 (void) color; (void) spec;
582 #else /* !FX_PACKEDCOLOR */
583 #define VERT_SET_RGBA( dst, f ) \
585 CNORM(dst->r, f[0]); \
586 CNORM(dst->g, f[1]); \
587 CNORM(dst->b, f[2]); \
588 CNORM(dst->a, f[3]); \
591 #define VERT_COPY_RGBA( v0, v1 ) \
593 COPY_FLOAT(v0->r, v1->r); \
594 COPY_FLOAT(v0->g, v1->g); \
595 COPY_FLOAT(v0->b, v1->b); \
596 COPY_FLOAT(v0->a, v1->a); \
599 #define VERT_SAVE_RGBA( idx ) \
601 COPY_FLOAT(color[idx][0], v[idx]->r); \
602 COPY_FLOAT(color[idx][1], v[idx]->g); \
603 COPY_FLOAT(color[idx][2], v[idx]->b); \
604 COPY_FLOAT(color[idx][3], v[idx]->a); \
607 #define VERT_RESTORE_RGBA( idx ) \
609 COPY_FLOAT(v[idx]->r, color[idx][0]); \
610 COPY_FLOAT(v[idx]->g, color[idx][1]); \
611 COPY_FLOAT(v[idx]->b, color[idx][2]); \
612 COPY_FLOAT(v[idx]->a, color[idx][3]); \
616 #define VERT_SET_SPEC( dst, f ) \
618 CNORM(dst->r1, f[0]); \
619 CNORM(dst->g1, f[1]); \
620 CNORM(dst->b1, f[2]); \
623 #define VERT_COPY_SPEC( v0, v1 ) \
625 COPY_FLOAT(v0->r1, v1->r1); \
626 COPY_FLOAT(v0->g1, v1->g1); \
627 COPY_FLOAT(v0->b1, v1->b1); \
630 #define VERT_SAVE_SPEC( idx ) \
632 COPY_FLOAT(spec[idx][0], v[idx]->r1); \
633 COPY_FLOAT(spec[idx][1], v[idx]->g1); \
634 COPY_FLOAT(spec[idx][2], v[idx]->b1); \
637 #define VERT_RESTORE_SPEC( idx ) \
639 COPY_FLOAT(v[idx]->r1, spec[idx][0]); \
640 COPY_FLOAT(v[idx]->g1, spec[idx][1]); \
641 COPY_FLOAT(v[idx]->b1, spec[idx][2]); \
645 #define LOCAL_VARS(n) \
646 fxMesaContext fxMesa = FX_CONTEXT(ctx); \
647 GLfloat color[n][4], spec[n][4]; \
648 (void) color; (void) spec;
649 #endif /* !FX_PACKEDCOLOR */
652 /***********************************************************************
654 ***********************************************************************/
655 #define SETUP_STENCIL(f) if (f) fxSetupStencilFace(ctx, f)
656 #define UNSET_STENCIL(f) if (f) fxSetupStencil(ctx)
659 /***********************************************************************
660 * Functions to draw basic unfilled primitives *
661 ***********************************************************************/
663 #define RASTERIZE(x) if (fxMesa->raster_primitive != reduced_prim[x]) \
664 fxRasterPrimitive( ctx, reduced_prim[x] )
665 #define RENDER_PRIMITIVE fxMesa->render_primitive
666 #define IND FX_FALLBACK_BIT
668 #include "tnl_dd/t_dd_unfilled.h"
671 /***********************************************************************
672 * Functions to draw GL primitives *
673 ***********************************************************************/
677 #include "tnl_dd/t_dd_tritmp.h"
679 #define IND (FX_OFFSET_BIT)
680 #define TAG(x) x##_offset
681 #include "tnl_dd/t_dd_tritmp.h"
683 #define IND (FX_TWOSIDE_BIT)
684 #define TAG(x) x##_twoside
685 #include "tnl_dd/t_dd_tritmp.h"
687 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT)
688 #define TAG(x) x##_twoside_offset
689 #include "tnl_dd/t_dd_tritmp.h"
691 #define IND (FX_UNFILLED_BIT)
692 #define TAG(x) x##_unfilled
693 #include "tnl_dd/t_dd_tritmp.h"
695 #define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT)
696 #define TAG(x) x##_offset_unfilled
697 #include "tnl_dd/t_dd_tritmp.h"
699 #define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT)
700 #define TAG(x) x##_twoside_unfilled
701 #include "tnl_dd/t_dd_tritmp.h"
703 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT)
704 #define TAG(x) x##_twoside_offset_unfilled
705 #include "tnl_dd/t_dd_tritmp.h"
707 #define IND (FX_FALLBACK_BIT)
708 #define TAG(x) x##_fallback
709 #include "tnl_dd/t_dd_tritmp.h"
711 #define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT)
712 #define TAG(x) x##_offset_fallback
713 #include "tnl_dd/t_dd_tritmp.h"
715 #define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT)
716 #define TAG(x) x##_twoside_fallback
717 #include "tnl_dd/t_dd_tritmp.h"
719 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT)
720 #define TAG(x) x##_twoside_offset_fallback
721 #include "tnl_dd/t_dd_tritmp.h"
723 #define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT)
724 #define TAG(x) x##_unfilled_fallback
725 #include "tnl_dd/t_dd_tritmp.h"
727 #define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT)
728 #define TAG(x) x##_offset_unfilled_fallback
729 #include "tnl_dd/t_dd_tritmp.h"
731 #define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT)
732 #define TAG(x) x##_twoside_unfilled_fallback
733 #include "tnl_dd/t_dd_tritmp.h"
735 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \
737 #define TAG(x) x##_twoside_offset_unfilled_fallback
738 #include "tnl_dd/t_dd_tritmp.h"
741 /* Fx doesn't support provoking-vertex flat-shading?
743 #define IND (FX_FLAT_BIT)
744 #define TAG(x) x##_flat
745 #include "tnl_dd/t_dd_tritmp.h"
747 #define IND (FX_OFFSET_BIT|FX_FLAT_BIT)
748 #define TAG(x) x##_offset_flat
749 #include "tnl_dd/t_dd_tritmp.h"
751 #define IND (FX_TWOSIDE_BIT|FX_FLAT_BIT)
752 #define TAG(x) x##_twoside_flat
753 #include "tnl_dd/t_dd_tritmp.h"
755 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FLAT_BIT)
756 #define TAG(x) x##_twoside_offset_flat
757 #include "tnl_dd/t_dd_tritmp.h"
759 #define IND (FX_UNFILLED_BIT|FX_FLAT_BIT)
760 #define TAG(x) x##_unfilled_flat
761 #include "tnl_dd/t_dd_tritmp.h"
763 #define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT)
764 #define TAG(x) x##_offset_unfilled_flat
765 #include "tnl_dd/t_dd_tritmp.h"
767 #define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT)
768 #define TAG(x) x##_twoside_unfilled_flat
769 #include "tnl_dd/t_dd_tritmp.h"
771 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT)
772 #define TAG(x) x##_twoside_offset_unfilled_flat
773 #include "tnl_dd/t_dd_tritmp.h"
775 #define IND (FX_FALLBACK_BIT|FX_FLAT_BIT)
776 #define TAG(x) x##_fallback_flat
777 #include "tnl_dd/t_dd_tritmp.h"
779 #define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT)
780 #define TAG(x) x##_offset_fallback_flat
781 #include "tnl_dd/t_dd_tritmp.h"
783 #define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT)
784 #define TAG(x) x##_twoside_fallback_flat
785 #include "tnl_dd/t_dd_tritmp.h"
787 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT)
788 #define TAG(x) x##_twoside_offset_fallback_flat
789 #include "tnl_dd/t_dd_tritmp.h"
791 #define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT)
792 #define TAG(x) x##_unfilled_fallback_flat
793 #include "tnl_dd/t_dd_tritmp.h"
795 #define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT)
796 #define TAG(x) x##_offset_unfilled_fallback_flat
797 #include "tnl_dd/t_dd_tritmp.h"
799 #define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT)
800 #define TAG(x) x##_twoside_unfilled_fallback_flat
801 #include "tnl_dd/t_dd_tritmp.h"
803 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \
804 FX_FALLBACK_BIT|FX_FLAT_BIT)
805 #define TAG(x) x##_twoside_offset_unfilled_fallback_flat
806 #include "tnl_dd/t_dd_tritmp.h"
809 /* 2-sided stencil begin */
810 #define IND (FX_TWOSTENCIL_BIT)
811 #define TAG(x) x##_twostencil
812 #include "tnl_dd/t_dd_tritmp.h"
814 #define IND (FX_OFFSET_BIT|FX_TWOSTENCIL_BIT)
815 #define TAG(x) x##_offset_twostencil
816 #include "tnl_dd/t_dd_tritmp.h"
818 #define IND (FX_TWOSIDE_BIT|FX_TWOSTENCIL_BIT)
819 #define TAG(x) x##_twoside_twostencil
820 #include "tnl_dd/t_dd_tritmp.h"
822 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_TWOSTENCIL_BIT)
823 #define TAG(x) x##_twoside_offset_twostencil
824 #include "tnl_dd/t_dd_tritmp.h"
826 #define IND (FX_UNFILLED_BIT|FX_TWOSTENCIL_BIT)
827 #define TAG(x) x##_unfilled_twostencil
828 #include "tnl_dd/t_dd_tritmp.h"
830 #define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_TWOSTENCIL_BIT)
831 #define TAG(x) x##_offset_unfilled_twostencil
832 #include "tnl_dd/t_dd_tritmp.h"
834 #define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_TWOSTENCIL_BIT)
835 #define TAG(x) x##_twoside_unfilled_twostencil
836 #include "tnl_dd/t_dd_tritmp.h"
838 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_TWOSTENCIL_BIT)
839 #define TAG(x) x##_twoside_offset_unfilled_twostencil
840 #include "tnl_dd/t_dd_tritmp.h"
842 #define IND (FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT)
843 #define TAG(x) x##_fallback_twostencil
844 #include "tnl_dd/t_dd_tritmp.h"
846 #define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT)
847 #define TAG(x) x##_offset_fallback_twostencil
848 #include "tnl_dd/t_dd_tritmp.h"
850 #define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT)
851 #define TAG(x) x##_twoside_fallback_twostencil
852 #include "tnl_dd/t_dd_tritmp.h"
854 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT)
855 #define TAG(x) x##_twoside_offset_fallback_twostencil
856 #include "tnl_dd/t_dd_tritmp.h"
858 #define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT)
859 #define TAG(x) x##_unfilled_fallback_twostencil
860 #include "tnl_dd/t_dd_tritmp.h"
862 #define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT)
863 #define TAG(x) x##_offset_unfilled_fallback_twostencil
864 #include "tnl_dd/t_dd_tritmp.h"
866 #define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT)
867 #define TAG(x) x##_twoside_unfilled_fallback_twostencil
868 #include "tnl_dd/t_dd_tritmp.h"
870 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \
871 FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT)
872 #define TAG(x) x##_twoside_offset_unfilled_fallback_twostencil
873 #include "tnl_dd/t_dd_tritmp.h"
876 /* Fx doesn't support provoking-vertex flat-shading?
878 #define IND (FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
879 #define TAG(x) x##_flat_twostencil
880 #include "tnl_dd/t_dd_tritmp.h"
882 #define IND (FX_OFFSET_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
883 #define TAG(x) x##_offset_flat_twostencil
884 #include "tnl_dd/t_dd_tritmp.h"
886 #define IND (FX_TWOSIDE_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
887 #define TAG(x) x##_twoside_flat_twostencil
888 #include "tnl_dd/t_dd_tritmp.h"
890 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
891 #define TAG(x) x##_twoside_offset_flat_twostencil
892 #include "tnl_dd/t_dd_tritmp.h"
894 #define IND (FX_UNFILLED_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
895 #define TAG(x) x##_unfilled_flat_twostencil
896 #include "tnl_dd/t_dd_tritmp.h"
898 #define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
899 #define TAG(x) x##_offset_unfilled_flat_twostencil
900 #include "tnl_dd/t_dd_tritmp.h"
902 #define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
903 #define TAG(x) x##_twoside_unfilled_flat_twostencil
904 #include "tnl_dd/t_dd_tritmp.h"
906 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
907 #define TAG(x) x##_twoside_offset_unfilled_flat_twostencil
908 #include "tnl_dd/t_dd_tritmp.h"
910 #define IND (FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
911 #define TAG(x) x##_fallback_flat_twostencil
912 #include "tnl_dd/t_dd_tritmp.h"
914 #define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
915 #define TAG(x) x##_offset_fallback_flat_twostencil
916 #include "tnl_dd/t_dd_tritmp.h"
918 #define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
919 #define TAG(x) x##_twoside_fallback_flat_twostencil
920 #include "tnl_dd/t_dd_tritmp.h"
922 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
923 #define TAG(x) x##_twoside_offset_fallback_flat_twostencil
924 #include "tnl_dd/t_dd_tritmp.h"
926 #define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
927 #define TAG(x) x##_unfilled_fallback_flat_twostencil
928 #include "tnl_dd/t_dd_tritmp.h"
930 #define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
931 #define TAG(x) x##_offset_unfilled_fallback_flat_twostencil
932 #include "tnl_dd/t_dd_tritmp.h"
934 #define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
935 #define TAG(x) x##_twoside_unfilled_fallback_flat_twostencil
936 #include "tnl_dd/t_dd_tritmp.h"
938 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \
939 FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
940 #define TAG(x) x##_twoside_offset_unfilled_fallback_flat_twostencil
941 #include "tnl_dd/t_dd_tritmp.h"
942 /* 2-sided stencil end */
945 static void init_rast_tab( void )
950 init_twoside_offset();
952 init_offset_unfilled();
953 init_twoside_unfilled();
954 init_twoside_offset_unfilled();
956 init_offset_fallback();
957 init_twoside_fallback();
958 init_twoside_offset_fallback();
959 init_unfilled_fallback();
960 init_offset_unfilled_fallback();
961 init_twoside_unfilled_fallback();
962 init_twoside_offset_unfilled_fallback();
967 init_twoside_offset_flat();
968 init_unfilled_flat();
969 init_offset_unfilled_flat();
970 init_twoside_unfilled_flat();
971 init_twoside_offset_unfilled_flat();
972 init_fallback_flat();
973 init_offset_fallback_flat();
974 init_twoside_fallback_flat();
975 init_twoside_offset_fallback_flat();
976 init_unfilled_fallback_flat();
977 init_offset_unfilled_fallback_flat();
978 init_twoside_unfilled_fallback_flat();
979 init_twoside_offset_unfilled_fallback_flat();
981 /* 2-sided stencil begin */
983 init_offset_twostencil();
984 init_twoside_twostencil();
985 init_twoside_offset_twostencil();
986 init_unfilled_twostencil();
987 init_offset_unfilled_twostencil();
988 init_twoside_unfilled_twostencil();
989 init_twoside_offset_unfilled_twostencil();
990 init_fallback_twostencil();
991 init_offset_fallback_twostencil();
992 init_twoside_fallback_twostencil();
993 init_twoside_offset_fallback_twostencil();
994 init_unfilled_fallback_twostencil();
995 init_offset_unfilled_fallback_twostencil();
996 init_twoside_unfilled_fallback_twostencil();
997 init_twoside_offset_unfilled_fallback_twostencil();
999 init_flat_twostencil();
1000 init_offset_flat_twostencil();
1001 init_twoside_flat_twostencil();
1002 init_twoside_offset_flat_twostencil();
1003 init_unfilled_flat_twostencil();
1004 init_offset_unfilled_flat_twostencil();
1005 init_twoside_unfilled_flat_twostencil();
1006 init_twoside_offset_unfilled_flat_twostencil();
1007 init_fallback_flat_twostencil();
1008 init_offset_fallback_flat_twostencil();
1009 init_twoside_fallback_flat_twostencil();
1010 init_twoside_offset_fallback_flat_twostencil();
1011 init_unfilled_fallback_flat_twostencil();
1012 init_offset_unfilled_fallback_flat_twostencil();
1013 init_twoside_unfilled_fallback_flat_twostencil();
1014 init_twoside_offset_unfilled_fallback_flat_twostencil();
1015 /* 2-sided stencil end */
1019 /**********************************************************************/
1020 /* Render whole begin/end objects */
1021 /**********************************************************************/
1024 /* Accelerate vertex buffer rendering when renderindex == 0 and
1025 * there is no clipping.
1027 #define INIT(x) fxRenderPrimitive( ctx, x )
1029 static void fx_render_vb_points( GLcontext
*ctx
,
1034 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1035 GrVertex
*fxVB
= fxMesa
->verts
;
1039 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1040 fprintf(stderr
, "fx_render_vb_points\n");
1045 /* Adjust point coords */
1046 for (i
= start
; i
< count
; i
++) {
1047 fxVB
[i
].x
+= PNT_X_OFFSET
- TRI_X_OFFSET
;
1048 fxVB
[i
].y
+= PNT_Y_OFFSET
- TRI_Y_OFFSET
;
1051 grDrawVertexArrayContiguous( GR_POINTS
, count
-start
,
1052 fxVB
+ start
, sizeof(GrVertex
));
1053 /* restore point coords */
1054 for (i
= start
; i
< count
; i
++) {
1055 fxVB
[i
].x
-= PNT_X_OFFSET
- TRI_X_OFFSET
;
1056 fxVB
[i
].y
-= PNT_Y_OFFSET
- TRI_Y_OFFSET
;
1060 static void fx_render_vb_line_strip( GLcontext
*ctx
,
1065 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1066 GrVertex
*fxVB
= fxMesa
->verts
;
1070 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1071 fprintf(stderr
, "fx_render_vb_line_strip\n");
1074 INIT(GL_LINE_STRIP
);
1076 /* adjust line coords */
1077 for (i
= start
; i
< count
; i
++) {
1078 fxVB
[i
].x
+= LINE_X_OFFSET
- TRI_X_OFFSET
;
1079 fxVB
[i
].y
+= LINE_Y_OFFSET
- TRI_Y_OFFSET
;
1082 grDrawVertexArrayContiguous( GR_LINE_STRIP
, count
-start
,
1083 fxVB
+ start
, sizeof(GrVertex
));
1085 /* restore line coords */
1086 for (i
= start
; i
< count
; i
++) {
1087 fxVB
[i
].x
-= LINE_X_OFFSET
- TRI_X_OFFSET
;
1088 fxVB
[i
].y
-= LINE_Y_OFFSET
- TRI_Y_OFFSET
;
1092 static void fx_render_vb_line_loop( GLcontext
*ctx
,
1097 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1098 GrVertex
*fxVB
= fxMesa
->verts
;
1103 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1104 fprintf(stderr
, "fx_render_vb_line_loop\n");
1109 if (!(flags
& PRIM_BEGIN
)) {
1113 /* adjust line coords */
1114 for (i
= start
; i
< count
; i
++) {
1115 fxVB
[i
].x
+= LINE_X_OFFSET
- TRI_X_OFFSET
;
1116 fxVB
[i
].y
+= LINE_Y_OFFSET
- TRI_Y_OFFSET
;
1119 grDrawVertexArrayContiguous( GR_LINE_STRIP
, count
-j
,
1120 fxVB
+ j
, sizeof(GrVertex
));
1122 if (flags
& PRIM_END
)
1123 grDrawLine( fxVB
+ (count
- 1),
1126 /* restore line coords */
1127 for (i
= start
; i
< count
; i
++) {
1128 fxVB
[i
].x
-= LINE_X_OFFSET
- TRI_X_OFFSET
;
1129 fxVB
[i
].y
-= LINE_Y_OFFSET
- TRI_Y_OFFSET
;
1133 static void fx_render_vb_lines( GLcontext
*ctx
,
1138 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1139 GrVertex
*fxVB
= fxMesa
->verts
;
1143 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1144 fprintf(stderr
, "fx_render_vb_lines\n");
1149 /* adjust line coords */
1150 for (i
= start
; i
< count
; i
++) {
1151 fxVB
[i
].x
+= LINE_X_OFFSET
- TRI_X_OFFSET
;
1152 fxVB
[i
].y
+= LINE_Y_OFFSET
- TRI_Y_OFFSET
;
1155 grDrawVertexArrayContiguous( GR_LINES
, count
-start
,
1156 fxVB
+ start
, sizeof(GrVertex
));
1158 /* restore line coords */
1159 for (i
= start
; i
< count
; i
++) {
1160 fxVB
[i
].x
-= LINE_X_OFFSET
- TRI_X_OFFSET
;
1161 fxVB
[i
].y
-= LINE_Y_OFFSET
- TRI_Y_OFFSET
;
1165 static void fx_render_vb_triangles( GLcontext
*ctx
,
1170 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1171 GrVertex
*fxVB
= fxMesa
->verts
;
1175 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1176 fprintf(stderr
, "fx_render_vb_triangles\n");
1181 for (j
=start
+2; j
<count
; j
+=3) {
1182 grDrawTriangle(fxVB
+ (j
-2), fxVB
+ (j
-1), fxVB
+ j
);
1187 static void fx_render_vb_tri_strip( GLcontext
*ctx
,
1192 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1193 GrVertex
*fxVB
= fxMesa
->verts
;
1196 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1197 fprintf(stderr
, "fx_render_vb_tri_strip\n");
1200 INIT(GL_TRIANGLE_STRIP
);
1202 /* no GR_TRIANGLE_STRIP_CONTINUE?!? */
1204 grDrawVertexArrayContiguous( GR_TRIANGLE_STRIP
, count
-start
,
1205 fxVB
+ start
, sizeof(GrVertex
));
1209 static void fx_render_vb_tri_fan( GLcontext
*ctx
,
1214 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1215 GrVertex
*fxVB
= fxMesa
->verts
;
1218 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1219 fprintf(stderr
, "fx_render_vb_tri_fan\n");
1222 INIT(GL_TRIANGLE_FAN
);
1224 grDrawVertexArrayContiguous( GR_TRIANGLE_FAN
, count
-start
,
1225 fxVB
+ start
, sizeof(GrVertex
) );
1228 static void fx_render_vb_quads( GLcontext
*ctx
,
1233 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1234 GrVertex
*fxVB
= fxMesa
->verts
;
1238 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1239 fprintf(stderr
, "fx_render_vb_quads\n");
1244 for (i
= start
+ 3 ; i
< count
; i
+= 4 ) {
1245 #define VERT(x) (fxVB + (x))
1251 grDrawVertexArray(GR_TRIANGLE_FAN
, 4, _v_
);
1252 /*grDrawTriangle( VERT(i-3), VERT(i-2), VERT(i) );*/
1253 /*grDrawTriangle( VERT(i-2), VERT(i-1), VERT(i) );*/
1258 static void fx_render_vb_quad_strip( GLcontext
*ctx
,
1263 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1264 GrVertex
*fxVB
= fxMesa
->verts
;
1267 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1268 fprintf(stderr
, "fx_render_vb_quad_strip\n");
1271 INIT(GL_QUAD_STRIP
);
1273 count
-= (count
-start
)&1;
1275 grDrawVertexArrayContiguous( GR_TRIANGLE_STRIP
,
1276 count
-start
, fxVB
+ start
, sizeof(GrVertex
));
1279 static void fx_render_vb_poly( GLcontext
*ctx
,
1284 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1285 GrVertex
*fxVB
= fxMesa
->verts
;
1288 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1289 fprintf(stderr
, "fx_render_vb_poly\n");
1294 grDrawVertexArrayContiguous( GR_POLYGON
, count
-start
,
1295 fxVB
+ start
, sizeof(GrVertex
));
1298 static void fx_render_vb_noop( GLcontext
*ctx
,
1303 (void) (ctx
&& start
&& count
&& flags
);
1306 static void (*fx_render_tab_verts
[GL_POLYGON
+2])(GLcontext
*,
1311 fx_render_vb_points
,
1313 fx_render_vb_line_loop
,
1314 fx_render_vb_line_strip
,
1315 fx_render_vb_triangles
,
1316 fx_render_vb_tri_strip
,
1317 fx_render_vb_tri_fan
,
1319 fx_render_vb_quad_strip
,
1326 /**********************************************************************/
1327 /* Render whole (indexed) begin/end objects */
1328 /**********************************************************************/
1331 #define VERT(x) (vertptr + x)
1333 #define RENDER_POINTS( start, count ) \
1334 for ( ; start < count ; start++) \
1335 grDrawPoint( VERT(ELT(start)) );
1337 #define RENDER_LINE( v0, v1 ) \
1338 grDrawLine( VERT(v0), VERT(v1) )
1340 #define RENDER_TRI( v0, v1, v2 ) \
1341 grDrawTriangle( VERT(v0), VERT(v1), VERT(v2) )
1343 #define RENDER_QUAD( v0, v1, v2, v3 ) \
1350 grDrawVertexArray(GR_TRIANGLE_FAN, 4, _v_);\
1351 /*grDrawTriangle( VERT(v0), VERT(v1), VERT(v3) );*/\
1352 /*grDrawTriangle( VERT(v1), VERT(v2), VERT(v3) );*/\
1355 #define INIT(x) fxRenderPrimitive( ctx, x )
1358 #define LOCAL_VARS \
1359 fxMesaContext fxMesa = FX_CONTEXT(ctx); \
1360 GrVertex *vertptr = fxMesa->verts; \
1361 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
1364 #define RESET_STIPPLE
1365 #define RESET_OCCLUSION
1366 #define PRESERVE_VB_DEFS
1368 /* Elts, no clipping.
1372 #define TAG(x) fx_##x##_elts
1373 #define ELT(x) elt[x]
1374 #include "tnl_dd/t_dd_rendertmp.h"
1376 /* Verts, no clipping.
1380 #define TAG(x) fx_##x##_verts
1382 /*#include "tnl_dd/t_dd_rendertmp.h"*/ /* we have fx_render_vb_* now */
1386 /**********************************************************************/
1387 /* Render clipped primitives */
1388 /**********************************************************************/
1392 static void fxRenderClippedPoly( GLcontext
*ctx
, const GLuint
*elts
,
1395 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1396 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1397 struct vertex_buffer
*VB
= &tnl
->vb
;
1398 GLuint prim
= fxMesa
->render_primitive
;
1400 /* Render the new vertices as an unclipped polygon.
1403 GLuint
*tmp
= VB
->Elts
;
1404 VB
->Elts
= (GLuint
*)elts
;
1405 tnl
->Driver
.Render
.PrimTabElts
[GL_POLYGON
]( ctx
, 0, n
,
1406 PRIM_BEGIN
|PRIM_END
);
1410 /* Restore the render primitive
1412 if (prim
!= GL_POLYGON
)
1413 tnl
->Driver
.Render
.PrimitiveNotify( ctx
, prim
);
1417 static void fxFastRenderClippedPoly( GLcontext
*ctx
, const GLuint
*elts
,
1421 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
1422 GrVertex
*vertptr
= fxMesa
->verts
;
1424 grDrawTriangle( VERT(elts
[0]), VERT(elts
[1]), VERT(elts
[2]) );
1425 } else if (n
<= 32) {
1426 GrVertex
*newvptr
[32];
1427 for (i
= 0 ; i
< n
; i
++) {
1428 newvptr
[i
] = VERT(elts
[i
]);
1430 grDrawVertexArray(GR_TRIANGLE_FAN
, n
, newvptr
);
1432 const GrVertex
*start
= VERT(elts
[0]);
1433 for (i
= 2 ; i
< n
; i
++) {
1434 grDrawTriangle( start
, VERT(elts
[i
-1]), VERT(elts
[i
]) );
1439 /**********************************************************************/
1440 /* Choose render functions */
1441 /**********************************************************************/
1444 #define POINT_FALLBACK (DD_POINT_SMOOTH)
1445 #define LINE_FALLBACK (DD_LINE_STIPPLE)
1446 #define TRI_FALLBACK (DD_TRI_SMOOTH | DD_TRI_STIPPLE)
1447 #define ANY_FALLBACK_FLAGS (POINT_FALLBACK | LINE_FALLBACK | TRI_FALLBACK)
1448 #define ANY_RASTER_FLAGS (DD_FLATSHADE | DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET \
1449 | DD_TRI_UNFILLED | DD_TRI_TWOSTENCIL)
1453 void fxDDChooseRenderState(GLcontext
*ctx
)
1455 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1456 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1457 GLuint flags
= ctx
->_TriangleCaps
;
1460 if (flags
& (ANY_FALLBACK_FLAGS
|ANY_RASTER_FLAGS
)) {
1461 if (flags
& ANY_RASTER_FLAGS
) {
1462 if (flags
& DD_TRI_TWOSTENCIL
) index
|= FX_TWOSTENCIL_BIT
;
1463 if (flags
& DD_TRI_LIGHT_TWOSIDE
) index
|= FX_TWOSIDE_BIT
;
1464 if (flags
& DD_TRI_OFFSET
) index
|= FX_OFFSET_BIT
;
1465 if (flags
& DD_TRI_UNFILLED
) index
|= FX_UNFILLED_BIT
;
1466 if (flags
& DD_FLATSHADE
) index
|= FX_FLAT_BIT
;
1469 fxMesa
->draw_point
= fx_draw_point
;
1470 fxMesa
->draw_line
= fx_draw_line
;
1471 fxMesa
->draw_tri
= fx_draw_triangle
;
1473 /* Hook in fallbacks for specific primitives. */
1474 if (flags
& (POINT_FALLBACK
|
1478 if (fxMesa
->verbose
) {
1479 fprintf(stderr
, "Voodoo ! fallback (%x), raster (%x)\n",
1480 flags
& ANY_FALLBACK_FLAGS
, flags
& ANY_RASTER_FLAGS
);
1483 if (flags
& POINT_FALLBACK
)
1484 fxMesa
->draw_point
= fx_fallback_point
;
1486 if (flags
& LINE_FALLBACK
)
1487 fxMesa
->draw_line
= fx_fallback_line
;
1489 if (flags
& TRI_FALLBACK
)
1490 fxMesa
->draw_tri
= fx_fallback_tri
;
1492 index
|= FX_FALLBACK_BIT
;
1496 tnl
->Driver
.Render
.Points
= rast_tab
[index
].points
;
1497 tnl
->Driver
.Render
.Line
= rast_tab
[index
].line
;
1498 tnl
->Driver
.Render
.ClippedLine
= rast_tab
[index
].line
;
1499 tnl
->Driver
.Render
.Triangle
= rast_tab
[index
].triangle
;
1500 tnl
->Driver
.Render
.Quad
= rast_tab
[index
].quad
;
1503 tnl
->Driver
.Render
.PrimTabVerts
= fx_render_tab_verts
;
1504 tnl
->Driver
.Render
.PrimTabElts
= fx_render_tab_elts
;
1505 tnl
->Driver
.Render
.ClippedPolygon
= fxFastRenderClippedPoly
;
1507 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
1508 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
1509 tnl
->Driver
.Render
.ClippedPolygon
= fxRenderClippedPoly
;
1512 fxMesa
->render_index
= index
;
1514 /* [dBorca] Hack alert: more a trick than a real plug-in!!! */
1515 if (flags
& (DD_POINT_SIZE
| DD_POINT_ATTEN
)) {
1516 /* We need to set the point primitive to go through "rast_tab",
1517 * to make sure "POINT" calls "fxMesa->draw_point" instead of
1518 * "grDrawPoint". We can achieve this by using FX_FALLBACK_BIT
1519 * (not really a total rasterization fallback, so we don't alter
1520 * "fxMesa->render_index"). If we get here with DD_POINT_SMOOTH,
1521 * we're done, cos we've already set _tnl_render_tab_{verts|elts}
1522 * above. Otherwise, the T&L engine can optimize point rendering
1523 * by using fx_render_tab_{verts|elts} hence the extra work.
1525 if (flags
& DD_POINT_SMOOTH
) {
1526 fxMesa
->draw_point
= fx_draw_point_wide_aa
;
1528 fxMesa
->draw_point
= fx_draw_point_wide
;
1529 fx_render_tab_verts
[0] = fx_render_pw_verts
;
1530 fx_render_tab_elts
[0] = fx_render_pw_elts
;
1532 tnl
->Driver
.Render
.Points
= rast_tab
[index
|FX_FALLBACK_BIT
].points
;
1534 fx_render_tab_verts
[0] = fx_render_vb_points
;
1535 fx_render_tab_elts
[0] = fx_render_points_elts
;
1540 /**********************************************************************/
1541 /* Runtime render state and callbacks */
1542 /**********************************************************************/
1544 static void fxRunPipeline( GLcontext
*ctx
)
1546 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1547 GLuint new_gl_state
= fxMesa
->new_gl_state
;
1549 if (TDFX_DEBUG
& VERBOSE_PIPELINE
) {
1550 fprintf(stderr
, "fxRunPipeline()\n");
1554 /* Recalculate fog table on projection matrix changes. This used to
1555 * be triggered by the NearFar callback.
1557 if (new_gl_state
& _NEW_PROJECTION
)
1558 fxMesa
->new_state
|= FX_NEW_FOG
;
1561 if (new_gl_state
& _FX_NEW_IS_IN_HARDWARE
)
1562 fxCheckIsInHardware(ctx
);
1564 if (fxMesa
->new_state
)
1565 fxSetupFXUnits(ctx
);
1567 if (!fxMesa
->fallback
) {
1568 if (new_gl_state
& _FX_NEW_RENDERSTATE
)
1569 fxDDChooseRenderState(ctx
);
1571 if (new_gl_state
& _FX_NEW_SETUP_FUNCTION
)
1572 fxChooseVertexState(ctx
);
1575 if (new_gl_state
& _NEW_TEXTURE
) {
1576 struct gl_texture_unit
*t0
= &ctx
->Texture
.Unit
[fxMesa
->tmu_source
[0]];
1577 struct gl_texture_unit
*t1
= &ctx
->Texture
.Unit
[fxMesa
->tmu_source
[1]];
1579 if (t0
->_Current
&& FX_TEXTURE_DATA(t0
)) {
1580 fxMesa
->s0scale
= FX_TEXTURE_DATA(t0
)->sScale
;
1581 fxMesa
->t0scale
= FX_TEXTURE_DATA(t0
)->tScale
;
1582 fxMesa
->inv_s0scale
= 1.0F
/ fxMesa
->s0scale
;
1583 fxMesa
->inv_t0scale
= 1.0F
/ fxMesa
->t0scale
;
1586 if (t1
->_Current
&& FX_TEXTURE_DATA(t1
)) {
1587 fxMesa
->s1scale
= FX_TEXTURE_DATA(t1
)->sScale
;
1588 fxMesa
->t1scale
= FX_TEXTURE_DATA(t1
)->tScale
;
1589 fxMesa
->inv_s1scale
= 1.0F
/ fxMesa
->s1scale
;
1590 fxMesa
->inv_t1scale
= 1.0F
/ fxMesa
->t1scale
;
1594 fxMesa
->new_gl_state
= 0;
1596 _tnl_run_pipeline( ctx
);
1601 /* Always called between RenderStart and RenderFinish --> We already
1604 static void fxRasterPrimitive( GLcontext
*ctx
, GLenum prim
)
1606 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
1608 fxMesa
->raster_primitive
= prim
;
1615 /* Determine the rasterized primitive when not drawing unfilled
1618 static void fxRenderPrimitive( GLcontext
*ctx
, GLenum prim
)
1620 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1621 GLuint rprim
= reduced_prim
[prim
];
1623 fxMesa
->render_primitive
= prim
;
1625 if (rprim
== GL_TRIANGLES
&& (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
))
1628 if (fxMesa
->raster_primitive
!= rprim
) {
1629 fxRasterPrimitive( ctx
, rprim
);
1633 static void fxRenderFinish( GLcontext
*ctx
)
1635 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1637 if (fxMesa
->render_index
& FX_FALLBACK_BIT
)
1638 _swrast_flush( ctx
);
1643 /**********************************************************************/
1644 /* Manage total rasterization fallbacks */
1645 /**********************************************************************/
1647 static char *fallbackStrings
[] = {
1648 "3D/Rect/Cube Texture map",
1649 "glDrawBuffer(GL_FRONT_AND_BACK)",
1650 "Separate specular color",
1651 "glEnable/Disable(GL_STENCIL_TEST)",
1652 "glRenderMode(selection or feedback)",
1662 static char *getFallbackString(GLuint bit
)
1669 return fallbackStrings
[i
];
1673 void fxCheckIsInHardware( GLcontext
*ctx
)
1675 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1676 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1677 GLuint oldfallback
= fxMesa
->fallback
;
1678 GLuint newfallback
= fxMesa
->fallback
= fx_check_IsInHardware( ctx
);
1681 if (oldfallback
== 0) {
1682 if (fxMesa
->verbose
) {
1683 fprintf(stderr
, "Voodoo ! enter SW 0x%08x %s\n", newfallback
, getFallbackString(newfallback
));
1685 _swsetup_Wakeup( ctx
);
1690 _swrast_flush( ctx
);
1691 tnl
->Driver
.Render
.Start
= fxCheckTexSizes
;
1692 tnl
->Driver
.Render
.Finish
= fxRenderFinish
;
1693 tnl
->Driver
.Render
.PrimitiveNotify
= fxRenderPrimitive
;
1694 tnl
->Driver
.Render
.ClippedPolygon
= _tnl_RenderClippedPolygon
;
1695 tnl
->Driver
.Render
.ClippedLine
= _tnl_RenderClippedLine
;
1696 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
1697 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
1698 tnl
->Driver
.Render
.ResetLineStipple
= _swrast_ResetLineStipple
;
1699 tnl
->Driver
.Render
.BuildVertices
= fxBuildVertices
;
1700 fxChooseVertexState(ctx
);
1701 fxDDChooseRenderState(ctx
);
1702 if (fxMesa
->verbose
) {
1703 fprintf(stderr
, "Voodoo ! leave SW 0x%08x %s\n", oldfallback
, getFallbackString(oldfallback
));
1706 tnl
->Driver
.Render
.Multipass
= NULL
;
1707 if (HAVE_SPEC
&& NEED_SECONDARY_COLOR(ctx
)) {
1708 tnl
->Driver
.Render
.Multipass
= fxMultipass_ColorSum
;
1709 /* obey stencil, but do not change it */
1710 fxMesa
->multipass
= GL_TRUE
;
1711 if (fxMesa
->unitsState
.stencilEnabled
) {
1712 fxMesa
->new_state
|= FX_NEW_STENCIL
;
1718 void fxDDInitTriFuncs( GLcontext
*ctx
)
1720 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1721 static int firsttime
= 1;
1728 tnl
->Driver
.RunPipeline
= fxRunPipeline
;
1729 tnl
->Driver
.Render
.Start
= fxCheckTexSizes
;
1730 tnl
->Driver
.Render
.Finish
= fxRenderFinish
;
1731 tnl
->Driver
.Render
.PrimitiveNotify
= fxRenderPrimitive
;
1732 tnl
->Driver
.Render
.ClippedPolygon
= _tnl_RenderClippedPolygon
;
1733 tnl
->Driver
.Render
.ClippedLine
= _tnl_RenderClippedLine
;
1734 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
1735 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
1736 tnl
->Driver
.Render
.ResetLineStipple
= _swrast_ResetLineStipple
;
1737 tnl
->Driver
.Render
.BuildVertices
= fxBuildVertices
;
1738 tnl
->Driver
.Render
.Multipass
= NULL
;
1740 (void) fx_print_vertex
;
1744 /* [dBorca] Hack alert:
1745 * doesn't work with blending.
1748 fxMultipass_ColorSum (GLcontext
*ctx
, GLuint pass
)
1750 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1751 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1757 case 1: /* first pass: the TEXTURED triangles are drawn */
1758 /* set stencil's real values */
1759 fxMesa
->multipass
= GL_FALSE
;
1760 if (us
->stencilEnabled
) {
1761 fxSetupStencil(ctx
);
1763 /* save per-pass data */
1764 fxMesa
->restoreUnitsState
= *us
;
1765 /* turn off texturing */
1766 t0
= ctx
->Texture
.Unit
[0]._ReallyEnabled
;
1767 t1
= ctx
->Texture
.Unit
[1]._ReallyEnabled
;
1768 ctx
->Texture
.Unit
[0]._ReallyEnabled
= 0;
1769 ctx
->Texture
.Unit
[1]._ReallyEnabled
= 0;
1770 /* SUM the colors */
1771 fxDDBlendEquationSeparate(ctx
, GL_FUNC_ADD
, GL_FUNC_ADD
);
1772 fxDDBlendFuncSeparate(ctx
, GL_ONE
, GL_ONE
, GL_ZERO
, GL_ONE
);
1773 fxDDEnable(ctx
, GL_BLEND
, GL_TRUE
);
1774 /* make sure we draw only where we want to */
1775 if (us
->depthTestEnabled
) {
1776 switch (us
->depthTestFunc
) {
1778 fxDDDepthFunc(ctx
, GL_EQUAL
);
1783 fxDDDepthMask(ctx
, GL_FALSE
);
1785 /* switch to secondary colors */
1787 grVertexLayout(GR_PARAM_PARGB
, GR_VERTEX_PSPEC_OFFSET
<< 2, GR_PARAM_ENABLE
);
1788 #else /* !FX_PACKEDCOLOR */
1789 grVertexLayout(GR_PARAM_RGB
, GR_VERTEX_SPEC_OFFSET
<< 2, GR_PARAM_ENABLE
);
1790 #endif /* !FX_PACKEDCOLOR */
1791 /* don't advertise new state */
1792 fxMesa
->new_state
= 0;
1794 case 2: /* 2nd pass (last): the secondary color is summed over texture */
1795 /* restore original state */
1796 *us
= fxMesa
->restoreUnitsState
;
1797 /* restore texturing */
1798 ctx
->Texture
.Unit
[0]._ReallyEnabled
= t0
;
1799 ctx
->Texture
.Unit
[1]._ReallyEnabled
= t1
;
1800 /* revert to primary colors */
1802 grVertexLayout(GR_PARAM_PARGB
, GR_VERTEX_PARGB_OFFSET
<< 2, GR_PARAM_ENABLE
);
1803 #else /* !FX_PACKEDCOLOR */
1804 grVertexLayout(GR_PARAM_RGB
, GR_VERTEX_RGB_OFFSET
<< 2, GR_PARAM_ENABLE
);
1805 #endif /* !FX_PACKEDCOLOR */
1808 assert(0); /* NOTREACHED */
1811 /* update HW state */
1813 fxSetupDepthTest(ctx
);
1814 fxSetupTexture(ctx
);
1824 * Need this to provide at least one external definition.
1827 extern int gl_fx_dummy_function_tris(void);
1829 gl_fx_dummy_function_tris(void)