Use the right FALLBACK macro for projtex so that projective textures actually
[mesa.git] / src / mesa / drivers / dri / r128 / r128_tris.c
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 /**************************************************************************
3
4 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
5 VA Linux Systems Inc., Fremont, California.
6
7 All Rights Reserved.
8
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:
15
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
18 Software.
19
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.
27
28 **************************************************************************/
29
30 /*
31 * Authors:
32 * Keith Whitwell <keith@tungstengraphics.com>
33 *
34 */
35
36 #include "glheader.h"
37 #include "mtypes.h"
38 #include "colormac.h"
39 #include "macros.h"
40
41 #include "swrast/swrast.h"
42 #include "swrast_setup/swrast_setup.h"
43 #include "tnl/tnl.h"
44 #include "tnl/t_context.h"
45 #include "tnl/t_pipeline.h"
46
47 #include "r128_tris.h"
48 #include "r128_state.h"
49 #include "r128_tex.h"
50 #include "r128_ioctl.h"
51
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,
63 };
64
65 static void r128RasterPrimitive( GLcontext *ctx, GLuint hwprim );
66 static void r128RenderPrimitive( GLcontext *ctx, GLenum prim );
67
68
69 /***********************************************************************
70 * Emit primitives as inline vertices *
71 ***********************************************************************/
72
73 #define HAVE_QUADS 0
74 #define HAVE_LINES 1
75 #define HAVE_POINTS 1
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 )
81 #undef LOCAL_VARS
82 #define LOCAL_VARS \
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
87 #undef TAG
88 #define TAG(x) r128_##x
89 #include "tnl_dd/t_dd_triemit.h"
90 #undef TAG
91 #undef LOCAL_VARS
92
93
94 /***********************************************************************
95 * Macros for t_dd_tritmp.h to draw basic primitives *
96 ***********************************************************************/
97
98 #define TRI( a, b, c ) \
99 do { \
100 if (DO_FALLBACK) \
101 rmesa->draw_tri( rmesa, a, b, c ); \
102 else \
103 r128_triangle( rmesa, a, b, c ); \
104 } while (0)
105
106 #define QUAD( a, b, c, d ) \
107 do { \
108 if (DO_FALLBACK) { \
109 rmesa->draw_tri( rmesa, a, b, d ); \
110 rmesa->draw_tri( rmesa, b, c, d ); \
111 } else \
112 r128_quad( rmesa, a, b, c, d ); \
113 } while (0)
114
115 #define LINE( v0, v1 ) \
116 do { \
117 if (DO_FALLBACK) \
118 rmesa->draw_line( rmesa, v0, v1 ); \
119 else \
120 r128_line( rmesa, v0, v1 ); \
121 } while (0)
122
123 #define POINT( v0 ) \
124 do { \
125 if (DO_FALLBACK) \
126 rmesa->draw_point( rmesa, v0 ); \
127 else \
128 r128_point( rmesa, v0 ); \
129 } while (0)
130
131
132 /***********************************************************************
133 * Build render functions from dd templates *
134 ***********************************************************************/
135
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
141
142
143 static struct {
144 tnl_points_func points;
145 tnl_line_func line;
146 tnl_triangle_func triangle;
147 tnl_quad_func quad;
148 } rast_tab[R128_MAX_TRIFUNC];
149
150
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)
155 #define DO_FLAT 0
156 #define DO_TRI 1
157 #define DO_QUAD 1
158 #define DO_LINE 1
159 #define DO_POINTS 1
160 #define DO_FULL_QUAD 1
161
162 #define HAVE_RGBA 1
163 #define HAVE_SPEC 1
164 #define HAVE_BACK_COLORS 0
165 #define HAVE_HW_FLATSHADE 1
166 #define VERTEX r128Vertex
167 #define TAB rast_tab
168
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)))
177
178 #define VERT_SET_RGBA( v, c ) \
179 do { \
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]); \
185 } while (0)
186
187 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
188
189 #define VERT_SET_SPEC( v0, c ) \
190 do { \
191 if (havespec) { \
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]); \
196 } \
197 } while (0)
198 #define VERT_COPY_SPEC( v0, v1 ) \
199 do { \
200 if (havespec) { \
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; \
206 } \
207 } while (0)
208
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.
211 */
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]
216
217
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;
226
227 /***********************************************************************
228 * Helpers for rendering unfilled primitives *
229 ***********************************************************************/
230
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
235 #define TAG(x) x
236 #include "tnl_dd/t_dd_unfilled.h"
237 #undef IND
238
239
240 /***********************************************************************
241 * Generate GL render functions *
242 ***********************************************************************/
243
244
245 #define IND (0)
246 #define TAG(x) x
247 #include "tnl_dd/t_dd_tritmp.h"
248
249 #define IND (R128_OFFSET_BIT)
250 #define TAG(x) x##_offset
251 #include "tnl_dd/t_dd_tritmp.h"
252
253 #define IND (R128_TWOSIDE_BIT)
254 #define TAG(x) x##_twoside
255 #include "tnl_dd/t_dd_tritmp.h"
256
257 #define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT)
258 #define TAG(x) x##_twoside_offset
259 #include "tnl_dd/t_dd_tritmp.h"
260
261 #define IND (R128_UNFILLED_BIT)
262 #define TAG(x) x##_unfilled
263 #include "tnl_dd/t_dd_tritmp.h"
264
265 #define IND (R128_OFFSET_BIT|R128_UNFILLED_BIT)
266 #define TAG(x) x##_offset_unfilled
267 #include "tnl_dd/t_dd_tritmp.h"
268
269 #define IND (R128_TWOSIDE_BIT|R128_UNFILLED_BIT)
270 #define TAG(x) x##_twoside_unfilled
271 #include "tnl_dd/t_dd_tritmp.h"
272
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"
276
277 #define IND (R128_FALLBACK_BIT)
278 #define TAG(x) x##_fallback
279 #include "tnl_dd/t_dd_tritmp.h"
280
281 #define IND (R128_OFFSET_BIT|R128_FALLBACK_BIT)
282 #define TAG(x) x##_offset_fallback
283 #include "tnl_dd/t_dd_tritmp.h"
284
285 #define IND (R128_TWOSIDE_BIT|R128_FALLBACK_BIT)
286 #define TAG(x) x##_twoside_fallback
287 #include "tnl_dd/t_dd_tritmp.h"
288
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"
292
293 #define IND (R128_UNFILLED_BIT|R128_FALLBACK_BIT)
294 #define TAG(x) x##_unfilled_fallback
295 #include "tnl_dd/t_dd_tritmp.h"
296
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"
300
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"
304
305 #define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT|R128_UNFILLED_BIT| \
306 R128_FALLBACK_BIT)
307 #define TAG(x) x##_twoside_offset_unfilled_fallback
308 #include "tnl_dd/t_dd_tritmp.h"
309
310
311 static void init_rast_tab( void )
312 {
313 init();
314 init_offset();
315 init_twoside();
316 init_twoside_offset();
317 init_unfilled();
318 init_offset_unfilled();
319 init_twoside_unfilled();
320 init_twoside_offset_unfilled();
321 init_fallback();
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();
329 }
330
331
332
333 /***********************************************************************
334 * Rasterization fallback helpers *
335 ***********************************************************************/
336
337
338 /* This code is hit only when a mix of accelerated and unaccelerated
339 * primitives are being drawn, and only for the unaccelerated
340 * primitives.
341 */
342 static void
343 r128_fallback_tri( r128ContextPtr rmesa,
344 r128Vertex *v0,
345 r128Vertex *v1,
346 r128Vertex *v2 )
347 {
348 GLcontext *ctx = rmesa->glCtx;
349 SWvertex v[3];
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] );
355 }
356
357
358 static void
359 r128_fallback_line( r128ContextPtr rmesa,
360 r128Vertex *v0,
361 r128Vertex *v1 )
362 {
363 GLcontext *ctx = rmesa->glCtx;
364 SWvertex v[2];
365 _swsetup_Translate( ctx, v0, &v[0] );
366 _swsetup_Translate( ctx, v1, &v[1] );
367 _swrast_Line( ctx, &v[0], &v[1] );
368 }
369
370
371 static void
372 r128_fallback_point( r128ContextPtr rmesa,
373 r128Vertex *v0 )
374 {
375 GLcontext *ctx = rmesa->glCtx;
376 SWvertex v[1];
377 _swsetup_Translate( ctx, v0, &v[0] );
378 _swrast_Point( ctx, &v[0] );
379 }
380
381
382
383 /**********************************************************************/
384 /* Render unclipped begin/end objects */
385 /**********************************************************************/
386
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 ); \
399 } while (0)
400 #undef LOCAL_VARS
401 #define LOCAL_VARS \
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; \
406 (void) elt;
407 #define RESET_STIPPLE
408 #define RESET_OCCLUSION
409 #define PRESERVE_VB_DEFS
410 #define ELT(x) (x)
411 #define TAG(x) r128_##x##_verts
412 #include "tnl/t_vb_rendertmp.h"
413 #undef ELT
414 #undef TAG
415 #define TAG(x) r128_##x##_elts
416 #define ELT(x) elt[x]
417 #include "tnl/t_vb_rendertmp.h"
418
419
420 /**********************************************************************/
421 /* Choose render functions */
422 /**********************************************************************/
423
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)
430
431 static void r128ChooseRenderState(GLcontext *ctx)
432 {
433 r128ContextPtr rmesa = R128_CONTEXT(ctx);
434 GLuint flags = ctx->_TriangleCaps;
435 GLuint index = 0;
436
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;
441
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;
446 }
447
448 /* Hook in fallbacks for specific primitives.
449 */
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;
455 }
456 }
457
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;
465
466 if (index == 0) {
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;
470 } else {
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;
474 }
475
476 rmesa->RenderIndex = index;
477 }
478 }
479
480 /**********************************************************************/
481 /* Validate state at pipeline start */
482 /**********************************************************************/
483
484 static void r128RunPipeline( GLcontext *ctx )
485 {
486 r128ContextPtr rmesa = R128_CONTEXT(ctx);
487
488 if (rmesa->new_state || rmesa->NewGLState & _NEW_TEXTURE)
489 r128DDUpdateHWState( ctx );
490
491 if (!rmesa->Fallback && rmesa->NewGLState) {
492 if (rmesa->NewGLState & _R128_NEW_RENDER_STATE)
493 r128ChooseRenderState( ctx );
494
495 rmesa->NewGLState = 0;
496 }
497
498 _tnl_run_pipeline( ctx );
499 }
500
501 /**********************************************************************/
502 /* High level hooks for t_vb_render.c */
503 /**********************************************************************/
504
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.
508 *
509 * As the r128 uses triangles to render lines and points, it is
510 * necessary to turn off hardware culling when rendering these
511 * primitives.
512 */
513
514 static void r128RasterPrimitive( GLcontext *ctx, GLuint hwprim )
515 {
516 r128ContextPtr rmesa = R128_CONTEXT(ctx);
517
518 rmesa->setup.dp_gui_master_cntl_c &= ~R128_GMC_BRUSH_NONE;
519
520 if ( ctx->Polygon.StippleFlag && hwprim == GL_TRIANGLES ) {
521 rmesa->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_32x32_MONO_FG_LA;
522 }
523 else {
524 rmesa->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_SOLID_COLOR;
525 }
526
527 rmesa->new_state |= R128_NEW_CONTEXT;
528 rmesa->dirty |= R128_UPLOAD_CONTEXT;
529
530 if (rmesa->hw_primitive != hwprim) {
531 FLUSH_BATCH( rmesa );
532 rmesa->hw_primitive = hwprim;
533 }
534 }
535
536 static void r128RenderPrimitive( GLcontext *ctx, GLenum prim )
537 {
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))
542 return;
543 r128RasterPrimitive( ctx, hw );
544 }
545
546 #define EMIT_ATTR( ATTR, STYLE, VF, SIZE ) \
547 do { \
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++; \
551 vc_frmt |= (VF); \
552 offset += (SIZE); \
553 } while (0)
554
555 #define EMIT_PAD( SIZE ) \
556 do { \
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++; \
561 offset += (SIZE); \
562 } while (0)
563
564 static void r128RenderStart( GLcontext *ctx )
565 {
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;
570 GLuint vc_frmt = 0;
571 GLboolean fallback_projtex = GL_FALSE;
572 GLuint offset = 0;
573
574 /* Important: */
575 VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
576 rmesa->vertex_attr_count = 0;
577 rmesa->specoffset = 0;
578
579 /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
580 * build up a hardware vertex.
581 */
582 if ( index & _TNL_BITS_TEX_ANY )
583 EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, R128_CCE_VC_FRMT_RHW, 16 );
584 else
585 EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 12 );
586
587 rmesa->coloroffset = offset;
588 EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA,
589 R128_CCE_VC_FRMT_DIFFUSE_ARGB, 4 );
590
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 );
596 } else
597 EMIT_PAD( 3 );
598
599 if (index & _TNL_BIT_FOG)
600 EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, R128_CCE_VC_FRMT_SPEC_FRGB,
601 1 );
602 else
603 EMIT_PAD( 1 );
604 }
605
606 if ( index & _TNL_BIT_TEX(rmesa->tmu_source[0]) ) {
607 if ( VB->TexCoordPtr[rmesa->tmu_source[0]]->size > 2 )
608 fallback_projtex = GL_TRUE;
609 EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, R128_CCE_VC_FRMT_S_T, 8 );
610 }
611 if ( index & _TNL_BIT_TEX(rmesa->tmu_source[1]) ) {
612 if ( VB->TexCoordPtr[rmesa->tmu_source[1]]->size > 2 )
613 fallback_projtex = GL_TRUE;
614 EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, R128_CCE_VC_FRMT_S2_T2, 8 );
615 }
616
617 /* projective textures are not supported by the hardware */
618 FALLBACK( rmesa, R128_FALLBACK_PROJTEX, fallback_projtex );
619
620 /* Only need to change the vertex emit code if there has been a
621 * statechange to a TNL index.
622 */
623 if ( index != rmesa->tnl_state ) {
624 FLUSH_BATCH( rmesa );
625 rmesa->dirty |= R128_UPLOAD_CONTEXT;
626
627 rmesa->vertex_size =
628 _tnl_install_attrs( ctx,
629 rmesa->vertex_attrs,
630 rmesa->vertex_attr_count,
631 rmesa->hw_viewport, 0 );
632 rmesa->vertex_size >>= 2;
633
634 rmesa->vertex_format = vc_frmt;
635 }
636 }
637
638 static void r128RenderFinish( GLcontext *ctx )
639 {
640 if (R128_CONTEXT(ctx)->RenderIndex & R128_FALLBACK_BIT)
641 _swrast_flush( ctx );
642 }
643
644
645 /**********************************************************************/
646 /* Transition to/from hardware rasterization. */
647 /**********************************************************************/
648
649 static const char * const fallbackStrings[] = {
650 "Texture mode",
651 "glDrawBuffer(GL_FRONT_AND_BACK)",
652 "glReadBuffer",
653 "glEnable(GL_STENCIL) without hw stencil buffer",
654 "glRenderMode(selection or feedback)",
655 "glLogicOp (mode != GL_COPY)",
656 "GL_SEPARATE_SPECULAR_COLOR",
657 "glBlendEquation",
658 "glBlendFunc(mode != ADD)",
659 "Projective texture",
660 "Rasterization disable",
661 };
662
663
664 static const char *getFallbackString(GLuint bit)
665 {
666 int i = 0;
667 while (bit > 1) {
668 i++;
669 bit >>= 1;
670 }
671 return fallbackStrings[i];
672 }
673
674 void r128Fallback( GLcontext *ctx, GLuint bit, GLboolean mode )
675 {
676 TNLcontext *tnl = TNL_CONTEXT(ctx);
677 r128ContextPtr rmesa = R128_CONTEXT(ctx);
678 GLuint oldfallback = rmesa->Fallback;
679
680 if (mode) {
681 rmesa->Fallback |= bit;
682 if (oldfallback == 0) {
683 FLUSH_BATCH( rmesa );
684 _swsetup_Wakeup( ctx );
685 rmesa->RenderIndex = ~0;
686 if ( R128_DEBUG & DEBUG_VERBOSE_FALL ) {
687 fprintf(stderr, "R128 begin rasterization fallback: 0x%x %s\n",
688 bit, getFallbackString(bit));
689 }
690 }
691 }
692 else {
693 rmesa->Fallback &= ~bit;
694 if (oldfallback == bit) {
695 _swrast_flush( ctx );
696 tnl->Driver.Render.Start = r128RenderStart;
697 tnl->Driver.Render.PrimitiveNotify = r128RenderPrimitive;
698 tnl->Driver.Render.Finish = r128RenderFinish;
699
700 tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
701 tnl->Driver.Render.CopyPV = _tnl_copy_pv;
702 tnl->Driver.Render.Interp = _tnl_interp;
703
704 _tnl_invalidate_vertex_state( ctx, ~0 );
705 _tnl_invalidate_vertices( ctx, ~0 );
706 _tnl_install_attrs( ctx,
707 rmesa->vertex_attrs,
708 rmesa->vertex_attr_count,
709 rmesa->hw_viewport, 0 );
710
711 rmesa->NewGLState |= _R128_NEW_RENDER_STATE;
712 if ( R128_DEBUG & DEBUG_VERBOSE_FALL ) {
713 fprintf(stderr, "R128 end rasterization fallback: 0x%x %s\n",
714 bit, getFallbackString(bit));
715 }
716 }
717 }
718 }
719
720
721 /**********************************************************************/
722 /* Initialization. */
723 /**********************************************************************/
724
725 void r128InitTriFuncs( GLcontext *ctx )
726 {
727 r128ContextPtr rmesa = R128_CONTEXT(ctx);
728 TNLcontext *tnl = TNL_CONTEXT(ctx);
729 static int firsttime = 1;
730
731 if (firsttime) {
732 init_rast_tab();
733 firsttime = 0;
734 }
735
736 tnl->Driver.RunPipeline = r128RunPipeline;
737 tnl->Driver.Render.Start = r128RenderStart;
738 tnl->Driver.Render.Finish = r128RenderFinish;
739 tnl->Driver.Render.PrimitiveNotify = r128RenderPrimitive;
740 tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
741 tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
742 tnl->Driver.Render.CopyPV = _tnl_copy_pv;
743 tnl->Driver.Render.Interp = _tnl_interp;
744
745 _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
746 (6 + 2 * ctx->Const.MaxTextureUnits) * sizeof(GLfloat) );
747 rmesa->verts = (char *)tnl->clipspace.vertex_buf;
748 rmesa->tnl_state = -1;
749
750 rmesa->NewGLState |= _R128_NEW_RENDER_STATE;
751 }