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