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 CTX_ARG2 rmesa
79 #define GET_VERTEX_DWORDS() rmesa->vertex_size
80 #define ALLOC_VERTS( n, size ) r128AllocDmaLow( rmesa, (n), (size) * 4 )
83 r128ContextPtr rmesa = R128_CONTEXT(ctx); \
84 const char *vertptr = rmesa->verts;
85 #define VERT(x) (r128Vertex *)(vertptr + ((x) * vertsize * 4))
86 #define VERTEX r128Vertex
88 #define TAG(x) r128_##x
89 #include "tnl_dd/t_dd_triemit.h"
94 /***********************************************************************
95 * Macros for t_dd_tritmp.h to draw basic primitives *
96 ***********************************************************************/
98 #define TRI( a, b, c ) \
101 rmesa->draw_tri( rmesa, a, b, c ); \
103 r128_triangle( rmesa, a, b, c ); \
106 #define QUAD( a, b, c, d ) \
109 rmesa->draw_tri( rmesa, a, b, d ); \
110 rmesa->draw_tri( rmesa, b, c, d ); \
112 r128_quad( rmesa, a, b, c, d ); \
115 #define LINE( v0, v1 ) \
118 rmesa->draw_line( rmesa, v0, v1 ); \
120 r128_line( rmesa, v0, v1 ); \
123 #define POINT( v0 ) \
126 rmesa->draw_point( rmesa, v0 ); \
128 r128_point( rmesa, v0 ); \
132 /***********************************************************************
133 * Build render functions from dd templates *
134 ***********************************************************************/
136 #define R128_OFFSET_BIT 0x01
137 #define R128_TWOSIDE_BIT 0x02
138 #define R128_UNFILLED_BIT 0x04
139 #define R128_FALLBACK_BIT 0x08
140 #define R128_MAX_TRIFUNC 0x10
144 tnl_points_func points
;
146 tnl_triangle_func triangle
;
148 } rast_tab
[R128_MAX_TRIFUNC
];
151 #define DO_FALLBACK (IND & R128_FALLBACK_BIT)
152 #define DO_OFFSET (IND & R128_OFFSET_BIT)
153 #define DO_UNFILLED (IND & R128_UNFILLED_BIT)
154 #define DO_TWOSIDE (IND & R128_TWOSIDE_BIT)
160 #define DO_FULL_QUAD 1
164 #define HAVE_BACK_COLORS 0
165 #define HAVE_HW_FLATSHADE 1
166 #define VERTEX r128Vertex
169 #define DEPTH_SCALE rmesa->depth_scale
170 #define UNFILLED_TRI unfilled_tri
171 #define UNFILLED_QUAD unfilled_quad
172 #define VERT_X(_v) _v->v.x
173 #define VERT_Y(_v) _v->v.y
174 #define VERT_Z(_v) _v->v.z
175 #define AREA_IS_CCW( a ) (a > 0)
176 #define GET_VERTEX(e) (rmesa->verts + (e * rmesa->vertex_size * sizeof(int)))
178 #define VERT_SET_RGBA( v, c ) \
180 r128_color_t *color = (r128_color_t *)&((v)->ui[coloroffset]); \
181 UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
182 UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
183 UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
184 UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
187 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
189 #define VERT_SET_SPEC( v0, c ) \
192 r128_color_t *spec = (r128_color_t *)&((v0)->ui[specoffset]); \
193 UNCLAMPED_FLOAT_TO_UBYTE(spec->red, (c)[0]); \
194 UNCLAMPED_FLOAT_TO_UBYTE(spec->green, (c)[1]); \
195 UNCLAMPED_FLOAT_TO_UBYTE(spec->blue, (c)[2]); \
198 #define VERT_COPY_SPEC( v0, v1 ) \
201 r128_color_t *spec0 = (r128_color_t *)&((v0)->ui[specoffset]); \
202 r128_color_t *spec1 = (r128_color_t *)&((v1)->ui[specoffset]); \
203 spec0->red = spec1->red; \
204 spec0->green = spec1->green; \
205 spec0->blue = spec1->blue; \
209 /* These don't need LE32_TO_CPU() as they are used to save and restore
210 * colors which are already in the correct format.
212 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
213 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
214 #define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = v[idx]->ui[specoffset]
215 #define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[specoffset] = spec[idx]
218 #define LOCAL_VARS(n) \
219 r128ContextPtr rmesa = R128_CONTEXT(ctx); \
220 GLuint color[n], spec[n]; \
221 GLuint coloroffset = rmesa->coloroffset; \
222 GLuint specoffset = rmesa->specoffset; \
223 GLboolean havespec = (rmesa->specoffset != 0); \
224 (void) color; (void) spec; (void) specoffset; \
225 (void) coloroffset; (void) havespec;
227 /***********************************************************************
228 * Helpers for rendering unfilled primitives *
229 ***********************************************************************/
231 #define RASTERIZE(x) if (rmesa->hw_primitive != hw_prim[x]) \
232 r128RasterPrimitive( ctx, hw_prim[x] )
233 #define RENDER_PRIMITIVE rmesa->render_primitive
234 #define IND R128_FALLBACK_BIT
236 #include "tnl_dd/t_dd_unfilled.h"
240 /***********************************************************************
241 * Generate GL render functions *
242 ***********************************************************************/
247 #include "tnl_dd/t_dd_tritmp.h"
249 #define IND (R128_OFFSET_BIT)
250 #define TAG(x) x##_offset
251 #include "tnl_dd/t_dd_tritmp.h"
253 #define IND (R128_TWOSIDE_BIT)
254 #define TAG(x) x##_twoside
255 #include "tnl_dd/t_dd_tritmp.h"
257 #define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT)
258 #define TAG(x) x##_twoside_offset
259 #include "tnl_dd/t_dd_tritmp.h"
261 #define IND (R128_UNFILLED_BIT)
262 #define TAG(x) x##_unfilled
263 #include "tnl_dd/t_dd_tritmp.h"
265 #define IND (R128_OFFSET_BIT|R128_UNFILLED_BIT)
266 #define TAG(x) x##_offset_unfilled
267 #include "tnl_dd/t_dd_tritmp.h"
269 #define IND (R128_TWOSIDE_BIT|R128_UNFILLED_BIT)
270 #define TAG(x) x##_twoside_unfilled
271 #include "tnl_dd/t_dd_tritmp.h"
273 #define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT|R128_UNFILLED_BIT)
274 #define TAG(x) x##_twoside_offset_unfilled
275 #include "tnl_dd/t_dd_tritmp.h"
277 #define IND (R128_FALLBACK_BIT)
278 #define TAG(x) x##_fallback
279 #include "tnl_dd/t_dd_tritmp.h"
281 #define IND (R128_OFFSET_BIT|R128_FALLBACK_BIT)
282 #define TAG(x) x##_offset_fallback
283 #include "tnl_dd/t_dd_tritmp.h"
285 #define IND (R128_TWOSIDE_BIT|R128_FALLBACK_BIT)
286 #define TAG(x) x##_twoside_fallback
287 #include "tnl_dd/t_dd_tritmp.h"
289 #define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT|R128_FALLBACK_BIT)
290 #define TAG(x) x##_twoside_offset_fallback
291 #include "tnl_dd/t_dd_tritmp.h"
293 #define IND (R128_UNFILLED_BIT|R128_FALLBACK_BIT)
294 #define TAG(x) x##_unfilled_fallback
295 #include "tnl_dd/t_dd_tritmp.h"
297 #define IND (R128_OFFSET_BIT|R128_UNFILLED_BIT|R128_FALLBACK_BIT)
298 #define TAG(x) x##_offset_unfilled_fallback
299 #include "tnl_dd/t_dd_tritmp.h"
301 #define IND (R128_TWOSIDE_BIT|R128_UNFILLED_BIT|R128_FALLBACK_BIT)
302 #define TAG(x) x##_twoside_unfilled_fallback
303 #include "tnl_dd/t_dd_tritmp.h"
305 #define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT|R128_UNFILLED_BIT| \
307 #define TAG(x) x##_twoside_offset_unfilled_fallback
308 #include "tnl_dd/t_dd_tritmp.h"
311 static void init_rast_tab( void )
316 init_twoside_offset();
318 init_offset_unfilled();
319 init_twoside_unfilled();
320 init_twoside_offset_unfilled();
322 init_offset_fallback();
323 init_twoside_fallback();
324 init_twoside_offset_fallback();
325 init_unfilled_fallback();
326 init_offset_unfilled_fallback();
327 init_twoside_unfilled_fallback();
328 init_twoside_offset_unfilled_fallback();
333 /***********************************************************************
334 * Rasterization fallback helpers *
335 ***********************************************************************/
338 /* This code is hit only when a mix of accelerated and unaccelerated
339 * primitives are being drawn, and only for the unaccelerated
343 r128_fallback_tri( r128ContextPtr rmesa
,
348 GLcontext
*ctx
= rmesa
->glCtx
;
350 _swsetup_Translate( ctx
, v0
, &v
[0] );
351 _swsetup_Translate( ctx
, v1
, &v
[1] );
352 _swsetup_Translate( ctx
, v2
, &v
[2] );
353 /* XXX: SpanRenderStart */
354 _swrast_Triangle( ctx
, &v
[0], &v
[1], &v
[2] );
359 r128_fallback_line( r128ContextPtr rmesa
,
363 GLcontext
*ctx
= rmesa
->glCtx
;
365 _swsetup_Translate( ctx
, v0
, &v
[0] );
366 _swsetup_Translate( ctx
, v1
, &v
[1] );
367 _swrast_Line( ctx
, &v
[0], &v
[1] );
372 r128_fallback_point( r128ContextPtr rmesa
,
375 GLcontext
*ctx
= rmesa
->glCtx
;
377 _swsetup_Translate( ctx
, v0
, &v
[0] );
378 _swrast_Point( ctx
, &v
[0] );
383 /**********************************************************************/
384 /* Render unclipped begin/end objects */
385 /**********************************************************************/
387 #define RENDER_POINTS( start, count ) \
388 for ( ; start < count ; start++) \
389 r128_point( rmesa, VERT(start) )
390 #define RENDER_LINE( v0, v1 ) \
391 r128_line( rmesa, VERT(v0), VERT(v1) )
392 #define RENDER_TRI( v0, v1, v2 ) \
393 r128_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
394 #define RENDER_QUAD( v0, v1, v2, v3 ) \
395 r128_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
396 #define INIT(x) do { \
397 if (0) fprintf(stderr, "%s\n", __FUNCTION__); \
398 r128RenderPrimitive( ctx, x ); \
402 r128ContextPtr rmesa = R128_CONTEXT(ctx); \
403 const GLuint vertsize = rmesa->vertex_size; \
404 const char *vertptr = (char *)rmesa->verts; \
405 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
407 #define RESET_STIPPLE
408 #define RESET_OCCLUSION
409 #define PRESERVE_VB_DEFS
411 #define TAG(x) r128_##x##_verts
412 #include "tnl/t_vb_rendertmp.h"
415 #define TAG(x) r128_##x##_elts
416 #define ELT(x) elt[x]
417 #include "tnl/t_vb_rendertmp.h"
420 /**********************************************************************/
421 /* Choose render functions */
422 /**********************************************************************/
424 #define POINT_FALLBACK (DD_POINT_SMOOTH)
425 #define LINE_FALLBACK (DD_LINE_STIPPLE|DD_LINE_SMOOTH)
426 #define TRI_FALLBACK (DD_TRI_SMOOTH)
427 #define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)
428 #define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
429 #define _R128_NEW_RENDER_STATE (ANY_FALLBACK_FLAGS | ANY_RASTER_FLAGS)
431 static void r128ChooseRenderState(GLcontext
*ctx
)
433 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
434 GLuint flags
= ctx
->_TriangleCaps
;
437 if (flags
& (ANY_RASTER_FLAGS
|ANY_FALLBACK_FLAGS
)) {
438 rmesa
->draw_point
= r128_point
;
439 rmesa
->draw_line
= r128_line
;
440 rmesa
->draw_tri
= r128_triangle
;
442 if (flags
& ANY_RASTER_FLAGS
) {
443 if (flags
& DD_TRI_LIGHT_TWOSIDE
) index
|= R128_TWOSIDE_BIT
;
444 if (flags
& DD_TRI_OFFSET
) index
|= R128_OFFSET_BIT
;
445 if (flags
& DD_TRI_UNFILLED
) index
|= R128_UNFILLED_BIT
;
448 /* Hook in fallbacks for specific primitives.
450 if (flags
& (POINT_FALLBACK
|LINE_FALLBACK
|TRI_FALLBACK
)) {
451 if (flags
& POINT_FALLBACK
) rmesa
->draw_point
= r128_fallback_point
;
452 if (flags
& LINE_FALLBACK
) rmesa
->draw_line
= r128_fallback_line
;
453 if (flags
& TRI_FALLBACK
) rmesa
->draw_tri
= r128_fallback_tri
;
454 index
|= R128_FALLBACK_BIT
;
458 if (index
!= rmesa
->RenderIndex
) {
459 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
460 tnl
->Driver
.Render
.Points
= rast_tab
[index
].points
;
461 tnl
->Driver
.Render
.Line
= rast_tab
[index
].line
;
462 tnl
->Driver
.Render
.ClippedLine
= rast_tab
[index
].line
;
463 tnl
->Driver
.Render
.Triangle
= rast_tab
[index
].triangle
;
464 tnl
->Driver
.Render
.Quad
= rast_tab
[index
].quad
;
467 tnl
->Driver
.Render
.PrimTabVerts
= r128_render_tab_verts
;
468 tnl
->Driver
.Render
.PrimTabElts
= r128_render_tab_elts
;
469 tnl
->Driver
.Render
.ClippedPolygon
= r128_fast_clipped_poly
;
471 tnl
->Driver
.Render
.PrimTabVerts
= _tnl_render_tab_verts
;
472 tnl
->Driver
.Render
.PrimTabElts
= _tnl_render_tab_elts
;
473 tnl
->Driver
.Render
.ClippedPolygon
= _tnl_RenderClippedPolygon
;
476 rmesa
->RenderIndex
= index
;
480 /**********************************************************************/
481 /* Validate state at pipeline start */
482 /**********************************************************************/
484 static void r128RunPipeline( GLcontext
*ctx
)
486 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
488 if (rmesa
->new_state
|| rmesa
->NewGLState
& _NEW_TEXTURE
)
489 r128DDUpdateHWState( ctx
);
491 if (!rmesa
->Fallback
&& rmesa
->NewGLState
) {
492 if (rmesa
->NewGLState
& _R128_NEW_RENDER_STATE
)
493 r128ChooseRenderState( ctx
);
495 rmesa
->NewGLState
= 0;
498 _tnl_run_pipeline( ctx
);
501 /**********************************************************************/
502 /* High level hooks for t_vb_render.c */
503 /**********************************************************************/
505 /* This is called when Mesa switches between rendering triangle
506 * primitives (such as GL_POLYGON, GL_QUADS, GL_TRIANGLE_STRIP, etc),
507 * and lines, points and bitmaps.
509 * As the r128 uses triangles to render lines and points, it is
510 * necessary to turn off hardware culling when rendering these
514 static void r128RasterPrimitive( GLcontext
*ctx
, GLuint hwprim
)
516 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
518 rmesa
->setup
.dp_gui_master_cntl_c
&= ~R128_GMC_BRUSH_NONE
;
520 if ( ctx
->Polygon
.StippleFlag
&& hwprim
== GL_TRIANGLES
) {
521 rmesa
->setup
.dp_gui_master_cntl_c
|= R128_GMC_BRUSH_32x32_MONO_FG_LA
;
524 rmesa
->setup
.dp_gui_master_cntl_c
|= R128_GMC_BRUSH_SOLID_COLOR
;
527 rmesa
->new_state
|= R128_NEW_CONTEXT
;
528 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
530 if (rmesa
->hw_primitive
!= hwprim
) {
531 FLUSH_BATCH( rmesa
);
532 rmesa
->hw_primitive
= hwprim
;
536 static void r128RenderPrimitive( GLcontext
*ctx
, GLenum prim
)
538 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
539 GLuint hw
= hw_prim
[prim
];
540 rmesa
->render_primitive
= prim
;
541 if (prim
>= GL_TRIANGLES
&& (ctx
->_TriangleCaps
& DD_TRI_UNFILLED
))
543 r128RasterPrimitive( ctx
, hw
);
546 #define EMIT_ATTR( ATTR, STYLE, VF, SIZE ) \
548 rmesa->vertex_attrs[rmesa->vertex_attr_count].attrib = (ATTR); \
549 rmesa->vertex_attrs[rmesa->vertex_attr_count].format = (STYLE); \
550 rmesa->vertex_attr_count++; \
555 #define EMIT_PAD( SIZE ) \
557 rmesa->vertex_attrs[rmesa->vertex_attr_count].attrib = 0; \
558 rmesa->vertex_attrs[rmesa->vertex_attr_count].format = EMIT_PAD; \
559 rmesa->vertex_attrs[rmesa->vertex_attr_count].offset = (SIZE); \
560 rmesa->vertex_attr_count++; \
564 static void r128RenderStart( GLcontext
*ctx
)
566 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
567 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
568 struct vertex_buffer
*VB
= &tnl
->vb
;
569 GLuint index
= tnl
->render_inputs
;
571 GLboolean fallback_projtex
= GL_FALSE
;
575 VB
->AttribPtr
[VERT_ATTRIB_POS
] = VB
->NdcPtr
;
576 rmesa
->vertex_attr_count
= 0;
577 rmesa
->specoffset
= 0;
579 /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
580 * build up a hardware vertex.
582 if ( index
& _TNL_BITS_TEX_ANY
)
583 EMIT_ATTR( _TNL_ATTRIB_POS
, EMIT_4F_VIEWPORT
, R128_CCE_VC_FRMT_RHW
, 16 );
585 EMIT_ATTR( _TNL_ATTRIB_POS
, EMIT_3F_VIEWPORT
, 0, 12 );
587 rmesa
->coloroffset
= offset
;
588 EMIT_ATTR( _TNL_ATTRIB_COLOR0
, EMIT_4UB_4F_BGRA
,
589 R128_CCE_VC_FRMT_DIFFUSE_ARGB
, 4 );
591 if ( index
& (_TNL_BIT_COLOR1
|_TNL_BIT_FOG
) ) {
592 if ( index
& _TNL_BIT_COLOR1
) {
593 rmesa
->specoffset
= offset
;
594 EMIT_ATTR( _TNL_ATTRIB_COLOR1
, EMIT_3UB_3F_RGB
,
595 R128_CCE_VC_FRMT_SPEC_FRGB
, 3 );
599 if (index
& _TNL_BIT_FOG
)
600 EMIT_ATTR( _TNL_ATTRIB_FOG
, EMIT_1UB_1F
, R128_CCE_VC_FRMT_SPEC_FRGB
,
606 if ( index
& _TNL_BIT_TEX(0) ) {
607 if ( VB
->TexCoordPtr
[0]->size
> 2 )
608 fallback_projtex
= GL_TRUE
;
609 EMIT_ATTR( _TNL_ATTRIB_TEX0
, EMIT_2F
, R128_CCE_VC_FRMT_S_T
, 8 );
610 if ( index
& _TNL_BIT_TEX(1) ) {
611 if ( VB
->TexCoordPtr
[1]->size
> 2 )
612 fallback_projtex
= GL_TRUE
;
613 EMIT_ATTR( _TNL_ATTRIB_TEX1
, EMIT_2F
, R128_CCE_VC_FRMT_S2_T2
, 8 );
615 } else if ( index
& _TNL_BIT_TEX(1) ) {
616 if ( VB
->TexCoordPtr
[1]->size
> 2 )
617 fallback_projtex
= GL_TRUE
;
618 EMIT_ATTR( _TNL_ATTRIB_TEX1
, EMIT_2F
, R128_CCE_VC_FRMT_S_T
, 8 );
621 /* projective textures are not supported by the hardware */
622 FALLBACK( rmesa
, R128_FALLBACK_TEXTURE
, fallback_projtex
);
624 /* Only need to change the vertex emit code if there has been a
625 * statechange to a TNL index.
627 if ( index
!= rmesa
->tnl_state
) {
628 FLUSH_BATCH( rmesa
);
629 rmesa
->dirty
|= R128_UPLOAD_CONTEXT
;
632 _tnl_install_attrs( ctx
,
634 rmesa
->vertex_attr_count
,
635 rmesa
->hw_viewport
, 0 );
636 rmesa
->vertex_size
>>= 2;
638 rmesa
->vertex_format
= vc_frmt
;
642 static void r128RenderFinish( GLcontext
*ctx
)
644 if (R128_CONTEXT(ctx
)->RenderIndex
& R128_FALLBACK_BIT
)
645 _swrast_flush( ctx
);
649 /**********************************************************************/
650 /* Transition to/from hardware rasterization. */
651 /**********************************************************************/
653 static const char * const fallbackStrings
[] = {
655 "glDrawBuffer(GL_FRONT_AND_BACK)",
657 "glEnable(GL_STENCIL) without hw stencil buffer",
658 "glRenderMode(selection or feedback)",
659 "glLogicOp (mode != GL_COPY)",
660 "GL_SEPARATE_SPECULAR_COLOR",
662 "glBlendFunc(mode != ADD)",
663 "Projective texture",
664 "Rasterization disable",
668 static const char *getFallbackString(GLuint bit
)
675 return fallbackStrings
[i
];
678 void r128Fallback( GLcontext
*ctx
, GLuint bit
, GLboolean mode
)
680 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
681 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
682 GLuint oldfallback
= rmesa
->Fallback
;
685 rmesa
->Fallback
|= bit
;
686 if (oldfallback
== 0) {
687 FLUSH_BATCH( rmesa
);
688 _swsetup_Wakeup( ctx
);
689 rmesa
->RenderIndex
= ~0;
690 if ( R128_DEBUG
& DEBUG_VERBOSE_FALL
) {
691 fprintf(stderr
, "R128 begin rasterization fallback: 0x%x %s\n",
692 bit
, getFallbackString(bit
));
697 rmesa
->Fallback
&= ~bit
;
698 if (oldfallback
== bit
) {
699 _swrast_flush( ctx
);
700 tnl
->Driver
.Render
.Start
= r128RenderStart
;
701 tnl
->Driver
.Render
.PrimitiveNotify
= r128RenderPrimitive
;
702 tnl
->Driver
.Render
.Finish
= r128RenderFinish
;
704 tnl
->Driver
.Render
.BuildVertices
= _tnl_build_vertices
;
705 tnl
->Driver
.Render
.CopyPV
= _tnl_copy_pv
;
706 tnl
->Driver
.Render
.Interp
= _tnl_interp
;
708 _tnl_invalidate_vertex_state( ctx
, ~0 );
709 _tnl_invalidate_vertices( ctx
, ~0 );
710 _tnl_install_attrs( ctx
,
712 rmesa
->vertex_attr_count
,
713 rmesa
->hw_viewport
, 0 );
715 rmesa
->NewGLState
|= _R128_NEW_RENDER_STATE
;
716 if ( R128_DEBUG
& DEBUG_VERBOSE_FALL
) {
717 fprintf(stderr
, "R128 end rasterization fallback: 0x%x %s\n",
718 bit
, getFallbackString(bit
));
725 /**********************************************************************/
726 /* Initialization. */
727 /**********************************************************************/
729 void r128InitTriFuncs( GLcontext
*ctx
)
731 r128ContextPtr rmesa
= R128_CONTEXT(ctx
);
732 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
733 static int firsttime
= 1;
740 tnl
->Driver
.RunPipeline
= r128RunPipeline
;
741 tnl
->Driver
.Render
.Start
= r128RenderStart
;
742 tnl
->Driver
.Render
.Finish
= r128RenderFinish
;
743 tnl
->Driver
.Render
.PrimitiveNotify
= r128RenderPrimitive
;
744 tnl
->Driver
.Render
.ResetLineStipple
= _swrast_ResetLineStipple
;
745 tnl
->Driver
.Render
.BuildVertices
= _tnl_build_vertices
;
746 tnl
->Driver
.Render
.CopyPV
= _tnl_copy_pv
;
747 tnl
->Driver
.Render
.Interp
= _tnl_interp
;
749 _tnl_init_vertices( ctx
, ctx
->Const
.MaxArrayLockSize
+ 12,
750 (6 + 2 * ctx
->Const
.MaxTextureUnits
) * sizeof(GLfloat
) );
751 rmesa
->verts
= (char *)tnl
->clipspace
.vertex_buf
;
752 rmesa
->tnl_state
= -1;
754 rmesa
->NewGLState
|= _R128_NEW_RENDER_STATE
;