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