2 * Copyright 2000-2001 VA Linux Systems, Inc.
3 * (c) Copyright IBM Corporation 2002
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * on the rights to use, copy, modify, merge, publish, distribute, sub
10 * license, and/or sell copies of the Software, and to permit persons to whom
11 * the Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 * VA LINUX SYSTEMS, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23 * USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * Ian Romanick <idr@us.ibm.com>
27 * Keith Whitwell <keithw@tungstengraphics.com>
30 #include "main/context.h"
31 #include "main/enums.h"
32 #include "main/macros.h"
34 #include "main/imports.h"
35 #include "main/simple_list.h"
37 #include "mgacontext.h"
43 #define MGA_USE_TABLE_FOR_FORMAT
44 #ifdef MGA_USE_TABLE_FOR_FORMAT
45 #define TMC_nr_tformat (MESA_FORMAT_YCBCR_REV + 1)
46 static const unsigned TMC_tformat[ TMC_nr_tformat ] =
48 [MESA_FORMAT_ARGB8888] = TMC_tformat_tw32,
49 [MESA_FORMAT_RGB565] = TMC_tformat_tw16,
50 [MESA_FORMAT_ARGB4444] = TMC_tformat_tw12,
51 [MESA_FORMAT_ARGB1555] = TMC_tformat_tw15,
52 [MESA_FORMAT_AL88] = TMC_tformat_tw8al,
53 [MESA_FORMAT_I8] = TMC_tformat_tw8a,
54 [MESA_FORMAT_CI8] = TMC_tformat_tw8 ,
55 [MESA_FORMAT_YCBCR] = TMC_tformat_tw422uyvy,
56 [MESA_FORMAT_YCBCR_REV] = TMC_tformat_tw422,
61 mgaSetTexImages( mgaContextPtr mmesa,
62 const struct gl_texture_object * tObj )
64 mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData;
65 struct gl_texture_image *baseImage = tObj->Image[0][ tObj->BaseLevel ];
70 GLint log2Width, log2Height;
74 /* Set the hardware texture format
76 #ifndef MGA_USE_TABLE_FOR_FORMAT
77 switch (baseImage->TexFormat->MesaFormat) {
79 case MESA_FORMAT_ARGB8888: txformat = TMC_tformat_tw32; break;
80 case MESA_FORMAT_RGB565: txformat = TMC_tformat_tw16; break;
81 case MESA_FORMAT_ARGB4444: txformat = TMC_tformat_tw12; break;
82 case MESA_FORMAT_ARGB1555: txformat = TMC_tformat_tw15; break;
83 case MESA_FORMAT_AL88: txformat = TMC_tformat_tw8al; break;
84 case MESA_FORMAT_I8: txformat = TMC_tformat_tw8a; break;
85 case MESA_FORMAT_CI8: txformat = TMC_tformat_tw8; break;
86 case MESA_FORMAT_YCBCR: txformat = TMC_tformat_tw422uyvy; break;
87 case MESA_FORMAT_YCBCR_REV: txformat = TMC_tformat_tw422; break;
90 _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__);
94 if ( (baseImage->TexFormat >= TMC_nr_tformat)
95 || (TMC_tformat[ baseImage->TexFormat ] == 0) )
97 _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__);
101 txformat = TMC_tformat[ baseImage->TexFormat ];
103 #endif /* MGA_USE_TABLE_FOR_FORMAT */
105 driCalculateTextureFirstLastLevel( (driTextureObject *) t );
106 if (tObj->Target == GL_TEXTURE_RECTANGLE_NV) {
110 log2Width = tObj->Image[0][t->base.firstLevel]->WidthLog2;
111 log2Height = tObj->Image[0][t->base.firstLevel]->HeightLog2;
114 width = tObj->Image[0][t->base.firstLevel]->Width;
115 height = tObj->Image[0][t->base.firstLevel]->Height;
117 numLevels = MIN2( t->base.lastLevel - t->base.firstLevel + 1,
118 MGA_IS_G200(mmesa) ? G200_TEX_MAXLEVELS : G400_TEX_MAXLEVELS);
122 for ( i = 0 ; i < numLevels ; i++ ) {
123 const struct gl_texture_image * const texImage =
124 tObj->Image[0][ i + t->base.firstLevel ];
127 if (texImage == NULL)
130 size = texImage->Width * texImage->Height *
131 _mesa_get_format_bytes(baseImage->TexFormat);
133 t->offsets[i] = totalSize;
134 t->base.dirty_images[0] |= (1<<i);
136 /* All mipmaps must be 32-byte aligned */
137 totalSize += (size + 31) & ~31;
139 /* Since G400 calculates the offsets in hardware
140 * it can't handle more than one < 32 byte mipmap.
142 * Further testing has indicated that it can't
143 * handle any < 32 byte mipmaps.
145 if (MGA_IS_G400( mmesa ) && size <= 32) {
151 /* save these values */
153 t->base.lastLevel = t->base.firstLevel + numLevels - 1;
154 t->base.totalSize = totalSize;
156 /* setup hardware register values */
157 t->setup.texctl &= (TMC_tformat_MASK & TMC_tpitch_MASK
158 & TMC_tpitchext_MASK);
159 t->setup.texctl |= txformat;
162 /* Set the texture width. In order to support non-power of 2 textures and
163 * textures larger than 1024 texels wide, "linear" pitch must be used. For
164 * the linear pitch, if the width is 2048, a value of zero is used.
167 t->setup.texctl |= TMC_tpitchlin_enable;
168 t->setup.texctl |= MGA_FIELD( TMC_tpitchext, width & (2048 - 1) );
171 /* G400 specifies the number of mip levels in a strange way. Since there
172 * are up to 11 levels, it requires 4 bits. Three of the bits are at the
173 * high end of TEXFILTER. The other bit is in the middle. Weird.
176 t->setup.texfilter &= TF_mapnb_MASK & TF_mapnbhigh_MASK & TF_reserved_MASK;
177 t->setup.texfilter |= MGA_FIELD( TF_mapnb, numLevels & 0x7 );
178 t->setup.texfilter |= MGA_FIELD( TF_mapnbhigh, (numLevels >> 3) & 0x1 );
180 /* warp texture registers */
181 ofs = MGA_IS_G200(mmesa) ? 28 : 11;
183 t->setup.texwidth = (MGA_FIELD(TW_twmask, width - 1) |
184 MGA_FIELD(TW_rfw, (10 - log2Width - 8) & 63 ) |
185 MGA_FIELD(TW_tw, (log2Width + ofs ) | 0x40 ));
187 t->setup.texheight = (MGA_FIELD(TH_thmask, height - 1) |
188 MGA_FIELD(TH_rfh, (10 - log2Height - 8) & 63 ) |
189 MGA_FIELD(TH_th, (log2Height + ofs ) | 0x40 ));
191 mgaUploadTexImages( mmesa, t );
195 /* ================================================================
196 * Texture unit state management
199 static void mgaUpdateTextureEnvG200( struct gl_context *ctx, GLuint unit )
201 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
202 struct gl_texture_object *tObj = ctx->Texture.Unit[0]._Current;
203 mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData;
204 GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
206 if (tObj != ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX] &&
207 tObj != ctx->Texture.Unit[0].CurrentTex[TEXTURE_RECT_INDEX])
211 t->setup.texctl &= ~TMC_tmodulate_enable;
212 t->setup.texctl2 &= ~(TMC_decalblend_enable |
214 TMC_decaldis_enable);
216 switch (ctx->Texture.Unit[0].EnvMode) {
218 if (format == GL_ALPHA)
219 t->setup.texctl2 |= TMC_idecal_enable;
221 if (format == GL_RGB || format == GL_LUMINANCE)
222 mmesa->hw.alpha_sel = AC_alphasel_diffused;
224 mmesa->hw.alpha_sel = AC_alphasel_fromtex;
228 t->setup.texctl |= TMC_tmodulate_enable;
230 if (format == GL_ALPHA)
231 t->setup.texctl2 |= (TMC_idecal_enable |
232 TMC_decaldis_enable);
234 if (format == GL_RGB || format == GL_LUMINANCE)
235 mmesa->hw.alpha_sel = AC_alphasel_diffused;
237 mmesa->hw.alpha_sel = AC_alphasel_modulated;
241 if (format == GL_RGB || format == GL_RGBA)
242 t->setup.texctl2 |= TMC_decalblend_enable;
244 t->setup.texctl2 |= TMC_idecal_enable;
246 mmesa->hw.alpha_sel = AC_alphasel_diffused;
250 if (format == GL_ALPHA) {
251 t->setup.texctl2 |= TMC_idecal_enable;
252 mmesa->hw.alpha_sel = AC_alphasel_modulated;
254 t->texenv_fallback = GL_TRUE;
264 #define MGA_REPLACE 0
265 #define MGA_MODULATE 1
268 #define MGA_MAX_COMBFUNC 4
270 static const GLuint g400_color_combine[][MGA_MAX_COMBFUNC] =
279 (TD0_color_sel_arg1 |
280 TD0_alpha_arg2_diffuse |
287 (TD0_color_arg2_diffuse |
289 TD0_alpha_arg2_diffuse |
296 (TD0_color_sel_arg1 |
297 TD0_alpha_arg2_diffuse |
304 (TD0_color_arg2_diffuse |
307 TD0_alpha_arg2_diffuse |
318 (TD0_color_sel_arg1 |
319 TD0_alpha_arg2_prevstage |
326 (TD0_color_arg2_prevstage |
328 TD0_alpha_arg2_prevstage |
335 (TD0_color_sel_arg1 |
336 TD0_alpha_arg2_prevstage |
343 (TD0_color_arg2_prevstage |
346 TD0_alpha_arg2_prevstage |
351 static const GLuint g400_color_alpha_combine[][MGA_MAX_COMBFUNC] =
360 (TD0_color_sel_arg1 |
367 (TD0_color_arg2_diffuse |
369 TD0_alpha_arg2_diffuse |
373 * tmp = Cf ( 1 - As )
377 (TD0_color_arg2_diffuse |
378 TD0_color_alpha_currtex |
379 TD0_color_alpha1inv_enable |
380 TD0_color_arg1mul_alpha1 |
381 TD0_color_blend_enable |
382 TD0_color_arg1add_mulout |
383 TD0_color_arg2add_mulout |
386 TD0_alpha_arg2_diffuse |
393 (TD0_color_arg2_diffuse |
396 TD0_alpha_arg2_diffuse |
407 (TD0_color_sel_arg1 |
414 (TD0_color_arg2_prevstage |
416 TD0_alpha_arg2_prevstage |
420 * tmp = Cp ( 1 - As )
424 (TD0_color_arg2_prevstage |
425 TD0_color_alpha_currtex |
426 TD0_color_alpha1inv_enable |
427 TD0_color_arg1mul_alpha1 |
428 TD0_color_blend_enable |
429 TD0_color_arg1add_mulout |
430 TD0_color_arg2add_mulout |
433 TD0_alpha_arg2_prevstage |
440 (TD0_color_arg2_prevstage |
443 TD0_alpha_arg2_prevstage |
448 static const GLuint g400_alpha_combine[][MGA_MAX_COMBFUNC] =
457 (TD0_color_arg2_diffuse |
465 (TD0_color_arg2_diffuse |
467 TD0_alpha_arg2_diffuse |
470 /* GL_DECAL (undefined)
474 (TD0_color_arg2_diffuse |
476 TD0_alpha_arg2_diffuse |
483 (TD0_color_arg2_diffuse |
485 TD0_alpha_arg2_diffuse |
496 (TD0_color_arg2_prevstage |
504 (TD0_color_arg2_prevstage |
506 TD0_alpha_arg2_prevstage |
509 /* GL_DECAL (undefined)
513 (TD0_color_arg2_prevstage |
515 TD0_alpha_arg2_prevstage |
522 (TD0_color_arg2_prevstage |
524 TD0_alpha_arg2_prevstage |
529 static GLboolean mgaUpdateTextureEnvBlend( struct gl_context *ctx, int unit )
531 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
532 const int source = mmesa->tmu_source[unit];
533 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
534 const struct gl_texture_object *tObj = texUnit->_Current;
535 GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit);
536 GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
540 if (format == GL_ALPHA) {
542 *reg |= (TD0_color_arg2_diffuse |
545 *reg |= (TD0_alpha_arg2_diffuse |
550 /* C1 = Cf ( 1 - Cs ) */
551 *reg |= (TD0_color_arg1_inv_enable |
552 TD0_color_arg2_diffuse |
555 if (format == GL_RGB || format == GL_LUMINANCE) {
557 *reg |= (TD0_alpha_arg2_diffuse |
560 if (format == GL_RGBA || format == GL_LUMINANCE_ALPHA) {
562 *reg |= (TD0_alpha_arg2_diffuse |
565 if (format == GL_INTENSITY) {
566 /* A1 = Af ( 1 - As ) */
567 *reg |= (TD0_alpha_arg1_inv_enable |
568 TD0_alpha_arg2_diffuse |
572 if (RGB_ZERO(mmesa->envcolor[source]) &&
573 (format != GL_INTENSITY || ALPHA_ZERO(mmesa->envcolor[source])))
574 return GL_TRUE; /* all done */
576 if (ctx->Texture._EnabledUnits == 0x03)
577 return GL_FALSE; /* need both units */
579 mmesa->force_dualtex = GL_TRUE;
580 reg = &mmesa->setup.tdualstage1;
583 if (RGB_ZERO(mmesa->envcolor[source])) {
585 *reg |= (TD0_color_arg2_prevstage |
588 if (RGB_ONE(mmesa->envcolor[source])) {
590 *reg |= (TD0_color_arg2_prevstage |
594 if (RGBA_EQUAL(mmesa->envcolor[source])) {
595 /* Cv = C1 + Cc Cs */
596 *reg |= (TD0_color_arg2_prevstage |
597 TD0_color_alpha_fcol |
598 TD0_color_arg2mul_alpha2 |
599 TD0_color_arg1add_mulout |
603 mmesa->setup.fcol = mmesa->envcolor[source];
608 if (format != GL_INTENSITY || ALPHA_ZERO(mmesa->envcolor[source])) {
610 *reg |= (TD0_alpha_arg2_prevstage |
613 if (ALPHA_ONE(mmesa->envcolor[source])) {
615 *reg |= (TD0_alpha_arg2_prevstage |
616 TD0_alpha_add_enable |
625 static void mgaUpdateTextureEnvG400( struct gl_context *ctx, GLuint unit )
627 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
628 const int source = mmesa->tmu_source[unit];
629 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
630 const struct gl_texture_object *tObj = texUnit->_Current;
631 GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit);
632 mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData;
633 GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat;
635 if (tObj != ctx->Texture.Unit[source].CurrentTex[TEXTURE_2D_INDEX] &&
636 tObj != ctx->Texture.Unit[source].CurrentTex[TEXTURE_RECT_INDEX])
639 switch (ctx->Texture.Unit[source].EnvMode) {
641 if (format == GL_ALPHA) {
642 *reg = g400_alpha_combine[unit][MGA_REPLACE];
643 } else if (format == GL_RGB || format == GL_LUMINANCE) {
644 *reg = g400_color_combine[unit][MGA_REPLACE];
646 *reg = g400_color_alpha_combine[unit][MGA_REPLACE];
651 if (format == GL_ALPHA) {
652 *reg = g400_alpha_combine[unit][MGA_MODULATE];
653 } else if (format == GL_RGB || format == GL_LUMINANCE) {
654 *reg = g400_color_combine[unit][MGA_MODULATE];
656 *reg = g400_color_alpha_combine[unit][MGA_MODULATE];
661 if (format == GL_RGB) {
662 *reg = g400_color_combine[unit][MGA_DECAL];
663 } else if (format == GL_RGBA) {
664 *reg = g400_color_alpha_combine[unit][MGA_DECAL];
665 if (ctx->Texture._EnabledUnits != 0x03) {
666 /* Linear blending mode needs dual texturing enabled */
667 *(reg+1) = (TD0_color_arg2_prevstage |
669 TD0_alpha_arg2_prevstage |
671 mmesa->force_dualtex = GL_TRUE;
675 *reg = g400_alpha_combine[unit][MGA_DECAL];
680 if (format == GL_ALPHA) {
681 *reg = g400_alpha_combine[unit][MGA_ADD];
682 } else if (format == GL_RGB || format == GL_LUMINANCE) {
683 *reg = g400_color_combine[unit][MGA_ADD];
684 } else if (format == GL_RGBA || format == GL_LUMINANCE_ALPHA) {
685 *reg = g400_color_alpha_combine[unit][MGA_ADD];
686 } else if (format == GL_INTENSITY) {
691 *reg = (TD0_color_arg2_diffuse |
694 TD0_alpha_arg2_diffuse |
695 TD0_alpha_add_enable |
698 *reg = (TD0_color_arg2_prevstage |
701 TD0_alpha_arg2_prevstage |
702 TD0_alpha_add_enable |
709 if (!mgaUpdateTextureEnvBlend(ctx, unit))
710 t->texenv_fallback = GL_TRUE;
714 if (!mgaUpdateTextureEnvCombine(ctx, unit))
715 t->texenv_fallback = GL_TRUE;
722 static void disable_tex( struct gl_context *ctx, int unit )
724 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
726 /* Texture unit disabled */
728 if ( mmesa->CurrentTexObj[unit] != NULL ) {
729 /* The old texture is no longer bound to this texture unit.
733 mmesa->CurrentTexObj[unit]->base.bound &= ~(1UL << unit);
734 mmesa->CurrentTexObj[unit] = NULL;
737 if ( unit != 0 && !mmesa->force_dualtex ) {
738 mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0;
741 if ( ctx->Texture._EnabledUnits == 0 ) {
742 mmesa->setup.dwgctl &= DC_opcod_MASK;
743 mmesa->setup.dwgctl |= DC_opcod_trap;
744 mmesa->hw.alpha_sel = AC_alphasel_diffused;
747 mmesa->dirty |= MGA_UPLOAD_CONTEXT | (MGA_UPLOAD_TEX0 << unit);
750 static GLboolean enable_tex( struct gl_context *ctx, int unit )
752 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
753 const int source = mmesa->tmu_source[unit];
754 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
755 const struct gl_texture_object *tObj = texUnit->_Current;
756 mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData;
758 /* Upload teximages (not pipelined)
760 if (t->base.dirty_images[0]) {
761 FLUSH_BATCH( mmesa );
762 mgaSetTexImages( mmesa, tObj );
763 if ( t->base.memBlock == NULL ) {
771 static GLboolean update_tex_common( struct gl_context *ctx, int unit )
773 mgaContextPtr mmesa = MGA_CONTEXT(ctx);
774 const int source = mmesa->tmu_source[unit];
775 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
776 struct gl_texture_object *tObj = texUnit->_Current;
777 mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData;
779 /* Fallback if there's a texture border */
780 if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) {
785 /* Update state if this is a different texture object to last
788 if ( mmesa->CurrentTexObj[unit] != t ) {
789 if ( mmesa->CurrentTexObj[unit] != NULL ) {
790 /* The old texture is no longer bound to this texture unit.
794 mmesa->CurrentTexObj[unit]->base.bound &= ~(1UL << unit);
797 mmesa->CurrentTexObj[unit] = t;
798 t->base.bound |= (1UL << unit);
800 driUpdateTextureLRU( (driTextureObject *) t ); /* done too often */
805 mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0;
808 t->texenv_fallback = GL_FALSE;
810 /* Set this before mgaUpdateTextureEnvG400() since
811 * GL_ARB_texture_env_crossbar may have to disable texturing.
813 mmesa->setup.dwgctl &= DC_opcod_MASK;
814 mmesa->setup.dwgctl |= DC_opcod_texture_trap;
816 /* FIXME: The Radeon has some cached state so that it can avoid calling
817 * FIXME: UpdateTextureEnv in some cases. Is that possible here?
819 if (MGA_IS_G400(mmesa)) {
820 /* G400: Regardless of texture env mode, we use the alpha from the
821 * texture unit (AC_alphasel_fromtex) since it will have already
822 * been modulated by the incoming fragment color, if needed.
823 * We don't want (AC_alphasel_modulate) since that'll effectively
824 * do the modulation twice.
826 mmesa->hw.alpha_sel = AC_alphasel_fromtex;
828 mgaUpdateTextureEnvG400( ctx, unit );
830 mgaUpdateTextureEnvG200( ctx, unit );
833 t->setup.texctl2 &= TMC_dualtex_MASK;
834 if (ctx->Texture._EnabledUnits == 0x03 || mmesa->force_dualtex) {
835 t->setup.texctl2 |= TMC_dualtex_enable;
838 mmesa->dirty |= MGA_UPLOAD_CONTEXT | (MGA_UPLOAD_TEX0 << unit);
840 FALLBACK( ctx, MGA_FALLBACK_BORDER_MODE, t->border_fallback );
841 return !t->border_fallback && !t->texenv_fallback;
845 static GLboolean updateTextureUnit( struct gl_context *ctx, int unit )
847 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
848 const int source = mmesa->tmu_source[unit];
849 const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source];
852 if ( texUnit->_ReallyEnabled == TEXTURE_2D_BIT ||
853 texUnit->_ReallyEnabled == TEXTURE_RECT_BIT ) {
854 return(enable_tex( ctx, unit ) &&
855 update_tex_common( ctx, unit ));
857 else if ( texUnit->_ReallyEnabled ) {
861 disable_tex( ctx, unit );
866 /* The G400 is now programmed quite differently wrt texture environment.
868 void mgaUpdateTextureState( struct gl_context *ctx )
870 mgaContextPtr mmesa = MGA_CONTEXT( ctx );
874 mmesa->force_dualtex = GL_FALSE;
875 mmesa->fcol_used = GL_FALSE;
877 /* This works around a quirk with the MGA hardware. If only OpenGL
878 * TEXTURE1 is enabled, then the hardware TEXTURE0 must be used. The
879 * hardware TEXTURE1 can ONLY be used when hardware TEXTURE0 is also used.
882 mmesa->tmu_source[0] = 0;
883 mmesa->tmu_source[1] = 1;
885 if ((ctx->Texture._EnabledUnits & 0x03) == 0x02) {
886 /* only texture 1 enabled */
887 mmesa->tmu_source[0] = 1;
888 mmesa->tmu_source[1] = 0;
891 for ( i = 0, ok = GL_TRUE
892 ; (i < ctx->Const.MaxTextureUnits) && ok
894 ok = updateTextureUnit( ctx, i );
897 FALLBACK( ctx, MGA_FALLBACK_TEXTURE, !ok );