Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / r200 / r200_texstate.c
1 /*
2 Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
3
4 The Weather Channel (TM) funded Tungsten Graphics to develop the
5 initial release of the Radeon 8500 driver under the XFree86 license.
6 This notice must be preserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
15
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 **************************************************************************/
29
30 /*
31  * Authors:
32  *   Keith Whitwell <keith@tungstengraphics.com>
33  */
34
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/context.h"
38 #include "main/macros.h"
39 #include "main/teximage.h"
40 #include "main/texobj.h"
41 #include "main/enums.h"
42
43 #include "radeon_common.h"
44 #include "radeon_mipmap_tree.h"
45 #include "r200_context.h"
46 #include "r200_state.h"
47 #include "r200_ioctl.h"
48 #include "r200_swtcl.h"
49 #include "r200_tex.h"
50 #include "r200_tcl.h"
51
52
53 #define R200_TXFORMAT_A8        R200_TXFORMAT_I8
54 #define R200_TXFORMAT_L8        R200_TXFORMAT_I8
55 #define R200_TXFORMAT_AL88      R200_TXFORMAT_AI88
56 #define R200_TXFORMAT_YCBCR     R200_TXFORMAT_YVYU422
57 #define R200_TXFORMAT_YCBCR_REV R200_TXFORMAT_VYUY422
58 #define R200_TXFORMAT_RGB_DXT1  R200_TXFORMAT_DXT1
59 #define R200_TXFORMAT_RGBA_DXT1 R200_TXFORMAT_DXT1
60 #define R200_TXFORMAT_RGBA_DXT3 R200_TXFORMAT_DXT23
61 #define R200_TXFORMAT_RGBA_DXT5 R200_TXFORMAT_DXT45
62
63 #define _COLOR(f) \
64     [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, 0 }
65 #define _COLOR_REV(f) \
66     [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f, 0 }
67 #define _ALPHA(f) \
68     [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
69 #define _ALPHA_REV(f) \
70     [ MESA_FORMAT_ ## f ## _REV ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
71 #define _YUV(f) \
72     [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, R200_YUV_TO_RGB }
73 #define _INVALID(f) \
74     [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
75 #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5) \
76                              && (tx_table_be[f].format != 0xffffffff) )
77
78 struct tx_table {
79    GLuint format, filter;
80 };
81
82 static const struct tx_table tx_table_be[] =
83 {
84    [ MESA_FORMAT_RGBA8888 ] = { R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
85    _ALPHA_REV(RGBA8888),
86    _ALPHA(ARGB8888),
87    _ALPHA_REV(ARGB8888),
88    _INVALID(RGB888),
89    _COLOR(RGB565),
90    _COLOR_REV(RGB565),
91    _ALPHA(ARGB4444),
92    _ALPHA_REV(ARGB4444),
93    _ALPHA(ARGB1555),
94    _ALPHA_REV(ARGB1555),
95    _ALPHA(AL88),
96    _ALPHA_REV(AL88),
97    _ALPHA(A8),
98    _COLOR(L8),
99    _ALPHA(I8),
100    _INVALID(CI8),
101    _YUV(YCBCR),
102    _YUV(YCBCR_REV),
103    _INVALID(RGB_FXT1),
104    _INVALID(RGBA_FXT1),
105    _COLOR(RGB_DXT1),
106    _ALPHA(RGBA_DXT1),
107    _ALPHA(RGBA_DXT3),
108    _ALPHA(RGBA_DXT5),
109 };
110
111 static const struct tx_table tx_table_le[] =
112 {
113    _ALPHA(RGBA8888),
114    [ MESA_FORMAT_RGBA8888_REV ] = { R200_TXFORMAT_ABGR8888 | R200_TXFORMAT_ALPHA_IN_MAP, 0 },
115    _ALPHA(ARGB8888),
116    _ALPHA_REV(ARGB8888),
117    [ MESA_FORMAT_RGB888 ] = { R200_TXFORMAT_ARGB8888, 0 },
118    _COLOR(RGB565),
119    _COLOR_REV(RGB565),
120    _ALPHA(ARGB4444),
121    _ALPHA_REV(ARGB4444),
122    _ALPHA(ARGB1555),
123    _ALPHA_REV(ARGB1555),
124    _ALPHA(AL88),
125    _ALPHA_REV(AL88),
126    _ALPHA(A8),
127    _COLOR(L8),
128    _ALPHA(I8),
129    _INVALID(CI8),
130    _YUV(YCBCR),
131    _YUV(YCBCR_REV),
132    _INVALID(RGB_FXT1),
133    _INVALID(RGBA_FXT1),
134    _COLOR(RGB_DXT1),
135    _ALPHA(RGBA_DXT1),
136    _ALPHA(RGBA_DXT3),
137    _ALPHA(RGBA_DXT5),
138 };
139
140 #undef _COLOR
141 #undef _ALPHA
142 #undef _INVALID
143
144 /* ================================================================
145  * Texture combine functions
146  */
147
148 /* GL_ARB_texture_env_combine support
149  */
150
151 /* The color tables have combine functions for GL_SRC_COLOR,
152  * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
153  */
154 static GLuint r200_register_color[][R200_MAX_TEXTURE_UNITS] =
155 {
156    {
157       R200_TXC_ARG_A_R0_COLOR,
158       R200_TXC_ARG_A_R1_COLOR,
159       R200_TXC_ARG_A_R2_COLOR,
160       R200_TXC_ARG_A_R3_COLOR,
161       R200_TXC_ARG_A_R4_COLOR,
162       R200_TXC_ARG_A_R5_COLOR
163    },
164    {
165       R200_TXC_ARG_A_R0_COLOR | R200_TXC_COMP_ARG_A,
166       R200_TXC_ARG_A_R1_COLOR | R200_TXC_COMP_ARG_A,
167       R200_TXC_ARG_A_R2_COLOR | R200_TXC_COMP_ARG_A,
168       R200_TXC_ARG_A_R3_COLOR | R200_TXC_COMP_ARG_A,
169       R200_TXC_ARG_A_R4_COLOR | R200_TXC_COMP_ARG_A,
170       R200_TXC_ARG_A_R5_COLOR | R200_TXC_COMP_ARG_A
171    },
172    {
173       R200_TXC_ARG_A_R0_ALPHA,
174       R200_TXC_ARG_A_R1_ALPHA,
175       R200_TXC_ARG_A_R2_ALPHA,
176       R200_TXC_ARG_A_R3_ALPHA,
177       R200_TXC_ARG_A_R4_ALPHA,
178       R200_TXC_ARG_A_R5_ALPHA
179    },
180    {
181       R200_TXC_ARG_A_R0_ALPHA | R200_TXC_COMP_ARG_A,
182       R200_TXC_ARG_A_R1_ALPHA | R200_TXC_COMP_ARG_A,
183       R200_TXC_ARG_A_R2_ALPHA | R200_TXC_COMP_ARG_A,
184       R200_TXC_ARG_A_R3_ALPHA | R200_TXC_COMP_ARG_A,
185       R200_TXC_ARG_A_R4_ALPHA | R200_TXC_COMP_ARG_A,
186       R200_TXC_ARG_A_R5_ALPHA | R200_TXC_COMP_ARG_A
187    },
188 };
189
190 static GLuint r200_tfactor_color[] =
191 {
192    R200_TXC_ARG_A_TFACTOR_COLOR,
193    R200_TXC_ARG_A_TFACTOR_COLOR | R200_TXC_COMP_ARG_A,
194    R200_TXC_ARG_A_TFACTOR_ALPHA,
195    R200_TXC_ARG_A_TFACTOR_ALPHA | R200_TXC_COMP_ARG_A
196 };
197
198 static GLuint r200_tfactor1_color[] =
199 {
200    R200_TXC_ARG_A_TFACTOR1_COLOR,
201    R200_TXC_ARG_A_TFACTOR1_COLOR | R200_TXC_COMP_ARG_A,
202    R200_TXC_ARG_A_TFACTOR1_ALPHA,
203    R200_TXC_ARG_A_TFACTOR1_ALPHA | R200_TXC_COMP_ARG_A
204 };
205
206 static GLuint r200_primary_color[] =
207 {
208    R200_TXC_ARG_A_DIFFUSE_COLOR,
209    R200_TXC_ARG_A_DIFFUSE_COLOR | R200_TXC_COMP_ARG_A,
210    R200_TXC_ARG_A_DIFFUSE_ALPHA,
211    R200_TXC_ARG_A_DIFFUSE_ALPHA | R200_TXC_COMP_ARG_A
212 };
213
214 /* GL_ZERO table - indices 0-3
215  * GL_ONE  table - indices 1-4
216  */
217 static GLuint r200_zero_color[] =
218 {
219    R200_TXC_ARG_A_ZERO,
220    R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A,
221    R200_TXC_ARG_A_ZERO,
222    R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A,
223    R200_TXC_ARG_A_ZERO
224 };
225
226 /* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
227  */
228 static GLuint r200_register_alpha[][R200_MAX_TEXTURE_UNITS] =
229 {
230    {
231       R200_TXA_ARG_A_R0_ALPHA,
232       R200_TXA_ARG_A_R1_ALPHA,
233       R200_TXA_ARG_A_R2_ALPHA,
234       R200_TXA_ARG_A_R3_ALPHA,
235       R200_TXA_ARG_A_R4_ALPHA,
236       R200_TXA_ARG_A_R5_ALPHA
237    },
238    {
239       R200_TXA_ARG_A_R0_ALPHA | R200_TXA_COMP_ARG_A,
240       R200_TXA_ARG_A_R1_ALPHA | R200_TXA_COMP_ARG_A,
241       R200_TXA_ARG_A_R2_ALPHA | R200_TXA_COMP_ARG_A,
242       R200_TXA_ARG_A_R3_ALPHA | R200_TXA_COMP_ARG_A,
243       R200_TXA_ARG_A_R4_ALPHA | R200_TXA_COMP_ARG_A,
244       R200_TXA_ARG_A_R5_ALPHA | R200_TXA_COMP_ARG_A
245    },
246 };
247
248 static GLuint r200_tfactor_alpha[] =
249 {
250    R200_TXA_ARG_A_TFACTOR_ALPHA,
251    R200_TXA_ARG_A_TFACTOR_ALPHA | R200_TXA_COMP_ARG_A
252 };
253
254 static GLuint r200_tfactor1_alpha[] =
255 {
256    R200_TXA_ARG_A_TFACTOR1_ALPHA,
257    R200_TXA_ARG_A_TFACTOR1_ALPHA | R200_TXA_COMP_ARG_A
258 };
259
260 static GLuint r200_primary_alpha[] =
261 {
262    R200_TXA_ARG_A_DIFFUSE_ALPHA,
263    R200_TXA_ARG_A_DIFFUSE_ALPHA | R200_TXA_COMP_ARG_A
264 };
265
266 /* GL_ZERO table - indices 0-1
267  * GL_ONE  table - indices 1-2
268  */
269 static GLuint r200_zero_alpha[] =
270 {
271    R200_TXA_ARG_A_ZERO,
272    R200_TXA_ARG_A_ZERO | R200_TXA_COMP_ARG_A,
273    R200_TXA_ARG_A_ZERO,
274 };
275
276
277 /* Extract the arg from slot A, shift it into the correct argument slot
278  * and set the corresponding complement bit.
279  */
280 #define R200_COLOR_ARG( n, arg )                        \
281 do {                                                    \
282    color_combine |=                                     \
283       ((color_arg[n] & R200_TXC_ARG_A_MASK)             \
284        << R200_TXC_ARG_##arg##_SHIFT);                  \
285    color_combine |=                                     \
286       ((color_arg[n] >> R200_TXC_COMP_ARG_A_SHIFT)      \
287        << R200_TXC_COMP_ARG_##arg##_SHIFT);             \
288 } while (0)
289
290 #define R200_ALPHA_ARG( n, arg )                        \
291 do {                                                    \
292    alpha_combine |=                                     \
293       ((alpha_arg[n] & R200_TXA_ARG_A_MASK)             \
294        << R200_TXA_ARG_##arg##_SHIFT);                  \
295    alpha_combine |=                                     \
296       ((alpha_arg[n] >> R200_TXA_COMP_ARG_A_SHIFT)      \
297        << R200_TXA_COMP_ARG_##arg##_SHIFT);             \
298 } while (0)
299
300
301 /* ================================================================
302  * Texture unit state management
303  */
304
305 static GLboolean r200UpdateTextureEnv( struct gl_context *ctx, int unit, int slot, GLuint replaceargs )
306 {
307    r200ContextPtr rmesa = R200_CONTEXT(ctx);
308    const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
309    GLuint color_combine, alpha_combine;
310    GLuint color_scale = rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND2] &
311       ~(R200_TXC_SCALE_MASK | R200_TXC_OUTPUT_REG_MASK | R200_TXC_TFACTOR_SEL_MASK |
312         R200_TXC_TFACTOR1_SEL_MASK);
313    GLuint alpha_scale = rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND2] &
314       ~(R200_TXA_DOT_ALPHA | R200_TXA_SCALE_MASK | R200_TXA_OUTPUT_REG_MASK |
315         R200_TXA_TFACTOR_SEL_MASK | R200_TXA_TFACTOR1_SEL_MASK);
316
317    /* texUnit->_Current can be NULL if and only if the texture unit is
318     * not actually enabled.
319     */
320    assert( (texUnit->_ReallyEnabled == 0)
321            || (texUnit->_Current != NULL) );
322
323    if ( R200_DEBUG & RADEON_TEXTURE ) {
324       fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, (void *)ctx, unit );
325    }
326
327    /* Set the texture environment state.  Isn't this nice and clean?
328     * The chip will automagically set the texture alpha to 0xff when
329     * the texture format does not include an alpha component.  This
330     * reduces the amount of special-casing we have to do, alpha-only
331     * textures being a notable exception.
332     */
333
334    color_scale |= ((rmesa->state.texture.unit[unit].outputreg + 1) << R200_TXC_OUTPUT_REG_SHIFT) |
335                         (unit << R200_TXC_TFACTOR_SEL_SHIFT) |
336                         (replaceargs << R200_TXC_TFACTOR1_SEL_SHIFT);
337    alpha_scale |= ((rmesa->state.texture.unit[unit].outputreg + 1) << R200_TXA_OUTPUT_REG_SHIFT) |
338                         (unit << R200_TXA_TFACTOR_SEL_SHIFT) |
339                         (replaceargs << R200_TXA_TFACTOR1_SEL_SHIFT);
340
341    if ( !texUnit->_ReallyEnabled ) {
342       assert( unit == 0);
343       color_combine = R200_TXC_ARG_A_ZERO | R200_TXC_ARG_B_ZERO
344           | R200_TXC_ARG_C_DIFFUSE_COLOR | R200_TXC_OP_MADD;
345       alpha_combine = R200_TXA_ARG_A_ZERO | R200_TXA_ARG_B_ZERO
346           | R200_TXA_ARG_C_DIFFUSE_ALPHA | R200_TXA_OP_MADD;
347    }
348    else {
349       GLuint color_arg[3], alpha_arg[3];
350       GLuint i;
351       const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
352       const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
353       GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB;
354       GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA;
355
356
357       const GLint replaceoprgb =
358          ctx->Texture.Unit[replaceargs]._CurrentCombine->OperandRGB[0] - GL_SRC_COLOR;
359       const GLint replaceopa =
360          ctx->Texture.Unit[replaceargs]._CurrentCombine->OperandA[0] - GL_SRC_ALPHA;
361
362       /* Step 1:
363        * Extract the color and alpha combine function arguments.
364        */
365       for ( i = 0 ; i < numColorArgs ; i++ ) {
366          GLint op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR;
367          const GLint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i];
368          assert(op >= 0);
369          assert(op <= 3);
370          switch ( srcRGBi ) {
371          case GL_TEXTURE:
372             color_arg[i] = r200_register_color[op][unit];
373             break;
374          case GL_CONSTANT:
375             color_arg[i] = r200_tfactor_color[op];
376             break;
377          case GL_PRIMARY_COLOR:
378             color_arg[i] = r200_primary_color[op];
379             break;
380          case GL_PREVIOUS:
381             if (replaceargs != unit) {
382                const GLint srcRGBreplace =
383                   ctx->Texture.Unit[replaceargs]._CurrentCombine->SourceRGB[0];
384                if (op >= 2) {
385                   op = op ^ replaceopa;
386                }
387                else {
388                   op = op ^ replaceoprgb;
389                }
390                switch (srcRGBreplace) {
391                case GL_TEXTURE:
392                   color_arg[i] = r200_register_color[op][replaceargs];
393                   break;
394                case GL_CONSTANT:
395                   color_arg[i] = r200_tfactor1_color[op];
396                   break;
397                case GL_PRIMARY_COLOR:
398                   color_arg[i] = r200_primary_color[op];
399                   break;
400                case GL_PREVIOUS:
401                   if (slot == 0)
402                      color_arg[i] = r200_primary_color[op];
403                   else
404                      color_arg[i] = r200_register_color[op]
405                         [rmesa->state.texture.unit[replaceargs - 1].outputreg];
406                   break;
407                case GL_ZERO:
408                   color_arg[i] = r200_zero_color[op];
409                   break;
410                case GL_ONE:
411                   color_arg[i] = r200_zero_color[op+1];
412                   break;
413                case GL_TEXTURE0:
414                case GL_TEXTURE1:
415                case GL_TEXTURE2:
416                case GL_TEXTURE3:
417                case GL_TEXTURE4:
418                case GL_TEXTURE5:
419                   color_arg[i] = r200_register_color[op][srcRGBreplace - GL_TEXTURE0];
420                   break;
421                default:
422                return GL_FALSE;
423                }
424             }
425             else {
426                if (slot == 0)
427                   color_arg[i] = r200_primary_color[op];
428                else
429                   color_arg[i] = r200_register_color[op]
430                      [rmesa->state.texture.unit[unit - 1].outputreg];
431             }
432             break;
433          case GL_ZERO:
434             color_arg[i] = r200_zero_color[op];
435             break;
436          case GL_ONE:
437             color_arg[i] = r200_zero_color[op+1];
438             break;
439          case GL_TEXTURE0:
440          case GL_TEXTURE1:
441          case GL_TEXTURE2:
442          case GL_TEXTURE3:
443          case GL_TEXTURE4:
444          case GL_TEXTURE5:
445             color_arg[i] = r200_register_color[op][srcRGBi - GL_TEXTURE0];
446             break;
447          default:
448             return GL_FALSE;
449          }
450       }
451
452       for ( i = 0 ; i < numAlphaArgs ; i++ ) {
453          GLint op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA;
454          const GLint srcAi = texUnit->_CurrentCombine->SourceA[i];
455          assert(op >= 0);
456          assert(op <= 1);
457          switch ( srcAi ) {
458          case GL_TEXTURE:
459             alpha_arg[i] = r200_register_alpha[op][unit];
460             break;
461          case GL_CONSTANT:
462             alpha_arg[i] = r200_tfactor_alpha[op];
463             break;
464          case GL_PRIMARY_COLOR:
465             alpha_arg[i] = r200_primary_alpha[op];
466             break;
467          case GL_PREVIOUS:
468             if (replaceargs != unit) {
469                const GLint srcAreplace =
470                   ctx->Texture.Unit[replaceargs]._CurrentCombine->SourceA[0];
471                op = op ^ replaceopa;
472                switch (srcAreplace) {
473                case GL_TEXTURE:
474                   alpha_arg[i] = r200_register_alpha[op][replaceargs];
475                   break;
476                case GL_CONSTANT:
477                   alpha_arg[i] = r200_tfactor1_alpha[op];
478                   break;
479                case GL_PRIMARY_COLOR:
480                   alpha_arg[i] = r200_primary_alpha[op];
481                   break;
482                case GL_PREVIOUS:
483                   if (slot == 0)
484                      alpha_arg[i] = r200_primary_alpha[op];
485                   else
486                      alpha_arg[i] = r200_register_alpha[op]
487                         [rmesa->state.texture.unit[replaceargs - 1].outputreg];
488                   break;
489                case GL_ZERO:
490                   alpha_arg[i] = r200_zero_alpha[op];
491                   break;
492                case GL_ONE:
493                   alpha_arg[i] = r200_zero_alpha[op+1];
494                   break;
495                case GL_TEXTURE0:
496                case GL_TEXTURE1:
497                case GL_TEXTURE2:
498                case GL_TEXTURE3:
499                case GL_TEXTURE4:
500                case GL_TEXTURE5:
501                   alpha_arg[i] = r200_register_alpha[op][srcAreplace - GL_TEXTURE0];
502                   break;
503                default:
504                return GL_FALSE;
505                }
506             }
507             else {
508                if (slot == 0)
509                   alpha_arg[i] = r200_primary_alpha[op];
510                else
511                   alpha_arg[i] = r200_register_alpha[op]
512                     [rmesa->state.texture.unit[unit - 1].outputreg];
513             }
514             break;
515          case GL_ZERO:
516             alpha_arg[i] = r200_zero_alpha[op];
517             break;
518          case GL_ONE:
519             alpha_arg[i] = r200_zero_alpha[op+1];
520             break;
521          case GL_TEXTURE0:
522          case GL_TEXTURE1:
523          case GL_TEXTURE2:
524          case GL_TEXTURE3:
525          case GL_TEXTURE4:
526          case GL_TEXTURE5:
527             alpha_arg[i] = r200_register_alpha[op][srcAi - GL_TEXTURE0];
528             break;
529          default:
530             return GL_FALSE;
531          }
532       }
533
534       /* Step 2:
535        * Build up the color and alpha combine functions.
536        */
537       switch ( texUnit->_CurrentCombine->ModeRGB ) {
538       case GL_REPLACE:
539          color_combine = (R200_TXC_ARG_A_ZERO |
540                           R200_TXC_ARG_B_ZERO |
541                           R200_TXC_OP_MADD);
542          R200_COLOR_ARG( 0, C );
543          break;
544       case GL_MODULATE:
545          color_combine = (R200_TXC_ARG_C_ZERO |
546                           R200_TXC_OP_MADD);
547          R200_COLOR_ARG( 0, A );
548          R200_COLOR_ARG( 1, B );
549          break;
550       case GL_ADD:
551          color_combine = (R200_TXC_ARG_B_ZERO |
552                           R200_TXC_COMP_ARG_B | 
553                           R200_TXC_OP_MADD);
554          R200_COLOR_ARG( 0, A );
555          R200_COLOR_ARG( 1, C );
556          break;
557       case GL_ADD_SIGNED:
558          color_combine = (R200_TXC_ARG_B_ZERO |
559                           R200_TXC_COMP_ARG_B |
560                           R200_TXC_BIAS_ARG_C | /* new */
561                           R200_TXC_OP_MADD); /* was ADDSIGNED */
562          R200_COLOR_ARG( 0, A );
563          R200_COLOR_ARG( 1, C );
564          break;
565       case GL_SUBTRACT:
566          color_combine = (R200_TXC_ARG_B_ZERO |
567                           R200_TXC_COMP_ARG_B | 
568                           R200_TXC_NEG_ARG_C |
569                           R200_TXC_OP_MADD);
570          R200_COLOR_ARG( 0, A );
571          R200_COLOR_ARG( 1, C );
572          break;
573       case GL_INTERPOLATE:
574          color_combine = (R200_TXC_OP_LERP);
575          R200_COLOR_ARG( 0, B );
576          R200_COLOR_ARG( 1, A );
577          R200_COLOR_ARG( 2, C );
578          break;
579
580       case GL_DOT3_RGB_EXT:
581       case GL_DOT3_RGBA_EXT:
582          /* The EXT version of the DOT3 extension does not support the
583           * scale factor, but the ARB version (and the version in OpenGL
584           * 1.3) does.
585           */
586          RGBshift = 0;
587          /* FALLTHROUGH */
588
589       case GL_DOT3_RGB:
590       case GL_DOT3_RGBA:
591          /* DOT3 works differently on R200 than on R100.  On R100, just
592           * setting the DOT3 mode did everything for you.  On R200, the
593           * driver has to enable the biasing and scale in the inputs to
594           * put them in the proper [-1,1] range.  This is what the 4x and
595           * the -0.5 in the DOT3 spec do.  The post-scale is then set
596           * normally.
597           */
598
599          color_combine = (R200_TXC_ARG_C_ZERO |
600                           R200_TXC_OP_DOT3 |
601                           R200_TXC_BIAS_ARG_A |
602                           R200_TXC_BIAS_ARG_B |
603                           R200_TXC_SCALE_ARG_A |
604                           R200_TXC_SCALE_ARG_B);
605          R200_COLOR_ARG( 0, A );
606          R200_COLOR_ARG( 1, B );
607          break;
608
609       case GL_MODULATE_ADD_ATI:
610          color_combine = (R200_TXC_OP_MADD);
611          R200_COLOR_ARG( 0, A );
612          R200_COLOR_ARG( 1, C );
613          R200_COLOR_ARG( 2, B );
614          break;
615       case GL_MODULATE_SIGNED_ADD_ATI:
616          color_combine = (R200_TXC_BIAS_ARG_C | /* new */
617                           R200_TXC_OP_MADD); /* was ADDSIGNED */
618          R200_COLOR_ARG( 0, A );
619          R200_COLOR_ARG( 1, C );
620          R200_COLOR_ARG( 2, B );
621          break;
622       case GL_MODULATE_SUBTRACT_ATI:
623          color_combine = (R200_TXC_NEG_ARG_C |
624                           R200_TXC_OP_MADD);
625          R200_COLOR_ARG( 0, A );
626          R200_COLOR_ARG( 1, C );
627          R200_COLOR_ARG( 2, B );
628          break;
629       default:
630          return GL_FALSE;
631       }
632
633       switch ( texUnit->_CurrentCombine->ModeA ) {
634       case GL_REPLACE:
635          alpha_combine = (R200_TXA_ARG_A_ZERO |
636                           R200_TXA_ARG_B_ZERO |
637                           R200_TXA_OP_MADD);
638          R200_ALPHA_ARG( 0, C );
639          break;
640       case GL_MODULATE:
641          alpha_combine = (R200_TXA_ARG_C_ZERO |
642                           R200_TXA_OP_MADD);
643          R200_ALPHA_ARG( 0, A );
644          R200_ALPHA_ARG( 1, B );
645          break;
646       case GL_ADD:
647          alpha_combine = (R200_TXA_ARG_B_ZERO |
648                           R200_TXA_COMP_ARG_B |
649                           R200_TXA_OP_MADD);
650          R200_ALPHA_ARG( 0, A );
651          R200_ALPHA_ARG( 1, C );
652          break;
653       case GL_ADD_SIGNED:
654          alpha_combine = (R200_TXA_ARG_B_ZERO |
655                           R200_TXA_COMP_ARG_B |
656                           R200_TXA_BIAS_ARG_C | /* new */
657                           R200_TXA_OP_MADD); /* was ADDSIGNED */
658          R200_ALPHA_ARG( 0, A );
659          R200_ALPHA_ARG( 1, C );
660          break;
661       case GL_SUBTRACT:
662          alpha_combine = (R200_TXA_ARG_B_ZERO |
663                           R200_TXA_COMP_ARG_B |
664                           R200_TXA_NEG_ARG_C |
665                           R200_TXA_OP_MADD);
666          R200_ALPHA_ARG( 0, A );
667          R200_ALPHA_ARG( 1, C );
668          break;
669       case GL_INTERPOLATE:
670          alpha_combine = (R200_TXA_OP_LERP);
671          R200_ALPHA_ARG( 0, B );
672          R200_ALPHA_ARG( 1, A );
673          R200_ALPHA_ARG( 2, C );
674          break;
675
676       case GL_MODULATE_ADD_ATI:
677          alpha_combine = (R200_TXA_OP_MADD);
678          R200_ALPHA_ARG( 0, A );
679          R200_ALPHA_ARG( 1, C );
680          R200_ALPHA_ARG( 2, B );
681          break;
682       case GL_MODULATE_SIGNED_ADD_ATI:
683          alpha_combine = (R200_TXA_BIAS_ARG_C | /* new */
684                           R200_TXA_OP_MADD); /* was ADDSIGNED */
685          R200_ALPHA_ARG( 0, A );
686          R200_ALPHA_ARG( 1, C );
687          R200_ALPHA_ARG( 2, B );
688          break;
689       case GL_MODULATE_SUBTRACT_ATI:
690          alpha_combine = (R200_TXA_NEG_ARG_C |
691                           R200_TXA_OP_MADD);
692          R200_ALPHA_ARG( 0, A );
693          R200_ALPHA_ARG( 1, C );
694          R200_ALPHA_ARG( 2, B );
695          break;
696       default:
697          return GL_FALSE;
698       }
699
700       if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT)
701            || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) {
702          alpha_scale |= R200_TXA_DOT_ALPHA;
703          Ashift = RGBshift;
704       }
705
706       /* Step 3:
707        * Apply the scale factor.
708        */
709       color_scale |= (RGBshift << R200_TXC_SCALE_SHIFT);
710       alpha_scale |= (Ashift   << R200_TXA_SCALE_SHIFT);
711
712       /* All done!
713        */
714    }
715
716    if ( rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND] != color_combine ||
717         rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND] != alpha_combine ||
718         rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND2] != color_scale ||
719         rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND2] != alpha_scale) {
720       R200_STATECHANGE( rmesa, pix[slot] );
721       rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND] = color_combine;
722       rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND] = alpha_combine;
723       rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND2] = color_scale;
724       rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND2] = alpha_scale;
725    }
726
727    return GL_TRUE;
728 }
729
730 void r200SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
731                       unsigned long long offset, GLint depth, GLuint pitch)
732 {
733         r200ContextPtr rmesa = pDRICtx->driverPrivate;
734         struct gl_texture_object *tObj =
735             _mesa_lookup_texture(rmesa->radeon.glCtx, texname);
736         radeonTexObjPtr t = radeon_tex_obj(tObj);
737
738         if (!tObj)
739                 return;
740
741         t->image_override = GL_TRUE;
742
743         if (!offset)
744                 return;
745
746         t->bo = NULL;
747         t->override_offset = offset;
748         t->pp_txpitch = pitch - 32;
749
750         switch (depth) {
751         case 32:
752                 t->pp_txformat = tx_table_le[MESA_FORMAT_ARGB8888].format;
753                 t->pp_txfilter |= tx_table_le[MESA_FORMAT_ARGB8888].filter;
754                 break;
755         case 24:
756         default:
757                 t->pp_txformat = tx_table_le[MESA_FORMAT_RGB888].format;
758                 t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB888].filter;
759                 break;
760         case 16:
761                 t->pp_txformat = tx_table_le[MESA_FORMAT_RGB565].format;
762                 t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB565].filter;
763                 break;
764         }
765 }
766
767 void r200SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint texture_format,
768                        __DRIdrawable *dPriv)
769 {
770         struct gl_texture_unit *texUnit;
771         struct gl_texture_object *texObj;
772         struct gl_texture_image *texImage;
773         struct radeon_renderbuffer *rb;
774         radeon_texture_image *rImage;
775         radeonContextPtr radeon;
776         r200ContextPtr rmesa;
777         struct radeon_framebuffer *rfb;
778         radeonTexObjPtr t;
779         uint32_t pitch_val;
780         uint32_t internalFormat, format;
781         gl_format texFormat;
782
783         format = GL_UNSIGNED_BYTE;
784         internalFormat = (texture_format == __DRI_TEXTURE_FORMAT_RGB ? 3 : 4);
785
786         radeon = pDRICtx->driverPrivate;
787         rmesa = pDRICtx->driverPrivate;
788
789         rfb = dPriv->driverPrivate;
790         texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit];
791         texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target);
792         texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0);
793
794         rImage = get_radeon_texture_image(texImage);
795         t = radeon_tex_obj(texObj);
796         if (t == NULL) {
797             return;
798         }
799
800         radeon_update_renderbuffers(pDRICtx, dPriv, GL_TRUE);
801         rb = rfb->color_rb[0];
802         if (rb->bo == NULL) {
803                 /* Failed to BO for the buffer */
804                 return;
805         }
806
807         _mesa_lock_texture(radeon->glCtx, texObj);
808         if (t->bo) {
809                 radeon_bo_unref(t->bo);
810                 t->bo = NULL;
811         }
812         if (rImage->bo) {
813                 radeon_bo_unref(rImage->bo);
814                 rImage->bo = NULL;
815         }
816
817         radeon_miptree_unreference(&t->mt);
818         radeon_miptree_unreference(&rImage->mt);
819
820         rImage->bo = rb->bo;
821         radeon_bo_ref(rImage->bo);
822         t->bo = rb->bo;
823         radeon_bo_ref(t->bo);
824         t->tile_bits = 0;
825         t->image_override = GL_TRUE;
826         t->override_offset = 0;
827         t->pp_txpitch &= (1 << 13) -1;
828         pitch_val = rb->pitch;
829         switch (rb->cpp) {
830         case 4:
831                 if (texture_format == __DRI_TEXTURE_FORMAT_RGB) {
832                         texFormat = MESA_FORMAT_RGB888;
833                         t->pp_txformat = tx_table_le[MESA_FORMAT_RGB888].format;
834                 }
835                 else {
836                         texFormat = MESA_FORMAT_ARGB8888;
837                         t->pp_txformat = tx_table_le[MESA_FORMAT_ARGB8888].format;
838                 }
839                 t->pp_txfilter |= tx_table_le[MESA_FORMAT_ARGB8888].filter;
840                 break;
841         case 3:
842         default:
843                 texFormat = MESA_FORMAT_RGB888;
844                 t->pp_txformat = tx_table_le[MESA_FORMAT_RGB888].format;
845                 t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB888].filter;
846                 break;
847         case 2:
848                 texFormat = MESA_FORMAT_RGB565;
849                 t->pp_txformat = tx_table_le[MESA_FORMAT_RGB565].format;
850                 t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB565].filter;
851                 break;
852         }
853
854         _mesa_init_teximage_fields(radeon->glCtx, target, texImage,
855                                    rb->base.Width, rb->base.Height, 1, 0,
856                                    rb->cpp, texFormat);
857         texImage->RowStride = rb->pitch / rb->cpp;
858
859
860         t->pp_txsize = ((rb->base.Width - 1) << RADEON_TEX_USIZE_SHIFT)
861                    | ((rb->base.Height - 1) << RADEON_TEX_VSIZE_SHIFT);
862
863         if (target == GL_TEXTURE_RECTANGLE_NV) {
864                 t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
865                 t->pp_txpitch = pitch_val;
866                 t->pp_txpitch -= 32;
867         } else {
868                 t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
869                                     R200_TXFORMAT_HEIGHT_MASK |
870                                     R200_TXFORMAT_CUBIC_MAP_ENABLE |
871                                     R200_TXFORMAT_F5_WIDTH_MASK |
872                                     R200_TXFORMAT_F5_HEIGHT_MASK);
873                 t->pp_txformat |= ((texImage->WidthLog2 << R200_TXFORMAT_WIDTH_SHIFT) |
874                                    (texImage->HeightLog2 << R200_TXFORMAT_HEIGHT_SHIFT));
875         }
876
877         t->validated = GL_TRUE;
878         _mesa_unlock_texture(radeon->glCtx, texObj);
879         return;
880 }
881
882
883 void r200SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
884 {
885         r200SetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
886 }
887
888
889 #define REF_COLOR 1
890 #define REF_ALPHA 2
891
892 static GLboolean r200UpdateAllTexEnv( struct gl_context *ctx )
893 {
894    r200ContextPtr rmesa = R200_CONTEXT(ctx);
895    GLint i, j, currslot;
896    GLint maxunitused = -1;
897    GLboolean texregfree[6] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE};
898    GLubyte stageref[7] = {0, 0, 0, 0, 0, 0, 0};
899    GLint nextunit[R200_MAX_TEXTURE_UNITS] = {0, 0, 0, 0, 0, 0};
900    GLint currentnext = -1;
901    GLboolean ok;
902
903    /* find highest used unit */
904    for ( j = 0; j < R200_MAX_TEXTURE_UNITS; j++) {
905       if (ctx->Texture.Unit[j]._ReallyEnabled) {
906          maxunitused = j;
907       }
908    }
909    stageref[maxunitused + 1] = REF_COLOR | REF_ALPHA;
910
911    for ( j = maxunitused; j >= 0; j-- ) {
912       const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[j];
913
914       rmesa->state.texture.unit[j].outputreg = -1;
915
916       if (stageref[j + 1]) {
917
918          /* use the lowest available reg. That gets us automatically reg0 for the last stage.
919             need this even for disabled units, as it may get referenced due to the replace
920             optimization */
921          for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS; i++ ) {
922             if (texregfree[i]) {
923                rmesa->state.texture.unit[j].outputreg = i;
924                break;
925             }
926          }
927          if (rmesa->state.texture.unit[j].outputreg == -1) {
928             /* no more free regs we can use. Need a fallback :-( */
929             return GL_FALSE;
930          }
931
932          nextunit[j] = currentnext;
933
934          if (!texUnit->_ReallyEnabled) {
935          /* the not enabled stages are referenced "indirectly",
936             must not cut off the lower stages */
937             stageref[j] = REF_COLOR | REF_ALPHA;
938             continue;
939          }
940          currentnext = j;
941  
942          const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB;
943          const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA;
944          const GLboolean isdot3rgba = (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ||
945                                       (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT);
946
947
948          /* check if we need the color part, special case for dot3_rgba
949             as if only the alpha part is referenced later on it still is using the color part */
950          if ((stageref[j + 1] & REF_COLOR) || isdot3rgba) {
951             for ( i = 0 ; i < numColorArgs ; i++ ) {
952                const GLuint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i];
953                const GLuint op = texUnit->_CurrentCombine->OperandRGB[i];
954                switch ( srcRGBi ) {
955                case GL_PREVIOUS:
956                   /* op 0/1 are referencing color, op 2/3 alpha */
957                   stageref[j] |= (op >> 1) + 1;
958                   break;
959                case GL_TEXTURE:
960                   texregfree[j] = GL_FALSE;
961                   break;
962                case GL_TEXTURE0:
963                case GL_TEXTURE1:
964                case GL_TEXTURE2:
965                case GL_TEXTURE3:
966                case GL_TEXTURE4:
967                case GL_TEXTURE5:
968                   texregfree[srcRGBi - GL_TEXTURE0] = GL_FALSE;
969                   break;
970                default: /* don't care about other sources here */
971                   break;
972                }
973             }
974          }
975
976          /* alpha args are ignored for dot3_rgba */
977          if ((stageref[j + 1] & REF_ALPHA) && !isdot3rgba) {
978
979             for ( i = 0 ; i < numAlphaArgs ; i++ ) {
980                const GLuint srcAi = texUnit->_CurrentCombine->SourceA[i];
981                switch ( srcAi ) {
982                case GL_PREVIOUS:
983                   stageref[j] |= REF_ALPHA;
984                   break;
985                case GL_TEXTURE:
986                   texregfree[j] = GL_FALSE;
987                   break;
988                case GL_TEXTURE0:
989                case GL_TEXTURE1:
990                case GL_TEXTURE2:
991                case GL_TEXTURE3:
992                case GL_TEXTURE4:
993                case GL_TEXTURE5:
994                   texregfree[srcAi - GL_TEXTURE0] = GL_FALSE;
995                   break;
996                default: /* don't care about other sources here */
997                   break;
998                }
999             }
1000          }
1001       }
1002    }
1003
1004    /* don't enable texture sampling for units if the result is not used */
1005    for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) {
1006       if (ctx->Texture.Unit[i]._ReallyEnabled && !texregfree[i])
1007          rmesa->state.texture.unit[i].unitneeded = ctx->Texture.Unit[i]._ReallyEnabled;
1008       else rmesa->state.texture.unit[i].unitneeded = 0;
1009    }
1010
1011    ok = GL_TRUE;
1012    currslot = 0;
1013    rmesa->state.envneeded = 1;
1014
1015    i = 0;
1016    while ((i <= maxunitused) && (i >= 0)) {
1017       /* only output instruction if the results are referenced */
1018       if (ctx->Texture.Unit[i]._ReallyEnabled && stageref[i+1]) {
1019          GLuint replaceunit = i;
1020          /* try to optimize GL_REPLACE away (only one level deep though) */
1021          if (   (ctx->Texture.Unit[i]._CurrentCombine->ModeRGB == GL_REPLACE) &&
1022                 (ctx->Texture.Unit[i]._CurrentCombine->ModeA == GL_REPLACE) &&
1023                 (ctx->Texture.Unit[i]._CurrentCombine->ScaleShiftRGB == 0) &&
1024                 (ctx->Texture.Unit[i]._CurrentCombine->ScaleShiftA == 0) &&
1025                 (nextunit[i] > 0) ) {
1026             /* yippie! can optimize it away! */
1027             replaceunit = i;
1028             i = nextunit[i];
1029          }
1030
1031          /* need env instruction slot */
1032          rmesa->state.envneeded |= 1 << currslot;
1033          ok = r200UpdateTextureEnv( ctx, i, currslot, replaceunit );
1034          if (!ok) return GL_FALSE;
1035          currslot++;
1036       }
1037       i = i + 1;
1038    }
1039
1040    if (currslot == 0) {
1041       /* need one stage at least */
1042       rmesa->state.texture.unit[0].outputreg = 0;
1043       ok = r200UpdateTextureEnv( ctx, 0, 0, 0 );
1044    }
1045
1046    R200_STATECHANGE( rmesa, ctx );
1047    rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_TEX_BLEND_ENABLE_MASK | R200_MULTI_PASS_ENABLE);
1048    rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= rmesa->state.envneeded << R200_TEX_BLEND_0_ENABLE_SHIFT;
1049
1050    return ok;
1051 }
1052
1053 #undef REF_COLOR
1054 #undef REF_ALPHA
1055
1056
1057 #define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK |         \
1058                               R200_MIN_FILTER_MASK |            \
1059                               R200_MAG_FILTER_MASK |            \
1060                               R200_MAX_ANISO_MASK |             \
1061                               R200_YUV_TO_RGB |                 \
1062                               R200_YUV_TEMPERATURE_MASK |       \
1063                               R200_CLAMP_S_MASK |               \
1064                               R200_CLAMP_T_MASK |               \
1065                               R200_BORDER_MODE_D3D )
1066
1067 #define TEXOBJ_TXFORMAT_MASK (R200_TXFORMAT_WIDTH_MASK |        \
1068                               R200_TXFORMAT_HEIGHT_MASK |       \
1069                               R200_TXFORMAT_FORMAT_MASK |       \
1070                               R200_TXFORMAT_F5_WIDTH_MASK |     \
1071                               R200_TXFORMAT_F5_HEIGHT_MASK |    \
1072                               R200_TXFORMAT_ALPHA_IN_MAP |      \
1073                               R200_TXFORMAT_CUBIC_MAP_ENABLE |  \
1074                               R200_TXFORMAT_NON_POWER2)
1075
1076 #define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK |          \
1077                                 R200_TEXCOORD_MASK |            \
1078                                 R200_MIN_MIP_LEVEL_MASK |       \
1079                                 R200_CLAMP_Q_MASK |             \
1080                                 R200_VOLUME_FILTER_MASK)
1081
1082
1083 static void disable_tex_obj_state( r200ContextPtr rmesa, 
1084                                    int unit )
1085 {
1086    
1087    R200_STATECHANGE( rmesa, vtx );
1088    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
1089
1090    R200_STATECHANGE( rmesa, ctx );
1091    rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_TEX_0_ENABLE << unit);
1092    if (rmesa->radeon.TclFallback & (R200_TCL_FALLBACK_TEXGEN_0<<unit)) {
1093       TCL_FALLBACK( rmesa->radeon.glCtx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
1094    }
1095
1096    /* Actually want to keep all units less than max active texture
1097     * enabled, right?  Fix this for >2 texunits.
1098     */
1099
1100    {
1101       GLuint tmp = rmesa->TexGenEnabled;
1102
1103       rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
1104       rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
1105       rmesa->TexGenNeedNormals[unit] = GL_FALSE;
1106       rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
1107
1108       if (tmp != rmesa->TexGenEnabled) {
1109          rmesa->recheck_texgen[unit] = GL_TRUE;
1110          rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
1111       }
1112    }
1113 }
1114 static void import_tex_obj_state( r200ContextPtr rmesa,
1115                                   int unit,
1116                                   radeonTexObjPtr texobj )
1117 {
1118 /* do not use RADEON_DB_STATE to avoid stale texture caches */
1119    GLuint *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0];
1120
1121    R200_STATECHANGE( rmesa, tex[unit] );
1122
1123    cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK;
1124    cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK;
1125    cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1126    cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK;
1127    cmd[TEX_PP_TXFORMAT_X] &= ~TEXOBJ_TXFORMAT_X_MASK;
1128    cmd[TEX_PP_TXFORMAT_X] |= texobj->pp_txformat_x & TEXOBJ_TXFORMAT_X_MASK;
1129    cmd[TEX_PP_TXSIZE] = texobj->pp_txsize; /* NPOT only! */
1130    cmd[TEX_PP_TXPITCH] = texobj->pp_txpitch; /* NPOT only! */
1131    cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
1132
1133    if (texobj->base.Target == GL_TEXTURE_CUBE_MAP) {
1134       GLuint *cube_cmd = &rmesa->hw.cube[unit].cmd[CUBE_CMD_0];
1135
1136       R200_STATECHANGE( rmesa, cube[unit] );
1137       cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
1138       if (rmesa->radeon.radeonScreen->drmSupportsFragShader) {
1139          /* that value is submitted twice. could change cube atom
1140             to not include that command when new drm is used */
1141          cmd[TEX_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
1142       }
1143    }
1144
1145 }
1146
1147 static void set_texgen_matrix( r200ContextPtr rmesa, 
1148                                GLuint unit,
1149                                const GLfloat *s_plane,
1150                                const GLfloat *t_plane,
1151                                const GLfloat *r_plane,
1152                                const GLfloat *q_plane )
1153 {
1154    GLfloat m[16];
1155
1156    m[0]  = s_plane[0];
1157    m[4]  = s_plane[1];
1158    m[8]  = s_plane[2];
1159    m[12] = s_plane[3];
1160
1161    m[1]  = t_plane[0];
1162    m[5]  = t_plane[1];
1163    m[9]  = t_plane[2];
1164    m[13] = t_plane[3];
1165
1166    m[2]  = r_plane[0];
1167    m[6]  = r_plane[1];
1168    m[10] = r_plane[2];
1169    m[14] = r_plane[3];
1170
1171    m[3]  = q_plane[0];
1172    m[7]  = q_plane[1];
1173    m[11] = q_plane[2];
1174    m[15] = q_plane[3];
1175
1176    _math_matrix_loadf( &(rmesa->TexGenMatrix[unit]), m);
1177    _math_matrix_analyse( &(rmesa->TexGenMatrix[unit]) );
1178    rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit;
1179 }
1180
1181
1182 static GLuint r200_need_dis_texgen(const GLbitfield texGenEnabled,
1183                                    const GLfloat *planeS,
1184                                    const GLfloat *planeT,
1185                                    const GLfloat *planeR,
1186                                    const GLfloat *planeQ)
1187 {
1188    GLuint needtgenable = 0;
1189
1190    if (!(texGenEnabled & S_BIT)) {
1191       if (((texGenEnabled & T_BIT) && planeT[0] != 0.0) ||
1192          ((texGenEnabled & R_BIT) && planeR[0] != 0.0) ||
1193          ((texGenEnabled & Q_BIT) && planeQ[0] != 0.0)) {
1194          needtgenable |= S_BIT;
1195       }
1196    }
1197    if (!(texGenEnabled & T_BIT)) {
1198       if (((texGenEnabled & S_BIT) && planeS[1] != 0.0) ||
1199          ((texGenEnabled & R_BIT) && planeR[1] != 0.0) ||
1200          ((texGenEnabled & Q_BIT) && planeQ[1] != 0.0)) {
1201          needtgenable |= T_BIT;
1202      }
1203    }
1204    if (!(texGenEnabled & R_BIT)) {
1205       if (((texGenEnabled & S_BIT) && planeS[2] != 0.0) ||
1206          ((texGenEnabled & T_BIT) && planeT[2] != 0.0) ||
1207          ((texGenEnabled & Q_BIT) && planeQ[2] != 0.0)) {
1208          needtgenable |= R_BIT;
1209       }
1210    }
1211    if (!(texGenEnabled & Q_BIT)) {
1212       if (((texGenEnabled & S_BIT) && planeS[3] != 0.0) ||
1213          ((texGenEnabled & T_BIT) && planeT[3] != 0.0) ||
1214          ((texGenEnabled & R_BIT) && planeR[3] != 0.0)) {
1215          needtgenable |= Q_BIT;
1216       }
1217    }
1218
1219    return needtgenable;
1220 }
1221
1222
1223 /*
1224  * Returns GL_FALSE if fallback required.  
1225  */
1226 static GLboolean r200_validate_texgen( struct gl_context *ctx, GLuint unit )
1227 {  
1228    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1229    const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1230    GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit*4;
1231    GLuint tgi, tgcm;
1232    GLuint mode = 0;
1233    GLboolean mixed_fallback = GL_FALSE;
1234    static const GLfloat I[16] = {
1235       1,  0,  0,  0,
1236       0,  1,  0,  0,
1237       0,  0,  1,  0,
1238       0,  0,  0,  1 };
1239    static const GLfloat reflect[16] = {
1240       -1,  0,  0,  0,
1241        0, -1,  0,  0,
1242        0,  0,  -1, 0,
1243        0,  0,  0,  1 };
1244
1245    rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
1246    rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
1247    rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
1248    rmesa->TexGenNeedNormals[unit] = GL_FALSE;
1249    tgi = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] & ~(R200_TEXGEN_INPUT_MASK <<
1250                                                    inputshift);
1251    tgcm = rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] & ~(R200_TEXGEN_COMP_MASK <<
1252                                                     (unit * 4));
1253
1254    if (0) 
1255       fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit);
1256
1257    if (texUnit->TexGenEnabled & S_BIT) {
1258       mode = texUnit->GenS.Mode;
1259    } else {
1260       tgcm |= R200_TEXGEN_COMP_S << (unit * 4);
1261    }
1262
1263    if (texUnit->TexGenEnabled & T_BIT) {
1264       if (texUnit->GenT.Mode != mode)
1265          mixed_fallback = GL_TRUE;
1266    } else {
1267       tgcm |= R200_TEXGEN_COMP_T << (unit * 4);
1268    }
1269    if (texUnit->TexGenEnabled & R_BIT) {
1270       if (texUnit->GenR.Mode != mode)
1271          mixed_fallback = GL_TRUE;
1272    } else {
1273       tgcm |= R200_TEXGEN_COMP_R << (unit * 4);
1274    }
1275
1276    if (texUnit->TexGenEnabled & Q_BIT) {
1277       if (texUnit->GenQ.Mode != mode)
1278          mixed_fallback = GL_TRUE;
1279    } else {
1280       tgcm |= R200_TEXGEN_COMP_Q << (unit * 4);
1281    }
1282
1283    if (mixed_fallback) {
1284       if (R200_DEBUG & RADEON_FALLBACKS)
1285          fprintf(stderr, "fallback mixed texgen, 0x%x (0x%x 0x%x 0x%x 0x%x)\n",
1286                  texUnit->TexGenEnabled, texUnit->GenS.Mode, texUnit->GenT.Mode,
1287                  texUnit->GenR.Mode, texUnit->GenQ.Mode);
1288       return GL_FALSE;
1289    }
1290
1291 /* we CANNOT do mixed mode if the texgen mode requires a plane where the input
1292    is not enabled for texgen, since the planes are concatenated into texmat,
1293    and thus the input will come from texcoord rather than tex gen equation!
1294    Either fallback or just hope that those texcoords aren't really needed...
1295    Assuming the former will cause lots of unnecessary fallbacks, the latter will
1296    generate bogus results sometimes - it's pretty much impossible to really know
1297    when a fallback is needed, depends on texmat and what sort of texture is bound
1298    etc, - for now fallback if we're missing either S or T bits, there's a high
1299    probability we need the texcoords in that case.
1300    That's a lot of work for some obscure texgen mixed mode fixup - why oh why
1301    doesn't the chip just directly accept the plane parameters :-(. */
1302    switch (mode) {
1303    case GL_OBJECT_LINEAR: {
1304       GLuint needtgenable = r200_need_dis_texgen( texUnit->TexGenEnabled,
1305                                                   texUnit->GenS.ObjectPlane,
1306                                                   texUnit->GenT.ObjectPlane,
1307                                                   texUnit->GenR.ObjectPlane,
1308                                                   texUnit->GenQ.ObjectPlane );
1309       if (needtgenable & (S_BIT | T_BIT)) {
1310          if (R200_DEBUG & RADEON_FALLBACKS)
1311          fprintf(stderr, "fallback mixed texgen / obj plane, 0x%x\n",
1312                  texUnit->TexGenEnabled);
1313          return GL_FALSE;
1314       }
1315       if (needtgenable & (R_BIT)) {
1316          tgcm &= ~(R200_TEXGEN_COMP_R << (unit * 4));
1317       }
1318       if (needtgenable & (Q_BIT)) {
1319          tgcm &= ~(R200_TEXGEN_COMP_Q << (unit * 4));
1320       }
1321
1322       tgi |= R200_TEXGEN_INPUT_OBJ << inputshift;
1323       set_texgen_matrix( rmesa, unit, 
1324          (texUnit->TexGenEnabled & S_BIT) ? texUnit->GenS.ObjectPlane : I,
1325          (texUnit->TexGenEnabled & T_BIT) ? texUnit->GenT.ObjectPlane : I + 4,
1326          (texUnit->TexGenEnabled & R_BIT) ? texUnit->GenR.ObjectPlane : I + 8,
1327          (texUnit->TexGenEnabled & Q_BIT) ? texUnit->GenQ.ObjectPlane : I + 12);
1328       }
1329       break;
1330
1331    case GL_EYE_LINEAR: {
1332       GLuint needtgenable = r200_need_dis_texgen( texUnit->TexGenEnabled,
1333                                                   texUnit->GenS.EyePlane,
1334                                                   texUnit->GenT.EyePlane,
1335                                                   texUnit->GenR.EyePlane,
1336                                                   texUnit->GenQ.EyePlane );
1337       if (needtgenable & (S_BIT | T_BIT)) {
1338          if (R200_DEBUG & RADEON_FALLBACKS)
1339          fprintf(stderr, "fallback mixed texgen / eye plane, 0x%x\n",
1340                  texUnit->TexGenEnabled);
1341          return GL_FALSE;
1342       }
1343       if (needtgenable & (R_BIT)) {
1344          tgcm &= ~(R200_TEXGEN_COMP_R << (unit * 4));
1345       }
1346       if (needtgenable & (Q_BIT)) {
1347          tgcm &= ~(R200_TEXGEN_COMP_Q << (unit * 4));
1348       }
1349       tgi |= R200_TEXGEN_INPUT_EYE << inputshift;
1350       set_texgen_matrix( rmesa, unit,
1351          (texUnit->TexGenEnabled & S_BIT) ? texUnit->GenS.EyePlane : I,
1352          (texUnit->TexGenEnabled & T_BIT) ? texUnit->GenT.EyePlane : I + 4,
1353          (texUnit->TexGenEnabled & R_BIT) ? texUnit->GenR.EyePlane : I + 8,
1354          (texUnit->TexGenEnabled & Q_BIT) ? texUnit->GenQ.EyePlane : I + 12);
1355       }
1356       break;
1357
1358    case GL_REFLECTION_MAP_NV:
1359       rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1360       tgi |= R200_TEXGEN_INPUT_EYE_REFLECT << inputshift;
1361       /* pretty weird, must only negate when lighting is enabled? */
1362       if (ctx->Light.Enabled)
1363          set_texgen_matrix( rmesa, unit, 
1364             (texUnit->TexGenEnabled & S_BIT) ? reflect : I,
1365             (texUnit->TexGenEnabled & T_BIT) ? reflect + 4 : I + 4,
1366             (texUnit->TexGenEnabled & R_BIT) ? reflect + 8 : I + 8,
1367             I + 12);
1368       break;
1369
1370    case GL_NORMAL_MAP_NV:
1371       rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1372       tgi |= R200_TEXGEN_INPUT_EYE_NORMAL<<inputshift;
1373       break;
1374
1375    case GL_SPHERE_MAP:
1376       rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1377       tgi |= R200_TEXGEN_INPUT_SPHERE<<inputshift;
1378       break;
1379
1380    case 0:
1381       /* All texgen units were disabled, so just pass coords through. */
1382       tgi |= unit << inputshift;
1383       break;
1384
1385    default:
1386       /* Unsupported mode, fallback:
1387        */
1388       if (R200_DEBUG & RADEON_FALLBACKS)
1389          fprintf(stderr, "fallback unsupported texgen, %d\n",
1390                  texUnit->GenS.Mode);
1391       return GL_FALSE;
1392    }
1393
1394    rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
1395    rmesa->TexGenCompSel |= R200_OUTPUT_TEX_0 << unit;
1396
1397    if (tgi != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] || 
1398        tgcm != rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2])
1399    {
1400       R200_STATECHANGE(rmesa, tcg);
1401       rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_1] = tgi;
1402       rmesa->hw.tcg.cmd[TCG_TEX_PROC_CTL_2] = tgcm;
1403    }
1404
1405    return GL_TRUE;
1406 }
1407
1408 void set_re_cntl_d3d( struct gl_context *ctx, int unit, GLboolean use_d3d )
1409 {
1410    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1411
1412    GLuint re_cntl;
1413
1414    re_cntl = rmesa->hw.set.cmd[SET_RE_CNTL] & ~(R200_VTX_STQ0_D3D << (2 * unit));
1415    if (use_d3d)
1416       re_cntl |= R200_VTX_STQ0_D3D << (2 * unit);
1417
1418    if ( re_cntl != rmesa->hw.set.cmd[SET_RE_CNTL] ) {
1419       R200_STATECHANGE( rmesa, set );
1420       rmesa->hw.set.cmd[SET_RE_CNTL] = re_cntl;
1421    }
1422 }
1423
1424 /**
1425  * Compute the cached hardware register values for the given texture object.
1426  *
1427  * \param rmesa Context pointer
1428  * \param t the r300 texture object
1429  */
1430 static void setup_hardware_state(r200ContextPtr rmesa, radeonTexObj *t)
1431 {
1432    const struct gl_texture_image *firstImage = t->base.Image[0][t->minLod];
1433    GLint log2Width, log2Height, log2Depth, texelBytes;
1434    uint extra_size = 0;
1435
1436    if ( t->bo ) {
1437        return;
1438    }
1439
1440    log2Width  = firstImage->WidthLog2;
1441    log2Height = firstImage->HeightLog2;
1442    log2Depth  = firstImage->DepthLog2;
1443    texelBytes = _mesa_get_format_bytes(firstImage->TexFormat);
1444
1445    radeon_print(RADEON_TEXTURE, RADEON_TRACE,
1446         "%s(%p, tex %p) log2(w %d, h %d, d %d), texelBytes %d. format %d\n",
1447         __func__, rmesa, t, log2Width, log2Height,
1448         log2Depth, texelBytes, firstImage->TexFormat);
1449
1450    if (!t->image_override) {
1451       if (VALID_FORMAT(firstImage->TexFormat)) {
1452          const struct tx_table *table = _mesa_little_endian() ? tx_table_le :
1453             tx_table_be;
1454          
1455          t->pp_txformat &= ~(R200_TXFORMAT_FORMAT_MASK |
1456                              R200_TXFORMAT_ALPHA_IN_MAP);
1457          t->pp_txfilter &= ~R200_YUV_TO_RGB;
1458          
1459          t->pp_txformat |= table[ firstImage->TexFormat ].format;
1460          t->pp_txfilter |= table[ firstImage->TexFormat ].filter;
1461
1462
1463       } else {
1464          _mesa_problem(NULL, "unexpected texture format in %s",
1465                        __FUNCTION__);
1466          return;
1467       }
1468    }
1469
1470    t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK;
1471    t->pp_txfilter |= ((t->maxLod) << R200_MAX_MIP_LEVEL_SHIFT)
1472            & R200_MAX_MIP_LEVEL_MASK;
1473
1474    if ( t->pp_txfilter &
1475                 (R200_MIN_FILTER_NEAREST_MIP_NEAREST
1476                  | R200_MIN_FILTER_NEAREST_MIP_LINEAR
1477                  | R200_MIN_FILTER_LINEAR_MIP_NEAREST
1478                  | R200_MIN_FILTER_LINEAR_MIP_LINEAR
1479                  | R200_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST
1480                  | R200_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR))
1481                  extra_size = t->minLod;
1482
1483    t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
1484                        R200_TXFORMAT_HEIGHT_MASK |
1485                        R200_TXFORMAT_CUBIC_MAP_ENABLE |
1486                        R200_TXFORMAT_F5_WIDTH_MASK |
1487                        R200_TXFORMAT_F5_HEIGHT_MASK);
1488    t->pp_txformat |= (((log2Width + extra_size) << R200_TXFORMAT_WIDTH_SHIFT) |
1489                       ((log2Height + extra_size)<< R200_TXFORMAT_HEIGHT_SHIFT));
1490    
1491    t->tile_bits = 0;
1492    
1493    t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK
1494                    | R200_MIN_MIP_LEVEL_MASK);
1495
1496    t->pp_txformat_x |= (t->minLod << R200_MIN_MIP_LEVEL_SHIFT)
1497            & R200_MIN_MIP_LEVEL_MASK;
1498
1499    if (t->base.Target == GL_TEXTURE_3D) {
1500       t->pp_txformat_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT);
1501       t->pp_txformat_x |= R200_TEXCOORD_VOLUME;
1502
1503    }
1504    else if (t->base.Target == GL_TEXTURE_CUBE_MAP) {
1505       ASSERT(log2Width == log2Height);
1506       t->pp_txformat |= ((log2Width << R200_TXFORMAT_F5_WIDTH_SHIFT) |
1507                          (log2Height << R200_TXFORMAT_F5_HEIGHT_SHIFT) |
1508                          /* don't think we need this bit, if it exists at all - fglrx does not set it */
1509                          (R200_TXFORMAT_CUBIC_MAP_ENABLE));
1510       t->pp_txformat_x |= R200_TEXCOORD_CUBIC_ENV;
1511       t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) |
1512                            (log2Height << R200_FACE_HEIGHT_1_SHIFT) |
1513                            (log2Width << R200_FACE_WIDTH_2_SHIFT) |
1514                            (log2Height << R200_FACE_HEIGHT_2_SHIFT) |
1515                            (log2Width << R200_FACE_WIDTH_3_SHIFT) |
1516                            (log2Height << R200_FACE_HEIGHT_3_SHIFT) |
1517                            (log2Width << R200_FACE_WIDTH_4_SHIFT) |
1518                            (log2Height << R200_FACE_HEIGHT_4_SHIFT));
1519    }
1520    else {
1521       /* If we don't in fact send enough texture coordinates, q will be 1,
1522        * making TEXCOORD_PROJ act like TEXCOORD_NONPROJ (Right?)
1523        */
1524       t->pp_txformat_x |= R200_TEXCOORD_PROJ;
1525    }
1526    /* FIXME: NPOT sizes, Is it correct realy? */
1527    t->pp_txsize = (((firstImage->Width - 1) << R200_PP_TX_WIDTHMASK_SHIFT)
1528                    | ((firstImage->Height - 1) << R200_PP_TX_HEIGHTMASK_SHIFT));
1529
1530    if ( !t->image_override ) {
1531       if (_mesa_is_format_compressed(firstImage->TexFormat))
1532          t->pp_txpitch = (firstImage->Width + 63) & ~(63);
1533       else
1534          t->pp_txpitch = ((firstImage->Width * texelBytes) + 63) & ~(63);
1535       t->pp_txpitch -= 32;
1536    }
1537
1538    if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) {
1539       t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
1540    }
1541
1542 }
1543
1544 static GLboolean r200_validate_texture(struct gl_context *ctx, struct gl_texture_object *texObj, int unit)
1545 {
1546    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1547    radeonTexObj *t = radeon_tex_obj(texObj);
1548
1549    if (!radeon_validate_texture_miptree(ctx, texObj))
1550       return GL_FALSE;
1551
1552    r200_validate_texgen(ctx, unit);
1553    /* Configure the hardware registers (more precisely, the cached version
1554     * of the hardware registers). */
1555    setup_hardware_state(rmesa, t);
1556
1557    if (texObj->Target == GL_TEXTURE_RECTANGLE_NV ||
1558        texObj->Target == GL_TEXTURE_2D ||
1559        texObj->Target == GL_TEXTURE_1D)
1560       set_re_cntl_d3d( ctx, unit, GL_FALSE );
1561    else
1562       set_re_cntl_d3d( ctx, unit, GL_TRUE );
1563    R200_STATECHANGE( rmesa, ctx );
1564    rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_0_ENABLE << unit;
1565    
1566    R200_STATECHANGE( rmesa, vtx );
1567    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
1568    rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3);
1569
1570    rmesa->recheck_texgen[unit] = GL_TRUE;
1571    import_tex_obj_state( rmesa, unit, t );
1572
1573    if (rmesa->recheck_texgen[unit]) {
1574       GLboolean fallback = !r200_validate_texgen( ctx, unit );
1575       TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
1576       rmesa->recheck_texgen[unit] = 0;
1577       rmesa->radeon.NewGLState |= _NEW_TEXTURE_MATRIX;
1578    }
1579
1580    t->validated = GL_TRUE;
1581
1582    FALLBACK( rmesa, RADEON_FALLBACK_BORDER_MODE, t->border_fallback );
1583
1584    return !t->border_fallback;
1585 }
1586
1587 static GLboolean r200UpdateTextureUnit(struct gl_context *ctx, int unit)
1588 {
1589    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1590    GLuint unitneeded = rmesa->state.texture.unit[unit].unitneeded;
1591
1592    if (!unitneeded) {
1593       /* disable the unit */
1594      disable_tex_obj_state(rmesa, unit);
1595      return GL_TRUE;
1596    }
1597
1598    if (!r200_validate_texture(ctx, ctx->Texture.Unit[unit]._Current, unit)) {
1599     _mesa_warning(ctx,
1600                   "failed to validate texture for unit %d.\n",
1601                   unit);
1602     rmesa->state.texture.unit[unit].texobj = NULL;
1603     return GL_FALSE;
1604   }
1605
1606    rmesa->state.texture.unit[unit].texobj = radeon_tex_obj(ctx->Texture.Unit[unit]._Current);
1607   return GL_TRUE;
1608 }
1609
1610
1611 void r200UpdateTextureState( struct gl_context *ctx )
1612 {
1613    r200ContextPtr rmesa = R200_CONTEXT(ctx);
1614    GLboolean ok;
1615    GLuint dbg;
1616
1617    /* NOTE: must not manipulate rmesa->state.texture.unit[].unitneeded or
1618       rmesa->state.envneeded before a R200_STATECHANGE (or R200_NEWPRIM) since
1619       we use these to determine if we want to emit the corresponding state
1620       atoms. */
1621    R200_NEWPRIM( rmesa );
1622
1623    if (ctx->ATIFragmentShader._Enabled) {
1624       GLuint i;
1625       for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) {
1626          rmesa->state.texture.unit[i].unitneeded = ctx->Texture.Unit[i]._ReallyEnabled;
1627       }
1628       ok = GL_TRUE;
1629    }
1630    else {
1631       ok = r200UpdateAllTexEnv( ctx );
1632    }
1633    if (ok) {
1634       ok = (r200UpdateTextureUnit( ctx, 0 ) &&
1635          r200UpdateTextureUnit( ctx, 1 ) &&
1636          r200UpdateTextureUnit( ctx, 2 ) &&
1637          r200UpdateTextureUnit( ctx, 3 ) &&
1638          r200UpdateTextureUnit( ctx, 4 ) &&
1639          r200UpdateTextureUnit( ctx, 5 ));
1640    }
1641
1642    if (ok && ctx->ATIFragmentShader._Enabled) {
1643       r200UpdateFragmentShader(ctx);
1644    }
1645
1646    FALLBACK( rmesa, R200_FALLBACK_TEXTURE, !ok );
1647
1648    if (rmesa->radeon.TclFallback)
1649       r200ChooseVertexState( ctx );
1650
1651
1652    if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) {
1653
1654       /*
1655        * T0 hang workaround -------------
1656        * not needed for r200 derivatives
1657         */
1658       if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_ENABLE_MASK) == R200_TEX_0_ENABLE &&
1659          (rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > R200_MIN_FILTER_LINEAR) {
1660
1661          R200_STATECHANGE(rmesa, ctx);
1662          R200_STATECHANGE(rmesa, tex[1]);
1663          rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_1_ENABLE;
1664          if (!(rmesa->hw.cst.cmd[CST_PP_CNTL_X] & R200_PPX_TEX_1_ENABLE))
1665            rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1666          rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] |= R200_TXFORMAT_LOOKUP_DISABLE;
1667       }
1668       else if (!ctx->ATIFragmentShader._Enabled) {
1669          if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE) &&
1670             (rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] & R200_TXFORMAT_LOOKUP_DISABLE)) {
1671             R200_STATECHANGE(rmesa, tex[1]);
1672             rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~R200_TXFORMAT_LOOKUP_DISABLE;
1673          }
1674       }
1675       /* do the same workaround for the first pass of a fragment shader.
1676        * completely unknown if necessary / sufficient.
1677        */
1678       if ((rmesa->hw.cst.cmd[CST_PP_CNTL_X] & R200_PPX_TEX_ENABLE_MASK) == R200_PPX_TEX_0_ENABLE &&
1679          (rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > R200_MIN_FILTER_LINEAR) {
1680
1681          R200_STATECHANGE(rmesa, cst);
1682          R200_STATECHANGE(rmesa, tex[1]);
1683          rmesa->hw.cst.cmd[CST_PP_CNTL_X] |= R200_PPX_TEX_1_ENABLE;
1684          if (!(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE))
1685             rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1686          rmesa->hw.tex[1].cmd[TEX_PP_TXMULTI_CTL] |= R200_PASS1_TXFORMAT_LOOKUP_DISABLE;
1687       }
1688
1689       /* maybe needs to be done pairwise due to 2 parallel (physical) tex units ?
1690          looks like that's not the case, if 8500/9100 owners don't complain remove this...
1691       for ( i = 0; i < ctx->Const.MaxTextureUnits; i += 2) {
1692          if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & ((R200_TEX_0_ENABLE |
1693             R200_TEX_1_ENABLE ) << i)) == (R200_TEX_0_ENABLE << i)) &&
1694             ((rmesa->hw.tex[i].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) >
1695             R200_MIN_FILTER_LINEAR)) {
1696             R200_STATECHANGE(rmesa, ctx);
1697             R200_STATECHANGE(rmesa, tex[i+1]);
1698             rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_1_ENABLE << i);
1699             rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1700             rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] |= 0x08000000;
1701          }
1702          else {
1703             if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE << i)) &&
1704                (rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] & 0x08000000)) {
1705                R200_STATECHANGE(rmesa, tex[i+1]);
1706                rmesa->hw.tex[i+1].cmd[TEX_PP_TXFORMAT] &= ~0x08000000;
1707             }
1708          }
1709       } */
1710
1711       /*
1712        * Texture cache LRU hang workaround -------------
1713        * not needed for r200 derivatives
1714        * hopefully this covers first pass of a shader as well
1715        */
1716
1717       /* While the cases below attempt to only enable the workaround in the
1718        * specific cases necessary, they were insufficient.  See bugzilla #1519,
1719        * #729, #814.  Tests with quake3 showed no impact on performance.
1720        */
1721       dbg = 0x6;
1722
1723       /*
1724       if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE )) &&
1725          ((((rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1726          0x04) == 0)) ||
1727          ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_2_ENABLE) &&
1728          ((((rmesa->hw.tex[2].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1729          0x04) == 0)) ||
1730          ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_4_ENABLE) &&
1731          ((((rmesa->hw.tex[4].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1732          0x04) == 0)))
1733       {
1734          dbg |= 0x02;
1735       }
1736
1737       if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_1_ENABLE )) &&
1738          ((((rmesa->hw.tex[1].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1739          0x04) == 0)) ||
1740          ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_3_ENABLE) &&
1741          ((((rmesa->hw.tex[3].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1742          0x04) == 0)) ||
1743          ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_5_ENABLE) &&
1744          ((((rmesa->hw.tex[5].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1745          0x04) == 0)))
1746       {
1747          dbg |= 0x04;
1748       }*/
1749
1750       if (dbg != rmesa->hw.tam.cmd[TAM_DEBUG3]) {
1751          R200_STATECHANGE( rmesa, tam );
1752          rmesa->hw.tam.cmd[TAM_DEBUG3] = dbg;
1753          if (0) printf("TEXCACHE LRU HANG WORKAROUND %x\n", dbg);
1754       }
1755    }
1756 }