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>
32 #include "swrast/swrast.h"
33 #include "swrast_setup/swrast_setup.h"
34 #include "swrast/s_context.h"
35 #include "tnl/t_context.h"
36 #include "tnl/t_pipeline.h"
38 #include "ffb_context.h"
40 #include "ffb_lines.h"
42 #include "ffb_points.h"
43 #include "ffb_state.h"
47 #undef FFB_RENDER_TRACE
51 static void ffb_print_vertex(const ffb_vertex
*v
)
53 fprintf(stderr
, "Vertex @(%p): "
54 "X[%f] Y[%f] Z[%f]\n",
56 fprintf(stderr
, "Vertex @(%p): "
57 "A[%f] R[%f] G[%f] B[%f]\n",
64 #define FFB_DUMP_VERTEX(V) ffb_print_vertex(V)
66 #define FFB_DUMP_VERTEX(V) do { } while(0)
69 #define FFB_ALPHA_BIT 0x01
70 #define FFB_FLAT_BIT 0x02
71 #define FFB_TRI_CULL_BIT 0x04
72 #define MAX_FFB_RENDER_FUNCS 0x08
74 /***********************************************************************
75 * Build low-level triangle/quad rasterize functions *
76 ***********************************************************************/
78 #define FFB_TRI_FLAT_BIT 0x01
79 #define FFB_TRI_ALPHA_BIT 0x02
80 /*#define FFB_TRI_CULL_BIT 0x04*/
82 static ffb_tri_func ffb_tri_tab
[0x8];
83 static ffb_quad_func ffb_quad_tab
[0x8];
87 #include "ffb_tritmp.h"
89 #define IND (FFB_TRI_FLAT_BIT)
90 #define TAG(x) x##_flat
91 #include "ffb_tritmp.h"
93 #define IND (FFB_TRI_CULL_BIT)
94 #define TAG(x) x##_cull
95 #include "ffb_tritmp.h"
97 #define IND (FFB_TRI_CULL_BIT|FFB_TRI_FLAT_BIT)
98 #define TAG(x) x##_cull_flat
99 #include "ffb_tritmp.h"
101 #define IND (FFB_TRI_ALPHA_BIT)
102 #define TAG(x) x##_alpha
103 #include "ffb_tritmp.h"
105 #define IND (FFB_TRI_ALPHA_BIT|FFB_TRI_FLAT_BIT)
106 #define TAG(x) x##_alpha_flat
107 #include "ffb_tritmp.h"
109 #define IND (FFB_TRI_ALPHA_BIT|FFB_TRI_CULL_BIT)
110 #define TAG(x) x##_alpha_cull
111 #include "ffb_tritmp.h"
113 #define IND (FFB_TRI_ALPHA_BIT|FFB_TRI_CULL_BIT|FFB_TRI_FLAT_BIT)
114 #define TAG(x) x##_alpha_cull_flat
115 #include "ffb_tritmp.h"
117 static void init_tri_tab(void)
122 ffb_init_cull_flat();
124 ffb_init_alpha_flat();
125 ffb_init_alpha_cull();
126 ffb_init_alpha_cull_flat();
129 /* Build a SWvertex from a hardware vertex. */
130 static void ffb_translate_vertex(GLcontext
*ctx
, const ffb_vertex
*src
,
133 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
134 GLfloat
*m
= ctx
->Viewport
._WindowMap
.m
;
135 const GLfloat sx
= m
[0];
136 const GLfloat sy
= m
[5];
137 const GLfloat sz
= m
[10];
138 const GLfloat tx
= m
[12];
139 const GLfloat ty
= m
[13];
140 const GLfloat tz
= m
[14];
142 dst
->win
[0] = sx
* src
->x
+ tx
;
143 dst
->win
[1] = sy
* src
->y
+ ty
;
144 dst
->win
[2] = sz
* src
->z
+ tz
;
147 dst
->color
[0] = FFB_UBYTE_FROM_COLOR(src
->color
[0].red
);
148 dst
->color
[1] = FFB_UBYTE_FROM_COLOR(src
->color
[0].green
);
149 dst
->color
[2] = FFB_UBYTE_FROM_COLOR(src
->color
[0].blue
);
150 dst
->color
[3] = FFB_UBYTE_FROM_COLOR(src
->color
[0].alpha
);
153 /***********************************************************************
154 * Build fallback triangle/quad rasterize functions *
155 ***********************************************************************/
157 static void ffb_fallback_triangle(GLcontext
*ctx
, ffb_vertex
*v0
,
158 ffb_vertex
*v1
, ffb_vertex
*v2
)
162 ffb_translate_vertex(ctx
, v0
, &v
[0]);
163 ffb_translate_vertex(ctx
, v1
, &v
[1]);
164 ffb_translate_vertex(ctx
, v2
, &v
[2]);
166 _swrast_Triangle(ctx
, &v
[0], &v
[1], &v
[2]);
169 static void ffb_fallback_quad(GLcontext
*ctx
,
170 ffb_vertex
*v0
, ffb_vertex
*v1
,
171 ffb_vertex
*v2
, ffb_vertex
*v3
)
175 ffb_translate_vertex(ctx
, v0
, &v
[0]);
176 ffb_translate_vertex(ctx
, v1
, &v
[1]);
177 ffb_translate_vertex(ctx
, v2
, &v
[2]);
178 ffb_translate_vertex(ctx
, v3
, &v
[3]);
180 _swrast_Quad(ctx
, &v
[0], &v
[1], &v
[2], &v
[3]);
183 void ffb_fallback_line(GLcontext
*ctx
, ffb_vertex
*v0
, ffb_vertex
*v1
)
187 ffb_translate_vertex(ctx
, v0
, &v
[0]);
188 ffb_translate_vertex(ctx
, v1
, &v
[1]);
190 _swrast_Line(ctx
, &v
[0], &v
[1]);
193 void ffb_fallback_point(GLcontext
*ctx
, ffb_vertex
*v0
)
197 ffb_translate_vertex(ctx
, v0
, &v
[0]);
199 _swrast_Point(ctx
, &v
[0]);
202 /***********************************************************************
203 * Rasterization functions for culled tris/quads *
204 ***********************************************************************/
206 static void ffb_nodraw_triangle(GLcontext
*ctx
, ffb_vertex
*v0
,
207 ffb_vertex
*v1
, ffb_vertex
*v2
)
209 (void) (ctx
&& v0
&& v1
&& v2
);
212 static void ffb_nodraw_quad(GLcontext
*ctx
,
213 ffb_vertex
*v0
, ffb_vertex
*v1
,
214 ffb_vertex
*v2
, ffb_vertex
*v3
)
216 (void) (ctx
&& v0
&& v1
&& v2
&& v3
);
219 static void ffb_update_cullsign(GLcontext
*ctx
)
221 GLfloat backface_sign
= 1;
223 switch (ctx
->Polygon
.CullFaceMode
) {
225 if (ctx
->Polygon
.FrontFace
==GL_CCW
)
230 if (ctx
->Polygon
.FrontFace
!=GL_CCW
)
238 FFB_CONTEXT(ctx
)->backface_sign
= backface_sign
;
241 /***********************************************************************
242 * Choose triangle/quad rasterize functions *
243 ***********************************************************************/
245 void ffbChooseTriangleState(GLcontext
*ctx
)
247 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
248 GLuint flags
= ctx
->_TriangleCaps
;
251 if (flags
& DD_TRI_SMOOTH
) {
252 fmesa
->draw_tri
= ffb_fallback_triangle
;
253 fmesa
->draw_quad
= ffb_fallback_quad
;
257 if (flags
& DD_FLATSHADE
)
258 ind
|= FFB_TRI_FLAT_BIT
;
260 if (ctx
->Polygon
.CullFlag
) {
261 if (ctx
->Polygon
.CullFaceMode
== GL_FRONT_AND_BACK
) {
262 fmesa
->draw_tri
= ffb_nodraw_triangle
;
263 fmesa
->draw_quad
= ffb_nodraw_quad
;
267 ind
|= FFB_TRI_CULL_BIT
;
268 ffb_update_cullsign(ctx
);
270 FFB_CONTEXT(ctx
)->backface_sign
= 0;
272 /* If blending or the alpha test is enabled we need to
273 * provide alpha components to the chip, else we can
274 * do without it and thus feed vertex data to the chip
277 if (ctx
->Color
.BlendEnabled
|| ctx
->Color
.AlphaEnabled
)
278 ind
|= FFB_TRI_ALPHA_BIT
;
280 fmesa
->draw_tri
= ffb_tri_tab
[ind
];
281 fmesa
->draw_quad
= ffb_quad_tab
[ind
];
284 static const GLenum reduced_prim
[GL_POLYGON
+1] = {
297 static void ffbRenderPrimitive(GLcontext
*ctx
, GLenum prim
);
298 static void ffbRasterPrimitive(GLcontext
*ctx
, GLenum rprim
);
300 /***********************************************************************
301 * Build render functions from dd templates *
302 ***********************************************************************/
304 #define FFB_OFFSET_BIT 0x01
305 #define FFB_TWOSIDE_BIT 0x02
306 #define FFB_UNFILLED_BIT 0x04
307 #define FFB_MAX_TRIFUNC 0x08
310 triangle_func triangle
;
312 } rast_tab
[FFB_MAX_TRIFUNC
];
314 #define DO_OFFSET (IND & FFB_OFFSET_BIT)
315 #define DO_UNFILLED (IND & FFB_UNFILLED_BIT)
316 #define DO_TWOSIDE (IND & FFB_TWOSIDE_BIT)
319 #define DO_FULL_QUAD 1
324 #define QUAD( a, b, c, d ) fmesa->draw_quad( ctx, a, b, c, d )
325 #define TRI( a, b, c ) fmesa->draw_tri( ctx, a, b, c )
326 #define LINE( a, b ) fmesa->draw_line( ctx, a, b )
327 #define POINT( a ) fmesa->draw_point( ctx, a )
329 #define HAVE_BACK_COLORS 1
332 #define HAVE_HW_FLATSHADE 1
333 #define VERTEX ffb_vertex
336 #define UNFILLED_TRI unfilled_tri
337 #define UNFILLED_QUAD unfilled_quad
338 #define DEPTH_SCALE (fmesa->depth_scale)
339 #define VERT_X(_v) (_v->x)
340 #define VERT_Y(_v) (_v->y)
341 #define VERT_Z(_v) (_v->z)
342 #define AREA_IS_CCW( a ) (a < fmesa->ffb_zero)
343 #define GET_VERTEX(e) (&fmesa->verts[e])
344 #define INSANE_VERTICES
345 #define VERT_SET_Z(v,val) ((v)->z = (val))
346 #define VERT_Z_ADD(v,val) ((v)->z += (val))
348 #define VERT_COPY_RGBA1( _v ) _v->color[0] = _v->color[1]
349 #define VERT_COPY_RGBA( v0, v1 ) v0->color[0] = v1->color[0]
350 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->color[0]
351 #define VERT_RESTORE_RGBA( idx ) v[idx]->color[0] = color[idx]
353 #define LOCAL_VARS(n) \
354 ffbContextPtr fmesa = FFB_CONTEXT(ctx); \
355 __DRIdrawablePrivate *dPriv = fmesa->driDrawable; \
356 ffb_color color[n]; \
357 (void) color; (void) dPriv;
359 /***********************************************************************
360 * Helpers for rendering unfilled primitives *
361 ***********************************************************************/
363 #define RASTERIZE(x) if (fmesa->raster_primitive != reduced_prim[x]) \
364 ffbRasterPrimitive( ctx, reduced_prim[x] )
365 #define RENDER_PRIMITIVE fmesa->render_primitive
367 #include "tnl_dd/t_dd_unfilled.h"
369 /***********************************************************************
370 * Generate GL render functions *
371 ***********************************************************************/
375 #include "tnl_dd/t_dd_tritmp.h"
377 #define IND (FFB_OFFSET_BIT)
378 #define TAG(x) x##_offset
379 #include "tnl_dd/t_dd_tritmp.h"
381 #define IND (FFB_TWOSIDE_BIT)
382 #define TAG(x) x##_twoside
383 #include "tnl_dd/t_dd_tritmp.h"
385 #define IND (FFB_TWOSIDE_BIT|FFB_OFFSET_BIT)
386 #define TAG(x) x##_twoside_offset
387 #include "tnl_dd/t_dd_tritmp.h"
389 #define IND (FFB_UNFILLED_BIT)
390 #define TAG(x) x##_unfilled
391 #include "tnl_dd/t_dd_tritmp.h"
393 #define IND (FFB_OFFSET_BIT|FFB_UNFILLED_BIT)
394 #define TAG(x) x##_offset_unfilled
395 #include "tnl_dd/t_dd_tritmp.h"
397 #define IND (FFB_TWOSIDE_BIT|FFB_UNFILLED_BIT)
398 #define TAG(x) x##_twoside_unfilled
399 #include "tnl_dd/t_dd_tritmp.h"
401 #define IND (FFB_TWOSIDE_BIT|FFB_OFFSET_BIT|FFB_UNFILLED_BIT)
402 #define TAG(x) x##_twoside_offset_unfilled
403 #include "tnl_dd/t_dd_tritmp.h"
405 static void init_rast_tab( void )
410 init_twoside_offset();
412 init_offset_unfilled();
413 init_twoside_unfilled();
414 init_twoside_offset_unfilled();
417 /**********************************************************************/
418 /* Render clipped primitives */
419 /**********************************************************************/
421 static void ffbRenderClippedPolygon(GLcontext
*ctx
, const GLuint
*elts
, GLuint n
)
423 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
424 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
425 struct vertex_buffer
*VB
= &tnl
->vb
;
426 GLuint prim
= fmesa
->render_primitive
;
428 /* Render the new vertices as an unclipped polygon. */
430 GLuint
*tmp
= VB
->Elts
;
431 VB
->Elts
= (GLuint
*)elts
;
432 tnl
->Driver
.Render
.PrimTabElts
[GL_POLYGON
](ctx
, 0, n
, PRIM_BEGIN
|PRIM_END
);
436 /* Restore the render primitive. */
437 if (prim
!= GL_POLYGON
)
438 tnl
->Driver
.Render
.PrimitiveNotify(ctx
, prim
);
441 static void ffbRenderClippedLine(GLcontext
*ctx
, GLuint ii
, GLuint jj
)
443 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
444 tnl
->Driver
.Render
.Line(ctx
, ii
, jj
);
447 /**********************************************************************/
448 /* Render unclipped begin/end objects */
449 /**********************************************************************/
451 static void ffb_vb_noop(GLcontext
*ctx
, GLuint start
, GLuint count
, GLuint flags
)
453 (void)(ctx
&& start
&& count
&& flags
);
460 #include "ffb_rendertmp.h"
462 #define IND (FFB_FLAT_BIT)
463 #define TAG(x) x##_flat
464 #include "ffb_rendertmp.h"
466 #define IND (FFB_ALPHA_BIT)
467 #define TAG(x) x##_alpha
468 #include "ffb_rendertmp.h"
470 #define IND (FFB_FLAT_BIT | FFB_ALPHA_BIT)
471 #define TAG(x) x##_flat_alpha
472 #include "ffb_rendertmp.h"
474 #define IND (FFB_TRI_CULL_BIT)
475 #define TAG(x) x##_tricull
476 #include "ffb_rendertmp.h"
478 #define IND (FFB_FLAT_BIT | FFB_TRI_CULL_BIT)
479 #define TAG(x) x##_flat_tricull
480 #include "ffb_rendertmp.h"
482 #define IND (FFB_ALPHA_BIT | FFB_TRI_CULL_BIT)
483 #define TAG(x) x##_alpha_tricull
484 #include "ffb_rendertmp.h"
486 #define IND (FFB_FLAT_BIT | FFB_ALPHA_BIT | FFB_TRI_CULL_BIT)
487 #define TAG(x) x##_flat_alpha_tricull
488 #include "ffb_rendertmp.h"
491 #define ELT(x) elt[x]
494 #define TAG(x) x##_elt
495 #include "ffb_rendertmp.h"
497 #define IND (FFB_FLAT_BIT)
498 #define TAG(x) x##_flat_elt
499 #include "ffb_rendertmp.h"
501 #define IND (FFB_ALPHA_BIT)
502 #define TAG(x) x##_alpha_elt
503 #include "ffb_rendertmp.h"
505 #define IND (FFB_FLAT_BIT | FFB_ALPHA_BIT)
506 #define TAG(x) x##_flat_alpha_elt
507 #include "ffb_rendertmp.h"
509 #define IND (FFB_TRI_CULL_BIT)
510 #define TAG(x) x##_tricull_elt
511 #include "ffb_rendertmp.h"
513 #define IND (FFB_FLAT_BIT | FFB_TRI_CULL_BIT)
514 #define TAG(x) x##_flat_tricull_elt
515 #include "ffb_rendertmp.h"
517 #define IND (FFB_ALPHA_BIT | FFB_TRI_CULL_BIT)
518 #define TAG(x) x##_alpha_tricull_elt
519 #include "ffb_rendertmp.h"
521 #define IND (FFB_FLAT_BIT | FFB_ALPHA_BIT | FFB_TRI_CULL_BIT)
522 #define TAG(x) x##_flat_alpha_tricull_elt
523 #include "ffb_rendertmp.h"
525 static void *render_tabs
[MAX_FFB_RENDER_FUNCS
];
526 static void *render_tabs_elt
[MAX_FFB_RENDER_FUNCS
];
528 static void init_render_tab(void)
532 render_tabs
[0] = render_tab
;
533 render_tabs
[FFB_FLAT_BIT
] = render_tab_flat
;
534 render_tabs
[FFB_ALPHA_BIT
] = render_tab_alpha
;
535 render_tabs
[FFB_FLAT_BIT
|FFB_ALPHA_BIT
] = render_tab_flat_alpha
;
536 render_tabs
[FFB_TRI_CULL_BIT
] = render_tab_tricull
;
537 render_tabs
[FFB_FLAT_BIT
|FFB_TRI_CULL_BIT
] = render_tab_flat_tricull
;
538 render_tabs
[FFB_ALPHA_BIT
|FFB_TRI_CULL_BIT
] = render_tab_alpha_tricull
;
539 render_tabs
[FFB_FLAT_BIT
|FFB_ALPHA_BIT
|FFB_TRI_CULL_BIT
] =
540 render_tab_flat_alpha_tricull
;
542 render_tabs_elt
[0] = render_tab_elt
;
543 render_tabs_elt
[FFB_FLAT_BIT
] = render_tab_flat_elt
;
544 render_tabs_elt
[FFB_ALPHA_BIT
] = render_tab_alpha_elt
;
545 render_tabs_elt
[FFB_FLAT_BIT
|FFB_ALPHA_BIT
] = render_tab_flat_alpha_elt
;
546 render_tabs_elt
[FFB_TRI_CULL_BIT
] = render_tab_tricull_elt
;
547 render_tabs_elt
[FFB_FLAT_BIT
|FFB_TRI_CULL_BIT
] = render_tab_flat_tricull_elt
;
548 render_tabs_elt
[FFB_ALPHA_BIT
|FFB_TRI_CULL_BIT
] = render_tab_alpha_tricull_elt
;
549 render_tabs_elt
[FFB_FLAT_BIT
|FFB_ALPHA_BIT
|FFB_TRI_CULL_BIT
] =
550 render_tab_flat_alpha_tricull_elt
;
552 for (i
= 0; i
< MAX_FFB_RENDER_FUNCS
; i
++) {
553 render_func
*rf
= render_tabs
[i
];
554 render_func
*rfe
= render_tabs_elt
[i
];
556 if (i
& FFB_TRI_CULL_BIT
) {
557 int from_idx
= (i
& ~FFB_TRI_CULL_BIT
);
558 render_func
*rf_from
= render_tabs
[from_idx
];
559 render_func
*rfe_from
= render_tabs_elt
[from_idx
];
562 for (j
= GL_POINTS
; j
< GL_TRIANGLES
; j
++) {
564 rfe
[j
] = rfe_from
[j
];
570 /**********************************************************************/
571 /* Choose render functions */
572 /**********************************************************************/
574 #ifdef FFB_RENDER_TRACE
575 static void ffbPrintRenderFlags(GLuint index
, GLuint render_index
)
578 "ffbChooseRenderState: "
580 "render_index(%s%s%s)\n",
581 ((index
& FFB_TWOSIDE_BIT
) ? "twoside " : ""),
582 ((index
& FFB_OFFSET_BIT
) ? "offset " : ""),
583 ((index
& FFB_UNFILLED_BIT
) ? "unfilled " : ""),
584 ((render_index
& FFB_FLAT_BIT
) ? "flat " : ""),
585 ((render_index
& FFB_ALPHA_BIT
) ? "alpha " : ""),
586 ((render_index
& FFB_TRI_CULL_BIT
) ? "tricull " : ""));
590 void ffbChooseRenderState(GLcontext
*ctx
)
592 GLuint flags
= ctx
->_TriangleCaps
;
593 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
596 /* Per-primitive fallbacks and the selection of fmesa->draw_* are
599 if (flags
& DD_TRI_LIGHT_TWOSIDE
)
600 index
|= FFB_TWOSIDE_BIT
;
602 if (flags
& DD_TRI_OFFSET
)
603 index
|= FFB_OFFSET_BIT
;
605 if (flags
& DD_TRI_UNFILLED
)
606 index
|= FFB_UNFILLED_BIT
;
608 tnl
->Driver
.Render
.Triangle
= rast_tab
[index
].triangle
;
609 tnl
->Driver
.Render
.Quad
= rast_tab
[index
].quad
;
612 GLuint render_index
= 0;
614 if (flags
& DD_FLATSHADE
)
615 render_index
|= FFB_FLAT_BIT
;
617 if (ctx
->Color
.BlendEnabled
|| ctx
->Color
.AlphaEnabled
)
618 render_index
|= FFB_ALPHA_BIT
;
620 if (ctx
->Polygon
.CullFlag
)
621 render_index
|= FFB_TRI_CULL_BIT
;
623 #ifdef FFB_RENDER_TRACE
624 ffbPrintRenderFlags(index
, render_index
);
626 tnl
->Driver
.Render
.PrimTabVerts
= render_tabs
[render_index
];
627 tnl
->Driver
.Render
.PrimTabElts
= render_tabs_elt
[render_index
];
629 #ifdef FFB_RENDER_TRACE
630 ffbPrintRenderFlags(index
, 0);
632 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
633 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
636 tnl
->Driver
.Render
.ClippedPolygon
= ffbRenderClippedPolygon
;
637 tnl
->Driver
.Render
.ClippedLine
= ffbRenderClippedLine
;
640 static void ffbRunPipeline(GLcontext
*ctx
)
642 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
644 if (fmesa
->bad_fragment_attrs
== 0 &&
645 fmesa
->new_gl_state
) {
646 if (fmesa
->new_gl_state
& _FFB_NEW_TRIANGLE
)
647 ffbChooseTriangleState(ctx
);
648 if (fmesa
->new_gl_state
& _FFB_NEW_LINE
)
649 ffbChooseLineState(ctx
);
650 if (fmesa
->new_gl_state
& _FFB_NEW_POINT
)
651 ffbChoosePointState(ctx
);
652 if (fmesa
->new_gl_state
& _FFB_NEW_RENDER
)
653 ffbChooseRenderState(ctx
);
654 if (fmesa
->new_gl_state
& _FFB_NEW_VERTEX
)
655 ffbChooseVertexState(ctx
);
657 fmesa
->new_gl_state
= 0;
660 _tnl_run_pipeline(ctx
);
663 static void ffbRenderStart(GLcontext
*ctx
)
665 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
667 LOCK_HARDWARE(fmesa
);
668 fmesa
->hw_locked
= 1;
670 if (fmesa
->state_dirty
!= 0)
671 ffbSyncHardware(fmesa
);
674 static void ffbRenderFinish(GLcontext
*ctx
)
676 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
678 UNLOCK_HARDWARE(fmesa
);
679 fmesa
->hw_locked
= 0;
682 /* Even when doing full software rendering we need to
683 * wrap render{start,finish} so that the hardware is kept
684 * in sync (because multipass rendering changes the write
687 static void ffbSWRenderStart(GLcontext
*ctx
)
689 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
691 LOCK_HARDWARE(fmesa
);
692 fmesa
->hw_locked
= 1;
694 if (fmesa
->state_dirty
!= 0)
695 ffbSyncHardware(fmesa
);
698 static void ffbSWRenderFinish(GLcontext
*ctx
)
700 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
702 UNLOCK_HARDWARE(fmesa
);
703 fmesa
->hw_locked
= 0;
706 static void ffbRasterPrimitive(GLcontext
*ctx
, GLenum rprim
)
708 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
709 GLuint drawop
, fbc
, ppc
;
712 fmesa
->raster_primitive
= rprim
;
714 drawop
= fmesa
->drawop
;
716 ppc
= fmesa
->ppc
& ~(FFB_PPC_ZS_MASK
| FFB_PPC_CS_MASK
);
720 "ffbReducedPrimitiveChange: rprim(%d) ", rprim
);
725 fprintf(stderr
, "GL_POINTS ");
727 if (fmesa
->draw_point
== ffb_fallback_point
) {
732 if (ctx
->Point
.SmoothFlag
) {
733 ppc
|= (FFB_PPC_ZS_VAR
| FFB_PPC_CS_CONST
);
734 drawop
= FFB_DRAWOP_AADOT
;
736 ppc
|= (FFB_PPC_ZS_CONST
| FFB_PPC_CS_CONST
);
737 drawop
= FFB_DRAWOP_DOT
;
743 fprintf(stderr
, "GL_LINES ");
745 if (fmesa
->draw_line
== ffb_fallback_line
) {
750 if (ctx
->_TriangleCaps
& DD_FLATSHADE
) {
751 ppc
|= FFB_PPC_ZS_VAR
| FFB_PPC_CS_CONST
;
753 ppc
|= FFB_PPC_ZS_VAR
| FFB_PPC_CS_VAR
;
755 if (ctx
->Line
.SmoothFlag
)
756 drawop
= FFB_DRAWOP_AALINE
;
758 drawop
= FFB_DRAWOP_DDLINE
;
763 fprintf(stderr
, "GL_POLYGON ");
765 if (fmesa
->draw_tri
== ffb_fallback_triangle
) {
770 ppc
&= ~FFB_PPC_APE_MASK
;
771 if (ctx
->Polygon
.StippleFlag
)
772 ppc
|= FFB_PPC_APE_ENABLE
;
774 ppc
|= FFB_PPC_APE_DISABLE
;
776 if (ctx
->_TriangleCaps
& DD_FLATSHADE
) {
777 ppc
|= FFB_PPC_ZS_VAR
| FFB_PPC_CS_CONST
;
779 ppc
|= FFB_PPC_ZS_VAR
| FFB_PPC_CS_VAR
;
781 drawop
= FFB_DRAWOP_TRIANGLE
;
786 fprintf(stderr
, "unknown %d!\n", rprim
);
792 fprintf(stderr
, "do_sw(%d) ", do_sw
);
795 fbc
&= ~(FFB_FBC_WB_C
);
796 fbc
&= ~(FFB_FBC_ZE_MASK
| FFB_FBC_RGBE_MASK
);
797 fbc
|= FFB_FBC_ZE_OFF
| FFB_FBC_RGBE_MASK
;
798 ppc
&= ~(FFB_PPC_XS_MASK
| FFB_PPC_ABE_MASK
|
799 FFB_PPC_DCE_MASK
| FFB_PPC_APE_MASK
);
800 ppc
|= (FFB_PPC_ZS_VAR
| FFB_PPC_CS_VAR
| FFB_PPC_XS_WID
|
801 FFB_PPC_ABE_DISABLE
| FFB_PPC_DCE_DISABLE
|
802 FFB_PPC_APE_DISABLE
);
805 fbc
&= ~(FFB_FBC_RGBE_MASK
);
806 fbc
|= FFB_FBC_RGBE_MASK
;
807 ppc
&= ~(FFB_PPC_ABE_MASK
| FFB_PPC_XS_MASK
);
808 if (ctx
->Color
.BlendEnabled
) {
809 if ((rprim
== GL_POINTS
&& !ctx
->Point
.SmoothFlag
) ||
810 (rprim
!= GL_POINTS
&& ctx
->_TriangleCaps
& DD_FLATSHADE
))
811 ppc
|= FFB_PPC_ABE_ENABLE
| FFB_PPC_XS_CONST
;
813 ppc
|= FFB_PPC_ABE_ENABLE
| FFB_PPC_XS_VAR
;
815 ppc
|= FFB_PPC_ABE_DISABLE
| FFB_PPC_XS_WID
;
819 fprintf(stderr
, "fbc(%08x) ppc(%08x)\n", fbc
, ppc
);
823 if (fmesa
->drawop
!= drawop
)
824 fmesa
->regs
->drawop
= fmesa
->drawop
= drawop
;
825 if (fmesa
->fbc
!= fbc
)
826 fmesa
->regs
->fbc
= fmesa
->fbc
= fbc
;
827 if (fmesa
->ppc
!= ppc
)
828 fmesa
->regs
->ppc
= fmesa
->ppc
= ppc
;
831 (fmesa
->cmp
& ~(0xff<<16)) | (0x80 << 16);
833 fmesa
->regs
->cmp
= fmesa
->cmp
;
836 static void ffbRenderPrimitive(GLcontext
*ctx
, GLenum prim
)
838 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
839 GLuint rprim
= reduced_prim
[prim
];
841 fmesa
->render_primitive
= prim
;
843 if (rprim
== GL_TRIANGLES
&& (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
))
846 if (fmesa
->raster_primitive
!= rprim
) {
847 ffbRasterPrimitive( ctx
, rprim
);
854 /**********************************************************************/
855 /* Transition to/from hardware rasterization. */
856 /**********************************************************************/
858 static char *fallbackStrings
[] = {
865 "LIBGL_SOFTWARE_RENDERING"
868 static char *getFallbackString(GLuint bit
)
876 return fallbackStrings
[i
];
879 void ffbFallback( GLcontext
*ctx
, GLuint bit
, GLboolean mode
)
881 ffbContextPtr fmesa
= FFB_CONTEXT(ctx
);
882 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
883 GLuint oldfallback
= fmesa
->bad_fragment_attrs
;
886 fmesa
->bad_fragment_attrs
|= bit
;
887 if (oldfallback
== 0) {
888 /* FFB_FIREVERTICES(fmesa); */
889 _swsetup_Wakeup( ctx
);
890 if (fmesa
->debugFallbacks
)
891 fprintf(stderr
, "FFB begin software fallback: 0x%x %s\n",
892 bit
, getFallbackString(bit
));
895 fmesa
->bad_fragment_attrs
&= ~bit
;
896 if (oldfallback
== bit
) {
897 _swrast_flush( ctx
);
899 tnl
->Driver
.Render
.Start
= ffbRenderStart
;
900 tnl
->Driver
.Render
.PrimitiveNotify
= ffbRenderPrimitive
;
901 tnl
->Driver
.Render
.Finish
= ffbRenderFinish
;
902 fmesa
->new_gl_state
= ~0;
904 /* Just re-choose everything:
906 ffbChooseVertexState(ctx
);
907 ffbChooseRenderState(ctx
);
908 ffbChooseTriangleState(ctx
);
909 ffbChooseLineState(ctx
);
910 ffbChoosePointState(ctx
);
912 if (fmesa
->debugFallbacks
)
913 fprintf(stderr
, "FFB end software fallback: 0x%x %s\n",
914 bit
, getFallbackString(bit
));
919 /**********************************************************************/
920 /* Initialization. */
921 /**********************************************************************/
923 void ffbDDInitRenderFuncs( GLcontext
*ctx
)
925 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
926 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
927 static int firsttime
= 1;
936 tnl
->Driver
.RunPipeline
= ffbRunPipeline
;
937 tnl
->Driver
.Render
.Start
= ffbRenderStart
;
938 tnl
->Driver
.Render
.Finish
= ffbRenderFinish
;
939 tnl
->Driver
.Render
.PrimitiveNotify
= ffbRenderPrimitive
;
940 tnl
->Driver
.Render
.ResetLineStipple
= _swrast_ResetLineStipple
;
941 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
942 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
944 swrast
->Driver
.SpanRenderStart
= ffbSWRenderStart
;
945 swrast
->Driver
.SpanRenderFinish
= ffbSWRenderFinish
;