10 #include "swrast/swrast.h"
11 #include "swrast_setup/swrast_setup.h"
13 #include "tnl/t_context.h"
14 #include "tnl/t_pipeline.h"
27 fx_draw_point( GLcontext
*ctx
, const fxVertex
*v
)
29 GLfloat sz
= ctx
->Point
._Size
;
33 grDrawPoint( &(v
->v
) );
46 verts
[0].x
= v
->v
.x
- sz
;
47 verts
[0].y
= v
->v
.y
- sz
;
49 verts
[1].x
= v
->v
.x
+ sz
;
50 verts
[1].y
= v
->v
.y
- sz
;
52 verts
[2].x
= v
->v
.x
+ sz
;
53 verts
[2].y
= v
->v
.y
+ sz
;
55 verts
[3].x
= v
->v
.x
- sz
;
56 verts
[3].y
= v
->v
.y
+ sz
;
58 grDrawTriangle( &verts
[0], &verts
[1], &verts
[3] );
59 grDrawTriangle( &verts
[1], &verts
[2], &verts
[3] );
65 fx_draw_line( GLcontext
*ctx
, const fxVertex
*v0
, const fxVertex
*v1
)
67 float width
= ctx
->Line
.Width
;
71 grDrawLine( &(v0
->v
), &(v1
->v
) );
78 dx
= v0
->v
.x
- v1
->v
.x
;
79 dy
= v0
->v
.y
- v1
->v
.y
;
81 if (dx
* dx
> dy
* dy
) {
106 grDrawTriangle( &verts
[0], &verts
[1], &verts
[3] );
107 grDrawTriangle( &verts
[1], &verts
[2], &verts
[3] );
112 fx_draw_tri( GLcontext
*ctx
, const fxVertex
*v0
, const fxVertex
*v1
,
115 grDrawTriangle( &(v0
->v
), &(v1
->v
), &(v2
->v
) );
120 #define FX_COLOR(vert, c) { \
122 vert->v.r=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[0]); \
123 vert->v.g=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[1]); \
124 vert->v.b=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[2]); \
125 vert->v.a=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[3]); \
128 #define FX_COPY_COLOR( dst, src ) { \
129 dst->v.r = src->v.r; \
130 dst->v.g = src->v.g; \
131 dst->v.b = src->v.b; \
132 dst->v.a = src->v.a; \
137 #define FX_FLAT_BIT 0x01
138 #define FX_OFFSET_BIT 0x02
139 #define FX_TWOSIDE_BIT 0x04
140 #define FX_UNFILLED_BIT 0x10
141 #define FX_FALLBACK_BIT 0x20
142 #define FX_MAX_TRIFUNC 0x40
147 triangle_func triangle
;
149 } rast_tab
[FX_MAX_TRIFUNC
];
154 #include "fxtritmp.h"
156 #define IND (FX_FLAT_BIT)
157 #define TAG(x) x##_flat
158 #include "fxtritmp.h"
160 #define IND (FX_OFFSET_BIT)
161 #define TAG(x) x##_offset
162 #include "fxtritmp.h"
164 #define IND (FX_OFFSET_BIT | FX_FLAT_BIT)
165 #define TAG(x) x##_offset_flat
166 #include "fxtritmp.h"
168 #define IND (FX_TWOSIDE_BIT)
169 #define TAG(x) x##_twoside
170 #include "fxtritmp.h"
172 #define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT)
173 #define TAG(x) x##_twoside_flat
174 #include "fxtritmp.h"
176 #define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT)
177 #define TAG(x) x##_twoside_offset
178 #include "fxtritmp.h"
180 #define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT)
181 #define TAG(x) x##_twoside_offset_flat
182 #include "fxtritmp.h"
184 #define IND (FX_FALLBACK_BIT)
185 #define TAG(x) x##_fallback
186 #include "fxtritmp.h"
188 #define IND (FX_FLAT_BIT | FX_FALLBACK_BIT)
189 #define TAG(x) x##_flat_fallback
190 #include "fxtritmp.h"
192 #define IND (FX_OFFSET_BIT | FX_FALLBACK_BIT)
193 #define TAG(x) x##_offset_fallback
194 #include "fxtritmp.h"
196 #define IND (FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT)
197 #define TAG(x) x##_offset_flat_fallback
198 #include "fxtritmp.h"
200 #define IND (FX_TWOSIDE_BIT | FX_FALLBACK_BIT)
201 #define TAG(x) x##_twoside_fallback
202 #include "fxtritmp.h"
204 #define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT)
205 #define TAG(x) x##_twoside_flat_fallback
206 #include "fxtritmp.h"
208 #define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FALLBACK_BIT)
209 #define TAG(x) x##_twoside_offset_fallback
210 #include "fxtritmp.h"
212 #define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT)
213 #define TAG(x) x##_twoside_offset_flat_fallback
214 #include "fxtritmp.h"
216 #define IND (FX_UNFILLED_BIT)
217 #define TAG(x) x##_unfilled
218 #include "fxtritmp.h"
220 #define IND (FX_FLAT_BIT | FX_UNFILLED_BIT)
221 #define TAG(x) x##_flat_unfilled
222 #include "fxtritmp.h"
224 #define IND (FX_OFFSET_BIT | FX_UNFILLED_BIT)
225 #define TAG(x) x##_offset_unfilled
226 #include "fxtritmp.h"
228 #define IND (FX_OFFSET_BIT | FX_FLAT_BIT | FX_UNFILLED_BIT)
229 #define TAG(x) x##_offset_flat_unfilled
230 #include "fxtritmp.h"
232 #define IND (FX_TWOSIDE_BIT | FX_UNFILLED_BIT)
233 #define TAG(x) x##_twoside_unfilled
234 #include "fxtritmp.h"
236 #define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT | FX_UNFILLED_BIT)
237 #define TAG(x) x##_twoside_flat_unfilled
238 #include "fxtritmp.h"
240 #define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_UNFILLED_BIT)
241 #define TAG(x) x##_twoside_offset_unfilled
242 #include "fxtritmp.h"
244 #define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT | FX_UNFILLED_BIT)
245 #define TAG(x) x##_twoside_offset_flat_unfilled
246 #include "fxtritmp.h"
248 #define IND (FX_FALLBACK_BIT | FX_UNFILLED_BIT)
249 #define TAG(x) x##_fallback_unfilled
250 #include "fxtritmp.h"
252 #define IND (FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
253 #define TAG(x) x##_flat_fallback_unfilled
254 #include "fxtritmp.h"
256 #define IND (FX_OFFSET_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
257 #define TAG(x) x##_offset_fallback_unfilled
258 #include "fxtritmp.h"
260 #define IND (FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
261 #define TAG(x) x##_offset_flat_fallback_unfilled
262 #include "fxtritmp.h"
264 #define IND (FX_TWOSIDE_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
265 #define TAG(x) x##_twoside_fallback_unfilled
266 #include "fxtritmp.h"
268 #define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
269 #define TAG(x) x##_twoside_flat_fallback_unfilled
270 #include "fxtritmp.h"
272 #define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
273 #define TAG(x) x##_twoside_offset_fallback_unfilled
274 #include "fxtritmp.h"
276 #define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
277 #define TAG(x) x##_twoside_offset_flat_fallback_unfilled
278 #include "fxtritmp.h"
285 void fxDDTrifuncInit( void )
293 init_twoside_offset();
294 init_twoside_offset_flat();
296 init_flat_fallback();
297 init_offset_fallback();
298 init_offset_flat_fallback();
299 init_twoside_fallback();
300 init_twoside_flat_fallback();
301 init_twoside_offset_fallback();
302 init_twoside_offset_flat_fallback();
305 init_flat_unfilled();
306 init_offset_unfilled();
307 init_offset_flat_unfilled();
308 init_twoside_unfilled();
309 init_twoside_flat_unfilled();
310 init_twoside_offset_unfilled();
311 init_twoside_offset_flat_unfilled();
312 init_fallback_unfilled();
313 init_flat_fallback_unfilled();
314 init_offset_fallback_unfilled();
315 init_offset_flat_fallback_unfilled();
316 init_twoside_fallback_unfilled();
317 init_twoside_flat_fallback_unfilled();
318 init_twoside_offset_fallback_unfilled();
319 init_twoside_offset_flat_fallback_unfilled();
323 /* Build an SWvertex from a GrVertex. This is workable because in
324 * states where the GrVertex is insufficent (eg seperate-specular),
325 * the driver initiates a total fallback, and builds SWvertices
326 * directly -- it recognizes that it will never have use for the
329 * This code is hit only when a mix of accelerated and unaccelerated
330 * primitives are being drawn, and only for the unaccelerated
334 fx_translate_vertex(GLcontext
*ctx
, const fxVertex
*src
, SWvertex
*dst
)
336 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
337 GLuint ts0
= fxMesa
->tmu_source
[0];
338 GLuint ts1
= fxMesa
->tmu_source
[1];
339 GLfloat w
= 1.0 / src
->v
.oow
;
341 dst
->win
[0] = src
->v
.x
;
342 dst
->win
[1] = src
->v
.y
;
343 dst
->win
[2] = src
->v
.ooz
;
344 dst
->win
[3] = src
->v
.oow
;
346 dst
->color
[0] = (GLubyte
) src
->v
.r
;
347 dst
->color
[1] = (GLubyte
) src
->v
.g
;
348 dst
->color
[2] = (GLubyte
) src
->v
.b
;
349 dst
->color
[3] = (GLubyte
) src
->v
.a
;
351 dst
->texcoord
[ts0
][0] = fxMesa
->inv_s0scale
* src
->v
.tmuvtx
[0].sow
* w
;
352 dst
->texcoord
[ts0
][1] = fxMesa
->inv_t0scale
* src
->v
.tmuvtx
[0].tow
* w
;
354 if (fxMesa
->stw_hint_state
& GR_STWHINT_W_DIFF_TMU0
)
355 dst
->texcoord
[ts0
][3] = src
->v
.tmuvtx
[0].oow
* w
;
357 dst
->texcoord
[ts0
][3] = 1.0;
359 dst
->texcoord
[ts1
][0] = fxMesa
->inv_s1scale
* src
->v
.tmuvtx
[1].sow
* w
;
360 dst
->texcoord
[ts1
][1] = fxMesa
->inv_t1scale
* src
->v
.tmuvtx
[1].tow
* w
;
362 if (fxMesa
->stw_hint_state
& GR_STWHINT_W_DIFF_TMU1
)
363 dst
->texcoord
[ts1
][3] = src
->v
.tmuvtx
[1].oow
* w
;
365 dst
->texcoord
[ts1
][3] = 1.0;
370 fx_fallback_tri( GLcontext
*ctx
,
371 const fxVertex
*v0
, const fxVertex
*v1
, const fxVertex
*v2
)
374 fx_translate_vertex( ctx
, v0
, &v
[0] );
375 fx_translate_vertex( ctx
, v1
, &v
[1] );
376 fx_translate_vertex( ctx
, v2
, &v
[2] );
377 _swrast_Triangle( ctx
, &v
[0], &v
[1], &v
[2] );
382 fx_fallback_line( GLcontext
*ctx
, const fxVertex
*v0
, const fxVertex
*v1
)
385 fx_translate_vertex( ctx
, v0
, &v
[0] );
386 fx_translate_vertex( ctx
, v1
, &v
[1] );
387 _swrast_Line( ctx
, &v
[0], &v
[1] );
392 fx_fallback_point( GLcontext
*ctx
, const fxVertex
*v0
)
395 fx_translate_vertex( ctx
, v0
, &v
[0] );
396 _swrast_Point( ctx
, &v
[0] );
400 /* System to turn culling off for rasterized lines and points, and
401 * back on for rasterized triangles.
404 fx_cull_draw_tri( GLcontext
*ctx
,
405 const fxVertex
*v0
, const fxVertex
*v1
, const fxVertex
*v2
)
407 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
409 FX_grCullMode(fxMesa
->cullMode
);
411 fxMesa
->draw_line
= fxMesa
->initial_line
;
412 fxMesa
->draw_point
= fxMesa
->initial_point
;
413 fxMesa
->draw_tri
= fxMesa
->subsequent_tri
;
415 fxMesa
->draw_tri( ctx
, v0
, v1
, v2
);
420 fx_cull_draw_line( GLcontext
*ctx
, const fxVertex
*v0
, const fxVertex
*v1
)
422 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
424 FX_grCullMode( GR_CULL_DISABLE
);
426 fxMesa
->draw_point
= fxMesa
->initial_point
;
427 fxMesa
->draw_tri
= fxMesa
->initial_tri
;
428 fxMesa
->draw_line
= fxMesa
->subsequent_line
;
430 fxMesa
->draw_line( ctx
, v0
, v1
);
435 fx_cull_draw_point( GLcontext
*ctx
, const fxVertex
*v0
)
437 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
439 FX_grCullMode(GR_CULL_DISABLE
);
441 fxMesa
->draw_line
= fxMesa
->initial_line
;
442 fxMesa
->draw_tri
= fxMesa
->initial_tri
;
443 fxMesa
->draw_point
= fxMesa
->subsequent_point
;
445 fxMesa
->draw_point( ctx
, v0
);
450 fx_null_tri( GLcontext
*ctx
,
451 const fxVertex
*v0
, const fxVertex
*v1
, const fxVertex
*v2
)
461 /**********************************************************************/
462 /* Render whole begin/end objects */
463 /**********************************************************************/
466 /* Vertices, no clipping.
468 #define RENDER_POINTS( start, count ) \
469 for ( ; start < count ; start++) \
470 grDrawPoint( &v[ELT(start)].v );
472 #define RENDER_LINE( i1, i ) \
473 grDrawLine( &v[i1].v, &v[i].v )
475 #define RENDER_TRI( i2, i1, i ) \
476 grDrawTriangle( &v[i2].v, &v[i1].v, &v[i].v )
478 #define RENDER_QUAD( i3, i2, i1, i ) \
479 grDrawTriangle( &v[i3].v, &v[i2].v, &v[i].v ); \
480 grDrawTriangle( &v[i2].v, &v[i1].v, &v[i].v )
482 #define TAG(x) fx_##x##_verts
484 fxVertex *v = FX_CONTEXT(ctx)->verts; \
485 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
488 /* Verts, no clipping.
491 #define RESET_STIPPLE
492 #define RESET_OCCLUSION
493 #define PRESERVE_VB_DEFS
494 #include "tnl/t_vb_rendertmp.h"
497 /* Elts, no clipping.
501 #define TAG(x) fx_##x##_elts
502 #define ELT(x) elt[x]
503 #include "tnl/t_vb_rendertmp.h"
506 /**********************************************************************/
507 /* Choose render functions */
508 /**********************************************************************/
513 #define POINT_FALLBACK (DD_POINT_SMOOTH )
514 #define LINE_FALLBACK (DD_LINE_STIPPLE)
515 #define TRI_FALLBACK (DD_TRI_SMOOTH | DD_TRI_STIPPLE )
516 #define ANY_FALLBACK (POINT_FALLBACK | LINE_FALLBACK | TRI_FALLBACK)
519 #define ANY_RENDER_FLAGS (DD_FLATSHADE | \
520 DD_TRI_LIGHT_TWOSIDE | \
526 /* Setup the Point, Line, Triangle and Quad functions based on the
527 * current rendering state. Wherever possible, use the hardware to
528 * render the primitive. Otherwise, fallback to software rendering.
530 void fxDDChooseRenderState( GLcontext
*ctx
)
532 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
533 GLuint flags
= ctx
->_TriangleCaps
;
536 if ( !fxMesa
->is_in_hardware
) {
537 /* Build software vertices directly. No acceleration is
538 * possible. GrVertices may be insufficient for this mode.
540 ctx
->Driver
.PointsFunc
= _swsetup_Points
;
541 ctx
->Driver
.LineFunc
= _swsetup_Line
;
542 ctx
->Driver
.TriangleFunc
= _swsetup_Triangle
;
543 ctx
->Driver
.QuadFunc
= _swsetup_Quad
;
544 ctx
->Driver
.RenderTabVerts
= _tnl_render_tab_verts
;
545 ctx
->Driver
.RenderTabElts
= _tnl_render_tab_elts
;
547 fxMesa
->render_index
= FX_FALLBACK_BIT
;
551 if ( flags
& ANY_RENDER_FLAGS
) {
552 if ( flags
& DD_FLATSHADE
) index
|= FX_FLAT_BIT
;
553 if ( flags
& DD_TRI_LIGHT_TWOSIDE
) index
|= FX_TWOSIDE_BIT
;
554 if ( flags
& DD_TRI_OFFSET
) index
|= FX_OFFSET_BIT
;
555 if ( flags
& DD_TRI_UNFILLED
) index
|= FX_UNFILLED_BIT
;
558 if ( flags
& (ANY_FALLBACK
|
561 DD_TRI_CULL_FRONT_BACK
) ) {
563 /* Hook in fallbacks for specific primitives.
565 * Set up a system to turn culling on/off for wide points and
566 * lines. Alternately: figure out what tris to send so that
567 * culling isn't a problem.
569 * This replaces the ReducedPrimitiveChange mechanism.
571 index
|= FX_FALLBACK_BIT
;
572 fxMesa
->initial_point
= fx_cull_draw_point
;
573 fxMesa
->initial_line
= fx_cull_draw_line
;
574 fxMesa
->initial_tri
= fx_cull_draw_tri
;
576 fxMesa
->subsequent_point
= fx_draw_point
;
577 fxMesa
->subsequent_line
= fx_draw_line
;
578 fxMesa
->subsequent_tri
= fx_draw_tri
;
580 if ( flags
& POINT_FALLBACK
)
581 fxMesa
->initial_point
= fx_fallback_point
;
583 if ( flags
& LINE_FALLBACK
)
584 fxMesa
->initial_line
= fx_fallback_line
;
586 if ((flags
& DD_LINE_SMOOTH
) && ctx
->Line
.Width
!= 1.0)
587 fxMesa
->initial_line
= fx_fallback_line
;
589 if ( flags
& TRI_FALLBACK
)
590 fxMesa
->initial_tri
= fx_fallback_tri
;
592 if ( flags
& DD_TRI_CULL_FRONT_BACK
)
593 fxMesa
->initial_tri
= fx_null_tri
;
595 fxMesa
->draw_point
= fxMesa
->initial_point
;
596 fxMesa
->draw_line
= fxMesa
->initial_line
;
597 fxMesa
->draw_tri
= fxMesa
->initial_tri
;
599 else if (fxMesa
->render_index
& FX_FALLBACK_BIT
) {
600 FX_grCullMode(fxMesa
->cullMode
);
603 ctx
->Driver
.PointsFunc
= rast_tab
[index
].points
;
604 ctx
->Driver
.LineFunc
= rast_tab
[index
].line
;
605 ctx
->Driver
.TriangleFunc
= rast_tab
[index
].triangle
;
606 ctx
->Driver
.QuadFunc
= rast_tab
[index
].quad
;
607 fxMesa
->render_index
= index
;
609 if (fxMesa
->render_index
== 0) {
610 ctx
->Driver
.RenderTabVerts
= fx_render_tab_verts
;
611 ctx
->Driver
.RenderTabElts
= fx_render_tab_elts
;
613 ctx
->Driver
.RenderTabVerts
= _tnl_render_tab_verts
;
614 ctx
->Driver
.RenderTabElts
= _tnl_render_tab_elts
;
625 * Need this to provide at least one external definition.
628 extern int gl_fx_dummy_function_trifuncs(void);
629 int gl_fx_dummy_function_trifuncs(void)