1 /* $XFree86: xc/lib/GL/mesa/src/drv/ffb/ffb_tris.c,v 1.3 2002/10/30 12:51:28 alanh Exp $
3 * GLX Hardware Device Driver for Sun Creator/Creator3D
4 * Copyright (C) 2000, 2001 David S. Miller
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * DAVID MILLER, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
22 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 * David S. Miller <davem@redhat.com>
31 #include "swrast/swrast.h"
32 #include "swrast_setup/swrast_setup.h"
33 #include "swrast/s_context.h"
34 #include "tnl/t_context.h"
35 #include "tnl/t_pipeline.h"
37 #include "ffb_context.h"
39 #include "ffb_lines.h"
41 #include "ffb_points.h"
42 #include "ffb_state.h"
46 #undef FFB_RENDER_TRACE
50 static void ffb_print_vertex(const ffb_vertex
*v
)
52 fprintf(stderr
, "Vertex @(%p): "
53 "X[%f] Y[%f] Z[%f]\n",
55 fprintf(stderr
, "Vertex @(%p): "
56 "A[%f] R[%f] G[%f] B[%f]\n",
63 #define FFB_DUMP_VERTEX(V) ffb_print_vertex(V)
65 #define FFB_DUMP_VERTEX(V) do { } while(0)
68 #define FFB_ALPHA_BIT 0x01
69 #define FFB_FLAT_BIT 0x02
70 #define FFB_TRI_CULL_BIT 0x04
71 #define MAX_FFB_RENDER_FUNCS 0x08
73 /***********************************************************************
74 * Build low-level triangle/quad rasterize functions *
75 ***********************************************************************/
77 #define FFB_TRI_FLAT_BIT 0x01
78 #define FFB_TRI_ALPHA_BIT 0x02
79 /*#define FFB_TRI_CULL_BIT 0x04*/
81 static ffb_tri_func ffb_tri_tab
[0x8];
82 static ffb_quad_func ffb_quad_tab
[0x8];
86 #include "ffb_tritmp.h"
88 #define IND (FFB_TRI_FLAT_BIT)
89 #define TAG(x) x##_flat
90 #include "ffb_tritmp.h"
92 #define IND (FFB_TRI_CULL_BIT)
93 #define TAG(x) x##_cull
94 #include "ffb_tritmp.h"
96 #define IND (FFB_TRI_CULL_BIT|FFB_TRI_FLAT_BIT)
97 #define TAG(x) x##_cull_flat
98 #include "ffb_tritmp.h"
100 #define IND (FFB_TRI_ALPHA_BIT)
101 #define TAG(x) x##_alpha
102 #include "ffb_tritmp.h"
104 #define IND (FFB_TRI_ALPHA_BIT|FFB_TRI_FLAT_BIT)
105 #define TAG(x) x##_alpha_flat
106 #include "ffb_tritmp.h"
108 #define IND (FFB_TRI_ALPHA_BIT|FFB_TRI_CULL_BIT)
109 #define TAG(x) x##_alpha_cull
110 #include "ffb_tritmp.h"
112 #define IND (FFB_TRI_ALPHA_BIT|FFB_TRI_CULL_BIT|FFB_TRI_FLAT_BIT)
113 #define TAG(x) x##_alpha_cull_flat
114 #include "ffb_tritmp.h"
116 static void init_tri_tab(void)
121 ffb_init_cull_flat();
123 ffb_init_alpha_flat();
124 ffb_init_alpha_cull();
125 ffb_init_alpha_cull_flat();
128 /* Build a SWvertex from a hardware vertex. */
129 static void ffb_translate_vertex(GLcontext
*ctx
, const ffb_vertex
*src
,
132 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
133 GLfloat
*m
= ctx
->Viewport
._WindowMap
.m
;
134 const GLfloat sx
= m
[0];
135 const GLfloat sy
= m
[5];
136 const GLfloat sz
= m
[10];
137 const GLfloat tx
= m
[12];
138 const GLfloat ty
= m
[13];
139 const GLfloat tz
= m
[14];
141 dst
->attrib
[FRAG_ATTRIB_WPOS
][0] = sx
* src
->x
+ tx
;
142 dst
->attrib
[FRAG_ATTRIB_WPOS
][1] = sy
* src
->y
+ ty
;
143 dst
->attrib
[FRAG_ATTRIB_WPOS
][2] = sz
* src
->z
+ tz
;
144 dst
->attrib
[FRAG_ATTRIB_WPOS
][3] = 1.0;
146 dst
->color
[0] = FFB_UBYTE_FROM_COLOR(src
->color
[0].red
);
147 dst
->color
[1] = FFB_UBYTE_FROM_COLOR(src
->color
[0].green
);
148 dst
->color
[2] = FFB_UBYTE_FROM_COLOR(src
->color
[0].blue
);
149 dst
->color
[3] = FFB_UBYTE_FROM_COLOR(src
->color
[0].alpha
);
152 /***********************************************************************
153 * Build fallback triangle/quad rasterize functions *
154 ***********************************************************************/
156 static void ffb_fallback_triangle(GLcontext
*ctx
, ffb_vertex
*v0
,
157 ffb_vertex
*v1
, ffb_vertex
*v2
)
161 ffb_translate_vertex(ctx
, v0
, &v
[0]);
162 ffb_translate_vertex(ctx
, v1
, &v
[1]);
163 ffb_translate_vertex(ctx
, v2
, &v
[2]);
165 _swrast_Triangle(ctx
, &v
[0], &v
[1], &v
[2]);
168 static void ffb_fallback_quad(GLcontext
*ctx
,
169 ffb_vertex
*v0
, ffb_vertex
*v1
,
170 ffb_vertex
*v2
, ffb_vertex
*v3
)
174 ffb_translate_vertex(ctx
, v0
, &v
[0]);
175 ffb_translate_vertex(ctx
, v1
, &v
[1]);
176 ffb_translate_vertex(ctx
, v2
, &v
[2]);
177 ffb_translate_vertex(ctx
, v3
, &v
[3]);
179 _swrast_Quad(ctx
, &v
[0], &v
[1], &v
[2], &v
[3]);
182 void ffb_fallback_line(GLcontext
*ctx
, ffb_vertex
*v0
, ffb_vertex
*v1
)
186 ffb_translate_vertex(ctx
, v0
, &v
[0]);
187 ffb_translate_vertex(ctx
, v1
, &v
[1]);
189 _swrast_Line(ctx
, &v
[0], &v
[1]);
192 void ffb_fallback_point(GLcontext
*ctx
, ffb_vertex
*v0
)
196 ffb_translate_vertex(ctx
, v0
, &v
[0]);
198 _swrast_Point(ctx
, &v
[0]);
201 /***********************************************************************
202 * Rasterization functions for culled tris/quads *
203 ***********************************************************************/
205 static void ffb_nodraw_triangle(GLcontext
*ctx
, ffb_vertex
*v0
,
206 ffb_vertex
*v1
, ffb_vertex
*v2
)
208 (void) (ctx
&& v0
&& v1
&& v2
);
211 static void ffb_nodraw_quad(GLcontext
*ctx
,
212 ffb_vertex
*v0
, ffb_vertex
*v1
,
213 ffb_vertex
*v2
, ffb_vertex
*v3
)
215 (void) (ctx
&& v0
&& v1
&& v2
&& v3
);
218 static void ffb_update_cullsign(GLcontext
*ctx
)
220 GLfloat backface_sign
= 1;
222 switch (ctx
->Polygon
.CullFaceMode
) {
224 if (ctx
->Polygon
.FrontFace
==GL_CCW
)
229 if (ctx
->Polygon
.FrontFace
!=GL_CCW
)
237 FFB_CONTEXT(ctx
)->backface_sign
= backface_sign
;
240 /***********************************************************************
241 * Choose triangle/quad rasterize functions *
242 ***********************************************************************/
244 void ffbChooseTriangleState(GLcontext
*ctx
)
246 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
247 GLuint flags
= ctx
->_TriangleCaps
;
250 if (flags
& DD_TRI_SMOOTH
) {
251 fmesa
->draw_tri
= ffb_fallback_triangle
;
252 fmesa
->draw_quad
= ffb_fallback_quad
;
256 if (flags
& DD_FLATSHADE
)
257 ind
|= FFB_TRI_FLAT_BIT
;
259 if (ctx
->Polygon
.CullFlag
) {
260 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT_AND_BACK
) {
261 fmesa
->draw_tri
= ffb_nodraw_triangle
;
262 fmesa
->draw_quad
= ffb_nodraw_quad
;
266 ind
|= FFB_TRI_CULL_BIT
;
267 ffb_update_cullsign(ctx
);
269 FFB_CONTEXT(ctx
)->backface_sign
= 0;
271 /* If blending or the alpha test is enabled we need to
272 * provide alpha components to the chip, else we can
273 * do without it and thus feed vertex data to the chip
276 if (ctx
->Color
.BlendEnabled
|| ctx
->Color
.AlphaEnabled
)
277 ind
|= FFB_TRI_ALPHA_BIT
;
279 fmesa
->draw_tri
= ffb_tri_tab
[ind
];
280 fmesa
->draw_quad
= ffb_quad_tab
[ind
];
283 static const GLenum reduced_prim
[GL_POLYGON
+1] = {
296 static void ffbRenderPrimitive(GLcontext
*ctx
, GLenum prim
);
297 static void ffbRasterPrimitive(GLcontext
*ctx
, GLenum rprim
);
299 /***********************************************************************
300 * Build render functions from dd templates *
301 ***********************************************************************/
303 #define FFB_OFFSET_BIT 0x01
304 #define FFB_TWOSIDE_BIT 0x02
305 #define FFB_UNFILLED_BIT 0x04
306 #define FFB_MAX_TRIFUNC 0x08
309 tnl_triangle_func triangle
;
311 } rast_tab
[FFB_MAX_TRIFUNC
];
313 #define DO_OFFSET (IND & FFB_OFFSET_BIT)
314 #define DO_UNFILLED (IND & FFB_UNFILLED_BIT)
315 #define DO_TWOSIDE (IND & FFB_TWOSIDE_BIT)
318 #define DO_FULL_QUAD 1
323 #define QUAD( a, b, c, d ) fmesa->draw_quad( ctx, a, b, c, d )
324 #define TRI( a, b, c ) fmesa->draw_tri( ctx, a, b, c )
325 #define LINE( a, b ) fmesa->draw_line( ctx, a, b )
326 #define POINT( a ) fmesa->draw_point( ctx, a )
328 #define HAVE_BACK_COLORS 1
331 #define HAVE_HW_FLATSHADE 1
332 #define VERTEX ffb_vertex
335 #define UNFILLED_TRI unfilled_tri
336 #define UNFILLED_QUAD unfilled_quad
337 #define DEPTH_SCALE (fmesa->depth_scale)
338 #define VERT_X(_v) (_v->x)
339 #define VERT_Y(_v) (_v->y)
340 #define VERT_Z(_v) (_v->z)
341 #define AREA_IS_CCW( a ) (a < fmesa->ffb_zero)
342 #define GET_VERTEX(e) (&fmesa->verts[e])
343 #define INSANE_VERTICES
344 #define VERT_SET_Z(v,val) ((v)->z = (val))
345 #define VERT_Z_ADD(v,val) ((v)->z += (val))
347 #define VERT_COPY_RGBA1( _v ) _v->color[0] = _v->color[1]
348 #define VERT_COPY_RGBA( v0, v1 ) v0->color[0] = v1->color[0]
349 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->color[0]
350 #define VERT_RESTORE_RGBA( idx ) v[idx]->color[0] = color[idx]
352 #define LOCAL_VARS(n) \
353 ffbContextPtr fmesa = FFB_CONTEXT(ctx); \
354 __DRIdrawablePrivate *dPriv = fmesa->driDrawable; \
355 ffb_color color[n]; \
356 (void) color; (void) dPriv;
358 /***********************************************************************
359 * Helpers for rendering unfilled primitives *
360 ***********************************************************************/
362 #define RASTERIZE(x) if (fmesa->raster_primitive != reduced_prim[x]) \
363 ffbRasterPrimitive( ctx, reduced_prim[x] )
364 #define RENDER_PRIMITIVE fmesa->render_primitive
366 #include "tnl_dd/t_dd_unfilled.h"
368 /***********************************************************************
369 * Generate GL render functions *
370 ***********************************************************************/
374 #include "tnl_dd/t_dd_tritmp.h"
376 #define IND (FFB_OFFSET_BIT)
377 #define TAG(x) x##_offset
378 #include "tnl_dd/t_dd_tritmp.h"
380 #define IND (FFB_TWOSIDE_BIT)
381 #define TAG(x) x##_twoside
382 #include "tnl_dd/t_dd_tritmp.h"
384 #define IND (FFB_TWOSIDE_BIT|FFB_OFFSET_BIT)
385 #define TAG(x) x##_twoside_offset
386 #include "tnl_dd/t_dd_tritmp.h"
388 #define IND (FFB_UNFILLED_BIT)
389 #define TAG(x) x##_unfilled
390 #include "tnl_dd/t_dd_tritmp.h"
392 #define IND (FFB_OFFSET_BIT|FFB_UNFILLED_BIT)
393 #define TAG(x) x##_offset_unfilled
394 #include "tnl_dd/t_dd_tritmp.h"
396 #define IND (FFB_TWOSIDE_BIT|FFB_UNFILLED_BIT)
397 #define TAG(x) x##_twoside_unfilled
398 #include "tnl_dd/t_dd_tritmp.h"
400 #define IND (FFB_TWOSIDE_BIT|FFB_OFFSET_BIT|FFB_UNFILLED_BIT)
401 #define TAG(x) x##_twoside_offset_unfilled
402 #include "tnl_dd/t_dd_tritmp.h"
404 static void init_rast_tab( void )
409 init_twoside_offset();
411 init_offset_unfilled();
412 init_twoside_unfilled();
413 init_twoside_offset_unfilled();
416 /**********************************************************************/
417 /* Render clipped primitives */
418 /**********************************************************************/
420 static void ffbRenderClippedPolygon(GLcontext
*ctx
, const GLuint
*elts
, GLuint n
)
422 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
423 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
424 struct vertex_buffer
*VB
= &tnl
->vb
;
425 GLuint prim
= fmesa
->render_primitive
;
427 /* Render the new vertices as an unclipped polygon. */
429 GLuint
*tmp
= VB
->Elts
;
430 VB
->Elts
= (GLuint
*)elts
;
431 tnl
->Driver
.Render
.PrimTabElts
[GL_POLYGON
](ctx
, 0, n
, PRIM_BEGIN
|PRIM_END
);
435 /* Restore the render primitive. */
436 if (prim
!= GL_POLYGON
)
437 tnl
->Driver
.Render
.PrimitiveNotify(ctx
, prim
);
440 static void ffbRenderClippedLine(GLcontext
*ctx
, GLuint ii
, GLuint jj
)
442 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
443 tnl
->Driver
.Render
.Line(ctx
, ii
, jj
);
446 /**********************************************************************/
447 /* Render unclipped begin/end objects */
448 /**********************************************************************/
450 static void ffb_vb_noop(GLcontext
*ctx
, GLuint start
, GLuint count
, GLuint flags
)
452 (void)(ctx
&& start
&& count
&& flags
);
459 #include "ffb_rendertmp.h"
461 #define IND (FFB_FLAT_BIT)
462 #define TAG(x) x##_flat
463 #include "ffb_rendertmp.h"
465 #define IND (FFB_ALPHA_BIT)
466 #define TAG(x) x##_alpha
467 #include "ffb_rendertmp.h"
469 #define IND (FFB_FLAT_BIT | FFB_ALPHA_BIT)
470 #define TAG(x) x##_flat_alpha
471 #include "ffb_rendertmp.h"
473 #define IND (FFB_TRI_CULL_BIT)
474 #define TAG(x) x##_tricull
475 #include "ffb_rendertmp.h"
477 #define IND (FFB_FLAT_BIT | FFB_TRI_CULL_BIT)
478 #define TAG(x) x##_flat_tricull
479 #include "ffb_rendertmp.h"
481 #define IND (FFB_ALPHA_BIT | FFB_TRI_CULL_BIT)
482 #define TAG(x) x##_alpha_tricull
483 #include "ffb_rendertmp.h"
485 #define IND (FFB_FLAT_BIT | FFB_ALPHA_BIT | FFB_TRI_CULL_BIT)
486 #define TAG(x) x##_flat_alpha_tricull
487 #include "ffb_rendertmp.h"
490 #define ELT(x) elt[x]
493 #define TAG(x) x##_elt
494 #include "ffb_rendertmp.h"
496 #define IND (FFB_FLAT_BIT)
497 #define TAG(x) x##_flat_elt
498 #include "ffb_rendertmp.h"
500 #define IND (FFB_ALPHA_BIT)
501 #define TAG(x) x##_alpha_elt
502 #include "ffb_rendertmp.h"
504 #define IND (FFB_FLAT_BIT | FFB_ALPHA_BIT)
505 #define TAG(x) x##_flat_alpha_elt
506 #include "ffb_rendertmp.h"
508 #define IND (FFB_TRI_CULL_BIT)
509 #define TAG(x) x##_tricull_elt
510 #include "ffb_rendertmp.h"
512 #define IND (FFB_FLAT_BIT | FFB_TRI_CULL_BIT)
513 #define TAG(x) x##_flat_tricull_elt
514 #include "ffb_rendertmp.h"
516 #define IND (FFB_ALPHA_BIT | FFB_TRI_CULL_BIT)
517 #define TAG(x) x##_alpha_tricull_elt
518 #include "ffb_rendertmp.h"
520 #define IND (FFB_FLAT_BIT | FFB_ALPHA_BIT | FFB_TRI_CULL_BIT)
521 #define TAG(x) x##_flat_alpha_tricull_elt
522 #include "ffb_rendertmp.h"
524 static void *render_tabs
[MAX_FFB_RENDER_FUNCS
];
525 static void *render_tabs_elt
[MAX_FFB_RENDER_FUNCS
];
527 static void init_render_tab(void)
531 render_tabs
[0] = render_tab
;
532 render_tabs
[FFB_FLAT_BIT
] = render_tab_flat
;
533 render_tabs
[FFB_ALPHA_BIT
] = render_tab_alpha
;
534 render_tabs
[FFB_FLAT_BIT
|FFB_ALPHA_BIT
] = render_tab_flat_alpha
;
535 render_tabs
[FFB_TRI_CULL_BIT
] = render_tab_tricull
;
536 render_tabs
[FFB_FLAT_BIT
|FFB_TRI_CULL_BIT
] = render_tab_flat_tricull
;
537 render_tabs
[FFB_ALPHA_BIT
|FFB_TRI_CULL_BIT
] = render_tab_alpha_tricull
;
538 render_tabs
[FFB_FLAT_BIT
|FFB_ALPHA_BIT
|FFB_TRI_CULL_BIT
] =
539 render_tab_flat_alpha_tricull
;
541 render_tabs_elt
[0] = render_tab_elt
;
542 render_tabs_elt
[FFB_FLAT_BIT
] = render_tab_flat_elt
;
543 render_tabs_elt
[FFB_ALPHA_BIT
] = render_tab_alpha_elt
;
544 render_tabs_elt
[FFB_FLAT_BIT
|FFB_ALPHA_BIT
] = render_tab_flat_alpha_elt
;
545 render_tabs_elt
[FFB_TRI_CULL_BIT
] = render_tab_tricull_elt
;
546 render_tabs_elt
[FFB_FLAT_BIT
|FFB_TRI_CULL_BIT
] = render_tab_flat_tricull_elt
;
547 render_tabs_elt
[FFB_ALPHA_BIT
|FFB_TRI_CULL_BIT
] = render_tab_alpha_tricull_elt
;
548 render_tabs_elt
[FFB_FLAT_BIT
|FFB_ALPHA_BIT
|FFB_TRI_CULL_BIT
] =
549 render_tab_flat_alpha_tricull_elt
;
551 for (i
= 0; i
< MAX_FFB_RENDER_FUNCS
; i
++) {
552 tnl_render_func
*rf
= render_tabs
[i
];
553 tnl_render_func
*rfe
= render_tabs_elt
[i
];
555 if (i
& FFB_TRI_CULL_BIT
) {
556 int from_idx
= (i
& ~FFB_TRI_CULL_BIT
);
557 tnl_render_func
*rf_from
= render_tabs
[from_idx
];
558 tnl_render_func
*rfe_from
= render_tabs_elt
[from_idx
];
561 for (j
= GL_POINTS
; j
< GL_TRIANGLES
; j
++) {
563 rfe
[j
] = rfe_from
[j
];
569 /**********************************************************************/
570 /* Choose render functions */
571 /**********************************************************************/
573 #ifdef FFB_RENDER_TRACE
574 static void ffbPrintRenderFlags(GLuint index
, GLuint render_index
)
577 "ffbChooseRenderState: "
579 "render_index(%s%s%s)\n",
580 ((index
& FFB_TWOSIDE_BIT
) ? "twoside " : ""),
581 ((index
& FFB_OFFSET_BIT
) ? "offset " : ""),
582 ((index
& FFB_UNFILLED_BIT
) ? "unfilled " : ""),
583 ((render_index
& FFB_FLAT_BIT
) ? "flat " : ""),
584 ((render_index
& FFB_ALPHA_BIT
) ? "alpha " : ""),
585 ((render_index
& FFB_TRI_CULL_BIT
) ? "tricull " : ""));
589 void ffbChooseRenderState(GLcontext
*ctx
)
591 GLuint flags
= ctx
->_TriangleCaps
;
592 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
595 /* Per-primitive fallbacks and the selection of fmesa->draw_* are
598 if (flags
& DD_TRI_LIGHT_TWOSIDE
)
599 index
|= FFB_TWOSIDE_BIT
;
601 if (flags
& DD_TRI_OFFSET
)
602 index
|= FFB_OFFSET_BIT
;
604 if (flags
& DD_TRI_UNFILLED
)
605 index
|= FFB_UNFILLED_BIT
;
607 tnl
->Driver
.Render
.Triangle
= rast_tab
[index
].triangle
;
608 tnl
->Driver
.Render
.Quad
= rast_tab
[index
].quad
;
611 GLuint render_index
= 0;
613 if (flags
& DD_FLATSHADE
)
614 render_index
|= FFB_FLAT_BIT
;
616 if (ctx
->Color
.BlendEnabled
|| ctx
->Color
.AlphaEnabled
)
617 render_index
|= FFB_ALPHA_BIT
;
619 if (ctx
->Polygon
.CullFlag
)
620 render_index
|= FFB_TRI_CULL_BIT
;
622 #ifdef FFB_RENDER_TRACE
623 ffbPrintRenderFlags(index
, render_index
);
625 tnl
->Driver
.Render
.PrimTabVerts
= render_tabs
[render_index
];
626 tnl
->Driver
.Render
.PrimTabElts
= render_tabs_elt
[render_index
];
628 #ifdef FFB_RENDER_TRACE
629 ffbPrintRenderFlags(index
, 0);
631 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
632 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
635 tnl
->Driver
.Render
.ClippedPolygon
= ffbRenderClippedPolygon
;
636 tnl
->Driver
.Render
.ClippedLine
= ffbRenderClippedLine
;
639 static void ffbRunPipeline(GLcontext
*ctx
)
641 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
643 if (fmesa
->bad_fragment_attrs
== 0 &&
644 fmesa
->new_gl_state
) {
645 if (fmesa
->new_gl_state
& _FFB_NEW_TRIANGLE
)
646 ffbChooseTriangleState(ctx
);
647 if (fmesa
->new_gl_state
& _FFB_NEW_LINE
)
648 ffbChooseLineState(ctx
);
649 if (fmesa
->new_gl_state
& _FFB_NEW_POINT
)
650 ffbChoosePointState(ctx
);
651 if (fmesa
->new_gl_state
& _FFB_NEW_RENDER
)
652 ffbChooseRenderState(ctx
);
653 if (fmesa
->new_gl_state
& _FFB_NEW_VERTEX
)
654 ffbChooseVertexState(ctx
);
656 fmesa
->new_gl_state
= 0;
659 _tnl_run_pipeline(ctx
);
662 static void ffbRenderStart(GLcontext
*ctx
)
664 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
666 LOCK_HARDWARE(fmesa
);
667 fmesa
->hw_locked
= 1;
669 if (fmesa
->state_dirty
!= 0)
670 ffbSyncHardware(fmesa
);
673 static void ffbRenderFinish(GLcontext
*ctx
)
675 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
677 UNLOCK_HARDWARE(fmesa
);
678 fmesa
->hw_locked
= 0;
681 /* Even when doing full software rendering we need to
682 * wrap render{start,finish} so that the hardware is kept
683 * in sync (because multipass rendering changes the write
686 static void ffbSWRenderStart(GLcontext
*ctx
)
688 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
690 LOCK_HARDWARE(fmesa
);
691 fmesa
->hw_locked
= 1;
693 if (fmesa
->state_dirty
!= 0)
694 ffbSyncHardware(fmesa
);
697 static void ffbSWRenderFinish(GLcontext
*ctx
)
699 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
701 UNLOCK_HARDWARE(fmesa
);
702 fmesa
->hw_locked
= 0;
705 static void ffbRasterPrimitive(GLcontext
*ctx
, GLenum rprim
)
707 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
708 GLuint drawop
, fbc
, ppc
;
711 fmesa
->raster_primitive
= rprim
;
713 drawop
= fmesa
->drawop
;
715 ppc
= fmesa
->ppc
& ~(FFB_PPC_ZS_MASK
| FFB_PPC_CS_MASK
);
719 "ffbReducedPrimitiveChange: rprim(%d) ", rprim
);
724 fprintf(stderr
, "GL_POINTS ");
726 if (fmesa
->draw_point
== ffb_fallback_point
) {
731 if (ctx
->Point
.SmoothFlag
) {
732 ppc
|= (FFB_PPC_ZS_VAR
| FFB_PPC_CS_CONST
);
733 drawop
= FFB_DRAWOP_AADOT
;
735 ppc
|= (FFB_PPC_ZS_CONST
| FFB_PPC_CS_CONST
);
736 drawop
= FFB_DRAWOP_DOT
;
742 fprintf(stderr
, "GL_LINES ");
744 if (fmesa
->draw_line
== ffb_fallback_line
) {
749 if (ctx
->_TriangleCaps
& DD_FLATSHADE
) {
750 ppc
|= FFB_PPC_ZS_VAR
| FFB_PPC_CS_CONST
;
752 ppc
|= FFB_PPC_ZS_VAR
| FFB_PPC_CS_VAR
;
754 if (ctx
->Line
.SmoothFlag
)
755 drawop
= FFB_DRAWOP_AALINE
;
757 drawop
= FFB_DRAWOP_DDLINE
;
762 fprintf(stderr
, "GL_POLYGON ");
764 if (fmesa
->draw_tri
== ffb_fallback_triangle
) {
769 ppc
&= ~FFB_PPC_APE_MASK
;
770 if (ctx
->Polygon
.StippleFlag
)
771 ppc
|= FFB_PPC_APE_ENABLE
;
773 ppc
|= FFB_PPC_APE_DISABLE
;
775 if (ctx
->_TriangleCaps
& DD_FLATSHADE
) {
776 ppc
|= FFB_PPC_ZS_VAR
| FFB_PPC_CS_CONST
;
778 ppc
|= FFB_PPC_ZS_VAR
| FFB_PPC_CS_VAR
;
780 drawop
= FFB_DRAWOP_TRIANGLE
;
785 fprintf(stderr
, "unknown %d!\n", rprim
);
791 fprintf(stderr
, "do_sw(%d) ", do_sw
);
794 fbc
&= ~(FFB_FBC_WB_C
);
795 fbc
&= ~(FFB_FBC_ZE_MASK
| FFB_FBC_RGBE_MASK
);
796 fbc
|= FFB_FBC_ZE_OFF
| FFB_FBC_RGBE_MASK
;
797 ppc
&= ~(FFB_PPC_XS_MASK
| FFB_PPC_ABE_MASK
|
798 FFB_PPC_DCE_MASK
| FFB_PPC_APE_MASK
);
799 ppc
|= (FFB_PPC_ZS_VAR
| FFB_PPC_CS_VAR
| FFB_PPC_XS_WID
|
800 FFB_PPC_ABE_DISABLE
| FFB_PPC_DCE_DISABLE
|
801 FFB_PPC_APE_DISABLE
);
804 fbc
&= ~(FFB_FBC_RGBE_MASK
);
805 fbc
|= FFB_FBC_RGBE_MASK
;
806 ppc
&= ~(FFB_PPC_ABE_MASK
| FFB_PPC_XS_MASK
);
807 if (ctx
->Color
.BlendEnabled
) {
808 if ((rprim
== GL_POINTS
&& !ctx
->Point
.SmoothFlag
) ||
809 (rprim
!= GL_POINTS
&& ctx
->_TriangleCaps
& DD_FLATSHADE
))
810 ppc
|= FFB_PPC_ABE_ENABLE
| FFB_PPC_XS_CONST
;
812 ppc
|= FFB_PPC_ABE_ENABLE
| FFB_PPC_XS_VAR
;
814 ppc
|= FFB_PPC_ABE_DISABLE
| FFB_PPC_XS_WID
;
818 fprintf(stderr
, "fbc(%08x) ppc(%08x)\n", fbc
, ppc
);
822 if (fmesa
->drawop
!= drawop
)
823 fmesa
->regs
->drawop
= fmesa
->drawop
= drawop
;
824 if (fmesa
->fbc
!= fbc
)
825 fmesa
->regs
->fbc
= fmesa
->fbc
= fbc
;
826 if (fmesa
->ppc
!= ppc
)
827 fmesa
->regs
->ppc
= fmesa
->ppc
= ppc
;
830 (fmesa
->cmp
& ~(0xff<<16)) | (0x80 << 16);
832 fmesa
->regs
->cmp
= fmesa
->cmp
;
835 static void ffbRenderPrimitive(GLcontext
*ctx
, GLenum prim
)
837 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
838 GLuint rprim
= reduced_prim
[prim
];
840 fmesa
->render_primitive
= prim
;
842 if (rprim
== GL_TRIANGLES
&& (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
))
845 if (fmesa
->raster_primitive
!= rprim
) {
846 ffbRasterPrimitive( ctx
, rprim
);
853 /**********************************************************************/
854 /* Transition to/from hardware rasterization. */
855 /**********************************************************************/
857 static char *fallbackStrings
[] = {
864 "LIBGL_SOFTWARE_RENDERING"
867 static char *getFallbackString(GLuint bit
)
875 return fallbackStrings
[i
];
878 void ffbFallback( GLcontext
*ctx
, GLuint bit
, GLboolean mode
)
880 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
881 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
882 GLuint oldfallback
= fmesa
->bad_fragment_attrs
;
885 fmesa
->bad_fragment_attrs
|= bit
;
886 if (oldfallback
== 0) {
887 /* FFB_FIREVERTICES(fmesa); */
888 _swsetup_Wakeup( ctx
);
889 if (fmesa
->debugFallbacks
)
890 fprintf(stderr
, "FFB begin software fallback: 0x%x %s\n",
891 bit
, getFallbackString(bit
));
894 fmesa
->bad_fragment_attrs
&= ~bit
;
895 if (oldfallback
== bit
) {
896 _swrast_flush( ctx
);
898 tnl
->Driver
.Render
.Start
= ffbRenderStart
;
899 tnl
->Driver
.Render
.PrimitiveNotify
= ffbRenderPrimitive
;
900 tnl
->Driver
.Render
.Finish
= ffbRenderFinish
;
901 fmesa
->new_gl_state
= ~0;
903 /* Just re-choose everything:
905 ffbChooseVertexState(ctx
);
906 ffbChooseRenderState(ctx
);
907 ffbChooseTriangleState(ctx
);
908 ffbChooseLineState(ctx
);
909 ffbChoosePointState(ctx
);
911 if (fmesa
->debugFallbacks
)
912 fprintf(stderr
, "FFB end software fallback: 0x%x %s\n",
913 bit
, getFallbackString(bit
));
918 /**********************************************************************/
919 /* Initialization. */
920 /**********************************************************************/
922 void ffbDDInitRenderFuncs( GLcontext
*ctx
)
924 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
925 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
926 static int firsttime
= 1;
935 tnl
->Driver
.RunPipeline
= ffbRunPipeline
;
936 tnl
->Driver
.Render
.Start
= ffbRenderStart
;
937 tnl
->Driver
.Render
.Finish
= ffbRenderFinish
;
938 tnl
->Driver
.Render
.PrimitiveNotify
= ffbRenderPrimitive
;
939 tnl
->Driver
.Render
.ResetLineStipple
= _swrast_ResetLineStipple
;
940 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
941 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
943 swrast
->Driver
.SpanRenderStart
= ffbSWRenderStart
;
944 swrast
->Driver
.SpanRenderFinish
= ffbSWRenderFinish
;