• 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 
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 
r200UpdateTextureEnv(struct gl_context * ctx,int unit,int slot,GLuint replaceargs)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 
r200SetTexBuffer2(__DRIcontext * pDRICtx,GLint target,GLint texture_format,__DRIdrawable * dPriv)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 		else
697 			texFormat = MESA_FORMAT_B8G8R8A8_UNORM;
698 		break;
699 	case 3:
700 	default:
701 		texFormat = MESA_FORMAT_BGR_UNORM8;
702 		break;
703 	case 2:
704 		texFormat = MESA_FORMAT_B5G6R5_UNORM;
705 		break;
706 	}
707 
708         t->pp_txformat = tx_table_le[texFormat].format;
709         t->pp_txfilter |= tx_table_le[texFormat].filter;
710 
711 	_mesa_init_teximage_fields(&radeon->glCtx, texImage,
712 				   rb->base.Base.Width, rb->base.Base.Height,
713 				   1, 0,
714 				   rb->cpp, texFormat);
715 	rImage->base.RowStride = rb->pitch / rb->cpp;
716 
717 
718         t->pp_txsize = ((rb->base.Base.Width - 1) << RADEON_TEX_USIZE_SHIFT)
719 		   | ((rb->base.Base.Height - 1) << RADEON_TEX_VSIZE_SHIFT);
720 
721 	if (target == GL_TEXTURE_RECTANGLE_NV) {
722 		t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
723 		t->pp_txpitch = pitch_val;
724 		t->pp_txpitch -= 32;
725 	} else {
726 		t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
727 				    R200_TXFORMAT_HEIGHT_MASK |
728 				    R200_TXFORMAT_CUBIC_MAP_ENABLE |
729 				    R200_TXFORMAT_F5_WIDTH_MASK |
730 				    R200_TXFORMAT_F5_HEIGHT_MASK);
731 		t->pp_txformat |= ((texImage->WidthLog2 << R200_TXFORMAT_WIDTH_SHIFT) |
732 				   (texImage->HeightLog2 << R200_TXFORMAT_HEIGHT_SHIFT));
733 	}
734 
735 	t->validated = GL_TRUE;
736 	_mesa_unlock_texture(&radeon->glCtx, texObj);
737 	return;
738 }
739 
740 
r200SetTexBuffer(__DRIcontext * pDRICtx,GLint target,__DRIdrawable * dPriv)741 void r200SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
742 {
743         r200SetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
744 }
745 
746 
747 #define REF_COLOR 1
748 #define REF_ALPHA 2
749 
r200UpdateAllTexEnv(struct gl_context * ctx)750 static GLboolean r200UpdateAllTexEnv( struct gl_context *ctx )
751 {
752    r200ContextPtr rmesa = R200_CONTEXT(ctx);
753    GLint i, j, currslot;
754    GLint maxunitused = -1;
755    GLboolean texregfree[6] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
756    GLubyte stageref[7] = {0, 0, 0, 0, 0, 0, 0};
757    GLint nextunit[R200_MAX_TEXTURE_UNITS] = {0, 0, 0, 0, 0, 0};
758    GLint currentnext = -1;
759    GLboolean ok;
760 
761    /* find highest used unit */
762    for ( j = 0; j < R200_MAX_TEXTURE_UNITS; j++) {
763       if (ctx->Texture.Unit[j]._Current) {
764 	 maxunitused = j;
765       }
766    }
767    stageref[maxunitused + 1] = REF_COLOR | REF_ALPHA;
768 
769    for ( j = maxunitused; j >= 0; j-- ) {
770       const struct gl_texture_unit *rtexUnit = &ctx->Texture.Unit[j];
771       const struct gl_fixedfunc_texture_unit *texUnit =
772          &ctx->Texture.FixedFuncUnit[j];
773 
774       rmesa->state.texture.unit[j].outputreg = -1;
775 
776       if (stageref[j + 1]) {
777 
778 	 /* use the lowest available reg. That gets us automatically reg0 for the last stage.
779 	    need this even for disabled units, as it may get referenced due to the replace
780 	    optimization */
781 	 for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS; i++ ) {
782 	    if (texregfree[i]) {
783 	       rmesa->state.texture.unit[j].outputreg = i;
784 	       break;
785 	    }
786 	 }
787 	 if (rmesa->state.texture.unit[j].outputreg == -1) {
788 	    /* no more free regs we can use. Need a fallback :-( */
789 	    return GL_FALSE;
790          }
791 
792          nextunit[j] = currentnext;
793 
794          if (!rtexUnit->_Current) {
795 	 /* the not enabled stages are referenced "indirectly",
796             must not cut off the lower stages */
797 	    stageref[j] = REF_COLOR | REF_ALPHA;
798 	    continue;
799          }
800 	 currentnext = j;
801 
802 	 const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
803 	 const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
804 	 const GLboolean isdot3rgba = (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ||
805 				      (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT);
806 
807 
808 	 /* check if we need the color part, special case for dot3_rgba
809 	    as if only the alpha part is referenced later on it still is using the color part */
810 	 if ((stageref[j + 1] & REF_COLOR) || isdot3rgba) {
811 	    for ( i = 0 ; i < numColorArgs ; i++ ) {
812 	       const GLuint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i];
813 	       const GLuint op = texUnit->_CurrentCombine->OperandRGB[i];
814 	       switch ( srcRGBi ) {
815 	       case GL_PREVIOUS:
816 		  /* op 0/1 are referencing color, op 2/3 alpha */
817 		  stageref[j] |= (op >> 1) + 1;
818 	          break;
819 	       case GL_TEXTURE:
820 		  texregfree[j] = GL_FALSE;
821 		  break;
822 	       case GL_TEXTURE0:
823 	       case GL_TEXTURE1:
824 	       case GL_TEXTURE2:
825 	       case GL_TEXTURE3:
826 	       case GL_TEXTURE4:
827 	       case GL_TEXTURE5:
828 		  texregfree[srcRGBi - GL_TEXTURE0] = GL_FALSE;
829 	          break;
830 	       default: /* don't care about other sources here */
831 		  break;
832 	       }
833 	    }
834 	 }
835 
836 	 /* alpha args are ignored for dot3_rgba */
837 	 if ((stageref[j + 1] & REF_ALPHA) && !isdot3rgba) {
838 
839 	    for ( i = 0 ; i < numAlphaArgs ; i++ ) {
840 	       const GLuint srcAi = texUnit->_CurrentCombine->SourceA[i];
841 	       switch ( srcAi ) {
842 	       case GL_PREVIOUS:
843 		  stageref[j] |= REF_ALPHA;
844 		  break;
845 	       case GL_TEXTURE:
846 		  texregfree[j] = GL_FALSE;
847 		  break;
848 	       case GL_TEXTURE0:
849 	       case GL_TEXTURE1:
850 	       case GL_TEXTURE2:
851 	       case GL_TEXTURE3:
852 	       case GL_TEXTURE4:
853 	       case GL_TEXTURE5:
854 		  texregfree[srcAi - GL_TEXTURE0] = GL_FALSE;
855 		  break;
856 	       default: /* don't care about other sources here */
857 		  break;
858 	       }
859 	    }
860 	 }
861       }
862    }
863 
864    /* don't enable texture sampling for units if the result is not used */
865    for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) {
866       if (ctx->Texture.Unit[i]._Current && !texregfree[i])
867 	 rmesa->state.texture.unit[i].unitneeded = 1 << _mesa_tex_target_to_index(ctx, ctx->Texture.Unit[i]._Current->Target);
868       else rmesa->state.texture.unit[i].unitneeded = 0;
869    }
870 
871    ok = GL_TRUE;
872    currslot = 0;
873    rmesa->state.envneeded = 1;
874 
875    i = 0;
876    while ((i <= maxunitused) && (i >= 0)) {
877       /* only output instruction if the results are referenced */
878       if (ctx->Texture.Unit[i]._Current && stageref[i+1]) {
879          GLuint replaceunit = i;
880 	 /* try to optimize GL_REPLACE away (only one level deep though) */
881 	 if (	(ctx->Texture.FixedFuncUnit[i]._CurrentCombine->ModeRGB == GL_REPLACE) &&
882 		(ctx->Texture.FixedFuncUnit[i]._CurrentCombine->ModeA == GL_REPLACE) &&
883 		(ctx->Texture.FixedFuncUnit[i]._CurrentCombine->ScaleShiftRGB == 0) &&
884 		(ctx->Texture.FixedFuncUnit[i]._CurrentCombine->ScaleShiftA == 0) &&
885 		(nextunit[i] > 0) ) {
886 	    /* yippie! can optimize it away! */
887 	    replaceunit = i;
888 	    i = nextunit[i];
889 	 }
890 
891 	 /* need env instruction slot */
892 	 rmesa->state.envneeded |= 1 << currslot;
893 	 ok = r200UpdateTextureEnv( ctx, i, currslot, replaceunit );
894 	 if (!ok) return GL_FALSE;
895 	 currslot++;
896       }
897       i = i + 1;
898    }
899 
900    if (currslot == 0) {
901       /* need one stage at least */
902       rmesa->state.texture.unit[0].outputreg = 0;
903       ok = r200UpdateTextureEnv( ctx, 0, 0, 0 );
904    }
905 
906    R200_STATECHANGE( rmesa, ctx );
907    rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_TEX_BLEND_ENABLE_MASK | R200_MULTI_PASS_ENABLE);
908    rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= rmesa->state.envneeded << R200_TEX_BLEND_0_ENABLE_SHIFT;
909 
910    return ok;
911 }
912 
913 #undef REF_COLOR
914 #undef REF_ALPHA
915 
916 
917 #define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK |		\
918 			      R200_MIN_FILTER_MASK | 		\
919 			      R200_MAG_FILTER_MASK |		\
920 			      R200_MAX_ANISO_MASK |		\
921 			      R200_YUV_TO_RGB |			\
922 			      R200_YUV_TEMPERATURE_MASK |	\
923 			      R200_CLAMP_S_MASK | 		\
924 			      R200_CLAMP_T_MASK | 		\
925 			      R200_BORDER_MODE_D3D )
926 
927 #define TEXOBJ_TXFORMAT_MASK (R200_TXFORMAT_WIDTH_MASK |	\
928 			      R200_TXFORMAT_HEIGHT_MASK |	\
929 			      R200_TXFORMAT_FORMAT_MASK |	\
930 			      R200_TXFORMAT_F5_WIDTH_MASK |	\
931 			      R200_TXFORMAT_F5_HEIGHT_MASK |	\
932 			      R200_TXFORMAT_ALPHA_IN_MAP |	\
933 			      R200_TXFORMAT_CUBIC_MAP_ENABLE |	\
934 			      R200_TXFORMAT_NON_POWER2)
935 
936 #define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK |		\
937                                 R200_TEXCOORD_MASK |		\
938                                 R200_MIN_MIP_LEVEL_MASK |	\
939                                 R200_CLAMP_Q_MASK | 		\
940                                 R200_VOLUME_FILTER_MASK)
941 
942 
disable_tex_obj_state(r200ContextPtr rmesa,int unit)943 static void disable_tex_obj_state( r200ContextPtr rmesa,
944 				   int unit )
945 {
946 
947    R200_STATECHANGE( rmesa, vtx );
948    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
949 
950    R200_STATECHANGE( rmesa, ctx );
951    rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_TEX_0_ENABLE << unit);
952    if (rmesa->radeon.TclFallback & (R200_TCL_FALLBACK_TEXGEN_0<<unit)) {
953       TCL_FALLBACK( &rmesa->radeon.glCtx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
954    }
955 
956    /* Actually want to keep all units less than max active texture
957     * enabled, right?  Fix this for >2 texunits.
958     */
959 
960    {
961       GLuint tmp = rmesa->TexGenEnabled;
962 
963       rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
964       rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
965       rmesa->TexGenNeedNormals[unit] = GL_FALSE;
966       rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
967 
968       if (tmp != rmesa->TexGenEnabled) {
969 	 rmesa->recheck_texgen[unit] = GL_TRUE;
970 	 rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
971       }
972    }
973 }
import_tex_obj_state(r200ContextPtr rmesa,int unit,radeonTexObjPtr texobj)974 static void import_tex_obj_state( r200ContextPtr rmesa,
975 				  int unit,
976 				  radeonTexObjPtr texobj )
977 {
978 /* do not use RADEON_DB_STATE to avoid stale texture caches */
979    GLuint *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
980 
981    R200_STATECHANGE( rmesa, tex[unit] );
982 
983    cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK;
984    cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK;
985    cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
986    cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK;
987    cmd[TEX_PP_TXFORMAT_X] &= ~TEXOBJ_TXFORMAT_X_MASK;
988    cmd[TEX_PP_TXFORMAT_X] |= texobj->pp_txformat_x & TEXOBJ_TXFORMAT_X_MASK;
989    cmd[TEX_PP_TXSIZE] = texobj->pp_txsize; /* NPOT only! */
990    cmd[TEX_PP_TXPITCH] = texobj->pp_txpitch; /* NPOT only! */
991    cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
992 
993    if (texobj->base.Target == GL_TEXTURE_CUBE_MAP) {
994       GLuint *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
995 
996       R200_STATECHANGE( rmesa, cube[unit] );
997       cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
998       /* that value is submitted twice. could change cube atom
999          to not include that command when new drm is used */
1000       cmd[TEX_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
1001    }
1002 
1003 }
1004 
set_texgen_matrix(r200ContextPtr rmesa,GLuint unit,const GLfloat * s_plane,const GLfloat * t_plane,const GLfloat * r_plane,const GLfloat * q_plane)1005 static void set_texgen_matrix( r200ContextPtr rmesa,
1006 			       GLuint unit,
1007 			       const GLfloat *s_plane,
1008 			       const GLfloat *t_plane,
1009 			       const GLfloat *r_plane,
1010 			       const GLfloat *q_plane )
1011 {
1012    GLfloat m[16];
1013 
1014    m[0]  = s_plane[0];
1015    m[4]  = s_plane[1];
1016    m[8]  = s_plane[2];
1017    m[12] = s_plane[3];
1018 
1019    m[1]  = t_plane[0];
1020    m[5]  = t_plane[1];
1021    m[9]  = t_plane[2];
1022    m[13] = t_plane[3];
1023 
1024    m[2]  = r_plane[0];
1025    m[6]  = r_plane[1];
1026    m[10] = r_plane[2];
1027    m[14] = r_plane[3];
1028 
1029    m[3]  = q_plane[0];
1030    m[7]  = q_plane[1];
1031    m[11] = q_plane[2];
1032    m[15] = q_plane[3];
1033 
1034    _math_matrix_loadf( &(rmesa->TexGenMatrix[unit]), m);
1035    _math_matrix_analyse( &(rmesa->TexGenMatrix[unit]) );
1036    rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit;
1037 }
1038 
1039 
r200_need_dis_texgen(const GLbitfield texGenEnabled,const GLfloat * planeS,const GLfloat * planeT,const GLfloat * planeR,const GLfloat * planeQ)1040 static GLuint r200_need_dis_texgen(const GLbitfield texGenEnabled,
1041 				   const GLfloat *planeS,
1042 				   const GLfloat *planeT,
1043 				   const GLfloat *planeR,
1044 				   const GLfloat *planeQ)
1045 {
1046    GLuint needtgenable = 0;
1047 
1048    if (!(texGenEnabled & S_BIT)) {
1049       if (((texGenEnabled & T_BIT) && planeT[0] != 0.0) ||
1050 	 ((texGenEnabled & R_BIT) && planeR[0] != 0.0) ||
1051 	 ((texGenEnabled & Q_BIT) && planeQ[0] != 0.0)) {
1052 	 needtgenable |= S_BIT;
1053       }
1054    }
1055    if (!(texGenEnabled & T_BIT)) {
1056       if (((texGenEnabled & S_BIT) && planeS[1] != 0.0) ||
1057 	 ((texGenEnabled & R_BIT) && planeR[1] != 0.0) ||
1058 	 ((texGenEnabled & Q_BIT) && planeQ[1] != 0.0)) {
1059 	 needtgenable |= T_BIT;
1060      }
1061    }
1062    if (!(texGenEnabled & R_BIT)) {
1063       if (((texGenEnabled & S_BIT) && planeS[2] != 0.0) ||
1064 	 ((texGenEnabled & T_BIT) && planeT[2] != 0.0) ||
1065 	 ((texGenEnabled & Q_BIT) && planeQ[2] != 0.0)) {
1066 	 needtgenable |= R_BIT;
1067       }
1068    }
1069    if (!(texGenEnabled & Q_BIT)) {
1070       if (((texGenEnabled & S_BIT) && planeS[3] != 0.0) ||
1071 	 ((texGenEnabled & T_BIT) && planeT[3] != 0.0) ||
1072 	 ((texGenEnabled & R_BIT) && planeR[3] != 0.0)) {
1073 	 needtgenable |= Q_BIT;
1074       }
1075    }
1076 
1077    return needtgenable;
1078 }
1079 
1080 
1081 /*
1082  * Returns GL_FALSE if fallback required.
1083  */
r200_validate_texgen(struct gl_context * ctx,GLuint unit)1084 static GLboolean r200_validate_texgen( struct gl_context *ctx, GLuint unit )
1085 {
1086    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1087    const struct gl_fixedfunc_texture_unit *texUnit =
1088       &ctx->Texture.FixedFuncUnit[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 #if UTIL_ARCH_LITTLE_ENDIAN
1312 	 const struct tx_table *table = tx_table_le;
1313 #else
1314 	 const struct tx_table *table = tx_table_be;
1315 #endif
1316 
1317 	 t->pp_txformat &= ~(R200_TXFORMAT_FORMAT_MASK |
1318 			     R200_TXFORMAT_ALPHA_IN_MAP);
1319 	 t->pp_txfilter &= ~R200_YUV_TO_RGB;
1320 
1321 	 t->pp_txformat |= table[ firstImage->TexFormat ].format;
1322 	 t->pp_txfilter |= table[ firstImage->TexFormat ].filter;
1323 
1324 
1325       } else {
1326 	 _mesa_problem(NULL, "unexpected texture format in %s",
1327 		       __func__);
1328 	 return;
1329       }
1330    }
1331 
1332    t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK;
1333    t->pp_txfilter |= ((t->maxLod) << R200_MAX_MIP_LEVEL_SHIFT)
1334 	   & R200_MAX_MIP_LEVEL_MASK;
1335 
1336    if ( t->pp_txfilter &
1337 		(R200_MIN_FILTER_NEAREST_MIP_NEAREST
1338 		 | R200_MIN_FILTER_NEAREST_MIP_LINEAR
1339 		 | R200_MIN_FILTER_LINEAR_MIP_NEAREST
1340 		 | R200_MIN_FILTER_LINEAR_MIP_LINEAR
1341 		 | R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST
1342 		 | R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR))
1343 		 extra_size = t->minLod;
1344 
1345    t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
1346 		       R200_TXFORMAT_HEIGHT_MASK |
1347 		       R200_TXFORMAT_CUBIC_MAP_ENABLE |
1348 		       R200_TXFORMAT_F5_WIDTH_MASK |
1349 		       R200_TXFORMAT_F5_HEIGHT_MASK);
1350    t->pp_txformat |= (((log2Width + extra_size) << R200_TXFORMAT_WIDTH_SHIFT) |
1351 		      ((log2Height + extra_size)<< R200_TXFORMAT_HEIGHT_SHIFT));
1352 
1353    t->tile_bits = 0;
1354 
1355    t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK
1356 		   | R200_MIN_MIP_LEVEL_MASK);
1357 
1358    t->pp_txformat_x |= (t->minLod << R200_MIN_MIP_LEVEL_SHIFT)
1359 	   & R200_MIN_MIP_LEVEL_MASK;
1360 
1361    if (t->base.Target == GL_TEXTURE_3D) {
1362       t->pp_txformat_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT);
1363       t->pp_txformat_x |= R200_TEXCOORD_VOLUME;
1364 
1365    }
1366    else if (t->base.Target == GL_TEXTURE_CUBE_MAP) {
1367       assert(log2Width == log2Height);
1368       t->pp_txformat |= ((log2Width << R200_TXFORMAT_F5_WIDTH_SHIFT) |
1369 			 (log2Height << R200_TXFORMAT_F5_HEIGHT_SHIFT) |
1370 			 /* don't think we need this bit, if it exists at all - fglrx does not set it */
1371 			 (R200_TXFORMAT_CUBIC_MAP_ENABLE));
1372       t->pp_txformat_x |= R200_TEXCOORD_CUBIC_ENV;
1373       t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) |
1374                            (log2Height << R200_FACE_HEIGHT_1_SHIFT) |
1375                            (log2Width << R200_FACE_WIDTH_2_SHIFT) |
1376                            (log2Height << R200_FACE_HEIGHT_2_SHIFT) |
1377                            (log2Width << R200_FACE_WIDTH_3_SHIFT) |
1378                            (log2Height << R200_FACE_HEIGHT_3_SHIFT) |
1379                            (log2Width << R200_FACE_WIDTH_4_SHIFT) |
1380                            (log2Height << R200_FACE_HEIGHT_4_SHIFT));
1381    }
1382    else {
1383       /* If we don't in fact send enough texture coordinates, q will be 1,
1384        * making TEXCOORD_PROJ act like TEXCOORD_NONPROJ (Right?)
1385        */
1386       t->pp_txformat_x |= R200_TEXCOORD_PROJ;
1387    }
1388    /* FIXME: NPOT sizes, is it correct really? */
1389    t->pp_txsize = (((firstImage->Width - 1) << R200_PP_TX_WIDTHMASK_SHIFT)
1390 		   | ((firstImage->Height - 1) << R200_PP_TX_HEIGHTMASK_SHIFT));
1391 
1392    if ( !t->image_override ) {
1393       if (_mesa_is_format_compressed(firstImage->TexFormat))
1394          t->pp_txpitch = (firstImage->Width + 63) & ~(63);
1395       else
1396          t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63);
1397       t->pp_txpitch -= 32;
1398    }
1399 
1400    if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
1401       t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
1402    }
1403 
1404 }
1405 
r200_validate_texture(struct gl_context * ctx,struct gl_texture_object * texObj,int unit)1406 static GLboolean r200_validate_texture(struct gl_context *ctx, struct gl_texture_object *texObj, int unit)
1407 {
1408    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1409    radeonTexObj *t = radeon_tex_obj(texObj);
1410 
1411    if (!radeon_validate_texture_miptree(ctx, _mesa_get_samplerobj(ctx, unit), texObj))
1412       return GL_FALSE;
1413 
1414    r200_validate_texgen(ctx, unit);
1415    /* Configure the hardware registers (more precisely, the cached version
1416     * of the hardware registers). */
1417    setup_hardware_state(rmesa, t);
1418 
1419    if (texObj->Target == GL_TEXTURE_RECTANGLE_NV ||
1420        texObj->Target == GL_TEXTURE_2D ||
1421        texObj->Target == GL_TEXTURE_1D)
1422       set_re_cntl_d3d( ctx, unit, GL_FALSE );
1423    else
1424       set_re_cntl_d3d( ctx, unit, GL_TRUE );
1425    R200_STATECHANGE( rmesa, ctx );
1426    rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << unit;
1427 
1428    R200_STATECHANGE( rmesa, vtx );
1429    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
1430    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3);
1431 
1432    rmesa->recheck_texgen[unit] = GL_TRUE;
1433    r200TexUpdateParameters(ctx, unit);
1434    import_tex_obj_state( rmesa, unit, t );
1435 
1436    if (rmesa->recheck_texgen[unit]) {
1437       GLboolean fallback = !r200_validate_texgen( ctx, unit );
1438       TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
1439       rmesa->recheck_texgen[unit] = 0;
1440       rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
1441    }
1442 
1443    t->validated = GL_TRUE;
1444 
1445    FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback );
1446 
1447    return !t->border_fallback;
1448 }
1449 
r200UpdateTextureUnit(struct gl_context * ctx,int unit)1450 static GLboolean r200UpdateTextureUnit(struct gl_context *ctx, int unit)
1451 {
1452    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1453    GLuint unitneeded = rmesa->state.texture.unit[unit].unitneeded;
1454 
1455    if (!unitneeded) {
1456       /* disable the unit */
1457      disable_tex_obj_state(rmesa, unit);
1458      return GL_TRUE;
1459    }
1460 
1461    if (!r200_validate_texture(ctx, ctx->Texture.Unit[unit]._Current, unit)) {
1462     _mesa_warning(ctx,
1463 		  "failed to validate texture for unit %d.\n",
1464 		  unit);
1465     rmesa->state.texture.unit[unit].texobj = NULL;
1466     return GL_FALSE;
1467   }
1468 
1469    rmesa->state.texture.unit[unit].texobj = radeon_tex_obj(ctx->Texture.Unit[unit]._Current);
1470   return GL_TRUE;
1471 }
1472 
1473 
r200UpdateTextureState(struct gl_context * ctx)1474 void r200UpdateTextureState( struct gl_context *ctx )
1475 {
1476    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1477    GLboolean ok;
1478    GLuint dbg;
1479 
1480    /* NOTE: must not manipulate rmesa->state.texture.unit[].unitneeded or
1481       rmesa->state.envneeded before a R200_STATECHANGE (or R200_NEWPRIM) since
1482       we use these to determine if we want to emit the corresponding state
1483       atoms. */
1484    R200_NEWPRIM( rmesa );
1485 
1486    if (_mesa_ati_fragment_shader_enabled(ctx)) {
1487       GLuint i;
1488       for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) {
1489          if (ctx->Texture.Unit[i]._Current)
1490             rmesa->state.texture.unit[i].unitneeded = 1 << _mesa_tex_target_to_index(ctx, ctx->Texture.Unit[i]._Current->Target);
1491          else
1492             rmesa->state.texture.unit[i].unitneeded = 0;
1493       }
1494       ok = GL_TRUE;
1495    }
1496    else {
1497       ok = r200UpdateAllTexEnv( ctx );
1498    }
1499    if (ok) {
1500       ok = (r200UpdateTextureUnit( ctx, 0 ) &&
1501 	 r200UpdateTextureUnit( ctx, 1 ) &&
1502 	 r200UpdateTextureUnit( ctx, 2 ) &&
1503 	 r200UpdateTextureUnit( ctx, 3 ) &&
1504 	 r200UpdateTextureUnit( ctx, 4 ) &&
1505 	 r200UpdateTextureUnit( ctx, 5 ));
1506    }
1507 
1508    if (ok && _mesa_ati_fragment_shader_enabled(ctx)) {
1509       r200UpdateFragmentShader(ctx);
1510    }
1511 
1512    FALLBACK( rmesa, R200_FALLBACK_TEXTURE, !ok );
1513 
1514    if (rmesa->radeon.TclFallback)
1515       r200ChooseVertexState( ctx );
1516 
1517 
1518    if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) {
1519 
1520       /*
1521        * T0 hang workaround -------------
1522        * not needed for r200 derivatives
1523         */
1524       if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_ENABLE_MASK) == R200_TEX_0_ENABLE &&
1525 	 (rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > R200_MIN_FILTER_LINEAR) {
1526 
1527 	 R200_STATECHANGE(rmesa, ctx);
1528 	 R200_STATECHANGE(rmesa, tex[1]);
1529 	 rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_1_ENABLE;
1530 	 if (!(rmesa->hw.cst.cmd[CST_PP_CNTL_X] & R200_PPX_TEX_1_ENABLE))
1531 	   rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1532 	 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] |= R200_TXFORMAT_LOOKUP_DISABLE;
1533       }
1534       else if (!_mesa_ati_fragment_shader_enabled(ctx)) {
1535 	 if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE) &&
1536 	    (rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] & R200_TXFORMAT_LOOKUP_DISABLE)) {
1537 	    R200_STATECHANGE(rmesa, tex[1]);
1538 	    rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~R200_TXFORMAT_LOOKUP_DISABLE;
1539          }
1540       }
1541       /* do the same workaround for the first pass of a fragment shader.
1542        * completely unknown if necessary / sufficient.
1543        */
1544       if ((rmesa->hw.cst.cmd[CST_PP_CNTL_X] & R200_PPX_TEX_ENABLE_MASK) == R200_PPX_TEX_0_ENABLE &&
1545 	 (rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > R200_MIN_FILTER_LINEAR) {
1546 
1547 	 R200_STATECHANGE(rmesa, cst);
1548 	 R200_STATECHANGE(rmesa, tex[1]);
1549 	 rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_1_ENABLE;
1550 	 if (!(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE))
1551 	    rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1552 	 rmesa->hw.tex[1].cmd[TEX_PP_TXMULTI_CTL] |= R200_PASS1_TXFORMAT_LOOKUP_DISABLE;
1553       }
1554 
1555       /* maybe needs to be done pairwise due to 2 parallel (physical) tex units ?
1556          looks like that's not the case, if 8500/9100 owners don't complain remove this...
1557       for ( i = 0; i < ctx->Const.MaxTextureUnits; i += 2) {
1558          if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & ((R200_TEX_0_ENABLE |
1559             R200_TEX_1_ENABLE ) << i)) == (R200_TEX_0_ENABLE << i)) &&
1560             ((rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) >
1561             R200_MIN_FILTER_LINEAR)) {
1562             R200_STATECHANGE(rmesa, ctx);
1563             R200_STATECHANGE(rmesa, tex[i+1]);
1564             rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_1_ENABLE << i);
1565             rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1566             rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] |= 0x08000000;
1567          }
1568          else {
1569             if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE << i)) &&
1570                (rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] & 0x08000000)) {
1571                R200_STATECHANGE(rmesa, tex[i+1]);
1572                rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~0x08000000;
1573             }
1574          }
1575       } */
1576 
1577       /*
1578        * Texture cache LRU hang workaround -------------
1579        * not needed for r200 derivatives
1580        * hopefully this covers first pass of a shader as well
1581        */
1582 
1583       /* While the cases below attempt to only enable the workaround in the
1584        * specific cases necessary, they were insufficient.  See bugzilla #1519,
1585        * #729, #814.  Tests with quake3 showed no impact on performance.
1586        */
1587       dbg = 0x6;
1588 
1589       /*
1590       if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE )) &&
1591          ((((rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1592          0x04) == 0)) ||
1593          ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_2_ENABLE) &&
1594          ((((rmesa->hw.tex[2].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1595          0x04) == 0)) ||
1596          ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_4_ENABLE) &&
1597          ((((rmesa->hw.tex[4].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1598          0x04) == 0)))
1599       {
1600          dbg |= 0x02;
1601       }
1602 
1603       if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE )) &&
1604          ((((rmesa->hw.tex[1].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1605          0x04) == 0)) ||
1606          ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_3_ENABLE) &&
1607          ((((rmesa->hw.tex[3].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1608          0x04) == 0)) ||
1609          ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_5_ENABLE) &&
1610          ((((rmesa->hw.tex[5].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1611          0x04) == 0)))
1612       {
1613          dbg |= 0x04;
1614       }*/
1615 
1616       if (dbg != rmesa->hw.tam.cmd[TAM_DEBUG3]) {
1617          R200_STATECHANGE( rmesa, tam );
1618          rmesa->hw.tam.cmd[TAM_DEBUG3] = dbg;
1619          if (0) printf("TEXCACHE LRU HANG WORKAROUND %x\n", dbg);
1620       }
1621    }
1622 }
1623