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
;
44 verts
[0].x
= v
->v
.x
- sz
;
45 verts
[0].y
= v
->v
.y
- sz
;
47 verts
[1].x
= v
->v
.x
+ sz
;
48 verts
[1].y
= v
->v
.y
- sz
;
50 verts
[2].x
= v
->v
.x
+ sz
;
51 verts
[2].y
= v
->v
.y
+ sz
;
53 verts
[3].x
= v
->v
.x
- sz
;
54 verts
[3].y
= v
->v
.y
+ sz
;
56 grDrawTriangle(&verts
[0], &verts
[1], &verts
[3]);
57 grDrawTriangle(&verts
[1], &verts
[2], &verts
[3]);
63 fx_draw_line(GLcontext
* ctx
, const fxVertex
* v0
, const fxVertex
* v1
)
65 float width
= ctx
->Line
.Width
;
68 grDrawLine(&(v0
->v
), &(v1
->v
));
74 dx
= v0
->v
.x
- v1
->v
.x
;
75 dy
= v0
->v
.y
- v1
->v
.y
;
77 if (dx
* dx
> dy
* dy
) {
103 grDrawTriangle(&verts
[0], &verts
[1], &verts
[3]);
104 grDrawTriangle(&verts
[1], &verts
[2], &verts
[3]);
109 fx_draw_tri(GLcontext
* ctx
, const fxVertex
* v0
, const fxVertex
* v1
,
112 grDrawTriangle(&(v0
->v
), &(v1
->v
), &(v2
->v
));
117 #define FX_COLOR(vert, c) { \
119 vert->v.r=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[0]); \
120 vert->v.g=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[1]); \
121 vert->v.b=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[2]); \
122 vert->v.a=UBYTE_COLOR_TO_FLOAT_255_COLOR(col[3]); \
125 #define FX_COPY_COLOR( dst, src ) { \
126 dst->v.r = src->v.r; \
127 dst->v.g = src->v.g; \
128 dst->v.b = src->v.b; \
129 dst->v.a = src->v.a; \
134 #define FX_FLAT_BIT 0x01
135 #define FX_OFFSET_BIT 0x02
136 #define FX_TWOSIDE_BIT 0x04
137 #define FX_UNFILLED_BIT 0x10
138 #define FX_FALLBACK_BIT 0x20
139 #define FX_MAX_TRIFUNC 0x40
145 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"
285 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
,
408 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
410 FX_grCullMode(fxMesa
->cullMode
);
412 fxMesa
->draw_line
= fxMesa
->initial_line
;
413 fxMesa
->draw_point
= fxMesa
->initial_point
;
414 fxMesa
->draw_tri
= fxMesa
->subsequent_tri
;
416 fxMesa
->draw_tri(ctx
, v0
, v1
, v2
);
421 fx_cull_draw_line(GLcontext
* ctx
, const fxVertex
* v0
, const fxVertex
* v1
)
423 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
425 FX_grCullMode(GR_CULL_DISABLE
);
427 fxMesa
->draw_point
= fxMesa
->initial_point
;
428 fxMesa
->draw_tri
= fxMesa
->initial_tri
;
429 fxMesa
->draw_line
= fxMesa
->subsequent_line
;
431 fxMesa
->draw_line(ctx
, v0
, v1
);
436 fx_cull_draw_point(GLcontext
* ctx
, const fxVertex
* v0
)
438 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
440 FX_grCullMode(GR_CULL_DISABLE
);
442 fxMesa
->draw_line
= fxMesa
->initial_line
;
443 fxMesa
->draw_tri
= fxMesa
->initial_tri
;
444 fxMesa
->draw_point
= fxMesa
->subsequent_point
;
446 fxMesa
->draw_point(ctx
, v0
);
451 fx_null_tri(GLcontext
* ctx
,
452 const fxVertex
* v0
, const fxVertex
* v1
, const fxVertex
* v2
)
462 /**********************************************************************/
463 /* Render whole begin/end objects */
464 /**********************************************************************/
467 /* Vertices, no clipping.
469 #define RENDER_POINTS( start, count ) \
470 for ( ; start < count ; start++) \
471 grDrawPoint( &v[ELT(start)].v );
473 #define RENDER_LINE( i1, i ) \
474 grDrawLine( &v[i1].v, &v[i].v )
476 #define RENDER_TRI( i2, i1, i ) \
477 grDrawTriangle( &v[i2].v, &v[i1].v, &v[i].v )
479 #define RENDER_QUAD( i3, i2, i1, i ) \
480 grDrawTriangle( &v[i3].v, &v[i2].v, &v[i].v ); \
481 grDrawTriangle( &v[i2].v, &v[i1].v, &v[i].v )
483 #define TAG(x) fx_##x##_verts
485 fxVertex *v = FX_CONTEXT(ctx)->verts; \
486 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
489 /* Verts, no clipping.
492 #define RESET_STIPPLE
493 #define RESET_OCCLUSION
494 #define PRESERVE_VB_DEFS
495 #include "tnl/t_vb_rendertmp.h"
498 /* Elts, no clipping.
502 #define TAG(x) fx_##x##_elts
503 #define ELT(x) elt[x]
504 #include "tnl/t_vb_rendertmp.h"
507 /**********************************************************************/
508 /* Choose render functions */
509 /**********************************************************************/
514 #define POINT_FALLBACK (DD_POINT_SMOOTH )
515 #define LINE_FALLBACK (DD_LINE_STIPPLE)
516 #define TRI_FALLBACK (DD_TRI_SMOOTH | DD_TRI_STIPPLE )
517 #define ANY_FALLBACK (POINT_FALLBACK | LINE_FALLBACK | TRI_FALLBACK)
520 #define ANY_RENDER_FLAGS (DD_FLATSHADE | \
521 DD_TRI_LIGHT_TWOSIDE | \
527 /* Setup the Point, Line, Triangle and Quad functions based on the
528 * current rendering state. Wherever possible, use the hardware to
529 * render the primitive. Otherwise, fallback to software rendering.
532 fxDDChooseRenderState(GLcontext
* ctx
)
534 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
535 GLuint flags
= ctx
->_TriangleCaps
;
538 if (!fxMesa
->is_in_hardware
) {
539 /* Build software vertices directly. No acceleration is
540 * possible. GrVertices may be insufficient for this mode.
542 ctx
->Driver
.PointsFunc
= _swsetup_Points
;
543 ctx
->Driver
.LineFunc
= _swsetup_Line
;
544 ctx
->Driver
.TriangleFunc
= _swsetup_Triangle
;
545 ctx
->Driver
.QuadFunc
= _swsetup_Quad
;
546 ctx
->Driver
.RenderTabVerts
= _tnl_render_tab_verts
;
547 ctx
->Driver
.RenderTabElts
= _tnl_render_tab_elts
;
549 fxMesa
->render_index
= FX_FALLBACK_BIT
;
553 if (flags
& ANY_RENDER_FLAGS
) {
554 if (flags
& DD_FLATSHADE
)
555 index
|= FX_FLAT_BIT
;
556 if (flags
& DD_TRI_LIGHT_TWOSIDE
)
557 index
|= FX_TWOSIDE_BIT
;
558 if (flags
& DD_TRI_OFFSET
)
559 index
|= FX_OFFSET_BIT
;
560 if (flags
& DD_TRI_UNFILLED
)
561 index
|= FX_UNFILLED_BIT
;
564 if (flags
& (ANY_FALLBACK
|
565 DD_LINE_WIDTH
| DD_POINT_SIZE
| DD_TRI_CULL_FRONT_BACK
)) {
567 /* Hook in fallbacks for specific primitives.
569 * Set up a system to turn culling on/off for wide points and
570 * lines. Alternately: figure out what tris to send so that
571 * culling isn't a problem.
573 * This replaces the ReducedPrimitiveChange mechanism.
575 index
|= FX_FALLBACK_BIT
;
576 fxMesa
->initial_point
= fx_cull_draw_point
;
577 fxMesa
->initial_line
= fx_cull_draw_line
;
578 fxMesa
->initial_tri
= fx_cull_draw_tri
;
580 fxMesa
->subsequent_point
= fx_draw_point
;
581 fxMesa
->subsequent_line
= fx_draw_line
;
582 fxMesa
->subsequent_tri
= fx_draw_tri
;
584 if (flags
& POINT_FALLBACK
)
585 fxMesa
->initial_point
= fx_fallback_point
;
587 if (flags
& LINE_FALLBACK
)
588 fxMesa
->initial_line
= fx_fallback_line
;
590 if ((flags
& DD_LINE_SMOOTH
) && ctx
->Line
.Width
!= 1.0)
591 fxMesa
->initial_line
= fx_fallback_line
;
593 if (flags
& TRI_FALLBACK
)
594 fxMesa
->initial_tri
= fx_fallback_tri
;
596 if (flags
& DD_TRI_CULL_FRONT_BACK
)
597 fxMesa
->initial_tri
= fx_null_tri
;
599 fxMesa
->draw_point
= fxMesa
->initial_point
;
600 fxMesa
->draw_line
= fxMesa
->initial_line
;
601 fxMesa
->draw_tri
= fxMesa
->initial_tri
;
603 else if (fxMesa
->render_index
& FX_FALLBACK_BIT
) {
604 FX_grCullMode(fxMesa
->cullMode
);
607 ctx
->Driver
.PointsFunc
= rast_tab
[index
].points
;
608 ctx
->Driver
.LineFunc
= rast_tab
[index
].line
;
609 ctx
->Driver
.TriangleFunc
= rast_tab
[index
].triangle
;
610 ctx
->Driver
.QuadFunc
= rast_tab
[index
].quad
;
611 fxMesa
->render_index
= index
;
613 if (fxMesa
->render_index
== 0) {
614 ctx
->Driver
.RenderTabVerts
= fx_render_tab_verts
;
615 ctx
->Driver
.RenderTabElts
= fx_render_tab_elts
;
618 ctx
->Driver
.RenderTabVerts
= _tnl_render_tab_verts
;
619 ctx
->Driver
.RenderTabElts
= _tnl_render_tab_elts
;
630 * Need this to provide at least one external definition.
633 extern int gl_fx_dummy_function_trifuncs(void);
635 gl_fx_dummy_function_trifuncs(void)