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