texstate.c revision 7e995a2e
17117f1b4Smrg/*
27117f1b4Smrg * Mesa 3-D graphics library
37117f1b4Smrg *
47117f1b4Smrg * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
57117f1b4Smrg *
67117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a
77117f1b4Smrg * copy of this software and associated documentation files (the "Software"),
87117f1b4Smrg * to deal in the Software without restriction, including without limitation
97117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
107117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the
117117f1b4Smrg * Software is furnished to do so, subject to the following conditions:
127117f1b4Smrg *
137117f1b4Smrg * The above copyright notice and this permission notice shall be included
147117f1b4Smrg * in all copies or substantial portions of the Software.
157117f1b4Smrg *
167117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
177117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
187117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19b167d5e7Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20b167d5e7Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21b167d5e7Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22b167d5e7Smrg * OTHER DEALINGS IN THE SOFTWARE.
237117f1b4Smrg */
247117f1b4Smrg
257e995a2eSmrg/**
267117f1b4Smrg * \file texstate.c
277117f1b4Smrg *
287117f1b4Smrg * Texture state handling.
297117f1b4Smrg */
307117f1b4Smrg
317e995a2eSmrg#include <stdio.h>
327117f1b4Smrg#include "glheader.h"
33ac997013Sriastradh#include "bufferobj.h"
347117f1b4Smrg#include "context.h"
357117f1b4Smrg#include "enums.h"
367117f1b4Smrg#include "macros.h"
377117f1b4Smrg#include "texobj.h"
387117f1b4Smrg#include "teximage.h"
397117f1b4Smrg#include "texstate.h"
407117f1b4Smrg#include "mtypes.h"
417e995a2eSmrg#include "state.h"
427e995a2eSmrg#include "util/bitscan.h"
437e995a2eSmrg#include "util/bitset.h"
447117f1b4Smrg
457117f1b4Smrg
467117f1b4Smrg/**
477117f1b4Smrg * Default texture combine environment state.  This is used to initialize
487117f1b4Smrg * a context's texture units and as the basis for converting "classic"
497117f1b4Smrg * texture environmnets to ARB_texture_env_combine style values.
507117f1b4Smrg */
517117f1b4Smrgstatic const struct gl_tex_env_combine_state default_combine_state = {
527117f1b4Smrg   GL_MODULATE, GL_MODULATE,
5356e89960Smrg   { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT, GL_CONSTANT },
5456e89960Smrg   { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT, GL_CONSTANT },
5556e89960Smrg   { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA, GL_SRC_ALPHA },
5656e89960Smrg   { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA },
577117f1b4Smrg   0, 0,
587117f1b4Smrg   2, 2
597117f1b4Smrg};
607117f1b4Smrg
617117f1b4Smrg
627117f1b4Smrg
637117f1b4Smrg/**
647117f1b4Smrg * Used by glXCopyContext to copy texture state from one context to another.
657117f1b4Smrg */
667117f1b4Smrgvoid
67ac997013Sriastradh_mesa_copy_texture_state( const struct gl_context *src, struct gl_context *dst )
687117f1b4Smrg{
6956e89960Smrg   GLuint u, tex;
707117f1b4Smrg
717e995a2eSmrg   assert(src);
727e995a2eSmrg   assert(dst);
737117f1b4Smrg
747117f1b4Smrg   dst->Texture.CurrentUnit = src->Texture.CurrentUnit;
757117f1b4Smrg   dst->Texture._GenFlags = src->Texture._GenFlags;
767117f1b4Smrg   dst->Texture._TexGenEnabled = src->Texture._TexGenEnabled;
777117f1b4Smrg   dst->Texture._TexMatEnabled = src->Texture._TexMatEnabled;
787117f1b4Smrg
797117f1b4Smrg   /* per-unit state */
801f16d945Smrg   for (u = 0; u < src->Const.MaxCombinedTextureImageUnits; u++) {
8156e89960Smrg      dst->Texture.Unit[u].LodBias = src->Texture.Unit[u].LodBias;
827117f1b4Smrg
8356e89960Smrg      /*
8456e89960Smrg       * XXX strictly speaking, we should compare texture names/ids and
8556e89960Smrg       * bind textures in the dest context according to id.  For now, only
8656e89960Smrg       * copy bindings if the contexts share the same pool of textures to
8756e89960Smrg       * avoid refcounting bugs.
8856e89960Smrg       */
8956e89960Smrg      if (dst->Shared == src->Shared) {
9056e89960Smrg         /* copy texture object bindings, not contents of texture objects */
9156e89960Smrg         _mesa_lock_context_textures(dst);
927117f1b4Smrg
9356e89960Smrg         for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
9456e89960Smrg            _mesa_reference_texobj(&dst->Texture.Unit[u].CurrentTex[tex],
9556e89960Smrg                                   src->Texture.Unit[u].CurrentTex[tex]);
96b167d5e7Smrg            if (src->Texture.Unit[u].CurrentTex[tex]) {
97b167d5e7Smrg               dst->Texture.NumCurrentTexUsed =
98b167d5e7Smrg                  MAX2(dst->Texture.NumCurrentTexUsed, u + 1);
99b167d5e7Smrg            }
10056e89960Smrg         }
101b167d5e7Smrg         dst->Texture.Unit[u]._BoundTextures = src->Texture.Unit[u]._BoundTextures;
10256e89960Smrg         _mesa_unlock_context_textures(dst);
10356e89960Smrg      }
1047117f1b4Smrg   }
1057e995a2eSmrg
1067e995a2eSmrg   for (u = 0; u < src->Const.MaxTextureCoordUnits; u++) {
1077e995a2eSmrg      dst->Texture.FixedFuncUnit[u].Enabled = src->Texture.FixedFuncUnit[u].Enabled;
1087e995a2eSmrg      dst->Texture.FixedFuncUnit[u].EnvMode = src->Texture.FixedFuncUnit[u].EnvMode;
1097e995a2eSmrg      COPY_4V(dst->Texture.FixedFuncUnit[u].EnvColor, src->Texture.FixedFuncUnit[u].EnvColor);
1107e995a2eSmrg      dst->Texture.FixedFuncUnit[u].TexGenEnabled = src->Texture.FixedFuncUnit[u].TexGenEnabled;
1117e995a2eSmrg      dst->Texture.FixedFuncUnit[u].GenS = src->Texture.FixedFuncUnit[u].GenS;
1127e995a2eSmrg      dst->Texture.FixedFuncUnit[u].GenT = src->Texture.FixedFuncUnit[u].GenT;
1137e995a2eSmrg      dst->Texture.FixedFuncUnit[u].GenR = src->Texture.FixedFuncUnit[u].GenR;
1147e995a2eSmrg      dst->Texture.FixedFuncUnit[u].GenQ = src->Texture.FixedFuncUnit[u].GenQ;
1157e995a2eSmrg
1167e995a2eSmrg      /* GL_EXT_texture_env_combine */
1177e995a2eSmrg      dst->Texture.FixedFuncUnit[u].Combine = src->Texture.FixedFuncUnit[u].Combine;
1187e995a2eSmrg   }
1197117f1b4Smrg}
1207117f1b4Smrg
1217117f1b4Smrg
1227117f1b4Smrg/*
1237117f1b4Smrg * For debugging
1247117f1b4Smrg */
1257117f1b4Smrgvoid
126ac997013Sriastradh_mesa_print_texunit_state( struct gl_context *ctx, GLuint unit )
1277117f1b4Smrg{
1287e995a2eSmrg   const struct gl_fixedfunc_texture_unit *texUnit = ctx->Texture.FixedFuncUnit + unit;
1291f16d945Smrg   printf("Texture Unit %d\n", unit);
1307e995a2eSmrg   printf("  GL_TEXTURE_ENV_MODE = %s\n", _mesa_enum_to_string(texUnit->EnvMode));
1317e995a2eSmrg   printf("  GL_COMBINE_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.ModeRGB));
1327e995a2eSmrg   printf("  GL_COMBINE_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.ModeA));
1337e995a2eSmrg   printf("  GL_SOURCE0_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceRGB[0]));
1347e995a2eSmrg   printf("  GL_SOURCE1_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceRGB[1]));
1357e995a2eSmrg   printf("  GL_SOURCE2_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceRGB[2]));
1367e995a2eSmrg   printf("  GL_SOURCE0_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceA[0]));
1377e995a2eSmrg   printf("  GL_SOURCE1_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceA[1]));
1387e995a2eSmrg   printf("  GL_SOURCE2_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceA[2]));
1397e995a2eSmrg   printf("  GL_OPERAND0_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandRGB[0]));
1407e995a2eSmrg   printf("  GL_OPERAND1_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandRGB[1]));
1417e995a2eSmrg   printf("  GL_OPERAND2_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandRGB[2]));
1427e995a2eSmrg   printf("  GL_OPERAND0_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandA[0]));
1437e995a2eSmrg   printf("  GL_OPERAND1_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandA[1]));
1447e995a2eSmrg   printf("  GL_OPERAND2_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandA[2]));
1451f16d945Smrg   printf("  GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB);
1461f16d945Smrg   printf("  GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA);
1471f16d945Smrg   printf("  GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit->EnvColor[0], texUnit->EnvColor[1], texUnit->EnvColor[2], texUnit->EnvColor[3]);
148c1f859d4Smrg}
1497117f1b4Smrg
1507117f1b4Smrg
1517117f1b4Smrg
152c1f859d4Smrg/**********************************************************************/
153c1f859d4Smrg/*                       Texture Environment                          */
154c1f859d4Smrg/**********************************************************************/
1557117f1b4Smrg
156c1f859d4Smrg/**
157c1f859d4Smrg * Convert "classic" texture environment to ARB_texture_env_combine style
158c1f859d4Smrg * environments.
1597e995a2eSmrg *
160c1f859d4Smrg * \param state  texture_env_combine state vector to be filled-in.
161c1f859d4Smrg * \param mode   Classic texture environment mode (i.e., \c GL_REPLACE,
162c1f859d4Smrg *               \c GL_BLEND, \c GL_DECAL, etc.).
163c1f859d4Smrg * \param texBaseFormat  Base format of the texture associated with the
164c1f859d4Smrg *               texture unit.
165c1f859d4Smrg */
166c1f859d4Smrgstatic void
167c1f859d4Smrgcalculate_derived_texenv( struct gl_tex_env_combine_state *state,
168c1f859d4Smrg			  GLenum mode, GLenum texBaseFormat )
169c1f859d4Smrg{
170c1f859d4Smrg   GLenum mode_rgb;
171c1f859d4Smrg   GLenum mode_a;
1727117f1b4Smrg
173c1f859d4Smrg   *state = default_combine_state;
1747117f1b4Smrg
175c1f859d4Smrg   switch (texBaseFormat) {
176c1f859d4Smrg   case GL_ALPHA:
177c1f859d4Smrg      state->SourceRGB[0] = GL_PREVIOUS;
178c1f859d4Smrg      break;
1797117f1b4Smrg
180c1f859d4Smrg   case GL_LUMINANCE_ALPHA:
181c1f859d4Smrg   case GL_INTENSITY:
182c1f859d4Smrg   case GL_RGBA:
183c1f859d4Smrg      break;
1847117f1b4Smrg
185c1f859d4Smrg   case GL_LUMINANCE:
186ac997013Sriastradh   case GL_RED:
187ac997013Sriastradh   case GL_RG:
188c1f859d4Smrg   case GL_RGB:
189c1f859d4Smrg   case GL_YCBCR_MESA:
190c1f859d4Smrg      state->SourceA[0] = GL_PREVIOUS;
191c1f859d4Smrg      break;
1927e995a2eSmrg
193c1f859d4Smrg   default:
19456e89960Smrg      _mesa_problem(NULL,
19556e89960Smrg                    "Invalid texBaseFormat 0x%x in calculate_derived_texenv",
19656e89960Smrg                    texBaseFormat);
1977117f1b4Smrg      return;
1987117f1b4Smrg   }
1997117f1b4Smrg
200c1f859d4Smrg   if (mode == GL_REPLACE_EXT)
201c1f859d4Smrg      mode = GL_REPLACE;
2027117f1b4Smrg
203c1f859d4Smrg   switch (mode) {
204c1f859d4Smrg   case GL_REPLACE:
205c1f859d4Smrg   case GL_MODULATE:
206c1f859d4Smrg      mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : mode;
207c1f859d4Smrg      mode_a   = mode;
208c1f859d4Smrg      break;
2097e995a2eSmrg
210c1f859d4Smrg   case GL_DECAL:
211c1f859d4Smrg      mode_rgb = GL_INTERPOLATE;
212c1f859d4Smrg      mode_a   = GL_REPLACE;
213c1f859d4Smrg
214c1f859d4Smrg      state->SourceA[0] = GL_PREVIOUS;
215c1f859d4Smrg
216c1f859d4Smrg      /* Having alpha / luminance / intensity textures replace using the
217c1f859d4Smrg       * incoming fragment color matches the definition in NV_texture_shader.
218c1f859d4Smrg       * The 1.5 spec simply marks these as "undefined".
219c1f859d4Smrg       */
220c1f859d4Smrg      switch (texBaseFormat) {
221c1f859d4Smrg      case GL_ALPHA:
222c1f859d4Smrg      case GL_LUMINANCE:
223c1f859d4Smrg      case GL_LUMINANCE_ALPHA:
224c1f859d4Smrg      case GL_INTENSITY:
225c1f859d4Smrg	 state->SourceRGB[0] = GL_PREVIOUS;
2267117f1b4Smrg	 break;
227ac997013Sriastradh      case GL_RED:
228ac997013Sriastradh      case GL_RG:
229c1f859d4Smrg      case GL_RGB:
230c1f859d4Smrg      case GL_YCBCR_MESA:
231c1f859d4Smrg	 mode_rgb = GL_REPLACE;
2327117f1b4Smrg	 break;
233c1f859d4Smrg      case GL_RGBA:
234c1f859d4Smrg	 state->SourceRGB[2] = GL_TEXTURE;
2357117f1b4Smrg	 break;
236c1f859d4Smrg      }
237c1f859d4Smrg      break;
2387117f1b4Smrg
239c1f859d4Smrg   case GL_BLEND:
240c1f859d4Smrg      mode_rgb = GL_INTERPOLATE;
241c1f859d4Smrg      mode_a   = GL_MODULATE;
2427117f1b4Smrg
243c1f859d4Smrg      switch (texBaseFormat) {
244c1f859d4Smrg      case GL_ALPHA:
245c1f859d4Smrg	 mode_rgb = GL_REPLACE;
246c1f859d4Smrg	 break;
247c1f859d4Smrg      case GL_INTENSITY:
248c1f859d4Smrg	 mode_a = GL_INTERPOLATE;
249c1f859d4Smrg	 state->SourceA[0] = GL_CONSTANT;
250c1f859d4Smrg	 state->OperandA[2] = GL_SRC_ALPHA;
251c1f859d4Smrg	 /* FALLTHROUGH */
252c1f859d4Smrg      case GL_LUMINANCE:
253ac997013Sriastradh      case GL_RED:
254ac997013Sriastradh      case GL_RG:
255c1f859d4Smrg      case GL_RGB:
256c1f859d4Smrg      case GL_LUMINANCE_ALPHA:
257c1f859d4Smrg      case GL_RGBA:
258c1f859d4Smrg      case GL_YCBCR_MESA:
259c1f859d4Smrg	 state->SourceRGB[2] = GL_TEXTURE;
260c1f859d4Smrg	 state->SourceA[2]   = GL_TEXTURE;
261c1f859d4Smrg	 state->SourceRGB[0] = GL_CONSTANT;
262c1f859d4Smrg	 state->OperandRGB[2] = GL_SRC_COLOR;
263c1f859d4Smrg	 break;
264c1f859d4Smrg      }
265c1f859d4Smrg      break;
2667117f1b4Smrg
267c1f859d4Smrg   case GL_ADD:
268c1f859d4Smrg      mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : GL_ADD;
269c1f859d4Smrg      mode_a   = (texBaseFormat == GL_INTENSITY) ? GL_ADD : GL_MODULATE;
270c1f859d4Smrg      break;
2717117f1b4Smrg
272c1f859d4Smrg   default:
273c1f859d4Smrg      _mesa_problem(NULL,
27456e89960Smrg                    "Invalid texture env mode 0x%x in calculate_derived_texenv",
27556e89960Smrg                    mode);
2767117f1b4Smrg      return;
2777117f1b4Smrg   }
2787e995a2eSmrg
279c1f859d4Smrg   state->ModeRGB = (state->SourceRGB[0] != GL_PREVIOUS)
280c1f859d4Smrg       ? mode_rgb : GL_REPLACE;
281c1f859d4Smrg   state->ModeA   = (state->SourceA[0]   != GL_PREVIOUS)
282c1f859d4Smrg       ? mode_a   : GL_REPLACE;
283c1f859d4Smrg}
2847117f1b4Smrg
2857117f1b4Smrg
2867117f1b4Smrg/* GL_ARB_multitexture */
2877e995a2eSmrgstatic ALWAYS_INLINE void
2887e995a2eSmrgactive_texture(GLenum texture, bool no_error)
2897117f1b4Smrg{
2907117f1b4Smrg   const GLuint texUnit = texture - GL_TEXTURE0;
2911f16d945Smrg
2927e995a2eSmrg   GET_CURRENT_CONTEXT(ctx);
2937117f1b4Smrg
2947117f1b4Smrg   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2957117f1b4Smrg      _mesa_debug(ctx, "glActiveTexture %s\n",
2967e995a2eSmrg                  _mesa_enum_to_string(texture));
2977117f1b4Smrg
2987e995a2eSmrg   if (ctx->Texture.CurrentUnit == texUnit)
2997117f1b4Smrg      return;
3007e995a2eSmrg
3017e995a2eSmrg   if (!no_error) {
3027e995a2eSmrg      GLuint k = _mesa_max_tex_unit(ctx);
3037e995a2eSmrg
3047e995a2eSmrg      assert(k <= ARRAY_SIZE(ctx->Texture.Unit));
3057e995a2eSmrg
3067e995a2eSmrg      if (texUnit >= k) {
3077e995a2eSmrg         _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture=%s)",
3087e995a2eSmrg                     _mesa_enum_to_string(texture));
3097e995a2eSmrg         return;
3107e995a2eSmrg      }
3117117f1b4Smrg   }
3127117f1b4Smrg
3137117f1b4Smrg
3147e995a2eSmrg   /* The below flush call seems useless because
3157e995a2eSmrg    * gl_context::Texture::CurrentUnit is not used by
3167e995a2eSmrg    * _mesa_update_texture_state() and friends.
3177e995a2eSmrg    *
3187e995a2eSmrg    * However removing the flush
3197e995a2eSmrg    * introduced some blinking textures in UT2004. More investigation is
3207e995a2eSmrg    * needed to find the root cause.
3217e995a2eSmrg    *
3227e995a2eSmrg    * https://bugs.freedesktop.org/show_bug.cgi?id=105436
3237e995a2eSmrg    */
3247e995a2eSmrg   FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE);
3257117f1b4Smrg
3267117f1b4Smrg   ctx->Texture.CurrentUnit = texUnit;
3277117f1b4Smrg   if (ctx->Transform.MatrixMode == GL_TEXTURE) {
3287117f1b4Smrg      /* update current stack pointer */
3297117f1b4Smrg      ctx->CurrentStack = &ctx->TextureMatrixStack[texUnit];
3307117f1b4Smrg   }
3317117f1b4Smrg}
3327117f1b4Smrg
3337117f1b4Smrg
3347e995a2eSmrgvoid GLAPIENTRY
3357e995a2eSmrg_mesa_ActiveTexture_no_error(GLenum texture)
3367e995a2eSmrg{
3377e995a2eSmrg   active_texture(texture, true);
3387e995a2eSmrg}
3397e995a2eSmrg
3407e995a2eSmrg
3417e995a2eSmrgvoid GLAPIENTRY
3427e995a2eSmrg_mesa_ActiveTexture(GLenum texture)
3437e995a2eSmrg{
3447e995a2eSmrg   active_texture(texture, false);
3457e995a2eSmrg}
3467e995a2eSmrg
3477e995a2eSmrg
3487117f1b4Smrg/* GL_ARB_multitexture */
3497117f1b4Smrgvoid GLAPIENTRY
350b167d5e7Smrg_mesa_ClientActiveTexture(GLenum texture)
3517117f1b4Smrg{
3527117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
3537117f1b4Smrg   GLuint texUnit = texture - GL_TEXTURE0;
3547117f1b4Smrg
35556e89960Smrg   if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE))
35656e89960Smrg      _mesa_debug(ctx, "glClientActiveTexture %s\n",
3577e995a2eSmrg                  _mesa_enum_to_string(texture));
35856e89960Smrg
3597e995a2eSmrg   if (ctx->Array.ActiveTexture == texUnit)
3607117f1b4Smrg      return;
3617117f1b4Smrg
3627e995a2eSmrg   if (texUnit >= ctx->Const.MaxTextureCoordUnits) {
3637e995a2eSmrg      _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(texture=%s)",
3647e995a2eSmrg                  _mesa_enum_to_string(texture));
36556e89960Smrg      return;
3667e995a2eSmrg   }
36756e89960Smrg
3687e995a2eSmrg   /* Don't flush vertices. This is a "latched" state. */
3697117f1b4Smrg   ctx->Array.ActiveTexture = texUnit;
3707117f1b4Smrg}
3717117f1b4Smrg
3727117f1b4Smrg
3737117f1b4Smrg
3747117f1b4Smrg/**********************************************************************/
3757117f1b4Smrg/*****                    State management                        *****/
3767117f1b4Smrg/**********************************************************************/
3777117f1b4Smrg
3787117f1b4Smrg
3797117f1b4Smrg/**
3807117f1b4Smrg * \note This routine refers to derived texture attribute values to
3817117f1b4Smrg * compute the ENABLE_TEXMAT flags, but is only called on
3827e995a2eSmrg * _NEW_TEXTURE_MATRIX.  On changes to _NEW_TEXTURE_OBJECT/STATE,
3837e995a2eSmrg * the ENABLE_TEXMAT flags are updated by _mesa_update_textures(), below.
3847117f1b4Smrg *
3857117f1b4Smrg * \param ctx GL context.
3867117f1b4Smrg */
3877e995a2eSmrgvoid
3887e995a2eSmrg_mesa_update_texture_matrices(struct gl_context *ctx)
3897117f1b4Smrg{
39056e89960Smrg   GLuint u;
3917117f1b4Smrg
39256e89960Smrg   ctx->Texture._TexMatEnabled = 0x0;
3937117f1b4Smrg
39456e89960Smrg   for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
3957e995a2eSmrg      assert(u < ARRAY_SIZE(ctx->TextureMatrixStack));
39656e89960Smrg      if (_math_matrix_is_dirty(ctx->TextureMatrixStack[u].Top)) {
39756e89960Smrg	 _math_matrix_analyse( ctx->TextureMatrixStack[u].Top );
3987117f1b4Smrg
399b167d5e7Smrg	 if (ctx->Texture.Unit[u]._Current &&
40056e89960Smrg	     ctx->TextureMatrixStack[u].Top->type != MATRIX_IDENTITY)
40156e89960Smrg	    ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(u);
4027117f1b4Smrg      }
4037117f1b4Smrg   }
4047117f1b4Smrg}
4057117f1b4Smrg
4067117f1b4Smrg
4077e995a2eSmrg/**
4087e995a2eSmrg * Translate GL combiner state into a MODE_x value
4097e995a2eSmrg */
4107e995a2eSmrgstatic uint32_t
4117e995a2eSmrgtex_combine_translate_mode(GLenum envMode, GLenum mode)
4127e995a2eSmrg{
4137e995a2eSmrg   switch (mode) {
4147e995a2eSmrg   case GL_REPLACE: return TEXENV_MODE_REPLACE;
4157e995a2eSmrg   case GL_MODULATE: return TEXENV_MODE_MODULATE;
4167e995a2eSmrg   case GL_ADD:
4177e995a2eSmrg      if (envMode == GL_COMBINE4_NV)
4187e995a2eSmrg	 return TEXENV_MODE_ADD_PRODUCTS_NV;
4197e995a2eSmrg      else
4207e995a2eSmrg	 return TEXENV_MODE_ADD;
4217e995a2eSmrg   case GL_ADD_SIGNED:
4227e995a2eSmrg      if (envMode == GL_COMBINE4_NV)
4237e995a2eSmrg	 return TEXENV_MODE_ADD_PRODUCTS_SIGNED_NV;
4247e995a2eSmrg      else
4257e995a2eSmrg	 return TEXENV_MODE_ADD_SIGNED;
4267e995a2eSmrg   case GL_INTERPOLATE: return TEXENV_MODE_INTERPOLATE;
4277e995a2eSmrg   case GL_SUBTRACT: return TEXENV_MODE_SUBTRACT;
4287e995a2eSmrg   case GL_DOT3_RGB: return TEXENV_MODE_DOT3_RGB;
4297e995a2eSmrg   case GL_DOT3_RGB_EXT: return TEXENV_MODE_DOT3_RGB_EXT;
4307e995a2eSmrg   case GL_DOT3_RGBA: return TEXENV_MODE_DOT3_RGBA;
4317e995a2eSmrg   case GL_DOT3_RGBA_EXT: return TEXENV_MODE_DOT3_RGBA_EXT;
4327e995a2eSmrg   case GL_MODULATE_ADD_ATI: return TEXENV_MODE_MODULATE_ADD_ATI;
4337e995a2eSmrg   case GL_MODULATE_SIGNED_ADD_ATI: return TEXENV_MODE_MODULATE_SIGNED_ADD_ATI;
4347e995a2eSmrg   case GL_MODULATE_SUBTRACT_ATI: return TEXENV_MODE_MODULATE_SUBTRACT_ATI;
4357e995a2eSmrg   default:
4367e995a2eSmrg      unreachable("Invalid TexEnv Combine mode");
4377e995a2eSmrg   }
4387e995a2eSmrg}
4397e995a2eSmrg
4407e995a2eSmrg
4417e995a2eSmrgstatic uint8_t
4427e995a2eSmrgtex_combine_translate_source(GLenum src)
4437e995a2eSmrg{
4447e995a2eSmrg   switch (src) {
4457e995a2eSmrg   case GL_TEXTURE0:
4467e995a2eSmrg   case GL_TEXTURE1:
4477e995a2eSmrg   case GL_TEXTURE2:
4487e995a2eSmrg   case GL_TEXTURE3:
4497e995a2eSmrg   case GL_TEXTURE4:
4507e995a2eSmrg   case GL_TEXTURE5:
4517e995a2eSmrg   case GL_TEXTURE6:
4527e995a2eSmrg   case GL_TEXTURE7: return TEXENV_SRC_TEXTURE0 + (src - GL_TEXTURE0);
4537e995a2eSmrg   case GL_TEXTURE: return TEXENV_SRC_TEXTURE;
4547e995a2eSmrg   case GL_PREVIOUS: return TEXENV_SRC_PREVIOUS;
4557e995a2eSmrg   case GL_PRIMARY_COLOR: return TEXENV_SRC_PRIMARY_COLOR;
4567e995a2eSmrg   case GL_CONSTANT: return TEXENV_SRC_CONSTANT;
4577e995a2eSmrg   case GL_ZERO: return TEXENV_SRC_ZERO;
4587e995a2eSmrg   case GL_ONE: return TEXENV_SRC_ONE;
4597e995a2eSmrg   default:
4607e995a2eSmrg      unreachable("Invalid TexEnv Combine argument source");
4617e995a2eSmrg   }
4627e995a2eSmrg}
4637e995a2eSmrg
4647e995a2eSmrg
4657e995a2eSmrgstatic uint8_t
4667e995a2eSmrgtex_combine_translate_operand(GLenum operand)
4677e995a2eSmrg{
4687e995a2eSmrg   switch (operand) {
4697e995a2eSmrg   case GL_SRC_COLOR: return TEXENV_OPR_COLOR;
4707e995a2eSmrg   case GL_ONE_MINUS_SRC_COLOR: return TEXENV_OPR_ONE_MINUS_COLOR;
4717e995a2eSmrg   case GL_SRC_ALPHA: return TEXENV_OPR_ALPHA;
4727e995a2eSmrg   case GL_ONE_MINUS_SRC_ALPHA: return TEXENV_OPR_ONE_MINUS_ALPHA;
4737e995a2eSmrg   default:
4747e995a2eSmrg      unreachable("Invalid TexEnv Combine argument source");
4757e995a2eSmrg   }
4767e995a2eSmrg}
4777e995a2eSmrg
4787e995a2eSmrg
4797e995a2eSmrgstatic void
4807e995a2eSmrgpack_tex_combine(struct gl_fixedfunc_texture_unit *texUnit)
4817e995a2eSmrg{
4827e995a2eSmrg   struct gl_tex_env_combine_state *state = texUnit->_CurrentCombine;
4837e995a2eSmrg   struct gl_tex_env_combine_packed *packed = &texUnit->_CurrentCombinePacked;
4847e995a2eSmrg
4857e995a2eSmrg   memset(packed, 0, sizeof *packed);
4867e995a2eSmrg
4877e995a2eSmrg   packed->ModeRGB = tex_combine_translate_mode(texUnit->EnvMode, state->ModeRGB);
4887e995a2eSmrg   packed->ModeA = tex_combine_translate_mode(texUnit->EnvMode, state->ModeA);
4897e995a2eSmrg   packed->ScaleShiftRGB = state->ScaleShiftRGB;
4907e995a2eSmrg   packed->ScaleShiftA = state->ScaleShiftA;
4917e995a2eSmrg   packed->NumArgsRGB = state->_NumArgsRGB;
4927e995a2eSmrg   packed->NumArgsA = state->_NumArgsA;
4937e995a2eSmrg
4947e995a2eSmrg   for (int i = 0; i < state->_NumArgsRGB; ++i)
4957e995a2eSmrg   {
4967e995a2eSmrg      packed->ArgsRGB[i].Source = tex_combine_translate_source(state->SourceRGB[i]);
4977e995a2eSmrg      packed->ArgsRGB[i].Operand = tex_combine_translate_operand(state->OperandRGB[i]);
4987e995a2eSmrg   }
4997e995a2eSmrg
5007e995a2eSmrg   for (int i = 0; i < state->_NumArgsA; ++i)
5017e995a2eSmrg   {
5027e995a2eSmrg      packed->ArgsA[i].Source = tex_combine_translate_source(state->SourceA[i]);
5037e995a2eSmrg      packed->ArgsA[i].Operand = tex_combine_translate_operand(state->OperandA[i]);
5047e995a2eSmrg   }
5057e995a2eSmrg}
5067e995a2eSmrg
5077e995a2eSmrg
508c1f859d4Smrg/**
50956e89960Smrg * Examine texture unit's combine/env state to update derived state.
510c1f859d4Smrg */
511c1f859d4Smrgstatic void
5127e995a2eSmrgupdate_tex_combine(struct gl_context *ctx,
5137e995a2eSmrg                   struct gl_texture_unit *texUnit,
5147e995a2eSmrg                   struct gl_fixedfunc_texture_unit *fftexUnit)
515c1f859d4Smrg{
51656e89960Smrg   struct gl_tex_env_combine_state *combine;
51756e89960Smrg
518b167d5e7Smrg   /* No combiners will apply to this. */
519b167d5e7Smrg   if (texUnit->_Current->Target == GL_TEXTURE_BUFFER)
520b167d5e7Smrg      return;
521b167d5e7Smrg
52256e89960Smrg   /* Set the texUnit->_CurrentCombine field to point to the user's combiner
52356e89960Smrg    * state, or the combiner state which is derived from traditional texenv
52456e89960Smrg    * mode.
525c1f859d4Smrg    */
5267e995a2eSmrg   if (fftexUnit->EnvMode == GL_COMBINE ||
5277e995a2eSmrg       fftexUnit->EnvMode == GL_COMBINE4_NV) {
5287e995a2eSmrg      fftexUnit->_CurrentCombine = & fftexUnit->Combine;
529c1f859d4Smrg   }
53056e89960Smrg   else {
53156e89960Smrg      const struct gl_texture_object *texObj = texUnit->_Current;
53256e89960Smrg      GLenum format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
533b167d5e7Smrg
534b167d5e7Smrg      if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
535b167d5e7Smrg         format = texObj->DepthMode;
536c1f859d4Smrg      }
5377e995a2eSmrg      calculate_derived_texenv(&fftexUnit->_EnvMode, fftexUnit->EnvMode, format);
5387e995a2eSmrg      fftexUnit->_CurrentCombine = & fftexUnit->_EnvMode;
539c1f859d4Smrg   }
540c1f859d4Smrg
5417e995a2eSmrg   combine = fftexUnit->_CurrentCombine;
542c1f859d4Smrg
54356e89960Smrg   /* Determine number of source RGB terms in the combiner function */
54456e89960Smrg   switch (combine->ModeRGB) {
54556e89960Smrg   case GL_REPLACE:
54656e89960Smrg      combine->_NumArgsRGB = 1;
54756e89960Smrg      break;
54856e89960Smrg   case GL_ADD:
54956e89960Smrg   case GL_ADD_SIGNED:
5507e995a2eSmrg      if (fftexUnit->EnvMode == GL_COMBINE4_NV)
55156e89960Smrg         combine->_NumArgsRGB = 4;
55256e89960Smrg      else
55356e89960Smrg         combine->_NumArgsRGB = 2;
55456e89960Smrg      break;
55556e89960Smrg   case GL_MODULATE:
55656e89960Smrg   case GL_SUBTRACT:
55756e89960Smrg   case GL_DOT3_RGB:
55856e89960Smrg   case GL_DOT3_RGBA:
55956e89960Smrg   case GL_DOT3_RGB_EXT:
56056e89960Smrg   case GL_DOT3_RGBA_EXT:
56156e89960Smrg      combine->_NumArgsRGB = 2;
56256e89960Smrg      break;
56356e89960Smrg   case GL_INTERPOLATE:
56456e89960Smrg   case GL_MODULATE_ADD_ATI:
56556e89960Smrg   case GL_MODULATE_SIGNED_ADD_ATI:
56656e89960Smrg   case GL_MODULATE_SUBTRACT_ATI:
56756e89960Smrg      combine->_NumArgsRGB = 3;
56856e89960Smrg      break;
56956e89960Smrg   default:
57056e89960Smrg      combine->_NumArgsRGB = 0;
57156e89960Smrg      _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state");
57256e89960Smrg      return;
57356e89960Smrg   }
57456e89960Smrg
57556e89960Smrg   /* Determine number of source Alpha terms in the combiner function */
57656e89960Smrg   switch (combine->ModeA) {
57756e89960Smrg   case GL_REPLACE:
57856e89960Smrg      combine->_NumArgsA = 1;
57956e89960Smrg      break;
58056e89960Smrg   case GL_ADD:
58156e89960Smrg   case GL_ADD_SIGNED:
5827e995a2eSmrg      if (fftexUnit->EnvMode == GL_COMBINE4_NV)
58356e89960Smrg         combine->_NumArgsA = 4;
58456e89960Smrg      else
58556e89960Smrg         combine->_NumArgsA = 2;
58656e89960Smrg      break;
58756e89960Smrg   case GL_MODULATE:
58856e89960Smrg   case GL_SUBTRACT:
58956e89960Smrg      combine->_NumArgsA = 2;
59056e89960Smrg      break;
59156e89960Smrg   case GL_INTERPOLATE:
59256e89960Smrg   case GL_MODULATE_ADD_ATI:
59356e89960Smrg   case GL_MODULATE_SIGNED_ADD_ATI:
59456e89960Smrg   case GL_MODULATE_SUBTRACT_ATI:
59556e89960Smrg      combine->_NumArgsA = 3;
59656e89960Smrg      break;
59756e89960Smrg   default:
59856e89960Smrg      combine->_NumArgsA = 0;
59956e89960Smrg      _mesa_problem(ctx, "invalid Alpha combine mode in update_texture_state");
60056e89960Smrg      break;
6017117f1b4Smrg   }
6027e995a2eSmrg
6037e995a2eSmrg   pack_tex_combine(fftexUnit);
6047117f1b4Smrg}
6057117f1b4Smrg
6067117f1b4Smrgstatic void
607b167d5e7Smrgupdate_texgen(struct gl_context *ctx)
6087117f1b4Smrg{
6097117f1b4Smrg   GLuint unit;
610ac997013Sriastradh
611b167d5e7Smrg   /* Setup texgen for those texture coordinate sets that are in use */
612b167d5e7Smrg   for (unit = 0; unit < ctx->Const.MaxTextureCoordUnits; unit++) {
6137e995a2eSmrg      struct gl_fixedfunc_texture_unit *texUnit =
6147e995a2eSmrg         &ctx->Texture.FixedFuncUnit[unit];
615b167d5e7Smrg
616b167d5e7Smrg      texUnit->_GenFlags = 0x0;
617b167d5e7Smrg
618b167d5e7Smrg      if (!(ctx->Texture._EnabledCoordUnits & (1 << unit)))
619b167d5e7Smrg	 continue;
620b167d5e7Smrg
621b167d5e7Smrg      if (texUnit->TexGenEnabled) {
622b167d5e7Smrg	 if (texUnit->TexGenEnabled & S_BIT) {
623b167d5e7Smrg	    texUnit->_GenFlags |= texUnit->GenS._ModeBit;
624b167d5e7Smrg	 }
625b167d5e7Smrg	 if (texUnit->TexGenEnabled & T_BIT) {
626b167d5e7Smrg	    texUnit->_GenFlags |= texUnit->GenT._ModeBit;
627b167d5e7Smrg	 }
628b167d5e7Smrg	 if (texUnit->TexGenEnabled & R_BIT) {
629b167d5e7Smrg	    texUnit->_GenFlags |= texUnit->GenR._ModeBit;
630b167d5e7Smrg	 }
631b167d5e7Smrg	 if (texUnit->TexGenEnabled & Q_BIT) {
632b167d5e7Smrg	    texUnit->_GenFlags |= texUnit->GenQ._ModeBit;
633b167d5e7Smrg	 }
634b167d5e7Smrg
635b167d5e7Smrg	 ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(unit);
636b167d5e7Smrg	 ctx->Texture._GenFlags |= texUnit->_GenFlags;
637b167d5e7Smrg      }
638b167d5e7Smrg
6397e995a2eSmrg      assert(unit < ARRAY_SIZE(ctx->TextureMatrixStack));
640b167d5e7Smrg      if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY)
641b167d5e7Smrg	 ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
6427117f1b4Smrg   }
643b167d5e7Smrg}
6447117f1b4Smrg
645b167d5e7Smrgstatic struct gl_texture_object *
646b167d5e7Smrgupdate_single_program_texture(struct gl_context *ctx, struct gl_program *prog,
6477e995a2eSmrg                              int unit)
648b167d5e7Smrg{
649b167d5e7Smrg   gl_texture_index target_index;
650b167d5e7Smrg   struct gl_texture_unit *texUnit;
651b167d5e7Smrg   struct gl_texture_object *texObj;
652b167d5e7Smrg   struct gl_sampler_object *sampler;
653b167d5e7Smrg
654b167d5e7Smrg   texUnit = &ctx->Texture.Unit[unit];
655b167d5e7Smrg
656b167d5e7Smrg   /* Note: If more than one bit was set in TexturesUsed[unit], then we should
657b167d5e7Smrg    * have had the draw call rejected already.  From the GL 4.4 specification,
658b167d5e7Smrg    * section 7.10 ("Samplers"):
659b167d5e7Smrg    *
660b167d5e7Smrg    *     "It is not allowed to have variables of different sampler types
661b167d5e7Smrg    *      pointing to the same texture image unit within a program
662b167d5e7Smrg    *      object. This situation can only be detected at the next rendering
663b167d5e7Smrg    *      command issued which triggers shader invocations, and an
664b167d5e7Smrg    *      INVALID_OPERATION error will then be generated."
665ac997013Sriastradh    */
666b167d5e7Smrg   target_index = ffs(prog->TexturesUsed[unit]) - 1;
667b167d5e7Smrg   texObj = texUnit->CurrentTex[target_index];
668ac997013Sriastradh
669b167d5e7Smrg   sampler = texUnit->Sampler ?
670b167d5e7Smrg      texUnit->Sampler : &texObj->Sampler;
6717117f1b4Smrg
672b167d5e7Smrg   if (likely(texObj)) {
673b167d5e7Smrg      if (_mesa_is_texture_complete(texObj, sampler))
674b167d5e7Smrg         return texObj;
675b167d5e7Smrg
676b167d5e7Smrg      _mesa_test_texobj_completeness(ctx, texObj);
677b167d5e7Smrg      if (_mesa_is_texture_complete(texObj, sampler))
678b167d5e7Smrg         return texObj;
679b167d5e7Smrg   }
6807117f1b4Smrg
681b167d5e7Smrg   /* If we've reached this point, we didn't find a complete texture of the
682b167d5e7Smrg    * shader's target.  From the GL 4.4 core specification, section 11.1.3.5
683b167d5e7Smrg    * ("Texture Access"):
684b167d5e7Smrg    *
685b167d5e7Smrg    *     "If a sampler is used in a shader and the sampler’s associated
686b167d5e7Smrg    *      texture is not complete, as defined in section 8.17, (0, 0, 0, 1)
687b167d5e7Smrg    *      will be returned for a non-shadow sampler and 0 for a shadow
688b167d5e7Smrg    *      sampler."
689b167d5e7Smrg    *
690b167d5e7Smrg    * Mesa implements this by creating a hidden texture object with a pixel of
691b167d5e7Smrg    * that value.
6927117f1b4Smrg    */
693b167d5e7Smrg   texObj = _mesa_get_fallback_texture(ctx, target_index);
694b167d5e7Smrg   assert(texObj);
695b167d5e7Smrg
696b167d5e7Smrg   return texObj;
697b167d5e7Smrg}
698b167d5e7Smrg
6997e995a2eSmrgstatic inline void
7007e995a2eSmrgupdate_single_program_texture_state(struct gl_context *ctx,
7017e995a2eSmrg                                    struct gl_program *prog,
7027e995a2eSmrg                                    int unit,
7037e995a2eSmrg                                    BITSET_WORD *enabled_texture_units)
7047e995a2eSmrg{
7057e995a2eSmrg   struct gl_texture_object *texObj;
7067e995a2eSmrg
7077e995a2eSmrg   texObj = update_single_program_texture(ctx, prog, unit);
7087e995a2eSmrg
7097e995a2eSmrg   _mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj);
7107e995a2eSmrg   BITSET_SET(enabled_texture_units, unit);
7117e995a2eSmrg   ctx->Texture._MaxEnabledTexImageUnit =
7127e995a2eSmrg      MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);
7137e995a2eSmrg}
7147e995a2eSmrg
715b167d5e7Smrgstatic void
716b167d5e7Smrgupdate_program_texture_state(struct gl_context *ctx, struct gl_program **prog,
717b167d5e7Smrg                             BITSET_WORD *enabled_texture_units)
718b167d5e7Smrg{
719b167d5e7Smrg   int i;
720b167d5e7Smrg
721b167d5e7Smrg   for (i = 0; i < MESA_SHADER_STAGES; i++) {
7227e995a2eSmrg      GLbitfield mask;
7237e995a2eSmrg      GLuint s;
724b167d5e7Smrg
725b167d5e7Smrg      if (!prog[i])
726b167d5e7Smrg         continue;
7277117f1b4Smrg
7287e995a2eSmrg      mask = prog[i]->SamplersUsed;
7297e995a2eSmrg
7307e995a2eSmrg      while (mask) {
7317e995a2eSmrg         s = u_bit_scan(&mask);
7327e995a2eSmrg
7337e995a2eSmrg         update_single_program_texture_state(ctx, prog[i],
7347e995a2eSmrg                                             prog[i]->SamplerUnits[s],
7357e995a2eSmrg                                             enabled_texture_units);
7367e995a2eSmrg      }
7377e995a2eSmrg
7387e995a2eSmrg      if (unlikely(prog[i]->sh.HasBoundBindlessSampler)) {
7397e995a2eSmrg         /* Loop over bindless samplers bound to texture units.
7407e995a2eSmrg          */
7417e995a2eSmrg         for (s = 0; s < prog[i]->sh.NumBindlessSamplers; s++) {
7427e995a2eSmrg            struct gl_bindless_sampler *sampler =
7437e995a2eSmrg               &prog[i]->sh.BindlessSamplers[s];
7447e995a2eSmrg
7457e995a2eSmrg            if (!sampler->bound)
7467e995a2eSmrg               continue;
7477e995a2eSmrg
7487e995a2eSmrg            update_single_program_texture_state(ctx, prog[i], sampler->unit,
7497e995a2eSmrg                                                enabled_texture_units);
750b167d5e7Smrg         }
751c1f859d4Smrg      }
752b167d5e7Smrg   }
75356e89960Smrg
754b167d5e7Smrg   if (prog[MESA_SHADER_FRAGMENT]) {
755b167d5e7Smrg      const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
756b167d5e7Smrg      ctx->Texture._EnabledCoordUnits |=
7577e995a2eSmrg         (prog[MESA_SHADER_FRAGMENT]->info.inputs_read >> VARYING_SLOT_TEX0) &
758b167d5e7Smrg         coordMask;
759b167d5e7Smrg   }
760b167d5e7Smrg}
761c1f859d4Smrg
762b167d5e7Smrgstatic void
763b167d5e7Smrgupdate_ff_texture_state(struct gl_context *ctx,
764b167d5e7Smrg                        BITSET_WORD *enabled_texture_units)
765b167d5e7Smrg{
766b167d5e7Smrg   int unit;
767c1f859d4Smrg
768b167d5e7Smrg   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
769b167d5e7Smrg      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
7707e995a2eSmrg      struct gl_fixedfunc_texture_unit *fftexUnit =
7717e995a2eSmrg         &ctx->Texture.FixedFuncUnit[unit];
7727e995a2eSmrg      GLbitfield mask;
7737e995a2eSmrg      bool complete;
77456e89960Smrg
7757e995a2eSmrg      if (fftexUnit->Enabled == 0x0)
776b167d5e7Smrg         continue;
777b167d5e7Smrg
778b167d5e7Smrg      /* If a shader already dictated what texture target was used for this
779b167d5e7Smrg       * unit, just go along with it.
780b167d5e7Smrg       */
781b167d5e7Smrg      if (BITSET_TEST(enabled_texture_units, unit))
78256e89960Smrg         continue;
7837117f1b4Smrg
784b167d5e7Smrg      /* From the GL 4.4 compat specification, section 16.2 ("Texture Application"):
785b167d5e7Smrg       *
786b167d5e7Smrg       *     "Texturing is enabled or disabled using the generic Enable and
787b167d5e7Smrg       *      Disable commands, respectively, with the symbolic constants
788b167d5e7Smrg       *      TEXTURE_1D, TEXTURE_2D, TEXTURE_RECTANGLE, TEXTURE_3D, or
789b167d5e7Smrg       *      TEXTURE_CUBE_MAP to enable the one-, two-, rectangular,
790b167d5e7Smrg       *      three-dimensional, or cube map texture, respectively. If more
791b167d5e7Smrg       *      than one of these textures is enabled, the first one enabled
792b167d5e7Smrg       *      from the following list is used:
793b167d5e7Smrg       *
794b167d5e7Smrg       *      • cube map texture
795b167d5e7Smrg       *      • three-dimensional texture
796b167d5e7Smrg       *      • rectangular texture
797b167d5e7Smrg       *      • two-dimensional texture
798b167d5e7Smrg       *      • one-dimensional texture"
799b167d5e7Smrg       *
80056e89960Smrg       * Note that the TEXTURE_x_INDEX values are in high to low priority.
801b167d5e7Smrg       * Also:
802b167d5e7Smrg       *
803b167d5e7Smrg       *     "If a texture unit is disabled or has an invalid or incomplete
804b167d5e7Smrg       *      texture (as defined in section 8.17) bound to it, then blending
805b167d5e7Smrg       *      is disabled for that texture unit. If the texture environment
806b167d5e7Smrg       *      for a given enabled texture unit references a disabled texture
807b167d5e7Smrg       *      unit, or an invalid or incomplete texture that is bound to
808b167d5e7Smrg       *      another unit, then the results of texture blending are
809b167d5e7Smrg       *      undefined."
8107117f1b4Smrg       */
8117e995a2eSmrg      complete = false;
8127e995a2eSmrg      mask = fftexUnit->Enabled;
8137e995a2eSmrg      while (mask) {
8147e995a2eSmrg         const int texIndex = u_bit_scan(&mask);
8157e995a2eSmrg         struct gl_texture_object *texObj = texUnit->CurrentTex[texIndex];
8167e995a2eSmrg         struct gl_sampler_object *sampler = texUnit->Sampler ?
8177e995a2eSmrg            texUnit->Sampler : &texObj->Sampler;
8187e995a2eSmrg
8197e995a2eSmrg         if (!_mesa_is_texture_complete(texObj, sampler)) {
8207e995a2eSmrg            _mesa_test_texobj_completeness(ctx, texObj);
8217e995a2eSmrg         }
8227e995a2eSmrg         if (_mesa_is_texture_complete(texObj, sampler)) {
8237e995a2eSmrg            _mesa_reference_texobj(&texUnit->_Current, texObj);
8247e995a2eSmrg            complete = true;
8257e995a2eSmrg            break;
82656e89960Smrg         }
827c1f859d4Smrg      }
8287117f1b4Smrg
8297e995a2eSmrg      if (!complete)
830b167d5e7Smrg         continue;
8317117f1b4Smrg
83256e89960Smrg      /* if we get here, we know this texture unit is enabled */
833b167d5e7Smrg      BITSET_SET(enabled_texture_units, unit);
834b167d5e7Smrg      ctx->Texture._MaxEnabledTexImageUnit =
835b167d5e7Smrg         MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);
8367117f1b4Smrg
837b167d5e7Smrg      ctx->Texture._EnabledCoordUnits |= 1 << unit;
83856e89960Smrg
8397e995a2eSmrg      update_tex_combine(ctx, texUnit, fftexUnit);
8407e995a2eSmrg   }
8417e995a2eSmrg}
8427e995a2eSmrg
8437e995a2eSmrgstatic void
8447e995a2eSmrgfix_missing_textures_for_atifs(struct gl_context *ctx,
8457e995a2eSmrg                               struct gl_program *prog,
8467e995a2eSmrg                               BITSET_WORD *enabled_texture_units)
8477e995a2eSmrg{
8487e995a2eSmrg   GLbitfield mask = prog->SamplersUsed;
8497e995a2eSmrg
8507e995a2eSmrg   while (mask) {
8517e995a2eSmrg      const int s = u_bit_scan(&mask);
8527e995a2eSmrg      const int unit = prog->SamplerUnits[s];
8537e995a2eSmrg      const gl_texture_index target_index = ffs(prog->TexturesUsed[unit]) - 1;
8547e995a2eSmrg
8557e995a2eSmrg      if (!ctx->Texture.Unit[unit]._Current) {
8567e995a2eSmrg         struct gl_texture_object *texObj =
8577e995a2eSmrg            _mesa_get_fallback_texture(ctx, target_index);
8587e995a2eSmrg         _mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj);
8597e995a2eSmrg         BITSET_SET(enabled_texture_units, unit);
8607e995a2eSmrg         ctx->Texture._MaxEnabledTexImageUnit =
8617e995a2eSmrg            MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);
8627e995a2eSmrg      }
863c1f859d4Smrg   }
864b167d5e7Smrg}
865c1f859d4Smrg
866b167d5e7Smrg/**
867b167d5e7Smrg * \note This routine refers to derived texture matrix values to
868b167d5e7Smrg * compute the ENABLE_TEXMAT flags, but is only called on
8697e995a2eSmrg * _NEW_TEXTURE_OBJECT/STATE.  On changes to _NEW_TEXTURE_MATRIX,
8707e995a2eSmrg * the ENABLE_TEXMAT flags are updated by _mesa_update_texture_matrices,
8717e995a2eSmrg * above.
872b167d5e7Smrg *
873b167d5e7Smrg * \param ctx GL context.
874b167d5e7Smrg */
8757e995a2eSmrgvoid
8767e995a2eSmrg_mesa_update_texture_state(struct gl_context *ctx)
877b167d5e7Smrg{
878b167d5e7Smrg   struct gl_program *prog[MESA_SHADER_STAGES];
879b167d5e7Smrg   int i;
880b167d5e7Smrg   int old_max_unit = ctx->Texture._MaxEnabledTexImageUnit;
881b167d5e7Smrg   BITSET_DECLARE(enabled_texture_units, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
882b167d5e7Smrg
8837e995a2eSmrg   memcpy(prog, ctx->_Shader->CurrentProgram, sizeof(prog));
8847e995a2eSmrg
8857e995a2eSmrg   if (prog[MESA_SHADER_FRAGMENT] == NULL &&
8867e995a2eSmrg       _mesa_arb_fragment_program_enabled(ctx)) {
8877e995a2eSmrg      prog[MESA_SHADER_FRAGMENT] = ctx->FragmentProgram.Current;
888c1f859d4Smrg   }
889c1f859d4Smrg
890b167d5e7Smrg   /* TODO: only set this if there are actual changes */
8917e995a2eSmrg   ctx->NewState |= _NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE;
892c1f859d4Smrg
893b167d5e7Smrg   ctx->Texture._GenFlags = 0x0;
894b167d5e7Smrg   ctx->Texture._TexMatEnabled = 0x0;
895b167d5e7Smrg   ctx->Texture._TexGenEnabled = 0x0;
896b167d5e7Smrg   ctx->Texture._MaxEnabledTexImageUnit = -1;
897b167d5e7Smrg   ctx->Texture._EnabledCoordUnits = 0x0;
89856e89960Smrg
899b167d5e7Smrg   memset(&enabled_texture_units, 0, sizeof(enabled_texture_units));
9007117f1b4Smrg
901b167d5e7Smrg   /* First, walk over our programs pulling in all the textures for them.
902b167d5e7Smrg    * Programs dictate specific texture targets to be enabled, and for a draw
903b167d5e7Smrg    * call to be valid they can't conflict about which texture targets are
904b167d5e7Smrg    * used.
905b167d5e7Smrg    */
906b167d5e7Smrg   update_program_texture_state(ctx, prog, enabled_texture_units);
9077117f1b4Smrg
908b167d5e7Smrg   /* Also pull in any textures necessary for fixed function fragment shading.
909b167d5e7Smrg    */
910b167d5e7Smrg   if (!prog[MESA_SHADER_FRAGMENT])
911b167d5e7Smrg      update_ff_texture_state(ctx, enabled_texture_units);
9127117f1b4Smrg
913b167d5e7Smrg   /* Now, clear out the _Current of any disabled texture units. */
914b167d5e7Smrg   for (i = 0; i <= ctx->Texture._MaxEnabledTexImageUnit; i++) {
915b167d5e7Smrg      if (!BITSET_TEST(enabled_texture_units, i))
916b167d5e7Smrg         _mesa_reference_texobj(&ctx->Texture.Unit[i]._Current, NULL);
917b167d5e7Smrg   }
918b167d5e7Smrg   for (i = ctx->Texture._MaxEnabledTexImageUnit + 1; i <= old_max_unit; i++) {
919b167d5e7Smrg      _mesa_reference_texobj(&ctx->Texture.Unit[i]._Current, NULL);
9207117f1b4Smrg   }
921b167d5e7Smrg
9227e995a2eSmrg   /* add fallback texture for SampleMapATI if there is nothing */
9237e995a2eSmrg   if (_mesa_ati_fragment_shader_enabled(ctx) &&
9247e995a2eSmrg       ctx->ATIFragmentShader.Current->Program)
9257e995a2eSmrg      fix_missing_textures_for_atifs(ctx,
9267e995a2eSmrg                                     ctx->ATIFragmentShader.Current->Program,
9277e995a2eSmrg                                     enabled_texture_units);
9287e995a2eSmrg
929b167d5e7Smrg   if (!prog[MESA_SHADER_FRAGMENT] || !prog[MESA_SHADER_VERTEX])
930b167d5e7Smrg      update_texgen(ctx);
9317117f1b4Smrg}
9327117f1b4Smrg
9337117f1b4Smrg
9347117f1b4Smrg/**********************************************************************/
9357117f1b4Smrg/*****                      Initialization                        *****/
9367117f1b4Smrg/**********************************************************************/
9377117f1b4Smrg
9387117f1b4Smrg/**
9397117f1b4Smrg * Allocate the proxy textures for the given context.
9407e995a2eSmrg *
9417117f1b4Smrg * \param ctx the context to allocate proxies for.
9427e995a2eSmrg *
9437117f1b4Smrg * \return GL_TRUE on success, or GL_FALSE on failure
9447e995a2eSmrg *
9457117f1b4Smrg * If run out of memory part way through the allocations, clean up and return
9467117f1b4Smrg * GL_FALSE.
9477117f1b4Smrg */
9487117f1b4Smrgstatic GLboolean
949ac997013Sriastradhalloc_proxy_textures( struct gl_context *ctx )
9507117f1b4Smrg{
951b167d5e7Smrg   /* NOTE: these values must be in the same order as the TEXTURE_x_INDEX
952b167d5e7Smrg    * values!
953b167d5e7Smrg    */
954c1f859d4Smrg   static const GLenum targets[] = {
955b167d5e7Smrg      GL_TEXTURE_2D_MULTISAMPLE,
956b167d5e7Smrg      GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
957b167d5e7Smrg      GL_TEXTURE_CUBE_MAP_ARRAY,
958b167d5e7Smrg      GL_TEXTURE_BUFFER,
959b167d5e7Smrg      GL_TEXTURE_2D_ARRAY_EXT,
960b167d5e7Smrg      GL_TEXTURE_1D_ARRAY_EXT,
961b167d5e7Smrg      GL_TEXTURE_EXTERNAL_OES,
9627e995a2eSmrg      GL_TEXTURE_CUBE_MAP,
963b167d5e7Smrg      GL_TEXTURE_3D,
964c1f859d4Smrg      GL_TEXTURE_RECTANGLE_NV,
965b167d5e7Smrg      GL_TEXTURE_2D,
966b167d5e7Smrg      GL_TEXTURE_1D,
967c1f859d4Smrg   };
968c1f859d4Smrg   GLint tgt;
9697117f1b4Smrg
9707e995a2eSmrg   STATIC_ASSERT(ARRAY_SIZE(targets) == NUM_TEXTURE_TARGETS);
971b167d5e7Smrg   assert(targets[TEXTURE_2D_INDEX] == GL_TEXTURE_2D);
972b167d5e7Smrg   assert(targets[TEXTURE_CUBE_INDEX] == GL_TEXTURE_CUBE_MAP);
9737117f1b4Smrg
974c1f859d4Smrg   for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
975c1f859d4Smrg      if (!(ctx->Texture.ProxyTex[tgt]
976c1f859d4Smrg            = ctx->Driver.NewTextureObject(ctx, 0, targets[tgt]))) {
977c1f859d4Smrg         /* out of memory, free what we did allocate */
978c1f859d4Smrg         while (--tgt >= 0) {
979c1f859d4Smrg            ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
980c1f859d4Smrg         }
981c1f859d4Smrg         return GL_FALSE;
982c1f859d4Smrg      }
983c1f859d4Smrg   }
9847117f1b4Smrg
985c1f859d4Smrg   assert(ctx->Texture.ProxyTex[0]->RefCount == 1); /* sanity check */
9867117f1b4Smrg   return GL_TRUE;
9877117f1b4Smrg}
9887117f1b4Smrg
9897117f1b4Smrg
9907117f1b4Smrg/**
9917117f1b4Smrg * Initialize texture state for the given context.
9927117f1b4Smrg */
9937117f1b4SmrgGLboolean
994ac997013Sriastradh_mesa_init_texture(struct gl_context *ctx)
9957117f1b4Smrg{
99656e89960Smrg   GLuint u;
9977117f1b4Smrg
9987117f1b4Smrg   /* Texture group */
9997117f1b4Smrg   ctx->Texture.CurrentUnit = 0;      /* multitexture */
1000b167d5e7Smrg
1001b167d5e7Smrg   /* Appendix F.2 of the OpenGL ES 3.0 spec says:
1002b167d5e7Smrg    *
1003b167d5e7Smrg    *     "OpenGL ES 3.0 requires that all cube map filtering be
1004b167d5e7Smrg    *     seamless. OpenGL ES 2.0 specified that a single cube map face be
1005b167d5e7Smrg    *     selected and used for filtering."
10067e995a2eSmrg    *
10077e995a2eSmrg    * Unfortunatley, a call to _mesa_is_gles3 below will only work if
10087e995a2eSmrg    * the driver has already computed and set ctx->Version, however drivers
10097e995a2eSmrg    * seem to call _mesa_initialize_context (which calls this) early
10107e995a2eSmrg    * in the CreateContext hook and _mesa_compute_version much later (since
10117e995a2eSmrg    * it needs information about available extensions). So, we will
10127e995a2eSmrg    * enable seamless cubemaps by default since GLES2. This should work
10137e995a2eSmrg    * for most implementations and drivers that don't support seamless
10147e995a2eSmrg    * cubemaps for GLES2 can still disable it.
1015b167d5e7Smrg    */
10167e995a2eSmrg   ctx->Texture.CubeMapSeamless = ctx->API == API_OPENGLES2;
10177e995a2eSmrg
10187e995a2eSmrg   for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
10197e995a2eSmrg      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
10207e995a2eSmrg      GLuint tex;
10217e995a2eSmrg
10227e995a2eSmrg      /* initialize current texture object ptrs to the shared default objects */
10237e995a2eSmrg      for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
10247e995a2eSmrg         _mesa_reference_texobj(&texUnit->CurrentTex[tex],
10257e995a2eSmrg                                ctx->Shared->DefaultTex[tex]);
10267e995a2eSmrg      }
10277e995a2eSmrg
10287e995a2eSmrg      texUnit->_BoundTextures = 0;
10297e995a2eSmrg   }
10307e995a2eSmrg
10317e995a2eSmrg   for (u = 0; u < ARRAY_SIZE(ctx->Texture.FixedFuncUnit); u++) {
10327e995a2eSmrg      struct gl_fixedfunc_texture_unit *texUnit =
10337e995a2eSmrg         &ctx->Texture.FixedFuncUnit[u];
10347117f1b4Smrg
10357e995a2eSmrg      texUnit->EnvMode = GL_MODULATE;
10367e995a2eSmrg      ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
10377e995a2eSmrg
10387e995a2eSmrg      texUnit->Combine = default_combine_state;
10397e995a2eSmrg      texUnit->_EnvMode = default_combine_state;
10407e995a2eSmrg      texUnit->_CurrentCombine = & texUnit->_EnvMode;
10417e995a2eSmrg
10427e995a2eSmrg      texUnit->TexGenEnabled = 0x0;
10437e995a2eSmrg      texUnit->GenS.Mode = GL_EYE_LINEAR;
10447e995a2eSmrg      texUnit->GenT.Mode = GL_EYE_LINEAR;
10457e995a2eSmrg      texUnit->GenR.Mode = GL_EYE_LINEAR;
10467e995a2eSmrg      texUnit->GenQ.Mode = GL_EYE_LINEAR;
10477e995a2eSmrg      texUnit->GenS._ModeBit = TEXGEN_EYE_LINEAR;
10487e995a2eSmrg      texUnit->GenT._ModeBit = TEXGEN_EYE_LINEAR;
10497e995a2eSmrg      texUnit->GenR._ModeBit = TEXGEN_EYE_LINEAR;
10507e995a2eSmrg      texUnit->GenQ._ModeBit = TEXGEN_EYE_LINEAR;
10517e995a2eSmrg
10527e995a2eSmrg      /* Yes, these plane coefficients are correct! */
10537e995a2eSmrg      ASSIGN_4V( texUnit->GenS.ObjectPlane, 1.0, 0.0, 0.0, 0.0 );
10547e995a2eSmrg      ASSIGN_4V( texUnit->GenT.ObjectPlane, 0.0, 1.0, 0.0, 0.0 );
10557e995a2eSmrg      ASSIGN_4V( texUnit->GenR.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
10567e995a2eSmrg      ASSIGN_4V( texUnit->GenQ.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
10577e995a2eSmrg      ASSIGN_4V( texUnit->GenS.EyePlane, 1.0, 0.0, 0.0, 0.0 );
10587e995a2eSmrg      ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 );
10597e995a2eSmrg      ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 );
10607e995a2eSmrg      ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 );
10617e995a2eSmrg   }
10627117f1b4Smrg
10637117f1b4Smrg   /* After we're done initializing the context's texture state the default
10641f16d945Smrg    * texture objects' refcounts should be at least
10651f16d945Smrg    * MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1.
10667117f1b4Smrg    */
1067c1f859d4Smrg   assert(ctx->Shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount
10681f16d945Smrg          >= MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1);
10697117f1b4Smrg
10707117f1b4Smrg   /* Allocate proxy textures */
10717117f1b4Smrg   if (!alloc_proxy_textures( ctx ))
10727117f1b4Smrg      return GL_FALSE;
10737117f1b4Smrg
1074ac997013Sriastradh   /* GL_ARB_texture_buffer_object */
1075ac997013Sriastradh   _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject,
1076ac997013Sriastradh                                 ctx->Shared->NullBufferObj);
1077ac997013Sriastradh
1078b167d5e7Smrg   ctx->Texture.NumCurrentTexUsed = 0;
1079b167d5e7Smrg
10807117f1b4Smrg   return GL_TRUE;
10817117f1b4Smrg}
10827117f1b4Smrg
10837117f1b4Smrg
10847117f1b4Smrg/**
1085c1f859d4Smrg * Free dynamically-allocted texture data attached to the given context.
10867117f1b4Smrg */
10877117f1b4Smrgvoid
1088ac997013Sriastradh_mesa_free_texture_data(struct gl_context *ctx)
10897117f1b4Smrg{
1090c1f859d4Smrg   GLuint u, tgt;
10917117f1b4Smrg
10927117f1b4Smrg   /* unreference current textures */
10937e995a2eSmrg   for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
1094c1f859d4Smrg      /* The _Current texture could account for another reference */
1095c1f859d4Smrg      _mesa_reference_texobj(&ctx->Texture.Unit[u]._Current, NULL);
1096c1f859d4Smrg
1097c1f859d4Smrg      for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
109856e89960Smrg         _mesa_reference_texobj(&ctx->Texture.Unit[u].CurrentTex[tgt], NULL);
1099c1f859d4Smrg      }
11007117f1b4Smrg   }
11017117f1b4Smrg
11027117f1b4Smrg   /* Free proxy texture objects */
1103c1f859d4Smrg   for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++)
1104c1f859d4Smrg      ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
1105c1f859d4Smrg
1106ac997013Sriastradh   /* GL_ARB_texture_buffer_object */
1107ac997013Sriastradh   _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject, NULL);
1108ac997013Sriastradh
11097e995a2eSmrg   for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
1110ac997013Sriastradh      _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[u].Sampler, NULL);
1111ac997013Sriastradh   }
1112c1f859d4Smrg}
1113c1f859d4Smrg
11147117f1b4Smrg
1115c1f859d4Smrg/**
1116c1f859d4Smrg * Update the default texture objects in the given context to reference those
11177e995a2eSmrg * specified in the shared state and release those referencing the old
1118c1f859d4Smrg * shared state.
1119c1f859d4Smrg */
1120c1f859d4Smrgvoid
1121ac997013Sriastradh_mesa_update_default_objects_texture(struct gl_context *ctx)
1122c1f859d4Smrg{
112356e89960Smrg   GLuint u, tex;
11247117f1b4Smrg
11257e995a2eSmrg   for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
112656e89960Smrg      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
1127c1f859d4Smrg      for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
1128c1f859d4Smrg         _mesa_reference_texobj(&texUnit->CurrentTex[tex],
1129c1f859d4Smrg                                ctx->Shared->DefaultTex[tex]);
1130c1f859d4Smrg      }
1131c1f859d4Smrg   }
11327117f1b4Smrg}
1133