Home | History | Annotate | Download | only in r200
      1 /**************************************************************************
      2  *
      3  * Copyright 2004 David Airlie
      4  * All Rights Reserved.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the
      8  * "Software"), to deal in the Software without restriction, including
      9  * without limitation the rights to use, copy, modify, merge, publish,
     10  * distribute, sub license, and/or sell copies of the Software, and to
     11  * permit persons to whom the Software is furnished to do so, subject to
     12  * the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the
     15  * next paragraph) shall be included in all copies or substantial portions
     16  * of the Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     21  * IN NO EVENT SHALL DAVID AIRLIE AND/OR ITS SUPPLIERS BE LIABLE FOR
     22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  *
     26  **************************************************************************/
     27 
     28 #include "main/glheader.h"
     29 #include "main/atifragshader.h"
     30 #include "main/macros.h"
     31 #include "main/enums.h"
     32 #include "tnl/t_context.h"
     33 #include "program/program.h"
     34 #include "r200_context.h"
     35 #include "r200_ioctl.h"
     36 #include "r200_tex.h"
     37 
     38 #define SET_INST(inst, type) afs_cmd[((inst<<2) + (type<<1) + 1)]
     39 #define SET_INST_2(inst, type) afs_cmd[((inst<<2) + (type<<1) + 2)]
     40 
     41 static void r200SetFragShaderArg( GLuint *afs_cmd, GLuint opnum, GLuint optype,
     42 				const struct atifragshader_src_register srcReg,
     43 				GLuint argPos, GLuint *tfactor )
     44 {
     45    const GLuint index = srcReg.Index;
     46    const GLuint srcmod = srcReg.argMod;
     47    const GLuint srcrep = srcReg.argRep;
     48    GLuint reg0 = 0;
     49    GLuint reg2 = 0;
     50    GLuint useOddSrc = 0;
     51 
     52    switch(srcrep) {
     53    case GL_RED:
     54       reg2 |= R200_TXC_REPL_RED << (R200_TXC_REPL_ARG_A_SHIFT + (2*argPos));
     55       if (optype)
     56 	 useOddSrc = 1;
     57       break;
     58    case GL_GREEN:
     59       reg2 |= R200_TXC_REPL_GREEN << (R200_TXC_REPL_ARG_A_SHIFT + (2*argPos));
     60       if (optype)
     61 	 useOddSrc = 1;
     62       break;
     63    case GL_BLUE:
     64       if (!optype)
     65 	 reg2 |= R200_TXC_REPL_BLUE << (R200_TXC_REPL_ARG_A_SHIFT + (2*argPos));
     66       else
     67 	 useOddSrc = 1;
     68       break;
     69    case GL_ALPHA:
     70       if (!optype)
     71 	 useOddSrc = 1;
     72       break;
     73    }
     74 
     75    if (index >= GL_REG_0_ATI && index <= GL_REG_5_ATI)
     76       reg0 |= (((index - GL_REG_0_ATI)*2) + 10 + useOddSrc) << (5*argPos);
     77    else if (index >= GL_CON_0_ATI && index <= GL_CON_7_ATI) {
     78       if ((*tfactor == 0) || (index == *tfactor)) {
     79 	 reg0 |= (R200_TXC_ARG_A_TFACTOR_COLOR + useOddSrc) << (5*argPos);
     80 	 reg2 |= (index - GL_CON_0_ATI) << R200_TXC_TFACTOR_SEL_SHIFT;
     81 	 *tfactor = index;
     82       }
     83       else {
     84 	 reg0 |= (R200_TXC_ARG_A_TFACTOR1_COLOR + useOddSrc) << (5*argPos);
     85 	 reg2 |= (index - GL_CON_0_ATI) << R200_TXC_TFACTOR1_SEL_SHIFT;
     86       }
     87    }
     88    else if (index == GL_PRIMARY_COLOR_EXT) {
     89       reg0 |= (R200_TXC_ARG_A_DIFFUSE_COLOR + useOddSrc) << (5*argPos);
     90    }
     91    else if (index == GL_SECONDARY_INTERPOLATOR_ATI) {
     92       reg0 |= (R200_TXC_ARG_A_SPECULAR_COLOR + useOddSrc) << (5*argPos);
     93    }
     94    /* GL_ZERO is a noop, for GL_ONE we set the complement */
     95    else if (index == GL_ONE) {
     96       reg0 |= R200_TXC_COMP_ARG_A << (4*argPos);
     97    }
     98 
     99    if (srcmod & GL_COMP_BIT_ATI)
    100       reg0 ^= R200_TXC_COMP_ARG_A << (4*argPos);
    101    if (srcmod & GL_BIAS_BIT_ATI)
    102       reg0 |= R200_TXC_BIAS_ARG_A << (4*argPos);
    103    if (srcmod & GL_2X_BIT_ATI)
    104       reg0 |= R200_TXC_SCALE_ARG_A << (4*argPos);
    105    if (srcmod & GL_NEGATE_BIT_ATI)
    106       reg0 ^= R200_TXC_NEG_ARG_A << (4*argPos);
    107 
    108    SET_INST(opnum, optype) |= reg0;
    109    SET_INST_2(opnum, optype) |= reg2;
    110 }
    111 
    112 static GLuint dstmask_table[8] =
    113 {
    114    R200_TXC_OUTPUT_MASK_RGB,
    115    R200_TXC_OUTPUT_MASK_R,
    116    R200_TXC_OUTPUT_MASK_G,
    117    R200_TXC_OUTPUT_MASK_RG,
    118    R200_TXC_OUTPUT_MASK_B,
    119    R200_TXC_OUTPUT_MASK_RB,
    120    R200_TXC_OUTPUT_MASK_GB,
    121    R200_TXC_OUTPUT_MASK_RGB
    122 };
    123 
    124 static void r200UpdateFSArith( struct gl_context *ctx )
    125 {
    126    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    127    GLuint *afs_cmd;
    128    const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;
    129    GLuint pass;
    130 
    131    R200_STATECHANGE( rmesa, afs[0] );
    132    R200_STATECHANGE( rmesa, afs[1] );
    133 
    134    if (shader->NumPasses < 2) {
    135       afs_cmd = (GLuint *) rmesa->hw.afs[1].cmd;
    136    }
    137    else {
    138       afs_cmd = (GLuint *) rmesa->hw.afs[0].cmd;
    139    }
    140    for (pass = 0; pass < shader->NumPasses; pass++) {
    141       GLuint opnum = 0;
    142       GLuint pc;
    143       for (pc = 0; pc < shader->numArithInstr[pass]; pc++) {
    144          GLuint optype;
    145 	 struct atifs_instruction *inst = &shader->Instructions[pass][pc];
    146 
    147 	 SET_INST(opnum, 0) = 0;
    148 	 SET_INST_2(opnum, 0) = 0;
    149 	 SET_INST(opnum, 1) = 0;
    150 	 SET_INST_2(opnum, 1) = 0;
    151 
    152 	 for (optype = 0; optype < 2; optype++) {
    153 	    GLuint tfactor = 0;
    154 
    155 	    if (inst->Opcode[optype]) {
    156 	       switch (inst->Opcode[optype]) {
    157 	       /* these are all MADD in disguise
    158 		  MADD is A * B + C
    159 		  so for GL_ADD use arg B/C and make A complement 0
    160 		  for GL_SUB use arg B/C, negate C and make A complement 0
    161 		  for GL_MOV use arg C
    162 		  for GL_MUL use arg A
    163 		  for GL_MAD all good */
    164 	       case GL_SUB_ATI:
    165 		  /* negate C */
    166 		  SET_INST(opnum, optype) |= R200_TXC_NEG_ARG_C;
    167 		  /* fallthrough */
    168 	       case GL_ADD_ATI:
    169 		  r200SetFragShaderArg(afs_cmd, opnum, optype,
    170 					inst->SrcReg[optype][0], 1, &tfactor);
    171 		  r200SetFragShaderArg(afs_cmd, opnum, optype,
    172 					inst->SrcReg[optype][1], 2, &tfactor);
    173 		  /* A = complement 0 */
    174 		  SET_INST(opnum, optype) |= R200_TXC_COMP_ARG_A;
    175 		  SET_INST(opnum, optype) |= R200_TXC_OP_MADD;
    176 		  break;
    177 	       case GL_MOV_ATI:
    178 		  /* put arg0 in C */
    179 		  r200SetFragShaderArg(afs_cmd, opnum, optype,
    180 					inst->SrcReg[optype][0], 2, &tfactor);
    181 		  SET_INST(opnum, optype) |= R200_TXC_OP_MADD;
    182 		  break;
    183 	       case GL_MAD_ATI:
    184 		  r200SetFragShaderArg(afs_cmd, opnum, optype,
    185 					inst->SrcReg[optype][2], 2, &tfactor);
    186 		  /* fallthrough */
    187 	       case GL_MUL_ATI:
    188 		  r200SetFragShaderArg(afs_cmd, opnum, optype,
    189 					inst->SrcReg[optype][0], 0, &tfactor);
    190 		  r200SetFragShaderArg(afs_cmd, opnum, optype,
    191 					inst->SrcReg[optype][1], 1, &tfactor);
    192 		  SET_INST(opnum, optype) |= R200_TXC_OP_MADD;
    193 		  break;
    194 	       case GL_LERP_ATI:
    195 		  /* arg order is not native chip order, swap A and C */
    196 		  r200SetFragShaderArg(afs_cmd, opnum, optype,
    197 					inst->SrcReg[optype][0], 2, &tfactor);
    198 		  r200SetFragShaderArg(afs_cmd, opnum, optype,
    199 					inst->SrcReg[optype][1], 1, &tfactor);
    200 		  r200SetFragShaderArg(afs_cmd, opnum, optype,
    201 					inst->SrcReg[optype][2], 0, &tfactor);
    202 		  SET_INST(opnum, optype) |= R200_TXC_OP_LERP;
    203 		  break;
    204 	       case GL_CND_ATI:
    205 		  r200SetFragShaderArg(afs_cmd, opnum, optype,
    206 					inst->SrcReg[optype][0], 0, &tfactor);
    207 		  r200SetFragShaderArg(afs_cmd, opnum, optype,
    208 					inst->SrcReg[optype][1], 1, &tfactor);
    209 		  r200SetFragShaderArg(afs_cmd, opnum, optype,
    210 					inst->SrcReg[optype][2], 2, &tfactor);
    211 		  SET_INST(opnum, optype) |= R200_TXC_OP_CONDITIONAL;
    212 		  break;
    213 	       case GL_CND0_ATI:
    214 		  r200SetFragShaderArg(afs_cmd, opnum, optype,
    215 					inst->SrcReg[optype][0], 0, &tfactor);
    216 		  r200SetFragShaderArg(afs_cmd, opnum, optype,
    217 					inst->SrcReg[optype][1], 1, &tfactor);
    218 		  r200SetFragShaderArg(afs_cmd, opnum, optype,
    219 					inst->SrcReg[optype][2], 2, &tfactor);
    220 		  SET_INST(opnum, optype) |= R200_TXC_OP_CND0;
    221 		  break;
    222 		  /* cannot specify dot ops as alpha ops directly */
    223 	       case GL_DOT2_ADD_ATI:
    224 		  if (optype)
    225 		     SET_INST_2(opnum, 1) |= R200_TXA_DOT_ALPHA;
    226 		  else {
    227 		     r200SetFragShaderArg(afs_cmd, opnum, 0,
    228 					inst->SrcReg[0][0], 0, &tfactor);
    229 		     r200SetFragShaderArg(afs_cmd, opnum, 0,
    230 					inst->SrcReg[0][1], 1, &tfactor);
    231 		     r200SetFragShaderArg(afs_cmd, opnum, 0,
    232 					inst->SrcReg[0][2], 2, &tfactor);
    233 		     SET_INST(opnum, 0) |= R200_TXC_OP_DOT2_ADD;
    234 		  }
    235 		  break;
    236 	       case GL_DOT3_ATI:
    237 		  if (optype)
    238 		     SET_INST_2(opnum, 1) |= R200_TXA_DOT_ALPHA;
    239 		  else {
    240 		     r200SetFragShaderArg(afs_cmd, opnum, 0,
    241 					inst->SrcReg[0][0], 0, &tfactor);
    242 		     r200SetFragShaderArg(afs_cmd, opnum, 0,
    243 					inst->SrcReg[0][1], 1, &tfactor);
    244 		     SET_INST(opnum, 0) |= R200_TXC_OP_DOT3;
    245 		  }
    246 		  break;
    247 	       case GL_DOT4_ATI:
    248 	       /* experimental verification: for dot4 setup of alpha args is needed
    249 		  (dstmod is ignored, though, so dot2/dot3 should be safe)
    250 		  the hardware apparently does R1*R2 + G1*G2 + B1*B2 + A3*A4
    251 		  but the API doesn't allow it */
    252 		  if (optype)
    253 		     SET_INST_2(opnum, 1) |= R200_TXA_DOT_ALPHA;
    254 		  else {
    255 		     r200SetFragShaderArg(afs_cmd, opnum, 0,
    256 					inst->SrcReg[0][0], 0, &tfactor);
    257 		     r200SetFragShaderArg(afs_cmd, opnum, 0,
    258 					inst->SrcReg[0][1], 1, &tfactor);
    259 		     r200SetFragShaderArg(afs_cmd, opnum, 1,
    260 					inst->SrcReg[0][0], 0, &tfactor);
    261 		     r200SetFragShaderArg(afs_cmd, opnum, 1,
    262 					inst->SrcReg[0][1], 1, &tfactor);
    263 		     SET_INST(opnum, optype) |= R200_TXC_OP_DOT4;
    264 		  }
    265 		  break;
    266 	       }
    267 	    }
    268 
    269 	    /* destination */
    270 	    if (inst->DstReg[optype].Index) {
    271 	       GLuint dstreg = inst->DstReg[optype].Index - GL_REG_0_ATI;
    272 	       GLuint dstmask = inst->DstReg[optype].dstMask;
    273 	       GLuint sat = inst->DstReg[optype].dstMod & GL_SATURATE_BIT_ATI;
    274 	       GLuint dstmod = inst->DstReg[optype].dstMod;
    275 
    276 	       dstmod &= ~GL_SATURATE_BIT_ATI;
    277 
    278 	       SET_INST_2(opnum, optype) |= (dstreg + 1) << R200_TXC_OUTPUT_REG_SHIFT;
    279 	       SET_INST_2(opnum, optype) |= dstmask_table[dstmask];
    280 
    281 		/* fglrx does clamp the last instructions to 0_1 it seems */
    282 		/* this won't necessarily catch the last instruction
    283 		   which writes to reg0 */
    284 	       if (sat || (pc == (shader->numArithInstr[pass] - 1) &&
    285 			((pass == 1) || (shader->NumPasses == 1))))
    286 		  SET_INST_2(opnum, optype) |= R200_TXC_CLAMP_0_1;
    287 	       else
    288 		/*should we clamp or not? spec is vague, I would suppose yes but fglrx doesn't */
    289 		  SET_INST_2(opnum, optype) |= R200_TXC_CLAMP_8_8;
    290 /*		  SET_INST_2(opnum, optype) |= R200_TXC_CLAMP_WRAP;*/
    291 	       switch(dstmod) {
    292 	       case GL_2X_BIT_ATI:
    293 		  SET_INST_2(opnum, optype) |= R200_TXC_SCALE_2X;
    294 		  break;
    295 	       case GL_4X_BIT_ATI:
    296 		  SET_INST_2(opnum, optype) |= R200_TXC_SCALE_4X;
    297 		  break;
    298 	       case GL_8X_BIT_ATI:
    299 		  SET_INST_2(opnum, optype) |= R200_TXC_SCALE_8X;
    300 		  break;
    301 	       case GL_HALF_BIT_ATI:
    302 		  SET_INST_2(opnum, optype) |= R200_TXC_SCALE_INV2;
    303 		  break;
    304 	       case GL_QUARTER_BIT_ATI:
    305 		  SET_INST_2(opnum, optype) |= R200_TXC_SCALE_INV4;
    306 		  break;
    307 	       case GL_EIGHTH_BIT_ATI:
    308 		  SET_INST_2(opnum, optype) |= R200_TXC_SCALE_INV8;
    309 		  break;
    310 	       default:
    311 		  break;
    312 	       }
    313 	    }
    314 	 }
    315 /*	 fprintf(stderr, "pass %d nr %d inst 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
    316 		pass, opnum, SET_INST(opnum, 0), SET_INST_2(opnum, 0),
    317 		SET_INST(opnum, 1), SET_INST_2(opnum, 1));*/
    318          opnum++;
    319       }
    320       afs_cmd = (GLuint *) rmesa->hw.afs[1].cmd;
    321    }
    322    rmesa->afs_loaded = ctx->ATIFragmentShader.Current;
    323 }
    324 
    325 static void r200UpdateFSRouting( struct gl_context *ctx ) {
    326    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    327    const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;
    328    GLuint reg;
    329 
    330    R200_STATECHANGE( rmesa, ctx );
    331    R200_STATECHANGE( rmesa, cst );
    332 
    333    for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
    334       if (shader->swizzlerq & (1 << (2 * reg)))
    335 	 /* r coord */
    336 	 set_re_cntl_d3d( ctx, reg, 1);
    337 	 /* q coord */
    338       else set_re_cntl_d3d( ctx, reg, 0);
    339    }
    340 
    341    rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_MULTI_PASS_ENABLE |
    342 				       R200_TEX_BLEND_ENABLE_MASK |
    343 				       R200_TEX_ENABLE_MASK);
    344    rmesa->hw.cst.cmd[CST_PP_CNTL_X] &= ~(R200_PPX_PFS_INST_ENABLE_MASK |
    345 					 R200_PPX_TEX_ENABLE_MASK |
    346 					 R200_PPX_OUTPUT_REG_MASK);
    347 
    348    /* first pass registers use slots 8 - 15
    349       but single pass shaders use slots 0 - 7 */
    350    if (shader->NumPasses < 2) {
    351       rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= shader->numArithInstr[0] == 8 ?
    352 	 0xff << (R200_TEX_BLEND_0_ENABLE_SHIFT - 1) :
    353 	 (0xff >> (8 - shader->numArithInstr[0])) << R200_TEX_BLEND_0_ENABLE_SHIFT;
    354    } else {
    355       rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_MULTI_PASS_ENABLE;
    356       rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= shader->numArithInstr[1] == 8 ?
    357 	 0xff << (R200_TEX_BLEND_0_ENABLE_SHIFT - 1) :
    358 	 (0xff >> (8 - shader->numArithInstr[1])) << R200_TEX_BLEND_0_ENABLE_SHIFT;
    359       rmesa->hw.cst.cmd[CST_PP_CNTL_X] |=
    360 	 (0xff >> (8 - shader->numArithInstr[0])) << R200_PPX_FPS_INST0_ENABLE_SHIFT;
    361    }
    362 
    363    if (shader->NumPasses < 2) {
    364       for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
    365          struct gl_texture_object *texObj = ctx->Texture.Unit[reg]._Current;
    366          R200_STATECHANGE( rmesa, tex[reg] );
    367 	 rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = 0;
    368 	 if (shader->SetupInst[0][reg].Opcode) {
    369 	    GLuint txformat = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT]
    370 		& ~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
    371 	    GLuint txformat_x = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] & ~R200_TEXCOORD_MASK;
    372 	    txformat |= (shader->SetupInst[0][reg].src - GL_TEXTURE0_ARB)
    373 		<< R200_TXFORMAT_ST_ROUTE_SHIFT;
    374 	    /* fix up texcoords for proj/non-proj 2d (3d and cube are not defined when
    375 	       using projection so don't have to worry there).
    376 	       When passing coords, need R200_TEXCOORD_VOLUME, otherwise loose a coord */
    377 	    /* FIXME: someone might rely on default tex coords r/q, which we unfortunately
    378 	       don't provide (we have the same problem without shaders) */
    379 	    if (shader->SetupInst[0][reg].Opcode == ATI_FRAGMENT_SHADER_PASS_OP) {
    380 	       txformat |= R200_TXFORMAT_LOOKUP_DISABLE;
    381 	       if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||
    382 		  shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
    383 		  txformat_x |= R200_TEXCOORD_VOLUME;
    384 	       }
    385 	       else {
    386 		  txformat_x |= R200_TEXCOORD_PROJ;
    387 	       }
    388 	       rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
    389 	    }
    390 	    else if (texObj && texObj->Target == GL_TEXTURE_3D) {
    391 	       txformat_x |= R200_TEXCOORD_VOLUME;
    392 	    }
    393 	    else if (texObj && texObj->Target == GL_TEXTURE_CUBE_MAP) {
    394 	       txformat_x |= R200_TEXCOORD_CUBIC_ENV;
    395 	    }
    396 	    else if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||
    397 	       shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
    398 	       txformat_x |= R200_TEXCOORD_NONPROJ;
    399 	    }
    400 	    else {
    401 	       txformat_x |= R200_TEXCOORD_PROJ;
    402 	    }
    403 	    rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT] = txformat;
    404 	    rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] = txformat_x;
    405 	    /* enabling texturing when unit isn't correctly configured may not be safe */
    406 	    if (texObj)
    407 	       rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
    408 	 }
    409       }
    410 
    411    } else {
    412       /* setup 1st pass */
    413       for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
    414 	 struct gl_texture_object *texObj = ctx->Texture.Unit[reg]._Current;
    415 	 R200_STATECHANGE( rmesa, tex[reg] );
    416 	 GLuint txformat_multi = 0;
    417 	 if (shader->SetupInst[0][reg].Opcode) {
    418 	    txformat_multi |= (shader->SetupInst[0][reg].src - GL_TEXTURE0_ARB)
    419 		<< R200_PASS1_ST_ROUTE_SHIFT;
    420 	    if (shader->SetupInst[0][reg].Opcode == ATI_FRAGMENT_SHADER_PASS_OP) {
    421 	       txformat_multi |= R200_PASS1_TXFORMAT_LOOKUP_DISABLE;
    422 	       if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||
    423 		  shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
    424 		  txformat_multi |= R200_PASS1_TEXCOORD_VOLUME;
    425 	       }
    426 	       else {
    427 		  txformat_multi |= R200_PASS1_TEXCOORD_PROJ;
    428 	       }
    429 	       rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_0_ENABLE << reg;
    430 	    }
    431 	    else if (texObj && texObj->Target == GL_TEXTURE_3D) {
    432 	       txformat_multi |= R200_PASS1_TEXCOORD_VOLUME;
    433 	    }
    434 	    else if (texObj && texObj->Target == GL_TEXTURE_CUBE_MAP) {
    435 	       txformat_multi |= R200_PASS1_TEXCOORD_CUBIC_ENV;
    436 	    }
    437 	    else if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI ||
    438 		  shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
    439 		  txformat_multi |= R200_PASS1_TEXCOORD_NONPROJ;
    440 	    }
    441 	    else {
    442 	       txformat_multi |= R200_PASS1_TEXCOORD_PROJ;
    443 	    }
    444 	    if (texObj)
    445 	       rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_0_ENABLE << reg;
    446 	 }
    447          rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = txformat_multi;
    448       }
    449 
    450       /* setup 2nd pass */
    451       for (reg=0; reg < R200_MAX_TEXTURE_UNITS; reg++) {
    452 	 struct gl_texture_object *texObj = ctx->Texture.Unit[reg]._Current;
    453 	 if (shader->SetupInst[1][reg].Opcode) {
    454 	    GLuint coord = shader->SetupInst[1][reg].src;
    455 	    GLuint txformat = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT]
    456 		& ~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE);
    457 	    GLuint txformat_x = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] & ~R200_TEXCOORD_MASK;
    458 	    R200_STATECHANGE( rmesa, tex[reg] );
    459 	    if (shader->SetupInst[1][reg].Opcode == ATI_FRAGMENT_SHADER_PASS_OP) {
    460 	       txformat |= R200_TXFORMAT_LOOKUP_DISABLE;
    461 	       txformat_x |= R200_TEXCOORD_VOLUME;
    462 	       if (shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STR_ATI ||
    463 		  shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
    464 	          txformat_x |= R200_TEXCOORD_VOLUME;
    465 	       }
    466 	       else {
    467 		  txformat_x |= R200_TEXCOORD_PROJ;
    468 	       }
    469 	       rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
    470 	    }
    471 	    else if (texObj && texObj->Target == GL_TEXTURE_3D) {
    472 	       txformat_x |= R200_TEXCOORD_VOLUME;
    473 	    }
    474 	    else if (texObj && texObj->Target == GL_TEXTURE_CUBE_MAP) {
    475 	       txformat_x |= R200_TEXCOORD_CUBIC_ENV;
    476 	    }
    477 	    else if (shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STR_ATI ||
    478 	       shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STQ_ATI) {
    479 	       txformat_x |= R200_TEXCOORD_NONPROJ;
    480 	    }
    481 	    else {
    482 	       txformat_x |= R200_TEXCOORD_PROJ;
    483 	    }
    484 	    if (coord >= GL_REG_0_ATI) {
    485 	       GLuint txformat_multi = rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL];
    486 	       txformat_multi |= (coord - GL_REG_0_ATI + 2) << R200_PASS2_COORDS_REG_SHIFT;
    487 	       rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = txformat_multi;
    488 	       rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= 1 <<
    489 		  (R200_PPX_OUTPUT_REG_0_SHIFT + coord - GL_REG_0_ATI);
    490 	    } else {
    491 	       txformat |= (coord - GL_TEXTURE0_ARB) << R200_TXFORMAT_ST_ROUTE_SHIFT;
    492 	    }
    493 	    rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] = txformat_x;
    494 	    rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT] = txformat;
    495 	    if (texObj)
    496 	       rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg;
    497 	 }
    498       }
    499    }
    500 }
    501 
    502 static void r200UpdateFSConstants( struct gl_context *ctx )
    503 {
    504    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    505    const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;
    506    GLuint i;
    507 
    508    /* update constants */
    509    R200_STATECHANGE(rmesa, atf);
    510    for (i = 0; i < 8; i++)
    511    {
    512       GLubyte con_byte[4];
    513       if ((shader->LocalConstDef >> i) & 1) {
    514 	 CLAMPED_FLOAT_TO_UBYTE(con_byte[0], shader->Constants[i][0]);
    515 	 CLAMPED_FLOAT_TO_UBYTE(con_byte[1], shader->Constants[i][1]);
    516 	 CLAMPED_FLOAT_TO_UBYTE(con_byte[2], shader->Constants[i][2]);
    517 	 CLAMPED_FLOAT_TO_UBYTE(con_byte[3], shader->Constants[i][3]);
    518       }
    519       else {
    520 	 CLAMPED_FLOAT_TO_UBYTE(con_byte[0], ctx->ATIFragmentShader.GlobalConstants[i][0]);
    521 	 CLAMPED_FLOAT_TO_UBYTE(con_byte[1], ctx->ATIFragmentShader.GlobalConstants[i][1]);
    522 	 CLAMPED_FLOAT_TO_UBYTE(con_byte[2], ctx->ATIFragmentShader.GlobalConstants[i][2]);
    523 	 CLAMPED_FLOAT_TO_UBYTE(con_byte[3], ctx->ATIFragmentShader.GlobalConstants[i][3]);
    524       }
    525       rmesa->hw.atf.cmd[ATF_TFACTOR_0 + i] = radeonPackColor (
    526 	 4, con_byte[0], con_byte[1], con_byte[2], con_byte[3] );
    527    }
    528 }
    529 
    530 /* update routing, constants and arithmetic
    531  * constants need to be updated always (globals can change, no separate notification)
    532  * routing needs to be updated always too (non-shader code will overwrite state, plus
    533  * some of the routing depends on what sort of texture is bound)
    534  * for both of them, we need to update anyway because of disabling/enabling ati_fs which
    535  * we'd need to track otherwise
    536  * arithmetic is only updated if current shader changes (and probably the data should be
    537  * stored in some DriverData object attached to the mesa atifs object, i.e. binding a
    538  * shader wouldn't force us to "recompile" the shader).
    539  */
    540 void r200UpdateFragmentShader( struct gl_context *ctx )
    541 {
    542    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    543 
    544    r200UpdateFSConstants( ctx );
    545    r200UpdateFSRouting( ctx );
    546    if (rmesa->afs_loaded != ctx->ATIFragmentShader.Current)
    547       r200UpdateFSArith( ctx );
    548 }
    549