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