• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
r200SetFragShaderArg(GLuint * afs_cmd,GLuint opnum,GLuint optype,const struct atifragshader_src_register srcReg,GLuint argPos,GLuint * tfactor)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[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 
r200UpdateFSArith(struct gl_context * ctx)126 static 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 
r200UpdateFSRouting(struct gl_context * ctx)327 static 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 
r200UpdateFSConstants(struct gl_context * ctx)504 static 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  */
r200UpdateFragmentShader(struct gl_context * ctx)542 void 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