1 /**************************************************************************
3 * Copyright 2004 David Airlie
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
28 #include "main/glheader.h"
29 #include "main/macros.h"
30 #include "main/enums.h"
31 #include "tnl/t_context.h"
32 #include "shader/atifragshader.h"
33 #include "shader/program.h"
34 #include "r200_context.h"
35 #include "r200_ioctl.h"
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)]
41 static void r200SetFragShaderArg( GLuint
*afs_cmd
, GLuint opnum
, GLuint optype
,
42 const struct atifragshader_src_register srcReg
,
43 GLuint argPos
, GLuint
*tfactor
)
45 const GLuint index
= srcReg
.Index
;
46 const GLuint srcmod
= srcReg
.argMod
;
47 const GLuint srcrep
= srcReg
.argRep
;
54 reg2
|= R200_TXC_REPL_RED
<< (R200_TXC_REPL_ARG_A_SHIFT
+ (2*argPos
));
59 reg2
|= R200_TXC_REPL_GREEN
<< (R200_TXC_REPL_ARG_A_SHIFT
+ (2*argPos
));
65 reg2
|= R200_TXC_REPL_BLUE
<< (R200_TXC_REPL_ARG_A_SHIFT
+ (2*argPos
));
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
;
84 reg0
|= (R200_TXC_ARG_A_TFACTOR1_COLOR
+ useOddSrc
) << (5*argPos
);
85 reg2
|= (index
- GL_CON_0_ATI
) << R200_TXC_TFACTOR1_SEL_SHIFT
;
88 else if (index
== GL_PRIMARY_COLOR_EXT
) {
89 reg0
|= (R200_TXC_ARG_A_DIFFUSE_COLOR
+ useOddSrc
) << (5*argPos
);
91 else if (index
== GL_SECONDARY_INTERPOLATOR_ATI
) {
92 reg0
|= (R200_TXC_ARG_A_SPECULAR_COLOR
+ useOddSrc
) << (5*argPos
);
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
);
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
);
108 SET_INST(opnum
, optype
) |= reg0
;
109 SET_INST_2(opnum
, optype
) |= reg2
;
112 static GLuint dstmask_table
[8] =
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
124 static void r200UpdateFSArith( GLcontext
*ctx
)
126 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
128 const struct ati_fragment_shader
*shader
= ctx
->ATIFragmentShader
.Current
;
131 R200_STATECHANGE( rmesa
, afs
[0] );
132 R200_STATECHANGE( rmesa
, afs
[1] );
134 if (shader
->NumPasses
< 2) {
135 afs_cmd
= (GLuint
*) rmesa
->hw
.afs
[1].cmd
;
138 afs_cmd
= (GLuint
*) rmesa
->hw
.afs
[0].cmd
;
140 for (pass
= 0; pass
< shader
->NumPasses
; pass
++) {
143 for (pc
= 0; pc
< shader
->numArithInstr
[pass
]; pc
++) {
145 struct atifs_instruction
*inst
= &shader
->Instructions
[pass
][pc
];
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;
152 for (optype
= 0; optype
< 2; optype
++) {
155 if (inst
->Opcode
[optype
]) {
156 switch (inst
->Opcode
[optype
]) {
157 /* these are all MADD in disguise
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
163 for GL_MAD all good */
166 SET_INST(opnum
, optype
) |= R200_TXC_NEG_ARG_C
;
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
;
179 r200SetFragShaderArg(afs_cmd
, opnum
, optype
,
180 inst
->SrcReg
[optype
][0], 2, &tfactor
);
181 SET_INST(opnum
, optype
) |= R200_TXC_OP_MADD
;
184 r200SetFragShaderArg(afs_cmd
, opnum
, optype
,
185 inst
->SrcReg
[optype
][2], 2, &tfactor
);
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
;
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
;
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
;
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
;
222 /* cannot specify dot ops as alpha ops directly */
223 case GL_DOT2_ADD_ATI
:
225 SET_INST_2(opnum
, 1) |= R200_TXA_DOT_ALPHA
;
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
;
238 SET_INST_2(opnum
, 1) |= R200_TXA_DOT_ALPHA
;
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
;
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 */
253 SET_INST_2(opnum
, 1) |= R200_TXA_DOT_ALPHA
;
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
;
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
;
276 dstmod
&= ~GL_SATURATE_BIT_ATI
;
278 SET_INST_2(opnum
, optype
) |= (dstreg
+ 1) << R200_TXC_OUTPUT_REG_SHIFT
;
279 SET_INST_2(opnum
, optype
) |= dstmask_table
[dstmask
];
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
;
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;*/
293 SET_INST_2(opnum
, optype
) |= R200_TXC_SCALE_2X
;
296 SET_INST_2(opnum
, optype
) |= R200_TXC_SCALE_4X
;
299 SET_INST_2(opnum
, optype
) |= R200_TXC_SCALE_8X
;
301 case GL_HALF_BIT_ATI
:
302 SET_INST_2(opnum
, optype
) |= R200_TXC_SCALE_INV2
;
304 case GL_QUARTER_BIT_ATI
:
305 SET_INST_2(opnum
, optype
) |= R200_TXC_SCALE_INV4
;
307 case GL_EIGHTH_BIT_ATI
:
308 SET_INST_2(opnum
, optype
) |= R200_TXC_SCALE_INV8
;
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));*/
320 afs_cmd
= (GLuint
*) rmesa
->hw
.afs
[1].cmd
;
322 rmesa
->afs_loaded
= ctx
->ATIFragmentShader
.Current
;
325 static void r200UpdateFSRouting( GLcontext
*ctx
) {
326 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
327 const struct ati_fragment_shader
*shader
= ctx
->ATIFragmentShader
.Current
;
330 R200_STATECHANGE( rmesa
, ctx
);
331 R200_STATECHANGE( rmesa
, cst
);
333 for (reg
= 0; reg
< R200_MAX_TEXTURE_UNITS
; reg
++) {
334 if (shader
->swizzlerq
& (1 << (2 * reg
)))
336 set_re_cntl_d3d( ctx
, reg
, 1);
338 else set_re_cntl_d3d( ctx
, reg
, 0);
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
);
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
;
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
;
363 if (shader
->NumPasses
< 2) {
364 for (reg
= 0; reg
< R200_MAX_TEXTURE_UNITS
; reg
++) {
365 GLbitfield targetbit
= ctx
->Texture
.Unit
[reg
]._ReallyEnabled
;
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
;
386 txformat_x
|= R200_TEXCOORD_PROJ
;
388 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_TEX_0_ENABLE
<< reg
;
390 else if (targetbit
== TEXTURE_3D_BIT
) {
391 txformat_x
|= R200_TEXCOORD_VOLUME
;
393 else if (targetbit
== TEXTURE_CUBE_BIT
) {
394 txformat_x
|= R200_TEXCOORD_CUBIC_ENV
;
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
;
401 txformat_x
|= R200_TEXCOORD_PROJ
;
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 */
407 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_TEX_0_ENABLE
<< reg
;
413 for (reg
= 0; reg
< R200_MAX_TEXTURE_UNITS
; reg
++) {
414 GLbitfield targetbit
= ctx
->Texture
.Unit
[reg
]._ReallyEnabled
;
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
;
427 txformat_multi
|= R200_PASS1_TEXCOORD_PROJ
;
429 rmesa
->hw
.cst
.cmd
[CST_PP_CNTL_X
] |= R200_PPX_TEX_0_ENABLE
<< reg
;
431 else if (targetbit
== TEXTURE_3D_BIT
) {
432 txformat_multi
|= R200_PASS1_TEXCOORD_VOLUME
;
434 else if (targetbit
== TEXTURE_CUBE_BIT
) {
435 txformat_multi
|= R200_PASS1_TEXCOORD_CUBIC_ENV
;
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
;
442 txformat_multi
|= R200_PASS1_TEXCOORD_PROJ
;
445 rmesa
->hw
.cst
.cmd
[CST_PP_CNTL_X
] |= R200_PPX_TEX_0_ENABLE
<< reg
;
447 rmesa
->hw
.tex
[reg
].cmd
[TEX_PP_TXMULTI_CTL
] = txformat_multi
;
451 for (reg
=0; reg
< R200_MAX_TEXTURE_UNITS
; reg
++) {
452 GLbitfield targetbit
= ctx
->Texture
.Unit
[reg
]._ReallyEnabled
;
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
;
467 txformat_x
|= R200_TEXCOORD_PROJ
;
469 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_TEX_0_ENABLE
<< reg
;
471 else if (targetbit
== TEXTURE_3D_BIT
) {
472 txformat_x
|= R200_TEXCOORD_VOLUME
;
474 else if (targetbit
== TEXTURE_CUBE_BIT
) {
475 txformat_x
|= R200_TEXCOORD_CUBIC_ENV
;
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
;
482 txformat_x
|= R200_TEXCOORD_PROJ
;
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
);
491 txformat
|= (coord
- GL_TEXTURE0_ARB
) << R200_TXFORMAT_ST_ROUTE_SHIFT
;
493 rmesa
->hw
.tex
[reg
].cmd
[TEX_PP_TXFORMAT_X
] = txformat_x
;
494 rmesa
->hw
.tex
[reg
].cmd
[TEX_PP_TXFORMAT
] = txformat
;
496 rmesa
->hw
.ctx
.cmd
[CTX_PP_CNTL
] |= R200_TEX_0_ENABLE
<< reg
;
502 static void r200UpdateFSConstants( GLcontext
*ctx
)
504 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
505 const struct ati_fragment_shader
*shader
= ctx
->ATIFragmentShader
.Current
;
508 /* update constants */
509 R200_STATECHANGE(rmesa
, atf
);
510 for (i
= 0; i
< 8; i
++)
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]);
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]);
525 rmesa
->hw
.atf
.cmd
[ATF_TFACTOR_0
+ i
] = radeonPackColor (
526 4, con_byte
[0], con_byte
[1], con_byte
[2], con_byte
[3] );
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).
540 void r200UpdateFragmentShader( GLcontext
*ctx
)
542 r200ContextPtr rmesa
= R200_CONTEXT(ctx
);
544 r200UpdateFSConstants( ctx
);
545 r200UpdateFSRouting( ctx
);
546 if (rmesa
->afs_loaded
!= ctx
->ATIFragmentShader
.Current
)
547 r200UpdateFSArith( ctx
);