1 /**************************************************************************
2 
3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4                      VA Linux Systems Inc., Fremont, California.
5 
6 All Rights Reserved.
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  *   Kevin E. Martin <martin@valinux.com>
33  *   Gareth Hughes <gareth@valinux.com>
34  */
35 
36 #include "main/glheader.h"
37 #include "main/context.h"
38 #include "main/macros.h"
39 #include "main/teximage.h"
40 #include "main/texstate.h"
41 #include "main/texobj.h"
42 #include "main/enums.h"
43 #include "main/samplerobj.h"
44 
45 #include "radeon_context.h"
46 #include "radeon_mipmap_tree.h"
47 #include "radeon_state.h"
48 #include "radeon_ioctl.h"
49 #include "radeon_swtcl.h"
50 #include "radeon_tex.h"
51 #include "radeon_tcl.h"
52 
53 
54 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \
55 			     && (tx_table[f].format != 0xffffffff) )
56 
57 /* ================================================================
58  * Texture combine functions
59  */
60 
61 /* GL_ARB_texture_env_combine support
62  */
63 
64 /* The color tables have combine functions for GL_SRC_COLOR,
65  * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
66  */
67 static GLuint radeon_texture_color[][RADEON_MAX_TEXTURE_UNITS] =
68 {
69    {
70       RADEON_COLOR_ARG_A_T0_COLOR,
71       RADEON_COLOR_ARG_A_T1_COLOR,
72       RADEON_COLOR_ARG_A_T2_COLOR
73    },
74    {
75       RADEON_COLOR_ARG_A_T0_COLOR | RADEON_COMP_ARG_A,
76       RADEON_COLOR_ARG_A_T1_COLOR | RADEON_COMP_ARG_A,
77       RADEON_COLOR_ARG_A_T2_COLOR | RADEON_COMP_ARG_A
78    },
79    {
80       RADEON_COLOR_ARG_A_T0_ALPHA,
81       RADEON_COLOR_ARG_A_T1_ALPHA,
82       RADEON_COLOR_ARG_A_T2_ALPHA
83    },
84    {
85       RADEON_COLOR_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
86       RADEON_COLOR_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
87       RADEON_COLOR_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
88    },
89 };
90 
91 static GLuint radeon_tfactor_color[] =
92 {
93    RADEON_COLOR_ARG_A_TFACTOR_COLOR,
94    RADEON_COLOR_ARG_A_TFACTOR_COLOR | RADEON_COMP_ARG_A,
95    RADEON_COLOR_ARG_A_TFACTOR_ALPHA,
96    RADEON_COLOR_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
97 };
98 
99 static GLuint radeon_primary_color[] =
100 {
101    RADEON_COLOR_ARG_A_DIFFUSE_COLOR,
102    RADEON_COLOR_ARG_A_DIFFUSE_COLOR | RADEON_COMP_ARG_A,
103    RADEON_COLOR_ARG_A_DIFFUSE_ALPHA,
104    RADEON_COLOR_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
105 };
106 
107 static GLuint radeon_previous_color[] =
108 {
109    RADEON_COLOR_ARG_A_CURRENT_COLOR,
110    RADEON_COLOR_ARG_A_CURRENT_COLOR | RADEON_COMP_ARG_A,
111    RADEON_COLOR_ARG_A_CURRENT_ALPHA,
112    RADEON_COLOR_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
113 };
114 
115 /* GL_ZERO table - indices 0-3
116  * GL_ONE  table - indices 1-4
117  */
118 static GLuint radeon_zero_color[] =
119 {
120    RADEON_COLOR_ARG_A_ZERO,
121    RADEON_COLOR_ARG_A_ZERO | RADEON_COMP_ARG_A,
122    RADEON_COLOR_ARG_A_ZERO,
123    RADEON_COLOR_ARG_A_ZERO | RADEON_COMP_ARG_A,
124    RADEON_COLOR_ARG_A_ZERO
125 };
126 
127 
128 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
129  */
130 static GLuint radeon_texture_alpha[][RADEON_MAX_TEXTURE_UNITS] =
131 {
132    {
133       RADEON_ALPHA_ARG_A_T0_ALPHA,
134       RADEON_ALPHA_ARG_A_T1_ALPHA,
135       RADEON_ALPHA_ARG_A_T2_ALPHA
136    },
137    {
138       RADEON_ALPHA_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A,
139       RADEON_ALPHA_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A,
140       RADEON_ALPHA_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A
141    },
142 };
143 
144 static GLuint radeon_tfactor_alpha[] =
145 {
146    RADEON_ALPHA_ARG_A_TFACTOR_ALPHA,
147    RADEON_ALPHA_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A
148 };
149 
150 static GLuint radeon_primary_alpha[] =
151 {
152    RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA,
153    RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A
154 };
155 
156 static GLuint radeon_previous_alpha[] =
157 {
158    RADEON_ALPHA_ARG_A_CURRENT_ALPHA,
159    RADEON_ALPHA_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A
160 };
161 
162 /* GL_ZERO table - indices 0-1
163  * GL_ONE  table - indices 1-2
164  */
165 static GLuint radeon_zero_alpha[] =
166 {
167    RADEON_ALPHA_ARG_A_ZERO,
168    RADEON_ALPHA_ARG_A_ZERO | RADEON_COMP_ARG_A,
169    RADEON_ALPHA_ARG_A_ZERO
170 };
171 
172 
173 /* Extract the arg from slot A, shift it into the correct argument slot
174  * and set the corresponding complement bit.
175  */
176 #define RADEON_COLOR_ARG( n, arg )			\
177 do {							\
178    color_combine |=					\
179       ((color_arg[n] & RADEON_COLOR_ARG_MASK)		\
180        << RADEON_COLOR_ARG_##arg##_SHIFT);		\
181    color_combine |=					\
182       ((color_arg[n] >> RADEON_COMP_ARG_SHIFT)		\
183        << RADEON_COMP_ARG_##arg##_SHIFT);		\
184 } while (0)
185 
186 #define RADEON_ALPHA_ARG( n, arg )			\
187 do {							\
188    alpha_combine |=					\
189       ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK)		\
190        << RADEON_ALPHA_ARG_##arg##_SHIFT);		\
191    alpha_combine |=					\
192       ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT)		\
193        << RADEON_COMP_ARG_##arg##_SHIFT);		\
194 } while (0)
195 
196 
197 /* ================================================================
198  * Texture unit state management
199  */
200 
201 static GLenum
texture_base_format(const struct gl_texture_object * t)202 texture_base_format(const struct gl_texture_object *t)
203 {
204 	return t->Image[0][t->Attrib.BaseLevel]->_BaseFormat;
205 }
206 
radeonUpdateTextureEnv(struct gl_context * ctx,int unit)207 static GLboolean radeonUpdateTextureEnv( struct gl_context *ctx, int unit )
208 {
209    r100ContextPtr rmesa = R100_CONTEXT(ctx);
210    const struct gl_texture_unit *rtexUnit = &ctx->Texture.Unit[unit];
211    const struct gl_fixedfunc_texture_unit *texUnit =
212       &ctx->Texture.FixedFuncUnit[unit];
213    GLuint color_combine, alpha_combine;
214    const GLuint color_combine0 = RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO
215          | RADEON_COLOR_ARG_C_CURRENT_COLOR | RADEON_BLEND_CTL_ADD
216          | RADEON_SCALE_1X | RADEON_CLAMP_TX;
217    const GLuint alpha_combine0 = RADEON_ALPHA_ARG_A_ZERO | RADEON_ALPHA_ARG_B_ZERO
218          | RADEON_ALPHA_ARG_C_CURRENT_ALPHA | RADEON_BLEND_CTL_ADD
219          | RADEON_SCALE_1X | RADEON_CLAMP_TX;
220 
221 
222    if ( RADEON_DEBUG & RADEON_TEXTURE ) {
223       fprintf( stderr, "%s( %p, %d )\n", __func__, (void *)ctx, unit );
224    }
225 
226    /* Set the texture environment state.  Isn't this nice and clean?
227     * The chip will automagically set the texture alpha to 0xff when
228     * the texture format does not include an alpha component. This
229     * reduces the amount of special-casing we have to do, alpha-only
230     * textures being a notable exception. Doesn't work for luminance
231     * textures realized with I8 and ALPHA_IN_MAP not set neither (on r100).
232     */
233     /* Don't cache these results.
234     */
235    rmesa->state.texture.unit[unit].format = 0;
236    rmesa->state.texture.unit[unit].envMode = 0;
237 
238    if ( !rtexUnit->_Current ) {
239       color_combine = color_combine0;
240       alpha_combine = alpha_combine0;
241    }
242    else {
243       GLuint color_arg[3], alpha_arg[3];
244       GLuint i;
245       const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
246       const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
247       GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB;
248       GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA;
249 
250 
251       /* Step 1:
252        * Extract the color and alpha combine function arguments.
253        */
254       for ( i = 0 ; i < numColorArgs ; i++ ) {
255 	 const GLint op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR;
256 	 const GLuint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i];
257 	 assert(op >= 0);
258 	 assert(op <= 3);
259 	 switch ( srcRGBi ) {
260 	 case GL_TEXTURE:
261 	    if (texture_base_format(rtexUnit->_Current) == GL_ALPHA)
262 	       color_arg[i] = radeon_zero_color[op];
263 	    else
264 	       color_arg[i] = radeon_texture_color[op][unit];
265 	    break;
266 	 case GL_CONSTANT:
267 	    color_arg[i] = radeon_tfactor_color[op];
268 	    break;
269 	 case GL_PRIMARY_COLOR:
270 	    color_arg[i] = radeon_primary_color[op];
271 	    break;
272 	 case GL_PREVIOUS:
273 	    color_arg[i] = radeon_previous_color[op];
274 	    break;
275 	 case GL_ZERO:
276 	    color_arg[i] = radeon_zero_color[op];
277 	    break;
278 	 case GL_ONE:
279 	    color_arg[i] = radeon_zero_color[op+1];
280 	    break;
281 	 case GL_TEXTURE0:
282 	 case GL_TEXTURE1:
283 	 case GL_TEXTURE2: {
284 	    GLuint txunit = srcRGBi - GL_TEXTURE0;
285 	    if (texture_base_format(ctx->Texture.Unit[txunit]._Current) == GL_ALPHA)
286 	       color_arg[i] = radeon_zero_color[op];
287 	    else
288 	 /* implement ogl 1.4/1.5 core spec here, not specification of
289 	  * GL_ARB_texture_env_crossbar (which would require disabling blending
290 	  * instead of undefined results when referencing not enabled texunit) */
291 	      color_arg[i] = radeon_texture_color[op][txunit];
292 	    }
293 	    break;
294 	 default:
295 	    return GL_FALSE;
296 	 }
297       }
298 
299       for ( i = 0 ; i < numAlphaArgs ; i++ ) {
300 	 const GLint op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA;
301 	 const GLuint srcAi = texUnit->_CurrentCombine->SourceA[i];
302 	 assert(op >= 0);
303 	 assert(op <= 1);
304 	 switch ( srcAi ) {
305 	 case GL_TEXTURE:
306 	    if (texture_base_format(rtexUnit->_Current) == GL_LUMINANCE)
307 	       alpha_arg[i] = radeon_zero_alpha[op+1];
308 	    else
309 	       alpha_arg[i] = radeon_texture_alpha[op][unit];
310 	    break;
311 	 case GL_CONSTANT:
312 	    alpha_arg[i] = radeon_tfactor_alpha[op];
313 	    break;
314 	 case GL_PRIMARY_COLOR:
315 	    alpha_arg[i] = radeon_primary_alpha[op];
316 	    break;
317 	 case GL_PREVIOUS:
318 	    alpha_arg[i] = radeon_previous_alpha[op];
319 	    break;
320 	 case GL_ZERO:
321 	    alpha_arg[i] = radeon_zero_alpha[op];
322 	    break;
323 	 case GL_ONE:
324 	    alpha_arg[i] = radeon_zero_alpha[op+1];
325 	    break;
326 	 case GL_TEXTURE0:
327 	 case GL_TEXTURE1:
328 	 case GL_TEXTURE2: {
329 	    GLuint txunit = srcAi - GL_TEXTURE0;
330 	    if (texture_base_format(ctx->Texture.Unit[txunit]._Current) == GL_LUMINANCE)
331 	       alpha_arg[i] = radeon_zero_alpha[op+1];
332 	    else
333 	       alpha_arg[i] = radeon_texture_alpha[op][txunit];
334 	    }
335 	    break;
336 	 default:
337 	    return GL_FALSE;
338 	 }
339       }
340 
341       /* Step 2:
342        * Build up the color and alpha combine functions.
343        */
344       switch ( texUnit->_CurrentCombine->ModeRGB ) {
345       case GL_REPLACE:
346 	 color_combine = (RADEON_COLOR_ARG_A_ZERO |
347 			  RADEON_COLOR_ARG_B_ZERO |
348 			  RADEON_BLEND_CTL_ADD |
349 			  RADEON_CLAMP_TX);
350 	 RADEON_COLOR_ARG( 0, C );
351 	 break;
352       case GL_MODULATE:
353 	 color_combine = (RADEON_COLOR_ARG_C_ZERO |
354 			  RADEON_BLEND_CTL_ADD |
355 			  RADEON_CLAMP_TX);
356 	 RADEON_COLOR_ARG( 0, A );
357 	 RADEON_COLOR_ARG( 1, B );
358 	 break;
359       case GL_ADD:
360 	 color_combine = (RADEON_COLOR_ARG_B_ZERO |
361 			  RADEON_COMP_ARG_B |
362 			  RADEON_BLEND_CTL_ADD |
363 			  RADEON_CLAMP_TX);
364 	 RADEON_COLOR_ARG( 0, A );
365 	 RADEON_COLOR_ARG( 1, C );
366 	 break;
367       case GL_ADD_SIGNED:
368 	 color_combine = (RADEON_COLOR_ARG_B_ZERO |
369 			  RADEON_COMP_ARG_B |
370 			  RADEON_BLEND_CTL_ADDSIGNED |
371 			  RADEON_CLAMP_TX);
372 	 RADEON_COLOR_ARG( 0, A );
373 	 RADEON_COLOR_ARG( 1, C );
374 	 break;
375       case GL_SUBTRACT:
376 	 color_combine = (RADEON_COLOR_ARG_B_ZERO |
377 			  RADEON_COMP_ARG_B |
378 			  RADEON_BLEND_CTL_SUBTRACT |
379 			  RADEON_CLAMP_TX);
380 	 RADEON_COLOR_ARG( 0, A );
381 	 RADEON_COLOR_ARG( 1, C );
382 	 break;
383       case GL_INTERPOLATE:
384 	 color_combine = (RADEON_BLEND_CTL_BLEND |
385 			  RADEON_CLAMP_TX);
386 	 RADEON_COLOR_ARG( 0, B );
387 	 RADEON_COLOR_ARG( 1, A );
388 	 RADEON_COLOR_ARG( 2, C );
389 	 break;
390 
391       case GL_DOT3_RGB_EXT:
392       case GL_DOT3_RGBA_EXT:
393 	 /* The EXT version of the DOT3 extension does not support the
394 	  * scale factor, but the ARB version (and the version in OpenGL
395 	  * 1.3) does.
396 	  */
397 	 RGBshift = 0;
398 	 FALLTHROUGH;
399 
400       case GL_DOT3_RGB:
401       case GL_DOT3_RGBA:
402 	 /* The R100 / RV200 only support a 1X multiplier in hardware
403 	  * w/the ARB version.
404 	  */
405 	 if ( RGBshift != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) ) {
406 	    return GL_FALSE;
407 	 }
408 
409 	 RGBshift += 2;
410 	 if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT)
411 	    || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) {
412             /* is it necessary to set this or will it be ignored anyway? */
413 	    Ashift = RGBshift;
414 	 }
415 
416 	 color_combine = (RADEON_COLOR_ARG_C_ZERO |
417 			  RADEON_BLEND_CTL_DOT3 |
418 			  RADEON_CLAMP_TX);
419 	 RADEON_COLOR_ARG( 0, A );
420 	 RADEON_COLOR_ARG( 1, B );
421 	 break;
422 
423       case GL_MODULATE_ADD_ATI:
424 	 color_combine = (RADEON_BLEND_CTL_ADD |
425 			  RADEON_CLAMP_TX);
426 	 RADEON_COLOR_ARG( 0, A );
427 	 RADEON_COLOR_ARG( 1, C );
428 	 RADEON_COLOR_ARG( 2, B );
429 	 break;
430       case GL_MODULATE_SIGNED_ADD_ATI:
431 	 color_combine = (RADEON_BLEND_CTL_ADDSIGNED |
432 			  RADEON_CLAMP_TX);
433 	 RADEON_COLOR_ARG( 0, A );
434 	 RADEON_COLOR_ARG( 1, C );
435 	 RADEON_COLOR_ARG( 2, B );
436 	 break;
437       case GL_MODULATE_SUBTRACT_ATI:
438 	 color_combine = (RADEON_BLEND_CTL_SUBTRACT |
439 			  RADEON_CLAMP_TX);
440 	 RADEON_COLOR_ARG( 0, A );
441 	 RADEON_COLOR_ARG( 1, C );
442 	 RADEON_COLOR_ARG( 2, B );
443 	 break;
444       default:
445 	 return GL_FALSE;
446       }
447 
448       switch ( texUnit->_CurrentCombine->ModeA ) {
449       case GL_REPLACE:
450 	 alpha_combine = (RADEON_ALPHA_ARG_A_ZERO |
451 			  RADEON_ALPHA_ARG_B_ZERO |
452 			  RADEON_BLEND_CTL_ADD |
453 			  RADEON_CLAMP_TX);
454 	 RADEON_ALPHA_ARG( 0, C );
455 	 break;
456       case GL_MODULATE:
457 	 alpha_combine = (RADEON_ALPHA_ARG_C_ZERO |
458 			  RADEON_BLEND_CTL_ADD |
459 			  RADEON_CLAMP_TX);
460 	 RADEON_ALPHA_ARG( 0, A );
461 	 RADEON_ALPHA_ARG( 1, B );
462 	 break;
463       case GL_ADD:
464 	 alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
465 			  RADEON_COMP_ARG_B |
466 			  RADEON_BLEND_CTL_ADD |
467 			  RADEON_CLAMP_TX);
468 	 RADEON_ALPHA_ARG( 0, A );
469 	 RADEON_ALPHA_ARG( 1, C );
470 	 break;
471       case GL_ADD_SIGNED:
472 	 alpha_combine = (RADEON_ALPHA_ARG_B_ZERO |
473 			  RADEON_COMP_ARG_B |
474 			  RADEON_BLEND_CTL_ADDSIGNED |
475 			  RADEON_CLAMP_TX);
476 	 RADEON_ALPHA_ARG( 0, A );
477 	 RADEON_ALPHA_ARG( 1, C );
478 	 break;
479       case GL_SUBTRACT:
480 	 alpha_combine = (RADEON_COLOR_ARG_B_ZERO |
481 			  RADEON_COMP_ARG_B |
482 			  RADEON_BLEND_CTL_SUBTRACT |
483 			  RADEON_CLAMP_TX);
484 	 RADEON_ALPHA_ARG( 0, A );
485 	 RADEON_ALPHA_ARG( 1, C );
486 	 break;
487       case GL_INTERPOLATE:
488 	 alpha_combine = (RADEON_BLEND_CTL_BLEND |
489 			  RADEON_CLAMP_TX);
490 	 RADEON_ALPHA_ARG( 0, B );
491 	 RADEON_ALPHA_ARG( 1, A );
492 	 RADEON_ALPHA_ARG( 2, C );
493 	 break;
494 
495       case GL_MODULATE_ADD_ATI:
496 	 alpha_combine = (RADEON_BLEND_CTL_ADD |
497 			  RADEON_CLAMP_TX);
498 	 RADEON_ALPHA_ARG( 0, A );
499 	 RADEON_ALPHA_ARG( 1, C );
500 	 RADEON_ALPHA_ARG( 2, B );
501 	 break;
502       case GL_MODULATE_SIGNED_ADD_ATI:
503 	 alpha_combine = (RADEON_BLEND_CTL_ADDSIGNED |
504 			  RADEON_CLAMP_TX);
505 	 RADEON_ALPHA_ARG( 0, A );
506 	 RADEON_ALPHA_ARG( 1, C );
507 	 RADEON_ALPHA_ARG( 2, B );
508 	 break;
509       case GL_MODULATE_SUBTRACT_ATI:
510 	 alpha_combine = (RADEON_BLEND_CTL_SUBTRACT |
511 			  RADEON_CLAMP_TX);
512 	 RADEON_ALPHA_ARG( 0, A );
513 	 RADEON_ALPHA_ARG( 1, C );
514 	 RADEON_ALPHA_ARG( 2, B );
515 	 break;
516       default:
517 	 return GL_FALSE;
518       }
519 
520       if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB_EXT)
521 	   || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB) ) {
522 	 alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE;
523       }
524 
525       /* Step 3:
526        * Apply the scale factor.
527        */
528       color_combine |= (RGBshift << RADEON_SCALE_SHIFT);
529       alpha_combine |= (Ashift   << RADEON_SCALE_SHIFT);
530 
531       /* All done!
532        */
533    }
534 
535    if ( rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] != color_combine ||
536 	rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] != alpha_combine ) {
537       RADEON_STATECHANGE( rmesa, tex[unit] );
538       rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] = color_combine;
539       rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] = alpha_combine;
540    }
541 
542    return GL_TRUE;
543 }
544 
radeonSetTexBuffer2(__DRIcontext * pDRICtx,GLint target,GLint texture_format,__DRIdrawable * dPriv)545 void radeonSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint texture_format,
546 			 __DRIdrawable *dPriv)
547 {
548 	struct gl_texture_object *texObj;
549 	struct gl_texture_image *texImage;
550 	struct radeon_renderbuffer *rb;
551 	radeon_texture_image *rImage;
552 	radeonContextPtr radeon;
553 	struct radeon_framebuffer *rfb;
554 	radeonTexObjPtr t;
555 	uint32_t pitch_val;
556 	mesa_format texFormat;
557 
558 	radeon = pDRICtx->driverPrivate;
559 
560 	rfb = dPriv->driverPrivate;
561 	texObj = _mesa_get_current_tex_object(&radeon->glCtx, target);
562 	texImage = _mesa_get_tex_image(&radeon->glCtx, texObj, target, 0);
563 
564 	rImage = get_radeon_texture_image(texImage);
565 	t = radeon_tex_obj(texObj);
566         if (t == NULL) {
567     	    return;
568     	}
569 
570 	radeon_update_renderbuffers(pDRICtx, dPriv, GL_TRUE);
571 	rb = rfb->color_rb[0];
572 	if (rb->bo == NULL) {
573 		/* Failed to BO for the buffer */
574 		return;
575 	}
576 
577 	_mesa_lock_texture(&radeon->glCtx, texObj);
578 	if (t->bo) {
579 		radeon_bo_unref(t->bo);
580 		t->bo = NULL;
581 	}
582 	if (rImage->bo) {
583 		radeon_bo_unref(rImage->bo);
584 		rImage->bo = NULL;
585 	}
586 
587 	radeon_miptree_unreference(&t->mt);
588 	radeon_miptree_unreference(&rImage->mt);
589 
590 	rImage->bo = rb->bo;
591 	radeon_bo_ref(rImage->bo);
592 	t->bo = rb->bo;
593 	radeon_bo_ref(t->bo);
594 	t->tile_bits = 0;
595 	t->image_override = GL_TRUE;
596 	t->override_offset = 0;
597 	switch (rb->cpp) {
598 	case 4:
599 		if (texture_format == __DRI_TEXTURE_FORMAT_RGB)
600 			texFormat = MESA_FORMAT_BGR_UNORM8;
601 		else
602 			texFormat = MESA_FORMAT_B8G8R8A8_UNORM;
603 		break;
604 	case 3:
605 	default:
606 		texFormat = MESA_FORMAT_BGR_UNORM8;
607 		break;
608 	case 2:
609 		texFormat = MESA_FORMAT_B5G6R5_UNORM;
610 		break;
611 	}
612 
613         t->pp_txformat = tx_table[texFormat].format;
614         t->pp_txfilter |= tx_table[texFormat].filter;
615 
616 	_mesa_init_teximage_fields(&radeon->glCtx, texImage,
617 				   rb->base.Base.Width, rb->base.Base.Height,
618 				   1, 0,
619 				   rb->cpp, texFormat);
620 	rImage->base.RowStride = rb->pitch / rb->cpp;
621 
622 	t->pp_txpitch &= (1 << 13) -1;
623 	pitch_val = rb->pitch;
624 
625         t->pp_txsize = ((rb->base.Base.Width - 1) << RADEON_TEX_USIZE_SHIFT)
626 		| ((rb->base.Base.Height - 1) << RADEON_TEX_VSIZE_SHIFT);
627 	if (target == GL_TEXTURE_RECTANGLE_NV) {
628 		t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2;
629 		t->pp_txpitch = pitch_val;
630 		t->pp_txpitch -= 32;
631 	} else {
632 	  t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK |
633 			      RADEON_TXFORMAT_HEIGHT_MASK |
634 			      RADEON_TXFORMAT_CUBIC_MAP_ENABLE |
635 			      RADEON_TXFORMAT_F5_WIDTH_MASK |
636 			      RADEON_TXFORMAT_F5_HEIGHT_MASK);
637 	  t->pp_txformat |= ((texImage->WidthLog2 << RADEON_TXFORMAT_WIDTH_SHIFT) |
638 			     (texImage->HeightLog2 << RADEON_TXFORMAT_HEIGHT_SHIFT));
639 	}
640 	t->validated = GL_TRUE;
641 	_mesa_unlock_texture(&radeon->glCtx, texObj);
642 	return;
643 }
644 
645 
radeonSetTexBuffer(__DRIcontext * pDRICtx,GLint target,__DRIdrawable * dPriv)646 void radeonSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
647 {
648         radeonSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
649 }
650 
651 
652 #define TEXOBJ_TXFILTER_MASK (RADEON_MAX_MIP_LEVEL_MASK |	\
653 			      RADEON_MIN_FILTER_MASK | 		\
654 			      RADEON_MAG_FILTER_MASK |		\
655 			      RADEON_MAX_ANISO_MASK |		\
656 			      RADEON_YUV_TO_RGB |		\
657 			      RADEON_YUV_TEMPERATURE_MASK |	\
658 			      RADEON_CLAMP_S_MASK | 		\
659 			      RADEON_CLAMP_T_MASK | 		\
660 			      RADEON_BORDER_MODE_D3D )
661 
662 #define TEXOBJ_TXFORMAT_MASK (RADEON_TXFORMAT_WIDTH_MASK |	\
663 			      RADEON_TXFORMAT_HEIGHT_MASK |	\
664 			      RADEON_TXFORMAT_FORMAT_MASK |	\
665                               RADEON_TXFORMAT_F5_WIDTH_MASK |	\
666                               RADEON_TXFORMAT_F5_HEIGHT_MASK |	\
667 			      RADEON_TXFORMAT_ALPHA_IN_MAP |	\
668 			      RADEON_TXFORMAT_CUBIC_MAP_ENABLE |	\
669                               RADEON_TXFORMAT_NON_POWER2)
670 
671 
disable_tex_obj_state(r100ContextPtr rmesa,int unit)672 static void disable_tex_obj_state( r100ContextPtr rmesa,
673 				   int unit )
674 {
675    RADEON_STATECHANGE( rmesa, tex[unit] );
676 
677    RADEON_STATECHANGE( rmesa, tcl );
678    rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_ST_BIT(unit) |
679 					     RADEON_Q_BIT(unit));
680 
681    if (rmesa->radeon.TclFallback & (RADEON_TCL_FALLBACK_TEXGEN_0<<unit)) {
682      TCL_FALLBACK( &rmesa->radeon.glCtx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
683      rmesa->recheck_texgen[unit] = GL_TRUE;
684    }
685 
686    if (rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) {
687      /* this seems to be a genuine (r100 only?) hw bug. Need to remove the
688 	cubic_map bit on unit 2 when the unit is disabled, otherwise every
689 	2nd (2d) mipmap on unit 0 will be broken (may not be needed for other
690 	units, better be safe than sorry though).*/
691      RADEON_STATECHANGE( rmesa, tex[unit] );
692      rmesa->hw.tex[unit].cmd[TEX_PP_TXFORMAT] &= ~RADEON_TXFORMAT_CUBIC_MAP_ENABLE;
693    }
694 
695    {
696       GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
697       GLuint tmp = rmesa->TexGenEnabled;
698 
699       rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE<<unit);
700       rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE<<unit);
701       rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK<<inputshift);
702       rmesa->TexGenNeedNormals[unit] = 0;
703       rmesa->TexGenEnabled |=
704 	(RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
705 
706       if (tmp != rmesa->TexGenEnabled) {
707 	rmesa->recheck_texgen[unit] = GL_TRUE;
708 	rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
709       }
710    }
711 }
712 
import_tex_obj_state(r100ContextPtr rmesa,int unit,radeonTexObjPtr texobj)713 static void import_tex_obj_state( r100ContextPtr rmesa,
714 				  int unit,
715 				  radeonTexObjPtr texobj )
716 {
717 /* do not use RADEON_DB_STATE to avoid stale texture caches */
718    uint32_t *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
719    GLuint se_coord_fmt = rmesa->hw.set.cmd[SET_SE_COORDFMT];
720 
721    RADEON_STATECHANGE( rmesa, tex[unit] );
722 
723    cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK;
724    cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK;
725    cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
726    cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK;
727    cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
728 
729    if (texobj->pp_txformat & RADEON_TXFORMAT_NON_POWER2) {
730       uint32_t *txr_cmd = &rmesa->hw.txr[unit].cmd[TXR_CMD_0];
731       txr_cmd[TXR_PP_TEX_SIZE] = texobj->pp_txsize; /* NPOT only! */
732       txr_cmd[TXR_PP_TEX_PITCH] = texobj->pp_txpitch; /* NPOT only! */
733       RADEON_STATECHANGE( rmesa, txr[unit] );
734    }
735 
736    if (texobj->base.Target == GL_TEXTURE_RECTANGLE_NV) {
737       se_coord_fmt |= RADEON_VTX_ST0_NONPARAMETRIC << unit;
738    }
739    else {
740       se_coord_fmt &= ~(RADEON_VTX_ST0_NONPARAMETRIC << unit);
741 
742       if (texobj->base.Target == GL_TEXTURE_CUBE_MAP) {
743 	 uint32_t *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
744 
745 	 RADEON_STATECHANGE( rmesa, cube[unit] );
746 	 cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
747 	 /* state filled out in the cube_emit */
748       }
749    }
750 
751    if (se_coord_fmt != rmesa->hw.set.cmd[SET_SE_COORDFMT]) {
752       RADEON_STATECHANGE( rmesa, set );
753       rmesa->hw.set.cmd[SET_SE_COORDFMT] = se_coord_fmt;
754    }
755 
756    rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
757 }
758 
759 
set_texgen_matrix(r100ContextPtr rmesa,GLuint unit,const GLfloat * s_plane,const GLfloat * t_plane,const GLfloat * r_plane,const GLfloat * q_plane)760 static void set_texgen_matrix( r100ContextPtr rmesa,
761 			       GLuint unit,
762 			       const GLfloat *s_plane,
763 			       const GLfloat *t_plane,
764 			       const GLfloat *r_plane,
765 			       const GLfloat *q_plane )
766 {
767    rmesa->TexGenMatrix[unit].m[0]  = s_plane[0];
768    rmesa->TexGenMatrix[unit].m[4]  = s_plane[1];
769    rmesa->TexGenMatrix[unit].m[8]  = s_plane[2];
770    rmesa->TexGenMatrix[unit].m[12] = s_plane[3];
771 
772    rmesa->TexGenMatrix[unit].m[1]  = t_plane[0];
773    rmesa->TexGenMatrix[unit].m[5]  = t_plane[1];
774    rmesa->TexGenMatrix[unit].m[9]  = t_plane[2];
775    rmesa->TexGenMatrix[unit].m[13] = t_plane[3];
776 
777    rmesa->TexGenMatrix[unit].m[2]  = r_plane[0];
778    rmesa->TexGenMatrix[unit].m[6]  = r_plane[1];
779    rmesa->TexGenMatrix[unit].m[10] = r_plane[2];
780    rmesa->TexGenMatrix[unit].m[14] = r_plane[3];
781 
782    rmesa->TexGenMatrix[unit].m[3]  = q_plane[0];
783    rmesa->TexGenMatrix[unit].m[7]  = q_plane[1];
784    rmesa->TexGenMatrix[unit].m[11] = q_plane[2];
785    rmesa->TexGenMatrix[unit].m[15] = q_plane[3];
786 
787    rmesa->TexGenEnabled |= RADEON_TEXMAT_0_ENABLE << unit;
788    rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
789 }
790 
791 /* Returns GL_FALSE if fallback required.
792  */
radeon_validate_texgen(struct gl_context * ctx,GLuint unit)793 static GLboolean radeon_validate_texgen( struct gl_context *ctx, GLuint unit )
794 {
795    r100ContextPtr rmesa = R100_CONTEXT(ctx);
796    struct gl_fixedfunc_texture_unit *texUnit =
797       &ctx->Texture.FixedFuncUnit[unit];
798    GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
799    GLuint tmp = rmesa->TexGenEnabled;
800    static const GLfloat reflect[16] = {
801       -1,  0,  0,  0,
802        0, -1,  0,  0,
803        0,  0,  -1, 0,
804        0,  0,  0,  1 };
805 
806    rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_TEXMAT_0_ENABLE << unit);
807    rmesa->TexGenEnabled &= ~(RADEON_TEXMAT_0_ENABLE << unit);
808    rmesa->TexGenEnabled &= ~(RADEON_TEXGEN_INPUT_MASK << inputshift);
809    rmesa->TexGenNeedNormals[unit] = 0;
810 
811    if ((texUnit->TexGenEnabled & (S_BIT|T_BIT|R_BIT|Q_BIT)) == 0) {
812       /* Disabled, no fallback:
813        */
814       rmesa->TexGenEnabled |=
815 	 (RADEON_TEXGEN_INPUT_TEXCOORD_0 + unit) << inputshift;
816       return GL_TRUE;
817    }
818    /* the r100 cannot do texgen for some coords and not for others
819     * we do not detect such cases (certainly can't do it here) and just
820     * ASSUME that when S and T are texgen enabled we do not need other
821     * non-texgen enabled coords, no matter if the R and Q bits are texgen
822     * enabled. Still check for mixed mode texgen for all coords.
823     */
824    else if ( (texUnit->TexGenEnabled & S_BIT) &&
825 	     (texUnit->TexGenEnabled & T_BIT) &&
826 	     (texUnit->GenS.Mode == texUnit->GenT.Mode) ) {
827       if ( ((texUnit->TexGenEnabled & R_BIT) &&
828 	    (texUnit->GenS.Mode != texUnit->GenR.Mode)) ||
829 	   ((texUnit->TexGenEnabled & Q_BIT) &&
830 	    (texUnit->GenS.Mode != texUnit->GenQ.Mode)) ) {
831 	 /* Mixed modes, fallback:
832 	  */
833 	 if (RADEON_DEBUG & RADEON_FALLBACKS)
834 	    fprintf(stderr, "fallback mixed texgen\n");
835 	 return GL_FALSE;
836       }
837       rmesa->TexGenEnabled |= RADEON_TEXGEN_TEXMAT_0_ENABLE << unit;
838    }
839    else {
840    /* some texgen mode not including both S and T bits */
841       if (RADEON_DEBUG & RADEON_FALLBACKS)
842 	 fprintf(stderr, "fallback mixed texgen/nontexgen\n");
843       return GL_FALSE;
844    }
845 
846    if ((texUnit->TexGenEnabled & (R_BIT | Q_BIT)) != 0) {
847       /* need this here for vtxfmt presumably. Argh we need to set
848          this from way too many places, would be much easier if we could leave
849          tcl q coord always enabled as on r200) */
850       RADEON_STATECHANGE( rmesa, tcl );
851       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_Q_BIT(unit);
852    }
853 
854    switch (texUnit->GenS.Mode) {
855    case GL_OBJECT_LINEAR:
856       rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_OBJ << inputshift;
857       set_texgen_matrix( rmesa, unit,
858 			 texUnit->ObjectPlane[GEN_S],
859 			 texUnit->ObjectPlane[GEN_T],
860 			 texUnit->ObjectPlane[GEN_R],
861 			 texUnit->ObjectPlane[GEN_Q]);
862       break;
863 
864    case GL_EYE_LINEAR:
865       rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE << inputshift;
866       set_texgen_matrix( rmesa, unit,
867 			 texUnit->EyePlane[GEN_S],
868 			 texUnit->EyePlane[GEN_T],
869 			 texUnit->EyePlane[GEN_R],
870 			 texUnit->EyePlane[GEN_Q]);
871       break;
872 
873    case GL_REFLECTION_MAP_NV:
874       rmesa->TexGenNeedNormals[unit] = GL_TRUE;
875       rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_REFLECT << inputshift;
876       /* TODO: unknown if this is needed/correct */
877       set_texgen_matrix( rmesa, unit, reflect, reflect + 4,
878 			reflect + 8, reflect + 12 );
879       break;
880 
881    case GL_NORMAL_MAP_NV:
882       rmesa->TexGenNeedNormals[unit] = GL_TRUE;
883       rmesa->TexGenEnabled |= RADEON_TEXGEN_INPUT_EYE_NORMAL << inputshift;
884       break;
885 
886    case GL_SPHERE_MAP:
887       /* the mode which everyone uses :-( */
888    default:
889       /* Unsupported mode, fallback:
890        */
891       if (RADEON_DEBUG & RADEON_FALLBACKS)
892 	 fprintf(stderr, "fallback GL_SPHERE_MAP\n");
893       return GL_FALSE;
894    }
895 
896    if (tmp != rmesa->TexGenEnabled) {
897       rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
898    }
899 
900    return GL_TRUE;
901 }
902 
903 /**
904  * Compute the cached hardware register values for the given texture object.
905  *
906  * \param rmesa Context pointer
907  * \param t the r300 texture object
908  */
setup_hardware_state(r100ContextPtr rmesa,radeonTexObj * t,int unit)909 static GLboolean setup_hardware_state(r100ContextPtr rmesa, radeonTexObj *t, int unit)
910 {
911    const struct gl_texture_image *firstImage;
912    GLint log2Width, log2Height, texelBytes;
913 
914    if ( t->bo ) {
915 	return GL_TRUE;
916    }
917 
918    firstImage = t->base.Image[0][t->minLod];
919 
920    log2Width  = firstImage->WidthLog2;
921    log2Height = firstImage->HeightLog2;
922    texelBytes = _mesa_get_format_bytes(firstImage->TexFormat);
923 
924    if (!t->image_override) {
925       if (VALID_FORMAT(firstImage->TexFormat)) {
926 	const struct tx_table *table = tx_table;
927 
928 	 t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK |
929 			     RADEON_TXFORMAT_ALPHA_IN_MAP);
930 	 t->pp_txfilter &= ~RADEON_YUV_TO_RGB;
931 
932 	 t->pp_txformat |= table[ firstImage->TexFormat ].format;
933 	 t->pp_txfilter |= table[ firstImage->TexFormat ].filter;
934       } else {
935 	 _mesa_problem(NULL, "unexpected texture format in %s",
936 		       __func__);
937 	 return GL_FALSE;
938       }
939    }
940 
941    t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK;
942    t->pp_txfilter |= (t->maxLod - t->minLod) << RADEON_MAX_MIP_LEVEL_SHIFT;
943 
944    t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK |
945 		       RADEON_TXFORMAT_HEIGHT_MASK |
946 		       RADEON_TXFORMAT_CUBIC_MAP_ENABLE |
947 		       RADEON_TXFORMAT_F5_WIDTH_MASK |
948 		       RADEON_TXFORMAT_F5_HEIGHT_MASK);
949    t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) |
950 		      (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT));
951 
952    t->tile_bits = 0;
953 
954    if (t->base.Target == GL_TEXTURE_CUBE_MAP) {
955       assert(log2Width == log2Height);
956       t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_F5_WIDTH_SHIFT) |
957 			 (log2Height << RADEON_TXFORMAT_F5_HEIGHT_SHIFT) |
958 			 /* don't think we need this bit, if it exists at all - fglrx does not set it */
959 			 (RADEON_TXFORMAT_CUBIC_MAP_ENABLE));
960       t->pp_cubic_faces = ((log2Width << RADEON_FACE_WIDTH_1_SHIFT) |
961                            (log2Height << RADEON_FACE_HEIGHT_1_SHIFT) |
962                            (log2Width << RADEON_FACE_WIDTH_2_SHIFT) |
963                            (log2Height << RADEON_FACE_HEIGHT_2_SHIFT) |
964                            (log2Width << RADEON_FACE_WIDTH_3_SHIFT) |
965                            (log2Height << RADEON_FACE_HEIGHT_3_SHIFT) |
966                            (log2Width << RADEON_FACE_WIDTH_4_SHIFT) |
967                            (log2Height << RADEON_FACE_HEIGHT_4_SHIFT));
968    }
969 
970    t->pp_txsize = (((firstImage->Width - 1) << RADEON_TEX_USIZE_SHIFT)
971 		   | ((firstImage->Height - 1) << RADEON_TEX_VSIZE_SHIFT));
972 
973    if ( !t->image_override ) {
974       if (_mesa_is_format_compressed(firstImage->TexFormat))
975          t->pp_txpitch = (firstImage->Width + 63) & ~(63);
976       else
977          t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63);
978       t->pp_txpitch -= 32;
979    }
980 
981    if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
982       t->pp_txformat |= RADEON_TXFORMAT_NON_POWER2;
983    }
984 
985    return GL_TRUE;
986 }
987 
radeon_validate_texture(struct gl_context * ctx,struct gl_texture_object * texObj,int unit)988 static GLboolean radeon_validate_texture(struct gl_context *ctx, struct gl_texture_object *texObj, int unit)
989 {
990    r100ContextPtr rmesa = R100_CONTEXT(ctx);
991    radeonTexObj *t = radeon_tex_obj(texObj);
992    int ret;
993 
994    if (!radeon_validate_texture_miptree(ctx, _mesa_get_samplerobj(ctx, unit), texObj))
995       return GL_FALSE;
996 
997    ret = setup_hardware_state(rmesa, t, unit);
998    if (ret == GL_FALSE)
999      return GL_FALSE;
1000 
1001    /* yuv conversion only works in first unit */
1002    if (unit != 0 && (t->pp_txfilter & RADEON_YUV_TO_RGB))
1003       return GL_FALSE;
1004 
1005    RADEON_STATECHANGE( rmesa, ctx );
1006    rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=
1007      (RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit;
1008    RADEON_STATECHANGE( rmesa, tcl );
1009    rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_ST_BIT(unit);
1010 
1011    rmesa->recheck_texgen[unit] = GL_TRUE;
1012 
1013    radeonTexUpdateParameters(ctx, unit);
1014    import_tex_obj_state( rmesa, unit, t );
1015 
1016    if (rmesa->recheck_texgen[unit]) {
1017       GLboolean fallback = !radeon_validate_texgen( ctx, unit );
1018       TCL_FALLBACK( ctx, (RADEON_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
1019       rmesa->recheck_texgen[unit] = 0;
1020       rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
1021    }
1022 
1023    if ( ! radeonUpdateTextureEnv( ctx, unit ) ) {
1024      return GL_FALSE;
1025    }
1026    FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback );
1027 
1028    t->validated = GL_TRUE;
1029    return !t->border_fallback;
1030 }
1031 
radeonUpdateTextureUnit(struct gl_context * ctx,int unit)1032 static GLboolean radeonUpdateTextureUnit( struct gl_context *ctx, int unit )
1033 {
1034    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1035 
1036    if (ctx->Texture.Unit[unit]._Current &&
1037        ctx->Texture.Unit[unit]._Current->Target == GL_TEXTURE_3D) {
1038      disable_tex_obj_state(rmesa, unit);
1039      rmesa->state.texture.unit[unit].texobj = NULL;
1040      return GL_FALSE;
1041    }
1042 
1043    if (!ctx->Texture.Unit[unit]._Current) {
1044      /* disable the unit */
1045      disable_tex_obj_state(rmesa, unit);
1046      rmesa->state.texture.unit[unit].texobj = NULL;
1047      return GL_TRUE;
1048    }
1049 
1050    if (!radeon_validate_texture(ctx, ctx->Texture.Unit[unit]._Current, unit)) {
1051     _mesa_warning(ctx,
1052 		  "failed to validate texture for unit %d.\n",
1053 		  unit);
1054      rmesa->state.texture.unit[unit].texobj = NULL;
1055      return GL_FALSE;
1056    }
1057    rmesa->state.texture.unit[unit].texobj = radeon_tex_obj(ctx->Texture.Unit[unit]._Current);
1058    return GL_TRUE;
1059 }
1060 
radeonUpdateTextureState(struct gl_context * ctx)1061 void radeonUpdateTextureState( struct gl_context *ctx )
1062 {
1063    r100ContextPtr rmesa = R100_CONTEXT(ctx);
1064    GLboolean ok;
1065 
1066    /* set the ctx all textures off */
1067    RADEON_STATECHANGE( rmesa, ctx );
1068    rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~((RADEON_TEX_ENABLE_MASK) | (RADEON_TEX_BLEND_ENABLE_MASK));
1069 
1070    ok = (radeonUpdateTextureUnit( ctx, 0 ) &&
1071 	 radeonUpdateTextureUnit( ctx, 1 ) &&
1072 	 radeonUpdateTextureUnit( ctx, 2 ));
1073 
1074    FALLBACK( rmesa, RADEON_FALLBACK_TEXTURE, !ok );
1075 
1076    if (rmesa->radeon.TclFallback)
1077       radeonChooseVertexState( ctx );
1078 }
1079