r200_texstate.c revision bcc6eddd335e97d49ed2ef3a1440f94d58dce12d
1/* $XFree86: xc/lib/GL/mesa/src/drv/r200/r200_texstate.c,v 1.3 2003/02/15 22:18:47 dawes Exp $ */
2/*
3Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
4
5The Weather Channel (TM) funded Tungsten Graphics to develop the
6initial release of the Radeon 8500 driver under the XFree86 license.
7This notice must be preserved.
8
9Permission is hereby granted, free of charge, to any person obtaining
10a copy of this software and associated documentation files (the
11"Software"), to deal in the Software without restriction, including
12without limitation the rights to use, copy, modify, merge, publish,
13distribute, sublicense, and/or sell copies of the Software, and to
14permit persons to whom the Software is furnished to do so, subject to
15the following conditions:
16
17The above copyright notice and this permission notice (including the
18next paragraph) shall be included in all copies or substantial
19portions of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
25LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29**************************************************************************/
30
31/*
32 * Authors:
33 *   Keith Whitwell <keith@tungstengraphics.com>
34 */
35
36#include "glheader.h"
37#include "imports.h"
38#include "context.h"
39#include "macros.h"
40#include "texformat.h"
41#include "enums.h"
42
43#include "r200_context.h"
44#include "r200_state.h"
45#include "r200_ioctl.h"
46#include "r200_swtcl.h"
47#include "r200_tex.h"
48#include "r200_tcl.h"
49
50
51#define R200_TXFORMAT_AL88      R200_TXFORMAT_AI88
52#define R200_TXFORMAT_YCBCR     R200_TXFORMAT_YVYU422
53#define R200_TXFORMAT_YCBCR_REV R200_TXFORMAT_VYUY422
54
55#define _COLOR(f) \
56    [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, 0 }
57#define _ALPHA(f) \
58    [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f | R200_TXFORMAT_ALPHA_IN_MAP, 0 }
59#define _YUV(f) \
60    [ MESA_FORMAT_ ## f ] = { R200_TXFORMAT_ ## f, R200_YUV_TO_RGB }
61#define _INVALID(f) \
62    [ MESA_FORMAT_ ## f ] = { 0xffffffff, 0 }
63#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_YCBCR_REV) \
64			     && (tx_table[f].format != 0xffffffff) )
65
66static const struct {
67   GLuint format, filter;
68}
69tx_table[] =
70{
71   _ALPHA(RGBA8888),
72   _ALPHA(ARGB8888),
73   _INVALID(RGB888),
74   _COLOR(RGB565),
75   _ALPHA(ARGB4444),
76   _ALPHA(ARGB1555),
77   _ALPHA(AL88),
78   _INVALID(A8),
79   _INVALID(L8),
80   _COLOR(I8),
81   _INVALID(CI8),
82   _YUV(YCBCR),
83   _YUV(YCBCR_REV),
84};
85
86#undef _COLOR
87#undef _ALPHA
88#undef _INVALID
89
90/**
91 * This function computes the number of bytes of storage needed for
92 * the given texture object (all mipmap levels, all cube faces).
93 * The \c image[face][level].x/y/width/height parameters for upload/blitting
94 * are computed here.  \c pp_txfilter, \c pp_txformat, etc. will be set here
95 * too.
96 *
97 * \param rmesa Context pointer
98 * \param tObj GL texture object whose images are to be posted to
99 *                 hardware state.
100 */
101static void r200SetTexImages( r200ContextPtr rmesa,
102			      struct gl_texture_object *tObj )
103{
104   r200TexObjPtr t = (r200TexObjPtr)tObj->DriverData;
105   const struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel];
106   GLint curOffset;
107   GLint i;
108   GLint numLevels;
109   GLint log2Width, log2Height, log2Depth;
110
111   /* Set the hardware texture format
112    */
113
114   t->pp_txformat &= ~(R200_TXFORMAT_FORMAT_MASK |
115		       R200_TXFORMAT_ALPHA_IN_MAP);
116   t->pp_txfilter &= ~R200_YUV_TO_RGB;
117
118   if ( VALID_FORMAT( baseImage->TexFormat->MesaFormat ) ) {
119      t->pp_txformat |= tx_table[ baseImage->TexFormat->MesaFormat ].format;
120      t->pp_txfilter |= tx_table[ baseImage->TexFormat->MesaFormat ].filter;
121   }
122   else {
123      _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__);
124      return;
125   }
126
127
128   /* Compute which mipmap levels we really want to send to the hardware.
129    */
130
131   driCalculateTextureFirstLastLevel( (driTextureObject *) t );
132   log2Width  = tObj->Image[t->base.firstLevel]->WidthLog2;
133   log2Height = tObj->Image[t->base.firstLevel]->HeightLog2;
134   log2Depth  = tObj->Image[t->base.firstLevel]->DepthLog2;
135
136   numLevels = t->base.lastLevel - t->base.firstLevel + 1;
137
138   assert(numLevels <= RADEON_MAX_TEXTURE_LEVELS);
139
140   /* Calculate mipmap offsets and dimensions for blitting (uploading)
141    * The idea is that we lay out the mipmap levels within a block of
142    * memory organized as a rectangle of width BLIT_WIDTH_BYTES.
143    */
144   curOffset = 0;
145
146   for (i = 0; i < numLevels; i++) {
147      const struct gl_texture_image *texImage;
148      GLuint size;
149
150      texImage = tObj->Image[i + t->base.firstLevel];
151      if ( !texImage )
152	 break;
153
154      /* find image size in bytes */
155      if (texImage->IsCompressed) {
156         size = texImage->CompressedSize;
157      }
158      else if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
159         size = ((texImage->Width * texImage->TexFormat->TexelBytes + 63)
160                 & ~63) * texImage->Height;
161      }
162      else {
163         int w = texImage->Width * texImage->TexFormat->TexelBytes;
164         if (w < 32)
165            w = 32;
166         size = w * texImage->Height * texImage->Depth;
167      }
168      assert(size > 0);
169
170
171      /* Align to 32-byte offset.  It is faster to do this unconditionally
172       * (no branch penalty).
173       */
174
175      curOffset = (curOffset + 0x1f) & ~0x1f;
176
177      t->image[0][i].x = curOffset % BLIT_WIDTH_BYTES;
178      t->image[0][i].y = curOffset / BLIT_WIDTH_BYTES;
179      t->image[0][i].width  = MIN2(size, BLIT_WIDTH_BYTES);
180      t->image[0][i].height = size / t->image[0][i].width;
181
182#if 0
183      /* for debugging only and only  applicable to non-rectangle targets */
184      assert(size % t->image[0][i].width == 0);
185      assert(t->image[0][i].x == 0
186             || (size < BLIT_WIDTH_BYTES && t->image[0][i].height == 1));
187#endif
188
189      if (0)
190         fprintf(stderr,
191                 "level %d: %dx%d x=%d y=%d w=%d h=%d size=%d at %d\n",
192                 i, texImage->Width, texImage->Height,
193                 t->image[0][i].x, t->image[0][i].y,
194                 t->image[0][i].width, t->image[0][i].height, size, curOffset);
195
196      curOffset += size;
197
198   }
199
200   /* Align the total size of texture memory block.
201    */
202   t->base.totalSize = (curOffset + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK;
203
204   /* Setup remaining cube face blits, if needed */
205   if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
206      /* Round totalSize up to multiple of BLIT_WIDTH_BYTES */
207      const GLuint faceSize = (t->base.totalSize + BLIT_WIDTH_BYTES - 1)
208                              & ~(BLIT_WIDTH_BYTES-1);
209      const GLuint lines = faceSize / BLIT_WIDTH_BYTES;
210      GLuint face;
211      /* reuse face 0 x/y/width/height - just adjust y */
212      for (face = 1; face < 6; face++) {
213         for (i = 0; i < numLevels; i++) {
214            t->image[face][i].x =  t->image[0][i].x;
215            t->image[face][i].y =  t->image[0][i].y + face * lines;
216            t->image[face][i].width  = t->image[0][i].width;
217            t->image[face][i].height = t->image[0][i].height;
218         }
219      }
220      t->base.totalSize = 6 * faceSize; /* total texmem needed */
221   }
222
223
224   /* Hardware state:
225    */
226   t->pp_txfilter &= ~R200_MAX_MIP_LEVEL_MASK;
227   t->pp_txfilter |= (numLevels - 1) << R200_MAX_MIP_LEVEL_SHIFT;
228
229   t->pp_txformat &= ~(R200_TXFORMAT_WIDTH_MASK |
230		       R200_TXFORMAT_HEIGHT_MASK |
231                       R200_TXFORMAT_CUBIC_MAP_ENABLE |
232                       R200_TXFORMAT_F5_WIDTH_MASK |
233                       R200_TXFORMAT_F5_HEIGHT_MASK);
234   t->pp_txformat |= ((log2Width << R200_TXFORMAT_WIDTH_SHIFT) |
235		      (log2Height << R200_TXFORMAT_HEIGHT_SHIFT));
236
237   t->pp_txformat_x &= ~(R200_DEPTH_LOG2_MASK | R200_TEXCOORD_MASK);
238   if (tObj->Target == GL_TEXTURE_3D) {
239      t->pp_txformat_x |= (log2Depth << R200_DEPTH_LOG2_SHIFT);
240      t->pp_txformat_x |= R200_TEXCOORD_VOLUME;
241   }
242   else if (tObj->Target == GL_TEXTURE_CUBE_MAP) {
243      ASSERT(log2Width == log2height);
244      t->pp_txformat |= ((log2Width << R200_TXFORMAT_F5_WIDTH_SHIFT) |
245                         (log2Height << R200_TXFORMAT_F5_HEIGHT_SHIFT) |
246                         (R200_TXFORMAT_CUBIC_MAP_ENABLE));
247      t->pp_txformat_x |= R200_TEXCOORD_CUBIC_ENV;
248      t->pp_cubic_faces = ((log2Width << R200_FACE_WIDTH_1_SHIFT) |
249                           (log2Height << R200_FACE_HEIGHT_1_SHIFT) |
250                           (log2Width << R200_FACE_WIDTH_2_SHIFT) |
251                           (log2Height << R200_FACE_HEIGHT_2_SHIFT) |
252                           (log2Width << R200_FACE_WIDTH_3_SHIFT) |
253                           (log2Height << R200_FACE_HEIGHT_3_SHIFT) |
254                           (log2Width << R200_FACE_WIDTH_4_SHIFT) |
255                           (log2Height << R200_FACE_HEIGHT_4_SHIFT));
256   }
257
258   t->pp_txsize = (((tObj->Image[t->base.firstLevel]->Width - 1) << 0) |
259                   ((tObj->Image[t->base.firstLevel]->Height - 1) << 16));
260
261   /* Only need to round to nearest 32 for textures, but the blitter
262    * requires 64-byte aligned pitches, and we may/may not need the
263    * blitter.   NPOT only!
264    */
265   if (baseImage->IsCompressed)
266      t->pp_txpitch = (tObj->Image[t->base.firstLevel]->Width + 63) & ~(63);
267   else
268      t->pp_txpitch = ((tObj->Image[t->base.firstLevel]->Width * baseImage->TexFormat->TexelBytes) + 63) & ~(63);
269   t->pp_txpitch -= 32;
270
271   t->dirty_state = TEX_ALL;
272
273   /* FYI: r200UploadTexImages( rmesa, t ) used to be called here */
274}
275
276
277
278/* ================================================================
279 * Texture combine functions
280 */
281
282#define R200_DISABLE		0
283#define R200_REPLACE		1
284#define R200_MODULATE		2
285#define R200_DECAL		3
286#define R200_BLEND		4
287#define R200_ADD		5
288#define R200_MAX_COMBFUNC	6
289
290static GLuint r200_color_combine[][R200_MAX_COMBFUNC] =
291{
292   /* Unit 0:
293    */
294   {
295      /* Disable combiner stage
296       */
297      (R200_TXC_ARG_A_ZERO  |
298       R200_TXC_ARG_B_ZERO |
299       R200_TXC_ARG_C_DIFFUSE_COLOR |
300       R200_TXC_OP_MADD),
301
302      /* GL_REPLACE = 0x00802800
303       */
304      (R200_TXC_ARG_A_ZERO |
305       R200_TXC_ARG_B_ZERO |
306       R200_TXC_ARG_C_R0_COLOR |
307       R200_TXC_OP_MADD),
308
309      /* GL_MODULATE = 0x00800142
310       */
311      (R200_TXC_ARG_A_DIFFUSE_COLOR | /* current starts in DIFFUSE */
312       R200_TXC_ARG_B_R0_COLOR |
313       R200_TXC_ARG_C_ZERO |
314       R200_TXC_OP_MADD),
315
316      /* GL_DECAL = 0x008c2d42
317       */
318      (R200_TXC_ARG_A_DIFFUSE_COLOR |
319       R200_TXC_ARG_B_R0_COLOR |
320       R200_TXC_ARG_C_R0_ALPHA |
321       R200_TXC_OP_LERP),
322
323      /* GL_BLEND = 0x008c2902
324       */
325      (R200_TXC_ARG_A_DIFFUSE_COLOR |
326       R200_TXC_ARG_B_TFACTOR_COLOR |
327       R200_TXC_ARG_C_R0_COLOR |
328       R200_TXC_OP_LERP),
329
330      /* GL_ADD = 0x00812802
331       */
332      (R200_TXC_ARG_A_DIFFUSE_COLOR |
333       R200_TXC_ARG_B_ZERO |
334       R200_TXC_ARG_C_R0_COLOR |
335       R200_TXC_COMP_ARG_B |
336       R200_TXC_OP_MADD),
337   },
338
339   /* Unit 1:
340    */
341   {
342      /* Disable combiner stage
343       */
344      (R200_TXC_ARG_A_ZERO |
345       R200_TXC_ARG_B_ZERO |
346       R200_TXC_ARG_C_R0_COLOR |
347       R200_TXC_OP_MADD),
348
349      /* GL_REPLACE = 0x00803000
350       */
351      (R200_TXC_ARG_A_ZERO |
352       R200_TXC_ARG_B_ZERO |
353       R200_TXC_ARG_C_R1_COLOR |
354       R200_TXC_OP_MADD),
355
356      /* GL_MODULATE = 0x00800182
357       */
358      (R200_TXC_ARG_A_R0_COLOR | /* current in R0 thereafter */
359       R200_TXC_ARG_B_R1_COLOR |
360       R200_TXC_ARG_C_ZERO |
361       R200_TXC_OP_MADD),
362
363      /* GL_DECAL = 0x008c3582
364       */
365      (R200_TXC_ARG_A_R0_COLOR |
366       R200_TXC_ARG_B_R1_COLOR |
367       R200_TXC_ARG_C_R1_ALPHA |
368       R200_TXC_OP_LERP),
369
370      /* GL_BLEND = 0x008c3102
371       */
372      (R200_TXC_ARG_A_R0_COLOR |
373       R200_TXC_ARG_B_TFACTOR_COLOR |
374       R200_TXC_ARG_C_R1_COLOR |
375       R200_TXC_OP_LERP),
376
377      /* GL_ADD = 0x00813002
378       */
379      (R200_TXC_ARG_A_R0_COLOR |
380       R200_TXC_ARG_B_ZERO |
381       R200_TXC_ARG_C_R1_COLOR |
382       R200_TXC_COMP_ARG_B |
383       R200_TXC_OP_MADD),
384   },
385
386   /* Unit 2:
387    */
388   {
389      /* Disable combiner stage
390       */
391      (R200_TXC_ARG_A_ZERO |
392       R200_TXC_ARG_B_ZERO |
393       R200_TXC_ARG_C_R0_COLOR |
394       R200_TXC_OP_MADD),
395
396      /* GL_REPLACE = 0x00803800
397       */
398      (R200_TXC_ARG_A_ZERO |
399       R200_TXC_ARG_B_ZERO |
400       R200_TXC_ARG_C_R2_COLOR |
401       R200_TXC_OP_MADD),
402
403      /* GL_MODULATE = 0x008001c2
404       */
405      (R200_TXC_ARG_A_R0_COLOR |
406       R200_TXC_ARG_B_R2_COLOR |
407       R200_TXC_ARG_C_ZERO |
408       R200_TXC_OP_MADD),
409
410      /* GL_DECAL = 0x008c3dc2
411       */
412      (R200_TXC_ARG_A_R0_COLOR |
413       R200_TXC_ARG_B_R2_COLOR |
414       R200_TXC_ARG_C_R2_ALPHA |
415       R200_TXC_OP_LERP),
416
417      /* GL_BLEND = 0x008c3902
418       */
419      (R200_TXC_ARG_A_R0_COLOR |
420       R200_TXC_ARG_B_TFACTOR_COLOR |
421       R200_TXC_ARG_C_R2_COLOR |
422       R200_TXC_OP_LERP),
423
424      /* GL_ADD = 0x00813802
425       */
426      (R200_TXC_ARG_A_R0_COLOR |
427       R200_TXC_ARG_B_ZERO |
428       R200_TXC_ARG_C_R2_COLOR |
429       R200_TXC_COMP_ARG_B |
430       R200_TXC_OP_MADD),
431   }
432};
433
434static GLuint r200_alpha_combine[][R200_MAX_COMBFUNC] =
435{
436   /* Unit 0:
437    */
438   {
439      /* Disable combiner stage
440       */
441      (R200_TXA_ARG_A_ZERO |
442       R200_TXA_ARG_B_ZERO |
443       R200_TXA_ARG_C_DIFFUSE_ALPHA |
444       R200_TXA_OP_MADD),
445
446
447      /* GL_REPLACE = 0x00800500
448       */
449      (R200_TXA_ARG_A_ZERO |
450       R200_TXA_ARG_B_ZERO |
451       R200_TXA_ARG_C_R0_ALPHA |
452       R200_TXA_OP_MADD),
453
454      /* GL_MODULATE = 0x00800051
455       */
456      (R200_TXA_ARG_A_DIFFUSE_ALPHA |
457       R200_TXA_ARG_B_R0_ALPHA |
458       R200_TXA_ARG_C_ZERO |
459       R200_TXA_OP_MADD),
460
461      /* GL_DECAL = 0x00800100
462       */
463      (R200_TXA_ARG_A_ZERO |
464       R200_TXA_ARG_B_ZERO |
465       R200_TXA_ARG_C_DIFFUSE_ALPHA |
466       R200_TXA_OP_MADD),
467
468      /* GL_BLEND = 0x00800051
469       */
470      (R200_TXA_ARG_A_DIFFUSE_ALPHA |
471       R200_TXA_ARG_B_TFACTOR_ALPHA |
472       R200_TXA_ARG_C_R0_ALPHA |
473       R200_TXA_OP_LERP),
474
475      /* GL_ADD = 0x00800051
476       */
477      (R200_TXA_ARG_A_DIFFUSE_ALPHA |
478       R200_TXA_ARG_B_ZERO |
479       R200_TXA_ARG_C_R0_ALPHA |
480       R200_TXA_COMP_ARG_B |
481       R200_TXA_OP_MADD),
482   },
483
484   /* Unit 1:
485    */
486   {
487      /* Disable combiner stage
488       */
489      (R200_TXA_ARG_A_ZERO |
490       R200_TXA_ARG_B_ZERO |
491       R200_TXA_ARG_C_R0_ALPHA |
492       R200_TXA_OP_MADD),
493
494      /* GL_REPLACE = 0x00800600
495       */
496      (R200_TXA_ARG_A_ZERO |
497       R200_TXA_ARG_B_ZERO |
498       R200_TXA_ARG_C_R1_ALPHA |
499       R200_TXA_OP_MADD),
500
501      /* GL_MODULATE = 0x00800061
502       */
503      (R200_TXA_ARG_A_R0_ALPHA |
504       R200_TXA_ARG_B_R1_ALPHA |
505       R200_TXA_ARG_C_ZERO |
506       R200_TXA_OP_MADD),
507
508      /* GL_DECAL = 0x00800100
509       */
510      (R200_TXA_ARG_A_ZERO |
511       R200_TXA_ARG_B_ZERO |
512       R200_TXA_ARG_C_R0_ALPHA |
513       R200_TXA_OP_MADD),
514
515      /* GL_BLEND = 0x00800061
516       */
517      (R200_TXA_ARG_A_R0_ALPHA |
518       R200_TXA_ARG_B_TFACTOR_ALPHA |
519       R200_TXA_ARG_C_R1_ALPHA |
520       R200_TXA_OP_LERP),
521
522      /* GL_ADD = 0x00800061
523       */
524      (R200_TXA_ARG_A_R0_ALPHA |
525       R200_TXA_ARG_B_ZERO |
526       R200_TXA_ARG_C_R1_ALPHA |
527       R200_TXA_COMP_ARG_B |
528       R200_TXA_OP_MADD),
529   },
530
531   /* Unit 2:
532    */
533   {
534      /* Disable combiner stage
535       */
536      (R200_TXA_ARG_A_ZERO |
537       R200_TXA_ARG_B_ZERO |
538       R200_TXA_ARG_C_R0_ALPHA |
539       R200_TXA_OP_MADD),
540
541      /* GL_REPLACE = 0x00800700
542       */
543      (R200_TXA_ARG_A_ZERO |
544       R200_TXA_ARG_B_ZERO |
545       R200_TXA_ARG_C_R2_ALPHA |
546       R200_TXA_OP_MADD),
547
548      /* GL_MODULATE = 0x00800071
549       */
550      (R200_TXA_ARG_A_R0_ALPHA |
551       R200_TXA_ARG_B_R2_ALPHA |
552       R200_TXA_ARG_C_ZERO |
553       R200_TXA_OP_MADD),
554
555      /* GL_DECAL = 0x00800100
556       */
557      (R200_TXA_ARG_A_ZERO |
558       R200_TXA_ARG_B_ZERO |
559       R200_TXA_ARG_C_R0_ALPHA |
560       R200_TXA_OP_MADD),
561
562      /* GL_BLEND = 0x00800071
563       */
564      (R200_TXA_ARG_A_R0_ALPHA |
565       R200_TXA_ARG_B_TFACTOR_ALPHA |
566       R200_TXA_ARG_C_R2_ALPHA |
567       R200_TXA_OP_LERP),
568
569      /* GL_ADD = 0x00800021
570       */
571      (R200_TXA_ARG_A_R0_ALPHA |
572       R200_TXA_ARG_B_ZERO |
573       R200_TXA_ARG_C_R2_ALPHA |
574       R200_TXA_COMP_ARG_B |
575       R200_TXA_OP_MADD),
576   }
577};
578
579
580/* GL_ARB_texture_env_combine support
581 */
582
583/* The color tables have combine functions for GL_SRC_COLOR,
584 * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
585 */
586static GLuint r200_register_color[][R200_MAX_TEXTURE_UNITS] =
587{
588   {
589      R200_TXC_ARG_A_R0_COLOR,
590      R200_TXC_ARG_A_R1_COLOR,
591      R200_TXC_ARG_A_R2_COLOR
592   },
593   {
594      R200_TXC_ARG_A_R0_COLOR | R200_TXC_COMP_ARG_A,
595      R200_TXC_ARG_A_R1_COLOR | R200_TXC_COMP_ARG_A,
596      R200_TXC_ARG_A_R2_COLOR | R200_TXC_COMP_ARG_A
597   },
598   {
599      R200_TXC_ARG_A_R0_ALPHA,
600      R200_TXC_ARG_A_R1_ALPHA,
601      R200_TXC_ARG_A_R2_ALPHA
602   },
603   {
604      R200_TXC_ARG_A_R0_ALPHA | R200_TXC_COMP_ARG_A,
605      R200_TXC_ARG_A_R1_ALPHA | R200_TXC_COMP_ARG_A,
606      R200_TXC_ARG_A_R2_ALPHA | R200_TXC_COMP_ARG_A
607   },
608};
609
610static GLuint r200_tfactor_color[] =
611{
612   R200_TXC_ARG_A_TFACTOR_COLOR,
613   R200_TXC_ARG_A_TFACTOR_COLOR | R200_TXC_COMP_ARG_A,
614   R200_TXC_ARG_A_TFACTOR_ALPHA,
615   R200_TXC_ARG_A_TFACTOR_ALPHA | R200_TXC_COMP_ARG_A
616};
617
618static GLuint r200_primary_color[] =
619{
620   R200_TXC_ARG_A_DIFFUSE_COLOR,
621   R200_TXC_ARG_A_DIFFUSE_COLOR | R200_TXC_COMP_ARG_A,
622   R200_TXC_ARG_A_DIFFUSE_ALPHA,
623   R200_TXC_ARG_A_DIFFUSE_ALPHA | R200_TXC_COMP_ARG_A
624};
625
626/* GL_ZERO table - indices 0-3
627 * GL_ONE  table - indices 1-4
628 */
629static GLuint r200_zero_color[] =
630{
631   R200_TXC_ARG_A_ZERO,
632   R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A,
633   R200_TXC_ARG_A_ZERO,
634   R200_TXC_ARG_A_ZERO | R200_TXC_COMP_ARG_A,
635   R200_TXC_ARG_A_ZERO
636};
637
638/* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA.
639 */
640static GLuint r200_register_alpha[][R200_MAX_TEXTURE_UNITS] =
641{
642   {
643      R200_TXA_ARG_A_R0_ALPHA,
644      R200_TXA_ARG_A_R1_ALPHA,
645      R200_TXA_ARG_A_R2_ALPHA
646   },
647   {
648      R200_TXA_ARG_A_R0_ALPHA | R200_TXA_COMP_ARG_A,
649      R200_TXA_ARG_A_R1_ALPHA | R200_TXA_COMP_ARG_A,
650      R200_TXA_ARG_A_R2_ALPHA | R200_TXA_COMP_ARG_A
651   },
652};
653
654static GLuint r200_tfactor_alpha[] =
655{
656   R200_TXA_ARG_A_TFACTOR_ALPHA,
657   R200_TXA_ARG_A_TFACTOR_ALPHA | R200_TXA_COMP_ARG_A
658};
659
660static GLuint r200_primary_alpha[] =
661{
662   R200_TXA_ARG_A_DIFFUSE_ALPHA,
663   R200_TXA_ARG_A_DIFFUSE_ALPHA | R200_TXA_COMP_ARG_A
664};
665
666/* GL_ZERO table - indices 0-1
667 * GL_ONE  table - indices 1-2
668 */
669static GLuint r200_zero_alpha[] =
670{
671   R200_TXA_ARG_A_ZERO,
672   R200_TXA_ARG_A_ZERO | R200_TXA_COMP_ARG_A,
673   R200_TXA_ARG_A_ZERO,
674};
675
676
677/* Extract the arg from slot A, shift it into the correct argument slot
678 * and set the corresponding complement bit.
679 */
680#define R200_COLOR_ARG( n, arg )			\
681do {							\
682   color_combine |=					\
683      ((color_arg[n] & R200_TXC_ARG_A_MASK)		\
684       << R200_TXC_ARG_##arg##_SHIFT);			\
685   color_combine |=					\
686      ((color_arg[n] >> R200_TXC_COMP_ARG_A_SHIFT)	\
687       << R200_TXC_COMP_ARG_##arg##_SHIFT);		\
688} while (0)
689
690#define R200_ALPHA_ARG( n, arg )			\
691do {							\
692   alpha_combine |=					\
693      ((alpha_arg[n] & R200_TXA_ARG_A_MASK)		\
694       << R200_TXA_ARG_##arg##_SHIFT);			\
695   alpha_combine |=					\
696      ((alpha_arg[n] >> R200_TXA_COMP_ARG_A_SHIFT)	\
697       << R200_TXA_COMP_ARG_##arg##_SHIFT);		\
698} while (0)
699
700
701/* ================================================================
702 * Texture unit state management
703 */
704
705static GLboolean r200UpdateTextureEnv( GLcontext *ctx, int unit )
706{
707   r200ContextPtr rmesa = R200_CONTEXT(ctx);
708   const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
709   GLuint color_combine, alpha_combine;
710   GLuint color_scale = rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2];
711   GLuint alpha_scale = rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2];
712
713   /* texUnit->_Current can be NULL if and only if the texture unit is
714    * not actually enabled.
715    */
716   assert( (texUnit->_ReallyEnabled == 0)
717	   || (texUnit->_Current != NULL) );
718
719   if ( R200_DEBUG & DEBUG_TEXTURE ) {
720      fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, ctx, unit );
721   }
722
723   /* Set the texture environment state.  Isn't this nice and clean?
724    * The chip will automagically set the texture alpha to 0xff when
725    * the texture format does not include an alpha component.  This
726    * reduces the amount of special-casing we have to do, alpha-only
727    * textures being a notable exception.
728    */
729   if ( !texUnit->_ReallyEnabled ) {
730      /* Don't cache these results.
731       */
732      rmesa->state.texture.unit[unit].format = 0;
733      rmesa->state.texture.unit[unit].envMode = 0;
734      color_combine = r200_color_combine[unit][R200_DISABLE];
735      alpha_combine = r200_alpha_combine[unit][R200_DISABLE];
736   }
737   else {
738      const struct gl_texture_object *tObj = texUnit->_Current;
739      const GLenum format = tObj->Image[tObj->BaseLevel]->Format;
740      GLuint color_arg[3], alpha_arg[3];
741      GLuint i, numColorArgs = 0, numAlphaArgs = 0;
742      GLuint RGBshift = texUnit->CombineScaleShiftRGB;
743      GLuint Ashift = texUnit->CombineScaleShiftA;
744
745      switch ( texUnit->EnvMode ) {
746      case GL_REPLACE:
747	 switch ( format ) {
748	 case GL_RGBA:
749	 case GL_LUMINANCE_ALPHA:
750	 case GL_INTENSITY:
751	    color_combine = r200_color_combine[unit][R200_REPLACE];
752	    alpha_combine = r200_alpha_combine[unit][R200_REPLACE];
753	    break;
754	 case GL_ALPHA:
755	    color_combine = r200_color_combine[unit][R200_DISABLE];
756	    alpha_combine = r200_alpha_combine[unit][R200_REPLACE];
757	    break;
758	 case GL_LUMINANCE:
759	 case GL_RGB:
760	 case GL_YCBCR_MESA:
761	    color_combine = r200_color_combine[unit][R200_REPLACE];
762	    alpha_combine = r200_alpha_combine[unit][R200_DISABLE];
763	    break;
764	 case GL_COLOR_INDEX:
765	 default:
766	    return GL_FALSE;
767	 }
768	 break;
769
770      case GL_MODULATE:
771	 switch ( format ) {
772	 case GL_RGBA:
773	 case GL_LUMINANCE_ALPHA:
774	 case GL_INTENSITY:
775	    color_combine = r200_color_combine[unit][R200_MODULATE];
776	    alpha_combine = r200_alpha_combine[unit][R200_MODULATE];
777	    break;
778	 case GL_ALPHA:
779	    color_combine = r200_color_combine[unit][R200_DISABLE];
780	    alpha_combine = r200_alpha_combine[unit][R200_MODULATE];
781	    break;
782	 case GL_RGB:
783	 case GL_LUMINANCE:
784	 case GL_YCBCR_MESA:
785	    color_combine = r200_color_combine[unit][R200_MODULATE];
786	    alpha_combine = r200_alpha_combine[unit][R200_DISABLE];
787	    break;
788	 case GL_COLOR_INDEX:
789	 default:
790	    return GL_FALSE;
791	 }
792	 break;
793
794      case GL_DECAL:
795	 switch ( format ) {
796	 case GL_RGBA:
797	 case GL_RGB:
798	 case GL_YCBCR_MESA:
799	    color_combine = r200_color_combine[unit][R200_DECAL];
800	    alpha_combine = r200_alpha_combine[unit][R200_DISABLE];
801	    break;
802	 case GL_ALPHA:
803	 case GL_LUMINANCE:
804	 case GL_LUMINANCE_ALPHA:
805	 case GL_INTENSITY:
806	    color_combine = r200_color_combine[unit][R200_DISABLE];
807	    alpha_combine = r200_alpha_combine[unit][R200_DISABLE];
808	    break;
809	 case GL_COLOR_INDEX:
810	 default:
811	    return GL_FALSE;
812	 }
813	 break;
814
815      case GL_BLEND:
816	 switch ( format ) {
817	 case GL_RGBA:
818	 case GL_RGB:
819	 case GL_LUMINANCE:
820	 case GL_LUMINANCE_ALPHA:
821	 case GL_YCBCR_MESA:
822	    color_combine = r200_color_combine[unit][R200_BLEND];
823	    alpha_combine = r200_alpha_combine[unit][R200_MODULATE];
824	    break;
825	 case GL_ALPHA:
826	    color_combine = r200_color_combine[unit][R200_DISABLE];
827	    alpha_combine = r200_alpha_combine[unit][R200_MODULATE];
828	    break;
829	 case GL_INTENSITY:
830	    color_combine = r200_color_combine[unit][R200_BLEND];
831	    alpha_combine = r200_alpha_combine[unit][R200_BLEND];
832	    break;
833	 case GL_COLOR_INDEX:
834	 default:
835	    return GL_FALSE;
836	 }
837	 break;
838
839      case GL_ADD:
840	 switch ( format ) {
841	 case GL_RGBA:
842	 case GL_RGB:
843	 case GL_LUMINANCE:
844	 case GL_LUMINANCE_ALPHA:
845	 case GL_YCBCR_MESA:
846	    color_combine = r200_color_combine[unit][R200_ADD];
847	    alpha_combine = r200_alpha_combine[unit][R200_MODULATE];
848	    break;
849	 case GL_ALPHA:
850	    color_combine = r200_color_combine[unit][R200_DISABLE];
851	    alpha_combine = r200_alpha_combine[unit][R200_MODULATE];
852	    break;
853	 case GL_INTENSITY:
854	    color_combine = r200_color_combine[unit][R200_ADD];
855	    alpha_combine = r200_alpha_combine[unit][R200_ADD];
856	    break;
857	 case GL_COLOR_INDEX:
858	 default:
859	    return GL_FALSE;
860	 }
861	 break;
862
863      case GL_COMBINE:
864	 /* Don't cache these results.
865	  */
866	 rmesa->state.texture.unit[unit].format = 0;
867	 rmesa->state.texture.unit[unit].envMode = 0;
868
869	 /* Step 0:
870	  * Calculate how many arguments we need to process.
871	  */
872	 switch ( texUnit->CombineModeRGB ) {
873	 case GL_REPLACE:
874	    numColorArgs = 1;
875	    break;
876	 case GL_MODULATE:
877	 case GL_ADD:
878	 case GL_ADD_SIGNED:
879	 case GL_SUBTRACT:
880	 case GL_DOT3_RGB:
881	 case GL_DOT3_RGBA:
882	 case GL_DOT3_RGB_EXT:
883	 case GL_DOT3_RGBA_EXT:
884	    numColorArgs = 2;
885	    break;
886	 case GL_INTERPOLATE:
887	 case GL_MODULATE_ADD_ATI:
888	 case GL_MODULATE_SIGNED_ADD_ATI:
889	 case GL_MODULATE_SUBTRACT_ATI:
890	    numColorArgs = 3;
891	    break;
892	 default:
893	    return GL_FALSE;
894	 }
895
896	 switch ( texUnit->CombineModeA ) {
897	 case GL_REPLACE:
898	    numAlphaArgs = 1;
899	    break;
900	 case GL_MODULATE:
901	 case GL_ADD:
902	 case GL_ADD_SIGNED:
903	 case GL_SUBTRACT:
904	    numAlphaArgs = 2;
905	    break;
906	 case GL_INTERPOLATE:
907	 case GL_MODULATE_ADD_ATI:
908	 case GL_MODULATE_SIGNED_ADD_ATI:
909	 case GL_MODULATE_SUBTRACT_ATI:
910	    numAlphaArgs = 3;
911	    break;
912	 default:
913	    return GL_FALSE;
914	 }
915
916	 /* Step 1:
917	  * Extract the color and alpha combine function arguments.
918	  */
919	 for ( i = 0 ; i < numColorArgs ; i++ ) {
920	    const GLuint op = texUnit->CombineOperandRGB[i] - GL_SRC_COLOR;
921	    assert(op >= 0);
922	    assert(op <= 3);
923	    switch ( texUnit->CombineSourceRGB[i] ) {
924	    case GL_TEXTURE:
925	       color_arg[i] = r200_register_color[op][unit];
926	       break;
927	    case GL_CONSTANT:
928	       color_arg[i] = r200_tfactor_color[op];
929	       break;
930	    case GL_PRIMARY_COLOR:
931	       color_arg[i] = r200_primary_color[op];
932	       break;
933	    case GL_PREVIOUS:
934	       if (unit == 0)
935		  color_arg[i] = r200_primary_color[op];
936	       else
937		  color_arg[i] = r200_register_color[op][0];
938	       break;
939	    case GL_ZERO:
940	       color_arg[i] = r200_zero_color[op];
941	       break;
942	    case GL_ONE:
943	       color_arg[i] = r200_zero_color[op+1];
944	       break;
945	    default:
946	       return GL_FALSE;
947	    }
948	 }
949
950	 for ( i = 0 ; i < numAlphaArgs ; i++ ) {
951	    const GLuint op = texUnit->CombineOperandA[i] - GL_SRC_ALPHA;
952	    assert(op >= 0);
953	    assert(op <= 1);
954	    switch ( texUnit->CombineSourceA[i] ) {
955	    case GL_TEXTURE:
956	       alpha_arg[i] = r200_register_alpha[op][unit];
957	       break;
958	    case GL_CONSTANT:
959	       alpha_arg[i] = r200_tfactor_alpha[op];
960	       break;
961	    case GL_PRIMARY_COLOR:
962	       alpha_arg[i] = r200_primary_alpha[op];
963	       break;
964	    case GL_PREVIOUS:
965	       if (unit == 0)
966		  alpha_arg[i] = r200_primary_alpha[op];
967	       else
968		  alpha_arg[i] = r200_register_alpha[op][0];
969	       break;
970	    case GL_ZERO:
971	       alpha_arg[i] = r200_zero_alpha[op];
972	       break;
973	    case GL_ONE:
974	       alpha_arg[i] = r200_zero_alpha[op+1];
975	       break;
976	    default:
977	       return GL_FALSE;
978	    }
979	 }
980
981	 /* Step 2:
982	  * Build up the color and alpha combine functions.
983	  */
984	 switch ( texUnit->CombineModeRGB ) {
985	 case GL_REPLACE:
986	    color_combine = (R200_TXC_ARG_A_ZERO |
987			     R200_TXC_ARG_B_ZERO |
988			     R200_TXC_OP_MADD);
989	    R200_COLOR_ARG( 0, C );
990	    break;
991	 case GL_MODULATE:
992	    color_combine = (R200_TXC_ARG_C_ZERO |
993			     R200_TXC_OP_MADD);
994	    R200_COLOR_ARG( 0, A );
995	    R200_COLOR_ARG( 1, B );
996	    break;
997	 case GL_ADD:
998	    color_combine = (R200_TXC_ARG_B_ZERO |
999			     R200_TXC_COMP_ARG_B |
1000			     R200_TXC_OP_MADD);
1001	    R200_COLOR_ARG( 0, A );
1002	    R200_COLOR_ARG( 1, C );
1003	    break;
1004	 case GL_ADD_SIGNED:
1005	    color_combine = (R200_TXC_ARG_B_ZERO |
1006			     R200_TXC_COMP_ARG_B |
1007			     R200_TXC_BIAS_ARG_C |	/* new */
1008			     R200_TXC_OP_MADD); /* was ADDSIGNED */
1009	    R200_COLOR_ARG( 0, A );
1010	    R200_COLOR_ARG( 1, C );
1011	    break;
1012	 case GL_SUBTRACT:
1013	    color_combine = (R200_TXC_ARG_B_ZERO |
1014			     R200_TXC_COMP_ARG_B |
1015			     R200_TXC_NEG_ARG_C |
1016			     R200_TXC_OP_MADD);
1017	    R200_COLOR_ARG( 0, A );
1018	    R200_COLOR_ARG( 1, C );
1019	    break;
1020	 case GL_INTERPOLATE:
1021	    color_combine = (R200_TXC_OP_LERP);
1022	    R200_COLOR_ARG( 0, B );
1023	    R200_COLOR_ARG( 1, A );
1024	    R200_COLOR_ARG( 2, C );
1025	    break;
1026
1027	 case GL_DOT3_RGB_EXT:
1028	 case GL_DOT3_RGBA_EXT:
1029	    /* The EXT version of the DOT3 extension does not support the
1030	     * scale factor, but the ARB version (and the version in OpenGL
1031	     * 1.3) does.
1032	     */
1033	    RGBshift = 0;
1034	    Ashift = 0;
1035	    /* FALLTHROUGH */
1036
1037	 case GL_DOT3_RGB:
1038	 case GL_DOT3_RGBA:
1039	    /* DOT3 works differently on R200 than on R100.  On R100, just
1040	     * setting the DOT3 mode did everything for you.  On R200, the
1041	     * driver has to enable the biasing (the -0.5 in the combine
1042	     * equation), and it has add the 4x scale factor.  The hardware
1043	     * only supports up to 8x in the post filter, so 2x part of it
1044	     * happens on the inputs going into the combiner.
1045	     */
1046
1047	    RGBshift++;
1048	    Ashift = RGBshift;
1049
1050	    color_combine = (R200_TXC_ARG_C_ZERO |
1051			     R200_TXC_OP_DOT3 |
1052			     R200_TXC_BIAS_ARG_A |
1053			     R200_TXC_BIAS_ARG_B |
1054			     R200_TXC_SCALE_ARG_A |
1055			     R200_TXC_SCALE_ARG_B);
1056	    R200_COLOR_ARG( 0, A );
1057	    R200_COLOR_ARG( 1, B );
1058	    break;
1059
1060	 case GL_MODULATE_ADD_ATI:
1061	    color_combine = (R200_TXC_OP_MADD);
1062	    R200_COLOR_ARG( 0, A );
1063	    R200_COLOR_ARG( 1, C );
1064	    R200_COLOR_ARG( 2, B );
1065	    break;
1066	 case GL_MODULATE_SIGNED_ADD_ATI:
1067	    color_combine = (R200_TXC_BIAS_ARG_C |	/* new */
1068			     R200_TXC_OP_MADD); /* was ADDSIGNED */
1069	    R200_COLOR_ARG( 0, A );
1070	    R200_COLOR_ARG( 1, C );
1071	    R200_COLOR_ARG( 2, B );
1072	    break;
1073	 case GL_MODULATE_SUBTRACT_ATI:
1074	    color_combine = (R200_TXC_NEG_ARG_C |
1075			     R200_TXC_OP_MADD);
1076	    R200_COLOR_ARG( 0, A );
1077	    R200_COLOR_ARG( 1, C );
1078	    R200_COLOR_ARG( 2, B );
1079	    break;
1080	 default:
1081	    return GL_FALSE;
1082	 }
1083
1084	 switch ( texUnit->CombineModeA ) {
1085	 case GL_REPLACE:
1086	    alpha_combine = (R200_TXA_ARG_A_ZERO |
1087			     R200_TXA_ARG_B_ZERO |
1088			     R200_TXA_OP_MADD);
1089	    R200_ALPHA_ARG( 0, C );
1090	    break;
1091	 case GL_MODULATE:
1092	    alpha_combine = (R200_TXA_ARG_C_ZERO |
1093			     R200_TXA_OP_MADD);
1094	    R200_ALPHA_ARG( 0, A );
1095	    R200_ALPHA_ARG( 1, B );
1096	    break;
1097	 case GL_ADD:
1098	    alpha_combine = (R200_TXA_ARG_B_ZERO |
1099			     R200_TXA_COMP_ARG_B |
1100			     R200_TXA_OP_MADD);
1101	    R200_ALPHA_ARG( 0, A );
1102	    R200_ALPHA_ARG( 1, C );
1103	    break;
1104	 case GL_ADD_SIGNED:
1105	    alpha_combine = (R200_TXA_ARG_B_ZERO |
1106			     R200_TXA_COMP_ARG_B |
1107			     R200_TXA_BIAS_ARG_C |	/* new */
1108			     R200_TXA_OP_MADD); /* was ADDSIGNED */
1109	    R200_ALPHA_ARG( 0, A );
1110	    R200_ALPHA_ARG( 1, C );
1111	    break;
1112	 case GL_SUBTRACT:
1113	    alpha_combine = (R200_TXA_ARG_B_ZERO |
1114			     R200_TXA_COMP_ARG_B |
1115			     R200_TXA_NEG_ARG_C |
1116			     R200_TXA_OP_MADD);
1117	    R200_ALPHA_ARG( 0, A );
1118	    R200_ALPHA_ARG( 1, C );
1119	    break;
1120	 case GL_INTERPOLATE:
1121	    alpha_combine = (R200_TXA_OP_LERP);
1122	    R200_ALPHA_ARG( 0, B );
1123	    R200_ALPHA_ARG( 1, A );
1124	    R200_ALPHA_ARG( 2, C );
1125	    break;
1126
1127	 case GL_MODULATE_ADD_ATI:
1128	    alpha_combine = (R200_TXA_OP_MADD);
1129	    R200_ALPHA_ARG( 0, A );
1130	    R200_ALPHA_ARG( 1, C );
1131	    R200_ALPHA_ARG( 2, B );
1132	    break;
1133	 case GL_MODULATE_SIGNED_ADD_ATI:
1134	    alpha_combine = (R200_TXA_BIAS_ARG_C |	/* new */
1135			     R200_TXA_OP_MADD); /* was ADDSIGNED */
1136	    R200_ALPHA_ARG( 0, A );
1137	    R200_ALPHA_ARG( 1, C );
1138	    R200_ALPHA_ARG( 2, B );
1139	    break;
1140	 case GL_MODULATE_SUBTRACT_ATI:
1141	    alpha_combine = (R200_TXA_NEG_ARG_C |
1142			     R200_TXA_OP_MADD);
1143	    R200_ALPHA_ARG( 0, A );
1144	    R200_ALPHA_ARG( 1, C );
1145	    R200_ALPHA_ARG( 2, B );
1146	    break;
1147	 default:
1148	    return GL_FALSE;
1149	 }
1150
1151	 if ( (texUnit->CombineModeRGB == GL_DOT3_RGB_EXT)
1152	      || (texUnit->CombineModeRGB == GL_DOT3_RGB) ) {
1153	    alpha_scale |= R200_TXA_DOT_ALPHA;
1154	 }
1155
1156	 /* Step 3:
1157	  * Apply the scale factor.
1158	  */
1159	 color_scale &= ~R200_TXC_SCALE_MASK;
1160	 alpha_scale &= ~R200_TXA_SCALE_MASK;
1161	 color_scale |= (RGBshift << R200_TXC_SCALE_SHIFT);
1162	 alpha_scale |= (Ashift   << R200_TXA_SCALE_SHIFT);
1163
1164	 /* All done!
1165	  */
1166	 break;
1167
1168      default:
1169	 return GL_FALSE;
1170      }
1171   }
1172
1173   if ( rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND] != color_combine ||
1174	rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND] != alpha_combine ||
1175	rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2] != color_scale ||
1176	rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2] != alpha_scale) {
1177      R200_STATECHANGE( rmesa, pix[unit] );
1178      rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND] = color_combine;
1179      rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND] = alpha_combine;
1180      rmesa->hw.pix[unit].cmd[PIX_PP_TXCBLEND2] = color_scale;
1181      rmesa->hw.pix[unit].cmd[PIX_PP_TXABLEND2] = alpha_scale;
1182   }
1183
1184   return GL_TRUE;
1185}
1186
1187#define TEXOBJ_TXFILTER_MASK (R200_MAX_MIP_LEVEL_MASK |		\
1188			      R200_MIN_FILTER_MASK | 		\
1189			      R200_MAG_FILTER_MASK |		\
1190			      R200_MAX_ANISO_MASK |		\
1191			      R200_YUV_TO_RGB |			\
1192			      R200_YUV_TEMPERATURE_MASK |	\
1193			      R200_CLAMP_S_MASK | 		\
1194			      R200_CLAMP_T_MASK | 		\
1195			      R200_BORDER_MODE_D3D )
1196
1197#define TEXOBJ_TXFORMAT_MASK (R200_TXFORMAT_WIDTH_MASK |	\
1198			      R200_TXFORMAT_HEIGHT_MASK |	\
1199			      R200_TXFORMAT_FORMAT_MASK |	\
1200                              R200_TXFORMAT_F5_WIDTH_MASK |	\
1201                              R200_TXFORMAT_F5_HEIGHT_MASK |	\
1202			      R200_TXFORMAT_ALPHA_IN_MAP |	\
1203			      R200_TXFORMAT_CUBIC_MAP_ENABLE |	\
1204                              R200_TXFORMAT_NON_POWER2)
1205
1206#define TEXOBJ_TXFORMAT_X_MASK (R200_DEPTH_LOG2_MASK |		\
1207                                R200_TEXCOORD_MASK |		\
1208                                R200_VOLUME_FILTER_MASK)
1209
1210
1211static void import_tex_obj_state( r200ContextPtr rmesa,
1212				  int unit,
1213				  r200TexObjPtr texobj )
1214{
1215   GLuint *cmd = R200_DB_STATE( tex[unit] );
1216
1217   cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK;
1218   cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK;
1219   cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1220   cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK;
1221   cmd[TEX_PP_TXFORMAT_X] &= ~TEXOBJ_TXFORMAT_X_MASK;
1222   cmd[TEX_PP_TXFORMAT_X] |= texobj->pp_txformat_x & TEXOBJ_TXFORMAT_X_MASK;
1223   cmd[TEX_PP_TXSIZE] = texobj->pp_txsize; /* NPOT only! */
1224   cmd[TEX_PP_TXPITCH] = texobj->pp_txpitch; /* NPOT only! */
1225   cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset;
1226   cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
1227   R200_DB_STATECHANGE( rmesa, &rmesa->hw.tex[unit] );
1228
1229   if (texobj->base.tObj->Target == GL_TEXTURE_CUBE_MAP) {
1230      GLuint *cube_cmd = R200_DB_STATE( cube[unit] );
1231      GLuint bytesPerFace = texobj->base.totalSize / 6;
1232      ASSERT(texobj->totalSize % 6 == 0);
1233      cube_cmd[CUBE_PP_CUBIC_FACES] = texobj->pp_cubic_faces;
1234      cube_cmd[CUBE_PP_CUBIC_OFFSET_F1] = texobj->pp_txoffset + 1 * bytesPerFace;
1235      cube_cmd[CUBE_PP_CUBIC_OFFSET_F2] = texobj->pp_txoffset + 2 * bytesPerFace;
1236      cube_cmd[CUBE_PP_CUBIC_OFFSET_F3] = texobj->pp_txoffset + 3 * bytesPerFace;
1237      cube_cmd[CUBE_PP_CUBIC_OFFSET_F4] = texobj->pp_txoffset + 4 * bytesPerFace;
1238      cube_cmd[CUBE_PP_CUBIC_OFFSET_F5] = texobj->pp_txoffset + 5 * bytesPerFace;
1239      R200_DB_STATECHANGE( rmesa, &rmesa->hw.cube[unit] );
1240   }
1241
1242   texobj->dirty_state &= ~(1<<unit);
1243}
1244
1245
1246
1247
1248static void set_texgen_matrix( r200ContextPtr rmesa,
1249			       GLuint unit,
1250			       const GLfloat *s_plane,
1251			       const GLfloat *t_plane,
1252			       const GLfloat *r_plane )
1253{
1254   static const GLfloat scale_identity[4] = { 1,1,1,1 };
1255
1256   if (!TEST_EQ_4V( s_plane, scale_identity) ||
1257       !TEST_EQ_4V( t_plane, scale_identity) ||
1258       !TEST_EQ_4V( r_plane, scale_identity)) {
1259      rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit;
1260      rmesa->TexGenMatrix[unit].m[0]  = s_plane[0];
1261      rmesa->TexGenMatrix[unit].m[4]  = s_plane[1];
1262      rmesa->TexGenMatrix[unit].m[8]  = s_plane[2];
1263      rmesa->TexGenMatrix[unit].m[12] = s_plane[3];
1264
1265      rmesa->TexGenMatrix[unit].m[1]  = t_plane[0];
1266      rmesa->TexGenMatrix[unit].m[5]  = t_plane[1];
1267      rmesa->TexGenMatrix[unit].m[9]  = t_plane[2];
1268      rmesa->TexGenMatrix[unit].m[13] = t_plane[3];
1269
1270      /* NOTE: r_plane goes in the 4th row, not 3rd! */
1271      rmesa->TexGenMatrix[unit].m[3]  = r_plane[0];
1272      rmesa->TexGenMatrix[unit].m[7]  = r_plane[1];
1273      rmesa->TexGenMatrix[unit].m[11] = r_plane[2];
1274      rmesa->TexGenMatrix[unit].m[15] = r_plane[3];
1275
1276      rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
1277   }
1278}
1279
1280/* Need this special matrix to get correct reflection map coords */
1281static void
1282set_texgen_reflection_matrix( r200ContextPtr rmesa, GLuint unit )
1283{
1284   static const GLfloat m[16] = {
1285      -1,  0,  0,  0,
1286       0, -1,  0,  0,
1287       0,  0,  0, -1,
1288       0,  0, -1,  0 };
1289   _math_matrix_loadf( &(rmesa->TexGenMatrix[unit]), m);
1290   _math_matrix_analyse( &(rmesa->TexGenMatrix[unit]) );
1291   rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit;
1292}
1293
1294/* Need this special matrix to get correct normal map coords */
1295static void
1296set_texgen_normal_map_matrix( r200ContextPtr rmesa, GLuint unit )
1297{
1298   static const GLfloat m[16] = {
1299      1, 0, 0, 0,
1300      0, 1, 0, 0,
1301      0, 0, 0, 1,
1302      0, 0, 1, 0 };
1303   _math_matrix_loadf( &(rmesa->TexGenMatrix[unit]), m);
1304   _math_matrix_analyse( &(rmesa->TexGenMatrix[unit]) );
1305   rmesa->TexGenEnabled |= R200_TEXMAT_0_ENABLE<<unit;
1306}
1307
1308
1309/* Ignoring the Q texcoord for now.
1310 *
1311 * Returns GL_FALSE if fallback required.
1312 */
1313static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit )
1314{
1315   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1316   const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1317   GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit*4;
1318   GLuint tmp = rmesa->TexGenEnabled;
1319
1320   rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
1321   rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
1322   rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
1323   rmesa->TexGenInputs &= ~(R200_TEXGEN_INPUT_MASK<<inputshift);
1324   rmesa->TexGenNeedNormals[unit] = 0;
1325
1326   if (0)
1327      fprintf(stderr, "%s unit %d\n", __FUNCTION__, unit);
1328
1329   if ((texUnit->TexGenEnabled & (S_BIT|T_BIT|R_BIT)) == 0) {
1330      /* Disabled, no fallback:
1331       */
1332      rmesa->TexGenInputs |=
1333	 (R200_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
1334      return GL_TRUE;
1335   }
1336   else if (texUnit->TexGenEnabled & Q_BIT) {
1337      /* Very easy to do this, in fact would remove a fallback case
1338       * elsewhere, but I haven't done it yet...  Fallback:
1339       */
1340      /*fprintf(stderr, "fallback Q_BIT\n");*/
1341      return GL_FALSE;
1342   }
1343   else if (texUnit->TexGenEnabled == (S_BIT|T_BIT) &&
1344	    texUnit->GenModeS == texUnit->GenModeT) {
1345      /* OK */
1346      rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
1347      /* continue */
1348   }
1349   else if (texUnit->TexGenEnabled == (S_BIT|T_BIT|R_BIT) &&
1350	    texUnit->GenModeS == texUnit->GenModeT &&
1351            texUnit->GenModeT == texUnit->GenModeR) {
1352      /* OK */
1353      rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
1354      /* continue */
1355   }
1356   else {
1357      /* Mixed modes, fallback:
1358       */
1359      /* fprintf(stderr, "fallback mixed texgen\n"); */
1360      return GL_FALSE;
1361   }
1362
1363   rmesa->TexGenEnabled |= R200_TEXGEN_TEXMAT_0_ENABLE << unit;
1364
1365   switch (texUnit->GenModeS) {
1366   case GL_OBJECT_LINEAR:
1367      rmesa->TexGenInputs |= R200_TEXGEN_INPUT_OBJ << inputshift;
1368      set_texgen_matrix( rmesa, unit,
1369			 texUnit->ObjectPlaneS,
1370			 texUnit->ObjectPlaneT,
1371                         texUnit->ObjectPlaneR);
1372      break;
1373
1374   case GL_EYE_LINEAR:
1375      rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE << inputshift;
1376      set_texgen_matrix( rmesa, unit,
1377			 texUnit->EyePlaneS,
1378			 texUnit->EyePlaneT,
1379			 texUnit->EyePlaneR);
1380      break;
1381
1382   case GL_REFLECTION_MAP_NV:
1383      rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1384      rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE_REFLECT<<inputshift;
1385      set_texgen_reflection_matrix(rmesa, unit);
1386      break;
1387
1388   case GL_NORMAL_MAP_NV:
1389      rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1390      rmesa->TexGenInputs |= R200_TEXGEN_INPUT_EYE_NORMAL<<inputshift;
1391      set_texgen_normal_map_matrix(rmesa, unit);
1392      break;
1393
1394   case GL_SPHERE_MAP:
1395      rmesa->TexGenNeedNormals[unit] = GL_TRUE;
1396      rmesa->TexGenInputs |= R200_TEXGEN_INPUT_SPHERE<<inputshift;
1397      break;
1398
1399   default:
1400      /* Unsupported mode, fallback:
1401       */
1402      /*  fprintf(stderr, "fallback unsupported texgen\n"); */
1403      return GL_FALSE;
1404   }
1405
1406   rmesa->TexGenCompSel |= R200_OUTPUT_TEX_0 << unit;
1407
1408   if (tmp != rmesa->TexGenEnabled) {
1409      rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
1410   }
1411
1412   return GL_TRUE;
1413}
1414
1415
1416static void disable_tex( GLcontext *ctx, int unit )
1417{
1418   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1419
1420   if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE<<unit)) {
1421      /* Texture unit disabled */
1422      if ( rmesa->state.texture.unit[unit].texobj != NULL ) {
1423	 /* The old texture is no longer bound to this texture unit.
1424	  * Mark it as such.
1425	  */
1426
1427	 rmesa->state.texture.unit[unit].texobj->base.bound &= ~(1UL << unit);
1428	 rmesa->state.texture.unit[unit].texobj = NULL;
1429      }
1430
1431      R200_STATECHANGE( rmesa, ctx );
1432      rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~((R200_TEX_0_ENABLE |
1433					   R200_TEX_BLEND_0_ENABLE) << unit);
1434      rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_BLEND_0_ENABLE;
1435
1436      R200_STATECHANGE( rmesa, tcl );
1437      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
1438
1439      if (rmesa->TclFallback & (R200_TCL_FALLBACK_TEXGEN_0<<unit)) {
1440	 TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
1441      }
1442
1443      /* Actually want to keep all units less than max active texture
1444       * enabled, right?  Fix this for >2 texunits.
1445       */
1446      /* FIXME: What should happen here if r200UpdateTextureEnv fails? */
1447      if (unit == 0)
1448	 r200UpdateTextureEnv( ctx, unit );
1449
1450
1451      {
1452	 GLuint inputshift = R200_TEXGEN_0_INPUT_SHIFT + unit*4;
1453	 GLuint tmp = rmesa->TexGenEnabled;
1454
1455	 rmesa->TexGenEnabled &= ~(R200_TEXGEN_TEXMAT_0_ENABLE<<unit);
1456	 rmesa->TexGenEnabled &= ~(R200_TEXMAT_0_ENABLE<<unit);
1457	 rmesa->TexGenEnabled &= ~(R200_TEXGEN_INPUT_MASK<<inputshift);
1458	 rmesa->TexGenNeedNormals[unit] = 0;
1459	 rmesa->TexGenCompSel &= ~(R200_OUTPUT_TEX_0 << unit);
1460	 rmesa->TexGenInputs &= ~(R200_TEXGEN_INPUT_MASK<<inputshift);
1461
1462	 if (tmp != rmesa->TexGenEnabled) {
1463	    rmesa->recheck_texgen[unit] = GL_TRUE;
1464	    rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
1465	 }
1466      }
1467   }
1468}
1469
1470static GLboolean enable_tex_2d( GLcontext *ctx, int unit )
1471{
1472   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1473   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1474   struct gl_texture_object *tObj = texUnit->_Current;
1475   r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData;
1476
1477   /* Need to load the 2d images associated with this unit.
1478    */
1479   if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) {
1480      t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2;
1481      t->base.dirty_images[0] = ~0;
1482   }
1483
1484   ASSERT(tObj->Target == GL_TEXTURE_2D || tObj->Target == GL_TEXTURE_1D);
1485
1486   if ( t->base.dirty_images[0] ) {
1487      R200_FIREVERTICES( rmesa );
1488      r200SetTexImages( rmesa, tObj );
1489      r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 );
1490      if ( !t->base.memBlock )
1491	 return GL_FALSE;
1492   }
1493
1494   return GL_TRUE;
1495}
1496
1497#if ENABLE_HW_3D_TEXTURE
1498static GLboolean enable_tex_3d( GLcontext *ctx, int unit )
1499{
1500   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1501   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1502   struct gl_texture_object *tObj = texUnit->_Current;
1503   r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData;
1504
1505   /* Need to load the 3d images associated with this unit.
1506    */
1507   if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) {
1508      t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2;
1509      t->base.dirty_images[0] = ~0;
1510   }
1511
1512   ASSERT(tObj->Target == GL_TEXTURE_3D);
1513
1514   /* R100 & R200 do not support mipmaps for 3D textures.
1515    */
1516   if ( (tObj->MinFilter != GL_NEAREST) && (tObj->MinFilter != GL_LINEAR) ) {
1517      return GL_FALSE;
1518   }
1519
1520   if ( t->base.dirty_images[0] ) {
1521      R200_FIREVERTICES( rmesa );
1522      r200SetTexImages( rmesa, tObj );
1523      r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 );
1524      if ( !t->base.memBlock )
1525	 return GL_FALSE;
1526   }
1527
1528   return GL_TRUE;
1529}
1530#endif
1531
1532static GLboolean enable_tex_cube( GLcontext *ctx, int unit )
1533{
1534   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1535   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1536   struct gl_texture_object *tObj = texUnit->_Current;
1537   r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData;
1538   GLuint face;
1539
1540   /* Need to load the 2d images associated with this unit.
1541    */
1542   if (t->pp_txformat & R200_TXFORMAT_NON_POWER2) {
1543      t->pp_txformat &= ~R200_TXFORMAT_NON_POWER2;
1544      for (face = 0; face < 6; face++)
1545         t->base.dirty_images[face] = ~0;
1546   }
1547
1548   ASSERT(tObj->Target == GL_TEXTURE_CUBE_MAP);
1549
1550   if ( t->base.dirty_images[0] || t->base.dirty_images[1] ||
1551        t->base.dirty_images[2] || t->base.dirty_images[3] ||
1552        t->base.dirty_images[4] || t->base.dirty_images[5] ) {
1553      /* flush */
1554      R200_FIREVERTICES( rmesa );
1555      /* layout memory space, once for all faces */
1556      r200SetTexImages( rmesa, tObj );
1557   }
1558
1559   /* upload (per face) */
1560   for (face = 0; face < 6; face++) {
1561      if (t->base.dirty_images[face]) {
1562         r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, face );
1563      }
1564   }
1565
1566   if ( !t->base.memBlock ) {
1567      /* texmem alloc failed, use s/w fallback */
1568      return GL_FALSE;
1569   }
1570
1571   return GL_TRUE;
1572}
1573
1574static GLboolean enable_tex_rect( GLcontext *ctx, int unit )
1575{
1576   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1577   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1578   struct gl_texture_object *tObj = texUnit->_Current;
1579   r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData;
1580
1581   if (!(t->pp_txformat & R200_TXFORMAT_NON_POWER2)) {
1582      t->pp_txformat |= R200_TXFORMAT_NON_POWER2;
1583      t->base.dirty_images[0] = ~0;
1584   }
1585
1586   ASSERT(tObj->Target == GL_TEXTURE_RECTANGLE_NV);
1587
1588   if ( t->base.dirty_images[0] ) {
1589      R200_FIREVERTICES( rmesa );
1590      r200SetTexImages( rmesa, tObj );
1591      r200UploadTexImages( rmesa, (r200TexObjPtr) tObj->DriverData, 0 );
1592      if ( !t->base.memBlock && !rmesa->prefer_gart_client_texturing )
1593	 return GL_FALSE;
1594   }
1595
1596   return GL_TRUE;
1597}
1598
1599
1600static GLboolean update_tex_common( GLcontext *ctx, int unit )
1601{
1602   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1603   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1604   struct gl_texture_object *tObj = texUnit->_Current;
1605   r200TexObjPtr t = (r200TexObjPtr) tObj->DriverData;
1606   GLenum format;
1607
1608   /* Fallback if there's a texture border */
1609   if ( tObj->Image[tObj->BaseLevel]->Border > 0 )
1610       return GL_FALSE;
1611
1612   /* Update state if this is a different texture object to last
1613    * time.
1614    */
1615   if ( rmesa->state.texture.unit[unit].texobj != t ) {
1616      if ( rmesa->state.texture.unit[unit].texobj != NULL ) {
1617	 /* The old texture is no longer bound to this texture unit.
1618	  * Mark it as such.
1619	  */
1620
1621	 rmesa->state.texture.unit[unit].texobj->base.bound &=
1622	     ~(1UL << unit);
1623      }
1624
1625      rmesa->state.texture.unit[unit].texobj = t;
1626      t->base.bound |= (1UL << unit);
1627      t->dirty_state |= 1<<unit;
1628      driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */
1629   }
1630
1631
1632   /* Newly enabled?
1633    */
1634   if ( 1|| !(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (R200_TEX_0_ENABLE<<unit))) {
1635      R200_STATECHANGE( rmesa, ctx );
1636      rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (R200_TEX_0_ENABLE |
1637					 R200_TEX_BLEND_0_ENABLE) << unit;
1638
1639      R200_STATECHANGE( rmesa, vtx );
1640      rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] |= 4 << (unit * 3);
1641
1642      rmesa->recheck_texgen[unit] = GL_TRUE;
1643   }
1644
1645   if (t->dirty_state & (1<<unit)) {
1646      import_tex_obj_state( rmesa, unit, t );
1647   }
1648
1649   if (rmesa->recheck_texgen[unit]) {
1650      GLboolean fallback = !r200_validate_texgen( ctx, unit );
1651      TCL_FALLBACK( ctx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), fallback);
1652      rmesa->recheck_texgen[unit] = 0;
1653      rmesa->NewGLState |= _NEW_TEXTURE_MATRIX;
1654   }
1655
1656   format = tObj->Image[tObj->BaseLevel]->Format;
1657   if ( rmesa->state.texture.unit[unit].format != format ||
1658	rmesa->state.texture.unit[unit].envMode != texUnit->EnvMode ) {
1659      rmesa->state.texture.unit[unit].format = format;
1660      rmesa->state.texture.unit[unit].envMode = texUnit->EnvMode;
1661      if ( ! r200UpdateTextureEnv( ctx, unit ) ) {
1662	 return GL_FALSE;
1663      }
1664   }
1665
1666   FALLBACK( rmesa, R200_FALLBACK_BORDER_MODE, t->border_fallback );
1667   return !t->border_fallback;
1668}
1669
1670
1671
1672static GLboolean r200UpdateTextureUnit( GLcontext *ctx, int unit )
1673{
1674   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
1675
1676   if ( texUnit->_ReallyEnabled & (TEXTURE_RECT_BIT) ) {
1677      return (enable_tex_rect( ctx, unit ) &&
1678	      update_tex_common( ctx, unit ));
1679   }
1680   else if ( texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) {
1681      return (enable_tex_2d( ctx, unit ) &&
1682	      update_tex_common( ctx, unit ));
1683   }
1684#if ENABLE_HW_3D_TEXTURE
1685   else if ( texUnit->_ReallyEnabled & (TEXTURE_3D_BIT) ) {
1686      return (enable_tex_3d( ctx, unit ) &&
1687	      update_tex_common( ctx, unit ));
1688   }
1689#endif
1690   else if ( texUnit->_ReallyEnabled & (TEXTURE_CUBE_BIT) ) {
1691      return (enable_tex_cube( ctx, unit ) &&
1692	      update_tex_common( ctx, unit ));
1693   }
1694   else if ( texUnit->_ReallyEnabled ) {
1695      return GL_FALSE;
1696   }
1697   else {
1698      disable_tex( ctx, unit );
1699      return GL_TRUE;
1700   }
1701}
1702
1703
1704void r200UpdateTextureState( GLcontext *ctx )
1705{
1706   r200ContextPtr rmesa = R200_CONTEXT(ctx);
1707   GLboolean ok;
1708   GLuint dbg;
1709
1710   ok = (r200UpdateTextureUnit( ctx, 0 ) &&
1711	 r200UpdateTextureUnit( ctx, 1 ));
1712
1713   FALLBACK( rmesa, R200_FALLBACK_TEXTURE, !ok );
1714
1715   if (rmesa->TclFallback)
1716      r200ChooseVertexState( ctx );
1717
1718   /*
1719    * T0 hang workaround -------------
1720    */
1721#if 1
1722   if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_ENABLE_MASK) == R200_TEX_0_ENABLE &&
1723       (rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK) > R200_MIN_FILTER_LINEAR) {
1724
1725      R200_STATECHANGE(rmesa, ctx);
1726      R200_STATECHANGE(rmesa, tex[1]);
1727      rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= R200_TEX_1_ENABLE;
1728      rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK;
1729      rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] |= 0x08000000;
1730   }
1731   else {
1732      if ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE) &&
1733	  (rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] & 0x08000000)) {
1734	 R200_STATECHANGE(rmesa, tex[1]);
1735	 rmesa->hw.tex[1].cmd[TEX_PP_TXFORMAT] &= ~0x08000000;
1736      }
1737   }
1738#endif
1739
1740#if 1
1741   /*
1742    * Texture cache LRU hang workaround -------------
1743    */
1744   dbg = 0x0;
1745   if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_0_ENABLE) &&
1746	((((rmesa->hw.tex[0].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1747	  0x04) == 0)))
1748   {
1749      dbg |= 0x02;
1750   }
1751
1752   if (((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_1_ENABLE) &&
1753	((((rmesa->hw.tex[1].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) &
1754	  0x04) == 0)))
1755   {
1756      dbg |= 0x04;
1757   }
1758
1759   if (dbg != rmesa->hw.tam.cmd[TAM_DEBUG3]) {
1760      R200_STATECHANGE( rmesa, tam );
1761      rmesa->hw.tam.cmd[TAM_DEBUG3] = dbg;
1762      if (0) printf("TEXCACHE LRU HANG WORKAROUND %x\n", dbg);
1763   }
1764#endif
1765}
1766
1767/*
1768  also tests for higher texunits:
1769
1770       ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_2_ENABLE) &&
1771	((((rmesa->hw.tex[2].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04) == 0)) ||
1772       ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_4_ENABLE) &&
1773	((((rmesa->hw.tex[4].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04) == 0)))
1774
1775       ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_3_ENABLE) &&
1776	((((rmesa->hw.tex[3].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04) == 0)) ||
1777       ((rmesa->hw.ctx.cmd[CTX_PP_CNTL] & R200_TEX_5_ENABLE) &&
1778	((((rmesa->hw.tex[5].cmd[TEX_PP_TXFILTER] & R200_MIN_FILTER_MASK)) & 0x04) == 0)))
1779
1780*/
1781