1 /* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.c,v 1.8 2002/10/30 12:51:43 alanh Exp $ */ /* -*- c-basic-offset: 3 -*- */
2 /**************************************************************************
4 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5 VA Linux Systems Inc., Fremont, California.
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the "Software"),
11 to deal in the Software without restriction, including without limitation
12 on the rights to use, copy, modify, merge, publish, distribute, sub
13 license, and/or sell copies of the Software, and to permit persons to whom
14 the Software is furnished to do so, subject to the following conditions:
16 The above copyright notice and this permission notice (including the next
17 paragraph) shall be included in all copies or substantial portions of the
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
23 ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
24 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
25 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
26 USE OR OTHER DEALINGS IN THE SOFTWARE.
28 **************************************************************************/
32 * Keith Whitwell <keith@tungstengraphics.com>
41 #include "swrast/swrast.h"
42 #include "swrast_setup/swrast_setup.h"
44 #include "tnl/t_context.h"
45 #include "tnl/t_pipeline.h"
47 #include "r128_tris.h"
48 #include "r128_state.h"
50 #include "r128_ioctl.h"
52 static const GLuint hw_prim
[GL_POLYGON
+1] = {
53 R128_CCE_VC_CNTL_PRIM_TYPE_POINT
,
54 R128_CCE_VC_CNTL_PRIM_TYPE_LINE
,
55 R128_CCE_VC_CNTL_PRIM_TYPE_LINE
,
56 R128_CCE_VC_CNTL_PRIM_TYPE_LINE
,
57 R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST
,
58 R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST
,
59 R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST
,
60 R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST
,
61 R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST
,
62 R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST
,
65 static void r128RasterPrimitive( GLcontext
*ctx
, GLuint hwprim
);
66 static void r128RenderPrimitive( GLcontext
*ctx
, GLenum prim
);
69 /***********************************************************************
70 * Emit primitives as inline vertices *
71 ***********************************************************************/
76 #define HAVE_LE32_VERTS 1
77 #define CTX_ARG r128ContextPtr rmesa
78 #define GET_VERTEX_DWORDS() rmesa->vertex_size
79 #define ALLOC_VERTS( n, size ) r128AllocDmaLow( rmesa, (n), (size) * 4 )
82 r128ContextPtr rmesa = R128_CONTEXT(ctx); \
83 const char *vertptr = rmesa->verts;
84 #define VERT(x) (r128Vertex *)(vertptr + ((x) * vertsize * 4))
85 #define VERTEX r128Vertex
87 #define TAG(x) r128_##x
88 #include "tnl_dd/t_dd_triemit.h"
93 /***********************************************************************
94 * Macros for t_dd_tritmp.h to draw basic primitives *
95 ***********************************************************************/
97 #define TRI( a, b, c ) \
100 rmesa->draw_tri( rmesa, a, b, c ); \
102 r128_triangle( rmesa, a, b, c ); \
105 #define QUAD( a, b, c, d ) \
108 rmesa->draw_tri( rmesa, a, b, d ); \
109 rmesa->draw_tri( rmesa, b, c, d ); \
111 r128_quad( rmesa, a, b, c, d ); \
114 #define LINE( v0, v1 ) \
117 rmesa->draw_line( rmesa, v0, v1 ); \
119 r128_line( rmesa, v0, v1 ); \
122 #define POINT( v0 ) \
125 rmesa->draw_point( rmesa, v0 ); \
127 r128_point( rmesa, v0 ); \
131 /***********************************************************************
132 * Build render functions from dd templates *
133 ***********************************************************************/
135 #define R128_OFFSET_BIT 0x01
136 #define R128_TWOSIDE_BIT 0x02
137 #define R128_UNFILLED_BIT 0x04
138 #define R128_FALLBACK_BIT 0x08
139 #define R128_MAX_TRIFUNC 0x10
143 tnl_points_func points
;
145 tnl_triangle_func triangle
;
147 } rast_tab
[R128_MAX_TRIFUNC
];
150 #define DO_FALLBACK (IND & R128_FALLBACK_BIT)
151 #define DO_OFFSET (IND & R128_OFFSET_BIT)
152 #define DO_UNFILLED (IND & R128_UNFILLED_BIT)
153 #define DO_TWOSIDE (IND & R128_TWOSIDE_BIT)
159 #define DO_FULL_QUAD 1
163 #define HAVE_BACK_COLORS 0
164 #define HAVE_HW_FLATSHADE 1
165 #define VERTEX r128Vertex
168 #define DEPTH_SCALE rmesa->depth_scale
169 #define UNFILLED_TRI unfilled_tri
170 #define UNFILLED_QUAD unfilled_quad
171 #define VERT_X(_v) _v->v.x
172 #define VERT_Y(_v) _v->v.y
173 #define VERT_Z(_v) _v->v.z
174 #define AREA_IS_CCW( a ) (a > 0)
175 #define GET_VERTEX(e) (rmesa->verts + (e * rmesa->vertex_size * sizeof(int)))
177 #define VERT_SET_RGBA( v, c ) \
179 r128_color_t *color = (r128_color_t *)&((v)->ui[coloroffset]); \
180 UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
181 UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
182 UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
183 UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
186 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
188 #define VERT_SET_SPEC( v0, c ) \
191 r128_color_t *spec = (r128_color_t *)&((v0)->ui[specoffset]); \
192 UNCLAMPED_FLOAT_TO_UBYTE(spec->red, (c)[0]); \
193 UNCLAMPED_FLOAT_TO_UBYTE(spec->green, (c)[1]); \
194 UNCLAMPED_FLOAT_TO_UBYTE(spec->blue, (c)[2]); \
197 #define VERT_COPY_SPEC( v0, v1 ) \
200 r128_color_t *spec0 = (r128_color_t *)&((v0)->ui[specoffset]); \
201 r128_color_t *spec1 = (r128_color_t *)&((v1)->ui[specoffset]); \
202 spec0->red = spec1->red; \
203 spec0->green = spec1->green; \
204 spec0->blue = spec1->blue; \
208 /* These don't need LE32_TO_CPU() as they are used to save and restore
209 * colors which are already in the correct format.
211 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
212 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
213 #define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = v[idx]->ui[specoffset]
214 #define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[specoffset] = spec[idx]
217 #define LOCAL_VARS(n) \
218 r128ContextPtr rmesa = R128_CONTEXT(ctx); \
219 GLuint color[n], spec[n]; \
220 GLuint coloroffset = rmesa->coloroffset; \
221 GLuint specoffset = rmesa->specoffset; \
222 GLboolean havespec = (rmesa->specoffset != 0); \
223 (void) color; (void) spec; (void) specoffset; \
224 (void) coloroffset; (void) havespec;
226 /***********************************************************************
227 * Helpers for rendering unfilled primitives *
228 ***********************************************************************/
230 #define RASTERIZE(x) if (rmesa->hw_primitive != hw_prim[x]) \
231 r128RasterPrimitive( ctx, hw_prim[x] )
232 #define RENDER_PRIMITIVE rmesa->render_primitive
233 #define IND R128_FALLBACK_BIT
235 #include "tnl_dd/t_dd_unfilled.h"
239 /***********************************************************************
240 * Generate GL render functions *
241 ***********************************************************************/
246 #include "tnl_dd/t_dd_tritmp.h"
248 #define IND (R128_OFFSET_BIT)
249 #define TAG(x) x##_offset
250 #include "tnl_dd/t_dd_tritmp.h"
252 #define IND (R128_TWOSIDE_BIT)
253 #define TAG(x) x##_twoside
254 #include "tnl_dd/t_dd_tritmp.h"
256 #define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT)
257 #define TAG(x) x##_twoside_offset
258 #include "tnl_dd/t_dd_tritmp.h"
260 #define IND (R128_UNFILLED_BIT)
261 #define TAG(x) x##_unfilled
262 #include "tnl_dd/t_dd_tritmp.h"
264 #define IND (R128_OFFSET_BIT|R128_UNFILLED_BIT)
265 #define TAG(x) x##_offset_unfilled
266 #include "tnl_dd/t_dd_tritmp.h"
268 #define IND (R128_TWOSIDE_BIT|R128_UNFILLED_BIT)
269 #define TAG(x) x##_twoside_unfilled
270 #include "tnl_dd/t_dd_tritmp.h"
272 #define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT|R128_UNFILLED_BIT)
273 #define TAG(x) x##_twoside_offset_unfilled
274 #include "tnl_dd/t_dd_tritmp.h"
276 #define IND (R128_FALLBACK_BIT)
277 #define TAG(x) x##_fallback
278 #include "tnl_dd/t_dd_tritmp.h"
280 #define IND (R128_OFFSET_BIT|R128_FALLBACK_BIT)
281 #define TAG(x) x##_offset_fallback
282 #include "tnl_dd/t_dd_tritmp.h"
284 #define IND (R128_TWOSIDE_BIT|R128_FALLBACK_BIT)
285 #define TAG(x) x##_twoside_fallback
286 #include "tnl_dd/t_dd_tritmp.h"
288 #define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT|R128_FALLBACK_BIT)
289 #define TAG(x) x##_twoside_offset_fallback
290 #include "tnl_dd/t_dd_tritmp.h"
292 #define IND (R128_UNFILLED_BIT|R128_FALLBACK_BIT)
293 #define TAG(x) x##_unfilled_fallback
294 #include "tnl_dd/t_dd_tritmp.h"
296 #define IND (R128_OFFSET_BIT|R128_UNFILLED_BIT|R128_FALLBACK_BIT)
297 #define TAG(x) x##_offset_unfilled_fallback
298 #include "tnl_dd/t_dd_tritmp.h"
300 #define IND (R128_TWOSIDE_BIT|R128_UNFILLED_BIT|R128_FALLBACK_BIT)
301 #define TAG(x) x##_twoside_unfilled_fallback
302 #include "tnl_dd/t_dd_tritmp.h"
304 #define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT|R128_UNFILLED_BIT| \
306 #define TAG(x) x##_twoside_offset_unfilled_fallback
307 #include "tnl_dd/t_dd_tritmp.h"
310 static void init_rast_tab( void )
315 init_twoside_offset();
317 init_offset_unfilled();
318 init_twoside_unfilled();
319 init_twoside_offset_unfilled();
321 init_offset_fallback();
322 init_twoside_fallback();
323 init_twoside_offset_fallback();
324 init_unfilled_fallback();
325 init_offset_unfilled_fallback();
326 init_twoside_unfilled_fallback();
327 init_twoside_offset_unfilled_fallback();
332 /***********************************************************************
333 * Rasterization fallback helpers *
334 ***********************************************************************/
337 /* This code is hit only when a mix of accelerated and unaccelerated
338 * primitives are being drawn, and only for the unaccelerated
342 r128_fallback_tri( r128ContextPtr rmesa
,
347 GLcontext
*ctx
= rmesa
->glCtx
;
349 _swsetup_Translate( ctx
, v0
, &v
[0] );
350 _swsetup_Translate( ctx
, v1
, &v
[1] );
351 _swsetup_Translate( ctx
, v2
, &v
[2] );
352 _swrast_Triangle( ctx
, &v
[0], &v
[1], &v
[2] );
357 r128_fallback_line( r128ContextPtr rmesa
,
361 GLcontext
*ctx
= rmesa
->glCtx
;
363 _swsetup_Translate( ctx
, v0
, &v
[0] );
364 _swsetup_Translate( ctx
, v1
, &v
[1] );
365 _swrast_Line( ctx
, &v
[0], &v
[1] );
370 r128_fallback_point( r128ContextPtr rmesa
,
373 GLcontext
*ctx
= rmesa
->glCtx
;
375 _swsetup_Translate( ctx
, v0
, &v
[0] );
376 _swrast_Point( ctx
, &v
[0] );
381 /**********************************************************************/
382 /* Render unclipped begin/end objects */
383 /**********************************************************************/
385 #define RENDER_POINTS( start, count ) \
386 for ( ; start < count ; start++) \
387 r128_point( rmesa, VERT(start) )
388 #define RENDER_LINE( v0, v1 ) \
389 r128_line( rmesa, VERT(v0), VERT(v1) )
390 #define RENDER_TRI( v0, v1, v2 ) \
391 r128_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
392 #define RENDER_QUAD( v0, v1, v2, v3 ) \
393 r128_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
394 #define INIT(x) do { \
395 if (0) fprintf(stderr, "%s\n", __FUNCTION__); \
396 r128RenderPrimitive( ctx, x ); \
400 r128ContextPtr rmesa = R128_CONTEXT(ctx); \
401 const GLuint vertsize = rmesa->vertex_size; \
402 const char *vertptr = (char *)rmesa->verts; \
403 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
405 #define RESET_STIPPLE
406 #define RESET_OCCLUSION
407 #define PRESERVE_VB_DEFS
409 #define TAG(x) r128_##x##_verts
410 #include "tnl/t_vb_rendertmp.h"
413 #define TAG(x) r128_##x##_elts
414 #define ELT(x) elt[x]
415 #include "tnl/t_vb_rendertmp.h"
418 /**********************************************************************/
419 /* Choose render functions */
420 /**********************************************************************/
422 #define POINT_FALLBACK (DD_POINT_SMOOTH)
423 #define LINE_FALLBACK (DD_LINE_STIPPLE|DD_LINE_SMOOTH)
424 #define TRI_FALLBACK (DD_TRI_SMOOTH)
425 #define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)
426 #define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
427 #define _R128_NEW_RENDER_STATE (ANY_FALLBACK_FLAGS | ANY_RASTER_FLAGS)
429 static void r128ChooseRenderState(GLcontext
*ctx
)
431 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
432 GLuint flags
= ctx
->_TriangleCaps
;
435 if (flags
& (ANY_RASTER_FLAGS
|ANY_FALLBACK_FLAGS
)) {
436 rmesa
->draw_point
= r128_point
;
437 rmesa
->draw_line
= r128_line
;
438 rmesa
->draw_tri
= r128_triangle
;
440 if (flags
& ANY_RASTER_FLAGS
) {
441 if (flags
& DD_TRI_LIGHT_TWOSIDE
) index
|= R128_TWOSIDE_BIT
;
442 if (flags
& DD_TRI_OFFSET
) index
|= R128_OFFSET_BIT
;
443 if (flags
& DD_TRI_UNFILLED
) index
|= R128_UNFILLED_BIT
;
446 /* Hook in fallbacks for specific primitives.
448 if (flags
& (POINT_FALLBACK
|LINE_FALLBACK
|TRI_FALLBACK
)) {
449 if (flags
& POINT_FALLBACK
) rmesa
->draw_point
= r128_fallback_point
;
450 if (flags
& LINE_FALLBACK
) rmesa
->draw_line
= r128_fallback_line
;
451 if (flags
& TRI_FALLBACK
) rmesa
->draw_tri
= r128_fallback_tri
;
452 index
|= R128_FALLBACK_BIT
;
456 if (index
!= rmesa
->RenderIndex
) {
457 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
458 tnl
->Driver
.Render
.Points
= rast_tab
[index
].points
;
459 tnl
->Driver
.Render
.Line
= rast_tab
[index
].line
;
460 tnl
->Driver
.Render
.ClippedLine
= rast_tab
[index
].line
;
461 tnl
->Driver
.Render
.Triangle
= rast_tab
[index
].triangle
;
462 tnl
->Driver
.Render
.Quad
= rast_tab
[index
].quad
;
465 tnl
->Driver
.Render
.PrimTabVerts
= r128_render_tab_verts
;
466 tnl
->Driver
.Render
.PrimTabElts
= r128_render_tab_elts
;
467 tnl
->Driver
.Render
.ClippedPolygon
= r128_fast_clipped_poly
;
469 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
470 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
471 tnl
->Driver
.Render
.ClippedPolygon
= _tnl_RenderClippedPolygon
;
474 rmesa
->RenderIndex
= index
;
478 /**********************************************************************/
479 /* Validate state at pipeline start */
480 /**********************************************************************/
482 static void r128RunPipeline( GLcontext
*ctx
)
484 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
486 if (rmesa
->new_state
|| rmesa
->NewGLState
& _NEW_TEXTURE
)
487 r128DDUpdateHWState( ctx
);
489 if (!rmesa
->Fallback
&& rmesa
->NewGLState
) {
490 if (rmesa
->NewGLState
& _R128_NEW_RENDER_STATE
)
491 r128ChooseRenderState( ctx
);
493 rmesa
->NewGLState
= 0;
496 _tnl_run_pipeline( ctx
);
499 /**********************************************************************/
500 /* High level hooks for t_vb_render.c */
501 /**********************************************************************/
503 /* This is called when Mesa switches between rendering triangle
504 * primitives (such as GL_POLYGON, GL_QUADS, GL_TRIANGLE_STRIP, etc),
505 * and lines, points and bitmaps.
507 * As the r128 uses triangles to render lines and points, it is
508 * necessary to turn off hardware culling when rendering these
512 static void r128RasterPrimitive( GLcontext
*ctx
, GLuint hwprim
)
514 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
516 rmesa
->setup
.dp_gui_master_cntl_c
&= ~R128_GMC_BRUSH_NONE
;
518 if ( ctx
->Polygon
.StippleFlag
&& hwprim
== GL_TRIANGLES
) {
519 rmesa
->setup
.dp_gui_master_cntl_c
|= R128_GMC_BRUSH_32x32_MONO_FG_LA
;
522 rmesa
->setup
.dp_gui_master_cntl_c
|= R128_GMC_BRUSH_SOLID_COLOR
;
525 rmesa
->new_state
|= R128_NEW_CONTEXT
;
526 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
528 if (rmesa
->hw_primitive
!= hwprim
) {
529 FLUSH_BATCH( rmesa
);
530 rmesa
->hw_primitive
= hwprim
;
534 static void r128RenderPrimitive( GLcontext
*ctx
, GLenum prim
)
536 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
537 GLuint hw
= hw_prim
[prim
];
538 rmesa
->render_primitive
= prim
;
539 if (prim
>= GL_TRIANGLES
&& (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
))
541 r128RasterPrimitive( ctx
, hw
);
544 #define EMIT_ATTR( ATTR, STYLE, VF, SIZE ) \
546 rmesa->vertex_attrs[rmesa->vertex_attr_count].attrib = (ATTR); \
547 rmesa->vertex_attrs[rmesa->vertex_attr_count].format = (STYLE); \
548 rmesa->vertex_attr_count++; \
553 #define EMIT_PAD( SIZE ) \
555 rmesa->vertex_attrs[rmesa->vertex_attr_count].attrib = 0; \
556 rmesa->vertex_attrs[rmesa->vertex_attr_count].format = EMIT_PAD; \
557 rmesa->vertex_attrs[rmesa->vertex_attr_count].offset = (SIZE); \
558 rmesa->vertex_attr_count++; \
562 static void r128RenderStart( GLcontext
*ctx
)
564 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
565 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
566 struct vertex_buffer
*VB
= &tnl
->vb
;
567 GLuint index
= tnl
->render_inputs
;
569 GLboolean fallback_projtex
= GL_FALSE
;
573 VB
->AttribPtr
[VERT_ATTRIB_POS
] = VB
->NdcPtr
;
574 rmesa
->vertex_attr_count
= 0;
575 rmesa
->specoffset
= 0;
577 /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
578 * build up a hardware vertex.
580 if ( index
& _TNL_BITS_TEX_ANY
)
581 EMIT_ATTR( _TNL_ATTRIB_POS
, EMIT_4F_VIEWPORT
, R128_CCE_VC_FRMT_RHW
, 16 );
583 EMIT_ATTR( _TNL_ATTRIB_POS
, EMIT_3F_VIEWPORT
, 0, 12 );
585 rmesa
->coloroffset
= offset
;
586 #if MESA_LITTLE_ENDIAN
587 EMIT_ATTR( _TNL_ATTRIB_COLOR0
, EMIT_4UB_4F_BGRA
,
588 R128_CCE_VC_FRMT_DIFFUSE_ARGB
, 4 );
590 EMIT_ATTR( _TNL_ATTRIB_COLOR0
, EMIT_4UB_4F_ARGB
,
591 R128_CCE_VC_FRMT_DIFFUSE_ARGB
, 4 );
594 if ( index
& (_TNL_BIT_COLOR1
|_TNL_BIT_FOG
) ) {
595 #if MESA_LITTLE_ENDIAN
596 if ( index
& _TNL_BIT_COLOR1
) {
597 rmesa
->specoffset
= offset
;
598 EMIT_ATTR( _TNL_ATTRIB_COLOR1
, EMIT_3UB_3F_RGB
,
599 R128_CCE_VC_FRMT_SPEC_FRGB
, 3 );
603 if (index
& _TNL_BIT_FOG
)
604 EMIT_ATTR( _TNL_ATTRIB_FOG
, EMIT_1UB_1F
, R128_CCE_VC_FRMT_SPEC_FRGB
,
609 if (index
& _TNL_BIT_FOG
)
610 EMIT_ATTR( _TNL_ATTRIB_FOG
, EMIT_1UB_1F
, R128_CCE_VC_FRMT_SPEC_FRGB
,
615 if ( index
& _TNL_BIT_COLOR1
) {
616 rmesa
->specoffset
= offset
;
617 EMIT_ATTR( _TNL_ATTRIB_COLOR1
, EMIT_3UB_3F_RGB
,
618 R128_CCE_VC_FRMT_SPEC_FRGB
, 3 );
624 if ( index
& _TNL_BIT_TEX(rmesa
->tmu_source
[0]) ) {
625 if ( VB
->TexCoordPtr
[rmesa
->tmu_source
[0]]->size
> 2 )
626 fallback_projtex
= GL_TRUE
;
627 EMIT_ATTR( _TNL_ATTRIB_TEX0
, EMIT_2F
, R128_CCE_VC_FRMT_S_T
, 8 );
629 if ( index
& _TNL_BIT_TEX(rmesa
->tmu_source
[1]) ) {
630 if ( VB
->TexCoordPtr
[rmesa
->tmu_source
[1]]->size
> 2 )
631 fallback_projtex
= GL_TRUE
;
632 EMIT_ATTR( _TNL_ATTRIB_TEX1
, EMIT_2F
, R128_CCE_VC_FRMT_S2_T2
, 8 );
635 /* projective textures are not supported by the hardware */
636 FALLBACK( rmesa
, R128_FALLBACK_PROJTEX
, fallback_projtex
);
638 /* Only need to change the vertex emit code if there has been a
639 * statechange to a TNL index.
641 if ( index
!= rmesa
->tnl_state
) {
642 FLUSH_BATCH( rmesa
);
643 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
646 _tnl_install_attrs( ctx
,
648 rmesa
->vertex_attr_count
,
649 rmesa
->hw_viewport
, 0 );
650 rmesa
->vertex_size
>>= 2;
652 rmesa
->vertex_format
= vc_frmt
;
656 static void r128RenderFinish( GLcontext
*ctx
)
658 if (R128_CONTEXT(ctx
)->RenderIndex
& R128_FALLBACK_BIT
)
659 _swrast_flush( ctx
);
663 /**********************************************************************/
664 /* Transition to/from hardware rasterization. */
665 /**********************************************************************/
667 static const char * const fallbackStrings
[] = {
669 "glDrawBuffer(GL_FRONT_AND_BACK)",
671 "glEnable(GL_STENCIL) without hw stencil buffer",
672 "glRenderMode(selection or feedback)",
673 "glLogicOp (mode != GL_COPY)",
674 "GL_SEPARATE_SPECULAR_COLOR",
675 "glBlendEquation(mode != ADD)",
677 "Projective texture",
678 "Rasterization disable",
682 static const char *getFallbackString(GLuint bit
)
689 return fallbackStrings
[i
];
692 void r128Fallback( GLcontext
*ctx
, GLuint bit
, GLboolean mode
)
694 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
695 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
696 GLuint oldfallback
= rmesa
->Fallback
;
699 rmesa
->Fallback
|= bit
;
700 if (oldfallback
== 0) {
701 FLUSH_BATCH( rmesa
);
702 _swsetup_Wakeup( ctx
);
703 rmesa
->RenderIndex
= ~0;
704 if ( R128_DEBUG
& DEBUG_VERBOSE_FALL
) {
705 fprintf(stderr
, "R128 begin rasterization fallback: 0x%x %s\n",
706 bit
, getFallbackString(bit
));
711 rmesa
->Fallback
&= ~bit
;
712 if (oldfallback
== bit
) {
713 _swrast_flush( ctx
);
714 tnl
->Driver
.Render
.Start
= r128RenderStart
;
715 tnl
->Driver
.Render
.PrimitiveNotify
= r128RenderPrimitive
;
716 tnl
->Driver
.Render
.Finish
= r128RenderFinish
;
718 tnl
->Driver
.Render
.BuildVertices
= _tnl_build_vertices
;
719 tnl
->Driver
.Render
.CopyPV
= _tnl_copy_pv
;
720 tnl
->Driver
.Render
.Interp
= _tnl_interp
;
722 _tnl_invalidate_vertex_state( ctx
, ~0 );
723 _tnl_invalidate_vertices( ctx
, ~0 );
724 _tnl_install_attrs( ctx
,
726 rmesa
->vertex_attr_count
,
727 rmesa
->hw_viewport
, 0 );
729 rmesa
->NewGLState
|= _R128_NEW_RENDER_STATE
;
730 if ( R128_DEBUG
& DEBUG_VERBOSE_FALL
) {
731 fprintf(stderr
, "R128 end rasterization fallback: 0x%x %s\n",
732 bit
, getFallbackString(bit
));
739 /**********************************************************************/
740 /* Initialization. */
741 /**********************************************************************/
743 void r128InitTriFuncs( GLcontext
*ctx
)
745 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
746 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
747 static int firsttime
= 1;
754 tnl
->Driver
.RunPipeline
= r128RunPipeline
;
755 tnl
->Driver
.Render
.Start
= r128RenderStart
;
756 tnl
->Driver
.Render
.Finish
= r128RenderFinish
;
757 tnl
->Driver
.Render
.PrimitiveNotify
= r128RenderPrimitive
;
758 tnl
->Driver
.Render
.ResetLineStipple
= _swrast_ResetLineStipple
;
759 tnl
->Driver
.Render
.BuildVertices
= _tnl_build_vertices
;
760 tnl
->Driver
.Render
.CopyPV
= _tnl_copy_pv
;
761 tnl
->Driver
.Render
.Interp
= _tnl_interp
;
763 _tnl_init_vertices( ctx
, ctx
->Const
.MaxArrayLockSize
+ 12,
764 (6 + 2 * ctx
->Const
.MaxTextureUnits
) * sizeof(GLfloat
) );
765 rmesa
->verts
= (char *)tnl
->clipspace
.vertex_buf
;
766 rmesa
->tnl_state
= -1;
768 rmesa
->NewGLState
|= _R128_NEW_RENDER_STATE
;