10 #include "swrast/swrast.h"
11 #include "swrast_setup/swrast_setup.h"
13 #include "tnl/t_context.h"
26 fx_draw_point( GLcontext
*ctx
, const fxVertex
*v
)
28 GLfloat sz
= ctx
->Point
._Size
;
32 grDrawPoint( &(v
->v
) );
45 verts
[0].x
= v
->v
.x
- sz
;
46 verts
[0].y
= v
->v
.y
- sz
;
48 verts
[1].x
= v
->v
.x
+ sz
;
49 verts
[1].y
= v
->v
.y
- sz
;
51 verts
[2].x
= v
->v
.x
+ sz
;
52 verts
[2].y
= v
->v
.y
+ sz
;
54 verts
[3].x
= v
->v
.x
- sz
;
55 verts
[3].y
= v
->v
.y
+ sz
;
57 grDrawTriangle( &verts
[0], &verts
[1], &verts
[3] );
58 grDrawTriangle( &verts
[1], &verts
[2], &verts
[3] );
64 fx_draw_line( GLcontext
*ctx
, const fxVertex
*v0
, const fxVertex
*v1
)
66 float width
= ctx
->Line
.Width
;
70 grDrawLine( &(v0
->v
), &(v1
->v
) );
77 dx
= v0
->v
.x
- v1
->v
.x
;
78 dy
= v0
->v
.y
- v1
->v
.y
;
80 if (dx
* dx
> dy
* dy
) {
105 grDrawTriangle( &verts
[0], &verts
[1], &verts
[3] );
106 grDrawTriangle( &verts
[1], &verts
[2], &verts
[3] );
111 fx_draw_tri( GLcontext
*ctx
, const fxVertex
*v0
, const fxVertex
*v1
,
114 grDrawTriangle( &(v0
->v
), &(v1
->v
), &(v2
->v
) );
119 #define FX_COLOR(vert, c) { \
121 vert->v.r=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[0]); \
122 vert->v.g=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[1]); \
123 vert->v.b=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[2]); \
124 vert->v.a=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[3]); \
127 #define FX_COPY_COLOR( dst, src ) { \
128 dst->v.r = src->v.r; \
129 dst->v.g = src->v.g; \
130 dst->v.b = src->v.b; \
131 dst->v.a = src->v.a; \
136 #define FX_FLAT_BIT 0x01
137 #define FX_OFFSET_BIT 0x02
138 #define FX_TWOSIDE_BIT 0x04
139 #define FX_UNFILLED_BIT 0x10
140 #define FX_FALLBACK_BIT 0x20
141 #define FX_MAX_TRIFUNC 0x40
146 triangle_func triangle
;
148 } rast_tab
[FX_MAX_TRIFUNC
];
153 #include "fxtritmp.h"
155 #define IND (FX_FLAT_BIT)
156 #define TAG(x) x##_flat
157 #include "fxtritmp.h"
159 #define IND (FX_OFFSET_BIT)
160 #define TAG(x) x##_offset
161 #include "fxtritmp.h"
163 #define IND (FX_OFFSET_BIT | FX_FLAT_BIT)
164 #define TAG(x) x##_offset_flat
165 #include "fxtritmp.h"
167 #define IND (FX_TWOSIDE_BIT)
168 #define TAG(x) x##_twoside
169 #include "fxtritmp.h"
171 #define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT)
172 #define TAG(x) x##_twoside_flat
173 #include "fxtritmp.h"
175 #define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT)
176 #define TAG(x) x##_twoside_offset
177 #include "fxtritmp.h"
179 #define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT)
180 #define TAG(x) x##_twoside_offset_flat
181 #include "fxtritmp.h"
183 #define IND (FX_FALLBACK_BIT)
184 #define TAG(x) x##_fallback
185 #include "fxtritmp.h"
187 #define IND (FX_FLAT_BIT | FX_FALLBACK_BIT)
188 #define TAG(x) x##_flat_fallback
189 #include "fxtritmp.h"
191 #define IND (FX_OFFSET_BIT | FX_FALLBACK_BIT)
192 #define TAG(x) x##_offset_fallback
193 #include "fxtritmp.h"
195 #define IND (FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT)
196 #define TAG(x) x##_offset_flat_fallback
197 #include "fxtritmp.h"
199 #define IND (FX_TWOSIDE_BIT | FX_FALLBACK_BIT)
200 #define TAG(x) x##_twoside_fallback
201 #include "fxtritmp.h"
203 #define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT)
204 #define TAG(x) x##_twoside_flat_fallback
205 #include "fxtritmp.h"
207 #define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FALLBACK_BIT)
208 #define TAG(x) x##_twoside_offset_fallback
209 #include "fxtritmp.h"
211 #define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT)
212 #define TAG(x) x##_twoside_offset_flat_fallback
213 #include "fxtritmp.h"
215 #define IND (FX_UNFILLED_BIT)
216 #define TAG(x) x##_unfilled
217 #include "fxtritmp.h"
219 #define IND (FX_FLAT_BIT | FX_UNFILLED_BIT)
220 #define TAG(x) x##_flat_unfilled
221 #include "fxtritmp.h"
223 #define IND (FX_OFFSET_BIT | FX_UNFILLED_BIT)
224 #define TAG(x) x##_offset_unfilled
225 #include "fxtritmp.h"
227 #define IND (FX_OFFSET_BIT | FX_FLAT_BIT | FX_UNFILLED_BIT)
228 #define TAG(x) x##_offset_flat_unfilled
229 #include "fxtritmp.h"
231 #define IND (FX_TWOSIDE_BIT | FX_UNFILLED_BIT)
232 #define TAG(x) x##_twoside_unfilled
233 #include "fxtritmp.h"
235 #define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT | FX_UNFILLED_BIT)
236 #define TAG(x) x##_twoside_flat_unfilled
237 #include "fxtritmp.h"
239 #define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_UNFILLED_BIT)
240 #define TAG(x) x##_twoside_offset_unfilled
241 #include "fxtritmp.h"
243 #define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT | FX_UNFILLED_BIT)
244 #define TAG(x) x##_twoside_offset_flat_unfilled
245 #include "fxtritmp.h"
247 #define IND (FX_FALLBACK_BIT | FX_UNFILLED_BIT)
248 #define TAG(x) x##_fallback_unfilled
249 #include "fxtritmp.h"
251 #define IND (FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
252 #define TAG(x) x##_flat_fallback_unfilled
253 #include "fxtritmp.h"
255 #define IND (FX_OFFSET_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
256 #define TAG(x) x##_offset_fallback_unfilled
257 #include "fxtritmp.h"
259 #define IND (FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
260 #define TAG(x) x##_offset_flat_fallback_unfilled
261 #include "fxtritmp.h"
263 #define IND (FX_TWOSIDE_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
264 #define TAG(x) x##_twoside_fallback_unfilled
265 #include "fxtritmp.h"
267 #define IND (FX_TWOSIDE_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
268 #define TAG(x) x##_twoside_flat_fallback_unfilled
269 #include "fxtritmp.h"
271 #define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
272 #define TAG(x) x##_twoside_offset_fallback_unfilled
273 #include "fxtritmp.h"
275 #define IND (FX_TWOSIDE_BIT | FX_OFFSET_BIT | FX_FLAT_BIT | FX_FALLBACK_BIT | FX_UNFILLED_BIT)
276 #define TAG(x) x##_twoside_offset_flat_fallback_unfilled
277 #include "fxtritmp.h"
284 void fxDDTrifuncInit( void )
292 init_twoside_offset();
293 init_twoside_offset_flat();
295 init_flat_fallback();
296 init_offset_fallback();
297 init_offset_flat_fallback();
298 init_twoside_fallback();
299 init_twoside_flat_fallback();
300 init_twoside_offset_fallback();
301 init_twoside_offset_flat_fallback();
304 init_flat_unfilled();
305 init_offset_unfilled();
306 init_offset_flat_unfilled();
307 init_twoside_unfilled();
308 init_twoside_flat_unfilled();
309 init_twoside_offset_unfilled();
310 init_twoside_offset_flat_unfilled();
311 init_fallback_unfilled();
312 init_flat_fallback_unfilled();
313 init_offset_fallback_unfilled();
314 init_offset_flat_fallback_unfilled();
315 init_twoside_fallback_unfilled();
316 init_twoside_flat_fallback_unfilled();
317 init_twoside_offset_fallback_unfilled();
318 init_twoside_offset_flat_fallback_unfilled();
322 /* Build an SWvertex from a GrVertex. This is workable because in
323 * states where the GrVertex is insufficent (eg seperate-specular),
324 * the driver initiates a total fallback, and builds SWvertices
325 * directly -- it recognizes that it will never have use for the
328 * This code is hit only when a mix of accelerated and unaccelerated
329 * primitives are being drawn, and only for the unaccelerated
333 fx_translate_vertex(GLcontext
*ctx
, const fxVertex
*src
, SWvertex
*dst
)
335 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
336 GLuint ts0
= fxMesa
->tmu_source
[0];
337 GLuint ts1
= fxMesa
->tmu_source
[1];
338 GLfloat w
= 1.0 / src
->v
.oow
;
340 dst
->win
[0] = src
->v
.x
;
341 dst
->win
[1] = src
->v
.y
;
342 dst
->win
[2] = src
->v
.ooz
;
343 dst
->win
[3] = src
->v
.oow
;
345 dst
->color
[0] = (GLubyte
) src
->v
.r
;
346 dst
->color
[1] = (GLubyte
) src
->v
.g
;
347 dst
->color
[2] = (GLubyte
) src
->v
.b
;
348 dst
->color
[3] = (GLubyte
) src
->v
.a
;
350 dst
->texcoord
[ts0
][0] = fxMesa
->inv_s0scale
* src
->v
.tmuvtx
[0].sow
* w
;
351 dst
->texcoord
[ts0
][1] = fxMesa
->inv_t0scale
* src
->v
.tmuvtx
[0].tow
* w
;
353 if (fxMesa
->stw_hint_state
& GR_STWHINT_W_DIFF_TMU0
)
354 dst
->texcoord
[ts0
][3] = src
->v
.tmuvtx
[0].oow
* w
;
356 dst
->texcoord
[ts0
][3] = 1.0;
358 dst
->texcoord
[ts1
][0] = fxMesa
->inv_s1scale
* src
->v
.tmuvtx
[1].sow
* w
;
359 dst
->texcoord
[ts1
][1] = fxMesa
->inv_t1scale
* src
->v
.tmuvtx
[1].tow
* w
;
361 if (fxMesa
->stw_hint_state
& GR_STWHINT_W_DIFF_TMU1
)
362 dst
->texcoord
[ts1
][3] = src
->v
.tmuvtx
[1].oow
* w
;
364 dst
->texcoord
[ts1
][3] = 1.0;
369 fx_fallback_tri( GLcontext
*ctx
,
370 const fxVertex
*v0
, const fxVertex
*v1
, const fxVertex
*v2
)
373 fx_translate_vertex( ctx
, v0
, &v
[0] );
374 fx_translate_vertex( ctx
, v1
, &v
[1] );
375 fx_translate_vertex( ctx
, v2
, &v
[2] );
376 _swrast_Triangle( ctx
, &v
[0], &v
[1], &v
[2] );
381 fx_fallback_line( GLcontext
*ctx
, const fxVertex
*v0
, const fxVertex
*v1
)
384 fx_translate_vertex( ctx
, v0
, &v
[0] );
385 fx_translate_vertex( ctx
, v1
, &v
[1] );
386 _swrast_Line( ctx
, &v
[0], &v
[1] );
391 fx_fallback_point( GLcontext
*ctx
, const fxVertex
*v0
)
394 fx_translate_vertex( ctx
, v0
, &v
[0] );
395 _swrast_Point( ctx
, &v
[0] );
399 /* System to turn culling off for rasterized lines and points, and
400 * back on for rasterized triangles.
403 fx_cull_draw_tri( GLcontext
*ctx
,
404 const fxVertex
*v0
, const fxVertex
*v1
, const fxVertex
*v2
)
406 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
408 FX_grCullMode(fxMesa
->cullMode
);
410 fxMesa
->draw_line
= fxMesa
->initial_line
;
411 fxMesa
->draw_point
= fxMesa
->initial_point
;
412 fxMesa
->draw_tri
= fxMesa
->subsequent_tri
;
414 fxMesa
->draw_tri( ctx
, v0
, v1
, v2
);
419 fx_cull_draw_line( GLcontext
*ctx
, const fxVertex
*v0
, const fxVertex
*v1
)
421 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
423 FX_grCullMode( GR_CULL_DISABLE
);
425 fxMesa
->draw_point
= fxMesa
->initial_point
;
426 fxMesa
->draw_tri
= fxMesa
->initial_tri
;
427 fxMesa
->draw_line
= fxMesa
->subsequent_line
;
429 fxMesa
->draw_line( ctx
, v0
, v1
);
434 fx_cull_draw_point( GLcontext
*ctx
, const fxVertex
*v0
)
436 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
438 FX_grCullMode(GR_CULL_DISABLE
);
440 fxMesa
->draw_line
= fxMesa
->initial_line
;
441 fxMesa
->draw_tri
= fxMesa
->initial_tri
;
442 fxMesa
->draw_point
= fxMesa
->subsequent_point
;
444 fxMesa
->draw_point( ctx
, v0
);
449 fx_null_tri( GLcontext
*ctx
,
450 const fxVertex
*v0
, const fxVertex
*v1
, const fxVertex
*v2
)
459 #define POINT_FALLBACK (DD_POINT_SMOOTH )
460 #define LINE_FALLBACK (DD_LINE_STIPPLE)
461 #define TRI_FALLBACK (DD_TRI_SMOOTH | DD_TRI_STIPPLE )
462 #define ANY_FALLBACK (POINT_FALLBACK | LINE_FALLBACK | TRI_FALLBACK)
465 #define ANY_RENDER_FLAGS (DD_FLATSHADE | \
466 DD_TRI_LIGHT_TWOSIDE | \
472 /* Setup the Point, Line, Triangle and Quad functions based on the
473 * current rendering state. Wherever possible, use the hardware to
474 * render the primitive. Otherwise, fallback to software rendering.
476 void fxDDChooseRenderState( GLcontext
*ctx
)
478 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
479 GLuint flags
= ctx
->_TriangleCaps
;
482 if ( !fxMesa
->is_in_hardware
) {
483 /* Build software vertices directly. No acceleration is
484 * possible. GrVertices may be insufficient for this mode.
486 ctx
->Driver
.PointsFunc
= _swsetup_Points
;
487 ctx
->Driver
.LineFunc
= _swsetup_Line
;
488 ctx
->Driver
.TriangleFunc
= _swsetup_Triangle
;
489 ctx
->Driver
.QuadFunc
= _swsetup_Quad
;
491 fxMesa
->render_index
= FX_FALLBACK_BIT
;
495 if ( flags
& ANY_RENDER_FLAGS
) {
496 if ( flags
& DD_FLATSHADE
) index
|= FX_FLAT_BIT
;
497 if ( flags
& DD_TRI_LIGHT_TWOSIDE
) index
|= FX_TWOSIDE_BIT
;
498 if ( flags
& DD_TRI_OFFSET
) index
|= FX_OFFSET_BIT
;
499 if ( flags
& DD_TRI_UNFILLED
) index
|= FX_UNFILLED_BIT
;
502 if ( flags
& (ANY_FALLBACK
|
505 DD_TRI_CULL_FRONT_BACK
) ) {
507 /* Hook in fallbacks for specific primitives.
509 * Set up a system to turn culling on/off for wide points and
510 * lines. Alternately: figure out what tris to send so that
511 * culling isn't a problem.
513 * This replaces the ReducedPrimitiveChange mechanism.
515 index
|= FX_FALLBACK_BIT
;
516 fxMesa
->initial_point
= fx_cull_draw_point
;
517 fxMesa
->initial_line
= fx_cull_draw_line
;
518 fxMesa
->initial_tri
= fx_cull_draw_tri
;
520 fxMesa
->subsequent_point
= fx_draw_point
;
521 fxMesa
->subsequent_line
= fx_draw_line
;
522 fxMesa
->subsequent_tri
= fx_draw_tri
;
524 if ( flags
& POINT_FALLBACK
)
525 fxMesa
->initial_point
= fx_fallback_point
;
527 if ( flags
& LINE_FALLBACK
)
528 fxMesa
->initial_line
= fx_fallback_line
;
530 if ((flags
& DD_LINE_SMOOTH
) && ctx
->Line
.Width
!= 1.0)
531 fxMesa
->initial_line
= fx_fallback_line
;
533 if ( flags
& TRI_FALLBACK
)
534 fxMesa
->initial_tri
= fx_fallback_tri
;
536 if ( flags
& DD_TRI_CULL_FRONT_BACK
)
537 fxMesa
->initial_tri
= fx_null_tri
;
539 fxMesa
->draw_point
= fxMesa
->initial_point
;
540 fxMesa
->draw_line
= fxMesa
->initial_line
;
541 fxMesa
->draw_tri
= fxMesa
->initial_tri
;
543 else if (fxMesa
->render_index
& FX_FALLBACK_BIT
) {
544 FX_grCullMode(fxMesa
->cullMode
);
547 ctx
->Driver
.PointsFunc
= rast_tab
[index
].points
;
548 ctx
->Driver
.LineFunc
= rast_tab
[index
].line
;
549 ctx
->Driver
.TriangleFunc
= rast_tab
[index
].triangle
;
550 ctx
->Driver
.QuadFunc
= rast_tab
[index
].quad
;
551 fxMesa
->render_index
= index
;
559 * Need this to provide at least one external definition.
562 extern int gl_fx_dummy_function_trifuncs(void);
563 int gl_fx_dummy_function_trifuncs(void)