1 /**************************************************************************
3 Copyright 2001 VA Linux Systems Inc., Fremont, California.
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the "Software"),
9 to deal in the Software without restriction, including without limitation
10 on the rights to use, copy, modify, merge, publish, distribute, sub
11 license, and/or sell copies of the Software, and to permit persons to whom
12 the Software is furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
30 * Keith Whitwell <keith@tungstengraphics.com>
33 #include "main/glheader.h"
34 #include "main/mtypes.h"
35 #include "main/macros.h"
36 #include "main/enums.h"
37 #include "main/colormac.h"
39 #include "swrast/swrast.h"
40 #include "swrast_setup/swrast_setup.h"
41 #include "tnl/t_context.h"
42 #include "tnl/t_pipeline.h"
44 #include "i810screen.h"
48 #include "i810state.h"
50 #include "i810ioctl.h"
52 static void i810RenderPrimitive( GLcontext
*ctx
, GLenum prim
);
54 /***********************************************************************
55 * Emit primitives as inline vertices *
56 ***********************************************************************/
58 #if defined(USE_X86_ASM)
59 #define COPY_DWORDS( j, vb, vertsize, v ) \
62 __asm__ __volatile__( "rep ; movsl" \
63 : "=%c" (j), "=D" (vb), "=S" (__tmp) \
69 #define COPY_DWORDS( j, vb, vertsize, v ) \
71 for ( j = 0 ; j < vertsize ; j++ ) \
72 vb[j] = ((GLuint *)v)[j]; \
77 static INLINE
void i810_draw_triangle( i810ContextPtr imesa
,
82 GLuint vertsize
= imesa
->vertex_size
;
83 GLuint
*vb
= i810AllocDmaLow( imesa
, 3 * 4 * vertsize
);
86 COPY_DWORDS( j
, vb
, vertsize
, v0
);
87 COPY_DWORDS( j
, vb
, vertsize
, v1
);
88 COPY_DWORDS( j
, vb
, vertsize
, v2
);
92 static INLINE
void i810_draw_quad( i810ContextPtr imesa
,
98 GLuint vertsize
= imesa
->vertex_size
;
99 GLuint
*vb
= i810AllocDmaLow( imesa
, 6 * 4 * vertsize
);
102 COPY_DWORDS( j
, vb
, vertsize
, v0
);
103 COPY_DWORDS( j
, vb
, vertsize
, v1
);
104 COPY_DWORDS( j
, vb
, vertsize
, v3
);
105 COPY_DWORDS( j
, vb
, vertsize
, v1
);
106 COPY_DWORDS( j
, vb
, vertsize
, v2
);
107 COPY_DWORDS( j
, vb
, vertsize
, v3
);
111 static INLINE
void i810_draw_point( i810ContextPtr imesa
,
114 GLfloat sz
= 0.5 * CLAMP(imesa
->glCtx
->Point
.Size
,
115 imesa
->glCtx
->Const
.MinPointSize
,
116 imesa
->glCtx
->Const
.MaxPointSize
);
117 int vertsize
= imesa
->vertex_size
;
118 GLuint
*vb
= i810AllocDmaLow( imesa
, 2 * 4 * vertsize
);
121 /* Draw a point as a horizontal line.
123 *(float *)&vb
[0] = tmp
->v
.x
- sz
+ 0.125;
124 for (j
= 1 ; j
< vertsize
; j
++)
128 *(float *)&vb
[0] = tmp
->v
.x
+ sz
+ 0.125;
129 for (j
= 1 ; j
< vertsize
; j
++)
135 static INLINE
void i810_draw_line( i810ContextPtr imesa
,
139 GLuint vertsize
= imesa
->vertex_size
;
140 GLuint
*vb
= i810AllocDmaLow( imesa
, 2 * 4 * vertsize
);
143 COPY_DWORDS( j
, vb
, vertsize
, v0
);
144 COPY_DWORDS( j
, vb
, vertsize
, v1
);
149 /***********************************************************************
150 * Macros for t_dd_tritmp.h to draw basic primitives *
151 ***********************************************************************/
153 #define TRI( a, b, c ) \
155 if (0) fprintf(stderr, "hw TRI\n"); \
157 imesa->draw_tri( imesa, a, b, c ); \
159 i810_draw_triangle( imesa, a, b, c ); \
162 #define QUAD( a, b, c, d ) \
164 if (0) fprintf(stderr, "hw QUAD\n"); \
166 imesa->draw_tri( imesa, a, b, d ); \
167 imesa->draw_tri( imesa, b, c, d ); \
169 i810_draw_quad( imesa, a, b, c, d ); \
172 #define LINE( v0, v1 ) \
174 if (0) fprintf(stderr, "hw LINE\n"); \
176 imesa->draw_line( imesa, v0, v1 ); \
178 i810_draw_line( imesa, v0, v1 ); \
181 #define POINT( v0 ) \
183 if (0) fprintf(stderr, "hw POINT\n"); \
185 imesa->draw_point( imesa, v0 ); \
187 i810_draw_point( imesa, v0 ); \
191 /***********************************************************************
192 * Build render functions from dd templates *
193 ***********************************************************************/
195 #define I810_OFFSET_BIT 0x01
196 #define I810_TWOSIDE_BIT 0x02
197 #define I810_UNFILLED_BIT 0x04
198 #define I810_FALLBACK_BIT 0x08
199 #define I810_MAX_TRIFUNC 0x10
203 tnl_points_func points
;
205 tnl_triangle_func triangle
;
207 } rast_tab
[I810_MAX_TRIFUNC
];
210 #define DO_FALLBACK (IND & I810_FALLBACK_BIT)
211 #define DO_OFFSET (IND & I810_OFFSET_BIT)
212 #define DO_UNFILLED (IND & I810_UNFILLED_BIT)
213 #define DO_TWOSIDE (IND & I810_TWOSIDE_BIT)
219 #define DO_FULL_QUAD 1
223 #define HAVE_BACK_COLORS 0
224 #define HAVE_HW_FLATSHADE 1
225 #define VERTEX i810Vertex
229 #define DEPTH_SCALE (1.0/0xffff)
230 #define UNFILLED_TRI unfilled_tri
231 #define UNFILLED_QUAD unfilled_quad
232 #define VERT_X(_v) _v->v.x
233 #define VERT_Y(_v) _v->v.y
234 #define VERT_Z(_v) _v->v.z
235 #define AREA_IS_CCW( a ) (a > 0)
236 #define GET_VERTEX(e) (imesa->verts + (e * imesa->vertex_size * sizeof(int)))
238 #define VERT_SET_RGBA( v, c ) \
240 i810_color_t *color = (i810_color_t *)&((v)->ui[coloroffset]); \
241 UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
242 UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
243 UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
244 UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
247 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
249 #define VERT_SET_SPEC( v0, c ) \
252 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]); \
253 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]); \
254 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]); \
257 #define VERT_COPY_SPEC( v0, v1 ) \
260 v0->v.specular.red = v1->v.specular.red; \
261 v0->v.specular.green = v1->v.specular.green; \
262 v0->v.specular.blue = v1->v.specular.blue; \
266 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
267 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
268 #define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = v[idx]->ui[5]
269 #define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx]
271 #define LOCAL_VARS(n) \
272 i810ContextPtr imesa = I810_CONTEXT(ctx); \
273 GLuint color[n], spec[n]; \
274 GLuint coloroffset = (imesa->vertex_size == 4 ? 3 : 4); \
275 GLboolean havespec = (imesa->vertex_size > 4); \
276 (void) color; (void) spec; (void) coloroffset; (void) havespec;
279 /***********************************************************************
280 * Helpers for rendering unfilled primitives *
281 ***********************************************************************/
283 static const GLuint hw_prim
[GL_POLYGON
+1] = {
296 #define RASTERIZE(x) if (imesa->hw_primitive != hw_prim[x]) \
297 i810RasterPrimitive( ctx, x, hw_prim[x] )
298 #define RENDER_PRIMITIVE imesa->render_primitive
300 #define IND I810_FALLBACK_BIT
301 #include "tnl_dd/t_dd_unfilled.h"
304 /***********************************************************************
305 * Generate GL render functions *
306 ***********************************************************************/
310 #include "tnl_dd/t_dd_tritmp.h"
312 #define IND (I810_OFFSET_BIT)
313 #define TAG(x) x##_offset
314 #include "tnl_dd/t_dd_tritmp.h"
316 #define IND (I810_TWOSIDE_BIT)
317 #define TAG(x) x##_twoside
318 #include "tnl_dd/t_dd_tritmp.h"
320 #define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT)
321 #define TAG(x) x##_twoside_offset
322 #include "tnl_dd/t_dd_tritmp.h"
324 #define IND (I810_UNFILLED_BIT)
325 #define TAG(x) x##_unfilled
326 #include "tnl_dd/t_dd_tritmp.h"
328 #define IND (I810_OFFSET_BIT|I810_UNFILLED_BIT)
329 #define TAG(x) x##_offset_unfilled
330 #include "tnl_dd/t_dd_tritmp.h"
332 #define IND (I810_TWOSIDE_BIT|I810_UNFILLED_BIT)
333 #define TAG(x) x##_twoside_unfilled
334 #include "tnl_dd/t_dd_tritmp.h"
336 #define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_UNFILLED_BIT)
337 #define TAG(x) x##_twoside_offset_unfilled
338 #include "tnl_dd/t_dd_tritmp.h"
340 #define IND (I810_FALLBACK_BIT)
341 #define TAG(x) x##_fallback
342 #include "tnl_dd/t_dd_tritmp.h"
344 #define IND (I810_OFFSET_BIT|I810_FALLBACK_BIT)
345 #define TAG(x) x##_offset_fallback
346 #include "tnl_dd/t_dd_tritmp.h"
348 #define IND (I810_TWOSIDE_BIT|I810_FALLBACK_BIT)
349 #define TAG(x) x##_twoside_fallback
350 #include "tnl_dd/t_dd_tritmp.h"
352 #define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_FALLBACK_BIT)
353 #define TAG(x) x##_twoside_offset_fallback
354 #include "tnl_dd/t_dd_tritmp.h"
356 #define IND (I810_UNFILLED_BIT|I810_FALLBACK_BIT)
357 #define TAG(x) x##_unfilled_fallback
358 #include "tnl_dd/t_dd_tritmp.h"
360 #define IND (I810_OFFSET_BIT|I810_UNFILLED_BIT|I810_FALLBACK_BIT)
361 #define TAG(x) x##_offset_unfilled_fallback
362 #include "tnl_dd/t_dd_tritmp.h"
364 #define IND (I810_TWOSIDE_BIT|I810_UNFILLED_BIT|I810_FALLBACK_BIT)
365 #define TAG(x) x##_twoside_unfilled_fallback
366 #include "tnl_dd/t_dd_tritmp.h"
368 #define IND (I810_TWOSIDE_BIT|I810_OFFSET_BIT|I810_UNFILLED_BIT| \
370 #define TAG(x) x##_twoside_offset_unfilled_fallback
371 #include "tnl_dd/t_dd_tritmp.h"
374 static void init_rast_tab( void )
379 init_twoside_offset();
381 init_offset_unfilled();
382 init_twoside_unfilled();
383 init_twoside_offset_unfilled();
385 init_offset_fallback();
386 init_twoside_fallback();
387 init_twoside_offset_fallback();
388 init_unfilled_fallback();
389 init_offset_unfilled_fallback();
390 init_twoside_unfilled_fallback();
391 init_twoside_offset_unfilled_fallback();
395 /***********************************************************************
396 * Rasterization fallback helpers *
397 ***********************************************************************/
400 /* This code is hit only when a mix of accelerated and unaccelerated
401 * primitives are being drawn, and only for the unaccelerated
405 i810_fallback_tri( i810ContextPtr imesa
,
410 GLcontext
*ctx
= imesa
->glCtx
;
412 i810_translate_vertex( ctx
, v0
, &v
[0] );
413 i810_translate_vertex( ctx
, v1
, &v
[1] );
414 i810_translate_vertex( ctx
, v2
, &v
[2] );
415 _swrast_Triangle( ctx
, &v
[0], &v
[1], &v
[2] );
420 i810_fallback_line( i810ContextPtr imesa
,
424 GLcontext
*ctx
= imesa
->glCtx
;
426 i810_translate_vertex( ctx
, v0
, &v
[0] );
427 i810_translate_vertex( ctx
, v1
, &v
[1] );
428 _swrast_Line( ctx
, &v
[0], &v
[1] );
433 i810_fallback_point( i810ContextPtr imesa
,
436 GLcontext
*ctx
= imesa
->glCtx
;
438 i810_translate_vertex( ctx
, v0
, &v
[0] );
439 _swrast_Point( ctx
, &v
[0] );
444 /**********************************************************************/
445 /* Render unclipped begin/end objects */
446 /**********************************************************************/
449 #define V(x) (i810Vertex *)(vertptr + ((x)*vertsize*sizeof(int)))
450 #define RENDER_POINTS( start, count ) \
451 for ( ; start < count ; start++) POINT( V(ELT(start)) );
452 #define RENDER_LINE( v0, v1 ) LINE( V(v0), V(v1) )
453 #define RENDER_TRI( v0, v1, v2 ) TRI( V(v0), V(v1), V(v2) )
454 #define RENDER_QUAD( v0, v1, v2, v3 ) QUAD( V(v0), V(v1), V(v2), V(v3) )
455 #define INIT(x) i810RenderPrimitive( ctx, x )
458 i810ContextPtr imesa = I810_CONTEXT(ctx); \
459 GLubyte *vertptr = (GLubyte *)imesa->verts; \
460 const GLuint vertsize = imesa->vertex_size; \
461 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
463 #define RESET_STIPPLE
464 #define RESET_OCCLUSION
465 #define PRESERVE_VB_DEFS
467 #define TAG(x) i810_##x##_verts
468 #include "tnl/t_vb_rendertmp.h"
471 #define TAG(x) i810_##x##_elts
472 #define ELT(x) elt[x]
473 #include "tnl/t_vb_rendertmp.h"
475 /**********************************************************************/
476 /* Render clipped primitives */
477 /**********************************************************************/
481 static void i810RenderClippedPoly( GLcontext
*ctx
, const GLuint
*elts
,
484 i810ContextPtr imesa
= I810_CONTEXT(ctx
);
485 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
486 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
487 GLuint prim
= imesa
->render_primitive
;
489 /* Render the new vertices as an unclipped polygon.
492 GLuint
*tmp
= VB
->Elts
;
493 VB
->Elts
= (GLuint
*)elts
;
494 tnl
->Driver
.Render
.PrimTabElts
[GL_POLYGON
]( ctx
, 0, n
,
495 PRIM_BEGIN
|PRIM_END
);
499 /* Restore the render primitive
501 if (prim
!= GL_POLYGON
)
502 tnl
->Driver
.Render
.PrimitiveNotify( ctx
, prim
);
505 static void i810RenderClippedLine( GLcontext
*ctx
, GLuint ii
, GLuint jj
)
507 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
508 tnl
->Driver
.Render
.Line( ctx
, ii
, jj
);
511 static void i810FastRenderClippedPoly( GLcontext
*ctx
, const GLuint
*elts
,
514 i810ContextPtr imesa
= I810_CONTEXT( ctx
);
515 GLuint vertsize
= imesa
->vertex_size
;
516 GLuint
*vb
= i810AllocDmaLow( imesa
, (n
-2) * 3 * 4 * vertsize
);
517 GLubyte
*vertptr
= (GLubyte
*)imesa
->verts
;
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
;