Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / r128 / r128_texstate.c
1 /**************************************************************************
2
3 Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
4                                                Cedar Park, Texas.
5 All Rights Reserved.
6
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the "Software"),
9 to deal in the Software without restriction, including without limitation
10 on the rights to use, copy, modify, merge, publish, distribute, sub
11 license, and/or sell copies of the Software, and to permit persons to whom
12 the Software is furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
16 Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **************************************************************************/
27
28 /*
29  * Authors:
30  *   Gareth Hughes <gareth@valinux.com>
31  *   Kevin E. Martin <martin@valinux.com>
32  *   Brian Paul <brianp@valinux.com>
33  */
34
35 #include "main/glheader.h"
36 #include "main/imports.h"
37 #include "main/context.h"
38 #include "main/macros.h"
39
40 #include "r128_context.h"
41 #include "r128_ioctl.h"
42 #include "r128_tris.h"
43 #include "r128_tex.h"
44
45
46 static void r128SetTexImages( r128ContextPtr rmesa,
47                               const struct gl_texture_object *tObj )
48 {
49    r128TexObjPtr t = (r128TexObjPtr) tObj->DriverData;
50    struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel];
51    int log2Pitch, log2Height, log2Size, log2MinSize;
52    int totalSize;
53    int i;
54    GLint firstLevel, lastLevel;
55
56    assert(t);
57    assert(baseImage);
58
59    if ( R128_DEBUG & DEBUG_VERBOSE_API )
60       fprintf( stderr, "%s( %p )\n", __FUNCTION__, (void *) tObj );
61
62    switch (baseImage->TexFormat) {
63    case MESA_FORMAT_ARGB8888:
64    case MESA_FORMAT_ARGB8888_REV:
65       t->textureFormat = R128_DATATYPE_ARGB8888;
66       break;
67    case MESA_FORMAT_ARGB4444:
68    case MESA_FORMAT_ARGB4444_REV:
69       t->textureFormat = R128_DATATYPE_ARGB4444;
70       break;
71    case MESA_FORMAT_RGB565:
72    case MESA_FORMAT_RGB565_REV:
73       t->textureFormat = R128_DATATYPE_RGB565;
74       break;
75    case MESA_FORMAT_RGB332:
76       t->textureFormat = R128_DATATYPE_RGB8;
77       break;
78    case MESA_FORMAT_CI8:
79       t->textureFormat = R128_DATATYPE_CI8;
80       break;
81    case MESA_FORMAT_YCBCR:
82       t->textureFormat = R128_DATATYPE_YVYU422;
83       break;
84    case MESA_FORMAT_YCBCR_REV:
85       t->textureFormat = R128_DATATYPE_VYUY422;
86       break;
87    default:
88       _mesa_problem(rmesa->glCtx, "Bad texture format in %s", __FUNCTION__);
89    };
90
91    /* Compute which mipmap levels we really want to send to the hardware.
92     */
93
94    driCalculateTextureFirstLastLevel( (driTextureObject *) t );
95    firstLevel = t->base.firstLevel;
96    lastLevel  = t->base.lastLevel;
97
98    log2Pitch = tObj->Image[0][firstLevel]->WidthLog2;
99    log2Height = tObj->Image[0][firstLevel]->HeightLog2;
100    log2Size = MAX2(log2Pitch, log2Height);
101    log2MinSize = log2Size;
102
103    t->base.dirty_images[0] = 0;
104    totalSize = 0;
105    for ( i = firstLevel; i <= lastLevel; i++ ) {
106       const struct gl_texture_image *texImage;
107
108       texImage = tObj->Image[0][i];
109       if ( !texImage || !texImage->Data ) {
110          lastLevel = i - 1;
111          break;
112       }
113
114       log2MinSize = texImage->MaxLog2;
115
116       t->image[i - firstLevel].offset = totalSize;
117       t->image[i - firstLevel].width  = tObj->Image[0][i]->Width;
118       t->image[i - firstLevel].height = tObj->Image[0][i]->Height;
119
120       t->base.dirty_images[0] |= (1 << i);
121
122       totalSize += (tObj->Image[0][i]->Height *
123                     tObj->Image[0][i]->Width *
124                     _mesa_get_format_bytes(tObj->Image[0][i]->TexFormat));
125
126       /* Offsets must be 32-byte aligned for host data blits and tiling */
127       totalSize = (totalSize + 31) & ~31;
128    }
129
130    t->base.totalSize = totalSize;
131    t->base.firstLevel = firstLevel;
132    t->base.lastLevel = lastLevel;
133
134    /* Set the texture format */
135    t->setup.tex_cntl &= ~(0xf << 16);
136    t->setup.tex_cntl |= t->textureFormat;
137
138    t->setup.tex_combine_cntl = 0x00000000;  /* XXX is this right? */
139
140    t->setup.tex_size_pitch = ((log2Pitch   << R128_TEX_PITCH_SHIFT) |
141                               (log2Size    << R128_TEX_SIZE_SHIFT) |
142                               (log2Height  << R128_TEX_HEIGHT_SHIFT) |
143                               (log2MinSize << R128_TEX_MIN_SIZE_SHIFT));
144
145    for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) {
146       t->setup.tex_offset[i]  = 0x00000000;
147    }
148
149    if (firstLevel == lastLevel)
150       t->setup.tex_cntl |= R128_MIP_MAP_DISABLE;
151    else
152       t->setup.tex_cntl &= ~R128_MIP_MAP_DISABLE;
153
154    /* FYI: r128UploadTexImages( rmesa, t ); used to be called here */
155 }
156
157
158 /* ================================================================
159  * Texture combine functions
160  */
161
162 #define COLOR_COMB_DISABLE              (R128_COMB_DIS |                \
163                                          R128_COLOR_FACTOR_TEX)
164 #define COLOR_COMB_COPY_INPUT           (R128_COMB_COPY_INP |           \
165                                          R128_COLOR_FACTOR_TEX)
166 #define COLOR_COMB_MODULATE             (R128_COMB_MODULATE |           \
167                                          R128_COLOR_FACTOR_TEX)
168 #define COLOR_COMB_MODULATE_NTEX        (R128_COMB_MODULATE |           \
169                                          R128_COLOR_FACTOR_NTEX)
170 #define COLOR_COMB_ADD                  (R128_COMB_ADD |                \
171                                          R128_COLOR_FACTOR_TEX)
172 #define COLOR_COMB_BLEND_TEX            (R128_COMB_BLEND_TEXTURE |      \
173                                          R128_COLOR_FACTOR_TEX)
174 /* Rage 128 Pro/M3 only! */
175 #define COLOR_COMB_BLEND_COLOR          (R128_COMB_MODULATE2X |         \
176                                          R128_COMB_FCN_MSB |            \
177                                          R128_COLOR_FACTOR_CONST_COLOR)
178
179 #define ALPHA_COMB_DISABLE              (R128_COMB_ALPHA_DIS |          \
180                                          R128_ALPHA_FACTOR_TEX_ALPHA)
181 #define ALPHA_COMB_COPY_INPUT           (R128_COMB_ALPHA_COPY_INP |     \
182                                          R128_ALPHA_FACTOR_TEX_ALPHA)
183 #define ALPHA_COMB_MODULATE             (R128_COMB_ALPHA_MODULATE |     \
184                                          R128_ALPHA_FACTOR_TEX_ALPHA)
185 #define ALPHA_COMB_MODULATE_NTEX        (R128_COMB_ALPHA_MODULATE |     \
186                                          R128_ALPHA_FACTOR_NTEX_ALPHA)
187 #define ALPHA_COMB_ADD                  (R128_COMB_ALPHA_ADD |          \
188                                          R128_ALPHA_FACTOR_TEX_ALPHA)
189
190 #define INPUT_INTERP                    (R128_INPUT_FACTOR_INT_COLOR |  \
191                                          R128_INP_FACTOR_A_INT_ALPHA)
192 #define INPUT_PREVIOUS                  (R128_INPUT_FACTOR_PREV_COLOR | \
193                                          R128_INP_FACTOR_A_PREV_ALPHA)
194
195 static GLboolean r128UpdateTextureEnv( struct gl_context *ctx, int unit )
196 {
197    r128ContextPtr rmesa = R128_CONTEXT(ctx);
198    GLint source = rmesa->tmu_source[unit];
199    const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
200    const struct gl_texture_object *tObj = texUnit->_Current;
201    const GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
202    GLuint combine;
203
204    if ( R128_DEBUG & DEBUG_VERBOSE_API ) {
205       fprintf( stderr, "%s( %p, %d )\n",
206                __FUNCTION__, (void *) ctx, unit );
207    }
208
209    if ( unit == 0 ) {
210       combine = INPUT_INTERP;
211    } else {
212       combine = INPUT_PREVIOUS;
213    }
214
215    /* Set the texture environment state */
216    switch ( texUnit->EnvMode ) {
217    case GL_REPLACE:
218       switch ( format ) {
219       case GL_RGBA:
220       case GL_LUMINANCE_ALPHA:
221       case GL_INTENSITY:
222          combine |= (COLOR_COMB_DISABLE |               /* C = Ct            */
223                      ALPHA_COMB_DISABLE);               /* A = At            */
224          break;
225       case GL_RGB:
226       case GL_LUMINANCE:
227          combine |= (COLOR_COMB_DISABLE |               /* C = Ct            */
228                      ALPHA_COMB_COPY_INPUT);            /* A = Af            */
229          break;
230       case GL_ALPHA:
231          combine |= (COLOR_COMB_COPY_INPUT |            /* C = Cf            */
232                      ALPHA_COMB_DISABLE);               /* A = At            */
233          break;
234       case GL_COLOR_INDEX:
235       default:
236          return GL_FALSE;
237       }
238       break;
239
240    case GL_MODULATE:
241       switch ( format ) {
242       case GL_RGBA:
243       case GL_LUMINANCE_ALPHA:
244       case GL_INTENSITY:
245          combine |= (COLOR_COMB_MODULATE |              /* C = CfCt          */
246                      ALPHA_COMB_MODULATE);              /* A = AfAt          */
247          break;
248       case GL_RGB:
249       case GL_LUMINANCE:
250          combine |= (COLOR_COMB_MODULATE |              /* C = CfCt          */
251                      ALPHA_COMB_COPY_INPUT);            /* A = Af            */
252          break;
253       case GL_ALPHA:
254          combine |= (COLOR_COMB_COPY_INPUT |            /* C = Cf            */
255                      ALPHA_COMB_MODULATE);              /* A = AfAt          */
256          break;
257       case GL_COLOR_INDEX:
258       default:
259          return GL_FALSE;
260       }
261       break;
262
263    case GL_DECAL:
264       switch ( format ) {
265       case GL_RGBA:
266          combine |= (COLOR_COMB_BLEND_TEX |             /* C = Cf(1-At)+CtAt */
267                      ALPHA_COMB_COPY_INPUT);            /* A = Af            */
268          break;
269       case GL_RGB:
270          combine |= (COLOR_COMB_DISABLE |               /* C = Ct            */
271                      ALPHA_COMB_COPY_INPUT);            /* A = Af            */
272          break;
273       case GL_ALPHA:
274       case GL_LUMINANCE:
275       case GL_LUMINANCE_ALPHA:
276       case GL_INTENSITY:
277          /* Undefined behaviour - just copy the incoming fragment */
278          combine |= (COLOR_COMB_COPY_INPUT |            /* C = undefined     */
279                      ALPHA_COMB_COPY_INPUT);            /* A = undefined     */
280          break;
281       case GL_COLOR_INDEX:
282       default:
283          return GL_FALSE;
284       }
285       break;
286
287    case GL_BLEND:
288       /* Rage 128 Pro and M3 can handle GL_BLEND texturing.
289        */
290       if ( !R128_IS_PLAIN( rmesa ) ) {
291          /* XXX this hasn't been fully tested, I don't have a Pro card. -BP */
292          switch ( format ) {
293          case GL_RGBA:
294          case GL_LUMINANCE_ALPHA:
295             combine |= (COLOR_COMB_BLEND_COLOR |        /* C = Cf(1-Ct)+CcCt */
296                         ALPHA_COMB_MODULATE);           /* A = AfAt          */
297             break;
298
299          case GL_RGB:
300          case GL_LUMINANCE:
301             combine |= (COLOR_COMB_BLEND_COLOR |        /* C = Cf(1-Ct)+CcCt */
302                         ALPHA_COMB_COPY_INPUT);         /* A = Af            */
303             break;
304
305          case GL_ALPHA:
306             combine |= (COLOR_COMB_COPY_INPUT |         /* C = Cf            */
307                         ALPHA_COMB_MODULATE);           /* A = AfAt          */
308             break;
309
310          case GL_INTENSITY:
311             /* GH: We could be smarter about this... */
312             switch ( rmesa->env_color & 0xff000000 ) {
313             case 0x00000000:
314                combine |= (COLOR_COMB_BLEND_COLOR |     /* C = Cf(1-It)+CcIt */
315                            ALPHA_COMB_MODULATE_NTEX);   /* A = Af(1-It)      */
316             default:
317                combine |= (COLOR_COMB_MODULATE |        /* C = fallback      */
318                            ALPHA_COMB_MODULATE);        /* A = fallback      */
319                return GL_FALSE;
320             }
321             break;
322
323          case GL_COLOR_INDEX:
324          default:
325             return GL_FALSE;
326          }
327          break;
328       }
329
330       /* Rage 128 has to fake some cases of GL_BLEND, otherwise fallback
331        * to software rendering.
332        */
333       if ( rmesa->blend_flags ) {
334          return GL_FALSE;
335       }
336       switch ( format ) {
337       case GL_RGBA:
338       case GL_LUMINANCE_ALPHA:
339          switch ( rmesa->env_color & 0x00ffffff ) {
340          case 0x00000000:
341             combine |= (COLOR_COMB_MODULATE_NTEX |      /* C = Cf(1-Ct)      */
342                         ALPHA_COMB_MODULATE);           /* A = AfAt          */
343             break;
344 #if 0
345          /* This isn't right - BP */
346          case 0x00ffffff:
347             if ( unit == 0 ) {
348                combine |= (COLOR_COMB_MODULATE_NTEX |   /* C = Cf(1-Ct)      */
349                            ALPHA_COMB_MODULATE);        /* A = AfAt          */
350             } else {
351                combine |= (COLOR_COMB_ADD |             /* C = Cf+Ct         */
352                            ALPHA_COMB_COPY_INPUT);      /* A = Af            */
353             }
354             break;
355 #endif
356          default:
357             combine |= (COLOR_COMB_MODULATE |           /* C = fallback      */
358                         ALPHA_COMB_MODULATE);           /* A = fallback      */
359             return GL_FALSE;
360          }
361          break;
362       case GL_RGB:
363       case GL_LUMINANCE:
364          switch ( rmesa->env_color & 0x00ffffff ) {
365          case 0x00000000:
366             combine |= (COLOR_COMB_MODULATE_NTEX |      /* C = Cf(1-Ct)      */
367                         ALPHA_COMB_COPY_INPUT);         /* A = Af            */
368             break;
369 #if 0
370          /* This isn't right - BP */
371          case 0x00ffffff:
372             if ( unit == 0 ) {
373                combine |= (COLOR_COMB_MODULATE_NTEX |   /* C = Cf(1-Ct)      */
374                            ALPHA_COMB_COPY_INPUT);      /* A = Af            */
375             } else {
376                combine |= (COLOR_COMB_ADD |             /* C = Cf+Ct         */
377                            ALPHA_COMB_COPY_INPUT);      /* A = Af            */
378             }
379             break;
380 #endif
381          default:
382             combine |= (COLOR_COMB_MODULATE |           /* C = fallback      */
383                         ALPHA_COMB_COPY_INPUT);         /* A = fallback      */
384             return GL_FALSE;
385          }
386          break;
387       case GL_ALPHA:
388          if ( unit == 0 ) {
389             combine |= (COLOR_COMB_COPY_INPUT |         /* C = Cf            */
390                         ALPHA_COMB_MODULATE);           /* A = AfAt          */
391          } else {
392             combine |= (COLOR_COMB_COPY_INPUT |         /* C = Cf            */
393                         ALPHA_COMB_COPY_INPUT);         /* A = Af            */
394          }
395          break;
396       case GL_INTENSITY:
397          switch ( rmesa->env_color & 0x00ffffff ) {
398          case 0x00000000:
399             combine |= COLOR_COMB_MODULATE_NTEX;        /* C = Cf(1-It)      */
400             break;
401 #if 0
402          /* This isn't right - BP */
403          case 0x00ffffff:
404             if ( unit == 0 ) {
405                combine |= COLOR_COMB_MODULATE_NTEX;     /* C = Cf(1-It)      */
406             } else {
407                combine |= COLOR_COMB_ADD;               /* C = Cf+It         */
408             }
409             break;
410 #endif
411          default:
412             combine |= (COLOR_COMB_MODULATE |           /* C = fallback      */
413                         ALPHA_COMB_MODULATE);           /* A = fallback      */
414             return GL_FALSE;
415          }
416          switch ( rmesa->env_color & 0xff000000 ) {
417          case 0x00000000:
418             combine |= ALPHA_COMB_MODULATE_NTEX;        /* A = Af(1-It)      */
419             break;
420 #if 0
421          /* This isn't right - BP */
422          case 0xff000000:
423             if ( unit == 0 ) {
424                combine |= ALPHA_COMB_MODULATE_NTEX;     /* A = Af(1-It)      */
425             } else {
426                combine |= ALPHA_COMB_ADD;               /* A = Af+It         */
427             }
428             break;
429 #endif
430          default:
431             combine |= (COLOR_COMB_MODULATE |           /* C = fallback      */
432                         ALPHA_COMB_MODULATE);           /* A = fallback      */
433             return GL_FALSE;
434          }
435          break;
436       case GL_COLOR_INDEX:
437       default:
438          return GL_FALSE;
439       }
440       break;
441
442    case GL_ADD:
443       switch ( format ) {
444       case GL_RGBA:
445       case GL_LUMINANCE_ALPHA:
446          combine |= (COLOR_COMB_ADD |                   /* C = Cf+Ct         */
447                      ALPHA_COMB_MODULATE);              /* A = AfAt          */
448          break;
449       case GL_RGB:
450       case GL_LUMINANCE:
451          combine |= (COLOR_COMB_ADD |                   /* C = Cf+Ct         */
452                      ALPHA_COMB_COPY_INPUT);            /* A = Af            */
453          break;
454       case GL_ALPHA:
455          combine |= (COLOR_COMB_COPY_INPUT |            /* C = Cf            */
456                      ALPHA_COMB_MODULATE);              /* A = AfAt          */
457          break;
458       case GL_INTENSITY:
459          combine |= (COLOR_COMB_ADD |                   /* C = Cf+Ct         */
460                      ALPHA_COMB_ADD);                   /* A = Af+At         */
461          break;
462       case GL_COLOR_INDEX:
463       default:
464          return GL_FALSE;
465       }
466       break;
467
468    default:
469       return GL_FALSE;
470    }
471
472    if ( rmesa->tex_combine[unit] != combine ) {
473      rmesa->tex_combine[unit] = combine;
474      rmesa->dirty |= R128_UPLOAD_TEX0 << unit;
475    }
476    return GL_TRUE;
477 }
478
479 static void disable_tex( struct gl_context *ctx, int unit )
480 {
481    r128ContextPtr rmesa = R128_CONTEXT(ctx);
482
483    FLUSH_BATCH( rmesa );
484
485    if ( rmesa->CurrentTexObj[unit] ) {
486       rmesa->CurrentTexObj[unit]->base.bound &= ~(1 << unit);
487       rmesa->CurrentTexObj[unit] = NULL;
488    }
489
490    rmesa->setup.tex_cntl_c &= ~(R128_TEXMAP_ENABLE << unit);
491    rmesa->setup.tex_size_pitch_c &= ~(R128_TEX_SIZE_PITCH_MASK << 
492                                       (R128_SEC_TEX_SIZE_PITCH_SHIFT * unit));
493    rmesa->dirty |= R128_UPLOAD_CONTEXT;
494
495    /* If either texture unit is disabled, then multitexturing is not
496     * happening.
497     */
498
499    rmesa->blend_flags &= ~R128_BLEND_MULTITEX;
500 }
501
502 static GLboolean enable_tex_2d( struct gl_context *ctx, int unit )
503 {
504    r128ContextPtr rmesa = R128_CONTEXT(ctx);
505    const int source = rmesa->tmu_source[unit];
506    const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
507    const struct gl_texture_object *tObj = texUnit->_Current;
508    r128TexObjPtr t = (r128TexObjPtr) tObj->DriverData;
509
510    /* Need to load the 2d images associated with this unit.
511     */
512    if ( t->base.dirty_images[0] ) {
513       /* FIXME: For Radeon, RADEON_FIREVERTICES is called here.  Should
514        * FIXME: something similar be done for R128?
515        */
516       /*  FLUSH_BATCH( rmesa ); */
517
518       r128SetTexImages( rmesa, tObj );
519       r128UploadTexImages( rmesa, t );
520       if ( !t->base.memBlock ) 
521           return GL_FALSE;
522    }
523
524    return GL_TRUE;
525 }
526
527 static GLboolean update_tex_common( struct gl_context *ctx, int unit )
528 {
529    r128ContextPtr rmesa = R128_CONTEXT(ctx);
530    const int source = rmesa->tmu_source[unit];
531    const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
532    const struct gl_texture_object *tObj = texUnit->_Current;
533    r128TexObjPtr t = (r128TexObjPtr) tObj->DriverData;
534
535
536    /* Fallback if there's a texture border */
537    if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) {
538       return GL_FALSE;
539    }
540
541
542    /* Update state if this is a different texture object to last
543     * time.
544     */
545    if ( rmesa->CurrentTexObj[unit] != t ) {
546       if ( rmesa->CurrentTexObj[unit] != NULL ) {
547          /* The old texture is no longer bound to this texture unit.
548           * Mark it as such.
549           */
550
551          rmesa->CurrentTexObj[unit]->base.bound &= 
552              ~(1UL << unit);
553       }
554
555       rmesa->CurrentTexObj[unit] = t;
556       t->base.bound |= (1UL << unit);
557       rmesa->dirty |= R128_UPLOAD_TEX0 << unit;
558
559       driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */
560    }
561
562    /* FIXME: We need to update the texture unit if any texture parameters have
563     * changed, but this texture was already bound.  This could be changed to
564     * work like the Radeon driver where the texture object has it's own
565     * dirty state flags
566     */
567    rmesa->dirty |= R128_UPLOAD_TEX0 << unit;
568
569    /* register setup */
570    rmesa->setup.tex_size_pitch_c &= ~(R128_TEX_SIZE_PITCH_MASK << 
571                                       (R128_SEC_TEX_SIZE_PITCH_SHIFT * unit));
572
573    if ( unit == 0 ) {
574       rmesa->setup.tex_cntl_c       |= R128_TEXMAP_ENABLE;
575       rmesa->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 0;
576       rmesa->setup.scale_3d_cntl    &= ~R128_TEX_CACHE_SPLIT;
577       t->setup.tex_cntl             &= ~R128_SEC_SELECT_SEC_ST;
578    }
579    else {
580       rmesa->setup.tex_cntl_c       |= R128_SEC_TEXMAP_ENABLE;
581       rmesa->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 16;
582       rmesa->setup.scale_3d_cntl    |= R128_TEX_CACHE_SPLIT;
583       t->setup.tex_cntl             |=  R128_SEC_SELECT_SEC_ST;
584
585       /* If the second TMU is enabled, then multitexturing is happening.
586        */
587       if ( R128_IS_PLAIN( rmesa ) )
588           rmesa->blend_flags            |= R128_BLEND_MULTITEX;
589    }
590
591    rmesa->dirty |= R128_UPLOAD_CONTEXT;
592
593
594    /* FIXME: The Radeon has some cached state so that it can avoid calling
595     * FIXME: UpdateTextureEnv in some cases.  Is that possible here?
596     */
597    return r128UpdateTextureEnv( ctx, unit );
598 }
599
600 static GLboolean updateTextureUnit( struct gl_context *ctx, int unit )
601 {
602    r128ContextPtr rmesa = R128_CONTEXT(ctx);
603    const int source = rmesa->tmu_source[unit];
604    const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
605
606
607    if (texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) {
608       return (enable_tex_2d( ctx, unit ) &&
609               update_tex_common( ctx, unit ));
610    }
611    else if ( texUnit->_ReallyEnabled ) {
612       return GL_FALSE;
613    }
614    else {
615       disable_tex( ctx, unit );
616       return GL_TRUE;
617    }
618 }
619
620
621 void r128UpdateTextureState( struct gl_context *ctx )
622 {
623    r128ContextPtr rmesa = R128_CONTEXT(ctx);
624    GLboolean ok;
625
626
627    /* This works around a quirk with the R128 hardware.  If only OpenGL 
628     * TEXTURE1 is enabled, then the hardware TEXTURE0 must be used.  The
629     * hardware TEXTURE1 can ONLY be used when hardware TEXTURE0 is also used.
630     */
631
632    rmesa->tmu_source[0] = 0;
633    rmesa->tmu_source[1] = 1;
634
635    if ((ctx->Texture._EnabledUnits & 0x03) == 0x02) {
636       /* only texture 1 enabled */
637       rmesa->tmu_source[0] = 1;
638       rmesa->tmu_source[1] = 0;
639    }
640
641    ok = (updateTextureUnit( ctx, 0 ) &&
642          updateTextureUnit( ctx, 1 ));
643
644    FALLBACK( rmesa, R128_FALLBACK_TEXTURE, !ok );
645 }