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>
34 #include "main/imports.h"
35 #include "main/mtypes.h"
36 #include "main/macros.h"
37 #include "main/colormac.h"
38 #include "swrast/swrast.h"
39 #include "swrast_setup/swrast_setup.h"
40 #include "tnl/t_context.h"
41 #include "tnl/t_pipeline.h"
46 static GLboolean
fxMultipass_ColorSum (GLcontext
*ctx
, GLuint pass
);
50 * Subpixel offsets to adjust Mesa's (true) window coordinates to
51 * Glide coordinates. We need these to ensure precise rasterization.
52 * Otherwise, we'll fail a bunch of conformance tests.
54 #define TRI_X_OFFSET ( 0.0F)
55 #define TRI_Y_OFFSET ( 0.0F)
56 #define LINE_X_OFFSET ( 0.0F)
57 #define LINE_Y_OFFSET ( 0.125F)
58 #define PNT_X_OFFSET ( 0.375F)
59 #define PNT_Y_OFFSET ( 0.375F)
61 static void fxRasterPrimitive( GLcontext
*ctx
, GLenum prim
);
62 static void fxRenderPrimitive( GLcontext
*ctx
, GLenum prim
);
64 static GLenum reduced_prim
[GL_POLYGON
+1] = {
77 /***********************************************************************
78 * Macros for t_dd_tritmp.h to draw basic primitives *
79 ***********************************************************************/
81 #define TRI( a, b, c ) \
84 fxMesa->draw_tri( fxMesa, a, b, c ); \
86 grDrawTriangle( a, b, c ); \
89 #define QUAD( a, b, c, d ) \
92 fxMesa->draw_tri( fxMesa, a, b, d ); \
93 fxMesa->draw_tri( fxMesa, b, c, d ); \
100 grDrawVertexArray(GR_TRIANGLE_FAN, 4, _v_);\
101 /*grDrawTriangle( a, b, d );*/ \
102 /*grDrawTriangle( b, c, d );*/ \
106 #define LINE( v0, v1 ) \
109 fxMesa->draw_line( fxMesa, v0, v1 ); \
111 v0->x += LINE_X_OFFSET - TRI_X_OFFSET; \
112 v0->y += LINE_Y_OFFSET - TRI_Y_OFFSET; \
113 v1->x += LINE_X_OFFSET - TRI_X_OFFSET; \
114 v1->y += LINE_Y_OFFSET - TRI_Y_OFFSET; \
115 grDrawLine( v0, v1 ); \
116 v0->x -= LINE_X_OFFSET - TRI_X_OFFSET; \
117 v0->y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \
118 v1->x -= LINE_X_OFFSET - TRI_X_OFFSET; \
119 v1->y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \
123 #define POINT( v0 ) \
126 fxMesa->draw_point( fxMesa, v0 ); \
128 v0->x += PNT_X_OFFSET - TRI_X_OFFSET; \
129 v0->y += PNT_Y_OFFSET - TRI_Y_OFFSET; \
131 v0->x -= PNT_X_OFFSET - TRI_X_OFFSET; \
132 v0->y -= PNT_Y_OFFSET - TRI_Y_OFFSET; \
137 /***********************************************************************
138 * Fallback to swrast for basic primitives *
139 ***********************************************************************/
141 /* Build an SWvertex from a hardware vertex.
143 * This code is hit only when a mix of accelerated and unaccelerated
144 * primitives are being drawn, and only for the unaccelerated
148 fx_translate_vertex( GLcontext
*ctx
, const GrVertex
*src
, SWvertex
*dst
)
150 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
151 GLuint ts0
= fxMesa
->tmu_source
[0];
152 GLuint ts1
= fxMesa
->tmu_source
[1];
153 GLfloat w
= 1.0F
/ src
->oow
;
155 dst
->win
[0] = src
->x
;
156 dst
->win
[1] = src
->y
;
157 dst
->win
[2] = src
->ooz
;
158 dst
->win
[3] = src
->oow
;
161 dst
->color
[0] = src
->pargb
[2];
162 dst
->color
[1] = src
->pargb
[1];
163 dst
->color
[2] = src
->pargb
[0];
164 dst
->color
[3] = src
->pargb
[3];
166 dst
->specular
[0] = src
->pspec
[2];
167 dst
->specular
[1] = src
->pspec
[1];
168 dst
->specular
[2] = src
->pspec
[0];
169 #else /* !FX_PACKEDCOLOR */
170 dst
->color
[0] = src
->r
;
171 dst
->color
[1] = src
->g
;
172 dst
->color
[2] = src
->b
;
173 dst
->color
[3] = src
->a
;
175 dst
->specular
[0] = src
->r1
;
176 dst
->specular
[1] = src
->g1
;
177 dst
->specular
[2] = src
->g1
;
178 #endif /* !FX_PACKEDCOLOR */
180 dst
->texcoord
[ts0
][0] = fxMesa
->inv_s0scale
* src
->tmuvtx
[0].sow
* w
;
181 dst
->texcoord
[ts0
][1] = fxMesa
->inv_t0scale
* src
->tmuvtx
[0].tow
* w
;
183 if (fxMesa
->stw_hint_state
& GR_STWHINT_W_DIFF_TMU0
)
184 dst
->texcoord
[ts0
][3] = src
->tmuvtx
[0].oow
* w
;
186 dst
->texcoord
[ts0
][3] = 1.0F
;
188 if (fxMesa
->SetupIndex
& SETUP_TMU1
) {
189 dst
->texcoord
[ts1
][0] = fxMesa
->inv_s1scale
* src
->tmuvtx
[1].sow
* w
;
190 dst
->texcoord
[ts1
][1] = fxMesa
->inv_t1scale
* src
->tmuvtx
[1].tow
* w
;
192 if (fxMesa
->stw_hint_state
& GR_STWHINT_W_DIFF_TMU1
)
193 dst
->texcoord
[ts1
][3] = src
->tmuvtx
[1].oow
* w
;
195 dst
->texcoord
[ts1
][3] = 1.0F
;
198 dst
->pointSize
= src
->psize
;
203 fx_fallback_tri( fxMesaContext fxMesa
,
208 GLcontext
*ctx
= fxMesa
->glCtx
;
211 fx_translate_vertex( ctx
, v0
, &v
[0] );
212 fx_translate_vertex( ctx
, v1
, &v
[1] );
213 fx_translate_vertex( ctx
, v2
, &v
[2] );
214 _swrast_Triangle( ctx
, &v
[0], &v
[1], &v
[2] );
219 fx_fallback_line( fxMesaContext fxMesa
,
223 GLcontext
*ctx
= fxMesa
->glCtx
;
225 fx_translate_vertex( ctx
, v0
, &v
[0] );
226 fx_translate_vertex( ctx
, v1
, &v
[1] );
227 _swrast_Line( ctx
, &v
[0], &v
[1] );
232 fx_fallback_point( fxMesaContext fxMesa
,
235 GLcontext
*ctx
= fxMesa
->glCtx
;
237 fx_translate_vertex( ctx
, v0
, &v
[0] );
238 _swrast_Point( ctx
, &v
[0] );
241 /***********************************************************************
242 * Functions to draw basic primitives *
243 ***********************************************************************/
245 static void fx_print_vertex( GLcontext
*ctx
, const GrVertex
*v
)
247 fprintf(stderr
, "fx_print_vertex:\n");
249 fprintf(stderr
, "\tvertex at %p\n", (void *) v
);
251 fprintf(stderr
, "\tx %f y %f z %f oow %f\n", v
->x
, v
->y
, v
->ooz
, v
->oow
);
253 fprintf(stderr
, "\tr %d g %d b %d a %d\n", v
->pargb
[2], v
->pargb
[1], v
->pargb
[0], v
->pargb
[3]);
254 #else /* !FX_PACKEDCOLOR */
255 fprintf(stderr
, "\tr %f g %f b %f a %f\n", v
->r
, v
->g
, v
->b
, v
->a
);
256 #endif /* !FX_PACKEDCOLOR */
258 fprintf(stderr
, "\n");
261 #define DO_FALLBACK 0
263 /* Need to do clip loop at each triangle when mixing swrast and hw
264 * rendering. These functions are only used when mixed-mode rendering
267 static void fx_draw_triangle( fxMesaContext fxMesa
,
277 static void fx_draw_line( fxMesaContext fxMesa
,
281 /* No support for wide lines (avoid wide/aa line fallback).
288 static void fx_draw_point( fxMesaContext fxMesa
,
291 /* No support for wide points.
299 #define M_2PI 6.28318530717958647692528676655901
301 #define __GL_COSF cos
302 #define __GL_SINF sin
303 static void fx_draw_point_sprite ( fxMesaContext fxMesa
,
304 GrVertex
*v0
, GLfloat psize
)
306 const GLcontext
*ctx
= fxMesa
->glCtx
;
310 GLuint ts0
= fxMesa
->tmu_source
[0];
311 GLuint ts1
= fxMesa
->tmu_source
[1];
313 GLfloat u0scale
= fxMesa
->s0scale
* w
;
314 GLfloat v0scale
= fxMesa
->t0scale
* w
;
315 GLfloat u1scale
= fxMesa
->s1scale
* w
;
316 GLfloat v1scale
= fxMesa
->t1scale
* w
;
318 radius
= psize
/ 2.0F
;
324 /* point coverage? */
325 /* we don't care about culling here (see fxSetupCull) */
327 if (ctx
->Point
.SpriteOrigin
== GL_UPPER_LEFT
) {
347 if (ctx
->Point
.CoordReplace
[ts0
]) {
348 _v_
[0].tmuvtx
[0].sow
= 0;
349 _v_
[0].tmuvtx
[0].tow
= 0;
350 _v_
[1].tmuvtx
[0].sow
= u0scale
;
351 _v_
[1].tmuvtx
[0].tow
= 0;
352 _v_
[2].tmuvtx
[0].sow
= u0scale
;
353 _v_
[2].tmuvtx
[0].tow
= v0scale
;
354 _v_
[3].tmuvtx
[0].sow
= 0;
355 _v_
[3].tmuvtx
[0].tow
= v0scale
;
357 if (ctx
->Point
.CoordReplace
[ts1
]) {
358 _v_
[0].tmuvtx
[1].sow
= 0;
359 _v_
[0].tmuvtx
[1].tow
= 0;
360 _v_
[1].tmuvtx
[1].sow
= u1scale
;
361 _v_
[1].tmuvtx
[1].tow
= 0;
362 _v_
[2].tmuvtx
[1].sow
= u1scale
;
363 _v_
[2].tmuvtx
[1].tow
= v1scale
;
364 _v_
[3].tmuvtx
[1].sow
= 0;
365 _v_
[3].tmuvtx
[1].tow
= v1scale
;
368 grDrawVertexArrayContiguous(GR_TRIANGLE_FAN
, 4, _v_
, sizeof(GrVertex
));
371 static void fx_draw_point_wide ( fxMesaContext fxMesa
,
375 GLfloat ang
, radius
, oon
;
379 const GLcontext
*ctx
= fxMesa
->glCtx
;
380 const GLfloat psize
= (ctx
->_TriangleCaps
& DD_POINT_ATTEN
)
381 ? CLAMP(v0
->psize
, ctx
->Point
.MinSize
, ctx
->Point
.MaxSize
)
382 : ctx
->Point
._Size
; /* clamped */
384 if (ctx
->Point
.PointSprite
) {
385 fx_draw_point_sprite(fxMesa
, v0
, psize
);
393 radius
= psize
/ 2.0F
;
394 n
= IROUND(psize
* 2); /* radius x 4 */
396 oon
= 1.0F
/ (GLfloat
)n
;
399 /* point coverage? */
400 /* we don't care about culling here (see fxSetupCull) */
407 vtxC
.x
+= radius
* __GL_COSF(ang
);
408 vtxC
.y
+= radius
* __GL_SINF(ang
);
409 grDrawVertexArray(GR_TRIANGLE_FAN
, 3, _v_
);
410 for (i
= 2; i
<= n
; i
++) {
411 ang
= M_2PI
* i
* oon
;
412 vtxC
.x
= v0
->x
+ radius
* __GL_COSF(ang
);
413 vtxC
.y
= v0
->y
+ radius
* __GL_SINF(ang
);
414 grDrawVertexArray(GR_TRIANGLE_FAN_CONTINUE
, 1, &_v_
[2]);
418 static void fx_render_pw_verts( GLcontext
*ctx
,
423 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
424 GrVertex
*fxVB
= fxMesa
->verts
;
427 fxRenderPrimitive( ctx
, GL_POINTS
);
429 for ( ; start
< count
; start
++)
430 fx_draw_point_wide(fxMesa
, fxVB
+ start
);
433 static void fx_render_pw_elts ( GLcontext
*ctx
,
438 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
439 GrVertex
*fxVB
= fxMesa
->verts
;
440 const GLuint
* const elt
= TNL_CONTEXT(ctx
)->vb
.Elts
;
443 fxRenderPrimitive( ctx
, GL_POINTS
);
445 for ( ; start
< count
; start
++)
446 fx_draw_point_wide(fxMesa
, fxVB
+ elt
[start
]);
449 static void fx_draw_point_wide_aa ( fxMesaContext fxMesa
,
453 GLfloat ang
, radius
, oon
;
456 const GLcontext
*ctx
= fxMesa
->glCtx
;
457 const GLfloat psize
= (ctx
->_TriangleCaps
& DD_POINT_ATTEN
)
458 ? CLAMP(v0
->psize
, ctx
->Point
.MinSize
, ctx
->Point
.MaxSize
)
459 : ctx
->Point
._Size
; /* clamped */
461 if (ctx
->Point
.PointSprite
) {
462 fx_draw_point_sprite(fxMesa
, v0
, psize
);
466 radius
= psize
/ 2.0F
;
467 n
= IROUND(psize
* 2); /* radius x 4 */
469 oon
= 1.0F
/ (GLfloat
)n
;
472 /* point coverage? */
473 /* we don't care about culling here (see fxSetupCull) */
479 for (i
= 1; i
<= n
; i
++) {
480 ang
= M_2PI
* i
* oon
;
481 vtxC
.x
= v0
->x
+ radius
* __GL_COSF(ang
);
482 vtxC
.y
= v0
->y
+ radius
* __GL_SINF(ang
);
483 grAADrawTriangle( v0
, &vtxB
, &vtxC
, FXFALSE
, FXTRUE
, FXFALSE
);
484 /*grDrawTriangle( v0, &vtxB, &vtxC);*/
496 #define FX_UNFILLED_BIT 0x1
497 #define FX_OFFSET_BIT 0x2
498 #define FX_TWOSIDE_BIT 0x4
499 #define FX_FLAT_BIT 0x8
500 #define FX_TWOSTENCIL_BIT 0x10
501 #define FX_FALLBACK_BIT 0x20
502 #define FX_MAX_TRIFUNC 0x40
505 tnl_points_func points
;
507 tnl_triangle_func triangle
;
509 } rast_tab
[FX_MAX_TRIFUNC
];
511 #define DO_FALLBACK (IND & FX_FALLBACK_BIT)
512 #define DO_OFFSET (IND & FX_OFFSET_BIT)
513 #define DO_UNFILLED (IND & FX_UNFILLED_BIT)
514 #define DO_TWOSIDE (IND & FX_TWOSIDE_BIT)
515 #define DO_FLAT (IND & FX_FLAT_BIT)
516 #define DO_TWOSTENCIL (IND & FX_TWOSTENCIL_BIT)
521 #define DO_FULL_QUAD 1
525 #define HAVE_HW_FLATSHADE 0
526 #define HAVE_BACK_COLORS 0
527 #define VERTEX GrVertex
530 #define DEPTH_SCALE 1.0
531 #define UNFILLED_TRI unfilled_tri
532 #define UNFILLED_QUAD unfilled_quad
533 #define VERT_X(_v) _v->x
534 #define VERT_Y(_v) _v->y
535 #define VERT_Z(_v) _v->ooz
536 #define AREA_IS_CCW( a ) IS_NEGATIVE( a )
537 #define GET_VERTEX(e) (fxMesa->verts + e)
541 #define VERT_SET_RGBA( dst, f ) \
543 UNCLAMPED_FLOAT_TO_UBYTE(dst->pargb[2], f[0]);\
544 UNCLAMPED_FLOAT_TO_UBYTE(dst->pargb[1], f[1]);\
545 UNCLAMPED_FLOAT_TO_UBYTE(dst->pargb[0], f[2]);\
546 UNCLAMPED_FLOAT_TO_UBYTE(dst->pargb[3], f[3]);\
549 #define VERT_COPY_RGBA( v0, v1 ) \
550 *(GLuint *)&v0->pargb = *(GLuint *)&v1->pargb
552 #define VERT_SAVE_RGBA( idx ) \
553 *(GLuint *)&color[idx] = *(GLuint *)&v[idx]->pargb
555 #define VERT_RESTORE_RGBA( idx ) \
556 *(GLuint *)&v[idx]->pargb = *(GLuint *)&color[idx]
559 #define VERT_SET_SPEC( dst, f ) \
561 UNCLAMPED_FLOAT_TO_UBYTE(dst->pspec[2], f[0]);\
562 UNCLAMPED_FLOAT_TO_UBYTE(dst->pspec[1], f[1]);\
563 UNCLAMPED_FLOAT_TO_UBYTE(dst->pspec[0], f[2]);\
566 #define VERT_COPY_SPEC( v0, v1 ) \
567 *(GLuint *)&v0->pspec = *(GLuint *)&v1->pspec
569 #define VERT_SAVE_SPEC( idx ) \
570 *(GLuint *)&spec[idx] = *(GLuint *)&v[idx]->pspec
572 #define VERT_RESTORE_SPEC( idx ) \
573 *(GLuint *)&v[idx]->pspec = *(GLuint *)&spec[idx]
576 #define LOCAL_VARS(n) \
577 fxMesaContext fxMesa = FX_CONTEXT(ctx); \
578 GLubyte color[n][4], spec[n][4]; \
579 (void) color; (void) spec;
580 #else /* !FX_PACKEDCOLOR */
581 #define VERT_SET_RGBA( dst, f ) \
583 CNORM(dst->r, f[0]); \
584 CNORM(dst->g, f[1]); \
585 CNORM(dst->b, f[2]); \
586 CNORM(dst->a, f[3]); \
589 #define VERT_COPY_RGBA( v0, v1 ) \
591 COPY_FLOAT(v0->r, v1->r); \
592 COPY_FLOAT(v0->g, v1->g); \
593 COPY_FLOAT(v0->b, v1->b); \
594 COPY_FLOAT(v0->a, v1->a); \
597 #define VERT_SAVE_RGBA( idx ) \
599 COPY_FLOAT(color[idx][0], v[idx]->r); \
600 COPY_FLOAT(color[idx][1], v[idx]->g); \
601 COPY_FLOAT(color[idx][2], v[idx]->b); \
602 COPY_FLOAT(color[idx][3], v[idx]->a); \
605 #define VERT_RESTORE_RGBA( idx ) \
607 COPY_FLOAT(v[idx]->r, color[idx][0]); \
608 COPY_FLOAT(v[idx]->g, color[idx][1]); \
609 COPY_FLOAT(v[idx]->b, color[idx][2]); \
610 COPY_FLOAT(v[idx]->a, color[idx][3]); \
614 #define VERT_SET_SPEC( dst, f ) \
616 CNORM(dst->r1, f[0]); \
617 CNORM(dst->g1, f[1]); \
618 CNORM(dst->b1, f[2]); \
621 #define VERT_COPY_SPEC( v0, v1 ) \
623 COPY_FLOAT(v0->r1, v1->r1); \
624 COPY_FLOAT(v0->g1, v1->g1); \
625 COPY_FLOAT(v0->b1, v1->b1); \
628 #define VERT_SAVE_SPEC( idx ) \
630 COPY_FLOAT(spec[idx][0], v[idx]->r1); \
631 COPY_FLOAT(spec[idx][1], v[idx]->g1); \
632 COPY_FLOAT(spec[idx][2], v[idx]->b1); \
635 #define VERT_RESTORE_SPEC( idx ) \
637 COPY_FLOAT(v[idx]->r1, spec[idx][0]); \
638 COPY_FLOAT(v[idx]->g1, spec[idx][1]); \
639 COPY_FLOAT(v[idx]->b1, spec[idx][2]); \
643 #define LOCAL_VARS(n) \
644 fxMesaContext fxMesa = FX_CONTEXT(ctx); \
645 GLfloat color[n][4], spec[n][4]; \
646 (void) color; (void) spec;
647 #endif /* !FX_PACKEDCOLOR */
650 /***********************************************************************
652 ***********************************************************************/
653 #define SETUP_STENCIL(f) if (f) fxSetupStencilFace(ctx, f)
654 #define UNSET_STENCIL(f) if (f) fxSetupStencil(ctx)
657 /***********************************************************************
658 * Functions to draw basic unfilled primitives *
659 ***********************************************************************/
661 #define RASTERIZE(x) if (fxMesa->raster_primitive != reduced_prim[x]) \
662 fxRasterPrimitive( ctx, reduced_prim[x] )
663 #define RENDER_PRIMITIVE fxMesa->render_primitive
664 #define IND FX_FALLBACK_BIT
666 #include "tnl_dd/t_dd_unfilled.h"
669 /***********************************************************************
670 * Functions to draw GL primitives *
671 ***********************************************************************/
675 #include "tnl_dd/t_dd_tritmp.h"
677 #define IND (FX_OFFSET_BIT)
678 #define TAG(x) x##_offset
679 #include "tnl_dd/t_dd_tritmp.h"
681 #define IND (FX_TWOSIDE_BIT)
682 #define TAG(x) x##_twoside
683 #include "tnl_dd/t_dd_tritmp.h"
685 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT)
686 #define TAG(x) x##_twoside_offset
687 #include "tnl_dd/t_dd_tritmp.h"
689 #define IND (FX_UNFILLED_BIT)
690 #define TAG(x) x##_unfilled
691 #include "tnl_dd/t_dd_tritmp.h"
693 #define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT)
694 #define TAG(x) x##_offset_unfilled
695 #include "tnl_dd/t_dd_tritmp.h"
697 #define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT)
698 #define TAG(x) x##_twoside_unfilled
699 #include "tnl_dd/t_dd_tritmp.h"
701 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT)
702 #define TAG(x) x##_twoside_offset_unfilled
703 #include "tnl_dd/t_dd_tritmp.h"
705 #define IND (FX_FALLBACK_BIT)
706 #define TAG(x) x##_fallback
707 #include "tnl_dd/t_dd_tritmp.h"
709 #define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT)
710 #define TAG(x) x##_offset_fallback
711 #include "tnl_dd/t_dd_tritmp.h"
713 #define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT)
714 #define TAG(x) x##_twoside_fallback
715 #include "tnl_dd/t_dd_tritmp.h"
717 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT)
718 #define TAG(x) x##_twoside_offset_fallback
719 #include "tnl_dd/t_dd_tritmp.h"
721 #define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT)
722 #define TAG(x) x##_unfilled_fallback
723 #include "tnl_dd/t_dd_tritmp.h"
725 #define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT)
726 #define TAG(x) x##_offset_unfilled_fallback
727 #include "tnl_dd/t_dd_tritmp.h"
729 #define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT)
730 #define TAG(x) x##_twoside_unfilled_fallback
731 #include "tnl_dd/t_dd_tritmp.h"
733 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \
735 #define TAG(x) x##_twoside_offset_unfilled_fallback
736 #include "tnl_dd/t_dd_tritmp.h"
739 /* Fx doesn't support provoking-vertex flat-shading?
741 #define IND (FX_FLAT_BIT)
742 #define TAG(x) x##_flat
743 #include "tnl_dd/t_dd_tritmp.h"
745 #define IND (FX_OFFSET_BIT|FX_FLAT_BIT)
746 #define TAG(x) x##_offset_flat
747 #include "tnl_dd/t_dd_tritmp.h"
749 #define IND (FX_TWOSIDE_BIT|FX_FLAT_BIT)
750 #define TAG(x) x##_twoside_flat
751 #include "tnl_dd/t_dd_tritmp.h"
753 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FLAT_BIT)
754 #define TAG(x) x##_twoside_offset_flat
755 #include "tnl_dd/t_dd_tritmp.h"
757 #define IND (FX_UNFILLED_BIT|FX_FLAT_BIT)
758 #define TAG(x) x##_unfilled_flat
759 #include "tnl_dd/t_dd_tritmp.h"
761 #define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT)
762 #define TAG(x) x##_offset_unfilled_flat
763 #include "tnl_dd/t_dd_tritmp.h"
765 #define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT)
766 #define TAG(x) x##_twoside_unfilled_flat
767 #include "tnl_dd/t_dd_tritmp.h"
769 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT)
770 #define TAG(x) x##_twoside_offset_unfilled_flat
771 #include "tnl_dd/t_dd_tritmp.h"
773 #define IND (FX_FALLBACK_BIT|FX_FLAT_BIT)
774 #define TAG(x) x##_fallback_flat
775 #include "tnl_dd/t_dd_tritmp.h"
777 #define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT)
778 #define TAG(x) x##_offset_fallback_flat
779 #include "tnl_dd/t_dd_tritmp.h"
781 #define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT)
782 #define TAG(x) x##_twoside_fallback_flat
783 #include "tnl_dd/t_dd_tritmp.h"
785 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT)
786 #define TAG(x) x##_twoside_offset_fallback_flat
787 #include "tnl_dd/t_dd_tritmp.h"
789 #define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT)
790 #define TAG(x) x##_unfilled_fallback_flat
791 #include "tnl_dd/t_dd_tritmp.h"
793 #define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT)
794 #define TAG(x) x##_offset_unfilled_fallback_flat
795 #include "tnl_dd/t_dd_tritmp.h"
797 #define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT)
798 #define TAG(x) x##_twoside_unfilled_fallback_flat
799 #include "tnl_dd/t_dd_tritmp.h"
801 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \
802 FX_FALLBACK_BIT|FX_FLAT_BIT)
803 #define TAG(x) x##_twoside_offset_unfilled_fallback_flat
804 #include "tnl_dd/t_dd_tritmp.h"
807 /* 2-sided stencil begin */
808 #define IND (FX_TWOSTENCIL_BIT)
809 #define TAG(x) x##_twostencil
810 #include "tnl_dd/t_dd_tritmp.h"
812 #define IND (FX_OFFSET_BIT|FX_TWOSTENCIL_BIT)
813 #define TAG(x) x##_offset_twostencil
814 #include "tnl_dd/t_dd_tritmp.h"
816 #define IND (FX_TWOSIDE_BIT|FX_TWOSTENCIL_BIT)
817 #define TAG(x) x##_twoside_twostencil
818 #include "tnl_dd/t_dd_tritmp.h"
820 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_TWOSTENCIL_BIT)
821 #define TAG(x) x##_twoside_offset_twostencil
822 #include "tnl_dd/t_dd_tritmp.h"
824 #define IND (FX_UNFILLED_BIT|FX_TWOSTENCIL_BIT)
825 #define TAG(x) x##_unfilled_twostencil
826 #include "tnl_dd/t_dd_tritmp.h"
828 #define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_TWOSTENCIL_BIT)
829 #define TAG(x) x##_offset_unfilled_twostencil
830 #include "tnl_dd/t_dd_tritmp.h"
832 #define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_TWOSTENCIL_BIT)
833 #define TAG(x) x##_twoside_unfilled_twostencil
834 #include "tnl_dd/t_dd_tritmp.h"
836 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_TWOSTENCIL_BIT)
837 #define TAG(x) x##_twoside_offset_unfilled_twostencil
838 #include "tnl_dd/t_dd_tritmp.h"
840 #define IND (FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT)
841 #define TAG(x) x##_fallback_twostencil
842 #include "tnl_dd/t_dd_tritmp.h"
844 #define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT)
845 #define TAG(x) x##_offset_fallback_twostencil
846 #include "tnl_dd/t_dd_tritmp.h"
848 #define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT)
849 #define TAG(x) x##_twoside_fallback_twostencil
850 #include "tnl_dd/t_dd_tritmp.h"
852 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT)
853 #define TAG(x) x##_twoside_offset_fallback_twostencil
854 #include "tnl_dd/t_dd_tritmp.h"
856 #define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT)
857 #define TAG(x) x##_unfilled_fallback_twostencil
858 #include "tnl_dd/t_dd_tritmp.h"
860 #define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT)
861 #define TAG(x) x##_offset_unfilled_fallback_twostencil
862 #include "tnl_dd/t_dd_tritmp.h"
864 #define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT)
865 #define TAG(x) x##_twoside_unfilled_fallback_twostencil
866 #include "tnl_dd/t_dd_tritmp.h"
868 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \
869 FX_FALLBACK_BIT|FX_TWOSTENCIL_BIT)
870 #define TAG(x) x##_twoside_offset_unfilled_fallback_twostencil
871 #include "tnl_dd/t_dd_tritmp.h"
874 /* Fx doesn't support provoking-vertex flat-shading?
876 #define IND (FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
877 #define TAG(x) x##_flat_twostencil
878 #include "tnl_dd/t_dd_tritmp.h"
880 #define IND (FX_OFFSET_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
881 #define TAG(x) x##_offset_flat_twostencil
882 #include "tnl_dd/t_dd_tritmp.h"
884 #define IND (FX_TWOSIDE_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
885 #define TAG(x) x##_twoside_flat_twostencil
886 #include "tnl_dd/t_dd_tritmp.h"
888 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
889 #define TAG(x) x##_twoside_offset_flat_twostencil
890 #include "tnl_dd/t_dd_tritmp.h"
892 #define IND (FX_UNFILLED_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
893 #define TAG(x) x##_unfilled_flat_twostencil
894 #include "tnl_dd/t_dd_tritmp.h"
896 #define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
897 #define TAG(x) x##_offset_unfilled_flat_twostencil
898 #include "tnl_dd/t_dd_tritmp.h"
900 #define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
901 #define TAG(x) x##_twoside_unfilled_flat_twostencil
902 #include "tnl_dd/t_dd_tritmp.h"
904 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
905 #define TAG(x) x##_twoside_offset_unfilled_flat_twostencil
906 #include "tnl_dd/t_dd_tritmp.h"
908 #define IND (FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
909 #define TAG(x) x##_fallback_flat_twostencil
910 #include "tnl_dd/t_dd_tritmp.h"
912 #define IND (FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
913 #define TAG(x) x##_offset_fallback_flat_twostencil
914 #include "tnl_dd/t_dd_tritmp.h"
916 #define IND (FX_TWOSIDE_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
917 #define TAG(x) x##_twoside_fallback_flat_twostencil
918 #include "tnl_dd/t_dd_tritmp.h"
920 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
921 #define TAG(x) x##_twoside_offset_fallback_flat_twostencil
922 #include "tnl_dd/t_dd_tritmp.h"
924 #define IND (FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
925 #define TAG(x) x##_unfilled_fallback_flat_twostencil
926 #include "tnl_dd/t_dd_tritmp.h"
928 #define IND (FX_OFFSET_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
929 #define TAG(x) x##_offset_unfilled_fallback_flat_twostencil
930 #include "tnl_dd/t_dd_tritmp.h"
932 #define IND (FX_TWOSIDE_BIT|FX_UNFILLED_BIT|FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
933 #define TAG(x) x##_twoside_unfilled_fallback_flat_twostencil
934 #include "tnl_dd/t_dd_tritmp.h"
936 #define IND (FX_TWOSIDE_BIT|FX_OFFSET_BIT|FX_UNFILLED_BIT| \
937 FX_FALLBACK_BIT|FX_FLAT_BIT|FX_TWOSTENCIL_BIT)
938 #define TAG(x) x##_twoside_offset_unfilled_fallback_flat_twostencil
939 #include "tnl_dd/t_dd_tritmp.h"
940 /* 2-sided stencil end */
943 static void init_rast_tab( void )
948 init_twoside_offset();
950 init_offset_unfilled();
951 init_twoside_unfilled();
952 init_twoside_offset_unfilled();
954 init_offset_fallback();
955 init_twoside_fallback();
956 init_twoside_offset_fallback();
957 init_unfilled_fallback();
958 init_offset_unfilled_fallback();
959 init_twoside_unfilled_fallback();
960 init_twoside_offset_unfilled_fallback();
965 init_twoside_offset_flat();
966 init_unfilled_flat();
967 init_offset_unfilled_flat();
968 init_twoside_unfilled_flat();
969 init_twoside_offset_unfilled_flat();
970 init_fallback_flat();
971 init_offset_fallback_flat();
972 init_twoside_fallback_flat();
973 init_twoside_offset_fallback_flat();
974 init_unfilled_fallback_flat();
975 init_offset_unfilled_fallback_flat();
976 init_twoside_unfilled_fallback_flat();
977 init_twoside_offset_unfilled_fallback_flat();
979 /* 2-sided stencil begin */
981 init_offset_twostencil();
982 init_twoside_twostencil();
983 init_twoside_offset_twostencil();
984 init_unfilled_twostencil();
985 init_offset_unfilled_twostencil();
986 init_twoside_unfilled_twostencil();
987 init_twoside_offset_unfilled_twostencil();
988 init_fallback_twostencil();
989 init_offset_fallback_twostencil();
990 init_twoside_fallback_twostencil();
991 init_twoside_offset_fallback_twostencil();
992 init_unfilled_fallback_twostencil();
993 init_offset_unfilled_fallback_twostencil();
994 init_twoside_unfilled_fallback_twostencil();
995 init_twoside_offset_unfilled_fallback_twostencil();
997 init_flat_twostencil();
998 init_offset_flat_twostencil();
999 init_twoside_flat_twostencil();
1000 init_twoside_offset_flat_twostencil();
1001 init_unfilled_flat_twostencil();
1002 init_offset_unfilled_flat_twostencil();
1003 init_twoside_unfilled_flat_twostencil();
1004 init_twoside_offset_unfilled_flat_twostencil();
1005 init_fallback_flat_twostencil();
1006 init_offset_fallback_flat_twostencil();
1007 init_twoside_fallback_flat_twostencil();
1008 init_twoside_offset_fallback_flat_twostencil();
1009 init_unfilled_fallback_flat_twostencil();
1010 init_offset_unfilled_fallback_flat_twostencil();
1011 init_twoside_unfilled_fallback_flat_twostencil();
1012 init_twoside_offset_unfilled_fallback_flat_twostencil();
1013 /* 2-sided stencil end */
1017 /**********************************************************************/
1018 /* Render whole begin/end objects */
1019 /**********************************************************************/
1022 /* Accelerate vertex buffer rendering when renderindex == 0 and
1023 * there is no clipping.
1025 #define INIT(x) fxRenderPrimitive( ctx, x )
1027 static void fx_render_vb_points( GLcontext
*ctx
,
1032 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1033 GrVertex
*fxVB
= fxMesa
->verts
;
1037 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1038 fprintf(stderr
, "fx_render_vb_points\n");
1043 /* Adjust point coords */
1044 for (i
= start
; i
< count
; i
++) {
1045 fxVB
[i
].x
+= PNT_X_OFFSET
- TRI_X_OFFSET
;
1046 fxVB
[i
].y
+= PNT_Y_OFFSET
- TRI_Y_OFFSET
;
1049 grDrawVertexArrayContiguous( GR_POINTS
, count
-start
,
1050 fxVB
+ start
, sizeof(GrVertex
));
1051 /* restore point coords */
1052 for (i
= start
; i
< count
; i
++) {
1053 fxVB
[i
].x
-= PNT_X_OFFSET
- TRI_X_OFFSET
;
1054 fxVB
[i
].y
-= PNT_Y_OFFSET
- TRI_Y_OFFSET
;
1058 static void fx_render_vb_line_strip( GLcontext
*ctx
,
1063 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1064 GrVertex
*fxVB
= fxMesa
->verts
;
1068 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1069 fprintf(stderr
, "fx_render_vb_line_strip\n");
1072 INIT(GL_LINE_STRIP
);
1074 /* adjust line coords */
1075 for (i
= start
; i
< count
; i
++) {
1076 fxVB
[i
].x
+= LINE_X_OFFSET
- TRI_X_OFFSET
;
1077 fxVB
[i
].y
+= LINE_Y_OFFSET
- TRI_Y_OFFSET
;
1080 grDrawVertexArrayContiguous( GR_LINE_STRIP
, count
-start
,
1081 fxVB
+ start
, sizeof(GrVertex
));
1083 /* restore line coords */
1084 for (i
= start
; i
< count
; i
++) {
1085 fxVB
[i
].x
-= LINE_X_OFFSET
- TRI_X_OFFSET
;
1086 fxVB
[i
].y
-= LINE_Y_OFFSET
- TRI_Y_OFFSET
;
1090 static void fx_render_vb_line_loop( GLcontext
*ctx
,
1095 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1096 GrVertex
*fxVB
= fxMesa
->verts
;
1101 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1102 fprintf(stderr
, "fx_render_vb_line_loop\n");
1107 if (!(flags
& PRIM_BEGIN
)) {
1111 /* adjust line coords */
1112 for (i
= start
; i
< count
; i
++) {
1113 fxVB
[i
].x
+= LINE_X_OFFSET
- TRI_X_OFFSET
;
1114 fxVB
[i
].y
+= LINE_Y_OFFSET
- TRI_Y_OFFSET
;
1117 grDrawVertexArrayContiguous( GR_LINE_STRIP
, count
-j
,
1118 fxVB
+ j
, sizeof(GrVertex
));
1120 if (flags
& PRIM_END
)
1121 grDrawLine( fxVB
+ (count
- 1),
1124 /* restore line coords */
1125 for (i
= start
; i
< count
; i
++) {
1126 fxVB
[i
].x
-= LINE_X_OFFSET
- TRI_X_OFFSET
;
1127 fxVB
[i
].y
-= LINE_Y_OFFSET
- TRI_Y_OFFSET
;
1131 static void fx_render_vb_lines( GLcontext
*ctx
,
1136 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1137 GrVertex
*fxVB
= fxMesa
->verts
;
1141 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1142 fprintf(stderr
, "fx_render_vb_lines\n");
1147 /* adjust line coords */
1148 for (i
= start
; i
< count
; i
++) {
1149 fxVB
[i
].x
+= LINE_X_OFFSET
- TRI_X_OFFSET
;
1150 fxVB
[i
].y
+= LINE_Y_OFFSET
- TRI_Y_OFFSET
;
1153 grDrawVertexArrayContiguous( GR_LINES
, count
-start
,
1154 fxVB
+ start
, sizeof(GrVertex
));
1156 /* restore line coords */
1157 for (i
= start
; i
< count
; i
++) {
1158 fxVB
[i
].x
-= LINE_X_OFFSET
- TRI_X_OFFSET
;
1159 fxVB
[i
].y
-= LINE_Y_OFFSET
- TRI_Y_OFFSET
;
1163 static void fx_render_vb_triangles( GLcontext
*ctx
,
1168 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1169 GrVertex
*fxVB
= fxMesa
->verts
;
1173 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1174 fprintf(stderr
, "fx_render_vb_triangles\n");
1179 for (j
=start
+2; j
<count
; j
+=3) {
1180 grDrawTriangle(fxVB
+ (j
-2), fxVB
+ (j
-1), fxVB
+ j
);
1185 static void fx_render_vb_tri_strip( GLcontext
*ctx
,
1190 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1191 GrVertex
*fxVB
= fxMesa
->verts
;
1194 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1195 fprintf(stderr
, "fx_render_vb_tri_strip\n");
1198 INIT(GL_TRIANGLE_STRIP
);
1200 /* no GR_TRIANGLE_STRIP_CONTINUE?!? */
1202 grDrawVertexArrayContiguous( GR_TRIANGLE_STRIP
, count
-start
,
1203 fxVB
+ start
, sizeof(GrVertex
));
1207 static void fx_render_vb_tri_fan( GLcontext
*ctx
,
1212 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1213 GrVertex
*fxVB
= fxMesa
->verts
;
1216 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1217 fprintf(stderr
, "fx_render_vb_tri_fan\n");
1220 INIT(GL_TRIANGLE_FAN
);
1222 grDrawVertexArrayContiguous( GR_TRIANGLE_FAN
, count
-start
,
1223 fxVB
+ start
, sizeof(GrVertex
) );
1226 static void fx_render_vb_quads( GLcontext
*ctx
,
1231 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1232 GrVertex
*fxVB
= fxMesa
->verts
;
1236 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1237 fprintf(stderr
, "fx_render_vb_quads\n");
1242 for (i
= start
+ 3 ; i
< count
; i
+= 4 ) {
1243 #define VERT(x) (fxVB + (x))
1249 grDrawVertexArray(GR_TRIANGLE_FAN
, 4, _v_
);
1250 /*grDrawTriangle( VERT(i-3), VERT(i-2), VERT(i) );*/
1251 /*grDrawTriangle( VERT(i-2), VERT(i-1), VERT(i) );*/
1256 static void fx_render_vb_quad_strip( GLcontext
*ctx
,
1261 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1262 GrVertex
*fxVB
= fxMesa
->verts
;
1265 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1266 fprintf(stderr
, "fx_render_vb_quad_strip\n");
1269 INIT(GL_QUAD_STRIP
);
1271 count
-= (count
-start
)&1;
1273 grDrawVertexArrayContiguous( GR_TRIANGLE_STRIP
,
1274 count
-start
, fxVB
+ start
, sizeof(GrVertex
));
1277 static void fx_render_vb_poly( GLcontext
*ctx
,
1282 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1283 GrVertex
*fxVB
= fxMesa
->verts
;
1286 if (TDFX_DEBUG
& VERBOSE_VARRAY
) {
1287 fprintf(stderr
, "fx_render_vb_poly\n");
1292 grDrawVertexArrayContiguous( GR_POLYGON
, count
-start
,
1293 fxVB
+ start
, sizeof(GrVertex
));
1296 static void fx_render_vb_noop( GLcontext
*ctx
,
1301 (void) (ctx
&& start
&& count
&& flags
);
1304 static void (*fx_render_tab_verts
[GL_POLYGON
+2])(GLcontext
*,
1309 fx_render_vb_points
,
1311 fx_render_vb_line_loop
,
1312 fx_render_vb_line_strip
,
1313 fx_render_vb_triangles
,
1314 fx_render_vb_tri_strip
,
1315 fx_render_vb_tri_fan
,
1317 fx_render_vb_quad_strip
,
1324 /**********************************************************************/
1325 /* Render whole (indexed) begin/end objects */
1326 /**********************************************************************/
1329 #define VERT(x) (vertptr + x)
1331 #define RENDER_POINTS( start, count ) \
1332 for ( ; start < count ; start++) \
1333 grDrawPoint( VERT(ELT(start)) );
1335 #define RENDER_LINE( v0, v1 ) \
1336 grDrawLine( VERT(v0), VERT(v1) )
1338 #define RENDER_TRI( v0, v1, v2 ) \
1339 grDrawTriangle( VERT(v0), VERT(v1), VERT(v2) )
1341 #define RENDER_QUAD( v0, v1, v2, v3 ) \
1348 grDrawVertexArray(GR_TRIANGLE_FAN, 4, _v_);\
1349 /*grDrawTriangle( VERT(v0), VERT(v1), VERT(v3) );*/\
1350 /*grDrawTriangle( VERT(v1), VERT(v2), VERT(v3) );*/\
1353 #define INIT(x) fxRenderPrimitive( ctx, x )
1356 #define LOCAL_VARS \
1357 fxMesaContext fxMesa = FX_CONTEXT(ctx); \
1358 GrVertex *vertptr = fxMesa->verts; \
1359 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
1362 #define RESET_STIPPLE
1363 #define RESET_OCCLUSION
1364 #define PRESERVE_VB_DEFS
1366 /* Elts, no clipping.
1370 #define TAG(x) fx_##x##_elts
1371 #define ELT(x) elt[x]
1372 #include "tnl_dd/t_dd_rendertmp.h"
1374 /* Verts, no clipping.
1378 #define TAG(x) fx_##x##_verts
1380 /*#include "tnl_dd/t_dd_rendertmp.h"*/ /* we have fx_render_vb_* now */
1384 /**********************************************************************/
1385 /* Render clipped primitives */
1386 /**********************************************************************/
1390 static void fxRenderClippedPoly( GLcontext
*ctx
, const GLuint
*elts
,
1393 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1394 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1395 struct vertex_buffer
*VB
= &tnl
->vb
;
1396 GLuint prim
= fxMesa
->render_primitive
;
1398 /* Render the new vertices as an unclipped polygon.
1401 GLuint
*tmp
= VB
->Elts
;
1402 VB
->Elts
= (GLuint
*)elts
;
1403 tnl
->Driver
.Render
.PrimTabElts
[GL_POLYGON
]( ctx
, 0, n
,
1404 PRIM_BEGIN
|PRIM_END
);
1408 /* Restore the render primitive
1410 if (prim
!= GL_POLYGON
)
1411 tnl
->Driver
.Render
.PrimitiveNotify( ctx
, prim
);
1415 static void fxFastRenderClippedPoly( GLcontext
*ctx
, const GLuint
*elts
,
1419 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
1420 GrVertex
*vertptr
= fxMesa
->verts
;
1422 grDrawTriangle( VERT(elts
[0]), VERT(elts
[1]), VERT(elts
[2]) );
1423 } else if (n
<= 32) {
1424 GrVertex
*newvptr
[32];
1425 for (i
= 0 ; i
< n
; i
++) {
1426 newvptr
[i
] = VERT(elts
[i
]);
1428 grDrawVertexArray(GR_TRIANGLE_FAN
, n
, newvptr
);
1430 const GrVertex
*start
= VERT(elts
[0]);
1431 for (i
= 2 ; i
< n
; i
++) {
1432 grDrawTriangle( start
, VERT(elts
[i
-1]), VERT(elts
[i
]) );
1437 /**********************************************************************/
1438 /* Choose render functions */
1439 /**********************************************************************/
1442 #define POINT_FALLBACK (DD_POINT_SMOOTH)
1443 #define LINE_FALLBACK (DD_LINE_STIPPLE)
1444 #define TRI_FALLBACK (DD_TRI_SMOOTH | DD_TRI_STIPPLE)
1445 #define ANY_FALLBACK_FLAGS (POINT_FALLBACK | LINE_FALLBACK | TRI_FALLBACK)
1446 #define ANY_RASTER_FLAGS (DD_FLATSHADE | DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET \
1447 | DD_TRI_UNFILLED | DD_TRI_TWOSTENCIL)
1451 void fxDDChooseRenderState(GLcontext
*ctx
)
1453 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1454 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1455 GLuint flags
= ctx
->_TriangleCaps
;
1458 if (flags
& (ANY_FALLBACK_FLAGS
|ANY_RASTER_FLAGS
)) {
1459 if (flags
& ANY_RASTER_FLAGS
) {
1460 if (flags
& DD_TRI_TWOSTENCIL
) index
|= FX_TWOSTENCIL_BIT
;
1461 if (flags
& DD_TRI_LIGHT_TWOSIDE
) index
|= FX_TWOSIDE_BIT
;
1462 if (flags
& DD_TRI_OFFSET
) index
|= FX_OFFSET_BIT
;
1463 if (flags
& DD_TRI_UNFILLED
) index
|= FX_UNFILLED_BIT
;
1464 if (flags
& DD_FLATSHADE
) index
|= FX_FLAT_BIT
;
1467 fxMesa
->draw_point
= fx_draw_point
;
1468 fxMesa
->draw_line
= fx_draw_line
;
1469 fxMesa
->draw_tri
= fx_draw_triangle
;
1471 /* Hook in fallbacks for specific primitives. */
1472 if (flags
& (POINT_FALLBACK
|
1476 if (fxMesa
->verbose
) {
1477 fprintf(stderr
, "Voodoo ! fallback (%x), raster (%x)\n",
1478 flags
& ANY_FALLBACK_FLAGS
, flags
& ANY_RASTER_FLAGS
);
1481 if (flags
& POINT_FALLBACK
)
1482 fxMesa
->draw_point
= fx_fallback_point
;
1484 if (flags
& LINE_FALLBACK
)
1485 fxMesa
->draw_line
= fx_fallback_line
;
1487 if (flags
& TRI_FALLBACK
)
1488 fxMesa
->draw_tri
= fx_fallback_tri
;
1490 index
|= FX_FALLBACK_BIT
;
1494 tnl
->Driver
.Render
.Points
= rast_tab
[index
].points
;
1495 tnl
->Driver
.Render
.Line
= rast_tab
[index
].line
;
1496 tnl
->Driver
.Render
.ClippedLine
= rast_tab
[index
].line
;
1497 tnl
->Driver
.Render
.Triangle
= rast_tab
[index
].triangle
;
1498 tnl
->Driver
.Render
.Quad
= rast_tab
[index
].quad
;
1501 tnl
->Driver
.Render
.PrimTabVerts
= fx_render_tab_verts
;
1502 tnl
->Driver
.Render
.PrimTabElts
= fx_render_tab_elts
;
1503 tnl
->Driver
.Render
.ClippedPolygon
= fxFastRenderClippedPoly
;
1505 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
1506 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
1507 tnl
->Driver
.Render
.ClippedPolygon
= fxRenderClippedPoly
;
1510 fxMesa
->render_index
= index
;
1512 /* [dBorca] Hack alert: more a trick than a real plug-in!!! */
1513 if (flags
& (DD_POINT_SIZE
| DD_POINT_ATTEN
)) {
1514 /* We need to set the point primitive to go through "rast_tab",
1515 * to make sure "POINT" calls "fxMesa->draw_point" instead of
1516 * "grDrawPoint". We can achieve this by using FX_FALLBACK_BIT
1517 * (not really a total rasterization fallback, so we don't alter
1518 * "fxMesa->render_index"). If we get here with DD_POINT_SMOOTH,
1519 * we're done, cos we've already set _tnl_render_tab_{verts|elts}
1520 * above. Otherwise, the T&L engine can optimize point rendering
1521 * by using fx_render_tab_{verts|elts} hence the extra work.
1523 if (flags
& DD_POINT_SMOOTH
) {
1524 fxMesa
->draw_point
= fx_draw_point_wide_aa
;
1526 fxMesa
->draw_point
= fx_draw_point_wide
;
1527 fx_render_tab_verts
[0] = fx_render_pw_verts
;
1528 fx_render_tab_elts
[0] = fx_render_pw_elts
;
1530 tnl
->Driver
.Render
.Points
= rast_tab
[index
|FX_FALLBACK_BIT
].points
;
1532 fx_render_tab_verts
[0] = fx_render_vb_points
;
1533 fx_render_tab_elts
[0] = fx_render_points_elts
;
1538 /**********************************************************************/
1539 /* Runtime render state and callbacks */
1540 /**********************************************************************/
1542 static void fxRunPipeline( GLcontext
*ctx
)
1544 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1545 GLuint new_gl_state
= fxMesa
->new_gl_state
;
1547 if (TDFX_DEBUG
& VERBOSE_PIPELINE
) {
1548 fprintf(stderr
, "fxRunPipeline()\n");
1552 /* Recalculate fog table on projection matrix changes. This used to
1553 * be triggered by the NearFar callback.
1555 if (new_gl_state
& _NEW_PROJECTION
)
1556 fxMesa
->new_state
|= FX_NEW_FOG
;
1559 if (new_gl_state
& _FX_NEW_IS_IN_HARDWARE
)
1560 fxCheckIsInHardware(ctx
);
1562 if (fxMesa
->new_state
)
1563 fxSetupFXUnits(ctx
);
1565 if (!fxMesa
->fallback
) {
1566 if (new_gl_state
& _FX_NEW_RENDERSTATE
)
1567 fxDDChooseRenderState(ctx
);
1569 if (new_gl_state
& _FX_NEW_SETUP_FUNCTION
)
1570 fxChooseVertexState(ctx
);
1573 if (new_gl_state
& _NEW_TEXTURE
) {
1574 struct gl_texture_unit
*t0
= &ctx
->Texture
.Unit
[fxMesa
->tmu_source
[0]];
1575 struct gl_texture_unit
*t1
= &ctx
->Texture
.Unit
[fxMesa
->tmu_source
[1]];
1577 if (t0
->_Current
&& FX_TEXTURE_DATA(t0
)) {
1578 fxMesa
->s0scale
= FX_TEXTURE_DATA(t0
)->sScale
;
1579 fxMesa
->t0scale
= FX_TEXTURE_DATA(t0
)->tScale
;
1580 fxMesa
->inv_s0scale
= 1.0F
/ fxMesa
->s0scale
;
1581 fxMesa
->inv_t0scale
= 1.0F
/ fxMesa
->t0scale
;
1584 if (t1
->_Current
&& FX_TEXTURE_DATA(t1
)) {
1585 fxMesa
->s1scale
= FX_TEXTURE_DATA(t1
)->sScale
;
1586 fxMesa
->t1scale
= FX_TEXTURE_DATA(t1
)->tScale
;
1587 fxMesa
->inv_s1scale
= 1.0F
/ fxMesa
->s1scale
;
1588 fxMesa
->inv_t1scale
= 1.0F
/ fxMesa
->t1scale
;
1592 fxMesa
->new_gl_state
= 0;
1594 _tnl_run_pipeline( ctx
);
1599 /* Always called between RenderStart and RenderFinish --> We already
1602 static void fxRasterPrimitive( GLcontext
*ctx
, GLenum prim
)
1604 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
1606 fxMesa
->raster_primitive
= prim
;
1613 /* Determine the rasterized primitive when not drawing unfilled
1616 static void fxRenderPrimitive( GLcontext
*ctx
, GLenum prim
)
1618 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1619 GLuint rprim
= reduced_prim
[prim
];
1621 fxMesa
->render_primitive
= prim
;
1623 if (rprim
== GL_TRIANGLES
&& (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
))
1626 if (fxMesa
->raster_primitive
!= rprim
) {
1627 fxRasterPrimitive( ctx
, rprim
);
1631 static void fxRenderFinish( GLcontext
*ctx
)
1633 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1635 if (fxMesa
->render_index
& FX_FALLBACK_BIT
)
1636 _swrast_flush( ctx
);
1641 /**********************************************************************/
1642 /* Manage total rasterization fallbacks */
1643 /**********************************************************************/
1645 static char *fallbackStrings
[] = {
1646 "3D/Rect/Cube Texture map",
1647 "glDrawBuffer(GL_FRONT_AND_BACK)",
1648 "Separate specular color",
1649 "glEnable/Disable(GL_STENCIL_TEST)",
1650 "glRenderMode(selection or feedback)",
1660 static char *getFallbackString(GLuint bit
)
1667 return fallbackStrings
[i
];
1671 void fxCheckIsInHardware( GLcontext
*ctx
)
1673 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1674 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1675 GLuint oldfallback
= fxMesa
->fallback
;
1676 GLuint newfallback
= fxMesa
->fallback
= fx_check_IsInHardware( ctx
);
1679 if (oldfallback
== 0) {
1680 if (fxMesa
->verbose
) {
1681 fprintf(stderr
, "Voodoo ! enter SW 0x%08x %s\n", newfallback
, getFallbackString(newfallback
));
1683 _swsetup_Wakeup( ctx
);
1688 _swrast_flush( ctx
);
1689 tnl
->Driver
.Render
.Start
= fxCheckTexSizes
;
1690 tnl
->Driver
.Render
.Finish
= fxRenderFinish
;
1691 tnl
->Driver
.Render
.PrimitiveNotify
= fxRenderPrimitive
;
1692 tnl
->Driver
.Render
.ClippedPolygon
= _tnl_RenderClippedPolygon
;
1693 tnl
->Driver
.Render
.ClippedLine
= _tnl_RenderClippedLine
;
1694 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
1695 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
1696 tnl
->Driver
.Render
.ResetLineStipple
= _swrast_ResetLineStipple
;
1697 tnl
->Driver
.Render
.BuildVertices
= fxBuildVertices
;
1698 fxChooseVertexState(ctx
);
1699 fxDDChooseRenderState(ctx
);
1700 if (fxMesa
->verbose
) {
1701 fprintf(stderr
, "Voodoo ! leave SW 0x%08x %s\n", oldfallback
, getFallbackString(oldfallback
));
1704 tnl
->Driver
.Render
.Multipass
= NULL
;
1705 if (HAVE_SPEC
&& NEED_SECONDARY_COLOR(ctx
)) {
1706 tnl
->Driver
.Render
.Multipass
= fxMultipass_ColorSum
;
1707 /* obey stencil, but do not change it */
1708 fxMesa
->multipass
= GL_TRUE
;
1709 if (fxMesa
->unitsState
.stencilEnabled
) {
1710 fxMesa
->new_state
|= FX_NEW_STENCIL
;
1716 void fxDDInitTriFuncs( GLcontext
*ctx
)
1718 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
1719 static int firsttime
= 1;
1726 tnl
->Driver
.RunPipeline
= fxRunPipeline
;
1727 tnl
->Driver
.Render
.Start
= fxCheckTexSizes
;
1728 tnl
->Driver
.Render
.Finish
= fxRenderFinish
;
1729 tnl
->Driver
.Render
.PrimitiveNotify
= fxRenderPrimitive
;
1730 tnl
->Driver
.Render
.ClippedPolygon
= _tnl_RenderClippedPolygon
;
1731 tnl
->Driver
.Render
.ClippedLine
= _tnl_RenderClippedLine
;
1732 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
1733 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
1734 tnl
->Driver
.Render
.ResetLineStipple
= _swrast_ResetLineStipple
;
1735 tnl
->Driver
.Render
.BuildVertices
= fxBuildVertices
;
1736 tnl
->Driver
.Render
.Multipass
= NULL
;
1738 (void) fx_print_vertex
;
1742 /* [dBorca] Hack alert:
1743 * doesn't work with blending.
1746 fxMultipass_ColorSum (GLcontext
*ctx
, GLuint pass
)
1748 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
1749 tfxUnitsState
*us
= &fxMesa
->unitsState
;
1755 case 1: /* first pass: the TEXTURED triangles are drawn */
1756 /* set stencil's real values */
1757 fxMesa
->multipass
= GL_FALSE
;
1758 if (us
->stencilEnabled
) {
1759 fxSetupStencil(ctx
);
1761 /* save per-pass data */
1762 fxMesa
->restoreUnitsState
= *us
;
1763 /* turn off texturing */
1764 t0
= ctx
->Texture
.Unit
[0]._ReallyEnabled
;
1765 t1
= ctx
->Texture
.Unit
[1]._ReallyEnabled
;
1766 ctx
->Texture
.Unit
[0]._ReallyEnabled
= 0;
1767 ctx
->Texture
.Unit
[1]._ReallyEnabled
= 0;
1768 /* SUM the colors */
1769 fxDDBlendEquationSeparate(ctx
, GL_FUNC_ADD
, GL_FUNC_ADD
);
1770 fxDDBlendFuncSeparate(ctx
, GL_ONE
, GL_ONE
, GL_ZERO
, GL_ONE
);
1771 fxDDEnable(ctx
, GL_BLEND
, GL_TRUE
);
1772 /* make sure we draw only where we want to */
1773 if (us
->depthTestEnabled
) {
1774 switch (us
->depthTestFunc
) {
1776 fxDDDepthFunc(ctx
, GL_EQUAL
);
1781 fxDDDepthMask(ctx
, GL_FALSE
);
1783 /* switch to secondary colors */
1785 grVertexLayout(GR_PARAM_PARGB
, GR_VERTEX_PSPEC_OFFSET
<< 2, GR_PARAM_ENABLE
);
1786 #else /* !FX_PACKEDCOLOR */
1787 grVertexLayout(GR_PARAM_RGB
, GR_VERTEX_SPEC_OFFSET
<< 2, GR_PARAM_ENABLE
);
1788 #endif /* !FX_PACKEDCOLOR */
1789 /* don't advertise new state */
1790 fxMesa
->new_state
= 0;
1792 case 2: /* 2nd pass (last): the secondary color is summed over texture */
1793 /* restore original state */
1794 *us
= fxMesa
->restoreUnitsState
;
1795 /* restore texturing */
1796 ctx
->Texture
.Unit
[0]._ReallyEnabled
= t0
;
1797 ctx
->Texture
.Unit
[1]._ReallyEnabled
= t1
;
1798 /* revert to primary colors */
1800 grVertexLayout(GR_PARAM_PARGB
, GR_VERTEX_PARGB_OFFSET
<< 2, GR_PARAM_ENABLE
);
1801 #else /* !FX_PACKEDCOLOR */
1802 grVertexLayout(GR_PARAM_RGB
, GR_VERTEX_RGB_OFFSET
<< 2, GR_PARAM_ENABLE
);
1803 #endif /* !FX_PACKEDCOLOR */
1806 assert(0); /* NOTREACHED */
1809 /* update HW state */
1811 fxSetupDepthTest(ctx
);
1812 fxSetupTexture(ctx
);
1822 * Need this to provide at least one external definition.
1825 extern int gl_fx_dummy_function_tris(void);
1827 gl_fx_dummy_function_tris(void)