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 <keith (at) tungstengraphics.com>
     33  */
     34 
     35 #include "main/glheader.h"
     36 #include "main/imports.h"
     37 #include "main/context.h"
     38 #include "main/macros.h"
     39 #include "main/teximage.h"
     40 #include "main/texobj.h"
     41 #include "main/enums.h"
     42 
     43 #include "radeon_common.h"
     44 #include "radeon_mipmap_tree.h"
     45 #include "r200_context.h"
     46 #include "r200_state.h"
     47 #include "r200_ioctl.h"
     48 #include "r200_swtcl.h"
     49 #include "r200_tex.h"
     50 #include "r200_tcl.h"
     51 
     52 
     53 #define R200_TXFORMAT_A8        R200_TXFORMAT_I8
     54 #define R200_TXFORMAT_L8        R200_TXFORMAT_I8
     55 #define R200_TXFORMAT_AL88      R200_TXFORMAT_AI88
     56 #define R200_TXFORMAT_YCBCR     R200_TXFORMAT_YVYU422
     57 #define R200_TXFORMAT_YCBCR_REV R200_TXFORMAT_VYUY422
     58 #define R200_TXFORMAT_RGB_DXT1  R200_TXFORMAT_DXT1
     59 #define R200_TXFORMAT_RGBA_DXT1 R200_TXFORMAT_DXT1
     60 #define R200_TXFORMAT_RGBA_DXT3 R200_TXFORMAT_DXT23
     61 #define R200_TXFORMAT_RGBA_DXT5 R200_TXFORMAT_DXT45
     62 
     63 #define _COLOR(f) \
     64     [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, 0 }
     65 #define _COLOR_REV(f) \
     66     [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f, 0 }
     67 #define _ALPHA(f) \
     68     [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
     69 #define _ALPHA_REV(f) \
     70     [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
     71 #define _YUV(f) \
     72     [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, R200_YUV_TO_RGB }
     73 #define _INVALID(f) \
     74     [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
     75 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \
     76 			     && (tx_table_be[f].format != 0xffffffff) )
     77 
     78 struct tx_table {
     79    GLuint format, filter;
     80 };
     81 
     82 static const struct tx_table tx_table_be[] =
     83 {
     84    [ MESA_FORMAT_RGBA8888 ] = { R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
     85    _ALPHA_REV(RGBA8888),
     86    _ALPHA(ARGB8888),
     87    _ALPHA_REV(ARGB8888),
     88    _INVALID(RGB888),
     89    _COLOR(RGB565),
     90    _COLOR_REV(RGB565),
     91    _ALPHA(ARGB4444),
     92    _ALPHA_REV(ARGB4444),
     93    _ALPHA(ARGB1555),
     94    _ALPHA_REV(ARGB1555),
     95    _ALPHA(AL88),
     96    _ALPHA_REV(AL88),
     97    _ALPHA(A8),
     98    _COLOR(L8),
     99    _ALPHA(I8),
    100    _YUV(YCBCR),
    101    _YUV(YCBCR_REV),
    102    _INVALID(RGB_FXT1),
    103    _INVALID(RGBA_FXT1),
    104    _COLOR(RGB_DXT1),
    105    _ALPHA(RGBA_DXT1),
    106    _ALPHA(RGBA_DXT3),
    107    _ALPHA(RGBA_DXT5),
    108 };
    109 
    110 static const struct tx_table tx_table_le[] =
    111 {
    112    _ALPHA(RGBA8888),
    113    [ MESA_FORMAT_RGBA8888_REV ] = { R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
    114    _ALPHA(ARGB8888),
    115    _ALPHA_REV(ARGB8888),
    116    [ MESA_FORMAT_RGB888 ] = { R200_TXFORMAT_ARGB8888, 0 },
    117    _COLOR(RGB565),
    118    _COLOR_REV(RGB565),
    119    _ALPHA(ARGB4444),
    120    _ALPHA_REV(ARGB4444),
    121    _ALPHA(ARGB1555),
    122    _ALPHA_REV(ARGB1555),
    123    _ALPHA(AL88),
    124    _ALPHA_REV(AL88),
    125    _ALPHA(A8),
    126    _COLOR(L8),
    127    _ALPHA(I8),
    128    _YUV(YCBCR),
    129    _YUV(YCBCR_REV),
    130    _INVALID(RGB_FXT1),
    131    _INVALID(RGBA_FXT1),
    132    _COLOR(RGB_DXT1),
    133    _ALPHA(RGBA_DXT1),
    134    _ALPHA(RGBA_DXT3),
    135    _ALPHA(RGBA_DXT5),
    136 };
    137 
    138 #undef _COLOR
    139 #undef _ALPHA
    140 #undef _INVALID
    141 
    142 /* ================================================================
    143  * Texture combine functions
    144  */
    145 
    146 /* GL_ARB_texture_env_combine support
    147  */
    148 
    149 /* The color tables have combine functions for GL_SRC_COLOR,
    150  * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
    151  */
    152 static GLuint r200_register_color[][R200_MAX_TEXTURE_UNITS] =
    153 {
    154    {
    155       R200_TXC_ARG_A_R0_COLOR,
    156       R200_TXC_ARG_A_R1_COLOR,
    157       R200_TXC_ARG_A_R2_COLOR,
    158       R200_TXC_ARG_A_R3_COLOR,
    159       R200_TXC_ARG_A_R4_COLOR,
    160       R200_TXC_ARG_A_R5_COLOR
    161    },
    162    {
    163       R200_TXC_ARG_A_R0_COLOR | R200_TXC_COMP_ARG_A,
    164       R200_TXC_ARG_A_R1_COLOR | R200_TXC_COMP_ARG_A,
    165       R200_TXC_ARG_A_R2_COLOR | R200_TXC_COMP_ARG_A,
    166       R200_TXC_ARG_A_R3_COLOR | R200_TXC_COMP_ARG_A,
    167       R200_TXC_ARG_A_R4_COLOR | R200_TXC_COMP_ARG_A,
    168       R200_TXC_ARG_A_R5_COLOR | R200_TXC_COMP_ARG_A
    169    },
    170    {
    171       R200_TXC_ARG_A_R0_ALPHA,
    172       R200_TXC_ARG_A_R1_ALPHA,
    173       R200_TXC_ARG_A_R2_ALPHA,
    174       R200_TXC_ARG_A_R3_ALPHA,
    175       R200_TXC_ARG_A_R4_ALPHA,
    176       R200_TXC_ARG_A_R5_ALPHA
    177    },
    178    {
    179       R200_TXC_ARG_A_R0_ALPHA | R200_TXC_COMP_ARG_A,
    180       R200_TXC_ARG_A_R1_ALPHA | R200_TXC_COMP_ARG_A,
    181       R200_TXC_ARG_A_R2_ALPHA | R200_TXC_COMP_ARG_A,
    182       R200_TXC_ARG_A_R3_ALPHA | R200_TXC_COMP_ARG_A,
    183       R200_TXC_ARG_A_R4_ALPHA | R200_TXC_COMP_ARG_A,
    184       R200_TXC_ARG_A_R5_ALPHA | R200_TXC_COMP_ARG_A
    185    },
    186 };
    187 
    188 static GLuint r200_tfactor_color[] =
    189 {
    190    R200_TXC_ARG_A_TFACTOR_COLOR,
    191    R200_TXC_ARG_A_TFACTOR_COLOR | R200_TXC_COMP_ARG_A,
    192    R200_TXC_ARG_A_TFACTOR_ALPHA,
    193    R200_TXC_ARG_A_TFACTOR_ALPHA | R200_TXC_COMP_ARG_A
    194 };
    195 
    196 static GLuint r200_tfactor1_color[] =
    197 {
    198    R200_TXC_ARG_A_TFACTOR1_COLOR,
    199    R200_TXC_ARG_A_TFACTOR1_COLOR | R200_TXC_COMP_ARG_A,
    200    R200_TXC_ARG_A_TFACTOR1_ALPHA,
    201    R200_TXC_ARG_A_TFACTOR1_ALPHA | R200_TXC_COMP_ARG_A
    202 };
    203 
    204 static GLuint r200_primary_color[] =
    205 {
    206    R200_TXC_ARG_A_DIFFUSE_COLOR,
    207    R200_TXC_ARG_A_DIFFUSE_COLOR | R200_TXC_COMP_ARG_A,
    208    R200_TXC_ARG_A_DIFFUSE_ALPHA,
    209    R200_TXC_ARG_A_DIFFUSE_ALPHA | R200_TXC_COMP_ARG_A
    210 };
    211 
    212 /* GL_ZERO table - indices 0-3
    213  * GL_ONE  table - indices 1-4
    214  */
    215 static GLuint r200_zero_color[] =
    216 {
    217    R200_TXC_ARG_A_ZERO,
    218    R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A,
    219    R200_TXC_ARG_A_ZERO,
    220    R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A,
    221    R200_TXC_ARG_A_ZERO
    222 };
    223 
    224 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
    225  */
    226 static GLuint r200_register_alpha[][R200_MAX_TEXTURE_UNITS] =
    227 {
    228    {
    229       R200_TXA_ARG_A_R0_ALPHA,
    230       R200_TXA_ARG_A_R1_ALPHA,
    231       R200_TXA_ARG_A_R2_ALPHA,
    232       R200_TXA_ARG_A_R3_ALPHA,
    233       R200_TXA_ARG_A_R4_ALPHA,
    234       R200_TXA_ARG_A_R5_ALPHA
    235    },
    236    {
    237       R200_TXA_ARG_A_R0_ALPHA | R200_TXA_COMP_ARG_A,
    238       R200_TXA_ARG_A_R1_ALPHA | R200_TXA_COMP_ARG_A,
    239       R200_TXA_ARG_A_R2_ALPHA | R200_TXA_COMP_ARG_A,
    240       R200_TXA_ARG_A_R3_ALPHA | R200_TXA_COMP_ARG_A,
    241       R200_TXA_ARG_A_R4_ALPHA | R200_TXA_COMP_ARG_A,
    242       R200_TXA_ARG_A_R5_ALPHA | R200_TXA_COMP_ARG_A
    243    },
    244 };
    245 
    246 static GLuint r200_tfactor_alpha[] =
    247 {
    248    R200_TXA_ARG_A_TFACTOR_ALPHA,
    249    R200_TXA_ARG_A_TFACTOR_ALPHA | R200_TXA_COMP_ARG_A
    250 };
    251 
    252 static GLuint r200_tfactor1_alpha[] =
    253 {
    254    R200_TXA_ARG_A_TFACTOR1_ALPHA,
    255    R200_TXA_ARG_A_TFACTOR1_ALPHA | R200_TXA_COMP_ARG_A
    256 };
    257 
    258 static GLuint r200_primary_alpha[] =
    259 {
    260    R200_TXA_ARG_A_DIFFUSE_ALPHA,
    261    R200_TXA_ARG_A_DIFFUSE_ALPHA | R200_TXA_COMP_ARG_A
    262 };
    263 
    264 /* GL_ZERO table - indices 0-1
    265  * GL_ONE  table - indices 1-2
    266  */
    267 static GLuint r200_zero_alpha[] =
    268 {
    269    R200_TXA_ARG_A_ZERO,
    270    R200_TXA_ARG_A_ZERO | R200_TXA_COMP_ARG_A,
    271    R200_TXA_ARG_A_ZERO,
    272 };
    273 
    274 
    275 /* Extract the arg from slot A, shift it into the correct argument slot
    276  * and set the corresponding complement bit.
    277  */
    278 #define R200_COLOR_ARG( n, arg )			\
    279 do {							\
    280    color_combine |=					\
    281       ((color_arg[n] & R200_TXC_ARG_A_MASK)		\
    282        << R200_TXC_ARG_##arg##_SHIFT);			\
    283    color_combine |=					\
    284       ((color_arg[n] >> R200_TXC_COMP_ARG_A_SHIFT)	\
    285        << R200_TXC_COMP_ARG_##arg##_SHIFT);		\
    286 } while (0)
    287 
    288 #define R200_ALPHA_ARG( n, arg )			\
    289 do {							\
    290    alpha_combine |=					\
    291       ((alpha_arg[n] & R200_TXA_ARG_A_MASK)		\
    292        << R200_TXA_ARG_##arg##_SHIFT);			\
    293    alpha_combine |=					\
    294       ((alpha_arg[n] >> R200_TXA_COMP_ARG_A_SHIFT)	\
    295        << R200_TXA_COMP_ARG_##arg##_SHIFT);		\
    296 } while (0)
    297 
    298 
    299 /* ================================================================
    300  * Texture unit state management
    301  */
    302 
    303 static GLboolean r200UpdateTextureEnv( struct gl_context *ctx, int unit, int slot, GLuint replaceargs )
    304 {
    305    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    306    const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
    307    GLuint color_combine, alpha_combine;
    308    GLuint color_scale = rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND2] &
    309       ~(R200_TXC_SCALE_MASK | R200_TXC_OUTPUT_REG_MASK | R200_TXC_TFACTOR_SEL_MASK |
    310 	R200_TXC_TFACTOR1_SEL_MASK);
    311    GLuint alpha_scale = rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND2] &
    312       ~(R200_TXA_DOT_ALPHA | R200_TXA_SCALE_MASK | R200_TXA_OUTPUT_REG_MASK |
    313 	R200_TXA_TFACTOR_SEL_MASK | R200_TXA_TFACTOR1_SEL_MASK);
    314 
    315    /* texUnit->_Current can be NULL if and only if the texture unit is
    316     * not actually enabled.
    317     */
    318    assert( (texUnit->_ReallyEnabled == 0)
    319 	   || (texUnit->_Current != NULL) );
    320 
    321    if ( R200_DEBUG & RADEON_TEXTURE ) {
    322       fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, (void *)ctx, unit );
    323    }
    324 
    325    /* Set the texture environment state.  Isn't this nice and clean?
    326     * The chip will automagically set the texture alpha to 0xff when
    327     * the texture format does not include an alpha component.  This
    328     * reduces the amount of special-casing we have to do, alpha-only
    329     * textures being a notable exception.
    330     */
    331 
    332    color_scale |= ((rmesa->state.texture.unit[unit].outputreg + 1) << R200_TXC_OUTPUT_REG_SHIFT) |
    333 			(unit << R200_TXC_TFACTOR_SEL_SHIFT) |
    334 			(replaceargs << R200_TXC_TFACTOR1_SEL_SHIFT);
    335    alpha_scale |= ((rmesa->state.texture.unit[unit].outputreg + 1) << R200_TXA_OUTPUT_REG_SHIFT) |
    336 			(unit << R200_TXA_TFACTOR_SEL_SHIFT) |
    337 			(replaceargs << R200_TXA_TFACTOR1_SEL_SHIFT);
    338 
    339    if ( !texUnit->_ReallyEnabled ) {
    340       assert( unit == 0);
    341       color_combine = R200_TXC_ARG_A_ZERO | R200_TXC_ARG_B_ZERO
    342 	  | R200_TXC_ARG_C_DIFFUSE_COLOR | R200_TXC_OP_MADD;
    343       alpha_combine = R200_TXA_ARG_A_ZERO | R200_TXA_ARG_B_ZERO
    344 	  | R200_TXA_ARG_C_DIFFUSE_ALPHA | R200_TXA_OP_MADD;
    345    }
    346    else {
    347       GLuint color_arg[3], alpha_arg[3];
    348       GLuint i;
    349       const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
    350       const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
    351       GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB;
    352       GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA;
    353 
    354 
    355       const GLint replaceoprgb =
    356 	 ctx->Texture.Unit[replaceargs]._CurrentCombine->OperandRGB[0] - GL_SRC_COLOR;
    357       const GLint replaceopa =
    358 	 ctx->Texture.Unit[replaceargs]._CurrentCombine->OperandA[0] - GL_SRC_ALPHA;
    359 
    360       /* Step 1:
    361        * Extract the color and alpha combine function arguments.
    362        */
    363       for ( i = 0 ; i < numColorArgs ; i++ ) {
    364 	 GLint op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR;
    365 	 const GLint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i];
    366 	 assert(op >= 0);
    367 	 assert(op <= 3);
    368 	 switch ( srcRGBi ) {
    369 	 case GL_TEXTURE:
    370 	    color_arg[i] = r200_register_color[op][unit];
    371 	    break;
    372 	 case GL_CONSTANT:
    373 	    color_arg[i] = r200_tfactor_color[op];
    374 	    break;
    375 	 case GL_PRIMARY_COLOR:
    376 	    color_arg[i] = r200_primary_color[op];
    377 	    break;
    378 	 case GL_PREVIOUS:
    379 	    if (replaceargs != unit) {
    380 	       const GLint srcRGBreplace =
    381 		  ctx->Texture.Unit[replaceargs]._CurrentCombine->SourceRGB[0];
    382 	       if (op >= 2) {
    383 		  op = op ^ replaceopa;
    384 	       }
    385 	       else {
    386 		  op = op ^ replaceoprgb;
    387 	       }
    388 	       switch (srcRGBreplace) {
    389 	       case GL_TEXTURE:
    390 		  color_arg[i] = r200_register_color[op][replaceargs];
    391 		  break;
    392 	       case GL_CONSTANT:
    393 		  color_arg[i] = r200_tfactor1_color[op];
    394 		  break;
    395 	       case GL_PRIMARY_COLOR:
    396 		  color_arg[i] = r200_primary_color[op];
    397 		  break;
    398 	       case GL_PREVIOUS:
    399 		  if (slot == 0)
    400 		     color_arg[i] = r200_primary_color[op];
    401 		  else
    402 		     color_arg[i] = r200_register_color[op]
    403 			[rmesa->state.texture.unit[replaceargs - 1].outputreg];
    404 		  break;
    405 	       case GL_ZERO:
    406 		  color_arg[i] = r200_zero_color[op];
    407 		  break;
    408 	       case GL_ONE:
    409 		  color_arg[i] = r200_zero_color[op+1];
    410 		  break;
    411 	       case GL_TEXTURE0:
    412 	       case GL_TEXTURE1:
    413 	       case GL_TEXTURE2:
    414 	       case GL_TEXTURE3:
    415 	       case GL_TEXTURE4:
    416 	       case GL_TEXTURE5:
    417 		  color_arg[i] = r200_register_color[op][srcRGBreplace - GL_TEXTURE0];
    418 		  break;
    419 	       default:
    420 	       return GL_FALSE;
    421 	       }
    422 	    }
    423 	    else {
    424 	       if (slot == 0)
    425 		  color_arg[i] = r200_primary_color[op];
    426 	       else
    427 		  color_arg[i] = r200_register_color[op]
    428 		     [rmesa->state.texture.unit[unit - 1].outputreg];
    429             }
    430 	    break;
    431 	 case GL_ZERO:
    432 	    color_arg[i] = r200_zero_color[op];
    433 	    break;
    434 	 case GL_ONE:
    435 	    color_arg[i] = r200_zero_color[op+1];
    436 	    break;
    437 	 case GL_TEXTURE0:
    438 	 case GL_TEXTURE1:
    439 	 case GL_TEXTURE2:
    440 	 case GL_TEXTURE3:
    441 	 case GL_TEXTURE4:
    442 	 case GL_TEXTURE5:
    443 	    color_arg[i] = r200_register_color[op][srcRGBi - GL_TEXTURE0];
    444 	    break;
    445 	 default:
    446 	    return GL_FALSE;
    447 	 }
    448       }
    449 
    450       for ( i = 0 ; i < numAlphaArgs ; i++ ) {
    451 	 GLint op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA;
    452 	 const GLint srcAi = texUnit->_CurrentCombine->SourceA[i];
    453 	 assert(op >= 0);
    454 	 assert(op <= 1);
    455 	 switch ( srcAi ) {
    456 	 case GL_TEXTURE:
    457 	    alpha_arg[i] = r200_register_alpha[op][unit];
    458 	    break;
    459 	 case GL_CONSTANT:
    460 	    alpha_arg[i] = r200_tfactor_alpha[op];
    461 	    break;
    462 	 case GL_PRIMARY_COLOR:
    463 	    alpha_arg[i] = r200_primary_alpha[op];
    464 	    break;
    465 	 case GL_PREVIOUS:
    466 	    if (replaceargs != unit) {
    467 	       const GLint srcAreplace =
    468 		  ctx->Texture.Unit[replaceargs]._CurrentCombine->SourceA[0];
    469 	       op = op ^ replaceopa;
    470 	       switch (srcAreplace) {
    471 	       case GL_TEXTURE:
    472 		  alpha_arg[i] = r200_register_alpha[op][replaceargs];
    473 		  break;
    474 	       case GL_CONSTANT:
    475 		  alpha_arg[i] = r200_tfactor1_alpha[op];
    476 		  break;
    477 	       case GL_PRIMARY_COLOR:
    478 		  alpha_arg[i] = r200_primary_alpha[op];
    479 		  break;
    480 	       case GL_PREVIOUS:
    481 		  if (slot == 0)
    482 		     alpha_arg[i] = r200_primary_alpha[op];
    483 		  else
    484 		     alpha_arg[i] = r200_register_alpha[op]
    485 			[rmesa->state.texture.unit[replaceargs - 1].outputreg];
    486 		  break;
    487 	       case GL_ZERO:
    488 		  alpha_arg[i] = r200_zero_alpha[op];
    489 		  break;
    490 	       case GL_ONE:
    491 		  alpha_arg[i] = r200_zero_alpha[op+1];
    492 		  break;
    493 	       case GL_TEXTURE0:
    494 	       case GL_TEXTURE1:
    495 	       case GL_TEXTURE2:
    496 	       case GL_TEXTURE3:
    497 	       case GL_TEXTURE4:
    498 	       case GL_TEXTURE5:
    499 		  alpha_arg[i] = r200_register_alpha[op][srcAreplace - GL_TEXTURE0];
    500 		  break;
    501 	       default:
    502 	       return GL_FALSE;
    503 	       }
    504 	    }
    505 	    else {
    506 	       if (slot == 0)
    507 		  alpha_arg[i] = r200_primary_alpha[op];
    508 	       else
    509 		  alpha_arg[i] = r200_register_alpha[op]
    510 		    [rmesa->state.texture.unit[unit - 1].outputreg];
    511             }
    512 	    break;
    513 	 case GL_ZERO:
    514 	    alpha_arg[i] = r200_zero_alpha[op];
    515 	    break;
    516 	 case GL_ONE:
    517 	    alpha_arg[i] = r200_zero_alpha[op+1];
    518 	    break;
    519 	 case GL_TEXTURE0:
    520 	 case GL_TEXTURE1:
    521 	 case GL_TEXTURE2:
    522 	 case GL_TEXTURE3:
    523 	 case GL_TEXTURE4:
    524 	 case GL_TEXTURE5:
    525 	    alpha_arg[i] = r200_register_alpha[op][srcAi - GL_TEXTURE0];
    526 	    break;
    527 	 default:
    528 	    return GL_FALSE;
    529 	 }
    530       }
    531 
    532       /* Step 2:
    533        * Build up the color and alpha combine functions.
    534        */
    535       switch ( texUnit->_CurrentCombine->ModeRGB ) {
    536       case GL_REPLACE:
    537 	 color_combine = (R200_TXC_ARG_A_ZERO |
    538 			  R200_TXC_ARG_B_ZERO |
    539 			  R200_TXC_OP_MADD);
    540 	 R200_COLOR_ARG( 0, C );
    541 	 break;
    542       case GL_MODULATE:
    543 	 color_combine = (R200_TXC_ARG_C_ZERO |
    544 			  R200_TXC_OP_MADD);
    545 	 R200_COLOR_ARG( 0, A );
    546 	 R200_COLOR_ARG( 1, B );
    547 	 break;
    548       case GL_ADD:
    549 	 color_combine = (R200_TXC_ARG_B_ZERO |
    550 			  R200_TXC_COMP_ARG_B |
    551 			  R200_TXC_OP_MADD);
    552 	 R200_COLOR_ARG( 0, A );
    553 	 R200_COLOR_ARG( 1, C );
    554 	 break;
    555       case GL_ADD_SIGNED:
    556 	 color_combine = (R200_TXC_ARG_B_ZERO |
    557 			  R200_TXC_COMP_ARG_B |
    558 			  R200_TXC_BIAS_ARG_C |	/* new */
    559 			  R200_TXC_OP_MADD); /* was ADDSIGNED */
    560 	 R200_COLOR_ARG( 0, A );
    561 	 R200_COLOR_ARG( 1, C );
    562 	 break;
    563       case GL_SUBTRACT:
    564 	 color_combine = (R200_TXC_ARG_B_ZERO |
    565 			  R200_TXC_COMP_ARG_B |
    566 			  R200_TXC_NEG_ARG_C |
    567 			  R200_TXC_OP_MADD);
    568 	 R200_COLOR_ARG( 0, A );
    569 	 R200_COLOR_ARG( 1, C );
    570 	 break;
    571       case GL_INTERPOLATE:
    572 	 color_combine = (R200_TXC_OP_LERP);
    573 	 R200_COLOR_ARG( 0, B );
    574 	 R200_COLOR_ARG( 1, A );
    575 	 R200_COLOR_ARG( 2, C );
    576 	 break;
    577 
    578       case GL_DOT3_RGB_EXT:
    579       case GL_DOT3_RGBA_EXT:
    580 	 /* The EXT version of the DOT3 extension does not support the
    581 	  * scale factor, but the ARB version (and the version in OpenGL
    582 	  * 1.3) does.
    583 	  */
    584 	 RGBshift = 0;
    585 	 /* FALLTHROUGH */
    586 
    587       case GL_DOT3_RGB:
    588       case GL_DOT3_RGBA:
    589 	 /* DOT3 works differently on R200 than on R100.  On R100, just
    590 	  * setting the DOT3 mode did everything for you.  On R200, the
    591 	  * driver has to enable the biasing and scale in the inputs to
    592 	  * put them in the proper [-1,1] range.  This is what the 4x and
    593 	  * the -0.5 in the DOT3 spec do.  The post-scale is then set
    594 	  * normally.
    595 	  */
    596 
    597 	 color_combine = (R200_TXC_ARG_C_ZERO |
    598 			  R200_TXC_OP_DOT3 |
    599 			  R200_TXC_BIAS_ARG_A |
    600 			  R200_TXC_BIAS_ARG_B |
    601 			  R200_TXC_SCALE_ARG_A |
    602 			  R200_TXC_SCALE_ARG_B);
    603 	 R200_COLOR_ARG( 0, A );
    604 	 R200_COLOR_ARG( 1, B );
    605 	 break;
    606 
    607       case GL_MODULATE_ADD_ATI:
    608 	 color_combine = (R200_TXC_OP_MADD);
    609 	 R200_COLOR_ARG( 0, A );
    610 	 R200_COLOR_ARG( 1, C );
    611 	 R200_COLOR_ARG( 2, B );
    612 	 break;
    613       case GL_MODULATE_SIGNED_ADD_ATI:
    614 	 color_combine = (R200_TXC_BIAS_ARG_C |	/* new */
    615 			  R200_TXC_OP_MADD); /* was ADDSIGNED */
    616 	 R200_COLOR_ARG( 0, A );
    617 	 R200_COLOR_ARG( 1, C );
    618 	 R200_COLOR_ARG( 2, B );
    619 	 break;
    620       case GL_MODULATE_SUBTRACT_ATI:
    621 	 color_combine = (R200_TXC_NEG_ARG_C |
    622 			  R200_TXC_OP_MADD);
    623 	 R200_COLOR_ARG( 0, A );
    624 	 R200_COLOR_ARG( 1, C );
    625 	 R200_COLOR_ARG( 2, B );
    626 	 break;
    627       default:
    628 	 return GL_FALSE;
    629       }
    630 
    631       switch ( texUnit->_CurrentCombine->ModeA ) {
    632       case GL_REPLACE:
    633 	 alpha_combine = (R200_TXA_ARG_A_ZERO |
    634 			  R200_TXA_ARG_B_ZERO |
    635 			  R200_TXA_OP_MADD);
    636 	 R200_ALPHA_ARG( 0, C );
    637 	 break;
    638       case GL_MODULATE:
    639 	 alpha_combine = (R200_TXA_ARG_C_ZERO |
    640 			  R200_TXA_OP_MADD);
    641 	 R200_ALPHA_ARG( 0, A );
    642 	 R200_ALPHA_ARG( 1, B );
    643 	 break;
    644       case GL_ADD:
    645 	 alpha_combine = (R200_TXA_ARG_B_ZERO |
    646 			  R200_TXA_COMP_ARG_B |
    647 			  R200_TXA_OP_MADD);
    648 	 R200_ALPHA_ARG( 0, A );
    649 	 R200_ALPHA_ARG( 1, C );
    650 	 break;
    651       case GL_ADD_SIGNED:
    652 	 alpha_combine = (R200_TXA_ARG_B_ZERO |
    653 			  R200_TXA_COMP_ARG_B |
    654 			  R200_TXA_BIAS_ARG_C |	/* new */
    655 			  R200_TXA_OP_MADD); /* was ADDSIGNED */
    656 	 R200_ALPHA_ARG( 0, A );
    657 	 R200_ALPHA_ARG( 1, C );
    658 	 break;
    659       case GL_SUBTRACT:
    660 	 alpha_combine = (R200_TXA_ARG_B_ZERO |
    661 			  R200_TXA_COMP_ARG_B |
    662 			  R200_TXA_NEG_ARG_C |
    663 			  R200_TXA_OP_MADD);
    664 	 R200_ALPHA_ARG( 0, A );
    665 	 R200_ALPHA_ARG( 1, C );
    666 	 break;
    667       case GL_INTERPOLATE:
    668 	 alpha_combine = (R200_TXA_OP_LERP);
    669 	 R200_ALPHA_ARG( 0, B );
    670 	 R200_ALPHA_ARG( 1, A );
    671 	 R200_ALPHA_ARG( 2, C );
    672 	 break;
    673 
    674       case GL_MODULATE_ADD_ATI:
    675 	 alpha_combine = (R200_TXA_OP_MADD);
    676 	 R200_ALPHA_ARG( 0, A );
    677 	 R200_ALPHA_ARG( 1, C );
    678 	 R200_ALPHA_ARG( 2, B );
    679 	 break;
    680       case GL_MODULATE_SIGNED_ADD_ATI:
    681 	 alpha_combine = (R200_TXA_BIAS_ARG_C |	/* new */
    682 			  R200_TXA_OP_MADD); /* was ADDSIGNED */
    683 	 R200_ALPHA_ARG( 0, A );
    684 	 R200_ALPHA_ARG( 1, C );
    685 	 R200_ALPHA_ARG( 2, B );
    686 	 break;
    687       case GL_MODULATE_SUBTRACT_ATI:
    688 	 alpha_combine = (R200_TXA_NEG_ARG_C |
    689 			  R200_TXA_OP_MADD);
    690 	 R200_ALPHA_ARG( 0, A );
    691 	 R200_ALPHA_ARG( 1, C );
    692 	 R200_ALPHA_ARG( 2, B );
    693 	 break;
    694       default:
    695 	 return GL_FALSE;
    696       }
    697 
    698       if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT)
    699 	   || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) {
    700 	 alpha_scale |= R200_TXA_DOT_ALPHA;
    701 	 Ashift = RGBshift;
    702       }
    703 
    704       /* Step 3:
    705        * Apply the scale factor.
    706        */
    707       color_scale |= (RGBshift << R200_TXC_SCALE_SHIFT);
    708       alpha_scale |= (Ashift   << R200_TXA_SCALE_SHIFT);
    709 
    710       /* All done!
    711        */
    712    }
    713 
    714    if ( rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND] != color_combine ||
    715 	rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND] != alpha_combine ||
    716 	rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND2] != color_scale ||
    717 	rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND2] != alpha_scale) {
    718       R200_STATECHANGE( rmesa, pix[slot] );
    719       rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND] = color_combine;
    720       rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND] = alpha_combine;
    721       rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND2] = color_scale;
    722       rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND2] = alpha_scale;
    723    }
    724 
    725    return GL_TRUE;
    726 }
    727 
    728 void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint texture_format,
    729 		       __DRIdrawable *dPriv)
    730 {
    731 	struct gl_texture_unit *texUnit;
    732 	struct gl_texture_object *texObj;
    733 	struct gl_texture_image *texImage;
    734 	struct radeon_renderbuffer *rb;
    735 	radeon_texture_image *rImage;
    736 	radeonContextPtr radeon;
    737 	struct radeon_framebuffer *rfb;
    738 	radeonTexObjPtr t;
    739 	uint32_t pitch_val;
    740 	gl_format texFormat;
    741 
    742 	radeon = pDRICtx->driverPrivate;
    743 
    744 	rfb = dPriv->driverPrivate;
    745         texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit];
    746 	texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target);
    747         texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0);
    748 
    749 	rImage = get_radeon_texture_image(texImage);
    750 	t = radeon_tex_obj(texObj);
    751         if (t == NULL) {
    752     	    return;
    753     	}
    754 
    755 	radeon_update_renderbuffers(pDRICtx, dPriv, GL_TRUE);
    756 	rb = rfb->color_rb[0];
    757 	if (rb->bo == NULL) {
    758 		/* Failed to BO for the buffer */
    759 		return;
    760 	}
    761 
    762 	_mesa_lock_texture(radeon->glCtx, texObj);
    763 	if (t->bo) {
    764 		radeon_bo_unref(t->bo);
    765 		t->bo = NULL;
    766 	}
    767 	if (rImage->bo) {
    768 		radeon_bo_unref(rImage->bo);
    769 		rImage->bo = NULL;
    770 	}
    771 
    772 	radeon_miptree_unreference(&t->mt);
    773 	radeon_miptree_unreference(&rImage->mt);
    774 
    775 	rImage->bo = rb->bo;
    776 	radeon_bo_ref(rImage->bo);
    777 	t->bo = rb->bo;
    778 	radeon_bo_ref(t->bo);
    779 	t->tile_bits = 0;
    780 	t->image_override = GL_TRUE;
    781 	t->override_offset = 0;
    782 	t->pp_txpitch &= (1 << 13) -1;
    783 	pitch_val = rb->pitch;
    784 	switch (rb->cpp) {
    785 	case 4:
    786 		if (texture_format == __DRI_TEXTURE_FORMAT_RGB) {
    787 			texFormat = MESA_FORMAT_RGB888;
    788 			t->pp_txformat = tx_table_le[MESA_FORMAT_RGB888].format;
    789 		}
    790 		else {
    791 			texFormat = MESA_FORMAT_ARGB8888;
    792 			t->pp_txformat = tx_table_le[MESA_FORMAT_ARGB8888].format;
    793 		}
    794 		t->pp_txfilter |= tx_table_le[MESA_FORMAT_ARGB8888].filter;
    795 		break;
    796 	case 3:
    797 	default:
    798 		texFormat = MESA_FORMAT_RGB888;
    799 		t->pp_txformat = tx_table_le[MESA_FORMAT_RGB888].format;
    800 		t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB888].filter;
    801 		break;
    802 	case 2:
    803 		texFormat = MESA_FORMAT_RGB565;
    804 		t->pp_txformat = tx_table_le[MESA_FORMAT_RGB565].format;
    805 		t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB565].filter;
    806 		break;
    807 	}
    808 
    809 	_mesa_init_teximage_fields(radeon->glCtx, texImage,
    810 				   rb->base.Base.Width, rb->base.Base.Height,
    811 				   1, 0,
    812 				   rb->cpp, texFormat);
    813 	rImage->base.RowStride = rb->pitch / rb->cpp;
    814 
    815 
    816         t->pp_txsize = ((rb->base.Base.Width - 1) << RADEON_TEX_USIZE_SHIFT)
    817 		   | ((rb->base.Base.Height - 1) << RADEON_TEX_VSIZE_SHIFT);
    818 
    819 	if (target == GL_TEXTURE_RECTANGLE_NV) {
    820 		t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
    821 		t->pp_txpitch = pitch_val;
    822 		t->pp_txpitch -= 32;
    823 	} else {
    824 		t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
    825 				    R200_TXFORMAT_HEIGHT_MASK |
    826 				    R200_TXFORMAT_CUBIC_MAP_ENABLE |
    827 				    R200_TXFORMAT_F5_WIDTH_MASK |
    828 				    R200_TXFORMAT_F5_HEIGHT_MASK);
    829 		t->pp_txformat |= ((texImage->WidthLog2 << R200_TXFORMAT_WIDTH_SHIFT) |
    830 				   (texImage->HeightLog2 << R200_TXFORMAT_HEIGHT_SHIFT));
    831 	}
    832 
    833 	t->validated = GL_TRUE;
    834 	_mesa_unlock_texture(radeon->glCtx, texObj);
    835 	return;
    836 }
    837 
    838 
    839 void r200SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
    840 {
    841         r200SetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
    842 }
    843 
    844 
    845 #define REF_COLOR 1
    846 #define REF_ALPHA 2
    847 
    848 static GLboolean r200UpdateAllTexEnv( struct gl_context *ctx )
    849 {
    850    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    851    GLint i, j, currslot;
    852    GLint maxunitused = -1;
    853    GLboolean texregfree[6] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
    854    GLubyte stageref[7] = {0, 0, 0, 0, 0, 0, 0};
    855    GLint nextunit[R200_MAX_TEXTURE_UNITS] = {0, 0, 0, 0, 0, 0};
    856    GLint currentnext = -1;
    857    GLboolean ok;
    858 
    859    /* find highest used unit */
    860    for ( j = 0; j < R200_MAX_TEXTURE_UNITS; j++) {
    861       if (ctx->Texture.Unit[j]._ReallyEnabled) {
    862 	 maxunitused = j;
    863       }
    864    }
    865    stageref[maxunitused + 1] = REF_COLOR | REF_ALPHA;
    866 
    867    for ( j = maxunitused; j >= 0; j-- ) {
    868       const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[j];
    869 
    870       rmesa->state.texture.unit[j].outputreg = -1;
    871 
    872       if (stageref[j + 1]) {
    873 
    874 	 /* use the lowest available reg. That gets us automatically reg0 for the last stage.
    875 	    need this even for disabled units, as it may get referenced due to the replace
    876 	    optimization */
    877 	 for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS; i++ ) {
    878 	    if (texregfree[i]) {
    879 	       rmesa->state.texture.unit[j].outputreg = i;
    880 	       break;
    881 	    }
    882 	 }
    883 	 if (rmesa->state.texture.unit[j].outputreg == -1) {
    884 	    /* no more free regs we can use. Need a fallback :-( */
    885 	    return GL_FALSE;
    886          }
    887 
    888          nextunit[j] = currentnext;
    889 
    890          if (!texUnit->_ReallyEnabled) {
    891 	 /* the not enabled stages are referenced "indirectly",
    892             must not cut off the lower stages */
    893 	    stageref[j] = REF_COLOR | REF_ALPHA;
    894 	    continue;
    895          }
    896 	 currentnext = j;
    897 
    898 	 const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
    899 	 const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
    900 	 const GLboolean isdot3rgba = (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ||
    901 				      (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT);
    902 
    903 
    904 	 /* check if we need the color part, special case for dot3_rgba
    905 	    as if only the alpha part is referenced later on it still is using the color part */
    906 	 if ((stageref[j + 1] & REF_COLOR) || isdot3rgba) {
    907 	    for ( i = 0 ; i < numColorArgs ; i++ ) {
    908 	       const GLuint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i];
    909 	       const GLuint op = texUnit->_CurrentCombine->OperandRGB[i];
    910 	       switch ( srcRGBi ) {
    911 	       case GL_PREVIOUS:
    912 		  /* op 0/1 are referencing color, op 2/3 alpha */
    913 		  stageref[j] |= (op >> 1) + 1;
    914 	          break;
    915 	       case GL_TEXTURE:
    916 		  texregfree[j] = GL_FALSE;
    917 		  break;
    918 	       case GL_TEXTURE0:
    919 	       case GL_TEXTURE1:
    920 	       case GL_TEXTURE2:
    921 	       case GL_TEXTURE3:
    922 	       case GL_TEXTURE4:
    923 	       case GL_TEXTURE5:
    924 		  texregfree[srcRGBi - GL_TEXTURE0] = GL_FALSE;
    925 	          break;
    926 	       default: /* don't care about other sources here */
    927 		  break;
    928 	       }
    929 	    }
    930 	 }
    931 
    932 	 /* alpha args are ignored for dot3_rgba */
    933 	 if ((stageref[j + 1] & REF_ALPHA) && !isdot3rgba) {
    934 
    935 	    for ( i = 0 ; i < numAlphaArgs ; i++ ) {
    936 	       const GLuint srcAi = texUnit->_CurrentCombine->SourceA[i];
    937 	       switch ( srcAi ) {
    938 	       case GL_PREVIOUS:
    939 		  stageref[j] |= REF_ALPHA;
    940 		  break;
    941 	       case GL_TEXTURE:
    942 		  texregfree[j] = GL_FALSE;
    943 		  break;
    944 	       case GL_TEXTURE0:
    945 	       case GL_TEXTURE1:
    946 	       case GL_TEXTURE2:
    947 	       case GL_TEXTURE3:
    948 	       case GL_TEXTURE4:
    949 	       case GL_TEXTURE5:
    950 		  texregfree[srcAi - GL_TEXTURE0] = GL_FALSE;
    951 		  break;
    952 	       default: /* don't care about other sources here */
    953 		  break;
    954 	       }
    955 	    }
    956 	 }
    957       }
    958    }
    959 
    960    /* don't enable texture sampling for units if the result is not used */
    961    for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) {
    962       if (ctx->Texture.Unit[i]._ReallyEnabled && !texregfree[i])
    963 	 rmesa->state.texture.unit[i].unitneeded = ctx->Texture.Unit[i]._ReallyEnabled;
    964       else rmesa->state.texture.unit[i].unitneeded = 0;
    965    }
    966 
    967    ok = GL_TRUE;
    968    currslot = 0;
    969    rmesa->state.envneeded = 1;
    970 
    971    i = 0;
    972    while ((i <= maxunitused) && (i >= 0)) {
    973       /* only output instruction if the results are referenced */
    974       if (ctx->Texture.Unit[i]._ReallyEnabled && stageref[i+1]) {
    975          GLuint replaceunit = i;
    976 	 /* try to optimize GL_REPLACE away (only one level deep though) */
    977 	 if (	(ctx->Texture.Unit[i]._CurrentCombine->ModeRGB == GL_REPLACE) &&
    978 		(ctx->Texture.Unit[i]._CurrentCombine->ModeA == GL_REPLACE) &&
    979 		(ctx->Texture.Unit[i]._CurrentCombine->ScaleShiftRGB == 0) &&
    980 		(ctx->Texture.Unit[i]._CurrentCombine->ScaleShiftA == 0) &&
    981 		(nextunit[i] > 0) ) {
    982 	    /* yippie! can optimize it away! */
    983 	    replaceunit = i;
    984 	    i = nextunit[i];
    985 	 }
    986 
    987 	 /* need env instruction slot */
    988 	 rmesa->state.envneeded |= 1 << currslot;
    989 	 ok = r200UpdateTextureEnv( ctx, i, currslot, replaceunit );
    990 	 if (!ok) return GL_FALSE;
    991 	 currslot++;
    992       }
    993       i = i + 1;
    994    }
    995 
    996    if (currslot == 0) {
    997       /* need one stage at least */
    998       rmesa->state.texture.unit[0].outputreg = 0;
    999       ok = r200UpdateTextureEnv( ctx, 0, 0, 0 );
   1000    }
   1001 
   1002    R200_STATECHANGE( rmesa, ctx );
   1003    rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_TEX_BLEND_ENABLE_MASK | R200_MULTI_PASS_ENABLE);
   1004    rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= rmesa->state.envneeded << R200_TEX_BLEND_0_ENABLE_SHIFT;
   1005 
   1006    return ok;
   1007 }
   1008 
   1009 #undef REF_COLOR
   1010 #undef REF_ALPHA
   1011 
   1012 
   1013 #define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK |		\
   1014 			      R200_MIN_FILTER_MASK | 		\
   1015 			      R200_MAG_FILTER_MASK |		\
   1016 			      R200_MAX_ANISO_MASK |		\
   1017 			      R200_YUV_TO_RGB |			\
   1018 			      R200_YUV_TEMPERATURE_MASK |	\
   1019 			      R200_CLAMP_S_MASK | 		\
   1020 			      R200_CLAMP_T_MASK | 		\
   1021 			      R200_BORDER_MODE_D3D )
   1022 
   1023 #define TEXOBJ_TXFORMAT_MASK (R200_TXFORMAT_WIDTH_MASK |	\
   1024 			      R200_TXFORMAT_HEIGHT_MASK |	\
   1025 			      R200_TXFORMAT_FORMAT_MASK |	\
   1026 			      R200_TXFORMAT_F5_WIDTH_MASK |	\
   1027 			      R200_TXFORMAT_F5_HEIGHT_MASK |	\
   1028 			      R200_TXFORMAT_ALPHA_IN_MAP |	\
   1029 			      R200_TXFORMAT_CUBIC_MAP_ENABLE |	\
   1030 			      R200_TXFORMAT_NON_POWER2)
   1031 
   1032 #define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK |		\
   1033                                 R200_TEXCOORD_MASK |		\
   1034                                 R200_MIN_MIP_LEVEL_MASK |	\
   1035                                 R200_CLAMP_Q_MASK | 		\
   1036                                 R200_VOLUME_FILTER_MASK)
   1037 
   1038 
   1039 static void disable_tex_obj_state( r200ContextPtr rmesa,
   1040 				   int unit )
   1041 {
   1042 
   1043    R200_STATECHANGE( rmesa, vtx );
   1044    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
   1045 
   1046    R200_STATECHANGE( rmesa, ctx );
   1047    rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_TEX_0_ENABLE << unit);
   1048    if (rmesa->radeon.TclFallback & (R200_TCL_FALLBACK_TEXGEN_0<<unit)) {
   1049       TCL_FALLBACK( rmesa->radeon.glCtx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
   1050    }
   1051 
   1052    /* Actually want to keep all units less than max active texture
   1053     * enabled, right?  Fix this for >2 texunits.
   1054     */
   1055 
   1056    {
   1057       GLuint tmp = rmesa->TexGenEnabled;
   1058 
   1059       rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
   1060       rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
   1061       rmesa->TexGenNeedNormals[unit] = GL_FALSE;
   1062       rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
   1063 
   1064       if (tmp != rmesa->TexGenEnabled) {
   1065 	 rmesa->recheck_texgen[unit] = GL_TRUE;
   1066 	 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
   1067       }
   1068    }
   1069 }
   1070 static void import_tex_obj_state( r200ContextPtr rmesa,
   1071 				  int unit,
   1072 				  radeonTexObjPtr texobj )
   1073 {
   1074 /* do not use RADEON_DB_STATE to avoid stale texture caches */
   1075    GLuint *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
   1076 
   1077    R200_STATECHANGE( rmesa, tex[unit] );
   1078 
   1079    cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK;
   1080    cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK;
   1081    cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
   1082    cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK;
   1083    cmd[TEX_PP_TXFORMAT_X] &= ~TEXOBJ_TXFORMAT_X_MASK;
   1084    cmd[TEX_PP_TXFORMAT_X] |= texobj->pp_txformat_x & TEXOBJ_TXFORMAT_X_MASK;
   1085    cmd[TEX_PP_TXSIZE] = texobj->pp_txsize; /* NPOT only! */
   1086    cmd[TEX_PP_TXPITCH] = texobj->pp_txpitch; /* NPOT only! */
   1087    cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
   1088 
   1089    if (texobj->base.Target == GL_TEXTURE_CUBE_MAP) {
   1090       GLuint *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
   1091 
   1092       R200_STATECHANGE( rmesa, cube[unit] );
   1093       cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
   1094       /* that value is submitted twice. could change cube atom
   1095          to not include that command when new drm is used */
   1096       cmd[TEX_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
   1097    }
   1098 
   1099 }
   1100 
   1101 static void set_texgen_matrix( r200ContextPtr rmesa,
   1102 			       GLuint unit,
   1103 			       const GLfloat *s_plane,
   1104 			       const GLfloat *t_plane,
   1105 			       const GLfloat *r_plane,
   1106 			       const GLfloat *q_plane )
   1107 {
   1108    GLfloat m[16];
   1109 
   1110    m[0]  = s_plane[0];
   1111    m[4]  = s_plane[1];
   1112    m[8]  = s_plane[2];
   1113    m[12] = s_plane[3];
   1114 
   1115    m[1]  = t_plane[0];
   1116    m[5]  = t_plane[1];
   1117    m[9]  = t_plane[2];
   1118    m[13] = t_plane[3];
   1119 
   1120    m[2]  = r_plane[0];
   1121    m[6]  = r_plane[1];
   1122    m[10] = r_plane[2];
   1123    m[14] = r_plane[3];
   1124 
   1125    m[3]  = q_plane[0];
   1126    m[7]  = q_plane[1];
   1127    m[11] = q_plane[2];
   1128    m[15] = q_plane[3];
   1129 
   1130    _math_matrix_loadf( &(rmesa->TexGenMatrix[unit]), m);
   1131    _math_matrix_analyse( &(rmesa->TexGenMatrix[unit]) );
   1132    rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit;
   1133 }
   1134 
   1135 
   1136 static GLuint r200_need_dis_texgen(const GLbitfield texGenEnabled,
   1137 				   const GLfloat *planeS,
   1138 				   const GLfloat *planeT,
   1139 				   const GLfloat *planeR,
   1140 				   const GLfloat *planeQ)
   1141 {
   1142    GLuint needtgenable = 0;
   1143 
   1144    if (!(texGenEnabled & S_BIT)) {
   1145       if (((texGenEnabled & T_BIT) && planeT[0] != 0.0) ||
   1146 	 ((texGenEnabled & R_BIT) && planeR[0] != 0.0) ||
   1147 	 ((texGenEnabled & Q_BIT) && planeQ[0] != 0.0)) {
   1148 	 needtgenable |= S_BIT;
   1149       }
   1150    }
   1151    if (!(texGenEnabled & T_BIT)) {
   1152       if (((texGenEnabled & S_BIT) && planeS[1] != 0.0) ||
   1153 	 ((texGenEnabled & R_BIT) && planeR[1] != 0.0) ||
   1154 	 ((texGenEnabled & Q_BIT) && planeQ[1] != 0.0)) {
   1155 	 needtgenable |= T_BIT;
   1156      }
   1157    }
   1158    if (!(texGenEnabled & R_BIT)) {
   1159       if (((texGenEnabled & S_BIT) && planeS[2] != 0.0) ||
   1160 	 ((texGenEnabled & T_BIT) && planeT[2] != 0.0) ||
   1161 	 ((texGenEnabled & Q_BIT) && planeQ[2] != 0.0)) {
   1162 	 needtgenable |= R_BIT;
   1163       }
   1164    }
   1165    if (!(texGenEnabled & Q_BIT)) {
   1166       if (((texGenEnabled & S_BIT) && planeS[3] != 0.0) ||
   1167 	 ((texGenEnabled & T_BIT) && planeT[3] != 0.0) ||
   1168 	 ((texGenEnabled & R_BIT) && planeR[3] != 0.0)) {
   1169 	 needtgenable |= Q_BIT;
   1170       }
   1171    }
   1172 
   1173    return needtgenable;
   1174 }
   1175 
   1176 
   1177 /*
   1178  * Returns GL_FALSE if fallback required.
   1179  */
   1180 static GLboolean r200_validate_texgen( struct gl_context *ctx, GLuint unit )
   1181 {
   1182    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1183    const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
   1184    GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit*4;
   1185    GLuint tgi, tgcm;
   1186    GLuint mode = 0;
   1187    GLboolean mixed_fallback = GL_FALSE;
   1188    static const GLfloat I[16] = {
   1189       1,  0,  0,  0,
   1190       0,  1,  0,  0,
   1191       0,  0,  1,  0,
   1192       0,  0,  0,  1 };
   1193    static const GLfloat reflect[16] = {
   1194       -1,  0,  0,  0,
   1195        0, -1,  0,  0,
   1196        0,  0,  -1, 0,
   1197        0,  0,  0,  1 };
   1198 
   1199    rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
   1200    rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
   1201    rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
   1202    rmesa->TexGenNeedNormals[unit] = GL_FALSE;
   1203    tgi = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] & ~(R200_TEXGEN_INPUT_MASK <<
   1204 						   inputshift);
   1205    tgcm = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] & ~(R200_TEXGEN_COMP_MASK <<
   1206 						    (unit * 4));
   1207 
   1208    if (0)
   1209       fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit);
   1210 
   1211    if (texUnit->TexGenEnabled & S_BIT) {
   1212       mode = texUnit->GenS.Mode;
   1213    } else {
   1214       tgcm |= R200_TEXGEN_COMP_S << (unit * 4);
   1215    }
   1216 
   1217    if (texUnit->TexGenEnabled & T_BIT) {
   1218       if (texUnit->GenT.Mode != mode)
   1219 	 mixed_fallback = GL_TRUE;
   1220    } else {
   1221       tgcm |= R200_TEXGEN_COMP_T << (unit * 4);
   1222    }
   1223    if (texUnit->TexGenEnabled & R_BIT) {
   1224       if (texUnit->GenR.Mode != mode)
   1225 	 mixed_fallback = GL_TRUE;
   1226    } else {
   1227       tgcm |= R200_TEXGEN_COMP_R << (unit * 4);
   1228    }
   1229 
   1230    if (texUnit->TexGenEnabled & Q_BIT) {
   1231       if (texUnit->GenQ.Mode != mode)
   1232 	 mixed_fallback = GL_TRUE;
   1233    } else {
   1234       tgcm |= R200_TEXGEN_COMP_Q << (unit * 4);
   1235    }
   1236 
   1237    if (mixed_fallback) {
   1238       if (R200_DEBUG & RADEON_FALLBACKS)
   1239 	 fprintf(stderr, "fallback mixed texgen, 0x%x (0x%x 0x%x 0x%x 0x%x)\n",
   1240 		 texUnit->TexGenEnabled, texUnit->GenS.Mode, texUnit->GenT.Mode,
   1241 		 texUnit->GenR.Mode, texUnit->GenQ.Mode);
   1242       return GL_FALSE;
   1243    }
   1244 
   1245 /* we CANNOT do mixed mode if the texgen mode requires a plane where the input
   1246    is not enabled for texgen, since the planes are concatenated into texmat,
   1247    and thus the input will come from texcoord rather than tex gen equation!
   1248    Either fallback or just hope that those texcoords aren't really needed...
   1249    Assuming the former will cause lots of unnecessary fallbacks, the latter will
   1250    generate bogus results sometimes - it's pretty much impossible to really know
   1251    when a fallback is needed, depends on texmat and what sort of texture is bound
   1252    etc, - for now fallback if we're missing either S or T bits, there's a high
   1253    probability we need the texcoords in that case.
   1254    That's a lot of work for some obscure texgen mixed mode fixup - why oh why
   1255    doesn't the chip just directly accept the plane parameters :-(. */
   1256    switch (mode) {
   1257    case GL_OBJECT_LINEAR: {
   1258       GLuint needtgenable = r200_need_dis_texgen( texUnit->TexGenEnabled,
   1259                                                   texUnit->GenS.ObjectPlane,
   1260                                                   texUnit->GenT.ObjectPlane,
   1261                                                   texUnit->GenR.ObjectPlane,
   1262                                                   texUnit->GenQ.ObjectPlane );
   1263       if (needtgenable & (S_BIT | T_BIT)) {
   1264 	 if (R200_DEBUG & RADEON_FALLBACKS)
   1265 	 fprintf(stderr, "fallback mixed texgen / obj plane, 0x%x\n",
   1266 		 texUnit->TexGenEnabled);
   1267 	 return GL_FALSE;
   1268       }
   1269       if (needtgenable & (R_BIT)) {
   1270 	 tgcm &= ~(R200_TEXGEN_COMP_R << (unit * 4));
   1271       }
   1272       if (needtgenable & (Q_BIT)) {
   1273 	 tgcm &= ~(R200_TEXGEN_COMP_Q << (unit * 4));
   1274       }
   1275 
   1276       tgi |= R200_TEXGEN_INPUT_OBJ << inputshift;
   1277       set_texgen_matrix( rmesa, unit,
   1278 	 (texUnit->TexGenEnabled & S_BIT) ? texUnit->GenS.ObjectPlane : I,
   1279 	 (texUnit->TexGenEnabled & T_BIT) ? texUnit->GenT.ObjectPlane : I + 4,
   1280 	 (texUnit->TexGenEnabled & R_BIT) ? texUnit->GenR.ObjectPlane : I + 8,
   1281 	 (texUnit->TexGenEnabled & Q_BIT) ? texUnit->GenQ.ObjectPlane : I + 12);
   1282       }
   1283       break;
   1284 
   1285    case GL_EYE_LINEAR: {
   1286       GLuint needtgenable = r200_need_dis_texgen( texUnit->TexGenEnabled,
   1287                                                   texUnit->GenS.EyePlane,
   1288                                                   texUnit->GenT.EyePlane,
   1289                                                   texUnit->GenR.EyePlane,
   1290                                                   texUnit->GenQ.EyePlane );
   1291       if (needtgenable & (S_BIT | T_BIT)) {
   1292 	 if (R200_DEBUG & RADEON_FALLBACKS)
   1293 	 fprintf(stderr, "fallback mixed texgen / eye plane, 0x%x\n",
   1294 		 texUnit->TexGenEnabled);
   1295 	 return GL_FALSE;
   1296       }
   1297       if (needtgenable & (R_BIT)) {
   1298 	 tgcm &= ~(R200_TEXGEN_COMP_R << (unit * 4));
   1299       }
   1300       if (needtgenable & (Q_BIT)) {
   1301 	 tgcm &= ~(R200_TEXGEN_COMP_Q << (unit * 4));
   1302       }
   1303       tgi |= R200_TEXGEN_INPUT_EYE << inputshift;
   1304       set_texgen_matrix( rmesa, unit,
   1305 	 (texUnit->TexGenEnabled & S_BIT) ? texUnit->GenS.EyePlane : I,
   1306 	 (texUnit->TexGenEnabled & T_BIT) ? texUnit->GenT.EyePlane : I + 4,
   1307 	 (texUnit->TexGenEnabled & R_BIT) ? texUnit->GenR.EyePlane : I + 8,
   1308 	 (texUnit->TexGenEnabled & Q_BIT) ? texUnit->GenQ.EyePlane : I + 12);
   1309       }
   1310       break;
   1311 
   1312    case GL_REFLECTION_MAP_NV:
   1313       rmesa->TexGenNeedNormals[unit] = GL_TRUE;
   1314       tgi |= R200_TEXGEN_INPUT_EYE_REFLECT << inputshift;
   1315       /* pretty weird, must only negate when lighting is enabled? */
   1316       if (ctx->Light.Enabled)
   1317 	 set_texgen_matrix( rmesa, unit,
   1318 	    (texUnit->TexGenEnabled & S_BIT) ? reflect : I,
   1319 	    (texUnit->TexGenEnabled & T_BIT) ? reflect + 4 : I + 4,
   1320 	    (texUnit->TexGenEnabled & R_BIT) ? reflect + 8 : I + 8,
   1321 	    I + 12);
   1322       break;
   1323 
   1324    case GL_NORMAL_MAP_NV:
   1325       rmesa->TexGenNeedNormals[unit] = GL_TRUE;
   1326       tgi |= R200_TEXGEN_INPUT_EYE_NORMAL<<inputshift;
   1327       break;
   1328 
   1329    case GL_SPHERE_MAP:
   1330       rmesa->TexGenNeedNormals[unit] = GL_TRUE;
   1331       tgi |= R200_TEXGEN_INPUT_SPHERE<<inputshift;
   1332       break;
   1333 
   1334    case 0:
   1335       /* All texgen units were disabled, so just pass coords through. */
   1336       tgi |= unit << inputshift;
   1337       break;
   1338 
   1339    default:
   1340       /* Unsupported mode, fallback:
   1341        */
   1342       if (R200_DEBUG & RADEON_FALLBACKS)
   1343 	 fprintf(stderr, "fallback unsupported texgen, %d\n",
   1344 		 texUnit->GenS.Mode);
   1345       return GL_FALSE;
   1346    }
   1347 
   1348    rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
   1349    rmesa->TexGenCompSel |= R200_OUTPUT_TEX_0 << unit;
   1350 
   1351    if (tgi != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] ||
   1352        tgcm != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2])
   1353    {
   1354       R200_STATECHANGE(rmesa, tcg);
   1355       rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] = tgi;
   1356       rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] = tgcm;
   1357    }
   1358 
   1359    return GL_TRUE;
   1360 }
   1361 
   1362 void set_re_cntl_d3d( struct gl_context *ctx, int unit, GLboolean use_d3d )
   1363 {
   1364    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1365 
   1366    GLuint re_cntl;
   1367 
   1368    re_cntl = rmesa->hw.set.cmd[SET_RE_CNTL] & ~(R200_VTX_STQ0_D3D << (2 * unit));
   1369    if (use_d3d)
   1370       re_cntl |= R200_VTX_STQ0_D3D << (2 * unit);
   1371 
   1372    if ( re_cntl != rmesa->hw.set.cmd[SET_RE_CNTL] ) {
   1373       R200_STATECHANGE( rmesa, set );
   1374       rmesa->hw.set.cmd[SET_RE_CNTL] = re_cntl;
   1375    }
   1376 }
   1377 
   1378 /**
   1379  * Compute the cached hardware register values for the given texture object.
   1380  *
   1381  * \param rmesa Context pointer
   1382  * \param t the r300 texture object
   1383  */
   1384 static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t)
   1385 {
   1386    const struct gl_texture_image *firstImage = t->base.Image[0][t->minLod];
   1387    GLint log2Width, log2Height, log2Depth, texelBytes;
   1388    uint extra_size = 0;
   1389 
   1390    if ( t->bo ) {
   1391        return;
   1392    }
   1393 
   1394    log2Width  = firstImage->WidthLog2;
   1395    log2Height = firstImage->HeightLog2;
   1396    log2Depth  = firstImage->DepthLog2;
   1397    texelBytes = _mesa_get_format_bytes(firstImage->TexFormat);
   1398 
   1399    radeon_print(RADEON_TEXTURE, RADEON_TRACE,
   1400 	"%s(%p, tex %p) log2(w %d, h %d, d %d), texelBytes %d. format %d\n",
   1401 	__func__, rmesa, t, log2Width, log2Height,
   1402 	log2Depth, texelBytes, firstImage->TexFormat);
   1403 
   1404    if (!t->image_override) {
   1405       if (VALID_FORMAT(firstImage->TexFormat)) {
   1406 	 const struct tx_table *table = _mesa_little_endian() ? tx_table_le :
   1407 	    tx_table_be;
   1408 
   1409 	 t->pp_txformat &= ~(R200_TXFORMAT_FORMAT_MASK |
   1410 			     R200_TXFORMAT_ALPHA_IN_MAP);
   1411 	 t->pp_txfilter &= ~R200_YUV_TO_RGB;
   1412 
   1413 	 t->pp_txformat |= table[ firstImage->TexFormat ].format;
   1414 	 t->pp_txfilter |= table[ firstImage->TexFormat ].filter;
   1415 
   1416 
   1417       } else {
   1418 	 _mesa_problem(NULL, "unexpected texture format in %s",
   1419 		       __FUNCTION__);
   1420 	 return;
   1421       }
   1422    }
   1423 
   1424    t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK;
   1425    t->pp_txfilter |= ((t->maxLod) << R200_MAX_MIP_LEVEL_SHIFT)
   1426 	   & R200_MAX_MIP_LEVEL_MASK;
   1427 
   1428    if ( t->pp_txfilter &
   1429 		(R200_MIN_FILTER_NEAREST_MIP_NEAREST
   1430 		 | R200_MIN_FILTER_NEAREST_MIP_LINEAR
   1431 		 | R200_MIN_FILTER_LINEAR_MIP_NEAREST
   1432 		 | R200_MIN_FILTER_LINEAR_MIP_LINEAR
   1433 		 | R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST
   1434 		 | R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR))
   1435 		 extra_size = t->minLod;
   1436 
   1437    t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
   1438 		       R200_TXFORMAT_HEIGHT_MASK |
   1439 		       R200_TXFORMAT_CUBIC_MAP_ENABLE |
   1440 		       R200_TXFORMAT_F5_WIDTH_MASK |
   1441 		       R200_TXFORMAT_F5_HEIGHT_MASK);
   1442    t->pp_txformat |= (((log2Width + extra_size) << R200_TXFORMAT_WIDTH_SHIFT) |
   1443 		      ((log2Height + extra_size)<< R200_TXFORMAT_HEIGHT_SHIFT));
   1444 
   1445    t->tile_bits = 0;
   1446 
   1447    t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK
   1448 		   | R200_MIN_MIP_LEVEL_MASK);
   1449 
   1450    t->pp_txformat_x |= (t->minLod << R200_MIN_MIP_LEVEL_SHIFT)
   1451 	   & R200_MIN_MIP_LEVEL_MASK;
   1452 
   1453    if (t->base.Target == GL_TEXTURE_3D) {
   1454       t->pp_txformat_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT);
   1455       t->pp_txformat_x |= R200_TEXCOORD_VOLUME;
   1456 
   1457    }
   1458    else if (t->base.Target == GL_TEXTURE_CUBE_MAP) {
   1459       ASSERT(log2Width == log2Height);
   1460       t->pp_txformat |= ((log2Width << R200_TXFORMAT_F5_WIDTH_SHIFT) |
   1461 			 (log2Height << R200_TXFORMAT_F5_HEIGHT_SHIFT) |
   1462 			 /* don't think we need this bit, if it exists at all - fglrx does not set it */
   1463 			 (R200_TXFORMAT_CUBIC_MAP_ENABLE));
   1464       t->pp_txformat_x |= R200_TEXCOORD_CUBIC_ENV;
   1465       t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) |
   1466                            (log2Height << R200_FACE_HEIGHT_1_SHIFT) |
   1467                            (log2Width << R200_FACE_WIDTH_2_SHIFT) |
   1468                            (log2Height << R200_FACE_HEIGHT_2_SHIFT) |
   1469                            (log2Width << R200_FACE_WIDTH_3_SHIFT) |
   1470                            (log2Height << R200_FACE_HEIGHT_3_SHIFT) |
   1471                            (log2Width << R200_FACE_WIDTH_4_SHIFT) |
   1472                            (log2Height << R200_FACE_HEIGHT_4_SHIFT));
   1473    }
   1474    else {
   1475       /* If we don't in fact send enough texture coordinates, q will be 1,
   1476        * making TEXCOORD_PROJ act like TEXCOORD_NONPROJ (Right?)
   1477        */
   1478       t->pp_txformat_x |= R200_TEXCOORD_PROJ;
   1479    }
   1480    /* FIXME: NPOT sizes, Is it correct realy? */
   1481    t->pp_txsize = (((firstImage->Width - 1) << R200_PP_TX_WIDTHMASK_SHIFT)
   1482 		   | ((firstImage->Height - 1) << R200_PP_TX_HEIGHTMASK_SHIFT));
   1483 
   1484    if ( !t->image_override ) {
   1485       if (_mesa_is_format_compressed(firstImage->TexFormat))
   1486          t->pp_txpitch = (firstImage->Width + 63) & ~(63);
   1487       else
   1488          t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63);
   1489       t->pp_txpitch -= 32;
   1490    }
   1491 
   1492    if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
   1493       t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
   1494    }
   1495 
   1496 }
   1497 
   1498 static GLboolean r200_validate_texture(struct gl_context *ctx, struct gl_texture_object *texObj, int unit)
   1499 {
   1500    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1501    radeonTexObj *t = radeon_tex_obj(texObj);
   1502 
   1503    if (!radeon_validate_texture_miptree(ctx, _mesa_get_samplerobj(ctx, unit), texObj))
   1504       return GL_FALSE;
   1505 
   1506    r200_validate_texgen(ctx, unit);
   1507    /* Configure the hardware registers (more precisely, the cached version
   1508     * of the hardware registers). */
   1509    setup_hardware_state(rmesa, t);
   1510 
   1511    if (texObj->Target == GL_TEXTURE_RECTANGLE_NV ||
   1512        texObj->Target == GL_TEXTURE_2D ||
   1513        texObj->Target == GL_TEXTURE_1D)
   1514       set_re_cntl_d3d( ctx, unit, GL_FALSE );
   1515    else
   1516       set_re_cntl_d3d( ctx, unit, GL_TRUE );
   1517    R200_STATECHANGE( rmesa, ctx );
   1518    rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << unit;
   1519 
   1520    R200_STATECHANGE( rmesa, vtx );
   1521    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
   1522    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3);
   1523 
   1524    rmesa->recheck_texgen[unit] = GL_TRUE;
   1525    r200TexUpdateParameters(ctx, unit);
   1526    import_tex_obj_state( rmesa, unit, t );
   1527 
   1528    if (rmesa->recheck_texgen[unit]) {
   1529       GLboolean fallback = !r200_validate_texgen( ctx, unit );
   1530       TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
   1531       rmesa->recheck_texgen[unit] = 0;
   1532       rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
   1533    }
   1534 
   1535    t->validated = GL_TRUE;
   1536 
   1537    FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback );
   1538 
   1539    return !t->border_fallback;
   1540 }
   1541 
   1542 static GLboolean r200UpdateTextureUnit(struct gl_context *ctx, int unit)
   1543 {
   1544    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1545    GLuint unitneeded = rmesa->state.texture.unit[unit].unitneeded;
   1546 
   1547    if (!unitneeded) {
   1548       /* disable the unit */
   1549      disable_tex_obj_state(rmesa, unit);
   1550      return GL_TRUE;
   1551    }
   1552 
   1553    if (!r200_validate_texture(ctx, ctx->Texture.Unit[unit]._Current, unit)) {
   1554     _mesa_warning(ctx,
   1555 		  "failed to validate texture for unit %d.\n",
   1556 		  unit);
   1557     rmesa->state.texture.unit[unit].texobj = NULL;
   1558     return GL_FALSE;
   1559   }
   1560 
   1561    rmesa->state.texture.unit[unit].texobj = radeon_tex_obj(ctx->Texture.Unit[unit]._Current);
   1562   return GL_TRUE;
   1563 }
   1564 
   1565 
   1566 void r200UpdateTextureState( struct gl_context *ctx )
   1567 {
   1568    r200ContextPtr rmesa = R200_CONTEXT(ctx);
   1569    GLboolean ok;
   1570    GLuint dbg;
   1571 
   1572    /* NOTE: must not manipulate rmesa->state.texture.unit[].unitneeded or
   1573       rmesa->state.envneeded before a R200_STATECHANGE (or R200_NEWPRIM) since
   1574       we use these to determine if we want to emit the corresponding state
   1575       atoms. */
   1576    R200_NEWPRIM( rmesa );
   1577 
   1578    if (ctx->ATIFragmentShader._Enabled) {
   1579       GLuint i;
   1580       for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) {
   1581 	 rmesa->state.texture.unit[i].unitneeded = ctx->Texture.Unit[i]._ReallyEnabled;
   1582       }
   1583       ok = GL_TRUE;
   1584    }
   1585    else {
   1586       ok = r200UpdateAllTexEnv( ctx );
   1587    }
   1588    if (ok) {
   1589       ok = (r200UpdateTextureUnit( ctx, 0 ) &&
   1590 	 r200UpdateTextureUnit( ctx, 1 ) &&
   1591 	 r200UpdateTextureUnit( ctx, 2 ) &&
   1592 	 r200UpdateTextureUnit( ctx, 3 ) &&
   1593 	 r200UpdateTextureUnit( ctx, 4 ) &&
   1594 	 r200UpdateTextureUnit( ctx, 5 ));
   1595    }
   1596 
   1597    if (ok && ctx->ATIFragmentShader._Enabled) {
   1598       r200UpdateFragmentShader(ctx);
   1599    }
   1600 
   1601    FALLBACK( rmesa, R200_FALLBACK_TEXTURE, !ok );
   1602 
   1603    if (rmesa->radeon.TclFallback)
   1604       r200ChooseVertexState( ctx );
   1605 
   1606 
   1607    if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) {
   1608 
   1609       /*
   1610        * T0 hang workaround -------------
   1611        * not needed for r200 derivatives
   1612         */
   1613       if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_ENABLE_MASK) == R200_TEX_0_ENABLE &&
   1614 	 (rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > R200_MIN_FILTER_LINEAR) {
   1615 
   1616 	 R200_STATECHANGE(rmesa, ctx);
   1617 	 R200_STATECHANGE(rmesa, tex[1]);
   1618 	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_1_ENABLE;
   1619 	 if (!(rmesa->hw.cst.cmd[CST_PP_CNTL_X] & R200_PPX_TEX_1_ENABLE))
   1620 	   rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
   1621 	 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] |= R200_TXFORMAT_LOOKUP_DISABLE;
   1622       }
   1623       else if (!ctx->ATIFragmentShader._Enabled) {
   1624 	 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE) &&
   1625 	    (rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] & R200_TXFORMAT_LOOKUP_DISABLE)) {
   1626 	    R200_STATECHANGE(rmesa, tex[1]);
   1627 	    rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~R200_TXFORMAT_LOOKUP_DISABLE;
   1628          }
   1629       }
   1630       /* do the same workaround for the first pass of a fragment shader.
   1631        * completely unknown if necessary / sufficient.
   1632        */
   1633       if ((rmesa->hw.cst.cmd[CST_PP_CNTL_X] & R200_PPX_TEX_ENABLE_MASK) == R200_PPX_TEX_0_ENABLE &&
   1634 	 (rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > R200_MIN_FILTER_LINEAR) {
   1635 
   1636 	 R200_STATECHANGE(rmesa, cst);
   1637 	 R200_STATECHANGE(rmesa, tex[1]);
   1638 	 rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_1_ENABLE;
   1639 	 if (!(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE))
   1640 	    rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
   1641 	 rmesa->hw.tex[1].cmd[TEX_PP_TXMULTI_CTL] |= R200_PASS1_TXFORMAT_LOOKUP_DISABLE;
   1642       }
   1643 
   1644       /* maybe needs to be done pairwise due to 2 parallel (physical) tex units ?
   1645          looks like that's not the case, if 8500/9100 owners don't complain remove this...
   1646       for ( i = 0; i < ctx->Const.MaxTextureUnits; i += 2) {
   1647          if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & ((R200_TEX_0_ENABLE |
   1648             R200_TEX_1_ENABLE ) << i)) == (R200_TEX_0_ENABLE << i)) &&
   1649             ((rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) >
   1650             R200_MIN_FILTER_LINEAR)) {
   1651             R200_STATECHANGE(rmesa, ctx);
   1652             R200_STATECHANGE(rmesa, tex[i+1]);
   1653             rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_1_ENABLE << i);
   1654             rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
   1655             rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] |= 0x08000000;
   1656          }
   1657          else {
   1658             if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE << i)) &&
   1659                (rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] & 0x08000000)) {
   1660                R200_STATECHANGE(rmesa, tex[i+1]);
   1661                rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~0x08000000;
   1662             }
   1663          }
   1664       } */
   1665 
   1666       /*
   1667        * Texture cache LRU hang workaround -------------
   1668        * not needed for r200 derivatives
   1669        * hopefully this covers first pass of a shader as well
   1670        */
   1671 
   1672       /* While the cases below attempt to only enable the workaround in the
   1673        * specific cases necessary, they were insufficient.  See bugzilla #1519,
   1674        * #729, #814.  Tests with quake3 showed no impact on performance.
   1675        */
   1676       dbg = 0x6;
   1677 
   1678       /*
   1679       if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE )) &&
   1680          ((((rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
   1681          0x04) == 0)) ||
   1682          ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_2_ENABLE) &&
   1683          ((((rmesa->hw.tex[2].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
   1684          0x04) == 0)) ||
   1685          ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_4_ENABLE) &&
   1686          ((((rmesa->hw.tex[4].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
   1687          0x04) == 0)))
   1688       {
   1689          dbg |= 0x02;
   1690       }
   1691 
   1692       if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE )) &&
   1693          ((((rmesa->hw.tex[1].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
   1694          0x04) == 0)) ||
   1695          ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_3_ENABLE) &&
   1696          ((((rmesa->hw.tex[3].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
   1697          0x04) == 0)) ||
   1698          ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_5_ENABLE) &&
   1699          ((((rmesa->hw.tex[5].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
   1700          0x04) == 0)))
   1701       {
   1702          dbg |= 0x04;
   1703       }*/
   1704 
   1705       if (dbg != rmesa->hw.tam.cmd[TAM_DEBUG3]) {
   1706          R200_STATECHANGE( rmesa, tam );
   1707          rmesa->hw.tam.cmd[TAM_DEBUG3] = dbg;
   1708          if (0) printf("TEXCACHE LRU HANG WORKAROUND %x\n", dbg);
   1709       }
   1710    }
   1711 }
   1712