Home | History | Annotate | Download | only in r200
      1 /*
      2 Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
      3 
      4 The Weather Channel (TM) funded Tungsten Graphics to develop the
      5 initial release of the Radeon 8500 driver under the XFree86 license.
      6 This notice must be preserved.
      7 
      8 Permission is hereby granted, free of charge, to any person obtaining
      9 a copy of this software and associated documentation files (the
     10 "Software"), to deal in the Software without restriction, including
     11 without limitation the rights to use, copy, modify, merge, publish,
     12 distribute, sublicense, and/or sell copies of the Software, and to
     13 permit persons to whom the Software is furnished to do so, subject to
     14 the following conditions:
     15 
     16 The above copyright notice and this permission notice (including the
     17 next paragraph) shall be included in all copies or substantial
     18 portions of the Software.
     19 
     20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
     24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
     25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
     26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     27 
     28 **************************************************************************/
     29 
     30 /*
     31  * Authors:
     32  *   Keith Whitwell <keithw (at) vmware.com>
     33  */
     34 
     35 #include "main/glheader.h"
     36 #include "main/mtypes.h"
     37 #include "main/enums.h"
     38 #include "main/image.h"
     39 #include "main/imports.h"
     40 #include "main/macros.h"
     41 
     42 #include "swrast/s_context.h"
     43 #include "swrast/s_fog.h"
     44 #include "swrast_setup/swrast_setup.h"
     45 #include "tnl/tnl.h"
     46 #include "tnl/t_context.h"
     47 #include "tnl/t_pipeline.h"
     48 
     49 #include "r200_context.h"
     50 #include "r200_ioctl.h"
     51 #include "r200_state.h"
     52 #include "r200_swtcl.h"
     53 #include "r200_tcl.h"
     54 
     55 
     56 /***********************************************************************
     57  *                         Initialization
     58  ***********************************************************************/
     59 
     60 #define EMIT_ATTR( ATTR, STYLE, F0 )					\
     61 do {									\
     62    rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = (ATTR);	\
     63    rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = (STYLE);	\
     64    rmesa->radeon.swtcl.vertex_attr_count++;					\
     65    fmt_0 |= F0;								\
     66 } while (0)
     67 
     68 #define EMIT_PAD( N )							\
     69 do {									\
     70    rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = 0;		\
     71    rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = EMIT_PAD;	\
     72    rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].offset = (N);		\
     73    rmesa->radeon.swtcl.vertex_attr_count++;					\
     74 } while (0)
     75 
     76 static void r200SetVertexFormat( struct gl_context *ctx )
     77 {
     78    r200ContextPtr rmesa = R200_CONTEXT( ctx );
     79    TNLcontext *tnl = TNL_CONTEXT(ctx);
     80    struct vertex_buffer *VB = &tnl->vb;
     81    GLbitfield64 index_bitset = tnl->render_inputs_bitset;
     82    int fmt_0 = 0;
     83    int fmt_1 = 0;
     84    int offset = 0;
     85 
     86    /* Important:
     87     */
     88    if ( VB->NdcPtr != NULL ) {
     89       VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr;
     90    }
     91    else {
     92       VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr;
     93    }
     94 
     95    assert( VB->AttribPtr[VERT_ATTRIB_POS] != NULL );
     96    rmesa->radeon.swtcl.vertex_attr_count = 0;
     97 
     98    /* EMIT_ATTR's must be in order as they tell t_vertex.c how to
     99     * build up a hardware vertex.
    100     */
    101    if ( !rmesa->swtcl.needproj ||
    102         (index_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX)) ) {
    103       /* need w coord for projected textures */
    104       EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F, R200_VTX_XY | R200_VTX_Z0 | R200_VTX_W0 );
    105       offset = 4;
    106    }
    107    else {
    108       EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_3F, R200_VTX_XY | R200_VTX_Z0 );
    109       offset = 3;
    110    }
    111 
    112    if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_POINTSIZE)) {
    113       EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, R200_VTX_POINT_SIZE );
    114       offset += 1;
    115    }
    116 
    117    rmesa->swtcl.coloroffset = offset;
    118 #if MESA_LITTLE_ENDIAN
    119    EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_RGBA, (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT) );
    120 #else
    121    EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_ABGR, (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT) );
    122 #endif
    123    offset += 1;
    124 
    125    rmesa->swtcl.specoffset = 0;
    126    if (index_bitset &
    127        (BITFIELD64_BIT(_TNL_ATTRIB_COLOR1) | BITFIELD64_BIT(_TNL_ATTRIB_FOG))) {
    128 
    129 #if MESA_LITTLE_ENDIAN
    130       if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_COLOR1)) {
    131 	 rmesa->swtcl.specoffset = offset;
    132 	 EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_RGB, (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT) );
    133       }
    134       else {
    135 	 EMIT_PAD( 3 );
    136       }
    137 
    138       if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_FOG)) {
    139 	 EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT) );
    140       }
    141       else {
    142 	 EMIT_PAD( 1 );
    143       }
    144 #else
    145       if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_FOG)) {
    146 	 EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1UB_1F, (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT) );
    147       }
    148       else {
    149 	 EMIT_PAD( 1 );
    150       }
    151 
    152       if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_COLOR1)) {
    153 	 rmesa->swtcl.specoffset = offset;
    154 	 EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR, (R200_VTX_PK_RGBA << R200_VTX_COLOR_1_SHIFT) );
    155       }
    156       else {
    157 	 EMIT_PAD( 3 );
    158       }
    159 #endif
    160    }
    161 
    162    if (index_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX)) {
    163       int i;
    164 
    165       for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
    166 	 if (index_bitset & BITFIELD64_BIT(_TNL_ATTRIB_TEX(i))) {
    167 	    GLuint sz = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->size;
    168 
    169 	    fmt_1 |= sz << (3 * i);
    170 	    EMIT_ATTR( _TNL_ATTRIB_TEX0+i, EMIT_1F + sz - 1, 0 );
    171 	 }
    172       }
    173    }
    174 
    175    if ( (rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] & R200_FOG_USE_MASK)
    176       != R200_FOG_USE_SPEC_ALPHA ) {
    177       R200_STATECHANGE( rmesa, ctx );
    178       rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~R200_FOG_USE_MASK;
    179       rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |= R200_FOG_USE_SPEC_ALPHA;
    180    }
    181 
    182    if (rmesa->radeon.tnl_index_bitset != index_bitset ||
    183 	(rmesa->hw.vtx.cmd[VTX_VTXFMT_0] != fmt_0) ||
    184 	(rmesa->hw.vtx.cmd[VTX_VTXFMT_1] != fmt_1) ) {
    185       R200_NEWPRIM(rmesa);
    186       R200_STATECHANGE( rmesa, vtx );
    187       rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = fmt_0;
    188       rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = fmt_1;
    189 
    190       rmesa->radeon.swtcl.vertex_size =
    191 	  _tnl_install_attrs( ctx,
    192 			      rmesa->radeon.swtcl.vertex_attrs,
    193 			      rmesa->radeon.swtcl.vertex_attr_count,
    194 			      NULL, 0 );
    195       rmesa->radeon.swtcl.vertex_size /= 4;
    196       rmesa->radeon.tnl_index_bitset = index_bitset;
    197    }
    198 }
    199 
    200 static void r200_predict_emit_size( r200ContextPtr rmesa )
    201 {
    202    if (RADEON_DEBUG & RADEON_VERTS)
    203       fprintf(stderr, "%s\n", __func__);
    204    const int vertex_array_size = 7;
    205    const int prim_size = 3;
    206    if (!rmesa->radeon.swtcl.emit_prediction) {
    207       const int state_size = radeonCountStateEmitSize(&rmesa->radeon);
    208       if (rcommonEnsureCmdBufSpace(&rmesa->radeon,
    209 	       state_size +
    210 	       vertex_array_size + prim_size,
    211 	       __func__))
    212 	 rmesa->radeon.swtcl.emit_prediction = radeonCountStateEmitSize(&rmesa->radeon);
    213       else
    214 	 rmesa->radeon.swtcl.emit_prediction = state_size;
    215       rmesa->radeon.swtcl.emit_prediction += vertex_array_size + prim_size
    216 	 + rmesa->radeon.cmdbuf.cs->cdw;
    217    }
    218 }
    219 
    220 
    221 static void r200RenderStart( struct gl_context *ctx )
    222 {
    223    r200SetVertexFormat( ctx );
    224    if (RADEON_DEBUG & RADEON_VERTS)
    225       fprintf(stderr, "%s\n", __func__);
    226 }
    227 
    228 
    229 /**
    230  * Set vertex state for SW TCL.  The primary purpose of this function is to
    231  * determine in advance whether or not the hardware can / should do the
    232  * projection divide or Mesa should do it.
    233  */
    234 void r200ChooseVertexState( struct gl_context *ctx )
    235 {
    236    r200ContextPtr rmesa = R200_CONTEXT( ctx );
    237    TNLcontext *tnl = TNL_CONTEXT(ctx);
    238    GLuint vte;
    239    GLuint vap;
    240    GLboolean unfilled = (ctx->Polygon.FrontMode != GL_FILL ||
    241                          ctx->Polygon.BackMode != GL_FILL);
    242    GLboolean twosided = ctx->Light.Enabled && ctx->Light.Model.TwoSide;
    243 
    244    /* We must ensure that we don't do _tnl_need_projected_coords while in a
    245     * rasterization fallback.  As this function will be called again when we
    246     * leave a rasterization fallback, we can just skip it for now.
    247     */
    248    if (rmesa->radeon.Fallback != 0)
    249       return;
    250 
    251    vte = rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL];
    252    vap = rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL];
    253 
    254    /* HW perspective divide is a win, but tiny vertex formats are a
    255     * bigger one.
    256     */
    257    if ((0 == (tnl->render_inputs_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX)))
    258        || twosided
    259        || unfilled) {
    260       rmesa->swtcl.needproj = GL_TRUE;
    261       vte |= R200_VTX_XY_FMT | R200_VTX_Z_FMT;
    262       vte &= ~R200_VTX_W0_FMT;
    263       if (tnl->render_inputs_bitset & BITFIELD64_RANGE(_TNL_ATTRIB_TEX0, _TNL_NUM_TEX)) {
    264 	 vap &= ~R200_VAP_FORCE_W_TO_ONE;
    265       }
    266       else {
    267 	 vap |= R200_VAP_FORCE_W_TO_ONE;
    268       }
    269    }
    270    else {
    271       rmesa->swtcl.needproj = GL_FALSE;
    272       vte &= ~(R200_VTX_XY_FMT | R200_VTX_Z_FMT);
    273       vte |= R200_VTX_W0_FMT;
    274       vap &= ~R200_VAP_FORCE_W_TO_ONE;
    275    }
    276 
    277    _tnl_need_projected_coords( ctx, rmesa->swtcl.needproj );
    278 
    279    if (vte != rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL]) {
    280       R200_STATECHANGE( rmesa, vte );
    281       rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] = vte;
    282    }
    283 
    284    if (vap != rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL]) {
    285       R200_STATECHANGE( rmesa, vap );
    286       rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] = vap;
    287    }
    288 }
    289 
    290 void r200_swtcl_flush(struct gl_context *ctx, uint32_t current_offset)
    291 {
    292    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    293    if (RADEON_DEBUG & RADEON_VERTS)
    294       fprintf(stderr, "%s\n", __func__);
    295 
    296 
    297    radeonEmitState(&rmesa->radeon);
    298    r200EmitVertexAOS( rmesa,
    299 		      rmesa->radeon.swtcl.vertex_size,
    300 		      rmesa->radeon.swtcl.bo,
    301 		      current_offset);
    302 
    303 
    304    r200EmitVbufPrim( rmesa,
    305 		     rmesa->radeon.swtcl.hw_primitive,
    306 		     rmesa->radeon.swtcl.numverts);
    307    if ( rmesa->radeon.swtcl.emit_prediction < rmesa->radeon.cmdbuf.cs->cdw )
    308       WARN_ONCE("Rendering was %d commands larger than predicted size."
    309 	    " We might overflow  command buffer.\n",
    310 	    rmesa->radeon.cmdbuf.cs->cdw - rmesa->radeon.swtcl.emit_prediction );
    311 
    312    rmesa->radeon.swtcl.emit_prediction = 0;
    313 
    314 }
    315 
    316 /**************************************************************************/
    317 
    318 
    319 static inline GLuint reduced_hw_prim( struct gl_context *ctx, GLuint prim)
    320 {
    321    switch (prim) {
    322    case GL_POINTS:
    323       return ((!ctx->Point.SmoothFlag) ?
    324 	 R200_VF_PRIM_POINT_SPRITES : R200_VF_PRIM_POINTS);
    325    case GL_LINES:
    326    /* fallthrough */
    327    case GL_LINE_LOOP:
    328    /* fallthrough */
    329    case GL_LINE_STRIP:
    330       return R200_VF_PRIM_LINES;
    331    default:
    332    /* all others reduced to triangles */
    333       return R200_VF_PRIM_TRIANGLES;
    334    }
    335 }
    336 
    337 
    338 static void r200RasterPrimitive( struct gl_context *ctx, GLuint hwprim );
    339 static void r200RenderPrimitive( struct gl_context *ctx, GLenum prim );
    340 static void r200ResetLineStipple( struct gl_context *ctx );
    341 
    342 /***********************************************************************
    343  *                    Emit primitives as inline vertices               *
    344  ***********************************************************************/
    345 
    346 #define HAVE_POINTS      1
    347 #define HAVE_LINES       1
    348 #define HAVE_LINE_STRIPS 1
    349 #define HAVE_TRIANGLES   1
    350 #define HAVE_TRI_STRIPS  1
    351 #define HAVE_TRI_FANS    1
    352 #define HAVE_QUADS       0
    353 #define HAVE_QUAD_STRIPS 0
    354 #define HAVE_POLYGONS    1
    355 #define HAVE_ELTS        0
    356 
    357 static void* r200_alloc_verts( r200ContextPtr rmesa, GLuint n, GLuint size)
    358 {
    359    void *rv;
    360    do {
    361       r200_predict_emit_size( rmesa );
    362       rv = rcommonAllocDmaLowVerts( &rmesa->radeon, n, size * 4 );
    363    } while(!rv);
    364    return rv;
    365 }
    366 
    367 #undef LOCAL_VARS
    368 #undef ALLOC_VERTS
    369 #define CTX_ARG r200ContextPtr rmesa
    370 #define GET_VERTEX_DWORDS() rmesa->radeon.swtcl.vertex_size
    371 #define ALLOC_VERTS( n, size ) r200_alloc_verts(rmesa, n, size)
    372 #define LOCAL_VARS						\
    373    r200ContextPtr rmesa = R200_CONTEXT(ctx);		\
    374    const char *r200verts = (char *)rmesa->radeon.swtcl.verts;
    375 #define VERT(x) (radeonVertex *)(r200verts + ((x) * vertsize * sizeof(int)))
    376 #define VERTEX radeonVertex
    377 #define DO_DEBUG_VERTS (1 && (R200_DEBUG & RADEON_VERTS))
    378 
    379 #undef TAG
    380 #define TAG(x) r200_##x
    381 #include "tnl_dd/t_dd_triemit.h"
    382 
    383 
    384 /***********************************************************************
    385  *          Macros for t_dd_tritmp.h to draw basic primitives          *
    386  ***********************************************************************/
    387 
    388 #define QUAD( a, b, c, d ) r200_quad( rmesa, a, b, c, d )
    389 #define TRI( a, b, c )     r200_triangle( rmesa, a, b, c )
    390 #define LINE( a, b )       r200_line( rmesa, a, b )
    391 #define POINT( a )         r200_point( rmesa, a )
    392 
    393 /***********************************************************************
    394  *              Build render functions from dd templates               *
    395  ***********************************************************************/
    396 
    397 #define R200_TWOSIDE_BIT	0x01
    398 #define R200_UNFILLED_BIT	0x02
    399 #define R200_MAX_TRIFUNC	0x04
    400 
    401 
    402 static struct {
    403    tnl_points_func	        points;
    404    tnl_line_func		line;
    405    tnl_triangle_func	triangle;
    406    tnl_quad_func		quad;
    407 } rast_tab[R200_MAX_TRIFUNC];
    408 
    409 
    410 #define DO_FALLBACK  0
    411 #define DO_UNFILLED ((IND & R200_UNFILLED_BIT) != 0)
    412 #define DO_TWOSIDE  ((IND & R200_TWOSIDE_BIT) != 0)
    413 #define DO_FLAT      0
    414 #define DO_OFFSET     0
    415 #define DO_TRI       1
    416 #define DO_QUAD      1
    417 #define DO_LINE      1
    418 #define DO_POINTS    1
    419 #define DO_FULL_QUAD 1
    420 
    421 #define HAVE_SPEC   1
    422 #define HAVE_BACK_COLORS  0
    423 #define HAVE_HW_FLATSHADE 1
    424 #define TAB rast_tab
    425 
    426 #define DEPTH_SCALE 1.0
    427 #define UNFILLED_TRI unfilled_tri
    428 #define UNFILLED_QUAD unfilled_quad
    429 #define VERT_X(_v) _v->v.x
    430 #define VERT_Y(_v) _v->v.y
    431 #define VERT_Z(_v) _v->v.z
    432 #define AREA_IS_CCW( a ) (a < 0)
    433 #define GET_VERTEX(e) (rmesa->radeon.swtcl.verts + (e*rmesa->radeon.swtcl.vertex_size*sizeof(int)))
    434 
    435 #define VERT_SET_RGBA( v, c )  					\
    436 do {								\
    437    radeon_color_t *color = (radeon_color_t *)&((v)->ui[coloroffset]);	\
    438    UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]);		\
    439    UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]);		\
    440    UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]);		\
    441    UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]);		\
    442 } while (0)
    443 
    444 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
    445 
    446 #define VERT_SET_SPEC( v, c )					\
    447 do {								\
    448    if (specoffset) {						\
    449       radeon_color_t *spec = (radeon_color_t *)&((v)->ui[specoffset]);	\
    450       UNCLAMPED_FLOAT_TO_UBYTE(spec->red, (c)[0]);	\
    451       UNCLAMPED_FLOAT_TO_UBYTE(spec->green, (c)[1]);	\
    452       UNCLAMPED_FLOAT_TO_UBYTE(spec->blue, (c)[2]);	\
    453    }								\
    454 } while (0)
    455 #define VERT_COPY_SPEC( v0, v1 )			\
    456 do {							\
    457    if (specoffset) {					\
    458       radeon_color_t *spec0 = (radeon_color_t *)&((v0)->ui[specoffset]);	\
    459       radeon_color_t *spec1 = (radeon_color_t *)&((v1)->ui[specoffset]);	\
    460       spec0->red   = spec1->red;	\
    461       spec0->green = spec1->green;	\
    462       spec0->blue  = spec1->blue; 	\
    463    }							\
    464 } while (0)
    465 
    466 /* These don't need LE32_TO_CPU() as they used to save and restore
    467  * colors which are already in the correct format.
    468  */
    469 #define VERT_SAVE_RGBA( idx )    color[idx] = v[idx]->ui[coloroffset]
    470 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
    471 #define VERT_SAVE_SPEC( idx )    if (specoffset) spec[idx] = v[idx]->ui[specoffset]
    472 #define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
    473 
    474 #undef LOCAL_VARS
    475 #undef TAG
    476 #undef INIT
    477 
    478 #define LOCAL_VARS(n)							\
    479    r200ContextPtr rmesa = R200_CONTEXT(ctx);			\
    480    GLuint color[n] = {0}, spec[n] = {0};						\
    481    GLuint coloroffset = rmesa->swtcl.coloroffset;	\
    482    GLuint specoffset = rmesa->swtcl.specoffset;			\
    483    (void) color; (void) spec; (void) coloroffset; (void) specoffset;
    484 
    485 /***********************************************************************
    486  *                Helpers for rendering unfilled primitives            *
    487  ***********************************************************************/
    488 
    489 #define RASTERIZE(x) r200RasterPrimitive( ctx, reduced_hw_prim(ctx, x) )
    490 #define RENDER_PRIMITIVE rmesa->radeon.swtcl.render_primitive
    491 #undef TAG
    492 #define TAG(x) x
    493 #include "tnl_dd/t_dd_unfilled.h"
    494 #undef IND
    495 
    496 
    497 /***********************************************************************
    498  *                      Generate GL render functions                   *
    499  ***********************************************************************/
    500 
    501 
    502 #define IND (0)
    503 #define TAG(x) x
    504 #include "tnl_dd/t_dd_tritmp.h"
    505 
    506 #define IND (R200_TWOSIDE_BIT)
    507 #define TAG(x) x##_twoside
    508 #include "tnl_dd/t_dd_tritmp.h"
    509 
    510 #define IND (R200_UNFILLED_BIT)
    511 #define TAG(x) x##_unfilled
    512 #include "tnl_dd/t_dd_tritmp.h"
    513 
    514 #define IND (R200_TWOSIDE_BIT|R200_UNFILLED_BIT)
    515 #define TAG(x) x##_twoside_unfilled
    516 #include "tnl_dd/t_dd_tritmp.h"
    517 
    518 
    519 static void init_rast_tab( void )
    520 {
    521    init();
    522    init_twoside();
    523    init_unfilled();
    524    init_twoside_unfilled();
    525 }
    526 
    527 /**********************************************************************/
    528 /*               Render unclipped begin/end objects                   */
    529 /**********************************************************************/
    530 
    531 #define RENDER_POINTS( start, count )		\
    532    for ( ; start < count ; start++)		\
    533       r200_point( rmesa, VERT(start) )
    534 #define RENDER_LINE( v0, v1 ) \
    535    r200_line( rmesa, VERT(v0), VERT(v1) )
    536 #define RENDER_TRI( v0, v1, v2 )  \
    537    r200_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
    538 #define RENDER_QUAD( v0, v1, v2, v3 ) \
    539    r200_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
    540 #define INIT(x) do {					\
    541    r200RenderPrimitive( ctx, x );			\
    542 } while (0)
    543 #undef LOCAL_VARS
    544 #define LOCAL_VARS						\
    545    r200ContextPtr rmesa = R200_CONTEXT(ctx);		\
    546    const GLuint vertsize = rmesa->radeon.swtcl.vertex_size;		\
    547    const char *r200verts = (char *)rmesa->radeon.swtcl.verts;		\
    548    const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts;	\
    549    const GLboolean stipple = ctx->Line.StippleFlag;		\
    550    (void) elt; (void) stipple;
    551 #define RESET_STIPPLE	if ( stipple ) r200ResetLineStipple( ctx );
    552 #define RESET_OCCLUSION
    553 #define PRESERVE_VB_DEFS
    554 #define ELT(x) (x)
    555 #define TAG(x) r200_##x##_verts
    556 #include "tnl/t_vb_rendertmp.h"
    557 #undef ELT
    558 #undef TAG
    559 #define TAG(x) r200_##x##_elts
    560 #define ELT(x) elt[x]
    561 #include "tnl/t_vb_rendertmp.h"
    562 
    563 
    564 
    565 /**********************************************************************/
    566 /*                    Choose render functions                         */
    567 /**********************************************************************/
    568 
    569 void r200ChooseRenderState( struct gl_context *ctx )
    570 {
    571    TNLcontext *tnl = TNL_CONTEXT(ctx);
    572    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    573    GLuint index = 0;
    574    GLboolean unfilled = (ctx->Polygon.FrontMode != GL_FILL ||
    575                          ctx->Polygon.BackMode != GL_FILL);
    576    GLboolean twosided = ctx->Light.Enabled && ctx->Light.Model.TwoSide;
    577 
    578    if (!rmesa->radeon.TclFallback || rmesa->radeon.Fallback)
    579       return;
    580 
    581    if (twosided)
    582       index |= R200_TWOSIDE_BIT;
    583    if (unfilled)
    584       index |= R200_UNFILLED_BIT;
    585 
    586    if (index != rmesa->radeon.swtcl.RenderIndex) {
    587       tnl->Driver.Render.Points = rast_tab[index].points;
    588       tnl->Driver.Render.Line = rast_tab[index].line;
    589       tnl->Driver.Render.ClippedLine = rast_tab[index].line;
    590       tnl->Driver.Render.Triangle = rast_tab[index].triangle;
    591       tnl->Driver.Render.Quad = rast_tab[index].quad;
    592 
    593       if (index == 0) {
    594 	 tnl->Driver.Render.PrimTabVerts = r200_render_tab_verts;
    595 	 tnl->Driver.Render.PrimTabElts = r200_render_tab_elts;
    596 	 tnl->Driver.Render.ClippedPolygon = r200_fast_clipped_poly;
    597       } else {
    598 	 tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
    599 	 tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
    600 	 tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
    601       }
    602 
    603       rmesa->radeon.swtcl.RenderIndex = index;
    604    }
    605 }
    606 
    607 
    608 /**********************************************************************/
    609 /*                 High level hooks for t_vb_render.c                 */
    610 /**********************************************************************/
    611 
    612 
    613 static void r200RasterPrimitive( struct gl_context *ctx, GLuint hwprim )
    614 {
    615    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    616 
    617    radeon_prepare_render(&rmesa->radeon);
    618    if (rmesa->radeon.NewGLState)
    619       r200ValidateState( ctx );
    620 
    621 
    622    if (rmesa->radeon.swtcl.hw_primitive != hwprim) {
    623       /* need to disable perspective-correct texturing for point sprites */
    624       if ((hwprim & 0xf) == R200_VF_PRIM_POINT_SPRITES && ctx->Point.PointSprite) {
    625 	 if (rmesa->hw.set.cmd[SET_RE_CNTL] & R200_PERSPECTIVE_ENABLE) {
    626 	    R200_STATECHANGE( rmesa, set );
    627 	    rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_PERSPECTIVE_ENABLE;
    628 	 }
    629       }
    630       else if (!(rmesa->hw.set.cmd[SET_RE_CNTL] & R200_PERSPECTIVE_ENABLE)) {
    631 	 R200_STATECHANGE( rmesa, set );
    632 	 rmesa->hw.set.cmd[SET_RE_CNTL] |= R200_PERSPECTIVE_ENABLE;
    633       }
    634       R200_NEWPRIM( rmesa );
    635       rmesa->radeon.swtcl.hw_primitive = hwprim;
    636    }
    637 }
    638 
    639 static void r200RenderPrimitive( struct gl_context *ctx, GLenum prim )
    640 {
    641    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    642    GLboolean unfilled = (ctx->Polygon.FrontMode != GL_FILL ||
    643                          ctx->Polygon.BackMode != GL_FILL);
    644 
    645    rmesa->radeon.swtcl.render_primitive = prim;
    646    if (prim < GL_TRIANGLES || !unfilled)
    647       r200RasterPrimitive( ctx, reduced_hw_prim(ctx, prim) );
    648 }
    649 
    650 static void r200RenderFinish( struct gl_context *ctx )
    651 {
    652 }
    653 
    654 static void r200ResetLineStipple( struct gl_context *ctx )
    655 {
    656    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    657    R200_STATECHANGE( rmesa, lin );
    658 }
    659 
    660 
    661 /**********************************************************************/
    662 /*           Transition to/from hardware rasterization.               */
    663 /**********************************************************************/
    664 
    665 static const char * const fallbackStrings[] = {
    666    "Texture mode",
    667    "glDrawBuffer(GL_FRONT_AND_BACK)",
    668    "glEnable(GL_STENCIL) without hw stencil buffer",
    669    "glRenderMode(selection or feedback)",
    670    "R200_NO_RAST",
    671    "Mixing GL_CLAMP_TO_BORDER and GL_CLAMP (or GL_MIRROR_CLAMP_ATI)"
    672 };
    673 
    674 
    675 static const char *getFallbackString(GLuint bit)
    676 {
    677    int i = 0;
    678    while (bit > 1) {
    679       i++;
    680       bit >>= 1;
    681    }
    682    return fallbackStrings[i];
    683 }
    684 
    685 
    686 void r200Fallback( struct gl_context *ctx, GLuint bit, GLboolean mode )
    687 {
    688    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    689    TNLcontext *tnl = TNL_CONTEXT(ctx);
    690    GLuint oldfallback = rmesa->radeon.Fallback;
    691 
    692    if (mode) {
    693       rmesa->radeon.Fallback |= bit;
    694       if (oldfallback == 0) {
    695 	 radeon_firevertices(&rmesa->radeon);
    696 	 TCL_FALLBACK( ctx, R200_TCL_FALLBACK_RASTER, GL_TRUE );
    697 	 _swsetup_Wakeup( ctx );
    698 	 rmesa->radeon.swtcl.RenderIndex = ~0;
    699          if (R200_DEBUG & RADEON_FALLBACKS) {
    700             fprintf(stderr, "R200 begin rasterization fallback: 0x%x %s\n",
    701                     bit, getFallbackString(bit));
    702          }
    703       }
    704    }
    705    else {
    706       rmesa->radeon.Fallback &= ~bit;
    707       if (oldfallback == bit) {
    708 
    709 	 _swrast_flush( ctx );
    710 	 tnl->Driver.Render.Start = r200RenderStart;
    711 	 tnl->Driver.Render.PrimitiveNotify = r200RenderPrimitive;
    712 	 tnl->Driver.Render.Finish = r200RenderFinish;
    713 
    714 	 tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
    715 	 tnl->Driver.Render.CopyPV = _tnl_copy_pv;
    716 	 tnl->Driver.Render.Interp = _tnl_interp;
    717 
    718 	 tnl->Driver.Render.ResetLineStipple = r200ResetLineStipple;
    719 	 TCL_FALLBACK( ctx, R200_TCL_FALLBACK_RASTER, GL_FALSE );
    720 	 if (rmesa->radeon.TclFallback) {
    721 	    /* These are already done if rmesa->radeon.TclFallback goes to
    722 	     * zero above. But not if it doesn't (R200_NO_TCL for
    723 	     * example?)
    724 	     */
    725 	    _tnl_invalidate_vertex_state( ctx, ~0 );
    726 	    _tnl_invalidate_vertices( ctx, ~0 );
    727 	    rmesa->radeon.tnl_index_bitset = 0;
    728 	    r200ChooseVertexState( ctx );
    729 	    r200ChooseRenderState( ctx );
    730 	 }
    731          if (R200_DEBUG & RADEON_FALLBACKS) {
    732             fprintf(stderr, "R200 end rasterization fallback: 0x%x %s\n",
    733                     bit, getFallbackString(bit));
    734          }
    735       }
    736    }
    737 }
    738 
    739 
    740 
    741 
    742 /**
    743  * Cope with depth operations by drawing individual pixels as points.
    744  *
    745  * \todo
    746  * The way the vertex state is set in this routine is hokey.  It seems to
    747  * work, but it's very hackish.  This whole routine is pretty hackish.  If
    748  * the bitmap is small enough, it seems like it would be faster to copy it
    749  * to AGP memory and use it as a non-power-of-two texture (i.e.,
    750  * NV_texture_rectangle).
    751  */
    752 void
    753 r200PointsBitmap( struct gl_context *ctx, GLint px, GLint py,
    754 		  GLsizei width, GLsizei height,
    755 		  const struct gl_pixelstore_attrib *unpack,
    756 		  const GLubyte *bitmap )
    757 {
    758    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    759    const GLfloat *rc = ctx->Current.RasterColor;
    760    GLint row, col;
    761    radeonVertex vert;
    762    GLuint orig_vte;
    763    GLuint h;
    764 
    765 
    766    /* Turn off tcl.
    767     */
    768    TCL_FALLBACK( ctx, R200_TCL_FALLBACK_BITMAP, 1 );
    769 
    770    /* Choose tiny vertex format
    771     */
    772    {
    773       const GLuint fmt_0 = R200_VTX_XY | R200_VTX_Z0 | R200_VTX_W0
    774 	  | (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT);
    775       const GLuint fmt_1 = 0;
    776       GLuint vte = rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL];
    777       GLuint vap = rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL];
    778 
    779       vte &= ~(R200_VTX_XY_FMT | R200_VTX_Z_FMT);
    780       vte |= R200_VTX_W0_FMT;
    781       vap &= ~R200_VAP_FORCE_W_TO_ONE;
    782 
    783       rmesa->radeon.swtcl.vertex_size = 5;
    784 
    785       if ( (rmesa->hw.vtx.cmd[VTX_VTXFMT_0] != fmt_0)
    786 	   || (rmesa->hw.vtx.cmd[VTX_VTXFMT_1] != fmt_1) ) {
    787 	 R200_NEWPRIM(rmesa);
    788 	 R200_STATECHANGE( rmesa, vtx );
    789 	 rmesa->hw.vtx.cmd[VTX_VTXFMT_0] = fmt_0;
    790 	 rmesa->hw.vtx.cmd[VTX_VTXFMT_1] = fmt_1;
    791       }
    792 
    793       if (vte != rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL]) {
    794 	 R200_STATECHANGE( rmesa, vte );
    795 	 rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] = vte;
    796       }
    797 
    798       if (vap != rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL]) {
    799 	 R200_STATECHANGE( rmesa, vap );
    800 	 rmesa->hw.vap.cmd[VAP_SE_VAP_CNTL] = vap;
    801       }
    802    }
    803 
    804    /* Ready for point primitives:
    805     */
    806    r200RenderPrimitive( ctx, GL_POINTS );
    807 
    808    /* Turn off the hw viewport transformation:
    809     */
    810    R200_STATECHANGE( rmesa, vte );
    811    orig_vte = rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL];
    812    rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~(R200_VPORT_X_SCALE_ENA |
    813 					   R200_VPORT_Y_SCALE_ENA |
    814 					   R200_VPORT_Z_SCALE_ENA |
    815 					   R200_VPORT_X_OFFSET_ENA |
    816 					   R200_VPORT_Y_OFFSET_ENA |
    817 					   R200_VPORT_Z_OFFSET_ENA);
    818 
    819    /* Turn off other stuff:  Stipple?, texture?, blending?, etc.
    820     */
    821 
    822 
    823    /* Populate the vertex
    824     *
    825     * Incorporate FOG into RGBA
    826     */
    827    if (ctx->Fog.Enabled) {
    828       const GLfloat *fc = ctx->Fog.Color;
    829       GLfloat color[4];
    830       GLfloat f;
    831 
    832       if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
    833          f = _swrast_z_to_fogfactor(ctx, ctx->Current.Attrib[VERT_ATTRIB_FOG][0]);
    834       else
    835          f = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
    836 
    837       color[0] = f * rc[0] + (1.F - f) * fc[0];
    838       color[1] = f * rc[1] + (1.F - f) * fc[1];
    839       color[2] = f * rc[2] + (1.F - f) * fc[2];
    840       color[3] = rc[3];
    841 
    842       UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.red,   color[0]);
    843       UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.green, color[1]);
    844       UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.blue,  color[2]);
    845       UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.alpha, color[3]);
    846    }
    847    else {
    848       UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.red,   rc[0]);
    849       UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.green, rc[1]);
    850       UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.blue,  rc[2]);
    851       UNCLAMPED_FLOAT_TO_CHAN(vert.tv.color.alpha, rc[3]);
    852    }
    853 
    854 
    855    vert.tv.z = ctx->Current.RasterPos[2];
    856 
    857 
    858    /* Update window height
    859     */
    860    h = radeon_get_drawable(&rmesa->radeon)->h;
    861 
    862    /* Clipping handled by existing mechansims in r200_ioctl.c?
    863     */
    864    for (row=0; row<height; row++) {
    865       const GLubyte *src = (const GLubyte *)
    866 	 _mesa_image_address2d(unpack, bitmap, width, height,
    867                                GL_COLOR_INDEX, GL_BITMAP, row, 0 );
    868 
    869       if (unpack->LsbFirst) {
    870          /* Lsb first */
    871          GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
    872          for (col=0; col<width; col++) {
    873             if (*src & mask) {
    874 	       vert.tv.x = px+col;
    875 	       vert.tv.y = h - (py+row) - 1;
    876 	       r200_point( rmesa, &vert );
    877             }
    878 	    src += (mask >> 7);
    879 	    mask = ((mask << 1) & 0xff) | (mask >> 7);
    880          }
    881 
    882          /* get ready for next row */
    883          if (mask != 1)
    884             src++;
    885       }
    886       else {
    887          /* Msb first */
    888          GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
    889          for (col=0; col<width; col++) {
    890             if (*src & mask) {
    891 	       vert.tv.x = px+col;
    892 	       vert.tv.y = h - (py+row) - 1;
    893 	       r200_point( rmesa, &vert );
    894             }
    895 	    src += mask & 1;
    896 	    mask = ((mask << 7) & 0xff) | (mask >> 1);
    897          }
    898          /* get ready for next row */
    899          if (mask != 128)
    900             src++;
    901       }
    902    }
    903 
    904    /* Fire outstanding vertices, restore state
    905     */
    906    R200_STATECHANGE( rmesa, vte );
    907    rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] = orig_vte;
    908 
    909    /* Unfallback
    910     */
    911    TCL_FALLBACK( ctx, R200_TCL_FALLBACK_BITMAP, 0 );
    912 
    913    /* Need to restore vertexformat?
    914     */
    915    if (rmesa->radeon.TclFallback)
    916       r200ChooseVertexState( ctx );
    917 }
    918 
    919 
    920 
    921 /**********************************************************************/
    922 /*                            Initialization.                         */
    923 /**********************************************************************/
    924 
    925 void r200InitSwtcl( struct gl_context *ctx )
    926 {
    927    TNLcontext *tnl = TNL_CONTEXT(ctx);
    928    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    929    static int firsttime = 1;
    930 
    931    if (firsttime) {
    932       init_rast_tab();
    933       firsttime = 0;
    934    }
    935    rmesa->radeon.swtcl.emit_prediction = 0;
    936 
    937    tnl->Driver.Render.Start = r200RenderStart;
    938    tnl->Driver.Render.Finish = r200RenderFinish;
    939    tnl->Driver.Render.PrimitiveNotify = r200RenderPrimitive;
    940    tnl->Driver.Render.ResetLineStipple = r200ResetLineStipple;
    941    tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
    942    tnl->Driver.Render.CopyPV = _tnl_copy_pv;
    943    tnl->Driver.Render.Interp = _tnl_interp;
    944 
    945    /* FIXME: what are these numbers? */
    946    _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
    947 		       36 * sizeof(GLfloat) );
    948 
    949    rmesa->radeon.swtcl.verts = (GLubyte *)tnl->clipspace.vertex_buf;
    950    rmesa->radeon.swtcl.RenderIndex = ~0;
    951    rmesa->radeon.swtcl.render_primitive = GL_TRIANGLES;
    952    rmesa->radeon.swtcl.hw_primitive = 0;
    953 }
    954 
    955