1 /* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810tris.c,v 1.7 2002/10/30 12:51:33 alanh Exp $ */
2 /**************************************************************************
4 Copyright 2001 VA Linux Systems Inc., Fremont, California.
8 Permission is hereby granted, free of charge, to any person obtaining a
9 copy of this software and associated documentation files (the "Software"),
10 to deal in the Software without restriction, including without limitation
11 on the rights to use, copy, modify, merge, publish, distribute, sub
12 license, and/or sell copies of the Software, and to permit persons to whom
13 the Software is furnished to do so, subject to the following conditions:
15 The above copyright notice and this permission notice (including the next
16 paragraph) shall be included in all copies or substantial portions of the
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
22 ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
23 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
25 USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
31 * Keith Whitwell <keith@tungstengraphics.com>
40 #include "swrast/swrast.h"
41 #include "swrast_setup/swrast_setup.h"
42 #include "tnl/t_context.h"
43 #include "tnl/t_pipeline.h"
45 #include "i810screen.h"
49 #include "i810state.h"
51 #include "i810ioctl.h"
53 static void i810RenderPrimitive( GLcontext
*ctx
, GLenum prim
);
55 /***********************************************************************
56 * Emit primitives as inline vertices *
57 ***********************************************************************/
59 #if defined(USE_X86_ASM)
60 #define COPY_DWORDS( j, vb, vertsize, v ) \
63 __asm__ __volatile__( "rep ; movsl" \
64 : "=%c" (j), "=D" (vb), "=S" (__tmp) \
70 #define COPY_DWORDS( j, vb, vertsize, v ) \
72 for ( j = 0 ; j < vertsize ; j++ ) \
73 vb[j] = ((GLuint *)v)[j]; \
78 static void __inline__
i810_draw_triangle( i810ContextPtr imesa
,
83 GLuint vertsize
= imesa
->vertex_size
;
84 GLuint
*vb
= i810AllocDmaLow( imesa
, 3 * 4 * vertsize
);
87 COPY_DWORDS( j
, vb
, vertsize
, v0
);
88 COPY_DWORDS( j
, vb
, vertsize
, v1
);
89 COPY_DWORDS( j
, vb
, vertsize
, v2
);
93 static void __inline__
i810_draw_quad( i810ContextPtr imesa
,
99 GLuint vertsize
= imesa
->vertex_size
;
100 GLuint
*vb
= i810AllocDmaLow( imesa
, 6 * 4 * vertsize
);
103 COPY_DWORDS( j
, vb
, vertsize
, v0
);
104 COPY_DWORDS( j
, vb
, vertsize
, v1
);
105 COPY_DWORDS( j
, vb
, vertsize
, v3
);
106 COPY_DWORDS( j
, vb
, vertsize
, v1
);
107 COPY_DWORDS( j
, vb
, vertsize
, v2
);
108 COPY_DWORDS( j
, vb
, vertsize
, v3
);
112 static __inline__
void i810_draw_point( i810ContextPtr imesa
,
115 GLfloat sz
= imesa
->glCtx
->Point
._Size
* .5;
116 int vertsize
= imesa
->vertex_size
;
117 GLuint
*vb
= i810AllocDmaLow( imesa
, 2 * 4 * vertsize
);
120 /* Draw a point as a horizontal line.
122 *(float *)&vb
[0] = tmp
->v
.x
- sz
+ 0.125;
123 for (j
= 1 ; j
< vertsize
; j
++)
127 *(float *)&vb
[0] = tmp
->v
.x
+ sz
+ 0.125;
128 for (j
= 1 ; j
< vertsize
; j
++)
134 static __inline__
void i810_draw_line( i810ContextPtr imesa
,
138 GLuint vertsize
= imesa
->vertex_size
;
139 GLuint
*vb
= i810AllocDmaLow( imesa
, 2 * 4 * vertsize
);
142 COPY_DWORDS( j
, vb
, vertsize
, v0
);
143 COPY_DWORDS( j
, vb
, vertsize
, v1
);
148 /***********************************************************************
149 * Macros for t_dd_tritmp.h to draw basic primitives *
150 ***********************************************************************/
152 #define TRI( a, b, c ) \
154 if (0) fprintf(stderr, "hw TRI\n"); \
156 imesa->draw_tri( imesa, a, b, c ); \
158 i810_draw_triangle( imesa, a, b, c ); \
161 #define QUAD( a, b, c, d ) \
163 if (0) fprintf(stderr, "hw QUAD\n"); \
165 imesa->draw_tri( imesa, a, b, d ); \
166 imesa->draw_tri( imesa, b, c, d ); \
168 i810_draw_quad( imesa, a, b, c, d ); \
171 #define LINE( v0, v1 ) \
173 if (0) fprintf(stderr, "hw LINE\n"); \
175 imesa->draw_line( imesa, v0, v1 ); \
177 i810_draw_line( imesa, v0, v1 ); \
180 #define POINT( v0 ) \
182 if (0) fprintf(stderr, "hw POINT\n"); \
184 imesa->draw_point( imesa, v0 ); \
186 i810_draw_point( imesa, v0 ); \
190 /***********************************************************************
191 * Build render functions from dd templates *
192 ***********************************************************************/
194 #define I810_OFFSET_BIT 0x01
195 #define I810_TWOSIDE_BIT 0x02
196 #define I810_UNFILLED_BIT 0x04
197 #define I810_FALLBACK_BIT 0x08
198 #define I810_MAX_TRIFUNC 0x10
204 triangle_func triangle
;
206 } rast_tab
[I810_MAX_TRIFUNC
];
209 #define DO_FALLBACK (IND & I810_FALLBACK_BIT)
210 #define DO_OFFSET (IND & I810_OFFSET_BIT)
211 #define DO_UNFILLED (IND & I810_UNFILLED_BIT)
212 #define DO_TWOSIDE (IND & I810_TWOSIDE_BIT)
218 #define DO_FULL_QUAD 1
222 #define HAVE_BACK_COLORS 0
223 #define HAVE_HW_FLATSHADE 1
224 #define VERTEX i810Vertex
228 #define DEPTH_SCALE (1.0/0xffff)
229 #define UNFILLED_TRI unfilled_tri
230 #define UNFILLED_QUAD unfilled_quad
231 #define VERT_X(_v) _v->v.x
232 #define VERT_Y(_v) _v->v.y
233 #define VERT_Z(_v) _v->v.z
234 #define AREA_IS_CCW( a ) (a > 0)
235 #define GET_VERTEX(e) (imesa->verts + (e * imesa->vertex_size * sizeof(int)))
237 #define VERT_SET_RGBA( v, c ) \
239 i810_color_t *color = (i810_color_t *)&((v)->ui[coloroffset]); \
240 UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
241 UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
242 UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
243 UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
246 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
248 #define VERT_SET_SPEC( v0, c ) \
251 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]); \
252 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]); \
253 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]); \
256 #define VERT_COPY_SPEC( v0, v1 ) \
259 v0->v.specular.red = v1->v.specular.red; \
260 v0->v.specular.green = v1->v.specular.green; \
261 v0->v.specular.blue = v1->v.specular.blue; \
265 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
266 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
267 #define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = v[idx]->ui[5]
268 #define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx]
270 #define LOCAL_VARS(n) \
271 i810ContextPtr imesa = I810_CONTEXT(ctx); \
272 GLuint color[n], spec[n]; \
273 GLuint coloroffset = (imesa->vertex_size == 4 ? 3 : 4); \
274 GLboolean havespec = (imesa->vertex_size > 4); \
275 (void) color; (void) spec; (void) coloroffset; (void) havespec;
278 /***********************************************************************
279 * Helpers for rendering unfilled primitives *
280 ***********************************************************************/
282 static const GLuint hw_prim
[GL_POLYGON
+1] = {
295 #define RASTERIZE(x) if (imesa->hw_primitive != hw_prim[x]) \
296 i810RasterPrimitive( ctx, x, hw_prim[x] )
297 #define RENDER_PRIMITIVE imesa->render_primitive
299 #define IND I810_FALLBACK_BIT
300 #include "tnl_dd/t_dd_unfilled.h"
303 /***********************************************************************
304 * Generate GL render functions *
305 ***********************************************************************/
309 #include "tnl_dd/t_dd_tritmp.h"
311 #define IND (I810_OFFSET_BIT)
312 #define TAG(x) x##_offset
313 #include "tnl_dd/t_dd_tritmp.h"
315 #define IND (I810_TWOSIDE_BIT)
316 #define TAG(x) x##_twoside
317 #include "tnl_dd/t_dd_tritmp.h"
319 #define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT)
320 #define TAG(x) x##_twoside_offset
321 #include "tnl_dd/t_dd_tritmp.h"
323 #define IND (I810_UNFILLED_BIT)
324 #define TAG(x) x##_unfilled
325 #include "tnl_dd/t_dd_tritmp.h"
327 #define IND (I810_OFFSET_BIT|I810_UNFILLED_BIT)
328 #define TAG(x) x##_offset_unfilled
329 #include "tnl_dd/t_dd_tritmp.h"
331 #define IND (I810_TWOSIDE_BIT|I810_UNFILLED_BIT)
332 #define TAG(x) x##_twoside_unfilled
333 #include "tnl_dd/t_dd_tritmp.h"
335 #define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_UNFILLED_BIT)
336 #define TAG(x) x##_twoside_offset_unfilled
337 #include "tnl_dd/t_dd_tritmp.h"
339 #define IND (I810_FALLBACK_BIT)
340 #define TAG(x) x##_fallback
341 #include "tnl_dd/t_dd_tritmp.h"
343 #define IND (I810_OFFSET_BIT|I810_FALLBACK_BIT)
344 #define TAG(x) x##_offset_fallback
345 #include "tnl_dd/t_dd_tritmp.h"
347 #define IND (I810_TWOSIDE_BIT|I810_FALLBACK_BIT)
348 #define TAG(x) x##_twoside_fallback
349 #include "tnl_dd/t_dd_tritmp.h"
351 #define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_FALLBACK_BIT)
352 #define TAG(x) x##_twoside_offset_fallback
353 #include "tnl_dd/t_dd_tritmp.h"
355 #define IND (I810_UNFILLED_BIT|I810_FALLBACK_BIT)
356 #define TAG(x) x##_unfilled_fallback
357 #include "tnl_dd/t_dd_tritmp.h"
359 #define IND (I810_OFFSET_BIT|I810_UNFILLED_BIT|I810_FALLBACK_BIT)
360 #define TAG(x) x##_offset_unfilled_fallback
361 #include "tnl_dd/t_dd_tritmp.h"
363 #define IND (I810_TWOSIDE_BIT|I810_UNFILLED_BIT|I810_FALLBACK_BIT)
364 #define TAG(x) x##_twoside_unfilled_fallback
365 #include "tnl_dd/t_dd_tritmp.h"
367 #define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_UNFILLED_BIT| \
369 #define TAG(x) x##_twoside_offset_unfilled_fallback
370 #include "tnl_dd/t_dd_tritmp.h"
373 static void init_rast_tab( void )
378 init_twoside_offset();
380 init_offset_unfilled();
381 init_twoside_unfilled();
382 init_twoside_offset_unfilled();
384 init_offset_fallback();
385 init_twoside_fallback();
386 init_twoside_offset_fallback();
387 init_unfilled_fallback();
388 init_offset_unfilled_fallback();
389 init_twoside_unfilled_fallback();
390 init_twoside_offset_unfilled_fallback();
394 /***********************************************************************
395 * Rasterization fallback helpers *
396 ***********************************************************************/
399 /* This code is hit only when a mix of accelerated and unaccelerated
400 * primitives are being drawn, and only for the unaccelerated
404 i810_fallback_tri( i810ContextPtr imesa
,
409 GLcontext
*ctx
= imesa
->glCtx
;
411 i810_translate_vertex( ctx
, v0
, &v
[0] );
412 i810_translate_vertex( ctx
, v1
, &v
[1] );
413 i810_translate_vertex( ctx
, v2
, &v
[2] );
414 _swrast_Triangle( ctx
, &v
[0], &v
[1], &v
[2] );
419 i810_fallback_line( i810ContextPtr imesa
,
423 GLcontext
*ctx
= imesa
->glCtx
;
425 i810_translate_vertex( ctx
, v0
, &v
[0] );
426 i810_translate_vertex( ctx
, v1
, &v
[1] );
427 _swrast_Line( ctx
, &v
[0], &v
[1] );
432 i810_fallback_point( i810ContextPtr imesa
,
435 GLcontext
*ctx
= imesa
->glCtx
;
437 i810_translate_vertex( ctx
, v0
, &v
[0] );
438 _swrast_Point( ctx
, &v
[0] );
443 /**********************************************************************/
444 /* Render unclipped begin/end objects */
445 /**********************************************************************/
448 #define V(x) (i810Vertex *)(vertptr + ((x)*vertsize*sizeof(int)))
449 #define RENDER_POINTS( start, count ) \
450 for ( ; start < count ; start++) POINT( V(ELT(start)) );
451 #define RENDER_LINE( v0, v1 ) LINE( V(v0), V(v1) )
452 #define RENDER_TRI( v0, v1, v2 ) TRI( V(v0), V(v1), V(v2) )
453 #define RENDER_QUAD( v0, v1, v2, v3 ) QUAD( V(v0), V(v1), V(v2), V(v3) )
454 #define INIT(x) i810RenderPrimitive( ctx, x )
457 i810ContextPtr imesa = I810_CONTEXT(ctx); \
458 GLubyte *vertptr = (GLubyte *)imesa->verts; \
459 const GLuint vertsize = imesa->vertex_size; \
460 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
462 #define RESET_STIPPLE
463 #define RESET_OCCLUSION
464 #define PRESERVE_VB_DEFS
466 #define TAG(x) i810_##x##_verts
467 #include "tnl/t_vb_rendertmp.h"
470 #define TAG(x) i810_##x##_elts
471 #define ELT(x) elt[x]
472 #include "tnl/t_vb_rendertmp.h"
474 /**********************************************************************/
475 /* Render clipped primitives */
476 /**********************************************************************/
480 static void i810RenderClippedPoly( GLcontext
*ctx
, const GLuint
*elts
,
483 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
484 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
485 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
486 GLuint prim
= imesa
->render_primitive
;
488 /* Render the new vertices as an unclipped polygon.
491 GLuint
*tmp
= VB
->Elts
;
492 VB
->Elts
= (GLuint
*)elts
;
493 tnl
->Driver
.Render
.PrimTabElts
[GL_POLYGON
]( ctx
, 0, n
,
494 PRIM_BEGIN
|PRIM_END
);
498 /* Restore the render primitive
500 if (prim
!= GL_POLYGON
)
501 tnl
->Driver
.Render
.PrimitiveNotify( ctx
, prim
);
504 static void i810RenderClippedLine( GLcontext
*ctx
, GLuint ii
, GLuint jj
)
506 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
507 tnl
->Driver
.Render
.Line( ctx
, ii
, jj
);
510 static void i810FastRenderClippedPoly( GLcontext
*ctx
, const GLuint
*elts
,
513 i810ContextPtr imesa
= I810_CONTEXT( ctx
);
514 GLuint vertsize
= imesa
->vertex_size
;
515 GLuint
*vb
= i810AllocDmaLow( imesa
, (n
-2) * 3 * 4 * vertsize
);
516 GLubyte
*vertptr
= (GLubyte
*)imesa
->verts
;
517 const GLuint
*start
= (const GLuint
*)V(elts
[0]);
520 for (i
= 2 ; i
< n
; i
++) {
521 COPY_DWORDS( j
, vb
, vertsize
, V(elts
[i
-1]) );
522 COPY_DWORDS( j
, vb
, vertsize
, V(elts
[i
]) );
523 COPY_DWORDS( j
, vb
, vertsize
, start
);
527 /**********************************************************************/
528 /* Choose render functions */
529 /**********************************************************************/
531 /***********************************************************************
532 * Rasterization fallback helpers *
533 ***********************************************************************/
537 #define _I810_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \
538 _DD_NEW_TRI_UNFILLED | \
539 _DD_NEW_TRI_LIGHT_TWOSIDE | \
540 _DD_NEW_TRI_OFFSET | \
541 _DD_NEW_TRI_STIPPLE | \
544 #define POINT_FALLBACK (0)
545 #define LINE_FALLBACK (DD_LINE_STIPPLE)
546 #define TRI_FALLBACK (0)
547 #define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|\
549 #define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
551 static void i810ChooseRenderState(GLcontext
*ctx
)
553 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
554 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
555 GLuint flags
= ctx
->_TriangleCaps
;
558 if (I810_DEBUG
& DEBUG_STATE
)
559 fprintf(stderr
,"\n%s\n",__FUNCTION__
);
561 if (flags
& (ANY_FALLBACK_FLAGS
|ANY_RASTER_FLAGS
)) {
562 if (flags
& ANY_RASTER_FLAGS
) {
563 if (flags
& DD_TRI_LIGHT_TWOSIDE
) index
|= I810_TWOSIDE_BIT
;
564 if (flags
& DD_TRI_OFFSET
) index
|= I810_OFFSET_BIT
;
565 if (flags
& DD_TRI_UNFILLED
) index
|= I810_UNFILLED_BIT
;
568 imesa
->draw_point
= i810_draw_point
;
569 imesa
->draw_line
= i810_draw_line
;
570 imesa
->draw_tri
= i810_draw_triangle
;
572 /* Hook in fallbacks for specific primitives.
574 if (flags
& ANY_FALLBACK_FLAGS
)
576 if (flags
& POINT_FALLBACK
)
577 imesa
->draw_point
= i810_fallback_point
;
579 if (flags
& LINE_FALLBACK
)
580 imesa
->draw_line
= i810_fallback_line
;
582 if (flags
& TRI_FALLBACK
)
583 imesa
->draw_tri
= i810_fallback_tri
;
585 if ((flags
& DD_TRI_STIPPLE
) && !imesa
->stipple_in_hw
)
586 imesa
->draw_tri
= i810_fallback_tri
;
588 index
|= I810_FALLBACK_BIT
;
592 if (imesa
->RenderIndex
!= index
) {
593 imesa
->RenderIndex
= index
;
595 tnl
->Driver
.Render
.Points
= rast_tab
[index
].points
;
596 tnl
->Driver
.Render
.Line
= rast_tab
[index
].line
;
597 tnl
->Driver
.Render
.Triangle
= rast_tab
[index
].triangle
;
598 tnl
->Driver
.Render
.Quad
= rast_tab
[index
].quad
;
601 tnl
->Driver
.Render
.PrimTabVerts
= i810_render_tab_verts
;
602 tnl
->Driver
.Render
.PrimTabElts
= i810_render_tab_elts
;
603 tnl
->Driver
.Render
.ClippedLine
= line
; /* from tritmp.h */
604 tnl
->Driver
.Render
.ClippedPolygon
= i810FastRenderClippedPoly
;
606 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
607 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
608 tnl
->Driver
.Render
.ClippedLine
= i810RenderClippedLine
;
609 tnl
->Driver
.Render
.ClippedPolygon
= i810RenderClippedPoly
;
614 static const GLenum reduced_prim
[GL_POLYGON
+1] = {
628 /**********************************************************************/
629 /* High level hooks for t_vb_render.c */
630 /**********************************************************************/
634 /* Determine the rasterized primitive when not drawing unfilled
637 * Used only for the default render stage which always decomposes
638 * primitives to trianges/lines/points. For the accelerated stage,
639 * which renders strips as strips, the equivalent calculations are
640 * performed in i810render.c.
642 static void i810RenderPrimitive( GLcontext
*ctx
, GLenum prim
)
644 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
645 GLuint rprim
= reduced_prim
[prim
];
647 imesa
->render_primitive
= prim
;
649 if (rprim
== GL_TRIANGLES
&& (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
))
652 if (imesa
->reduced_primitive
!= rprim
||
653 hw_prim
[prim
] != imesa
->hw_primitive
) {
654 i810RasterPrimitive( ctx
, rprim
, hw_prim
[prim
] );
658 static void i810RunPipeline( GLcontext
*ctx
)
660 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
662 if (imesa
->new_state
) {
663 if (imesa
->new_state
& _NEW_TEXTURE
)
664 i810UpdateTextureState( ctx
); /* may modify imesa->new_state */
666 if (!imesa
->Fallback
) {
667 if (imesa
->new_state
& _I810_NEW_VERTEX
)
668 i810ChooseVertexState( ctx
);
670 if (imesa
->new_state
& _I810_NEW_RENDERSTATE
)
671 i810ChooseRenderState( ctx
);
674 imesa
->new_state
= 0;
677 _tnl_run_pipeline( ctx
);
680 static void i810RenderStart( GLcontext
*ctx
)
682 /* Check for projective textureing. Make sure all texcoord
683 * pointers point to something. (fix in mesa?)
685 i810CheckTexSizes( ctx
);
688 static void i810RenderFinish( GLcontext
*ctx
)
690 if (I810_CONTEXT(ctx
)->RenderIndex
& I810_FALLBACK_BIT
)
691 _swrast_flush( ctx
);
697 /* System to flush dma and emit state changes based on the rasterized
700 void i810RasterPrimitive( GLcontext
*ctx
,
704 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
705 GLuint st1
= imesa
->Setup
[I810_CTXREG_ST1
];
706 GLuint aa
= imesa
->Setup
[I810_CTXREG_AA
];
707 GLuint lcs
= imesa
->Setup
[I810_CTXREG_LCS
];
712 if (I810_DEBUG
& DEBUG_PRIMS
) {
713 /* Prints reduced prim, and hw prim */
714 char *prim_name
= "Unknown";
721 prim_name
= "LineStrip";
724 prim_name
= "Triangles";
727 prim_name
= "TriStrip_0";
730 prim_name
= "TriFan";
733 prim_name
= "Polygons";
739 fprintf(stderr
, "%s : rprim(%s), hwprim(%s)\n",
741 _mesa_lookup_enum_by_nr(rprim
),
747 if (ctx
->Polygon
.StippleFlag
)
749 if (ctx
->Polygon
.SmoothFlag
)
753 lcs
&= ~(LCS_LINEWIDTH_3_0
|LCS_LINEWIDTH_0_5
);
754 lcs
|= imesa
->LcsLineWidth
;
755 if (ctx
->Line
.SmoothFlag
) {
757 lcs
|= LCS_LINEWIDTH_0_5
;
761 lcs
&= ~(LCS_LINEWIDTH_3_0
|LCS_LINEWIDTH_0_5
);
762 lcs
|= imesa
->LcsPointSize
;
763 if (ctx
->Point
.SmoothFlag
) {
765 lcs
|= LCS_LINEWIDTH_0_5
;
772 imesa
->reduced_primitive
= rprim
;
774 if (st1
!= imesa
->Setup
[I810_CTXREG_ST1
] ||
775 aa
!= imesa
->Setup
[I810_CTXREG_AA
] ||
776 lcs
!= imesa
->Setup
[I810_CTXREG_LCS
])
778 I810_STATECHANGE(imesa
, I810_UPLOAD_CTX
);
779 imesa
->hw_primitive
= hwprim
;
780 imesa
->Setup
[I810_CTXREG_LCS
] = lcs
;
781 imesa
->Setup
[I810_CTXREG_ST1
] = st1
;
782 imesa
->Setup
[I810_CTXREG_AA
] = aa
;
784 else if (hwprim
!= imesa
->hw_primitive
) {
785 I810_STATECHANGE(imesa
, 0);
786 imesa
->hw_primitive
= hwprim
;
790 /**********************************************************************/
791 /* Transition to/from hardware rasterization. */
792 /**********************************************************************/
793 static char *fallbackStrings
[] = {
805 static char *getFallbackString(GLuint bit
)
812 return fallbackStrings
[i
];
815 void i810Fallback( i810ContextPtr imesa
, GLuint bit
, GLboolean mode
)
817 GLcontext
*ctx
= imesa
->glCtx
;
818 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
819 GLuint oldfallback
= imesa
->Fallback
;
821 if (0) fprintf(stderr
, "%s old %x bit %x mode %d\n", __FUNCTION__
,
822 imesa
->Fallback
, bit
, mode
);
825 imesa
->Fallback
|= bit
;
826 if (oldfallback
== 0) {
827 I810_FIREVERTICES(imesa
);
828 if (I810_DEBUG
& DEBUG_FALLBACKS
)
829 fprintf(stderr
, "ENTER FALLBACK %s\n", getFallbackString( bit
));
830 _swsetup_Wakeup( ctx
);
831 imesa
->RenderIndex
= ~0;
835 imesa
->Fallback
&= ~bit
;
836 if (oldfallback
== bit
) {
837 _swrast_flush( ctx
);
838 if (I810_DEBUG
& DEBUG_FALLBACKS
)
839 fprintf(stderr
, "LEAVE FALLBACK %s\n", getFallbackString( bit
));
840 tnl
->Driver
.Render
.Start
= i810RenderStart
;
841 tnl
->Driver
.Render
.PrimitiveNotify
= i810RenderPrimitive
;
842 tnl
->Driver
.Render
.Finish
= i810RenderFinish
;
843 tnl
->Driver
.Render
.BuildVertices
= i810BuildVertices
;
844 imesa
->new_state
|= (_I810_NEW_RENDERSTATE
|_I810_NEW_VERTEX
);
850 /**********************************************************************/
851 /* Initialization. */
852 /**********************************************************************/
855 void i810InitTriFuncs( GLcontext
*ctx
)
857 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
858 static int firsttime
= 1;
865 tnl
->Driver
.RunPipeline
= i810RunPipeline
;
866 tnl
->Driver
.Render
.Start
= i810RenderStart
;
867 tnl
->Driver
.Render
.Finish
= i810RenderFinish
;
868 tnl
->Driver
.Render
.PrimitiveNotify
= i810RenderPrimitive
;
869 tnl
->Driver
.Render
.ResetLineStipple
= _swrast_ResetLineStipple
;
870 tnl
->Driver
.Render
.BuildVertices
= i810BuildVertices
;