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