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_stride_shift))
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)<<vertshift))
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 vertshift = imesa->vertex_stride_shift; \
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 vertshift
= imesa
->vertex_stride_shift
;
518 const GLuint
*start
= (const GLuint
*)V(elts
[0]);
521 for (i
= 2 ; i
< n
; i
++) {
522 COPY_DWORDS( j
, vb
, vertsize
, V(elts
[i
-1]) );
523 COPY_DWORDS( j
, vb
, vertsize
, V(elts
[i
]) );
524 COPY_DWORDS( j
, vb
, vertsize
, start
);
528 /**********************************************************************/
529 /* Choose render functions */
530 /**********************************************************************/
532 /***********************************************************************
533 * Rasterization fallback helpers *
534 ***********************************************************************/
538 #define _I810_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \
539 _DD_NEW_TRI_UNFILLED | \
540 _DD_NEW_TRI_LIGHT_TWOSIDE | \
541 _DD_NEW_TRI_OFFSET | \
542 _DD_NEW_TRI_STIPPLE | \
545 #define POINT_FALLBACK (0)
546 #define LINE_FALLBACK (DD_LINE_STIPPLE)
547 #define TRI_FALLBACK (0)
548 #define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|\
550 #define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
552 static void i810ChooseRenderState(GLcontext
*ctx
)
554 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
555 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
556 GLuint flags
= ctx
->_TriangleCaps
;
559 if (I810_DEBUG
& DEBUG_STATE
)
560 fprintf(stderr
,"\n%s\n",__FUNCTION__
);
562 if (flags
& (ANY_FALLBACK_FLAGS
|ANY_RASTER_FLAGS
)) {
563 if (flags
& ANY_RASTER_FLAGS
) {
564 if (flags
& DD_TRI_LIGHT_TWOSIDE
) index
|= I810_TWOSIDE_BIT
;
565 if (flags
& DD_TRI_OFFSET
) index
|= I810_OFFSET_BIT
;
566 if (flags
& DD_TRI_UNFILLED
) index
|= I810_UNFILLED_BIT
;
569 imesa
->draw_point
= i810_draw_point
;
570 imesa
->draw_line
= i810_draw_line
;
571 imesa
->draw_tri
= i810_draw_triangle
;
573 /* Hook in fallbacks for specific primitives.
575 if (flags
& ANY_FALLBACK_FLAGS
)
577 if (flags
& POINT_FALLBACK
)
578 imesa
->draw_point
= i810_fallback_point
;
580 if (flags
& LINE_FALLBACK
)
581 imesa
->draw_line
= i810_fallback_line
;
583 if (flags
& TRI_FALLBACK
)
584 imesa
->draw_tri
= i810_fallback_tri
;
586 if ((flags
& DD_TRI_STIPPLE
) && !imesa
->stipple_in_hw
)
587 imesa
->draw_tri
= i810_fallback_tri
;
589 index
|= I810_FALLBACK_BIT
;
593 if (imesa
->RenderIndex
!= index
) {
594 imesa
->RenderIndex
= index
;
596 tnl
->Driver
.Render
.Points
= rast_tab
[index
].points
;
597 tnl
->Driver
.Render
.Line
= rast_tab
[index
].line
;
598 tnl
->Driver
.Render
.Triangle
= rast_tab
[index
].triangle
;
599 tnl
->Driver
.Render
.Quad
= rast_tab
[index
].quad
;
602 tnl
->Driver
.Render
.PrimTabVerts
= i810_render_tab_verts
;
603 tnl
->Driver
.Render
.PrimTabElts
= i810_render_tab_elts
;
604 tnl
->Driver
.Render
.ClippedLine
= line
; /* from tritmp.h */
605 tnl
->Driver
.Render
.ClippedPolygon
= i810FastRenderClippedPoly
;
607 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
608 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
609 tnl
->Driver
.Render
.ClippedLine
= i810RenderClippedLine
;
610 tnl
->Driver
.Render
.ClippedPolygon
= i810RenderClippedPoly
;
615 static const GLenum reduced_prim
[GL_POLYGON
+1] = {
629 /**********************************************************************/
630 /* High level hooks for t_vb_render.c */
631 /**********************************************************************/
635 /* Determine the rasterized primitive when not drawing unfilled
638 * Used only for the default render stage which always decomposes
639 * primitives to trianges/lines/points. For the accelerated stage,
640 * which renders strips as strips, the equivalent calculations are
641 * performed in i810render.c.
643 static void i810RenderPrimitive( GLcontext
*ctx
, GLenum prim
)
645 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
646 GLuint rprim
= reduced_prim
[prim
];
648 imesa
->render_primitive
= prim
;
650 if (rprim
== GL_TRIANGLES
&& (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
))
653 if (imesa
->reduced_primitive
!= rprim
||
654 hw_prim
[prim
] != imesa
->hw_primitive
) {
655 i810RasterPrimitive( ctx
, rprim
, hw_prim
[prim
] );
659 static void i810RunPipeline( GLcontext
*ctx
)
661 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
663 if (imesa
->new_state
) {
664 if (imesa
->new_state
& _NEW_TEXTURE
)
665 i810UpdateTextureState( ctx
); /* may modify imesa->new_state */
667 if (!imesa
->Fallback
) {
668 if (imesa
->new_state
& _I810_NEW_VERTEX
)
669 i810ChooseVertexState( ctx
);
671 if (imesa
->new_state
& _I810_NEW_RENDERSTATE
)
672 i810ChooseRenderState( ctx
);
675 imesa
->new_state
= 0;
678 _tnl_run_pipeline( ctx
);
681 static void i810RenderStart( GLcontext
*ctx
)
683 /* Check for projective textureing. Make sure all texcoord
684 * pointers point to something. (fix in mesa?)
686 i810CheckTexSizes( ctx
);
689 static void i810RenderFinish( GLcontext
*ctx
)
691 if (I810_CONTEXT(ctx
)->RenderIndex
& I810_FALLBACK_BIT
)
692 _swrast_flush( ctx
);
698 /* System to flush dma and emit state changes based on the rasterized
701 void i810RasterPrimitive( GLcontext
*ctx
,
705 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
706 GLuint st1
= imesa
->Setup
[I810_CTXREG_ST1
];
707 GLuint aa
= imesa
->Setup
[I810_CTXREG_AA
];
708 GLuint lcs
= imesa
->Setup
[I810_CTXREG_LCS
];
713 if (I810_DEBUG
& DEBUG_PRIMS
) {
714 /* Prints reduced prim, and hw prim */
715 char *prim_name
= "Unknown";
722 prim_name
= "LineStrip";
725 prim_name
= "Triangles";
728 prim_name
= "TriStrip_0";
731 prim_name
= "TriFan";
734 prim_name
= "Polygons";
740 fprintf(stderr
, "%s : rprim(%s), hwprim(%s)\n",
742 _mesa_lookup_enum_by_nr(rprim
),
748 if (ctx
->Polygon
.StippleFlag
)
750 if (ctx
->Polygon
.SmoothFlag
)
754 lcs
&= ~(LCS_LINEWIDTH_3_0
|LCS_LINEWIDTH_0_5
);
755 lcs
|= imesa
->LcsLineWidth
;
756 if (ctx
->Line
.SmoothFlag
) {
758 lcs
|= LCS_LINEWIDTH_0_5
;
762 lcs
&= ~(LCS_LINEWIDTH_3_0
|LCS_LINEWIDTH_0_5
);
763 lcs
|= imesa
->LcsPointSize
;
764 if (ctx
->Point
.SmoothFlag
) {
766 lcs
|= LCS_LINEWIDTH_0_5
;
773 imesa
->reduced_primitive
= rprim
;
775 if (st1
!= imesa
->Setup
[I810_CTXREG_ST1
] ||
776 aa
!= imesa
->Setup
[I810_CTXREG_AA
] ||
777 lcs
!= imesa
->Setup
[I810_CTXREG_LCS
])
779 I810_STATECHANGE(imesa
, I810_UPLOAD_CTX
);
780 imesa
->hw_primitive
= hwprim
;
781 imesa
->Setup
[I810_CTXREG_LCS
] = lcs
;
782 imesa
->Setup
[I810_CTXREG_ST1
] = st1
;
783 imesa
->Setup
[I810_CTXREG_AA
] = aa
;
785 else if (hwprim
!= imesa
->hw_primitive
) {
786 I810_STATECHANGE(imesa
, 0);
787 imesa
->hw_primitive
= hwprim
;
791 /**********************************************************************/
792 /* Transition to/from hardware rasterization. */
793 /**********************************************************************/
794 static char *fallbackStrings
[] = {
806 static char *getFallbackString(GLuint bit
)
813 return fallbackStrings
[i
];
816 void i810Fallback( i810ContextPtr imesa
, GLuint bit
, GLboolean mode
)
818 GLcontext
*ctx
= imesa
->glCtx
;
819 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
820 GLuint oldfallback
= imesa
->Fallback
;
822 if (0) fprintf(stderr
, "%s old %x bit %x mode %d\n", __FUNCTION__
,
823 imesa
->Fallback
, bit
, mode
);
826 imesa
->Fallback
|= bit
;
827 if (oldfallback
== 0) {
828 I810_FIREVERTICES(imesa
);
829 if (I810_DEBUG
& DEBUG_FALLBACKS
)
830 fprintf(stderr
, "ENTER FALLBACK %s\n", getFallbackString( bit
));
831 _swsetup_Wakeup( ctx
);
832 imesa
->RenderIndex
= ~0;
836 imesa
->Fallback
&= ~bit
;
837 if (oldfallback
== bit
) {
838 _swrast_flush( ctx
);
839 if (I810_DEBUG
& DEBUG_FALLBACKS
)
840 fprintf(stderr
, "LEAVE FALLBACK %s\n", getFallbackString( bit
));
841 tnl
->Driver
.Render
.Start
= i810RenderStart
;
842 tnl
->Driver
.Render
.PrimitiveNotify
= i810RenderPrimitive
;
843 tnl
->Driver
.Render
.Finish
= i810RenderFinish
;
844 tnl
->Driver
.Render
.BuildVertices
= i810BuildVertices
;
845 imesa
->new_state
|= (_I810_NEW_RENDERSTATE
|_I810_NEW_VERTEX
);
851 /**********************************************************************/
852 /* Initialization. */
853 /**********************************************************************/
856 void i810InitTriFuncs( GLcontext
*ctx
)
858 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
859 static int firsttime
= 1;
866 tnl
->Driver
.RunPipeline
= i810RunPipeline
;
867 tnl
->Driver
.Render
.Start
= i810RenderStart
;
868 tnl
->Driver
.Render
.Finish
= i810RenderFinish
;
869 tnl
->Driver
.Render
.PrimitiveNotify
= i810RenderPrimitive
;
870 tnl
->Driver
.Render
.ResetLineStipple
= _swrast_ResetLineStipple
;
871 tnl
->Driver
.Render
.BuildVertices
= i810BuildVertices
;