Home | History | Annotate | Download | only in radeon
      1 /**************************************************************************
      2 
      3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
      4                      VA Linux Systems Inc., Fremont, California.
      5 
      6 All Rights Reserved.
      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  *   Kevin E. Martin <martin (at) valinux.com>
     33  *   Gareth Hughes <gareth (at) valinux.com>
     34  */
     35 
     36 #include "main/glheader.h"
     37 #include "main/imports.h"
     38 #include "main/colormac.h"
     39 #include "main/context.h"
     40 #include "main/macros.h"
     41 #include "main/teximage.h"
     42 #include "main/texstate.h"
     43 #include "main/texobj.h"
     44 #include "main/enums.h"
     45 #include "main/samplerobj.h"
     46 
     47 #include "radeon_context.h"
     48 #include "radeon_mipmap_tree.h"
     49 #include "radeon_state.h"
     50 #include "radeon_ioctl.h"
     51 #include "radeon_swtcl.h"
     52 #include "radeon_tex.h"
     53 #include "radeon_tcl.h"
     54 
     55 
     56 #define RADEON_TXFORMAT_A8        RADEON_TXFORMAT_I8
     57 #define RADEON_TXFORMAT_L8        RADEON_TXFORMAT_I8
     58 #define RADEON_TXFORMAT_AL88      RADEON_TXFORMAT_AI88
     59 #define RADEON_TXFORMAT_YCBCR     RADEON_TXFORMAT_YVYU422
     60 #define RADEON_TXFORMAT_YCBCR_REV RADEON_TXFORMAT_VYUY422
     61 #define RADEON_TXFORMAT_RGB_DXT1  RADEON_TXFORMAT_DXT1
     62 #define RADEON_TXFORMAT_RGBA_DXT1 RADEON_TXFORMAT_DXT1
     63 #define RADEON_TXFORMAT_RGBA_DXT3 RADEON_TXFORMAT_DXT23
     64 #define RADEON_TXFORMAT_RGBA_DXT5 RADEON_TXFORMAT_DXT45
     65 
     66 #define _COLOR(f) \
     67     [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, 0 }
     68 #define _COLOR_REV(f) \
     69     [ MESA_FORMAT_ ## f ## _REV ] = { RADEON_TXFORMAT_ ## f, 0 }
     70 #define _ALPHA(f) \
     71     [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 }
     72 #define _ALPHA_REV(f) \
     73     [ MESA_FORMAT_ ## f ## _REV ] = { RADEON_TXFORMAT_ ## f | RADEON_TXFORMAT_ALPHA_IN_MAP, 0 }
     74 #define _YUV(f) \
     75    [ MESA_FORMAT_ ## f ] = { RADEON_TXFORMAT_ ## f, RADEON_YUV_TO_RGB }
     76 #define _INVALID(f) \
     77     [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
     78 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \
     79 			     && (tx_table[f].format != 0xffffffff) )
     80 
     81 struct tx_table {
     82    GLuint format, filter;
     83 };
     84 
     85 /* XXX verify this table against MESA_FORMAT_x values */
     86 static const struct tx_table tx_table[] =
     87 {
     88    _INVALID(NONE), /* MESA_FORMAT_NONE */
     89    _ALPHA(RGBA8888),
     90    _ALPHA_REV(RGBA8888),
     91    _ALPHA(ARGB8888),
     92    _ALPHA_REV(ARGB8888),
     93    [ MESA_FORMAT_RGB888 ] = { RADEON_TXFORMAT_ARGB8888, 0 },
     94    _COLOR(RGB565),
     95    _COLOR_REV(RGB565),
     96    _ALPHA(ARGB4444),
     97    _ALPHA_REV(ARGB4444),
     98    _ALPHA(ARGB1555),
     99    _ALPHA_REV(ARGB1555),
    100    _ALPHA(AL88),
    101    _ALPHA_REV(AL88),
    102    _ALPHA(A8),
    103    _COLOR(L8),
    104    _ALPHA(I8),
    105    _YUV(YCBCR),
    106    _YUV(YCBCR_REV),
    107    _INVALID(RGB_FXT1),
    108    _INVALID(RGBA_FXT1),
    109    _COLOR(RGB_DXT1),
    110    _ALPHA(RGBA_DXT1),
    111    _ALPHA(RGBA_DXT3),
    112    _ALPHA(RGBA_DXT5),
    113 };
    114 
    115 #undef _COLOR
    116 #undef _ALPHA
    117 #undef _INVALID
    118 
    119 /* ================================================================
    120  * Texture combine functions
    121  */
    122 
    123 /* GL_ARB_texture_env_combine support
    124  */
    125 
    126 /* The color tables have combine functions for GL_SRC_COLOR,
    127  * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
    128  */
    129 static GLuint radeon_texture_color[][RADEON_MAX_TEXTURE_UNITS] =
    130 {
    131    {
    132       RADEON_COLOR_ARG_A_T0_COLOR,
    133       RADEON_COLOR_ARG_A_T1_COLOR,
    134       RADEON_COLOR_ARG_A_T2_COLOR
    135    },
    136    {
    137       RADEON_COLOR_ARG_A_T0_COLOR | RADEON_COMP_ARG_A,
    138       RADEON_COLOR_ARG_A_T1_COLOR | RADEON_COMP_ARG_A,
    139       RADEON_COLOR_ARG_A_T2_COLOR | RADEON_COMP_ARG_A
    140    },
    141    {
    142       RADEON_COLOR_ARG_A_T0_ALPHA,
    143       RADEON_COLOR_ARG_A_T1_ALPHA,
    144       RADEON_COLOR_ARG_A_T2_ALPHA
    145    },
    146    {
    147       RADEON_COLOR_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
    148       RADEON_COLOR_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
    149       RADEON_COLOR_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
    150    },
    151 };
    152 
    153 static GLuint radeon_tfactor_color[] =
    154 {
    155    RADEON_COLOR_ARG_A_TFACTOR_COLOR,
    156    RADEON_COLOR_ARG_A_TFACTOR_COLOR | RADEON_COMP_ARG_A,
    157    RADEON_COLOR_ARG_A_TFACTOR_ALPHA,
    158    RADEON_COLOR_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
    159 };
    160 
    161 static GLuint radeon_primary_color[] =
    162 {
    163    RADEON_COLOR_ARG_A_DIFFUSE_COLOR,
    164    RADEON_COLOR_ARG_A_DIFFUSE_COLOR | RADEON_COMP_ARG_A,
    165    RADEON_COLOR_ARG_A_DIFFUSE_ALPHA,
    166    RADEON_COLOR_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
    167 };
    168 
    169 static GLuint radeon_previous_color[] =
    170 {
    171    RADEON_COLOR_ARG_A_CURRENT_COLOR,
    172    RADEON_COLOR_ARG_A_CURRENT_COLOR | RADEON_COMP_ARG_A,
    173    RADEON_COLOR_ARG_A_CURRENT_ALPHA,
    174    RADEON_COLOR_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
    175 };
    176 
    177 /* GL_ZERO table - indices 0-3
    178  * GL_ONE  table - indices 1-4
    179  */
    180 static GLuint radeon_zero_color[] =
    181 {
    182    RADEON_COLOR_ARG_A_ZERO,
    183    RADEON_COLOR_ARG_A_ZERO | RADEON_COMP_ARG_A,
    184    RADEON_COLOR_ARG_A_ZERO,
    185    RADEON_COLOR_ARG_A_ZERO | RADEON_COMP_ARG_A,
    186    RADEON_COLOR_ARG_A_ZERO
    187 };
    188 
    189 
    190 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
    191  */
    192 static GLuint radeon_texture_alpha[][RADEON_MAX_TEXTURE_UNITS] =
    193 {
    194    {
    195       RADEON_ALPHA_ARG_A_T0_ALPHA,
    196       RADEON_ALPHA_ARG_A_T1_ALPHA,
    197       RADEON_ALPHA_ARG_A_T2_ALPHA
    198    },
    199    {
    200       RADEON_ALPHA_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
    201       RADEON_ALPHA_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
    202       RADEON_ALPHA_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
    203    },
    204 };
    205 
    206 static GLuint radeon_tfactor_alpha[] =
    207 {
    208    RADEON_ALPHA_ARG_A_TFACTOR_ALPHA,
    209    RADEON_ALPHA_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
    210 };
    211 
    212 static GLuint radeon_primary_alpha[] =
    213 {
    214    RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA,
    215    RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
    216 };
    217 
    218 static GLuint radeon_previous_alpha[] =
    219 {
    220    RADEON_ALPHA_ARG_A_CURRENT_ALPHA,
    221    RADEON_ALPHA_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
    222 };
    223 
    224 /* GL_ZERO table - indices 0-1
    225  * GL_ONE  table - indices 1-2
    226  */
    227 static GLuint radeon_zero_alpha[] =
    228 {
    229    RADEON_ALPHA_ARG_A_ZERO,
    230    RADEON_ALPHA_ARG_A_ZERO | RADEON_COMP_ARG_A,
    231    RADEON_ALPHA_ARG_A_ZERO
    232 };
    233 
    234 
    235 /* Extract the arg from slot A, shift it into the correct argument slot
    236  * and set the corresponding complement bit.
    237  */
    238 #define RADEON_COLOR_ARG( n, arg )			\
    239 do {							\
    240    color_combine |=					\
    241       ((color_arg[n] & RADEON_COLOR_ARG_MASK)		\
    242        << RADEON_COLOR_ARG_##arg##_SHIFT);		\
    243    color_combine |=					\
    244       ((color_arg[n] >> RADEON_COMP_ARG_SHIFT)		\
    245        << RADEON_COMP_ARG_##arg##_SHIFT);		\
    246 } while (0)
    247 
    248 #define RADEON_ALPHA_ARG( n, arg )			\
    249 do {							\
    250    alpha_combine |=					\
    251       ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK)		\
    252        << RADEON_ALPHA_ARG_##arg##_SHIFT);		\
    253    alpha_combine |=					\
    254       ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT)		\
    255        << RADEON_COMP_ARG_##arg##_SHIFT);		\
    256 } while (0)
    257 
    258 
    259 /* ================================================================
    260  * Texture unit state management
    261  */
    262 
    263 static GLboolean radeonUpdateTextureEnv( struct gl_context *ctx, int unit )
    264 {
    265    r100ContextPtr rmesa = R100_CONTEXT(ctx);
    266    const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
    267    GLuint color_combine, alpha_combine;
    268    const GLuint color_combine0 = RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO
    269          | RADEON_COLOR_ARG_C_CURRENT_COLOR | RADEON_BLEND_CTL_ADD
    270          | RADEON_SCALE_1X | RADEON_CLAMP_TX;
    271    const GLuint alpha_combine0 = RADEON_ALPHA_ARG_A_ZERO | RADEON_ALPHA_ARG_B_ZERO
    272          | RADEON_ALPHA_ARG_C_CURRENT_ALPHA | RADEON_BLEND_CTL_ADD
    273          | RADEON_SCALE_1X | RADEON_CLAMP_TX;
    274 
    275 
    276    /* texUnit->_Current can be NULL if and only if the texture unit is
    277     * not actually enabled.
    278     */
    279    assert( (texUnit->_ReallyEnabled == 0)
    280 	   || (texUnit->_Current != NULL) );
    281 
    282    if ( RADEON_DEBUG & RADEON_TEXTURE ) {
    283       fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, (void *)ctx, unit );
    284    }
    285 
    286    /* Set the texture environment state.  Isn't this nice and clean?
    287     * The chip will automagically set the texture alpha to 0xff when
    288     * the texture format does not include an alpha component. This
    289     * reduces the amount of special-casing we have to do, alpha-only
    290     * textures being a notable exception. Doesn't work for luminance
    291     * textures realized with I8 and ALPHA_IN_MAP not set neither (on r100).
    292     */
    293     /* Don't cache these results.
    294     */
    295    rmesa->state.texture.unit[unit].format = 0;
    296    rmesa->state.texture.unit[unit].envMode = 0;
    297 
    298    if ( !texUnit->_ReallyEnabled ) {
    299       color_combine = color_combine0;
    300       alpha_combine = alpha_combine0;
    301    }
    302    else {
    303       GLuint color_arg[3], alpha_arg[3];
    304       GLuint i;
    305       const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
    306       const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
    307       GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB;
    308       GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA;
    309 
    310 
    311       /* Step 1:
    312        * Extract the color and alpha combine function arguments.
    313        */
    314       for ( i = 0 ; i < numColorArgs ; i++ ) {
    315 	 const GLint op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR;
    316 	 const GLuint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i];
    317 	 assert(op >= 0);
    318 	 assert(op <= 3);
    319 	 switch ( srcRGBi ) {
    320 	 case GL_TEXTURE:
    321 	    if (texUnit->_Current->Image[0][0]->_BaseFormat == GL_ALPHA)
    322 	       color_arg[i] = radeon_zero_color[op];
    323 	    else
    324 	       color_arg[i] = radeon_texture_color[op][unit];
    325 	    break;
    326 	 case GL_CONSTANT:
    327 	    color_arg[i] = radeon_tfactor_color[op];
    328 	    break;
    329 	 case GL_PRIMARY_COLOR:
    330 	    color_arg[i] = radeon_primary_color[op];
    331 	    break;
    332 	 case GL_PREVIOUS:
    333 	    color_arg[i] = radeon_previous_color[op];
    334 	    break;
    335 	 case GL_ZERO:
    336 	    color_arg[i] = radeon_zero_color[op];
    337 	    break;
    338 	 case GL_ONE:
    339 	    color_arg[i] = radeon_zero_color[op+1];
    340 	    break;
    341 	 case GL_TEXTURE0:
    342 	 case GL_TEXTURE1:
    343 	 case GL_TEXTURE2: {
    344 	    GLuint txunit = srcRGBi - GL_TEXTURE0;
    345 	    if (ctx->Texture.Unit[txunit]._Current->Image[0][0]->_BaseFormat == GL_ALPHA)
    346 	       color_arg[i] = radeon_zero_color[op];
    347 	    else
    348 	 /* implement ogl 1.4/1.5 core spec here, not specification of
    349 	  * GL_ARB_texture_env_crossbar (which would require disabling blending
    350 	  * instead of undefined results when referencing not enabled texunit) */
    351 	      color_arg[i] = radeon_texture_color[op][txunit];
    352 	    }
    353 	    break;
    354 	 default:
    355 	    return GL_FALSE;
    356 	 }
    357       }
    358 
    359       for ( i = 0 ; i < numAlphaArgs ; i++ ) {
    360 	 const GLint op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA;
    361 	 const GLuint srcAi = texUnit->_CurrentCombine->SourceA[i];
    362 	 assert(op >= 0);
    363 	 assert(op <= 1);
    364 	 switch ( srcAi ) {
    365 	 case GL_TEXTURE:
    366 	    if (texUnit->_Current->Image[0][0]->_BaseFormat == GL_LUMINANCE)
    367 	       alpha_arg[i] = radeon_zero_alpha[op+1];
    368 	    else
    369 	       alpha_arg[i] = radeon_texture_alpha[op][unit];
    370 	    break;
    371 	 case GL_CONSTANT:
    372 	    alpha_arg[i] = radeon_tfactor_alpha[op];
    373 	    break;
    374 	 case GL_PRIMARY_COLOR:
    375 	    alpha_arg[i] = radeon_primary_alpha[op];
    376 	    break;
    377 	 case GL_PREVIOUS:
    378 	    alpha_arg[i] = radeon_previous_alpha[op];
    379 	    break;
    380 	 case GL_ZERO:
    381 	    alpha_arg[i] = radeon_zero_alpha[op];
    382 	    break;
    383 	 case GL_ONE:
    384 	    alpha_arg[i] = radeon_zero_alpha[op+1];
    385 	    break;
    386 	 case GL_TEXTURE0:
    387 	 case GL_TEXTURE1:
    388 	 case GL_TEXTURE2: {
    389 	    GLuint txunit = srcAi - GL_TEXTURE0;
    390 	    if (ctx->Texture.Unit[txunit]._Current->Image[0][0]->_BaseFormat == GL_LUMINANCE)
    391 	       alpha_arg[i] = radeon_zero_alpha[op+1];
    392 	    else
    393 	       alpha_arg[i] = radeon_texture_alpha[op][txunit];
    394 	    }
    395 	    break;
    396 	 default:
    397 	    return GL_FALSE;
    398 	 }
    399       }
    400 
    401       /* Step 2:
    402        * Build up the color and alpha combine functions.
    403        */
    404       switch ( texUnit->_CurrentCombine->ModeRGB ) {
    405       case GL_REPLACE:
    406 	 color_combine = (RADEON_COLOR_ARG_A_ZERO |
    407 			  RADEON_COLOR_ARG_B_ZERO |
    408 			  RADEON_BLEND_CTL_ADD |
    409 			  RADEON_CLAMP_TX);
    410 	 RADEON_COLOR_ARG( 0, C );
    411 	 break;
    412       case GL_MODULATE:
    413 	 color_combine = (RADEON_COLOR_ARG_C_ZERO |
    414 			  RADEON_BLEND_CTL_ADD |
    415 			  RADEON_CLAMP_TX);
    416 	 RADEON_COLOR_ARG( 0, A );
    417 	 RADEON_COLOR_ARG( 1, B );
    418 	 break;
    419       case GL_ADD:
    420 	 color_combine = (RADEON_COLOR_ARG_B_ZERO |
    421 			  RADEON_COMP_ARG_B |
    422 			  RADEON_BLEND_CTL_ADD |
    423 			  RADEON_CLAMP_TX);
    424 	 RADEON_COLOR_ARG( 0, A );
    425 	 RADEON_COLOR_ARG( 1, C );
    426 	 break;
    427       case GL_ADD_SIGNED:
    428 	 color_combine = (RADEON_COLOR_ARG_B_ZERO |
    429 			  RADEON_COMP_ARG_B |
    430 			  RADEON_BLEND_CTL_ADDSIGNED |
    431 			  RADEON_CLAMP_TX);
    432 	 RADEON_COLOR_ARG( 0, A );
    433 	 RADEON_COLOR_ARG( 1, C );
    434 	 break;
    435       case GL_SUBTRACT:
    436 	 color_combine = (RADEON_COLOR_ARG_B_ZERO |
    437 			  RADEON_COMP_ARG_B |
    438 			  RADEON_BLEND_CTL_SUBTRACT |
    439 			  RADEON_CLAMP_TX);
    440 	 RADEON_COLOR_ARG( 0, A );
    441 	 RADEON_COLOR_ARG( 1, C );
    442 	 break;
    443       case GL_INTERPOLATE:
    444 	 color_combine = (RADEON_BLEND_CTL_BLEND |
    445 			  RADEON_CLAMP_TX);
    446 	 RADEON_COLOR_ARG( 0, B );
    447 	 RADEON_COLOR_ARG( 1, A );
    448 	 RADEON_COLOR_ARG( 2, C );
    449 	 break;
    450 
    451       case GL_DOT3_RGB_EXT:
    452       case GL_DOT3_RGBA_EXT:
    453 	 /* The EXT version of the DOT3 extension does not support the
    454 	  * scale factor, but the ARB version (and the version in OpenGL
    455 	  * 1.3) does.
    456 	  */
    457 	 RGBshift = 0;
    458 	 /* FALLTHROUGH */
    459 
    460       case GL_DOT3_RGB:
    461       case GL_DOT3_RGBA:
    462 	 /* The R100 / RV200 only support a 1X multiplier in hardware
    463 	  * w/the ARB version.
    464 	  */
    465 	 if ( RGBshift != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) ) {
    466 	    return GL_FALSE;
    467 	 }
    468 
    469 	 RGBshift += 2;
    470 	 if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT)
    471 	    || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) {
    472             /* is it necessary to set this or will it be ignored anyway? */
    473 	    Ashift = RGBshift;
    474 	 }
    475 
    476 	 color_combine = (RADEON_COLOR_ARG_C_ZERO |
    477 			  RADEON_BLEND_CTL_DOT3 |
    478 			  RADEON_CLAMP_TX);
    479 	 RADEON_COLOR_ARG( 0, A );
    480 	 RADEON_COLOR_ARG( 1, B );
    481 	 break;
    482 
    483       case GL_MODULATE_ADD_ATI:
    484 	 color_combine = (RADEON_BLEND_CTL_ADD |
    485 			  RADEON_CLAMP_TX);
    486 	 RADEON_COLOR_ARG( 0, A );
    487 	 RADEON_COLOR_ARG( 1, C );
    488 	 RADEON_COLOR_ARG( 2, B );
    489 	 break;
    490       case GL_MODULATE_SIGNED_ADD_ATI:
    491 	 color_combine = (RADEON_BLEND_CTL_ADDSIGNED |
    492 			  RADEON_CLAMP_TX);
    493 	 RADEON_COLOR_ARG( 0, A );
    494 	 RADEON_COLOR_ARG( 1, C );
    495 	 RADEON_COLOR_ARG( 2, B );
    496 	 break;
    497       case GL_MODULATE_SUBTRACT_ATI:
    498 	 color_combine = (RADEON_BLEND_CTL_SUBTRACT |
    499 			  RADEON_CLAMP_TX);
    500 	 RADEON_COLOR_ARG( 0, A );
    501 	 RADEON_COLOR_ARG( 1, C );
    502 	 RADEON_COLOR_ARG( 2, B );
    503 	 break;
    504       default:
    505 	 return GL_FALSE;
    506       }
    507 
    508       switch ( texUnit->_CurrentCombine->ModeA ) {
    509       case GL_REPLACE:
    510 	 alpha_combine = (RADEON_ALPHA_ARG_A_ZERO |
    511 			  RADEON_ALPHA_ARG_B_ZERO |
    512 			  RADEON_BLEND_CTL_ADD |
    513 			  RADEON_CLAMP_TX);
    514 	 RADEON_ALPHA_ARG( 0, C );
    515 	 break;
    516       case GL_MODULATE:
    517 	 alpha_combine = (RADEON_ALPHA_ARG_C_ZERO |
    518 			  RADEON_BLEND_CTL_ADD |
    519 			  RADEON_CLAMP_TX);
    520 	 RADEON_ALPHA_ARG( 0, A );
    521 	 RADEON_ALPHA_ARG( 1, B );
    522 	 break;
    523       case GL_ADD:
    524 	 alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
    525 			  RADEON_COMP_ARG_B |
    526 			  RADEON_BLEND_CTL_ADD |
    527 			  RADEON_CLAMP_TX);
    528 	 RADEON_ALPHA_ARG( 0, A );
    529 	 RADEON_ALPHA_ARG( 1, C );
    530 	 break;
    531       case GL_ADD_SIGNED:
    532 	 alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
    533 			  RADEON_COMP_ARG_B |
    534 			  RADEON_BLEND_CTL_ADDSIGNED |
    535 			  RADEON_CLAMP_TX);
    536 	 RADEON_ALPHA_ARG( 0, A );
    537 	 RADEON_ALPHA_ARG( 1, C );
    538 	 break;
    539       case GL_SUBTRACT:
    540 	 alpha_combine = (RADEON_COLOR_ARG_B_ZERO |
    541 			  RADEON_COMP_ARG_B |
    542 			  RADEON_BLEND_CTL_SUBTRACT |
    543 			  RADEON_CLAMP_TX);
    544 	 RADEON_ALPHA_ARG( 0, A );
    545 	 RADEON_ALPHA_ARG( 1, C );
    546 	 break;
    547       case GL_INTERPOLATE:
    548 	 alpha_combine = (RADEON_BLEND_CTL_BLEND |
    549 			  RADEON_CLAMP_TX);
    550 	 RADEON_ALPHA_ARG( 0, B );
    551 	 RADEON_ALPHA_ARG( 1, A );
    552 	 RADEON_ALPHA_ARG( 2, C );
    553 	 break;
    554 
    555       case GL_MODULATE_ADD_ATI:
    556 	 alpha_combine = (RADEON_BLEND_CTL_ADD |
    557 			  RADEON_CLAMP_TX);
    558 	 RADEON_ALPHA_ARG( 0, A );
    559 	 RADEON_ALPHA_ARG( 1, C );
    560 	 RADEON_ALPHA_ARG( 2, B );
    561 	 break;
    562       case GL_MODULATE_SIGNED_ADD_ATI:
    563 	 alpha_combine = (RADEON_BLEND_CTL_ADDSIGNED |
    564 			  RADEON_CLAMP_TX);
    565 	 RADEON_ALPHA_ARG( 0, A );
    566 	 RADEON_ALPHA_ARG( 1, C );
    567 	 RADEON_ALPHA_ARG( 2, B );
    568 	 break;
    569       case GL_MODULATE_SUBTRACT_ATI:
    570 	 alpha_combine = (RADEON_BLEND_CTL_SUBTRACT |
    571 			  RADEON_CLAMP_TX);
    572 	 RADEON_ALPHA_ARG( 0, A );
    573 	 RADEON_ALPHA_ARG( 1, C );
    574 	 RADEON_ALPHA_ARG( 2, B );
    575 	 break;
    576       default:
    577 	 return GL_FALSE;
    578       }
    579 
    580       if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB_EXT)
    581 	   || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB) ) {
    582 	 alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE;
    583       }
    584 
    585       /* Step 3:
    586        * Apply the scale factor.
    587        */
    588       color_combine |= (RGBshift << RADEON_SCALE_SHIFT);
    589       alpha_combine |= (Ashift   << RADEON_SCALE_SHIFT);
    590 
    591       /* All done!
    592        */
    593    }
    594 
    595    if ( rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] != color_combine ||
    596 	rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] != alpha_combine ) {
    597       RADEON_STATECHANGE( rmesa, tex[unit] );
    598       rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] = color_combine;
    599       rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] = alpha_combine;
    600    }
    601 
    602    return GL_TRUE;
    603 }
    604 
    605 void radeonSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint texture_format,
    606 			 __DRIdrawable *dPriv)
    607 {
    608 	struct gl_texture_unit *texUnit;
    609 	struct gl_texture_object *texObj;
    610 	struct gl_texture_image *texImage;
    611 	struct radeon_renderbuffer *rb;
    612 	radeon_texture_image *rImage;
    613 	radeonContextPtr radeon;
    614 	struct radeon_framebuffer *rfb;
    615 	radeonTexObjPtr t;
    616 	uint32_t pitch_val;
    617 	gl_format texFormat;
    618 
    619 	radeon = pDRICtx->driverPrivate;
    620 
    621 	rfb = dPriv->driverPrivate;
    622         texUnit = _mesa_get_current_tex_unit(radeon->glCtx);
    623 	texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target);
    624         texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0);
    625 
    626 	rImage = get_radeon_texture_image(texImage);
    627 	t = radeon_tex_obj(texObj);
    628         if (t == NULL) {
    629     	    return;
    630     	}
    631 
    632 	radeon_update_renderbuffers(pDRICtx, dPriv, GL_TRUE);
    633 	rb = rfb->color_rb[0];
    634 	if (rb->bo == NULL) {
    635 		/* Failed to BO for the buffer */
    636 		return;
    637 	}
    638 
    639 	_mesa_lock_texture(radeon->glCtx, texObj);
    640 	if (t->bo) {
    641 		radeon_bo_unref(t->bo);
    642 		t->bo = NULL;
    643 	}
    644 	if (rImage->bo) {
    645 		radeon_bo_unref(rImage->bo);
    646 		rImage->bo = NULL;
    647 	}
    648 
    649 	radeon_miptree_unreference(&t->mt);
    650 	radeon_miptree_unreference(&rImage->mt);
    651 
    652 	rImage->bo = rb->bo;
    653 	radeon_bo_ref(rImage->bo);
    654 	t->bo = rb->bo;
    655 	radeon_bo_ref(t->bo);
    656 	t->tile_bits = 0;
    657 	t->image_override = GL_TRUE;
    658 	t->override_offset = 0;
    659 	switch (rb->cpp) {
    660 	case 4:
    661 		if (texture_format == __DRI_TEXTURE_FORMAT_RGB) {
    662 			t->pp_txformat = tx_table[MESA_FORMAT_RGB888].format;
    663 			texFormat = MESA_FORMAT_RGB888;
    664 		}
    665 		else {
    666 			t->pp_txformat = tx_table[MESA_FORMAT_ARGB8888].format;
    667 			texFormat = MESA_FORMAT_ARGB8888;
    668 		}
    669 		t->pp_txfilter |= tx_table[MESA_FORMAT_ARGB8888].filter;
    670 		break;
    671 	case 3:
    672 	default:
    673 		texFormat = MESA_FORMAT_RGB888;
    674 		t->pp_txformat = tx_table[MESA_FORMAT_RGB888].format;
    675 		t->pp_txfilter |= tx_table[MESA_FORMAT_RGB888].filter;
    676 		break;
    677 	case 2:
    678 		texFormat = MESA_FORMAT_RGB565;
    679 		t->pp_txformat = tx_table[MESA_FORMAT_RGB565].format;
    680 		t->pp_txfilter |= tx_table[MESA_FORMAT_RGB565].filter;
    681 		break;
    682 	}
    683 
    684 	_mesa_init_teximage_fields(radeon->glCtx, texImage,
    685 				   rb->base.Base.Width, rb->base.Base.Height,
    686 				   1, 0,
    687 				   rb->cpp, texFormat);
    688 	rImage->base.RowStride = rb->pitch / rb->cpp;
    689 
    690 	t->pp_txpitch &= (1 << 13) -1;
    691 	pitch_val = rb->pitch;
    692 
    693         t->pp_txsize = ((rb->base.Base.Width - 1) << RADEON_TEX_USIZE_SHIFT)
    694 		| ((rb->base.Base.Height - 1) << RADEON_TEX_VSIZE_SHIFT);
    695 	if (target == GL_TEXTURE_RECTANGLE_NV) {
    696 		t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2;
    697 		t->pp_txpitch = pitch_val;
    698 		t->pp_txpitch -= 32;
    699 	} else {
    700 	  t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK |
    701 			      RADEON_TXFORMAT_HEIGHT_MASK |
    702 			      RADEON_TXFORMAT_CUBIC_MAP_ENABLE |
    703 			      RADEON_TXFORMAT_F5_WIDTH_MASK |
    704 			      RADEON_TXFORMAT_F5_HEIGHT_MASK);
    705 	  t->pp_txformat |= ((texImage->WidthLog2 << RADEON_TXFORMAT_WIDTH_SHIFT) |
    706 			     (texImage->HeightLog2 << RADEON_TXFORMAT_HEIGHT_SHIFT));
    707 	}
    708 	t->validated = GL_TRUE;
    709 	_mesa_unlock_texture(radeon->glCtx, texObj);
    710 	return;
    711 }
    712 
    713 
    714 void radeonSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
    715 {
    716         radeonSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
    717 }
    718 
    719 
    720 #define TEXOBJ_TXFILTER_MASK (RADEON_MAX_MIP_LEVEL_MASK |	\
    721 			      RADEON_MIN_FILTER_MASK | 		\
    722 			      RADEON_MAG_FILTER_MASK |		\
    723 			      RADEON_MAX_ANISO_MASK |		\
    724 			      RADEON_YUV_TO_RGB |		\
    725 			      RADEON_YUV_TEMPERATURE_MASK |	\
    726 			      RADEON_CLAMP_S_MASK | 		\
    727 			      RADEON_CLAMP_T_MASK | 		\
    728 			      RADEON_BORDER_MODE_D3D )
    729 
    730 #define TEXOBJ_TXFORMAT_MASK (RADEON_TXFORMAT_WIDTH_MASK |	\
    731 			      RADEON_TXFORMAT_HEIGHT_MASK |	\
    732 			      RADEON_TXFORMAT_FORMAT_MASK |	\
    733                               RADEON_TXFORMAT_F5_WIDTH_MASK |	\
    734                               RADEON_TXFORMAT_F5_HEIGHT_MASK |	\
    735 			      RADEON_TXFORMAT_ALPHA_IN_MAP |	\
    736 			      RADEON_TXFORMAT_CUBIC_MAP_ENABLE |	\
    737                               RADEON_TXFORMAT_NON_POWER2)
    738 
    739 
    740 static void disable_tex_obj_state( r100ContextPtr rmesa,
    741 				   int unit )
    742 {
    743    RADEON_STATECHANGE( rmesa, tex[unit] );
    744 
    745    RADEON_STATECHANGE( rmesa, tcl );
    746    rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_ST_BIT(unit) |
    747 					     RADEON_Q_BIT(unit));
    748 
    749    if (rmesa->radeon.TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<<unit)) {
    750      TCL_FALLBACK( rmesa->radeon.glCtx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
    751      rmesa->recheck_texgen[unit] = GL_TRUE;
    752    }
    753 
    754    if (rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) {
    755      /* this seems to be a genuine (r100 only?) hw bug. Need to remove the
    756 	cubic_map bit on unit 2 when the unit is disabled, otherwise every
    757 	2nd (2d) mipmap on unit 0 will be broken (may not be needed for other
    758 	units, better be safe than sorry though).*/
    759      RADEON_STATECHANGE( rmesa, tex[unit] );
    760      rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &= ~RADEON_TXFORMAT_CUBIC_MAP_ENABLE;
    761    }
    762 
    763    {
    764       GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
    765       GLuint tmp = rmesa->TexGenEnabled;
    766 
    767       rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
    768       rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
    769       rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
    770       rmesa->TexGenNeedNormals[unit] = 0;
    771       rmesa->TexGenEnabled |=
    772 	(RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
    773 
    774       if (tmp != rmesa->TexGenEnabled) {
    775 	rmesa->recheck_texgen[unit] = GL_TRUE;
    776 	rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
    777       }
    778    }
    779 }
    780 
    781 static void import_tex_obj_state( r100ContextPtr rmesa,
    782 				  int unit,
    783 				  radeonTexObjPtr texobj )
    784 {
    785 /* do not use RADEON_DB_STATE to avoid stale texture caches */
    786    uint32_t *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
    787    GLuint se_coord_fmt = rmesa->hw.set.cmd[SET_SE_COORDFMT];
    788 
    789    RADEON_STATECHANGE( rmesa, tex[unit] );
    790 
    791    cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK;
    792    cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK;
    793    cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
    794    cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK;
    795    cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
    796 
    797    if (texobj->pp_txformat & RADEON_TXFORMAT_NON_POWER2) {
    798       uint32_t *txr_cmd = &rmesa->hw.txr[unit].cmd[TXR_CMD_0];
    799       txr_cmd[TXR_PP_TEX_SIZE] = texobj->pp_txsize; /* NPOT only! */
    800       txr_cmd[TXR_PP_TEX_PITCH] = texobj->pp_txpitch; /* NPOT only! */
    801       RADEON_STATECHANGE( rmesa, txr[unit] );
    802    }
    803 
    804    if (texobj->base.Target == GL_TEXTURE_RECTANGLE_NV) {
    805       se_coord_fmt |= RADEON_VTX_ST0_NONPARAMETRIC << unit;
    806    }
    807    else {
    808       se_coord_fmt &= ~(RADEON_VTX_ST0_NONPARAMETRIC << unit);
    809 
    810       if (texobj->base.Target == GL_TEXTURE_CUBE_MAP) {
    811 	 uint32_t *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
    812 
    813 	 RADEON_STATECHANGE( rmesa, cube[unit] );
    814 	 cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
    815 	 /* state filled out in the cube_emit */
    816       }
    817    }
    818 
    819    if (se_coord_fmt != rmesa->hw.set.cmd[SET_SE_COORDFMT]) {
    820       RADEON_STATECHANGE( rmesa, set );
    821       rmesa->hw.set.cmd[SET_SE_COORDFMT] = se_coord_fmt;
    822    }
    823 
    824    rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
    825 }
    826 
    827 
    828 static void set_texgen_matrix( r100ContextPtr rmesa,
    829 			       GLuint unit,
    830 			       const GLfloat *s_plane,
    831 			       const GLfloat *t_plane,
    832 			       const GLfloat *r_plane,
    833 			       const GLfloat *q_plane )
    834 {
    835    rmesa->TexGenMatrix[unit].m[0]  = s_plane[0];
    836    rmesa->TexGenMatrix[unit].m[4]  = s_plane[1];
    837    rmesa->TexGenMatrix[unit].m[8]  = s_plane[2];
    838    rmesa->TexGenMatrix[unit].m[12] = s_plane[3];
    839 
    840    rmesa->TexGenMatrix[unit].m[1]  = t_plane[0];
    841    rmesa->TexGenMatrix[unit].m[5]  = t_plane[1];
    842    rmesa->TexGenMatrix[unit].m[9]  = t_plane[2];
    843    rmesa->TexGenMatrix[unit].m[13] = t_plane[3];
    844 
    845    rmesa->TexGenMatrix[unit].m[2]  = r_plane[0];
    846    rmesa->TexGenMatrix[unit].m[6]  = r_plane[1];
    847    rmesa->TexGenMatrix[unit].m[10] = r_plane[2];
    848    rmesa->TexGenMatrix[unit].m[14] = r_plane[3];
    849 
    850    rmesa->TexGenMatrix[unit].m[3]  = q_plane[0];
    851    rmesa->TexGenMatrix[unit].m[7]  = q_plane[1];
    852    rmesa->TexGenMatrix[unit].m[11] = q_plane[2];
    853    rmesa->TexGenMatrix[unit].m[15] = q_plane[3];
    854 
    855    rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE << unit;
    856    rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
    857 }
    858 
    859 /* Returns GL_FALSE if fallback required.
    860  */
    861 static GLboolean radeon_validate_texgen( struct gl_context *ctx, GLuint unit )
    862 {
    863    r100ContextPtr rmesa = R100_CONTEXT(ctx);
    864    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
    865    GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
    866    GLuint tmp = rmesa->TexGenEnabled;
    867    static const GLfloat reflect[16] = {
    868       -1,  0,  0,  0,
    869        0, -1,  0,  0,
    870        0,  0,  -1, 0,
    871        0,  0,  0,  1 };
    872 
    873    rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE << unit);
    874    rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE << unit);
    875    rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK << inputshift);
    876    rmesa->TexGenNeedNormals[unit] = 0;
    877 
    878    if ((texUnit->TexGenEnabled & (S_BIT|T_BIT|R_BIT|Q_BIT)) == 0) {
    879       /* Disabled, no fallback:
    880        */
    881       rmesa->TexGenEnabled |=
    882 	 (RADEON_TEXGEN_INPUT_TEXCOORD_0 + unit) << inputshift;
    883       return GL_TRUE;
    884    }
    885    /* the r100 cannot do texgen for some coords and not for others
    886     * we do not detect such cases (certainly can't do it here) and just
    887     * ASSUME that when S and T are texgen enabled we do not need other
    888     * non-texgen enabled coords, no matter if the R and Q bits are texgen
    889     * enabled. Still check for mixed mode texgen for all coords.
    890     */
    891    else if ( (texUnit->TexGenEnabled & S_BIT) &&
    892 	     (texUnit->TexGenEnabled & T_BIT) &&
    893 	     (texUnit->GenS.Mode == texUnit->GenT.Mode) ) {
    894       if ( ((texUnit->TexGenEnabled & R_BIT) &&
    895 	    (texUnit->GenS.Mode != texUnit->GenR.Mode)) ||
    896 	   ((texUnit->TexGenEnabled & Q_BIT) &&
    897 	    (texUnit->GenS.Mode != texUnit->GenQ.Mode)) ) {
    898 	 /* Mixed modes, fallback:
    899 	  */
    900 	 if (RADEON_DEBUG & RADEON_FALLBACKS)
    901 	    fprintf(stderr, "fallback mixed texgen\n");
    902 	 return GL_FALSE;
    903       }
    904       rmesa->TexGenEnabled |= RADEON_TEXGEN_TEXMAT_0_ENABLE << unit;
    905    }
    906    else {
    907    /* some texgen mode not including both S and T bits */
    908       if (RADEON_DEBUG & RADEON_FALLBACKS)
    909 	 fprintf(stderr, "fallback mixed texgen/nontexgen\n");
    910       return GL_FALSE;
    911    }
    912 
    913    if ((texUnit->TexGenEnabled & (R_BIT | Q_BIT)) != 0) {
    914       /* need this here for vtxfmt presumably. Argh we need to set
    915          this from way too many places, would be much easier if we could leave
    916          tcl q coord always enabled as on r200) */
    917       RADEON_STATECHANGE( rmesa, tcl );
    918       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_Q_BIT(unit);
    919    }
    920 
    921    switch (texUnit->GenS.Mode) {
    922    case GL_OBJECT_LINEAR:
    923       rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_OBJ << inputshift;
    924       set_texgen_matrix( rmesa, unit,
    925 			 texUnit->GenS.ObjectPlane,
    926 			 texUnit->GenT.ObjectPlane,
    927 			 texUnit->GenR.ObjectPlane,
    928 			 texUnit->GenQ.ObjectPlane);
    929       break;
    930 
    931    case GL_EYE_LINEAR:
    932       rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE << inputshift;
    933       set_texgen_matrix( rmesa, unit,
    934 			 texUnit->GenS.EyePlane,
    935 			 texUnit->GenT.EyePlane,
    936 			 texUnit->GenR.EyePlane,
    937 			 texUnit->GenQ.EyePlane);
    938       break;
    939 
    940    case GL_REFLECTION_MAP_NV:
    941       rmesa->TexGenNeedNormals[unit] = GL_TRUE;
    942       rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_REFLECT << inputshift;
    943       /* TODO: unknown if this is needed/correct */
    944       set_texgen_matrix( rmesa, unit, reflect, reflect + 4,
    945 			reflect + 8, reflect + 12 );
    946       break;
    947 
    948    case GL_NORMAL_MAP_NV:
    949       rmesa->TexGenNeedNormals[unit] = GL_TRUE;
    950       rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL << inputshift;
    951       break;
    952 
    953    case GL_SPHERE_MAP:
    954       /* the mode which everyone uses :-( */
    955    default:
    956       /* Unsupported mode, fallback:
    957        */
    958       if (RADEON_DEBUG & RADEON_FALLBACKS)
    959 	 fprintf(stderr, "fallback GL_SPHERE_MAP\n");
    960       return GL_FALSE;
    961    }
    962 
    963    if (tmp != rmesa->TexGenEnabled) {
    964       rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
    965    }
    966 
    967    return GL_TRUE;
    968 }
    969 
    970 /**
    971  * Compute the cached hardware register values for the given texture object.
    972  *
    973  * \param rmesa Context pointer
    974  * \param t the r300 texture object
    975  */
    976 static GLboolean setup_hardware_state(r100ContextPtr rmesa, radeonTexObj *t, int unit)
    977 {
    978    const struct gl_texture_image *firstImage;
    979    GLint log2Width, log2Height, texelBytes;
    980 
    981    if ( t->bo ) {
    982 	return GL_TRUE;
    983    }
    984 
    985    firstImage = t->base.Image[0][t->minLod];
    986 
    987    log2Width  = firstImage->WidthLog2;
    988    log2Height = firstImage->HeightLog2;
    989    texelBytes = _mesa_get_format_bytes(firstImage->TexFormat);
    990 
    991    if (!t->image_override) {
    992       if (VALID_FORMAT(firstImage->TexFormat)) {
    993 	const struct tx_table *table = tx_table;
    994 
    995 	 t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK |
    996 			     RADEON_TXFORMAT_ALPHA_IN_MAP);
    997 	 t->pp_txfilter &= ~RADEON_YUV_TO_RGB;
    998 
    999 	 t->pp_txformat |= table[ firstImage->TexFormat ].format;
   1000 	 t->pp_txfilter |= table[ firstImage->TexFormat ].filter;
   1001       } else {
   1002 	 _mesa_problem(NULL, "unexpected texture format in %s",
   1003 		       __FUNCTION__);
   1004 	 return GL_FALSE;
   1005       }
   1006    }
   1007 
   1008    t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK;
   1009    t->pp_txfilter |= (t->maxLod - t->minLod) << RADEON_MAX_MIP_LEVEL_SHIFT;
   1010 
   1011    t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK |
   1012 		       RADEON_TXFORMAT_HEIGHT_MASK |
   1013 		       RADEON_TXFORMAT_CUBIC_MAP_ENABLE |
   1014 		       RADEON_TXFORMAT_F5_WIDTH_MASK |
   1015 		       RADEON_TXFORMAT_F5_HEIGHT_MASK);
   1016    t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) |
   1017 		      (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT));
   1018 
   1019    t->tile_bits = 0;
   1020 
   1021    if (t->base.Target == GL_TEXTURE_CUBE_MAP) {
   1022       ASSERT(log2Width == log2Height);
   1023       t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_F5_WIDTH_SHIFT) |
   1024 			 (log2Height << RADEON_TXFORMAT_F5_HEIGHT_SHIFT) |
   1025 			 /* don't think we need this bit, if it exists at all - fglrx does not set it */
   1026 			 (RADEON_TXFORMAT_CUBIC_MAP_ENABLE));
   1027       t->pp_cubic_faces = ((log2Width << RADEON_FACE_WIDTH_1_SHIFT) |
   1028                            (log2Height << RADEON_FACE_HEIGHT_1_SHIFT) |
   1029                            (log2Width << RADEON_FACE_WIDTH_2_SHIFT) |
   1030                            (log2Height << RADEON_FACE_HEIGHT_2_SHIFT) |
   1031                            (log2Width << RADEON_FACE_WIDTH_3_SHIFT) |
   1032                            (log2Height << RADEON_FACE_HEIGHT_3_SHIFT) |
   1033                            (log2Width << RADEON_FACE_WIDTH_4_SHIFT) |
   1034                            (log2Height << RADEON_FACE_HEIGHT_4_SHIFT));
   1035    }
   1036 
   1037    t->pp_txsize = (((firstImage->Width - 1) << RADEON_TEX_USIZE_SHIFT)
   1038 		   | ((firstImage->Height - 1) << RADEON_TEX_VSIZE_SHIFT));
   1039 
   1040    if ( !t->image_override ) {
   1041       if (_mesa_is_format_compressed(firstImage->TexFormat))
   1042          t->pp_txpitch = (firstImage->Width + 63) & ~(63);
   1043       else
   1044          t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63);
   1045       t->pp_txpitch -= 32;
   1046    }
   1047 
   1048    if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
   1049       t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2;
   1050    }
   1051 
   1052    return GL_TRUE;
   1053 }
   1054 
   1055 static GLboolean radeon_validate_texture(struct gl_context *ctx, struct gl_texture_object *texObj, int unit)
   1056 {
   1057    r100ContextPtr rmesa = R100_CONTEXT(ctx);
   1058    radeonTexObj *t = radeon_tex_obj(texObj);
   1059    int ret;
   1060 
   1061    if (!radeon_validate_texture_miptree(ctx, _mesa_get_samplerobj(ctx, unit), texObj))
   1062       return GL_FALSE;
   1063 
   1064    ret = setup_hardware_state(rmesa, t, unit);
   1065    if (ret == GL_FALSE)
   1066      return GL_FALSE;
   1067 
   1068    /* yuv conversion only works in first unit */
   1069    if (unit != 0 && (t->pp_txfilter & RADEON_YUV_TO_RGB))
   1070       return GL_FALSE;
   1071 
   1072    RADEON_STATECHANGE( rmesa, ctx );
   1073    rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=
   1074      (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit;
   1075    RADEON_STATECHANGE( rmesa, tcl );
   1076    rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_ST_BIT(unit);
   1077 
   1078    rmesa->recheck_texgen[unit] = GL_TRUE;
   1079 
   1080    radeonTexUpdateParameters(ctx, unit);
   1081    import_tex_obj_state( rmesa, unit, t );
   1082 
   1083    if (rmesa->recheck_texgen[unit]) {
   1084       GLboolean fallback = !radeon_validate_texgen( ctx, unit );
   1085       TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
   1086       rmesa->recheck_texgen[unit] = 0;
   1087       rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
   1088    }
   1089 
   1090    if ( ! radeonUpdateTextureEnv( ctx, unit ) ) {
   1091      return GL_FALSE;
   1092    }
   1093    FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback );
   1094 
   1095    t->validated = GL_TRUE;
   1096    return !t->border_fallback;
   1097 }
   1098 
   1099 static GLboolean radeonUpdateTextureUnit( struct gl_context *ctx, int unit )
   1100 {
   1101    r100ContextPtr rmesa = R100_CONTEXT(ctx);
   1102 
   1103    if (ctx->Texture.Unit[unit]._ReallyEnabled & TEXTURE_3D_BIT) {
   1104      disable_tex_obj_state(rmesa, unit);
   1105      rmesa->state.texture.unit[unit].texobj = NULL;
   1106      return GL_FALSE;
   1107    }
   1108 
   1109    if (!ctx->Texture.Unit[unit]._ReallyEnabled) {
   1110      /* disable the unit */
   1111      disable_tex_obj_state(rmesa, unit);
   1112      rmesa->state.texture.unit[unit].texobj = NULL;
   1113      return GL_TRUE;
   1114    }
   1115 
   1116    if (!radeon_validate_texture(ctx, ctx->Texture.Unit[unit]._Current, unit)) {
   1117     _mesa_warning(ctx,
   1118 		  "failed to validate texture for unit %d.\n",
   1119 		  unit);
   1120      rmesa->state.texture.unit[unit].texobj = NULL;
   1121      return GL_FALSE;
   1122    }
   1123    rmesa->state.texture.unit[unit].texobj = radeon_tex_obj(ctx->Texture.Unit[unit]._Current);
   1124    return GL_TRUE;
   1125 }
   1126 
   1127 void radeonUpdateTextureState( struct gl_context *ctx )
   1128 {
   1129    r100ContextPtr rmesa = R100_CONTEXT(ctx);
   1130    GLboolean ok;
   1131 
   1132    /* set the ctx all textures off */
   1133    RADEON_STATECHANGE( rmesa, ctx );
   1134    rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~((RADEON_TEX_ENABLE_MASK) | (RADEON_TEX_BLEND_ENABLE_MASK));
   1135 
   1136    ok = (radeonUpdateTextureUnit( ctx, 0 ) &&
   1137 	 radeonUpdateTextureUnit( ctx, 1 ) &&
   1138 	 radeonUpdateTextureUnit( ctx, 2 ));
   1139 
   1140    FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, !ok );
   1141 
   1142    if (rmesa->radeon.TclFallback)
   1143       radeonChooseVertexState( ctx );
   1144 }
   1145