1
/* -*- 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>
36
#include "main/glheader.h"
37
#include "main/mtypes.h"
38
#include "main/colormac.h"
39
#include "main/macros.h"
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)
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 r128SetupAntialias( GLcontext *ctx, GLenum prim )
536
r128ContextPtr rmesa = R128_CONTEXT(ctx);
538
GLuint currAA, wantAA;
540
currAA = (rmesa->setup.pm4_vc_fpu_setup & R128_EDGE_ANTIALIAS) != 0;
541
if( prim >= GL_TRIANGLES )
542
wantAA = ctx->Polygon.SmoothFlag;
543
else if( prim >= GL_LINES )
544
wantAA = ctx->Line.SmoothFlag;
548
if( wantAA != currAA )
550
FLUSH_BATCH( rmesa );
551
rmesa->setup.pm4_vc_fpu_setup ^= R128_EDGE_ANTIALIAS;
552
rmesa->dirty |= R128_UPLOAD_SETUP;
556
static void r128RenderPrimitive( GLcontext *ctx, GLenum prim )
558
r128ContextPtr rmesa = R128_CONTEXT(ctx);
559
GLuint hw = hw_prim[prim];
560
rmesa->render_primitive = prim;
562
r128SetupAntialias( ctx, prim );
564
if (prim >= GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
566
r128RasterPrimitive( ctx, hw );
569
#define EMIT_ATTR( ATTR, STYLE, VF, SIZE ) \
571
rmesa->vertex_attrs[rmesa->vertex_attr_count].attrib = (ATTR); \
572
rmesa->vertex_attrs[rmesa->vertex_attr_count].format = (STYLE); \
573
rmesa->vertex_attr_count++; \
578
#define EMIT_PAD( SIZE ) \
580
rmesa->vertex_attrs[rmesa->vertex_attr_count].attrib = 0; \
581
rmesa->vertex_attrs[rmesa->vertex_attr_count].format = EMIT_PAD; \
582
rmesa->vertex_attrs[rmesa->vertex_attr_count].offset = (SIZE); \
583
rmesa->vertex_attr_count++; \
587
static void r128RenderStart( GLcontext *ctx )
589
r128ContextPtr rmesa = R128_CONTEXT(ctx);
590
TNLcontext *tnl = TNL_CONTEXT(ctx);
591
struct vertex_buffer *VB = &tnl->vb;
592
DECLARE_RENDERINPUTS(index_bitset);
594
GLboolean fallback_projtex = GL_FALSE;
597
RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset );
600
VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
601
rmesa->vertex_attr_count = 0;
602
rmesa->specoffset = 0;
604
/* EMIT_ATTR's must be in order as they tell t_vertex.c how to
605
* build up a hardware vertex.
607
if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX ))
608
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, R128_CCE_VC_FRMT_RHW, 4 );
610
EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F_VIEWPORT, 0, 3 );
612
rmesa->coloroffset = offset;
613
#if MESA_LITTLE_ENDIAN
614
EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA,
615
R128_CCE_VC_FRMT_DIFFUSE_ARGB, 4 );
617
EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_ARGB,
618
R128_CCE_VC_FRMT_DIFFUSE_ARGB, 4 );
621
if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) ||
622
RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) {
623
#if MESA_LITTLE_ENDIAN
624
if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
625
rmesa->specoffset = offset;
626
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR,
627
R128_CCE_VC_FRMT_SPEC_FRGB, 3 );
631
if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG ))
632
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, R128_CCE_VC_FRMT_SPEC_FRGB,
637
if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG ))
638
EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, R128_CCE_VC_FRMT_SPEC_FRGB,
643
if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) {
644
rmesa->specoffset = offset;
645
EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_RGB,
646
R128_CCE_VC_FRMT_SPEC_FRGB, 3 );
652
if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(rmesa->tmu_source[0]) )) {
653
if ( VB->TexCoordPtr[rmesa->tmu_source[0]]->size > 2 )
654
fallback_projtex = GL_TRUE;
655
EMIT_ATTR( _TNL_ATTRIB_TEX0, EMIT_2F, R128_CCE_VC_FRMT_S_T, 8 );
657
if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(rmesa->tmu_source[1]) )) {
658
if ( VB->TexCoordPtr[rmesa->tmu_source[1]]->size > 2 )
659
fallback_projtex = GL_TRUE;
660
EMIT_ATTR( _TNL_ATTRIB_TEX1, EMIT_2F, R128_CCE_VC_FRMT_S2_T2, 8 );
663
/* projective textures are not supported by the hardware */
664
FALLBACK( rmesa, R128_FALLBACK_PROJTEX, fallback_projtex );
666
/* Only need to change the vertex emit code if there has been a
667
* statechange to a TNL index.
669
if (!RENDERINPUTS_EQUAL( index_bitset, rmesa->tnl_state_bitset )) {
670
FLUSH_BATCH( rmesa );
671
rmesa->dirty |= R128_UPLOAD_CONTEXT;
674
_tnl_install_attrs( ctx,
676
rmesa->vertex_attr_count,
677
rmesa->hw_viewport, 0 );
678
rmesa->vertex_size >>= 2;
680
rmesa->vertex_format = vc_frmt;
684
static void r128RenderFinish( GLcontext *ctx )
686
if (R128_CONTEXT(ctx)->RenderIndex & R128_FALLBACK_BIT)
687
_swrast_flush( ctx );
691
/**********************************************************************/
692
/* Transition to/from hardware rasterization. */
693
/**********************************************************************/
695
static const char * const fallbackStrings[] = {
697
"glDrawBuffer(GL_FRONT_AND_BACK)",
699
"glEnable(GL_STENCIL) without hw stencil buffer",
700
"glRenderMode(selection or feedback)",
701
"glLogicOp (mode != GL_COPY)",
702
"GL_SEPARATE_SPECULAR_COLOR",
703
"glBlendEquation(mode != ADD)",
705
"Projective texture",
706
"Rasterization disable",
710
static const char *getFallbackString(GLuint bit)
717
return fallbackStrings[i];
720
void r128Fallback( GLcontext *ctx, GLuint bit, GLboolean mode )
722
TNLcontext *tnl = TNL_CONTEXT(ctx);
723
r128ContextPtr rmesa = R128_CONTEXT(ctx);
724
GLuint oldfallback = rmesa->Fallback;
727
rmesa->Fallback |= bit;
728
if (oldfallback == 0) {
729
FLUSH_BATCH( rmesa );
730
_swsetup_Wakeup( ctx );
731
rmesa->RenderIndex = ~0;
732
if ( R128_DEBUG & DEBUG_VERBOSE_FALL ) {
733
fprintf(stderr, "R128 begin rasterization fallback: 0x%x %s\n",
734
bit, getFallbackString(bit));
739
rmesa->Fallback &= ~bit;
740
if (oldfallback == bit) {
741
_swrast_flush( ctx );
742
tnl->Driver.Render.Start = r128RenderStart;
743
tnl->Driver.Render.PrimitiveNotify = r128RenderPrimitive;
744
tnl->Driver.Render.Finish = r128RenderFinish;
746
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
747
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
748
tnl->Driver.Render.Interp = _tnl_interp;
750
_tnl_invalidate_vertex_state( ctx, ~0 );
751
_tnl_invalidate_vertices( ctx, ~0 );
752
_tnl_install_attrs( ctx,
754
rmesa->vertex_attr_count,
755
rmesa->hw_viewport, 0 );
757
rmesa->NewGLState |= _R128_NEW_RENDER_STATE;
758
if ( R128_DEBUG & DEBUG_VERBOSE_FALL ) {
759
fprintf(stderr, "R128 end rasterization fallback: 0x%x %s\n",
760
bit, getFallbackString(bit));
767
/**********************************************************************/
768
/* Initialization. */
769
/**********************************************************************/
771
void r128InitTriFuncs( GLcontext *ctx )
773
r128ContextPtr rmesa = R128_CONTEXT(ctx);
774
TNLcontext *tnl = TNL_CONTEXT(ctx);
775
static int firsttime = 1;
782
tnl->Driver.RunPipeline = r128RunPipeline;
783
tnl->Driver.Render.Start = r128RenderStart;
784
tnl->Driver.Render.Finish = r128RenderFinish;
785
tnl->Driver.Render.PrimitiveNotify = r128RenderPrimitive;
786
tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple;
787
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
788
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
789
tnl->Driver.Render.Interp = _tnl_interp;
791
_tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
792
(6 + 2 * ctx->Const.MaxTextureUnits) * sizeof(GLfloat) );
793
rmesa->verts = (char *)tnl->clipspace.vertex_buf;
794
RENDERINPUTS_ONES( rmesa->tnl_state_bitset );
796
rmesa->NewGLState |= _R128_NEW_RENDER_STATE;