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