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