texstate.c revision 1463c08d
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
767117f1b4Smrg   /* per-unit state */
771f16d945Smrg   for (u = 0; u < src->Const.MaxCombinedTextureImageUnits; u++) {
7856e89960Smrg      dst->Texture.Unit[u].LodBias = src->Texture.Unit[u].LodBias;
791463c08dSmrg      dst->Texture.Unit[u].LodBiasQuantized = src->Texture.Unit[u].LodBiasQuantized;
807117f1b4Smrg
8156e89960Smrg      /*
8256e89960Smrg       * XXX strictly speaking, we should compare texture names/ids and
8356e89960Smrg       * bind textures in the dest context according to id.  For now, only
8456e89960Smrg       * copy bindings if the contexts share the same pool of textures to
8556e89960Smrg       * avoid refcounting bugs.
8656e89960Smrg       */
8756e89960Smrg      if (dst->Shared == src->Shared) {
8856e89960Smrg         /* copy texture object bindings, not contents of texture objects */
8956e89960Smrg         _mesa_lock_context_textures(dst);
907117f1b4Smrg
9156e89960Smrg         for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
9256e89960Smrg            _mesa_reference_texobj(&dst->Texture.Unit[u].CurrentTex[tex],
9356e89960Smrg                                   src->Texture.Unit[u].CurrentTex[tex]);
94b167d5e7Smrg            if (src->Texture.Unit[u].CurrentTex[tex]) {
95b167d5e7Smrg               dst->Texture.NumCurrentTexUsed =
96b167d5e7Smrg                  MAX2(dst->Texture.NumCurrentTexUsed, u + 1);
97b167d5e7Smrg            }
9856e89960Smrg         }
99b167d5e7Smrg         dst->Texture.Unit[u]._BoundTextures = src->Texture.Unit[u]._BoundTextures;
10056e89960Smrg         _mesa_unlock_context_textures(dst);
10156e89960Smrg      }
1027117f1b4Smrg   }
1037e995a2eSmrg
1047e995a2eSmrg   for (u = 0; u < src->Const.MaxTextureCoordUnits; u++) {
1057e995a2eSmrg      dst->Texture.FixedFuncUnit[u].Enabled = src->Texture.FixedFuncUnit[u].Enabled;
1067e995a2eSmrg      dst->Texture.FixedFuncUnit[u].EnvMode = src->Texture.FixedFuncUnit[u].EnvMode;
1077e995a2eSmrg      COPY_4V(dst->Texture.FixedFuncUnit[u].EnvColor, src->Texture.FixedFuncUnit[u].EnvColor);
1087e995a2eSmrg      dst->Texture.FixedFuncUnit[u].TexGenEnabled = src->Texture.FixedFuncUnit[u].TexGenEnabled;
1097e995a2eSmrg      dst->Texture.FixedFuncUnit[u].GenS = src->Texture.FixedFuncUnit[u].GenS;
1107e995a2eSmrg      dst->Texture.FixedFuncUnit[u].GenT = src->Texture.FixedFuncUnit[u].GenT;
1117e995a2eSmrg      dst->Texture.FixedFuncUnit[u].GenR = src->Texture.FixedFuncUnit[u].GenR;
1127e995a2eSmrg      dst->Texture.FixedFuncUnit[u].GenQ = src->Texture.FixedFuncUnit[u].GenQ;
1131463c08dSmrg      memcpy(dst->Texture.FixedFuncUnit[u].ObjectPlane,
1141463c08dSmrg             src->Texture.FixedFuncUnit[u].ObjectPlane,
1151463c08dSmrg             sizeof(src->Texture.FixedFuncUnit[u].ObjectPlane));
1161463c08dSmrg      memcpy(dst->Texture.FixedFuncUnit[u].EyePlane,
1171463c08dSmrg             src->Texture.FixedFuncUnit[u].EyePlane,
1181463c08dSmrg             sizeof(src->Texture.FixedFuncUnit[u].EyePlane));
1197e995a2eSmrg
1207e995a2eSmrg      /* GL_EXT_texture_env_combine */
1217e995a2eSmrg      dst->Texture.FixedFuncUnit[u].Combine = src->Texture.FixedFuncUnit[u].Combine;
1227e995a2eSmrg   }
1237117f1b4Smrg}
1247117f1b4Smrg
1257117f1b4Smrg
1267117f1b4Smrg/*
1277117f1b4Smrg * For debugging
1287117f1b4Smrg */
1297117f1b4Smrgvoid
130ac997013Sriastradh_mesa_print_texunit_state( struct gl_context *ctx, GLuint unit )
1317117f1b4Smrg{
1327e995a2eSmrg   const struct gl_fixedfunc_texture_unit *texUnit = ctx->Texture.FixedFuncUnit + unit;
1331f16d945Smrg   printf("Texture Unit %d\n", unit);
1347e995a2eSmrg   printf("  GL_TEXTURE_ENV_MODE = %s\n", _mesa_enum_to_string(texUnit->EnvMode));
1357e995a2eSmrg   printf("  GL_COMBINE_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.ModeRGB));
1367e995a2eSmrg   printf("  GL_COMBINE_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.ModeA));
1377e995a2eSmrg   printf("  GL_SOURCE0_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceRGB[0]));
1387e995a2eSmrg   printf("  GL_SOURCE1_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceRGB[1]));
1397e995a2eSmrg   printf("  GL_SOURCE2_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceRGB[2]));
1407e995a2eSmrg   printf("  GL_SOURCE0_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceA[0]));
1417e995a2eSmrg   printf("  GL_SOURCE1_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceA[1]));
1427e995a2eSmrg   printf("  GL_SOURCE2_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.SourceA[2]));
1437e995a2eSmrg   printf("  GL_OPERAND0_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandRGB[0]));
1447e995a2eSmrg   printf("  GL_OPERAND1_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandRGB[1]));
1457e995a2eSmrg   printf("  GL_OPERAND2_RGB = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandRGB[2]));
1467e995a2eSmrg   printf("  GL_OPERAND0_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandA[0]));
1477e995a2eSmrg   printf("  GL_OPERAND1_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandA[1]));
1487e995a2eSmrg   printf("  GL_OPERAND2_ALPHA = %s\n", _mesa_enum_to_string(texUnit->Combine.OperandA[2]));
1491f16d945Smrg   printf("  GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB);
1501f16d945Smrg   printf("  GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA);
1511f16d945Smrg   printf("  GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit->EnvColor[0], texUnit->EnvColor[1], texUnit->EnvColor[2], texUnit->EnvColor[3]);
152c1f859d4Smrg}
1537117f1b4Smrg
1547117f1b4Smrg
1557117f1b4Smrg
156c1f859d4Smrg/**********************************************************************/
157c1f859d4Smrg/*                       Texture Environment                          */
158c1f859d4Smrg/**********************************************************************/
1597117f1b4Smrg
160c1f859d4Smrg/**
161c1f859d4Smrg * Convert "classic" texture environment to ARB_texture_env_combine style
162c1f859d4Smrg * environments.
1637e995a2eSmrg *
164c1f859d4Smrg * \param state  texture_env_combine state vector to be filled-in.
165c1f859d4Smrg * \param mode   Classic texture environment mode (i.e., \c GL_REPLACE,
166c1f859d4Smrg *               \c GL_BLEND, \c GL_DECAL, etc.).
167c1f859d4Smrg * \param texBaseFormat  Base format of the texture associated with the
168c1f859d4Smrg *               texture unit.
169c1f859d4Smrg */
170c1f859d4Smrgstatic void
171c1f859d4Smrgcalculate_derived_texenv( struct gl_tex_env_combine_state *state,
172c1f859d4Smrg			  GLenum mode, GLenum texBaseFormat )
173c1f859d4Smrg{
174c1f859d4Smrg   GLenum mode_rgb;
175c1f859d4Smrg   GLenum mode_a;
1767117f1b4Smrg
177c1f859d4Smrg   *state = default_combine_state;
1787117f1b4Smrg
179c1f859d4Smrg   switch (texBaseFormat) {
180c1f859d4Smrg   case GL_ALPHA:
181c1f859d4Smrg      state->SourceRGB[0] = GL_PREVIOUS;
182c1f859d4Smrg      break;
1837117f1b4Smrg
184c1f859d4Smrg   case GL_LUMINANCE_ALPHA:
185c1f859d4Smrg   case GL_INTENSITY:
186c1f859d4Smrg   case GL_RGBA:
187c1f859d4Smrg      break;
1887117f1b4Smrg
189c1f859d4Smrg   case GL_LUMINANCE:
190ac997013Sriastradh   case GL_RED:
191ac997013Sriastradh   case GL_RG:
192c1f859d4Smrg   case GL_RGB:
193c1f859d4Smrg   case GL_YCBCR_MESA:
194c1f859d4Smrg      state->SourceA[0] = GL_PREVIOUS;
195c1f859d4Smrg      break;
1967e995a2eSmrg
197c1f859d4Smrg   default:
19856e89960Smrg      _mesa_problem(NULL,
19956e89960Smrg                    "Invalid texBaseFormat 0x%x in calculate_derived_texenv",
20056e89960Smrg                    texBaseFormat);
2017117f1b4Smrg      return;
2027117f1b4Smrg   }
2037117f1b4Smrg
204c1f859d4Smrg   if (mode == GL_REPLACE_EXT)
205c1f859d4Smrg      mode = GL_REPLACE;
2067117f1b4Smrg
207c1f859d4Smrg   switch (mode) {
208c1f859d4Smrg   case GL_REPLACE:
209c1f859d4Smrg   case GL_MODULATE:
210c1f859d4Smrg      mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : mode;
211c1f859d4Smrg      mode_a   = mode;
212c1f859d4Smrg      break;
2137e995a2eSmrg
214c1f859d4Smrg   case GL_DECAL:
215c1f859d4Smrg      mode_rgb = GL_INTERPOLATE;
216c1f859d4Smrg      mode_a   = GL_REPLACE;
217c1f859d4Smrg
218c1f859d4Smrg      state->SourceA[0] = GL_PREVIOUS;
219c1f859d4Smrg
220c1f859d4Smrg      /* Having alpha / luminance / intensity textures replace using the
221c1f859d4Smrg       * incoming fragment color matches the definition in NV_texture_shader.
222c1f859d4Smrg       * The 1.5 spec simply marks these as "undefined".
223c1f859d4Smrg       */
224c1f859d4Smrg      switch (texBaseFormat) {
225c1f859d4Smrg      case GL_ALPHA:
226c1f859d4Smrg      case GL_LUMINANCE:
227c1f859d4Smrg      case GL_LUMINANCE_ALPHA:
228c1f859d4Smrg      case GL_INTENSITY:
229c1f859d4Smrg	 state->SourceRGB[0] = GL_PREVIOUS;
2307117f1b4Smrg	 break;
231ac997013Sriastradh      case GL_RED:
232ac997013Sriastradh      case GL_RG:
233c1f859d4Smrg      case GL_RGB:
234c1f859d4Smrg      case GL_YCBCR_MESA:
235c1f859d4Smrg	 mode_rgb = GL_REPLACE;
2367117f1b4Smrg	 break;
237c1f859d4Smrg      case GL_RGBA:
238c1f859d4Smrg	 state->SourceRGB[2] = GL_TEXTURE;
2397117f1b4Smrg	 break;
240c1f859d4Smrg      }
241c1f859d4Smrg      break;
2427117f1b4Smrg
243c1f859d4Smrg   case GL_BLEND:
244c1f859d4Smrg      mode_rgb = GL_INTERPOLATE;
245c1f859d4Smrg      mode_a   = GL_MODULATE;
2467117f1b4Smrg
247c1f859d4Smrg      switch (texBaseFormat) {
248c1f859d4Smrg      case GL_ALPHA:
249c1f859d4Smrg	 mode_rgb = GL_REPLACE;
250c1f859d4Smrg	 break;
251c1f859d4Smrg      case GL_INTENSITY:
252c1f859d4Smrg	 mode_a = GL_INTERPOLATE;
253c1f859d4Smrg	 state->SourceA[0] = GL_CONSTANT;
254c1f859d4Smrg	 state->OperandA[2] = GL_SRC_ALPHA;
2551463c08dSmrg	 FALLTHROUGH;
256c1f859d4Smrg      case GL_LUMINANCE:
257ac997013Sriastradh      case GL_RED:
258ac997013Sriastradh      case GL_RG:
259c1f859d4Smrg      case GL_RGB:
260c1f859d4Smrg      case GL_LUMINANCE_ALPHA:
261c1f859d4Smrg      case GL_RGBA:
262c1f859d4Smrg      case GL_YCBCR_MESA:
263c1f859d4Smrg	 state->SourceRGB[2] = GL_TEXTURE;
264c1f859d4Smrg	 state->SourceA[2]   = GL_TEXTURE;
265c1f859d4Smrg	 state->SourceRGB[0] = GL_CONSTANT;
266c1f859d4Smrg	 state->OperandRGB[2] = GL_SRC_COLOR;
267c1f859d4Smrg	 break;
268c1f859d4Smrg      }
269c1f859d4Smrg      break;
2707117f1b4Smrg
271c1f859d4Smrg   case GL_ADD:
272c1f859d4Smrg      mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : GL_ADD;
273c1f859d4Smrg      mode_a   = (texBaseFormat == GL_INTENSITY) ? GL_ADD : GL_MODULATE;
274c1f859d4Smrg      break;
2757117f1b4Smrg
276c1f859d4Smrg   default:
277c1f859d4Smrg      _mesa_problem(NULL,
27856e89960Smrg                    "Invalid texture env mode 0x%x in calculate_derived_texenv",
27956e89960Smrg                    mode);
2807117f1b4Smrg      return;
2817117f1b4Smrg   }
2827e995a2eSmrg
283c1f859d4Smrg   state->ModeRGB = (state->SourceRGB[0] != GL_PREVIOUS)
284c1f859d4Smrg       ? mode_rgb : GL_REPLACE;
285c1f859d4Smrg   state->ModeA   = (state->SourceA[0]   != GL_PREVIOUS)
286c1f859d4Smrg       ? mode_a   : GL_REPLACE;
287c1f859d4Smrg}
2887117f1b4Smrg
2897117f1b4Smrg
2907117f1b4Smrg/* GL_ARB_multitexture */
2917e995a2eSmrgstatic ALWAYS_INLINE void
2927e995a2eSmrgactive_texture(GLenum texture, bool no_error)
2937117f1b4Smrg{
2947117f1b4Smrg   const GLuint texUnit = texture - GL_TEXTURE0;
2951f16d945Smrg
2967e995a2eSmrg   GET_CURRENT_CONTEXT(ctx);
2977117f1b4Smrg
2987117f1b4Smrg   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2997117f1b4Smrg      _mesa_debug(ctx, "glActiveTexture %s\n",
3007e995a2eSmrg                  _mesa_enum_to_string(texture));
3017117f1b4Smrg
3027e995a2eSmrg   if (ctx->Texture.CurrentUnit == texUnit)
3037117f1b4Smrg      return;
3047e995a2eSmrg
3057e995a2eSmrg   if (!no_error) {
3067e995a2eSmrg      GLuint k = _mesa_max_tex_unit(ctx);
3077e995a2eSmrg
3087e995a2eSmrg      assert(k <= ARRAY_SIZE(ctx->Texture.Unit));
3097e995a2eSmrg
3107e995a2eSmrg      if (texUnit >= k) {
3117e995a2eSmrg         _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture=%s)",
3127e995a2eSmrg                     _mesa_enum_to_string(texture));
3137e995a2eSmrg         return;
3147e995a2eSmrg      }
3157117f1b4Smrg   }
3167117f1b4Smrg
3177117f1b4Smrg
3187e995a2eSmrg   /* The below flush call seems useless because
3197e995a2eSmrg    * gl_context::Texture::CurrentUnit is not used by
3207e995a2eSmrg    * _mesa_update_texture_state() and friends.
3217e995a2eSmrg    *
3227e995a2eSmrg    * However removing the flush
3237e995a2eSmrg    * introduced some blinking textures in UT2004. More investigation is
3247e995a2eSmrg    * needed to find the root cause.
3257e995a2eSmrg    *
3267e995a2eSmrg    * https://bugs.freedesktop.org/show_bug.cgi?id=105436
3277e995a2eSmrg    */
3281463c08dSmrg   FLUSH_VERTICES(ctx, _NEW_TEXTURE_STATE, GL_TEXTURE_BIT);
3297117f1b4Smrg
3307117f1b4Smrg   ctx->Texture.CurrentUnit = texUnit;
3317117f1b4Smrg   if (ctx->Transform.MatrixMode == GL_TEXTURE) {
3327117f1b4Smrg      /* update current stack pointer */
3337117f1b4Smrg      ctx->CurrentStack = &ctx->TextureMatrixStack[texUnit];
3347117f1b4Smrg   }
3357117f1b4Smrg}
3367117f1b4Smrg
3377117f1b4Smrg
3387e995a2eSmrgvoid GLAPIENTRY
3397e995a2eSmrg_mesa_ActiveTexture_no_error(GLenum texture)
3407e995a2eSmrg{
3417e995a2eSmrg   active_texture(texture, true);
3427e995a2eSmrg}
3437e995a2eSmrg
3447e995a2eSmrg
3457e995a2eSmrgvoid GLAPIENTRY
3467e995a2eSmrg_mesa_ActiveTexture(GLenum texture)
3477e995a2eSmrg{
3487e995a2eSmrg   active_texture(texture, false);
3497e995a2eSmrg}
3507e995a2eSmrg
3517e995a2eSmrg
3527117f1b4Smrg/* GL_ARB_multitexture */
3537117f1b4Smrgvoid GLAPIENTRY
354b167d5e7Smrg_mesa_ClientActiveTexture(GLenum texture)
3557117f1b4Smrg{
3567117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
3577117f1b4Smrg   GLuint texUnit = texture - GL_TEXTURE0;
3587117f1b4Smrg
35956e89960Smrg   if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE))
36056e89960Smrg      _mesa_debug(ctx, "glClientActiveTexture %s\n",
3617e995a2eSmrg                  _mesa_enum_to_string(texture));
36256e89960Smrg
3637e995a2eSmrg   if (ctx->Array.ActiveTexture == texUnit)
3647117f1b4Smrg      return;
3657117f1b4Smrg
3667e995a2eSmrg   if (texUnit >= ctx->Const.MaxTextureCoordUnits) {
3677e995a2eSmrg      _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(texture=%s)",
3687e995a2eSmrg                  _mesa_enum_to_string(texture));
36956e89960Smrg      return;
3707e995a2eSmrg   }
37156e89960Smrg
3727e995a2eSmrg   /* Don't flush vertices. This is a "latched" state. */
3737117f1b4Smrg   ctx->Array.ActiveTexture = texUnit;
3747117f1b4Smrg}
3757117f1b4Smrg
3767117f1b4Smrg
3777117f1b4Smrg
3787117f1b4Smrg/**********************************************************************/
3797117f1b4Smrg/*****                    State management                        *****/
3807117f1b4Smrg/**********************************************************************/
3817117f1b4Smrg
3827117f1b4Smrg
3837117f1b4Smrg/**
3847117f1b4Smrg * \note This routine refers to derived texture attribute values to
3857117f1b4Smrg * compute the ENABLE_TEXMAT flags, but is only called on
3867e995a2eSmrg * _NEW_TEXTURE_MATRIX.  On changes to _NEW_TEXTURE_OBJECT/STATE,
3877e995a2eSmrg * the ENABLE_TEXMAT flags are updated by _mesa_update_textures(), below.
3887117f1b4Smrg *
3897117f1b4Smrg * \param ctx GL context.
3907117f1b4Smrg */
3911463c08dSmrgGLbitfield
3927e995a2eSmrg_mesa_update_texture_matrices(struct gl_context *ctx)
3937117f1b4Smrg{
39456e89960Smrg   GLuint u;
3951463c08dSmrg   GLbitfield old_texmat_enabled = ctx->Texture._TexMatEnabled;
3967117f1b4Smrg
39756e89960Smrg   ctx->Texture._TexMatEnabled = 0x0;
3987117f1b4Smrg
39956e89960Smrg   for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
4007e995a2eSmrg      assert(u < ARRAY_SIZE(ctx->TextureMatrixStack));
40156e89960Smrg      if (_math_matrix_is_dirty(ctx->TextureMatrixStack[u].Top)) {
40256e89960Smrg	 _math_matrix_analyse( ctx->TextureMatrixStack[u].Top );
4037117f1b4Smrg
404b167d5e7Smrg	 if (ctx->Texture.Unit[u]._Current &&
40556e89960Smrg	     ctx->TextureMatrixStack[u].Top->type != MATRIX_IDENTITY)
40656e89960Smrg	    ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(u);
4077117f1b4Smrg      }
4087117f1b4Smrg   }
4091463c08dSmrg
4101463c08dSmrg   if (old_texmat_enabled != ctx->Texture._TexMatEnabled)
4111463c08dSmrg      return _NEW_FF_VERT_PROGRAM | _NEW_FF_FRAG_PROGRAM;
4121463c08dSmrg
4131463c08dSmrg   return 0;
4147117f1b4Smrg}
4157117f1b4Smrg
4167117f1b4Smrg
4177e995a2eSmrg/**
4187e995a2eSmrg * Translate GL combiner state into a MODE_x value
4197e995a2eSmrg */
4207e995a2eSmrgstatic uint32_t
4217e995a2eSmrgtex_combine_translate_mode(GLenum envMode, GLenum mode)
4227e995a2eSmrg{
4237e995a2eSmrg   switch (mode) {
4247e995a2eSmrg   case GL_REPLACE: return TEXENV_MODE_REPLACE;
4257e995a2eSmrg   case GL_MODULATE: return TEXENV_MODE_MODULATE;
4267e995a2eSmrg   case GL_ADD:
4277e995a2eSmrg      if (envMode == GL_COMBINE4_NV)
4287e995a2eSmrg	 return TEXENV_MODE_ADD_PRODUCTS_NV;
4297e995a2eSmrg      else
4307e995a2eSmrg	 return TEXENV_MODE_ADD;
4317e995a2eSmrg   case GL_ADD_SIGNED:
4327e995a2eSmrg      if (envMode == GL_COMBINE4_NV)
4337e995a2eSmrg	 return TEXENV_MODE_ADD_PRODUCTS_SIGNED_NV;
4347e995a2eSmrg      else
4357e995a2eSmrg	 return TEXENV_MODE_ADD_SIGNED;
4367e995a2eSmrg   case GL_INTERPOLATE: return TEXENV_MODE_INTERPOLATE;
4377e995a2eSmrg   case GL_SUBTRACT: return TEXENV_MODE_SUBTRACT;
4387e995a2eSmrg   case GL_DOT3_RGB: return TEXENV_MODE_DOT3_RGB;
4397e995a2eSmrg   case GL_DOT3_RGB_EXT: return TEXENV_MODE_DOT3_RGB_EXT;
4407e995a2eSmrg   case GL_DOT3_RGBA: return TEXENV_MODE_DOT3_RGBA;
4417e995a2eSmrg   case GL_DOT3_RGBA_EXT: return TEXENV_MODE_DOT3_RGBA_EXT;
4427e995a2eSmrg   case GL_MODULATE_ADD_ATI: return TEXENV_MODE_MODULATE_ADD_ATI;
4437e995a2eSmrg   case GL_MODULATE_SIGNED_ADD_ATI: return TEXENV_MODE_MODULATE_SIGNED_ADD_ATI;
4447e995a2eSmrg   case GL_MODULATE_SUBTRACT_ATI: return TEXENV_MODE_MODULATE_SUBTRACT_ATI;
4457e995a2eSmrg   default:
4467e995a2eSmrg      unreachable("Invalid TexEnv Combine mode");
4477e995a2eSmrg   }
4487e995a2eSmrg}
4497e995a2eSmrg
4507e995a2eSmrg
4517e995a2eSmrgstatic uint8_t
4527e995a2eSmrgtex_combine_translate_source(GLenum src)
4537e995a2eSmrg{
4547e995a2eSmrg   switch (src) {
4557e995a2eSmrg   case GL_TEXTURE0:
4567e995a2eSmrg   case GL_TEXTURE1:
4577e995a2eSmrg   case GL_TEXTURE2:
4587e995a2eSmrg   case GL_TEXTURE3:
4597e995a2eSmrg   case GL_TEXTURE4:
4607e995a2eSmrg   case GL_TEXTURE5:
4617e995a2eSmrg   case GL_TEXTURE6:
4627e995a2eSmrg   case GL_TEXTURE7: return TEXENV_SRC_TEXTURE0 + (src - GL_TEXTURE0);
4637e995a2eSmrg   case GL_TEXTURE: return TEXENV_SRC_TEXTURE;
4647e995a2eSmrg   case GL_PREVIOUS: return TEXENV_SRC_PREVIOUS;
4657e995a2eSmrg   case GL_PRIMARY_COLOR: return TEXENV_SRC_PRIMARY_COLOR;
4667e995a2eSmrg   case GL_CONSTANT: return TEXENV_SRC_CONSTANT;
4677e995a2eSmrg   case GL_ZERO: return TEXENV_SRC_ZERO;
4687e995a2eSmrg   case GL_ONE: return TEXENV_SRC_ONE;
4697e995a2eSmrg   default:
4707e995a2eSmrg      unreachable("Invalid TexEnv Combine argument source");
4717e995a2eSmrg   }
4727e995a2eSmrg}
4737e995a2eSmrg
4747e995a2eSmrg
4757e995a2eSmrgstatic uint8_t
4767e995a2eSmrgtex_combine_translate_operand(GLenum operand)
4777e995a2eSmrg{
4787e995a2eSmrg   switch (operand) {
4797e995a2eSmrg   case GL_SRC_COLOR: return TEXENV_OPR_COLOR;
4807e995a2eSmrg   case GL_ONE_MINUS_SRC_COLOR: return TEXENV_OPR_ONE_MINUS_COLOR;
4817e995a2eSmrg   case GL_SRC_ALPHA: return TEXENV_OPR_ALPHA;
4827e995a2eSmrg   case GL_ONE_MINUS_SRC_ALPHA: return TEXENV_OPR_ONE_MINUS_ALPHA;
4837e995a2eSmrg   default:
4847e995a2eSmrg      unreachable("Invalid TexEnv Combine argument source");
4857e995a2eSmrg   }
4867e995a2eSmrg}
4877e995a2eSmrg
4887e995a2eSmrg
4897e995a2eSmrgstatic void
4907e995a2eSmrgpack_tex_combine(struct gl_fixedfunc_texture_unit *texUnit)
4917e995a2eSmrg{
4927e995a2eSmrg   struct gl_tex_env_combine_state *state = texUnit->_CurrentCombine;
4937e995a2eSmrg   struct gl_tex_env_combine_packed *packed = &texUnit->_CurrentCombinePacked;
4947e995a2eSmrg
4957e995a2eSmrg   memset(packed, 0, sizeof *packed);
4967e995a2eSmrg
4977e995a2eSmrg   packed->ModeRGB = tex_combine_translate_mode(texUnit->EnvMode, state->ModeRGB);
4987e995a2eSmrg   packed->ModeA = tex_combine_translate_mode(texUnit->EnvMode, state->ModeA);
4997e995a2eSmrg   packed->ScaleShiftRGB = state->ScaleShiftRGB;
5007e995a2eSmrg   packed->ScaleShiftA = state->ScaleShiftA;
5017e995a2eSmrg   packed->NumArgsRGB = state->_NumArgsRGB;
5027e995a2eSmrg   packed->NumArgsA = state->_NumArgsA;
5037e995a2eSmrg
5047e995a2eSmrg   for (int i = 0; i < state->_NumArgsRGB; ++i)
5057e995a2eSmrg   {
5067e995a2eSmrg      packed->ArgsRGB[i].Source = tex_combine_translate_source(state->SourceRGB[i]);
5077e995a2eSmrg      packed->ArgsRGB[i].Operand = tex_combine_translate_operand(state->OperandRGB[i]);
5087e995a2eSmrg   }
5097e995a2eSmrg
5107e995a2eSmrg   for (int i = 0; i < state->_NumArgsA; ++i)
5117e995a2eSmrg   {
5127e995a2eSmrg      packed->ArgsA[i].Source = tex_combine_translate_source(state->SourceA[i]);
5137e995a2eSmrg      packed->ArgsA[i].Operand = tex_combine_translate_operand(state->OperandA[i]);
5147e995a2eSmrg   }
5157e995a2eSmrg}
5167e995a2eSmrg
5177e995a2eSmrg
518c1f859d4Smrg/**
51956e89960Smrg * Examine texture unit's combine/env state to update derived state.
520c1f859d4Smrg */
521c1f859d4Smrgstatic void
5227e995a2eSmrgupdate_tex_combine(struct gl_context *ctx,
5237e995a2eSmrg                   struct gl_texture_unit *texUnit,
5247e995a2eSmrg                   struct gl_fixedfunc_texture_unit *fftexUnit)
525c1f859d4Smrg{
52656e89960Smrg   struct gl_tex_env_combine_state *combine;
52756e89960Smrg
528b167d5e7Smrg   /* No combiners will apply to this. */
529b167d5e7Smrg   if (texUnit->_Current->Target == GL_TEXTURE_BUFFER)
530b167d5e7Smrg      return;
531b167d5e7Smrg
53256e89960Smrg   /* Set the texUnit->_CurrentCombine field to point to the user's combiner
53356e89960Smrg    * state, or the combiner state which is derived from traditional texenv
53456e89960Smrg    * mode.
535c1f859d4Smrg    */
5367e995a2eSmrg   if (fftexUnit->EnvMode == GL_COMBINE ||
5377e995a2eSmrg       fftexUnit->EnvMode == GL_COMBINE4_NV) {
5387e995a2eSmrg      fftexUnit->_CurrentCombine = & fftexUnit->Combine;
539c1f859d4Smrg   }
54056e89960Smrg   else {
54156e89960Smrg      const struct gl_texture_object *texObj = texUnit->_Current;
5421463c08dSmrg      GLenum format = texObj->Image[0][texObj->Attrib.BaseLevel]->_BaseFormat;
543b167d5e7Smrg
544b167d5e7Smrg      if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
5451463c08dSmrg         format = texObj->Attrib.DepthMode;
546c1f859d4Smrg      }
5477e995a2eSmrg      calculate_derived_texenv(&fftexUnit->_EnvMode, fftexUnit->EnvMode, format);
5487e995a2eSmrg      fftexUnit->_CurrentCombine = & fftexUnit->_EnvMode;
549c1f859d4Smrg   }
550c1f859d4Smrg
5517e995a2eSmrg   combine = fftexUnit->_CurrentCombine;
552c1f859d4Smrg
55356e89960Smrg   /* Determine number of source RGB terms in the combiner function */
55456e89960Smrg   switch (combine->ModeRGB) {
55556e89960Smrg   case GL_REPLACE:
55656e89960Smrg      combine->_NumArgsRGB = 1;
55756e89960Smrg      break;
55856e89960Smrg   case GL_ADD:
55956e89960Smrg   case GL_ADD_SIGNED:
5607e995a2eSmrg      if (fftexUnit->EnvMode == GL_COMBINE4_NV)
56156e89960Smrg         combine->_NumArgsRGB = 4;
56256e89960Smrg      else
56356e89960Smrg         combine->_NumArgsRGB = 2;
56456e89960Smrg      break;
56556e89960Smrg   case GL_MODULATE:
56656e89960Smrg   case GL_SUBTRACT:
56756e89960Smrg   case GL_DOT3_RGB:
56856e89960Smrg   case GL_DOT3_RGBA:
56956e89960Smrg   case GL_DOT3_RGB_EXT:
57056e89960Smrg   case GL_DOT3_RGBA_EXT:
57156e89960Smrg      combine->_NumArgsRGB = 2;
57256e89960Smrg      break;
57356e89960Smrg   case GL_INTERPOLATE:
57456e89960Smrg   case GL_MODULATE_ADD_ATI:
57556e89960Smrg   case GL_MODULATE_SIGNED_ADD_ATI:
57656e89960Smrg   case GL_MODULATE_SUBTRACT_ATI:
57756e89960Smrg      combine->_NumArgsRGB = 3;
57856e89960Smrg      break;
57956e89960Smrg   default:
58056e89960Smrg      combine->_NumArgsRGB = 0;
58156e89960Smrg      _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state");
58256e89960Smrg      return;
58356e89960Smrg   }
58456e89960Smrg
58556e89960Smrg   /* Determine number of source Alpha terms in the combiner function */
58656e89960Smrg   switch (combine->ModeA) {
58756e89960Smrg   case GL_REPLACE:
58856e89960Smrg      combine->_NumArgsA = 1;
58956e89960Smrg      break;
59056e89960Smrg   case GL_ADD:
59156e89960Smrg   case GL_ADD_SIGNED:
5927e995a2eSmrg      if (fftexUnit->EnvMode == GL_COMBINE4_NV)
59356e89960Smrg         combine->_NumArgsA = 4;
59456e89960Smrg      else
59556e89960Smrg         combine->_NumArgsA = 2;
59656e89960Smrg      break;
59756e89960Smrg   case GL_MODULATE:
59856e89960Smrg   case GL_SUBTRACT:
59956e89960Smrg      combine->_NumArgsA = 2;
60056e89960Smrg      break;
60156e89960Smrg   case GL_INTERPOLATE:
60256e89960Smrg   case GL_MODULATE_ADD_ATI:
60356e89960Smrg   case GL_MODULATE_SIGNED_ADD_ATI:
60456e89960Smrg   case GL_MODULATE_SUBTRACT_ATI:
60556e89960Smrg      combine->_NumArgsA = 3;
60656e89960Smrg      break;
60756e89960Smrg   default:
60856e89960Smrg      combine->_NumArgsA = 0;
60956e89960Smrg      _mesa_problem(ctx, "invalid Alpha combine mode in update_texture_state");
61056e89960Smrg      break;
6117117f1b4Smrg   }
6127e995a2eSmrg
6137e995a2eSmrg   pack_tex_combine(fftexUnit);
6147117f1b4Smrg}
6157117f1b4Smrg
6167117f1b4Smrgstatic void
617b167d5e7Smrgupdate_texgen(struct gl_context *ctx)
6187117f1b4Smrg{
6197117f1b4Smrg   GLuint unit;
620ac997013Sriastradh
621b167d5e7Smrg   /* Setup texgen for those texture coordinate sets that are in use */
622b167d5e7Smrg   for (unit = 0; unit < ctx->Const.MaxTextureCoordUnits; unit++) {
6237e995a2eSmrg      struct gl_fixedfunc_texture_unit *texUnit =
6247e995a2eSmrg         &ctx->Texture.FixedFuncUnit[unit];
625b167d5e7Smrg
626b167d5e7Smrg      texUnit->_GenFlags = 0x0;
627b167d5e7Smrg
628b167d5e7Smrg      if (!(ctx->Texture._EnabledCoordUnits & (1 << unit)))
629b167d5e7Smrg	 continue;
630b167d5e7Smrg
631b167d5e7Smrg      if (texUnit->TexGenEnabled) {
632b167d5e7Smrg	 if (texUnit->TexGenEnabled & S_BIT) {
633b167d5e7Smrg	    texUnit->_GenFlags |= texUnit->GenS._ModeBit;
634b167d5e7Smrg	 }
635b167d5e7Smrg	 if (texUnit->TexGenEnabled & T_BIT) {
636b167d5e7Smrg	    texUnit->_GenFlags |= texUnit->GenT._ModeBit;
637b167d5e7Smrg	 }
638b167d5e7Smrg	 if (texUnit->TexGenEnabled & R_BIT) {
639b167d5e7Smrg	    texUnit->_GenFlags |= texUnit->GenR._ModeBit;
640b167d5e7Smrg	 }
641b167d5e7Smrg	 if (texUnit->TexGenEnabled & Q_BIT) {
642b167d5e7Smrg	    texUnit->_GenFlags |= texUnit->GenQ._ModeBit;
643b167d5e7Smrg	 }
644b167d5e7Smrg
645b167d5e7Smrg	 ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(unit);
646b167d5e7Smrg	 ctx->Texture._GenFlags |= texUnit->_GenFlags;
647b167d5e7Smrg      }
648b167d5e7Smrg
6497e995a2eSmrg      assert(unit < ARRAY_SIZE(ctx->TextureMatrixStack));
650b167d5e7Smrg      if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY)
651b167d5e7Smrg	 ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
6527117f1b4Smrg   }
653b167d5e7Smrg}
6547117f1b4Smrg
655b167d5e7Smrgstatic struct gl_texture_object *
656b167d5e7Smrgupdate_single_program_texture(struct gl_context *ctx, struct gl_program *prog,
6577e995a2eSmrg                              int unit)
658b167d5e7Smrg{
659b167d5e7Smrg   gl_texture_index target_index;
660b167d5e7Smrg   struct gl_texture_unit *texUnit;
661b167d5e7Smrg   struct gl_texture_object *texObj;
662b167d5e7Smrg   struct gl_sampler_object *sampler;
663b167d5e7Smrg
664b167d5e7Smrg   texUnit = &ctx->Texture.Unit[unit];
665b167d5e7Smrg
666b167d5e7Smrg   /* Note: If more than one bit was set in TexturesUsed[unit], then we should
667b167d5e7Smrg    * have had the draw call rejected already.  From the GL 4.4 specification,
668b167d5e7Smrg    * section 7.10 ("Samplers"):
669b167d5e7Smrg    *
670b167d5e7Smrg    *     "It is not allowed to have variables of different sampler types
671b167d5e7Smrg    *      pointing to the same texture image unit within a program
672b167d5e7Smrg    *      object. This situation can only be detected at the next rendering
673b167d5e7Smrg    *      command issued which triggers shader invocations, and an
674b167d5e7Smrg    *      INVALID_OPERATION error will then be generated."
675ac997013Sriastradh    */
676b167d5e7Smrg   target_index = ffs(prog->TexturesUsed[unit]) - 1;
677b167d5e7Smrg   texObj = texUnit->CurrentTex[target_index];
678ac997013Sriastradh
679b167d5e7Smrg   sampler = texUnit->Sampler ?
680b167d5e7Smrg      texUnit->Sampler : &texObj->Sampler;
6817117f1b4Smrg
682b167d5e7Smrg   if (likely(texObj)) {
6831463c08dSmrg      if (_mesa_is_texture_complete(texObj, sampler,
6841463c08dSmrg                                    ctx->Const.ForceIntegerTexNearest))
685b167d5e7Smrg         return texObj;
686b167d5e7Smrg
687b167d5e7Smrg      _mesa_test_texobj_completeness(ctx, texObj);
6881463c08dSmrg      if (_mesa_is_texture_complete(texObj, sampler,
6891463c08dSmrg                                    ctx->Const.ForceIntegerTexNearest))
690b167d5e7Smrg         return texObj;
691b167d5e7Smrg   }
6927117f1b4Smrg
693b167d5e7Smrg   /* If we've reached this point, we didn't find a complete texture of the
694b167d5e7Smrg    * shader's target.  From the GL 4.4 core specification, section 11.1.3.5
695b167d5e7Smrg    * ("Texture Access"):
696b167d5e7Smrg    *
697b167d5e7Smrg    *     "If a sampler is used in a shader and the sampler’s associated
698b167d5e7Smrg    *      texture is not complete, as defined in section 8.17, (0, 0, 0, 1)
699b167d5e7Smrg    *      will be returned for a non-shadow sampler and 0 for a shadow
700b167d5e7Smrg    *      sampler."
701b167d5e7Smrg    *
702b167d5e7Smrg    * Mesa implements this by creating a hidden texture object with a pixel of
703b167d5e7Smrg    * that value.
7047117f1b4Smrg    */
705b167d5e7Smrg   texObj = _mesa_get_fallback_texture(ctx, target_index);
706b167d5e7Smrg   assert(texObj);
707b167d5e7Smrg
708b167d5e7Smrg   return texObj;
709b167d5e7Smrg}
710b167d5e7Smrg
7117e995a2eSmrgstatic inline void
7127e995a2eSmrgupdate_single_program_texture_state(struct gl_context *ctx,
7137e995a2eSmrg                                    struct gl_program *prog,
7147e995a2eSmrg                                    int unit,
7157e995a2eSmrg                                    BITSET_WORD *enabled_texture_units)
7167e995a2eSmrg{
7177e995a2eSmrg   struct gl_texture_object *texObj;
7187e995a2eSmrg
7197e995a2eSmrg   texObj = update_single_program_texture(ctx, prog, unit);
7207e995a2eSmrg
7217e995a2eSmrg   _mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj);
7227e995a2eSmrg   BITSET_SET(enabled_texture_units, unit);
7237e995a2eSmrg   ctx->Texture._MaxEnabledTexImageUnit =
7247e995a2eSmrg      MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);
7257e995a2eSmrg}
7267e995a2eSmrg
727b167d5e7Smrgstatic void
728b167d5e7Smrgupdate_program_texture_state(struct gl_context *ctx, struct gl_program **prog,
729b167d5e7Smrg                             BITSET_WORD *enabled_texture_units)
730b167d5e7Smrg{
731b167d5e7Smrg   int i;
732b167d5e7Smrg
733b167d5e7Smrg   for (i = 0; i < MESA_SHADER_STAGES; i++) {
7347e995a2eSmrg      GLbitfield mask;
7357e995a2eSmrg      GLuint s;
736b167d5e7Smrg
737b167d5e7Smrg      if (!prog[i])
738b167d5e7Smrg         continue;
7397117f1b4Smrg
7407e995a2eSmrg      mask = prog[i]->SamplersUsed;
7417e995a2eSmrg
7427e995a2eSmrg      while (mask) {
7437e995a2eSmrg         s = u_bit_scan(&mask);
7447e995a2eSmrg
7457e995a2eSmrg         update_single_program_texture_state(ctx, prog[i],
7467e995a2eSmrg                                             prog[i]->SamplerUnits[s],
7477e995a2eSmrg                                             enabled_texture_units);
7487e995a2eSmrg      }
7497e995a2eSmrg
7507e995a2eSmrg      if (unlikely(prog[i]->sh.HasBoundBindlessSampler)) {
7517e995a2eSmrg         /* Loop over bindless samplers bound to texture units.
7527e995a2eSmrg          */
7537e995a2eSmrg         for (s = 0; s < prog[i]->sh.NumBindlessSamplers; s++) {
7547e995a2eSmrg            struct gl_bindless_sampler *sampler =
7557e995a2eSmrg               &prog[i]->sh.BindlessSamplers[s];
7567e995a2eSmrg
7577e995a2eSmrg            if (!sampler->bound)
7587e995a2eSmrg               continue;
7597e995a2eSmrg
7607e995a2eSmrg            update_single_program_texture_state(ctx, prog[i], sampler->unit,
7617e995a2eSmrg                                                enabled_texture_units);
762b167d5e7Smrg         }
763c1f859d4Smrg      }
764b167d5e7Smrg   }
76556e89960Smrg
766b167d5e7Smrg   if (prog[MESA_SHADER_FRAGMENT]) {
767b167d5e7Smrg      const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
768b167d5e7Smrg      ctx->Texture._EnabledCoordUnits |=
7697e995a2eSmrg         (prog[MESA_SHADER_FRAGMENT]->info.inputs_read >> VARYING_SLOT_TEX0) &
770b167d5e7Smrg         coordMask;
771b167d5e7Smrg   }
772b167d5e7Smrg}
773c1f859d4Smrg
774b167d5e7Smrgstatic void
775b167d5e7Smrgupdate_ff_texture_state(struct gl_context *ctx,
776b167d5e7Smrg                        BITSET_WORD *enabled_texture_units)
777b167d5e7Smrg{
778b167d5e7Smrg   int unit;
779c1f859d4Smrg
780b167d5e7Smrg   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
781b167d5e7Smrg      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
7827e995a2eSmrg      struct gl_fixedfunc_texture_unit *fftexUnit =
7837e995a2eSmrg         &ctx->Texture.FixedFuncUnit[unit];
7847e995a2eSmrg      GLbitfield mask;
7857e995a2eSmrg      bool complete;
78656e89960Smrg
7877e995a2eSmrg      if (fftexUnit->Enabled == 0x0)
788b167d5e7Smrg         continue;
789b167d5e7Smrg
790b167d5e7Smrg      /* If a shader already dictated what texture target was used for this
791b167d5e7Smrg       * unit, just go along with it.
792b167d5e7Smrg       */
793b167d5e7Smrg      if (BITSET_TEST(enabled_texture_units, unit))
79456e89960Smrg         continue;
7957117f1b4Smrg
796b167d5e7Smrg      /* From the GL 4.4 compat specification, section 16.2 ("Texture Application"):
797b167d5e7Smrg       *
798b167d5e7Smrg       *     "Texturing is enabled or disabled using the generic Enable and
799b167d5e7Smrg       *      Disable commands, respectively, with the symbolic constants
800b167d5e7Smrg       *      TEXTURE_1D, TEXTURE_2D, TEXTURE_RECTANGLE, TEXTURE_3D, or
801b167d5e7Smrg       *      TEXTURE_CUBE_MAP to enable the one-, two-, rectangular,
802b167d5e7Smrg       *      three-dimensional, or cube map texture, respectively. If more
803b167d5e7Smrg       *      than one of these textures is enabled, the first one enabled
804b167d5e7Smrg       *      from the following list is used:
805b167d5e7Smrg       *
806b167d5e7Smrg       *      • cube map texture
807b167d5e7Smrg       *      • three-dimensional texture
808b167d5e7Smrg       *      • rectangular texture
809b167d5e7Smrg       *      • two-dimensional texture
810b167d5e7Smrg       *      • one-dimensional texture"
811b167d5e7Smrg       *
81256e89960Smrg       * Note that the TEXTURE_x_INDEX values are in high to low priority.
813b167d5e7Smrg       * Also:
814b167d5e7Smrg       *
815b167d5e7Smrg       *     "If a texture unit is disabled or has an invalid or incomplete
816b167d5e7Smrg       *      texture (as defined in section 8.17) bound to it, then blending
817b167d5e7Smrg       *      is disabled for that texture unit. If the texture environment
818b167d5e7Smrg       *      for a given enabled texture unit references a disabled texture
819b167d5e7Smrg       *      unit, or an invalid or incomplete texture that is bound to
820b167d5e7Smrg       *      another unit, then the results of texture blending are
821b167d5e7Smrg       *      undefined."
8227117f1b4Smrg       */
8237e995a2eSmrg      complete = false;
8247e995a2eSmrg      mask = fftexUnit->Enabled;
8257e995a2eSmrg      while (mask) {
8267e995a2eSmrg         const int texIndex = u_bit_scan(&mask);
8277e995a2eSmrg         struct gl_texture_object *texObj = texUnit->CurrentTex[texIndex];
8287e995a2eSmrg         struct gl_sampler_object *sampler = texUnit->Sampler ?
8297e995a2eSmrg            texUnit->Sampler : &texObj->Sampler;
8307e995a2eSmrg
8311463c08dSmrg         if (!_mesa_is_texture_complete(texObj, sampler,
8321463c08dSmrg                                        ctx->Const.ForceIntegerTexNearest)) {
8337e995a2eSmrg            _mesa_test_texobj_completeness(ctx, texObj);
8347e995a2eSmrg         }
8351463c08dSmrg         if (_mesa_is_texture_complete(texObj, sampler,
8361463c08dSmrg                                       ctx->Const.ForceIntegerTexNearest)) {
8377e995a2eSmrg            _mesa_reference_texobj(&texUnit->_Current, texObj);
8387e995a2eSmrg            complete = true;
8397e995a2eSmrg            break;
84056e89960Smrg         }
841c1f859d4Smrg      }
8427117f1b4Smrg
8437e995a2eSmrg      if (!complete)
844b167d5e7Smrg         continue;
8457117f1b4Smrg
84656e89960Smrg      /* if we get here, we know this texture unit is enabled */
847b167d5e7Smrg      BITSET_SET(enabled_texture_units, unit);
848b167d5e7Smrg      ctx->Texture._MaxEnabledTexImageUnit =
849b167d5e7Smrg         MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);
8507117f1b4Smrg
851b167d5e7Smrg      ctx->Texture._EnabledCoordUnits |= 1 << unit;
85256e89960Smrg
8537e995a2eSmrg      update_tex_combine(ctx, texUnit, fftexUnit);
8547e995a2eSmrg   }
8557e995a2eSmrg}
8567e995a2eSmrg
8577e995a2eSmrgstatic void
8587e995a2eSmrgfix_missing_textures_for_atifs(struct gl_context *ctx,
8597e995a2eSmrg                               struct gl_program *prog,
8607e995a2eSmrg                               BITSET_WORD *enabled_texture_units)
8617e995a2eSmrg{
8627e995a2eSmrg   GLbitfield mask = prog->SamplersUsed;
8637e995a2eSmrg
8647e995a2eSmrg   while (mask) {
8657e995a2eSmrg      const int s = u_bit_scan(&mask);
8667e995a2eSmrg      const int unit = prog->SamplerUnits[s];
8677e995a2eSmrg      const gl_texture_index target_index = ffs(prog->TexturesUsed[unit]) - 1;
8687e995a2eSmrg
8697e995a2eSmrg      if (!ctx->Texture.Unit[unit]._Current) {
8707e995a2eSmrg         struct gl_texture_object *texObj =
8717e995a2eSmrg            _mesa_get_fallback_texture(ctx, target_index);
8727e995a2eSmrg         _mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj);
8737e995a2eSmrg         BITSET_SET(enabled_texture_units, unit);
8747e995a2eSmrg         ctx->Texture._MaxEnabledTexImageUnit =
8757e995a2eSmrg            MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);
8767e995a2eSmrg      }
877c1f859d4Smrg   }
878b167d5e7Smrg}
879c1f859d4Smrg
880b167d5e7Smrg/**
881b167d5e7Smrg * \note This routine refers to derived texture matrix values to
882b167d5e7Smrg * compute the ENABLE_TEXMAT flags, but is only called on
8837e995a2eSmrg * _NEW_TEXTURE_OBJECT/STATE.  On changes to _NEW_TEXTURE_MATRIX,
8847e995a2eSmrg * the ENABLE_TEXMAT flags are updated by _mesa_update_texture_matrices,
8857e995a2eSmrg * above.
886b167d5e7Smrg *
887b167d5e7Smrg * \param ctx GL context.
888b167d5e7Smrg */
8891463c08dSmrgGLbitfield
8907e995a2eSmrg_mesa_update_texture_state(struct gl_context *ctx)
891b167d5e7Smrg{
892b167d5e7Smrg   struct gl_program *prog[MESA_SHADER_STAGES];
893b167d5e7Smrg   int i;
894b167d5e7Smrg   int old_max_unit = ctx->Texture._MaxEnabledTexImageUnit;
895b167d5e7Smrg   BITSET_DECLARE(enabled_texture_units, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
896b167d5e7Smrg
8977e995a2eSmrg   memcpy(prog, ctx->_Shader->CurrentProgram, sizeof(prog));
8987e995a2eSmrg
8997e995a2eSmrg   if (prog[MESA_SHADER_FRAGMENT] == NULL &&
9007e995a2eSmrg       _mesa_arb_fragment_program_enabled(ctx)) {
9017e995a2eSmrg      prog[MESA_SHADER_FRAGMENT] = ctx->FragmentProgram.Current;
902c1f859d4Smrg   }
903c1f859d4Smrg
904b167d5e7Smrg   /* TODO: only set this if there are actual changes */
9057e995a2eSmrg   ctx->NewState |= _NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE;
906c1f859d4Smrg
9071463c08dSmrg   GLbitfield old_genflags = ctx->Texture._GenFlags;
9081463c08dSmrg   GLbitfield old_enabled_coord_units = ctx->Texture._EnabledCoordUnits;
9091463c08dSmrg   GLbitfield old_texgen_enabled = ctx->Texture._TexGenEnabled;
9101463c08dSmrg   GLbitfield old_texmat_enabled = ctx->Texture._TexMatEnabled;
9111463c08dSmrg
912b167d5e7Smrg   ctx->Texture._GenFlags = 0x0;
913b167d5e7Smrg   ctx->Texture._TexMatEnabled = 0x0;
914b167d5e7Smrg   ctx->Texture._TexGenEnabled = 0x0;
915b167d5e7Smrg   ctx->Texture._MaxEnabledTexImageUnit = -1;
916b167d5e7Smrg   ctx->Texture._EnabledCoordUnits = 0x0;
91756e89960Smrg
918b167d5e7Smrg   memset(&enabled_texture_units, 0, sizeof(enabled_texture_units));
9197117f1b4Smrg
920b167d5e7Smrg   /* First, walk over our programs pulling in all the textures for them.
921b167d5e7Smrg    * Programs dictate specific texture targets to be enabled, and for a draw
922b167d5e7Smrg    * call to be valid they can't conflict about which texture targets are
923b167d5e7Smrg    * used.
924b167d5e7Smrg    */
925b167d5e7Smrg   update_program_texture_state(ctx, prog, enabled_texture_units);
9267117f1b4Smrg
927b167d5e7Smrg   /* Also pull in any textures necessary for fixed function fragment shading.
928b167d5e7Smrg    */
929b167d5e7Smrg   if (!prog[MESA_SHADER_FRAGMENT])
930b167d5e7Smrg      update_ff_texture_state(ctx, enabled_texture_units);
9317117f1b4Smrg
932b167d5e7Smrg   /* Now, clear out the _Current of any disabled texture units. */
933b167d5e7Smrg   for (i = 0; i <= ctx->Texture._MaxEnabledTexImageUnit; i++) {
934b167d5e7Smrg      if (!BITSET_TEST(enabled_texture_units, i))
935b167d5e7Smrg         _mesa_reference_texobj(&ctx->Texture.Unit[i]._Current, NULL);
936b167d5e7Smrg   }
937b167d5e7Smrg   for (i = ctx->Texture._MaxEnabledTexImageUnit + 1; i <= old_max_unit; i++) {
938b167d5e7Smrg      _mesa_reference_texobj(&ctx->Texture.Unit[i]._Current, NULL);
9397117f1b4Smrg   }
940b167d5e7Smrg
9417e995a2eSmrg   /* add fallback texture for SampleMapATI if there is nothing */
9427e995a2eSmrg   if (_mesa_ati_fragment_shader_enabled(ctx) &&
9437e995a2eSmrg       ctx->ATIFragmentShader.Current->Program)
9447e995a2eSmrg      fix_missing_textures_for_atifs(ctx,
9457e995a2eSmrg                                     ctx->ATIFragmentShader.Current->Program,
9467e995a2eSmrg                                     enabled_texture_units);
9477e995a2eSmrg
948b167d5e7Smrg   if (!prog[MESA_SHADER_FRAGMENT] || !prog[MESA_SHADER_VERTEX])
949b167d5e7Smrg      update_texgen(ctx);
9501463c08dSmrg
9511463c08dSmrg   GLbitfield new_state = 0;
9521463c08dSmrg
9531463c08dSmrg   if (old_enabled_coord_units != ctx->Texture._EnabledCoordUnits ||
9541463c08dSmrg       old_texgen_enabled != ctx->Texture._TexGenEnabled ||
9551463c08dSmrg       old_texmat_enabled != ctx->Texture._TexMatEnabled) {
9561463c08dSmrg      new_state |= _NEW_FF_VERT_PROGRAM | _NEW_FF_FRAG_PROGRAM;
9571463c08dSmrg   }
9581463c08dSmrg
9591463c08dSmrg   if (old_genflags != ctx->Texture._GenFlags)
9601463c08dSmrg      new_state |= _NEW_TNL_SPACES;
9611463c08dSmrg
9621463c08dSmrg   return new_state;
9637117f1b4Smrg}
9647117f1b4Smrg
9657117f1b4Smrg
9667117f1b4Smrg/**********************************************************************/
9677117f1b4Smrg/*****                      Initialization                        *****/
9687117f1b4Smrg/**********************************************************************/
9697117f1b4Smrg
9707117f1b4Smrg/**
9717117f1b4Smrg * Allocate the proxy textures for the given context.
9727e995a2eSmrg *
9737117f1b4Smrg * \param ctx the context to allocate proxies for.
9747e995a2eSmrg *
9757117f1b4Smrg * \return GL_TRUE on success, or GL_FALSE on failure
9767e995a2eSmrg *
9777117f1b4Smrg * If run out of memory part way through the allocations, clean up and return
9787117f1b4Smrg * GL_FALSE.
9797117f1b4Smrg */
9807117f1b4Smrgstatic GLboolean
981ac997013Sriastradhalloc_proxy_textures( struct gl_context *ctx )
9827117f1b4Smrg{
983b167d5e7Smrg   /* NOTE: these values must be in the same order as the TEXTURE_x_INDEX
984b167d5e7Smrg    * values!
985b167d5e7Smrg    */
986c1f859d4Smrg   static const GLenum targets[] = {
987b167d5e7Smrg      GL_TEXTURE_2D_MULTISAMPLE,
988b167d5e7Smrg      GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
989b167d5e7Smrg      GL_TEXTURE_CUBE_MAP_ARRAY,
990b167d5e7Smrg      GL_TEXTURE_BUFFER,
991b167d5e7Smrg      GL_TEXTURE_2D_ARRAY_EXT,
992b167d5e7Smrg      GL_TEXTURE_1D_ARRAY_EXT,
993b167d5e7Smrg      GL_TEXTURE_EXTERNAL_OES,
9947e995a2eSmrg      GL_TEXTURE_CUBE_MAP,
995b167d5e7Smrg      GL_TEXTURE_3D,
996c1f859d4Smrg      GL_TEXTURE_RECTANGLE_NV,
997b167d5e7Smrg      GL_TEXTURE_2D,
998b167d5e7Smrg      GL_TEXTURE_1D,
999c1f859d4Smrg   };
1000c1f859d4Smrg   GLint tgt;
10017117f1b4Smrg
10027e995a2eSmrg   STATIC_ASSERT(ARRAY_SIZE(targets) == NUM_TEXTURE_TARGETS);
1003b167d5e7Smrg   assert(targets[TEXTURE_2D_INDEX] == GL_TEXTURE_2D);
1004b167d5e7Smrg   assert(targets[TEXTURE_CUBE_INDEX] == GL_TEXTURE_CUBE_MAP);
10057117f1b4Smrg
1006c1f859d4Smrg   for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
1007c1f859d4Smrg      if (!(ctx->Texture.ProxyTex[tgt]
1008c1f859d4Smrg            = ctx->Driver.NewTextureObject(ctx, 0, targets[tgt]))) {
1009c1f859d4Smrg         /* out of memory, free what we did allocate */
1010c1f859d4Smrg         while (--tgt >= 0) {
1011c1f859d4Smrg            ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
1012c1f859d4Smrg         }
1013c1f859d4Smrg         return GL_FALSE;
1014c1f859d4Smrg      }
1015c1f859d4Smrg   }
10167117f1b4Smrg
1017c1f859d4Smrg   assert(ctx->Texture.ProxyTex[0]->RefCount == 1); /* sanity check */
10187117f1b4Smrg   return GL_TRUE;
10197117f1b4Smrg}
10207117f1b4Smrg
10217117f1b4Smrg
10227117f1b4Smrg/**
10237117f1b4Smrg * Initialize texture state for the given context.
10247117f1b4Smrg */
10257117f1b4SmrgGLboolean
1026ac997013Sriastradh_mesa_init_texture(struct gl_context *ctx)
10277117f1b4Smrg{
102856e89960Smrg   GLuint u;
10297117f1b4Smrg
10307117f1b4Smrg   /* Texture group */
10317117f1b4Smrg   ctx->Texture.CurrentUnit = 0;      /* multitexture */
1032b167d5e7Smrg
1033b167d5e7Smrg   /* Appendix F.2 of the OpenGL ES 3.0 spec says:
1034b167d5e7Smrg    *
1035b167d5e7Smrg    *     "OpenGL ES 3.0 requires that all cube map filtering be
1036b167d5e7Smrg    *     seamless. OpenGL ES 2.0 specified that a single cube map face be
1037b167d5e7Smrg    *     selected and used for filtering."
10387e995a2eSmrg    *
10397e995a2eSmrg    * Unfortunatley, a call to _mesa_is_gles3 below will only work if
10407e995a2eSmrg    * the driver has already computed and set ctx->Version, however drivers
10417e995a2eSmrg    * seem to call _mesa_initialize_context (which calls this) early
10427e995a2eSmrg    * in the CreateContext hook and _mesa_compute_version much later (since
10437e995a2eSmrg    * it needs information about available extensions). So, we will
10447e995a2eSmrg    * enable seamless cubemaps by default since GLES2. This should work
10457e995a2eSmrg    * for most implementations and drivers that don't support seamless
10467e995a2eSmrg    * cubemaps for GLES2 can still disable it.
1047b167d5e7Smrg    */
10487e995a2eSmrg   ctx->Texture.CubeMapSeamless = ctx->API == API_OPENGLES2;
10497e995a2eSmrg
10507e995a2eSmrg   for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
10517e995a2eSmrg      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
10527e995a2eSmrg      GLuint tex;
10537e995a2eSmrg
10547e995a2eSmrg      /* initialize current texture object ptrs to the shared default objects */
10557e995a2eSmrg      for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
10567e995a2eSmrg         _mesa_reference_texobj(&texUnit->CurrentTex[tex],
10577e995a2eSmrg                                ctx->Shared->DefaultTex[tex]);
10587e995a2eSmrg      }
10597e995a2eSmrg
10607e995a2eSmrg      texUnit->_BoundTextures = 0;
10617e995a2eSmrg   }
10627e995a2eSmrg
10637e995a2eSmrg   for (u = 0; u < ARRAY_SIZE(ctx->Texture.FixedFuncUnit); u++) {
10647e995a2eSmrg      struct gl_fixedfunc_texture_unit *texUnit =
10657e995a2eSmrg         &ctx->Texture.FixedFuncUnit[u];
10667117f1b4Smrg
10677e995a2eSmrg      texUnit->EnvMode = GL_MODULATE;
10687e995a2eSmrg      ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
10697e995a2eSmrg
10707e995a2eSmrg      texUnit->Combine = default_combine_state;
10717e995a2eSmrg      texUnit->_EnvMode = default_combine_state;
10727e995a2eSmrg      texUnit->_CurrentCombine = & texUnit->_EnvMode;
10737e995a2eSmrg
10747e995a2eSmrg      texUnit->TexGenEnabled = 0x0;
10757e995a2eSmrg      texUnit->GenS.Mode = GL_EYE_LINEAR;
10767e995a2eSmrg      texUnit->GenT.Mode = GL_EYE_LINEAR;
10777e995a2eSmrg      texUnit->GenR.Mode = GL_EYE_LINEAR;
10787e995a2eSmrg      texUnit->GenQ.Mode = GL_EYE_LINEAR;
10797e995a2eSmrg      texUnit->GenS._ModeBit = TEXGEN_EYE_LINEAR;
10807e995a2eSmrg      texUnit->GenT._ModeBit = TEXGEN_EYE_LINEAR;
10817e995a2eSmrg      texUnit->GenR._ModeBit = TEXGEN_EYE_LINEAR;
10827e995a2eSmrg      texUnit->GenQ._ModeBit = TEXGEN_EYE_LINEAR;
10837e995a2eSmrg
10847e995a2eSmrg      /* Yes, these plane coefficients are correct! */
10851463c08dSmrg      ASSIGN_4V( texUnit->ObjectPlane[GEN_S], 1.0, 0.0, 0.0, 0.0 );
10861463c08dSmrg      ASSIGN_4V( texUnit->ObjectPlane[GEN_T], 0.0, 1.0, 0.0, 0.0 );
10871463c08dSmrg      ASSIGN_4V( texUnit->ObjectPlane[GEN_R], 0.0, 0.0, 0.0, 0.0 );
10881463c08dSmrg      ASSIGN_4V( texUnit->ObjectPlane[GEN_Q], 0.0, 0.0, 0.0, 0.0 );
10891463c08dSmrg      ASSIGN_4V( texUnit->EyePlane[GEN_S], 1.0, 0.0, 0.0, 0.0 );
10901463c08dSmrg      ASSIGN_4V( texUnit->EyePlane[GEN_T], 0.0, 1.0, 0.0, 0.0 );
10911463c08dSmrg      ASSIGN_4V( texUnit->EyePlane[GEN_R], 0.0, 0.0, 0.0, 0.0 );
10921463c08dSmrg      ASSIGN_4V( texUnit->EyePlane[GEN_Q], 0.0, 0.0, 0.0, 0.0 );
10937e995a2eSmrg   }
10947117f1b4Smrg
10957117f1b4Smrg   /* After we're done initializing the context's texture state the default
10961f16d945Smrg    * texture objects' refcounts should be at least
10971f16d945Smrg    * MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1.
10987117f1b4Smrg    */
1099c1f859d4Smrg   assert(ctx->Shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount
11001f16d945Smrg          >= MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1);
11017117f1b4Smrg
11027117f1b4Smrg   /* Allocate proxy textures */
11037117f1b4Smrg   if (!alloc_proxy_textures( ctx ))
11047117f1b4Smrg      return GL_FALSE;
11057117f1b4Smrg
1106ac997013Sriastradh   /* GL_ARB_texture_buffer_object */
11071463c08dSmrg   _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject, NULL);
1108ac997013Sriastradh
1109b167d5e7Smrg   ctx->Texture.NumCurrentTexUsed = 0;
1110b167d5e7Smrg
11117117f1b4Smrg   return GL_TRUE;
11127117f1b4Smrg}
11137117f1b4Smrg
11147117f1b4Smrg
11157117f1b4Smrg/**
1116c1f859d4Smrg * Free dynamically-allocted texture data attached to the given context.
11177117f1b4Smrg */
11187117f1b4Smrgvoid
1119ac997013Sriastradh_mesa_free_texture_data(struct gl_context *ctx)
11207117f1b4Smrg{
1121c1f859d4Smrg   GLuint u, tgt;
11227117f1b4Smrg
11237117f1b4Smrg   /* unreference current textures */
11247e995a2eSmrg   for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
1125c1f859d4Smrg      /* The _Current texture could account for another reference */
1126c1f859d4Smrg      _mesa_reference_texobj(&ctx->Texture.Unit[u]._Current, NULL);
1127c1f859d4Smrg
1128c1f859d4Smrg      for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
112956e89960Smrg         _mesa_reference_texobj(&ctx->Texture.Unit[u].CurrentTex[tgt], NULL);
1130c1f859d4Smrg      }
11317117f1b4Smrg   }
11327117f1b4Smrg
11337117f1b4Smrg   /* Free proxy texture objects */
1134c1f859d4Smrg   for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++)
1135c1f859d4Smrg      ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
1136c1f859d4Smrg
1137ac997013Sriastradh   /* GL_ARB_texture_buffer_object */
1138ac997013Sriastradh   _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject, NULL);
1139ac997013Sriastradh
11407e995a2eSmrg   for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
1141ac997013Sriastradh      _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[u].Sampler, NULL);
1142ac997013Sriastradh   }
1143c1f859d4Smrg}
1144c1f859d4Smrg
11457117f1b4Smrg
1146c1f859d4Smrg/**
1147c1f859d4Smrg * Update the default texture objects in the given context to reference those
11487e995a2eSmrg * specified in the shared state and release those referencing the old
1149c1f859d4Smrg * shared state.
1150c1f859d4Smrg */
1151c1f859d4Smrgvoid
1152ac997013Sriastradh_mesa_update_default_objects_texture(struct gl_context *ctx)
1153c1f859d4Smrg{
115456e89960Smrg   GLuint u, tex;
11557117f1b4Smrg
11567e995a2eSmrg   for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) {
115756e89960Smrg      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
1158c1f859d4Smrg      for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
1159c1f859d4Smrg         _mesa_reference_texobj(&texUnit->CurrentTex[tex],
1160c1f859d4Smrg                                ctx->Shared->DefaultTex[tex]);
1161c1f859d4Smrg      }
1162c1f859d4Smrg   }
11637117f1b4Smrg}
1164