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 41static 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 112static GLuint dstmask_table[9] = 113{ 114 /* first slot never used, GL_NONE translated to RGB by mesa and you can't get a 0 dstmask. */ 115 R200_TXC_OUTPUT_MASK_RGB, 116 R200_TXC_OUTPUT_MASK_R, 117 R200_TXC_OUTPUT_MASK_G, 118 R200_TXC_OUTPUT_MASK_RG, 119 R200_TXC_OUTPUT_MASK_B, 120 R200_TXC_OUTPUT_MASK_RB, 121 R200_TXC_OUTPUT_MASK_GB, 122 R200_TXC_OUTPUT_MASK_RGB, 123 R200_TXC_OUTPUT_MASK_RGB, /* alpha ops */ 124}; 125 126static void r200UpdateFSArith( struct gl_context *ctx ) 127{ 128 r200ContextPtr rmesa = R200_CONTEXT(ctx); 129 GLuint *afs_cmd; 130 const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current; 131 GLuint pass; 132 133 R200_STATECHANGE( rmesa, afs[0] ); 134 R200_STATECHANGE( rmesa, afs[1] ); 135 136 if (shader->NumPasses < 2) { 137 afs_cmd = (GLuint *) rmesa->hw.afs[1].cmd; 138 } 139 else { 140 afs_cmd = (GLuint *) rmesa->hw.afs[0].cmd; 141 } 142 for (pass = 0; pass < shader->NumPasses; pass++) { 143 GLuint opnum = 0; 144 GLuint pc; 145 for (pc = 0; pc < shader->numArithInstr[pass]; pc++) { 146 GLuint optype; 147 struct atifs_instruction *inst = &shader->Instructions[pass][pc]; 148 149 SET_INST(opnum, 0) = 0; 150 SET_INST_2(opnum, 0) = 0; 151 SET_INST(opnum, 1) = 0; 152 SET_INST_2(opnum, 1) = 0; 153 154 for (optype = 0; optype < 2; optype++) { 155 GLuint tfactor = 0; 156 157 if (inst->Opcode[optype]) { 158 switch (inst->Opcode[optype]) { 159 /* these are all MADD in disguise 160 MADD is A * B + C 161 so for GL_ADD use arg B/C and make A complement 0 162 for GL_SUB use arg B/C, negate C and make A complement 0 163 for GL_MOV use arg C 164 for GL_MUL use arg A 165 for GL_MAD all good */ 166 case GL_SUB_ATI: 167 /* negate C */ 168 SET_INST(opnum, optype) |= R200_TXC_NEG_ARG_C; 169 FALLTHROUGH; 170 case GL_ADD_ATI: 171 r200SetFragShaderArg(afs_cmd, opnum, optype, 172 inst->SrcReg[optype][0], 1, &tfactor); 173 r200SetFragShaderArg(afs_cmd, opnum, optype, 174 inst->SrcReg[optype][1], 2, &tfactor); 175 /* A = complement 0 */ 176 SET_INST(opnum, optype) |= R200_TXC_COMP_ARG_A; 177 SET_INST(opnum, optype) |= R200_TXC_OP_MADD; 178 break; 179 case GL_MOV_ATI: 180 /* put arg0 in C */ 181 r200SetFragShaderArg(afs_cmd, opnum, optype, 182 inst->SrcReg[optype][0], 2, &tfactor); 183 SET_INST(opnum, optype) |= R200_TXC_OP_MADD; 184 break; 185 case GL_MAD_ATI: 186 r200SetFragShaderArg(afs_cmd, opnum, optype, 187 inst->SrcReg[optype][2], 2, &tfactor); 188 FALLTHROUGH; 189 case GL_MUL_ATI: 190 r200SetFragShaderArg(afs_cmd, opnum, optype, 191 inst->SrcReg[optype][0], 0, &tfactor); 192 r200SetFragShaderArg(afs_cmd, opnum, optype, 193 inst->SrcReg[optype][1], 1, &tfactor); 194 SET_INST(opnum, optype) |= R200_TXC_OP_MADD; 195 break; 196 case GL_LERP_ATI: 197 /* arg order is not native chip order, swap A and C */ 198 r200SetFragShaderArg(afs_cmd, opnum, optype, 199 inst->SrcReg[optype][0], 2, &tfactor); 200 r200SetFragShaderArg(afs_cmd, opnum, optype, 201 inst->SrcReg[optype][1], 1, &tfactor); 202 r200SetFragShaderArg(afs_cmd, opnum, optype, 203 inst->SrcReg[optype][2], 0, &tfactor); 204 SET_INST(opnum, optype) |= R200_TXC_OP_LERP; 205 break; 206 case GL_CND_ATI: 207 r200SetFragShaderArg(afs_cmd, opnum, optype, 208 inst->SrcReg[optype][0], 0, &tfactor); 209 r200SetFragShaderArg(afs_cmd, opnum, optype, 210 inst->SrcReg[optype][1], 1, &tfactor); 211 r200SetFragShaderArg(afs_cmd, opnum, optype, 212 inst->SrcReg[optype][2], 2, &tfactor); 213 SET_INST(opnum, optype) |= R200_TXC_OP_CONDITIONAL; 214 break; 215 case GL_CND0_ATI: 216 r200SetFragShaderArg(afs_cmd, opnum, optype, 217 inst->SrcReg[optype][0], 0, &tfactor); 218 r200SetFragShaderArg(afs_cmd, opnum, optype, 219 inst->SrcReg[optype][1], 1, &tfactor); 220 r200SetFragShaderArg(afs_cmd, opnum, optype, 221 inst->SrcReg[optype][2], 2, &tfactor); 222 SET_INST(opnum, optype) |= R200_TXC_OP_CND0; 223 break; 224 /* cannot specify dot ops as alpha ops directly */ 225 case GL_DOT2_ADD_ATI: 226 if (optype) 227 SET_INST_2(opnum, 1) |= R200_TXA_DOT_ALPHA; 228 else { 229 r200SetFragShaderArg(afs_cmd, opnum, 0, 230 inst->SrcReg[0][0], 0, &tfactor); 231 r200SetFragShaderArg(afs_cmd, opnum, 0, 232 inst->SrcReg[0][1], 1, &tfactor); 233 r200SetFragShaderArg(afs_cmd, opnum, 0, 234 inst->SrcReg[0][2], 2, &tfactor); 235 SET_INST(opnum, 0) |= R200_TXC_OP_DOT2_ADD; 236 } 237 break; 238 case GL_DOT3_ATI: 239 if (optype) 240 SET_INST_2(opnum, 1) |= R200_TXA_DOT_ALPHA; 241 else { 242 r200SetFragShaderArg(afs_cmd, opnum, 0, 243 inst->SrcReg[0][0], 0, &tfactor); 244 r200SetFragShaderArg(afs_cmd, opnum, 0, 245 inst->SrcReg[0][1], 1, &tfactor); 246 SET_INST(opnum, 0) |= R200_TXC_OP_DOT3; 247 } 248 break; 249 case GL_DOT4_ATI: 250 /* experimental verification: for dot4 setup of alpha args is needed 251 (dstmod is ignored, though, so dot2/dot3 should be safe) 252 the hardware apparently does R1*R2 + G1*G2 + B1*B2 + A3*A4 253 but the API doesn't allow it */ 254 if (optype) 255 SET_INST_2(opnum, 1) |= R200_TXA_DOT_ALPHA; 256 else { 257 r200SetFragShaderArg(afs_cmd, opnum, 0, 258 inst->SrcReg[0][0], 0, &tfactor); 259 r200SetFragShaderArg(afs_cmd, opnum, 0, 260 inst->SrcReg[0][1], 1, &tfactor); 261 r200SetFragShaderArg(afs_cmd, opnum, 1, 262 inst->SrcReg[0][0], 0, &tfactor); 263 r200SetFragShaderArg(afs_cmd, opnum, 1, 264 inst->SrcReg[0][1], 1, &tfactor); 265 SET_INST(opnum, optype) |= R200_TXC_OP_DOT4; 266 } 267 break; 268 } 269 } 270 271 /* destination */ 272 if (inst->DstReg[optype].Index) { 273 GLuint dstreg = inst->DstReg[optype].Index - GL_REG_0_ATI; 274 GLuint dstmask = inst->DstReg[optype].dstMask; 275 GLuint sat = inst->DstReg[optype].dstMod & GL_SATURATE_BIT_ATI; 276 GLuint dstmod = inst->DstReg[optype].dstMod; 277 278 dstmod &= ~GL_SATURATE_BIT_ATI; 279 280 SET_INST_2(opnum, optype) |= (dstreg + 1) << R200_TXC_OUTPUT_REG_SHIFT; 281 SET_INST_2(opnum, optype) |= dstmask_table[dstmask]; 282 283 /* fglrx does clamp the last instructions to 0_1 it seems */ 284 /* this won't necessarily catch the last instruction 285 which writes to reg0 */ 286 if (sat || (pc == (shader->numArithInstr[pass] - 1) && 287 ((pass == 1) || (shader->NumPasses == 1)))) 288 SET_INST_2(opnum, optype) |= R200_TXC_CLAMP_0_1; 289 else 290 /*should we clamp or not? spec is vague, I would suppose yes but fglrx doesn't */ 291 SET_INST_2(opnum, optype) |= R200_TXC_CLAMP_8_8; 292/* SET_INST_2(opnum, optype) |= R200_TXC_CLAMP_WRAP;*/ 293 switch(dstmod) { 294 case GL_2X_BIT_ATI: 295 SET_INST_2(opnum, optype) |= R200_TXC_SCALE_2X; 296 break; 297 case GL_4X_BIT_ATI: 298 SET_INST_2(opnum, optype) |= R200_TXC_SCALE_4X; 299 break; 300 case GL_8X_BIT_ATI: 301 SET_INST_2(opnum, optype) |= R200_TXC_SCALE_8X; 302 break; 303 case GL_HALF_BIT_ATI: 304 SET_INST_2(opnum, optype) |= R200_TXC_SCALE_INV2; 305 break; 306 case GL_QUARTER_BIT_ATI: 307 SET_INST_2(opnum, optype) |= R200_TXC_SCALE_INV4; 308 break; 309 case GL_EIGHTH_BIT_ATI: 310 SET_INST_2(opnum, optype) |= R200_TXC_SCALE_INV8; 311 break; 312 default: 313 break; 314 } 315 } 316 } 317/* fprintf(stderr, "pass %d nr %d inst 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n", 318 pass, opnum, SET_INST(opnum, 0), SET_INST_2(opnum, 0), 319 SET_INST(opnum, 1), SET_INST_2(opnum, 1));*/ 320 opnum++; 321 } 322 afs_cmd = (GLuint *) rmesa->hw.afs[1].cmd; 323 } 324 rmesa->afs_loaded = ctx->ATIFragmentShader.Current; 325} 326 327static void r200UpdateFSRouting( struct gl_context *ctx ) { 328 r200ContextPtr rmesa = R200_CONTEXT(ctx); 329 const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current; 330 GLuint reg; 331 332 R200_STATECHANGE( rmesa, ctx ); 333 R200_STATECHANGE( rmesa, cst ); 334 335 for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) { 336 if (shader->swizzlerq & (1 << (2 * reg))) 337 /* r coord */ 338 set_re_cntl_d3d( ctx, reg, 1); 339 /* q coord */ 340 else set_re_cntl_d3d( ctx, reg, 0); 341 } 342 343 rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_MULTI_PASS_ENABLE | 344 R200_TEX_BLEND_ENABLE_MASK | 345 R200_TEX_ENABLE_MASK); 346 rmesa->hw.cst.cmd[CST_PP_CNTL_X] &= ~(R200_PPX_PFS_INST_ENABLE_MASK | 347 R200_PPX_TEX_ENABLE_MASK | 348 R200_PPX_OUTPUT_REG_MASK); 349 350 /* first pass registers use slots 8 - 15 351 but single pass shaders use slots 0 - 7 */ 352 if (shader->NumPasses < 2) { 353 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= shader->numArithInstr[0] == 8 ? 354 0xff << (R200_TEX_BLEND_0_ENABLE_SHIFT - 1) : 355 (0xff >> (8 - shader->numArithInstr[0])) << R200_TEX_BLEND_0_ENABLE_SHIFT; 356 } else { 357 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_MULTI_PASS_ENABLE; 358 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= shader->numArithInstr[1] == 8 ? 359 0xff << (R200_TEX_BLEND_0_ENABLE_SHIFT - 1) : 360 (0xff >> (8 - shader->numArithInstr[1])) << R200_TEX_BLEND_0_ENABLE_SHIFT; 361 rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= 362 (0xff >> (8 - shader->numArithInstr[0])) << R200_PPX_FPS_INST0_ENABLE_SHIFT; 363 } 364 365 if (shader->NumPasses < 2) { 366 for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) { 367 struct gl_texture_object *texObj = ctx->Texture.Unit[reg]._Current; 368 R200_STATECHANGE( rmesa, tex[reg] ); 369 rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = 0; 370 if (shader->SetupInst[0][reg].Opcode) { 371 GLuint txformat = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT] 372 & ~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE); 373 GLuint txformat_x = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] & ~R200_TEXCOORD_MASK; 374 txformat |= (shader->SetupInst[0][reg].src - GL_TEXTURE0_ARB) 375 << R200_TXFORMAT_ST_ROUTE_SHIFT; 376 /* fix up texcoords for proj/non-proj 2d (3d and cube are not defined when 377 using projection so don't have to worry there). 378 When passing coords, need R200_TEXCOORD_VOLUME, otherwise loose a coord */ 379 /* FIXME: someone might rely on default tex coords r/q, which we unfortunately 380 don't provide (we have the same problem without shaders) */ 381 if (shader->SetupInst[0][reg].Opcode == ATI_FRAGMENT_SHADER_PASS_OP) { 382 txformat |= R200_TXFORMAT_LOOKUP_DISABLE; 383 if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI || 384 shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) { 385 txformat_x |= R200_TEXCOORD_VOLUME; 386 } 387 else { 388 txformat_x |= R200_TEXCOORD_PROJ; 389 } 390 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg; 391 } 392 else if (texObj && texObj->Target == GL_TEXTURE_3D) { 393 txformat_x |= R200_TEXCOORD_VOLUME; 394 } 395 else if (texObj && texObj->Target == GL_TEXTURE_CUBE_MAP) { 396 txformat_x |= R200_TEXCOORD_CUBIC_ENV; 397 } 398 else if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI || 399 shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) { 400 txformat_x |= R200_TEXCOORD_NONPROJ; 401 } 402 else { 403 txformat_x |= R200_TEXCOORD_PROJ; 404 } 405 rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT] = txformat; 406 rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] = txformat_x; 407 /* enabling texturing when unit isn't correctly configured may not be safe */ 408 if (texObj) 409 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg; 410 } 411 } 412 413 } else { 414 /* setup 1st pass */ 415 for (reg = 0; reg < R200_MAX_TEXTURE_UNITS; reg++) { 416 struct gl_texture_object *texObj = ctx->Texture.Unit[reg]._Current; 417 R200_STATECHANGE( rmesa, tex[reg] ); 418 GLuint txformat_multi = 0; 419 if (shader->SetupInst[0][reg].Opcode) { 420 txformat_multi |= (shader->SetupInst[0][reg].src - GL_TEXTURE0_ARB) 421 << R200_PASS1_ST_ROUTE_SHIFT; 422 if (shader->SetupInst[0][reg].Opcode == ATI_FRAGMENT_SHADER_PASS_OP) { 423 txformat_multi |= R200_PASS1_TXFORMAT_LOOKUP_DISABLE; 424 if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI || 425 shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) { 426 txformat_multi |= R200_PASS1_TEXCOORD_VOLUME; 427 } 428 else { 429 txformat_multi |= R200_PASS1_TEXCOORD_PROJ; 430 } 431 rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_0_ENABLE << reg; 432 } 433 else if (texObj && texObj->Target == GL_TEXTURE_3D) { 434 txformat_multi |= R200_PASS1_TEXCOORD_VOLUME; 435 } 436 else if (texObj && texObj->Target == GL_TEXTURE_CUBE_MAP) { 437 txformat_multi |= R200_PASS1_TEXCOORD_CUBIC_ENV; 438 } 439 else if (shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STR_ATI || 440 shader->SetupInst[0][reg].swizzle == GL_SWIZZLE_STQ_ATI) { 441 txformat_multi |= R200_PASS1_TEXCOORD_NONPROJ; 442 } 443 else { 444 txformat_multi |= R200_PASS1_TEXCOORD_PROJ; 445 } 446 if (texObj) 447 rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_0_ENABLE << reg; 448 } 449 rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = txformat_multi; 450 } 451 452 /* setup 2nd pass */ 453 for (reg=0; reg < R200_MAX_TEXTURE_UNITS; reg++) { 454 struct gl_texture_object *texObj = ctx->Texture.Unit[reg]._Current; 455 if (shader->SetupInst[1][reg].Opcode) { 456 GLuint coord = shader->SetupInst[1][reg].src; 457 GLuint txformat = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT] 458 & ~(R200_TXFORMAT_ST_ROUTE_MASK | R200_TXFORMAT_LOOKUP_DISABLE); 459 GLuint txformat_x = rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] & ~R200_TEXCOORD_MASK; 460 R200_STATECHANGE( rmesa, tex[reg] ); 461 if (shader->SetupInst[1][reg].Opcode == ATI_FRAGMENT_SHADER_PASS_OP) { 462 txformat |= R200_TXFORMAT_LOOKUP_DISABLE; 463 txformat_x |= R200_TEXCOORD_VOLUME; 464 if (shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STR_ATI || 465 shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STQ_ATI) { 466 txformat_x |= R200_TEXCOORD_VOLUME; 467 } 468 else { 469 txformat_x |= R200_TEXCOORD_PROJ; 470 } 471 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg; 472 } 473 else if (texObj && texObj->Target == GL_TEXTURE_3D) { 474 txformat_x |= R200_TEXCOORD_VOLUME; 475 } 476 else if (texObj && texObj->Target == GL_TEXTURE_CUBE_MAP) { 477 txformat_x |= R200_TEXCOORD_CUBIC_ENV; 478 } 479 else if (shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STR_ATI || 480 shader->SetupInst[1][reg].swizzle == GL_SWIZZLE_STQ_ATI) { 481 txformat_x |= R200_TEXCOORD_NONPROJ; 482 } 483 else { 484 txformat_x |= R200_TEXCOORD_PROJ; 485 } 486 if (coord >= GL_REG_0_ATI) { 487 GLuint txformat_multi = rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL]; 488 txformat_multi |= (coord - GL_REG_0_ATI + 2) << R200_PASS2_COORDS_REG_SHIFT; 489 rmesa->hw.tex[reg].cmd[TEX_PP_TXMULTI_CTL] = txformat_multi; 490 rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= 1 << 491 (R200_PPX_OUTPUT_REG_0_SHIFT + coord - GL_REG_0_ATI); 492 } else { 493 txformat |= (coord - GL_TEXTURE0_ARB) << R200_TXFORMAT_ST_ROUTE_SHIFT; 494 } 495 rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT_X] = txformat_x; 496 rmesa->hw.tex[reg].cmd[TEX_PP_TXFORMAT] = txformat; 497 if (texObj) 498 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << reg; 499 } 500 } 501 } 502} 503 504static void r200UpdateFSConstants( struct gl_context *ctx ) 505{ 506 r200ContextPtr rmesa = R200_CONTEXT(ctx); 507 const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current; 508 GLuint i; 509 510 /* update constants */ 511 R200_STATECHANGE(rmesa, atf); 512 for (i = 0; i < 8; i++) 513 { 514 GLubyte con_byte[4]; 515 if ((shader->LocalConstDef >> i) & 1) { 516 CLAMPED_FLOAT_TO_UBYTE(con_byte[0], shader->Constants[i][0]); 517 CLAMPED_FLOAT_TO_UBYTE(con_byte[1], shader->Constants[i][1]); 518 CLAMPED_FLOAT_TO_UBYTE(con_byte[2], shader->Constants[i][2]); 519 CLAMPED_FLOAT_TO_UBYTE(con_byte[3], shader->Constants[i][3]); 520 } 521 else { 522 CLAMPED_FLOAT_TO_UBYTE(con_byte[0], ctx->ATIFragmentShader.GlobalConstants[i][0]); 523 CLAMPED_FLOAT_TO_UBYTE(con_byte[1], ctx->ATIFragmentShader.GlobalConstants[i][1]); 524 CLAMPED_FLOAT_TO_UBYTE(con_byte[2], ctx->ATIFragmentShader.GlobalConstants[i][2]); 525 CLAMPED_FLOAT_TO_UBYTE(con_byte[3], ctx->ATIFragmentShader.GlobalConstants[i][3]); 526 } 527 rmesa->hw.atf.cmd[ATF_TFACTOR_0 + i] = radeonPackColor ( 528 4, con_byte[0], con_byte[1], con_byte[2], con_byte[3] ); 529 } 530} 531 532/* update routing, constants and arithmetic 533 * constants need to be updated always (globals can change, no separate notification) 534 * routing needs to be updated always too (non-shader code will overwrite state, plus 535 * some of the routing depends on what sort of texture is bound) 536 * for both of them, we need to update anyway because of disabling/enabling ati_fs which 537 * we'd need to track otherwise 538 * arithmetic is only updated if current shader changes (and probably the data should be 539 * stored in some DriverData object attached to the mesa atifs object, i.e. binding a 540 * shader wouldn't force us to "recompile" the shader). 541 */ 542void r200UpdateFragmentShader( struct gl_context *ctx ) 543{ 544 r200ContextPtr rmesa = R200_CONTEXT(ctx); 545 546 r200UpdateFSConstants( ctx ); 547 r200UpdateFSRouting( ctx ); 548 if (rmesa->afs_loaded != ctx->ATIFragmentShader.Current) 549 r200UpdateFSArith( ctx ); 550} 551