texstate.c revision b167d5e7
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
257117f1b4Smrg/**
267117f1b4Smrg * \file texstate.c
277117f1b4Smrg *
287117f1b4Smrg * Texture state handling.
297117f1b4Smrg */
307117f1b4Smrg
317117f1b4Smrg#include "glheader.h"
32ac997013Sriastradh#include "bufferobj.h"
337117f1b4Smrg#include "colormac.h"
347117f1b4Smrg#include "colortab.h"
357117f1b4Smrg#include "context.h"
367117f1b4Smrg#include "enums.h"
377117f1b4Smrg#include "macros.h"
38b167d5e7Smrg#include "shaderimage.h"
397117f1b4Smrg#include "texobj.h"
407117f1b4Smrg#include "teximage.h"
417117f1b4Smrg#include "texstate.h"
427117f1b4Smrg#include "mtypes.h"
43b167d5e7Smrg#include "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
717117f1b4Smrg   ASSERT(src);
727117f1b4Smrg   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].Enabled = src->Texture.Unit[u].Enabled;
8256e89960Smrg      dst->Texture.Unit[u].EnvMode = src->Texture.Unit[u].EnvMode;
8356e89960Smrg      COPY_4V(dst->Texture.Unit[u].EnvColor, src->Texture.Unit[u].EnvColor);
8456e89960Smrg      dst->Texture.Unit[u].TexGenEnabled = src->Texture.Unit[u].TexGenEnabled;
8556e89960Smrg      dst->Texture.Unit[u].GenS = src->Texture.Unit[u].GenS;
8656e89960Smrg      dst->Texture.Unit[u].GenT = src->Texture.Unit[u].GenT;
8756e89960Smrg      dst->Texture.Unit[u].GenR = src->Texture.Unit[u].GenR;
8856e89960Smrg      dst->Texture.Unit[u].GenQ = src->Texture.Unit[u].GenQ;
8956e89960Smrg      dst->Texture.Unit[u].LodBias = src->Texture.Unit[u].LodBias;
907117f1b4Smrg
917117f1b4Smrg      /* GL_EXT_texture_env_combine */
9256e89960Smrg      dst->Texture.Unit[u].Combine = src->Texture.Unit[u].Combine;
937117f1b4Smrg
9456e89960Smrg      /*
9556e89960Smrg       * XXX strictly speaking, we should compare texture names/ids and
9656e89960Smrg       * bind textures in the dest context according to id.  For now, only
9756e89960Smrg       * copy bindings if the contexts share the same pool of textures to
9856e89960Smrg       * avoid refcounting bugs.
9956e89960Smrg       */
10056e89960Smrg      if (dst->Shared == src->Shared) {
10156e89960Smrg         /* copy texture object bindings, not contents of texture objects */
10256e89960Smrg         _mesa_lock_context_textures(dst);
1037117f1b4Smrg
10456e89960Smrg         for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
10556e89960Smrg            _mesa_reference_texobj(&dst->Texture.Unit[u].CurrentTex[tex],
10656e89960Smrg                                   src->Texture.Unit[u].CurrentTex[tex]);
107b167d5e7Smrg            if (src->Texture.Unit[u].CurrentTex[tex]) {
108b167d5e7Smrg               dst->Texture.NumCurrentTexUsed =
109b167d5e7Smrg                  MAX2(dst->Texture.NumCurrentTexUsed, u + 1);
110b167d5e7Smrg            }
11156e89960Smrg         }
112b167d5e7Smrg         dst->Texture.Unit[u]._BoundTextures = src->Texture.Unit[u]._BoundTextures;
11356e89960Smrg         _mesa_unlock_context_textures(dst);
11456e89960Smrg      }
1157117f1b4Smrg   }
1167117f1b4Smrg}
1177117f1b4Smrg
1187117f1b4Smrg
1197117f1b4Smrg/*
1207117f1b4Smrg * For debugging
1217117f1b4Smrg */
1227117f1b4Smrgvoid
123ac997013Sriastradh_mesa_print_texunit_state( struct gl_context *ctx, GLuint unit )
1247117f1b4Smrg{
1257117f1b4Smrg   const struct gl_texture_unit *texUnit = ctx->Texture.Unit + unit;
1261f16d945Smrg   printf("Texture Unit %d\n", unit);
1271f16d945Smrg   printf("  GL_TEXTURE_ENV_MODE = %s\n", _mesa_lookup_enum_by_nr(texUnit->EnvMode));
1281f16d945Smrg   printf("  GL_COMBINE_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB));
1291f16d945Smrg   printf("  GL_COMBINE_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA));
1301f16d945Smrg   printf("  GL_SOURCE0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[0]));
1311f16d945Smrg   printf("  GL_SOURCE1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[1]));
1321f16d945Smrg   printf("  GL_SOURCE2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[2]));
1331f16d945Smrg   printf("  GL_SOURCE0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[0]));
1341f16d945Smrg   printf("  GL_SOURCE1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[1]));
1351f16d945Smrg   printf("  GL_SOURCE2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[2]));
1361f16d945Smrg   printf("  GL_OPERAND0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[0]));
1371f16d945Smrg   printf("  GL_OPERAND1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[1]));
1381f16d945Smrg   printf("  GL_OPERAND2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[2]));
1391f16d945Smrg   printf("  GL_OPERAND0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[0]));
1401f16d945Smrg   printf("  GL_OPERAND1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[1]));
1411f16d945Smrg   printf("  GL_OPERAND2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[2]));
1421f16d945Smrg   printf("  GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB);
1431f16d945Smrg   printf("  GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA);
1441f16d945Smrg   printf("  GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit->EnvColor[0], texUnit->EnvColor[1], texUnit->EnvColor[2], texUnit->EnvColor[3]);
145c1f859d4Smrg}
1467117f1b4Smrg
1477117f1b4Smrg
1487117f1b4Smrg
149c1f859d4Smrg/**********************************************************************/
150c1f859d4Smrg/*                       Texture Environment                          */
151c1f859d4Smrg/**********************************************************************/
1527117f1b4Smrg
153c1f859d4Smrg/**
154c1f859d4Smrg * Convert "classic" texture environment to ARB_texture_env_combine style
155c1f859d4Smrg * environments.
156c1f859d4Smrg *
157c1f859d4Smrg * \param state  texture_env_combine state vector to be filled-in.
158c1f859d4Smrg * \param mode   Classic texture environment mode (i.e., \c GL_REPLACE,
159c1f859d4Smrg *               \c GL_BLEND, \c GL_DECAL, etc.).
160c1f859d4Smrg * \param texBaseFormat  Base format of the texture associated with the
161c1f859d4Smrg *               texture unit.
162c1f859d4Smrg */
163c1f859d4Smrgstatic void
164c1f859d4Smrgcalculate_derived_texenv( struct gl_tex_env_combine_state *state,
165c1f859d4Smrg			  GLenum mode, GLenum texBaseFormat )
166c1f859d4Smrg{
167c1f859d4Smrg   GLenum mode_rgb;
168c1f859d4Smrg   GLenum mode_a;
1697117f1b4Smrg
170c1f859d4Smrg   *state = default_combine_state;
1717117f1b4Smrg
172c1f859d4Smrg   switch (texBaseFormat) {
173c1f859d4Smrg   case GL_ALPHA:
174c1f859d4Smrg      state->SourceRGB[0] = GL_PREVIOUS;
175c1f859d4Smrg      break;
1767117f1b4Smrg
177c1f859d4Smrg   case GL_LUMINANCE_ALPHA:
178c1f859d4Smrg   case GL_INTENSITY:
179c1f859d4Smrg   case GL_RGBA:
180c1f859d4Smrg      break;
1817117f1b4Smrg
182c1f859d4Smrg   case GL_LUMINANCE:
183ac997013Sriastradh   case GL_RED:
184ac997013Sriastradh   case GL_RG:
185c1f859d4Smrg   case GL_RGB:
186c1f859d4Smrg   case GL_YCBCR_MESA:
187c1f859d4Smrg      state->SourceA[0] = GL_PREVIOUS;
188c1f859d4Smrg      break;
189c1f859d4Smrg
190c1f859d4Smrg   default:
19156e89960Smrg      _mesa_problem(NULL,
19256e89960Smrg                    "Invalid texBaseFormat 0x%x in calculate_derived_texenv",
19356e89960Smrg                    texBaseFormat);
1947117f1b4Smrg      return;
1957117f1b4Smrg   }
1967117f1b4Smrg
197c1f859d4Smrg   if (mode == GL_REPLACE_EXT)
198c1f859d4Smrg      mode = GL_REPLACE;
1997117f1b4Smrg
200c1f859d4Smrg   switch (mode) {
201c1f859d4Smrg   case GL_REPLACE:
202c1f859d4Smrg   case GL_MODULATE:
203c1f859d4Smrg      mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : mode;
204c1f859d4Smrg      mode_a   = mode;
205c1f859d4Smrg      break;
206c1f859d4Smrg
207c1f859d4Smrg   case GL_DECAL:
208c1f859d4Smrg      mode_rgb = GL_INTERPOLATE;
209c1f859d4Smrg      mode_a   = GL_REPLACE;
210c1f859d4Smrg
211c1f859d4Smrg      state->SourceA[0] = GL_PREVIOUS;
212c1f859d4Smrg
213c1f859d4Smrg      /* Having alpha / luminance / intensity textures replace using the
214c1f859d4Smrg       * incoming fragment color matches the definition in NV_texture_shader.
215c1f859d4Smrg       * The 1.5 spec simply marks these as "undefined".
216c1f859d4Smrg       */
217c1f859d4Smrg      switch (texBaseFormat) {
218c1f859d4Smrg      case GL_ALPHA:
219c1f859d4Smrg      case GL_LUMINANCE:
220c1f859d4Smrg      case GL_LUMINANCE_ALPHA:
221c1f859d4Smrg      case GL_INTENSITY:
222c1f859d4Smrg	 state->SourceRGB[0] = GL_PREVIOUS;
2237117f1b4Smrg	 break;
224ac997013Sriastradh      case GL_RED:
225ac997013Sriastradh      case GL_RG:
226c1f859d4Smrg      case GL_RGB:
227c1f859d4Smrg      case GL_YCBCR_MESA:
228c1f859d4Smrg	 mode_rgb = GL_REPLACE;
2297117f1b4Smrg	 break;
230c1f859d4Smrg      case GL_RGBA:
231c1f859d4Smrg	 state->SourceRGB[2] = GL_TEXTURE;
2327117f1b4Smrg	 break;
233c1f859d4Smrg      }
234c1f859d4Smrg      break;
2357117f1b4Smrg
236c1f859d4Smrg   case GL_BLEND:
237c1f859d4Smrg      mode_rgb = GL_INTERPOLATE;
238c1f859d4Smrg      mode_a   = GL_MODULATE;
2397117f1b4Smrg
240c1f859d4Smrg      switch (texBaseFormat) {
241c1f859d4Smrg      case GL_ALPHA:
242c1f859d4Smrg	 mode_rgb = GL_REPLACE;
243c1f859d4Smrg	 break;
244c1f859d4Smrg      case GL_INTENSITY:
245c1f859d4Smrg	 mode_a = GL_INTERPOLATE;
246c1f859d4Smrg	 state->SourceA[0] = GL_CONSTANT;
247c1f859d4Smrg	 state->OperandA[2] = GL_SRC_ALPHA;
248c1f859d4Smrg	 /* FALLTHROUGH */
249c1f859d4Smrg      case GL_LUMINANCE:
250ac997013Sriastradh      case GL_RED:
251ac997013Sriastradh      case GL_RG:
252c1f859d4Smrg      case GL_RGB:
253c1f859d4Smrg      case GL_LUMINANCE_ALPHA:
254c1f859d4Smrg      case GL_RGBA:
255c1f859d4Smrg      case GL_YCBCR_MESA:
256c1f859d4Smrg	 state->SourceRGB[2] = GL_TEXTURE;
257c1f859d4Smrg	 state->SourceA[2]   = GL_TEXTURE;
258c1f859d4Smrg	 state->SourceRGB[0] = GL_CONSTANT;
259c1f859d4Smrg	 state->OperandRGB[2] = GL_SRC_COLOR;
260c1f859d4Smrg	 break;
261c1f859d4Smrg      }
262c1f859d4Smrg      break;
2637117f1b4Smrg
264c1f859d4Smrg   case GL_ADD:
265c1f859d4Smrg      mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : GL_ADD;
266c1f859d4Smrg      mode_a   = (texBaseFormat == GL_INTENSITY) ? GL_ADD : GL_MODULATE;
267c1f859d4Smrg      break;
2687117f1b4Smrg
269c1f859d4Smrg   default:
270c1f859d4Smrg      _mesa_problem(NULL,
27156e89960Smrg                    "Invalid texture env mode 0x%x in calculate_derived_texenv",
27256e89960Smrg                    mode);
2737117f1b4Smrg      return;
2747117f1b4Smrg   }
275c1f859d4Smrg
276c1f859d4Smrg   state->ModeRGB = (state->SourceRGB[0] != GL_PREVIOUS)
277c1f859d4Smrg       ? mode_rgb : GL_REPLACE;
278c1f859d4Smrg   state->ModeA   = (state->SourceA[0]   != GL_PREVIOUS)
279c1f859d4Smrg       ? mode_a   : GL_REPLACE;
280c1f859d4Smrg}
2817117f1b4Smrg
2827117f1b4Smrg
2837117f1b4Smrg
2847117f1b4Smrg
2857117f1b4Smrg/* GL_ARB_multitexture */
2867117f1b4Smrgvoid GLAPIENTRY
287b167d5e7Smrg_mesa_ActiveTexture(GLenum texture)
2887117f1b4Smrg{
2897117f1b4Smrg   const GLuint texUnit = texture - GL_TEXTURE0;
2901f16d945Smrg   GLuint k;
2911f16d945Smrg   GET_CURRENT_CONTEXT(ctx);
2921f16d945Smrg
2931f16d945Smrg   /* See OpenGL spec for glActiveTexture: */
2941f16d945Smrg   k = MAX2(ctx->Const.MaxCombinedTextureImageUnits,
2951f16d945Smrg            ctx->Const.MaxTextureCoordUnits);
2961f16d945Smrg
2971f16d945Smrg   ASSERT(k <= Elements(ctx->Texture.Unit));
2987117f1b4Smrg
2997117f1b4Smrg   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
3007117f1b4Smrg      _mesa_debug(ctx, "glActiveTexture %s\n",
3017117f1b4Smrg                  _mesa_lookup_enum_by_nr(texture));
3027117f1b4Smrg
3031f16d945Smrg   if (texUnit >= k) {
3041f16d945Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture=%s)",
3051f16d945Smrg                  _mesa_lookup_enum_by_nr(texture));
3067117f1b4Smrg      return;
3077117f1b4Smrg   }
3087117f1b4Smrg
3097117f1b4Smrg   if (ctx->Texture.CurrentUnit == texUnit)
3107117f1b4Smrg      return;
3117117f1b4Smrg
3127117f1b4Smrg   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
3137117f1b4Smrg
3147117f1b4Smrg   ctx->Texture.CurrentUnit = texUnit;
3157117f1b4Smrg   if (ctx->Transform.MatrixMode == GL_TEXTURE) {
3167117f1b4Smrg      /* update current stack pointer */
3177117f1b4Smrg      ctx->CurrentStack = &ctx->TextureMatrixStack[texUnit];
3187117f1b4Smrg   }
3197117f1b4Smrg}
3207117f1b4Smrg
3217117f1b4Smrg
3227117f1b4Smrg/* GL_ARB_multitexture */
3237117f1b4Smrgvoid GLAPIENTRY
324b167d5e7Smrg_mesa_ClientActiveTexture(GLenum texture)
3257117f1b4Smrg{
3267117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
3277117f1b4Smrg   GLuint texUnit = texture - GL_TEXTURE0;
3287117f1b4Smrg
32956e89960Smrg   if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE))
33056e89960Smrg      _mesa_debug(ctx, "glClientActiveTexture %s\n",
33156e89960Smrg                  _mesa_lookup_enum_by_nr(texture));
33256e89960Smrg
3337117f1b4Smrg   if (texUnit >= ctx->Const.MaxTextureCoordUnits) {
3347117f1b4Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(texture)");
3357117f1b4Smrg      return;
3367117f1b4Smrg   }
3377117f1b4Smrg
33856e89960Smrg   if (ctx->Array.ActiveTexture == texUnit)
33956e89960Smrg      return;
34056e89960Smrg
3417117f1b4Smrg   FLUSH_VERTICES(ctx, _NEW_ARRAY);
3427117f1b4Smrg   ctx->Array.ActiveTexture = texUnit;
3437117f1b4Smrg}
3447117f1b4Smrg
3457117f1b4Smrg
3467117f1b4Smrg
3477117f1b4Smrg/**********************************************************************/
3487117f1b4Smrg/*****                    State management                        *****/
3497117f1b4Smrg/**********************************************************************/
3507117f1b4Smrg
3517117f1b4Smrg
3527117f1b4Smrg/**
3537117f1b4Smrg * \note This routine refers to derived texture attribute values to
3547117f1b4Smrg * compute the ENABLE_TEXMAT flags, but is only called on
3557117f1b4Smrg * _NEW_TEXTURE_MATRIX.  On changes to _NEW_TEXTURE, the ENABLE_TEXMAT
3567117f1b4Smrg * flags are updated by _mesa_update_textures(), below.
3577117f1b4Smrg *
3587117f1b4Smrg * \param ctx GL context.
3597117f1b4Smrg */
3607117f1b4Smrgstatic void
361ac997013Sriastradhupdate_texture_matrices( struct gl_context *ctx )
3627117f1b4Smrg{
36356e89960Smrg   GLuint u;
3647117f1b4Smrg
36556e89960Smrg   ctx->Texture._TexMatEnabled = 0x0;
3667117f1b4Smrg
36756e89960Smrg   for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
3681f16d945Smrg      ASSERT(u < Elements(ctx->TextureMatrixStack));
36956e89960Smrg      if (_math_matrix_is_dirty(ctx->TextureMatrixStack[u].Top)) {
37056e89960Smrg	 _math_matrix_analyse( ctx->TextureMatrixStack[u].Top );
3717117f1b4Smrg
372b167d5e7Smrg	 if (ctx->Texture.Unit[u]._Current &&
37356e89960Smrg	     ctx->TextureMatrixStack[u].Top->type != MATRIX_IDENTITY)
37456e89960Smrg	    ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(u);
3757117f1b4Smrg      }
3767117f1b4Smrg   }
3777117f1b4Smrg}
3787117f1b4Smrg
3797117f1b4Smrg
380c1f859d4Smrg/**
38156e89960Smrg * Examine texture unit's combine/env state to update derived state.
382c1f859d4Smrg */
383c1f859d4Smrgstatic void
384ac997013Sriastradhupdate_tex_combine(struct gl_context *ctx, struct gl_texture_unit *texUnit)
385c1f859d4Smrg{
38656e89960Smrg   struct gl_tex_env_combine_state *combine;
38756e89960Smrg
388b167d5e7Smrg   /* No combiners will apply to this. */
389b167d5e7Smrg   if (texUnit->_Current->Target == GL_TEXTURE_BUFFER)
390b167d5e7Smrg      return;
391b167d5e7Smrg
39256e89960Smrg   /* Set the texUnit->_CurrentCombine field to point to the user's combiner
39356e89960Smrg    * state, or the combiner state which is derived from traditional texenv
39456e89960Smrg    * mode.
395c1f859d4Smrg    */
39656e89960Smrg   if (texUnit->EnvMode == GL_COMBINE ||
39756e89960Smrg       texUnit->EnvMode == GL_COMBINE4_NV) {
39856e89960Smrg      texUnit->_CurrentCombine = & texUnit->Combine;
399c1f859d4Smrg   }
40056e89960Smrg   else {
40156e89960Smrg      const struct gl_texture_object *texObj = texUnit->_Current;
40256e89960Smrg      GLenum format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
403b167d5e7Smrg
404b167d5e7Smrg      if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
405b167d5e7Smrg         format = texObj->DepthMode;
406c1f859d4Smrg      }
40756e89960Smrg      calculate_derived_texenv(&texUnit->_EnvMode, texUnit->EnvMode, format);
40856e89960Smrg      texUnit->_CurrentCombine = & texUnit->_EnvMode;
409c1f859d4Smrg   }
410c1f859d4Smrg
41156e89960Smrg   combine = texUnit->_CurrentCombine;
412c1f859d4Smrg
41356e89960Smrg   /* Determine number of source RGB terms in the combiner function */
41456e89960Smrg   switch (combine->ModeRGB) {
41556e89960Smrg   case GL_REPLACE:
41656e89960Smrg      combine->_NumArgsRGB = 1;
41756e89960Smrg      break;
41856e89960Smrg   case GL_ADD:
41956e89960Smrg   case GL_ADD_SIGNED:
42056e89960Smrg      if (texUnit->EnvMode == GL_COMBINE4_NV)
42156e89960Smrg         combine->_NumArgsRGB = 4;
42256e89960Smrg      else
42356e89960Smrg         combine->_NumArgsRGB = 2;
42456e89960Smrg      break;
42556e89960Smrg   case GL_MODULATE:
42656e89960Smrg   case GL_SUBTRACT:
42756e89960Smrg   case GL_DOT3_RGB:
42856e89960Smrg   case GL_DOT3_RGBA:
42956e89960Smrg   case GL_DOT3_RGB_EXT:
43056e89960Smrg   case GL_DOT3_RGBA_EXT:
43156e89960Smrg      combine->_NumArgsRGB = 2;
43256e89960Smrg      break;
43356e89960Smrg   case GL_INTERPOLATE:
43456e89960Smrg   case GL_MODULATE_ADD_ATI:
43556e89960Smrg   case GL_MODULATE_SIGNED_ADD_ATI:
43656e89960Smrg   case GL_MODULATE_SUBTRACT_ATI:
43756e89960Smrg      combine->_NumArgsRGB = 3;
43856e89960Smrg      break;
43956e89960Smrg   default:
44056e89960Smrg      combine->_NumArgsRGB = 0;
44156e89960Smrg      _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state");
44256e89960Smrg      return;
44356e89960Smrg   }
44456e89960Smrg
44556e89960Smrg   /* Determine number of source Alpha terms in the combiner function */
44656e89960Smrg   switch (combine->ModeA) {
44756e89960Smrg   case GL_REPLACE:
44856e89960Smrg      combine->_NumArgsA = 1;
44956e89960Smrg      break;
45056e89960Smrg   case GL_ADD:
45156e89960Smrg   case GL_ADD_SIGNED:
45256e89960Smrg      if (texUnit->EnvMode == GL_COMBINE4_NV)
45356e89960Smrg         combine->_NumArgsA = 4;
45456e89960Smrg      else
45556e89960Smrg         combine->_NumArgsA = 2;
45656e89960Smrg      break;
45756e89960Smrg   case GL_MODULATE:
45856e89960Smrg   case GL_SUBTRACT:
45956e89960Smrg      combine->_NumArgsA = 2;
46056e89960Smrg      break;
46156e89960Smrg   case GL_INTERPOLATE:
46256e89960Smrg   case GL_MODULATE_ADD_ATI:
46356e89960Smrg   case GL_MODULATE_SIGNED_ADD_ATI:
46456e89960Smrg   case GL_MODULATE_SUBTRACT_ATI:
46556e89960Smrg      combine->_NumArgsA = 3;
46656e89960Smrg      break;
46756e89960Smrg   default:
46856e89960Smrg      combine->_NumArgsA = 0;
46956e89960Smrg      _mesa_problem(ctx, "invalid Alpha combine mode in update_texture_state");
47056e89960Smrg      break;
4717117f1b4Smrg   }
4727117f1b4Smrg}
4737117f1b4Smrg
4747117f1b4Smrgstatic void
475b167d5e7Smrgupdate_texgen(struct gl_context *ctx)
4767117f1b4Smrg{
4777117f1b4Smrg   GLuint unit;
478ac997013Sriastradh
479b167d5e7Smrg   /* Setup texgen for those texture coordinate sets that are in use */
480b167d5e7Smrg   for (unit = 0; unit < ctx->Const.MaxTextureCoordUnits; unit++) {
481b167d5e7Smrg      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
482b167d5e7Smrg
483b167d5e7Smrg      texUnit->_GenFlags = 0x0;
484b167d5e7Smrg
485b167d5e7Smrg      if (!(ctx->Texture._EnabledCoordUnits & (1 << unit)))
486b167d5e7Smrg	 continue;
487b167d5e7Smrg
488b167d5e7Smrg      if (texUnit->TexGenEnabled) {
489b167d5e7Smrg	 if (texUnit->TexGenEnabled & S_BIT) {
490b167d5e7Smrg	    texUnit->_GenFlags |= texUnit->GenS._ModeBit;
491b167d5e7Smrg	 }
492b167d5e7Smrg	 if (texUnit->TexGenEnabled & T_BIT) {
493b167d5e7Smrg	    texUnit->_GenFlags |= texUnit->GenT._ModeBit;
494b167d5e7Smrg	 }
495b167d5e7Smrg	 if (texUnit->TexGenEnabled & R_BIT) {
496b167d5e7Smrg	    texUnit->_GenFlags |= texUnit->GenR._ModeBit;
497b167d5e7Smrg	 }
498b167d5e7Smrg	 if (texUnit->TexGenEnabled & Q_BIT) {
499b167d5e7Smrg	    texUnit->_GenFlags |= texUnit->GenQ._ModeBit;
500b167d5e7Smrg	 }
501b167d5e7Smrg
502b167d5e7Smrg	 ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(unit);
503b167d5e7Smrg	 ctx->Texture._GenFlags |= texUnit->_GenFlags;
504b167d5e7Smrg      }
505b167d5e7Smrg
506b167d5e7Smrg      ASSERT(unit < Elements(ctx->TextureMatrixStack));
507b167d5e7Smrg      if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY)
508b167d5e7Smrg	 ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
5097117f1b4Smrg   }
510b167d5e7Smrg}
5117117f1b4Smrg
512b167d5e7Smrgstatic struct gl_texture_object *
513b167d5e7Smrgupdate_single_program_texture(struct gl_context *ctx, struct gl_program *prog,
514b167d5e7Smrg                              int s)
515b167d5e7Smrg{
516b167d5e7Smrg   gl_texture_index target_index;
517b167d5e7Smrg   struct gl_texture_unit *texUnit;
518b167d5e7Smrg   struct gl_texture_object *texObj;
519b167d5e7Smrg   struct gl_sampler_object *sampler;
520b167d5e7Smrg   int unit;
521b167d5e7Smrg
522b167d5e7Smrg   if (!(prog->SamplersUsed & (1 << s)))
523b167d5e7Smrg      return NULL;
524b167d5e7Smrg
525b167d5e7Smrg   unit = prog->SamplerUnits[s];
526b167d5e7Smrg   texUnit = &ctx->Texture.Unit[unit];
527b167d5e7Smrg
528b167d5e7Smrg   /* Note: If more than one bit was set in TexturesUsed[unit], then we should
529b167d5e7Smrg    * have had the draw call rejected already.  From the GL 4.4 specification,
530b167d5e7Smrg    * section 7.10 ("Samplers"):
531b167d5e7Smrg    *
532b167d5e7Smrg    *     "It is not allowed to have variables of different sampler types
533b167d5e7Smrg    *      pointing to the same texture image unit within a program
534b167d5e7Smrg    *      object. This situation can only be detected at the next rendering
535b167d5e7Smrg    *      command issued which triggers shader invocations, and an
536b167d5e7Smrg    *      INVALID_OPERATION error will then be generated."
537ac997013Sriastradh    */
538b167d5e7Smrg   target_index = ffs(prog->TexturesUsed[unit]) - 1;
539b167d5e7Smrg   texObj = texUnit->CurrentTex[target_index];
540ac997013Sriastradh
541b167d5e7Smrg   sampler = texUnit->Sampler ?
542b167d5e7Smrg      texUnit->Sampler : &texObj->Sampler;
5437117f1b4Smrg
544b167d5e7Smrg   if (likely(texObj)) {
545b167d5e7Smrg      if (_mesa_is_texture_complete(texObj, sampler))
546b167d5e7Smrg         return texObj;
547b167d5e7Smrg
548b167d5e7Smrg      _mesa_test_texobj_completeness(ctx, texObj);
549b167d5e7Smrg      if (_mesa_is_texture_complete(texObj, sampler))
550b167d5e7Smrg         return texObj;
551b167d5e7Smrg   }
5527117f1b4Smrg
553b167d5e7Smrg   /* If we've reached this point, we didn't find a complete texture of the
554b167d5e7Smrg    * shader's target.  From the GL 4.4 core specification, section 11.1.3.5
555b167d5e7Smrg    * ("Texture Access"):
556b167d5e7Smrg    *
557b167d5e7Smrg    *     "If a sampler is used in a shader and the sampler’s associated
558b167d5e7Smrg    *      texture is not complete, as defined in section 8.17, (0, 0, 0, 1)
559b167d5e7Smrg    *      will be returned for a non-shadow sampler and 0 for a shadow
560b167d5e7Smrg    *      sampler."
561b167d5e7Smrg    *
562b167d5e7Smrg    * Mesa implements this by creating a hidden texture object with a pixel of
563b167d5e7Smrg    * that value.
5647117f1b4Smrg    */
565b167d5e7Smrg   texObj = _mesa_get_fallback_texture(ctx, target_index);
566b167d5e7Smrg   assert(texObj);
567b167d5e7Smrg
568b167d5e7Smrg   return texObj;
569b167d5e7Smrg}
570b167d5e7Smrg
571b167d5e7Smrgstatic void
572b167d5e7Smrgupdate_program_texture_state(struct gl_context *ctx, struct gl_program **prog,
573b167d5e7Smrg                             BITSET_WORD *enabled_texture_units)
574b167d5e7Smrg{
575b167d5e7Smrg   int i;
576b167d5e7Smrg
577b167d5e7Smrg   for (i = 0; i < MESA_SHADER_STAGES; i++) {
578b167d5e7Smrg      int s;
579b167d5e7Smrg
580b167d5e7Smrg      if (!prog[i])
581b167d5e7Smrg         continue;
5827117f1b4Smrg
583b167d5e7Smrg      /* We can't only do the shifting trick as the loop condition because if
584b167d5e7Smrg       * sampler 31 is active, the next iteration tries to shift by 32, which is
585b167d5e7Smrg       * undefined.
5867117f1b4Smrg       */
587b167d5e7Smrg      for (s = 0; s < MAX_SAMPLERS && (1 << s) <= prog[i]->SamplersUsed; s++) {
588b167d5e7Smrg         struct gl_texture_object *texObj;
589b167d5e7Smrg
590b167d5e7Smrg         texObj = update_single_program_texture(ctx, prog[i], s);
591b167d5e7Smrg         if (texObj) {
592b167d5e7Smrg            int unit = prog[i]->SamplerUnits[s];
593b167d5e7Smrg            _mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj);
594b167d5e7Smrg            BITSET_SET(enabled_texture_units, unit);
595b167d5e7Smrg            ctx->Texture._MaxEnabledTexImageUnit =
596b167d5e7Smrg               MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);
597b167d5e7Smrg         }
598c1f859d4Smrg      }
599b167d5e7Smrg   }
60056e89960Smrg
601b167d5e7Smrg   if (prog[MESA_SHADER_FRAGMENT]) {
602b167d5e7Smrg      const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
603b167d5e7Smrg      ctx->Texture._EnabledCoordUnits |=
604b167d5e7Smrg         (prog[MESA_SHADER_FRAGMENT]->InputsRead >> VARYING_SLOT_TEX0) &
605b167d5e7Smrg         coordMask;
606b167d5e7Smrg   }
607b167d5e7Smrg}
608c1f859d4Smrg
609b167d5e7Smrgstatic void
610b167d5e7Smrgupdate_ff_texture_state(struct gl_context *ctx,
611b167d5e7Smrg                        BITSET_WORD *enabled_texture_units)
612b167d5e7Smrg{
613b167d5e7Smrg   int unit;
614c1f859d4Smrg
615b167d5e7Smrg   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
616b167d5e7Smrg      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
617b167d5e7Smrg      GLuint texIndex;
61856e89960Smrg
619b167d5e7Smrg      if (texUnit->Enabled == 0x0)
620b167d5e7Smrg         continue;
621b167d5e7Smrg
622b167d5e7Smrg      /* If a shader already dictated what texture target was used for this
623b167d5e7Smrg       * unit, just go along with it.
624b167d5e7Smrg       */
625b167d5e7Smrg      if (BITSET_TEST(enabled_texture_units, unit))
62656e89960Smrg         continue;
6277117f1b4Smrg
628b167d5e7Smrg      /* From the GL 4.4 compat specification, section 16.2 ("Texture Application"):
629b167d5e7Smrg       *
630b167d5e7Smrg       *     "Texturing is enabled or disabled using the generic Enable and
631b167d5e7Smrg       *      Disable commands, respectively, with the symbolic constants
632b167d5e7Smrg       *      TEXTURE_1D, TEXTURE_2D, TEXTURE_RECTANGLE, TEXTURE_3D, or
633b167d5e7Smrg       *      TEXTURE_CUBE_MAP to enable the one-, two-, rectangular,
634b167d5e7Smrg       *      three-dimensional, or cube map texture, respectively. If more
635b167d5e7Smrg       *      than one of these textures is enabled, the first one enabled
636b167d5e7Smrg       *      from the following list is used:
637b167d5e7Smrg       *
638b167d5e7Smrg       *      • cube map texture
639b167d5e7Smrg       *      • three-dimensional texture
640b167d5e7Smrg       *      • rectangular texture
641b167d5e7Smrg       *      • two-dimensional texture
642b167d5e7Smrg       *      • one-dimensional texture"
643b167d5e7Smrg       *
64456e89960Smrg       * Note that the TEXTURE_x_INDEX values are in high to low priority.
645b167d5e7Smrg       * Also:
646b167d5e7Smrg       *
647b167d5e7Smrg       *     "If a texture unit is disabled or has an invalid or incomplete
648b167d5e7Smrg       *      texture (as defined in section 8.17) bound to it, then blending
649b167d5e7Smrg       *      is disabled for that texture unit. If the texture environment
650b167d5e7Smrg       *      for a given enabled texture unit references a disabled texture
651b167d5e7Smrg       *      unit, or an invalid or incomplete texture that is bound to
652b167d5e7Smrg       *      another unit, then the results of texture blending are
653b167d5e7Smrg       *      undefined."
6547117f1b4Smrg       */
65556e89960Smrg      for (texIndex = 0; texIndex < NUM_TEXTURE_TARGETS; texIndex++) {
656b167d5e7Smrg         if (texUnit->Enabled & (1 << texIndex)) {
65756e89960Smrg            struct gl_texture_object *texObj = texUnit->CurrentTex[texIndex];
658b167d5e7Smrg            struct gl_sampler_object *sampler = texUnit->Sampler ?
659b167d5e7Smrg               texUnit->Sampler : &texObj->Sampler;
660b167d5e7Smrg
661b167d5e7Smrg            if (!_mesa_is_texture_complete(texObj, sampler)) {
66256e89960Smrg               _mesa_test_texobj_completeness(ctx, texObj);
66356e89960Smrg            }
664b167d5e7Smrg            if (_mesa_is_texture_complete(texObj, sampler)) {
66556e89960Smrg               _mesa_reference_texobj(&texUnit->_Current, texObj);
66656e89960Smrg               break;
66756e89960Smrg            }
66856e89960Smrg         }
669c1f859d4Smrg      }
6707117f1b4Smrg
671b167d5e7Smrg      if (texIndex == NUM_TEXTURE_TARGETS)
672b167d5e7Smrg         continue;
6737117f1b4Smrg
67456e89960Smrg      /* if we get here, we know this texture unit is enabled */
675b167d5e7Smrg      BITSET_SET(enabled_texture_units, unit);
676b167d5e7Smrg      ctx->Texture._MaxEnabledTexImageUnit =
677b167d5e7Smrg         MAX2(ctx->Texture._MaxEnabledTexImageUnit, (int)unit);
6787117f1b4Smrg
679b167d5e7Smrg      ctx->Texture._EnabledCoordUnits |= 1 << unit;
68056e89960Smrg
68156e89960Smrg      update_tex_combine(ctx, texUnit);
682c1f859d4Smrg   }
683b167d5e7Smrg}
684c1f859d4Smrg
685b167d5e7Smrg/**
686b167d5e7Smrg * \note This routine refers to derived texture matrix values to
687b167d5e7Smrg * compute the ENABLE_TEXMAT flags, but is only called on
688b167d5e7Smrg * _NEW_TEXTURE.  On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT
689b167d5e7Smrg * flags are updated by _mesa_update_texture_matrices, above.
690b167d5e7Smrg *
691b167d5e7Smrg * \param ctx GL context.
692b167d5e7Smrg */
693b167d5e7Smrgstatic void
694b167d5e7Smrgupdate_texture_state( struct gl_context *ctx )
695b167d5e7Smrg{
696b167d5e7Smrg   struct gl_program *prog[MESA_SHADER_STAGES];
697b167d5e7Smrg   int i;
698b167d5e7Smrg   int old_max_unit = ctx->Texture._MaxEnabledTexImageUnit;
699b167d5e7Smrg   BITSET_DECLARE(enabled_texture_units, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
700b167d5e7Smrg
701b167d5e7Smrg   for (i = 0; i < MESA_SHADER_STAGES; i++) {
702b167d5e7Smrg      if (ctx->_Shader->CurrentProgram[i] &&
703b167d5e7Smrg          ctx->_Shader->CurrentProgram[i]->LinkStatus) {
704b167d5e7Smrg         prog[i] = ctx->_Shader->CurrentProgram[i]->_LinkedShaders[i]->Program;
705b167d5e7Smrg      } else {
706b167d5e7Smrg         if (i == MESA_SHADER_FRAGMENT && ctx->FragmentProgram._Enabled)
707b167d5e7Smrg            prog[i] = &ctx->FragmentProgram.Current->Base;
708b167d5e7Smrg         else
709b167d5e7Smrg            prog[i] = NULL;
710b167d5e7Smrg      }
711c1f859d4Smrg   }
712c1f859d4Smrg
713b167d5e7Smrg   /* TODO: only set this if there are actual changes */
714b167d5e7Smrg   ctx->NewState |= _NEW_TEXTURE;
715c1f859d4Smrg
716b167d5e7Smrg   ctx->Texture._GenFlags = 0x0;
717b167d5e7Smrg   ctx->Texture._TexMatEnabled = 0x0;
718b167d5e7Smrg   ctx->Texture._TexGenEnabled = 0x0;
719b167d5e7Smrg   ctx->Texture._MaxEnabledTexImageUnit = -1;
720b167d5e7Smrg   ctx->Texture._EnabledCoordUnits = 0x0;
72156e89960Smrg
722b167d5e7Smrg   memset(&enabled_texture_units, 0, sizeof(enabled_texture_units));
7237117f1b4Smrg
724b167d5e7Smrg   /* First, walk over our programs pulling in all the textures for them.
725b167d5e7Smrg    * Programs dictate specific texture targets to be enabled, and for a draw
726b167d5e7Smrg    * call to be valid they can't conflict about which texture targets are
727b167d5e7Smrg    * used.
728b167d5e7Smrg    */
729b167d5e7Smrg   update_program_texture_state(ctx, prog, enabled_texture_units);
7307117f1b4Smrg
731b167d5e7Smrg   /* Also pull in any textures necessary for fixed function fragment shading.
732b167d5e7Smrg    */
733b167d5e7Smrg   if (!prog[MESA_SHADER_FRAGMENT])
734b167d5e7Smrg      update_ff_texture_state(ctx, enabled_texture_units);
7357117f1b4Smrg
736b167d5e7Smrg   /* Now, clear out the _Current of any disabled texture units. */
737b167d5e7Smrg   for (i = 0; i <= ctx->Texture._MaxEnabledTexImageUnit; i++) {
738b167d5e7Smrg      if (!BITSET_TEST(enabled_texture_units, i))
739b167d5e7Smrg         _mesa_reference_texobj(&ctx->Texture.Unit[i]._Current, NULL);
740b167d5e7Smrg   }
741b167d5e7Smrg   for (i = ctx->Texture._MaxEnabledTexImageUnit + 1; i <= old_max_unit; i++) {
742b167d5e7Smrg      _mesa_reference_texobj(&ctx->Texture.Unit[i]._Current, NULL);
7437117f1b4Smrg   }
744b167d5e7Smrg
745b167d5e7Smrg   if (!prog[MESA_SHADER_FRAGMENT] || !prog[MESA_SHADER_VERTEX])
746b167d5e7Smrg      update_texgen(ctx);
747b167d5e7Smrg
748b167d5e7Smrg   _mesa_validate_image_units(ctx);
7497117f1b4Smrg}
7507117f1b4Smrg
7517117f1b4Smrg
7527117f1b4Smrg/**
7537117f1b4Smrg * Update texture-related derived state.
7547117f1b4Smrg */
7557117f1b4Smrgvoid
756ac997013Sriastradh_mesa_update_texture( struct gl_context *ctx, GLuint new_state )
7577117f1b4Smrg{
7587117f1b4Smrg   if (new_state & _NEW_TEXTURE_MATRIX)
7597117f1b4Smrg      update_texture_matrices( ctx );
7607117f1b4Smrg
7617117f1b4Smrg   if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM))
7627117f1b4Smrg      update_texture_state( ctx );
7637117f1b4Smrg}
7647117f1b4Smrg
7657117f1b4Smrg
7667117f1b4Smrg/**********************************************************************/
7677117f1b4Smrg/*****                      Initialization                        *****/
7687117f1b4Smrg/**********************************************************************/
7697117f1b4Smrg
7707117f1b4Smrg/**
7717117f1b4Smrg * Allocate the proxy textures for the given context.
7727117f1b4Smrg *
7737117f1b4Smrg * \param ctx the context to allocate proxies for.
7747117f1b4Smrg *
7757117f1b4Smrg * \return GL_TRUE on success, or GL_FALSE on failure
7767117f1b4Smrg *
7777117f1b4Smrg * If run out of memory part way through the allocations, clean up and return
7787117f1b4Smrg * GL_FALSE.
7797117f1b4Smrg */
7807117f1b4Smrgstatic GLboolean
781ac997013Sriastradhalloc_proxy_textures( struct gl_context *ctx )
7827117f1b4Smrg{
783b167d5e7Smrg   /* NOTE: these values must be in the same order as the TEXTURE_x_INDEX
784b167d5e7Smrg    * values!
785b167d5e7Smrg    */
786c1f859d4Smrg   static const GLenum targets[] = {
787b167d5e7Smrg      GL_TEXTURE_2D_MULTISAMPLE,
788b167d5e7Smrg      GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
789b167d5e7Smrg      GL_TEXTURE_CUBE_MAP_ARRAY,
790b167d5e7Smrg      GL_TEXTURE_BUFFER,
791b167d5e7Smrg      GL_TEXTURE_2D_ARRAY_EXT,
792b167d5e7Smrg      GL_TEXTURE_1D_ARRAY_EXT,
793b167d5e7Smrg      GL_TEXTURE_EXTERNAL_OES,
794c1f859d4Smrg      GL_TEXTURE_CUBE_MAP_ARB,
795b167d5e7Smrg      GL_TEXTURE_3D,
796c1f859d4Smrg      GL_TEXTURE_RECTANGLE_NV,
797b167d5e7Smrg      GL_TEXTURE_2D,
798b167d5e7Smrg      GL_TEXTURE_1D,
799c1f859d4Smrg   };
800c1f859d4Smrg   GLint tgt;
8017117f1b4Smrg
802b167d5e7Smrg   STATIC_ASSERT(Elements(targets) == NUM_TEXTURE_TARGETS);
803b167d5e7Smrg   assert(targets[TEXTURE_2D_INDEX] == GL_TEXTURE_2D);
804b167d5e7Smrg   assert(targets[TEXTURE_CUBE_INDEX] == GL_TEXTURE_CUBE_MAP);
8057117f1b4Smrg
806c1f859d4Smrg   for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
807c1f859d4Smrg      if (!(ctx->Texture.ProxyTex[tgt]
808c1f859d4Smrg            = ctx->Driver.NewTextureObject(ctx, 0, targets[tgt]))) {
809c1f859d4Smrg         /* out of memory, free what we did allocate */
810c1f859d4Smrg         while (--tgt >= 0) {
811c1f859d4Smrg            ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
812c1f859d4Smrg         }
813c1f859d4Smrg         return GL_FALSE;
814c1f859d4Smrg      }
815c1f859d4Smrg   }
8167117f1b4Smrg
817c1f859d4Smrg   assert(ctx->Texture.ProxyTex[0]->RefCount == 1); /* sanity check */
8187117f1b4Smrg   return GL_TRUE;
8197117f1b4Smrg}
8207117f1b4Smrg
8217117f1b4Smrg
8227117f1b4Smrg/**
8237117f1b4Smrg * Initialize a texture unit.
8247117f1b4Smrg *
8257117f1b4Smrg * \param ctx GL context.
8267117f1b4Smrg * \param unit texture unit number to be initialized.
8277117f1b4Smrg */
8287117f1b4Smrgstatic void
829ac997013Sriastradhinit_texture_unit( struct gl_context *ctx, GLuint unit )
8307117f1b4Smrg{
8317117f1b4Smrg   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
832c1f859d4Smrg   GLuint tex;
8337117f1b4Smrg
8347117f1b4Smrg   texUnit->EnvMode = GL_MODULATE;
8357117f1b4Smrg   ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
8367117f1b4Smrg
8377117f1b4Smrg   texUnit->Combine = default_combine_state;
8387117f1b4Smrg   texUnit->_EnvMode = default_combine_state;
8397117f1b4Smrg   texUnit->_CurrentCombine = & texUnit->_EnvMode;
84056e89960Smrg
84156e89960Smrg   texUnit->TexGenEnabled = 0x0;
84256e89960Smrg   texUnit->GenS.Mode = GL_EYE_LINEAR;
84356e89960Smrg   texUnit->GenT.Mode = GL_EYE_LINEAR;
84456e89960Smrg   texUnit->GenR.Mode = GL_EYE_LINEAR;
84556e89960Smrg   texUnit->GenQ.Mode = GL_EYE_LINEAR;
84656e89960Smrg   texUnit->GenS._ModeBit = TEXGEN_EYE_LINEAR;
84756e89960Smrg   texUnit->GenT._ModeBit = TEXGEN_EYE_LINEAR;
84856e89960Smrg   texUnit->GenR._ModeBit = TEXGEN_EYE_LINEAR;
84956e89960Smrg   texUnit->GenQ._ModeBit = TEXGEN_EYE_LINEAR;
8507117f1b4Smrg
8517117f1b4Smrg   /* Yes, these plane coefficients are correct! */
85256e89960Smrg   ASSIGN_4V( texUnit->GenS.ObjectPlane, 1.0, 0.0, 0.0, 0.0 );
85356e89960Smrg   ASSIGN_4V( texUnit->GenT.ObjectPlane, 0.0, 1.0, 0.0, 0.0 );
85456e89960Smrg   ASSIGN_4V( texUnit->GenR.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
85556e89960Smrg   ASSIGN_4V( texUnit->GenQ.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
85656e89960Smrg   ASSIGN_4V( texUnit->GenS.EyePlane, 1.0, 0.0, 0.0, 0.0 );
85756e89960Smrg   ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 );
85856e89960Smrg   ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 );
85956e89960Smrg   ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 );
86056e89960Smrg
8617117f1b4Smrg   /* initialize current texture object ptrs to the shared default objects */
862c1f859d4Smrg   for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
863c1f859d4Smrg      _mesa_reference_texobj(&texUnit->CurrentTex[tex],
864c1f859d4Smrg                             ctx->Shared->DefaultTex[tex]);
865c1f859d4Smrg   }
866b167d5e7Smrg
867b167d5e7Smrg   texUnit->_BoundTextures = 0;
8687117f1b4Smrg}
8697117f1b4Smrg
8707117f1b4Smrg
8717117f1b4Smrg/**
8727117f1b4Smrg * Initialize texture state for the given context.
8737117f1b4Smrg */
8747117f1b4SmrgGLboolean
875ac997013Sriastradh_mesa_init_texture(struct gl_context *ctx)
8767117f1b4Smrg{
87756e89960Smrg   GLuint u;
8787117f1b4Smrg
8797117f1b4Smrg   /* Texture group */
8807117f1b4Smrg   ctx->Texture.CurrentUnit = 0;      /* multitexture */
881b167d5e7Smrg
882b167d5e7Smrg   /* Appendix F.2 of the OpenGL ES 3.0 spec says:
883b167d5e7Smrg    *
884b167d5e7Smrg    *     "OpenGL ES 3.0 requires that all cube map filtering be
885b167d5e7Smrg    *     seamless. OpenGL ES 2.0 specified that a single cube map face be
886b167d5e7Smrg    *     selected and used for filtering."
887b167d5e7Smrg    */
888b167d5e7Smrg   ctx->Texture.CubeMapSeamless = _mesa_is_gles3(ctx);
8897117f1b4Smrg
8901f16d945Smrg   for (u = 0; u < Elements(ctx->Texture.Unit); u++)
89156e89960Smrg      init_texture_unit(ctx, u);
8927117f1b4Smrg
8937117f1b4Smrg   /* After we're done initializing the context's texture state the default
8941f16d945Smrg    * texture objects' refcounts should be at least
8951f16d945Smrg    * MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1.
8967117f1b4Smrg    */
897c1f859d4Smrg   assert(ctx->Shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount
8981f16d945Smrg          >= MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1);
8997117f1b4Smrg
9007117f1b4Smrg   /* Allocate proxy textures */
9017117f1b4Smrg   if (!alloc_proxy_textures( ctx ))
9027117f1b4Smrg      return GL_FALSE;
9037117f1b4Smrg
904ac997013Sriastradh   /* GL_ARB_texture_buffer_object */
905ac997013Sriastradh   _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject,
906ac997013Sriastradh                                 ctx->Shared->NullBufferObj);
907ac997013Sriastradh
908b167d5e7Smrg   ctx->Texture.NumCurrentTexUsed = 0;
909b167d5e7Smrg
9107117f1b4Smrg   return GL_TRUE;
9117117f1b4Smrg}
9127117f1b4Smrg
9137117f1b4Smrg
9147117f1b4Smrg/**
915c1f859d4Smrg * Free dynamically-allocted texture data attached to the given context.
9167117f1b4Smrg */
9177117f1b4Smrgvoid
918ac997013Sriastradh_mesa_free_texture_data(struct gl_context *ctx)
9197117f1b4Smrg{
920c1f859d4Smrg   GLuint u, tgt;
9217117f1b4Smrg
9227117f1b4Smrg   /* unreference current textures */
9231f16d945Smrg   for (u = 0; u < Elements(ctx->Texture.Unit); u++) {
924c1f859d4Smrg      /* The _Current texture could account for another reference */
925c1f859d4Smrg      _mesa_reference_texobj(&ctx->Texture.Unit[u]._Current, NULL);
926c1f859d4Smrg
927c1f859d4Smrg      for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
92856e89960Smrg         _mesa_reference_texobj(&ctx->Texture.Unit[u].CurrentTex[tgt], NULL);
929c1f859d4Smrg      }
9307117f1b4Smrg   }
9317117f1b4Smrg
9327117f1b4Smrg   /* Free proxy texture objects */
933c1f859d4Smrg   for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++)
934c1f859d4Smrg      ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
935c1f859d4Smrg
936ac997013Sriastradh   /* GL_ARB_texture_buffer_object */
937ac997013Sriastradh   _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject, NULL);
938ac997013Sriastradh
939ac997013Sriastradh   for (u = 0; u < Elements(ctx->Texture.Unit); u++) {
940ac997013Sriastradh      _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[u].Sampler, NULL);
941ac997013Sriastradh   }
942c1f859d4Smrg}
943c1f859d4Smrg
9447117f1b4Smrg
945c1f859d4Smrg/**
946c1f859d4Smrg * Update the default texture objects in the given context to reference those
947c1f859d4Smrg * specified in the shared state and release those referencing the old
948c1f859d4Smrg * shared state.
949c1f859d4Smrg */
950c1f859d4Smrgvoid
951ac997013Sriastradh_mesa_update_default_objects_texture(struct gl_context *ctx)
952c1f859d4Smrg{
95356e89960Smrg   GLuint u, tex;
9547117f1b4Smrg
9551f16d945Smrg   for (u = 0; u < Elements(ctx->Texture.Unit); u++) {
95656e89960Smrg      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
957c1f859d4Smrg      for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
958c1f859d4Smrg         _mesa_reference_texobj(&texUnit->CurrentTex[tex],
959c1f859d4Smrg                                ctx->Shared->DefaultTex[tex]);
960c1f859d4Smrg      }
961c1f859d4Smrg   }
9627117f1b4Smrg}
963