texstate.c revision 7117f1b4
17117f1b4Smrg/*
27117f1b4Smrg * Mesa 3-D graphics library
37117f1b4Smrg * Version:  6.5.3
47117f1b4Smrg *
57117f1b4Smrg * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
67117f1b4Smrg *
77117f1b4Smrg * Permission is hereby granted, free of charge, to any person obtaining a
87117f1b4Smrg * copy of this software and associated documentation files (the "Software"),
97117f1b4Smrg * to deal in the Software without restriction, including without limitation
107117f1b4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
117117f1b4Smrg * and/or sell copies of the Software, and to permit persons to whom the
127117f1b4Smrg * Software is furnished to do so, subject to the following conditions:
137117f1b4Smrg *
147117f1b4Smrg * The above copyright notice and this permission notice shall be included
157117f1b4Smrg * in all copies or substantial portions of the Software.
167117f1b4Smrg *
177117f1b4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
187117f1b4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
197117f1b4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
207117f1b4Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
217117f1b4Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
227117f1b4Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
237117f1b4Smrg */
247117f1b4Smrg
257117f1b4Smrg/**
267117f1b4Smrg * \file texstate.c
277117f1b4Smrg *
287117f1b4Smrg * Texture state handling.
297117f1b4Smrg */
307117f1b4Smrg
317117f1b4Smrg#include "glheader.h"
327117f1b4Smrg#include "colormac.h"
337117f1b4Smrg#include "colortab.h"
347117f1b4Smrg#include "context.h"
357117f1b4Smrg#include "enums.h"
367117f1b4Smrg#include "macros.h"
377117f1b4Smrg#include "texcompress.h"
387117f1b4Smrg#include "texobj.h"
397117f1b4Smrg#include "teximage.h"
407117f1b4Smrg#include "texstate.h"
417117f1b4Smrg#include "texenvprogram.h"
427117f1b4Smrg#include "mtypes.h"
437117f1b4Smrg#include "math/m_xform.h"
447117f1b4Smrg
457117f1b4Smrg
467117f1b4Smrg#define ENUM_TO_FLOAT(X) ((GLfloat)(GLint)(X))
477117f1b4Smrg#define ENUM_TO_DOUBLE(X) ((GLdouble)(GLint)(X))
487117f1b4Smrg
497117f1b4Smrg
507117f1b4Smrg/**
517117f1b4Smrg * Default texture combine environment state.  This is used to initialize
527117f1b4Smrg * a context's texture units and as the basis for converting "classic"
537117f1b4Smrg * texture environmnets to ARB_texture_env_combine style values.
547117f1b4Smrg */
557117f1b4Smrgstatic const struct gl_tex_env_combine_state default_combine_state = {
567117f1b4Smrg   GL_MODULATE, GL_MODULATE,
577117f1b4Smrg   { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT },
587117f1b4Smrg   { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT },
597117f1b4Smrg   { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA },
607117f1b4Smrg   { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA },
617117f1b4Smrg   0, 0,
627117f1b4Smrg   2, 2
637117f1b4Smrg};
647117f1b4Smrg
657117f1b4Smrg
667117f1b4Smrg
677117f1b4Smrg/**
687117f1b4Smrg * Used by glXCopyContext to copy texture state from one context to another.
697117f1b4Smrg */
707117f1b4Smrgvoid
717117f1b4Smrg_mesa_copy_texture_state( const GLcontext *src, GLcontext *dst )
727117f1b4Smrg{
737117f1b4Smrg   GLuint i;
747117f1b4Smrg
757117f1b4Smrg   ASSERT(src);
767117f1b4Smrg   ASSERT(dst);
777117f1b4Smrg
787117f1b4Smrg   dst->Texture.CurrentUnit = src->Texture.CurrentUnit;
797117f1b4Smrg   dst->Texture._GenFlags = src->Texture._GenFlags;
807117f1b4Smrg   dst->Texture._TexGenEnabled = src->Texture._TexGenEnabled;
817117f1b4Smrg   dst->Texture._TexMatEnabled = src->Texture._TexMatEnabled;
827117f1b4Smrg   dst->Texture.SharedPalette = src->Texture.SharedPalette;
837117f1b4Smrg
847117f1b4Smrg   /* per-unit state */
857117f1b4Smrg   for (i = 0; i < src->Const.MaxTextureUnits; i++) {
867117f1b4Smrg      dst->Texture.Unit[i].Enabled = src->Texture.Unit[i].Enabled;
877117f1b4Smrg      dst->Texture.Unit[i].EnvMode = src->Texture.Unit[i].EnvMode;
887117f1b4Smrg      COPY_4V(dst->Texture.Unit[i].EnvColor, src->Texture.Unit[i].EnvColor);
897117f1b4Smrg      dst->Texture.Unit[i].TexGenEnabled = src->Texture.Unit[i].TexGenEnabled;
907117f1b4Smrg      dst->Texture.Unit[i].GenModeS = src->Texture.Unit[i].GenModeS;
917117f1b4Smrg      dst->Texture.Unit[i].GenModeT = src->Texture.Unit[i].GenModeT;
927117f1b4Smrg      dst->Texture.Unit[i].GenModeR = src->Texture.Unit[i].GenModeR;
937117f1b4Smrg      dst->Texture.Unit[i].GenModeQ = src->Texture.Unit[i].GenModeQ;
947117f1b4Smrg      dst->Texture.Unit[i]._GenBitS = src->Texture.Unit[i]._GenBitS;
957117f1b4Smrg      dst->Texture.Unit[i]._GenBitT = src->Texture.Unit[i]._GenBitT;
967117f1b4Smrg      dst->Texture.Unit[i]._GenBitR = src->Texture.Unit[i]._GenBitR;
977117f1b4Smrg      dst->Texture.Unit[i]._GenBitQ = src->Texture.Unit[i]._GenBitQ;
987117f1b4Smrg      dst->Texture.Unit[i]._GenFlags = src->Texture.Unit[i]._GenFlags;
997117f1b4Smrg      COPY_4V(dst->Texture.Unit[i].ObjectPlaneS, src->Texture.Unit[i].ObjectPlaneS);
1007117f1b4Smrg      COPY_4V(dst->Texture.Unit[i].ObjectPlaneT, src->Texture.Unit[i].ObjectPlaneT);
1017117f1b4Smrg      COPY_4V(dst->Texture.Unit[i].ObjectPlaneR, src->Texture.Unit[i].ObjectPlaneR);
1027117f1b4Smrg      COPY_4V(dst->Texture.Unit[i].ObjectPlaneQ, src->Texture.Unit[i].ObjectPlaneQ);
1037117f1b4Smrg      COPY_4V(dst->Texture.Unit[i].EyePlaneS, src->Texture.Unit[i].EyePlaneS);
1047117f1b4Smrg      COPY_4V(dst->Texture.Unit[i].EyePlaneT, src->Texture.Unit[i].EyePlaneT);
1057117f1b4Smrg      COPY_4V(dst->Texture.Unit[i].EyePlaneR, src->Texture.Unit[i].EyePlaneR);
1067117f1b4Smrg      COPY_4V(dst->Texture.Unit[i].EyePlaneQ, src->Texture.Unit[i].EyePlaneQ);
1077117f1b4Smrg      dst->Texture.Unit[i].LodBias = src->Texture.Unit[i].LodBias;
1087117f1b4Smrg
1097117f1b4Smrg      /* GL_EXT_texture_env_combine */
1107117f1b4Smrg      dst->Texture.Unit[i].Combine.ModeRGB = src->Texture.Unit[i].Combine.ModeRGB;
1117117f1b4Smrg      dst->Texture.Unit[i].Combine.ModeA = src->Texture.Unit[i].Combine.ModeA;
1127117f1b4Smrg      COPY_3V(dst->Texture.Unit[i].Combine.SourceRGB, src->Texture.Unit[i].Combine.SourceRGB);
1137117f1b4Smrg      COPY_3V(dst->Texture.Unit[i].Combine.SourceA, src->Texture.Unit[i].Combine.SourceA);
1147117f1b4Smrg      COPY_3V(dst->Texture.Unit[i].Combine.OperandRGB, src->Texture.Unit[i].Combine.OperandRGB);
1157117f1b4Smrg      COPY_3V(dst->Texture.Unit[i].Combine.OperandA, src->Texture.Unit[i].Combine.OperandA);
1167117f1b4Smrg      dst->Texture.Unit[i].Combine.ScaleShiftRGB = src->Texture.Unit[i].Combine.ScaleShiftRGB;
1177117f1b4Smrg      dst->Texture.Unit[i].Combine.ScaleShiftA = src->Texture.Unit[i].Combine.ScaleShiftA;
1187117f1b4Smrg
1197117f1b4Smrg      /* copy texture object bindings, not contents of texture objects */
1207117f1b4Smrg      _mesa_lock_context_textures(dst);
1217117f1b4Smrg
1227117f1b4Smrg      _mesa_reference_texobj(&dst->Texture.Unit[i].Current1D,
1237117f1b4Smrg                             src->Texture.Unit[i].Current1D);
1247117f1b4Smrg      _mesa_reference_texobj(&dst->Texture.Unit[i].Current2D,
1257117f1b4Smrg                             src->Texture.Unit[i].Current2D);
1267117f1b4Smrg      _mesa_reference_texobj(&dst->Texture.Unit[i].Current3D,
1277117f1b4Smrg                             src->Texture.Unit[i].Current3D);
1287117f1b4Smrg      _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentCubeMap,
1297117f1b4Smrg                             src->Texture.Unit[i].CurrentCubeMap);
1307117f1b4Smrg      _mesa_reference_texobj(&dst->Texture.Unit[i].CurrentRect,
1317117f1b4Smrg                             src->Texture.Unit[i].CurrentRect);
1327117f1b4Smrg
1337117f1b4Smrg      _mesa_unlock_context_textures(dst);
1347117f1b4Smrg   }
1357117f1b4Smrg}
1367117f1b4Smrg
1377117f1b4Smrg
1387117f1b4Smrg/*
1397117f1b4Smrg * For debugging
1407117f1b4Smrg */
1417117f1b4Smrgvoid
1427117f1b4Smrg_mesa_print_texunit_state( GLcontext *ctx, GLuint unit )
1437117f1b4Smrg{
1447117f1b4Smrg   const struct gl_texture_unit *texUnit = ctx->Texture.Unit + unit;
1457117f1b4Smrg   _mesa_printf("Texture Unit %d\n", unit);
1467117f1b4Smrg   _mesa_printf("  GL_TEXTURE_ENV_MODE = %s\n", _mesa_lookup_enum_by_nr(texUnit->EnvMode));
1477117f1b4Smrg   _mesa_printf("  GL_COMBINE_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB));
1487117f1b4Smrg   _mesa_printf("  GL_COMBINE_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA));
1497117f1b4Smrg   _mesa_printf("  GL_SOURCE0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[0]));
1507117f1b4Smrg   _mesa_printf("  GL_SOURCE1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[1]));
1517117f1b4Smrg   _mesa_printf("  GL_SOURCE2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[2]));
1527117f1b4Smrg   _mesa_printf("  GL_SOURCE0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[0]));
1537117f1b4Smrg   _mesa_printf("  GL_SOURCE1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[1]));
1547117f1b4Smrg   _mesa_printf("  GL_SOURCE2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[2]));
1557117f1b4Smrg   _mesa_printf("  GL_OPERAND0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[0]));
1567117f1b4Smrg   _mesa_printf("  GL_OPERAND1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[1]));
1577117f1b4Smrg   _mesa_printf("  GL_OPERAND2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[2]));
1587117f1b4Smrg   _mesa_printf("  GL_OPERAND0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[0]));
1597117f1b4Smrg   _mesa_printf("  GL_OPERAND1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[1]));
1607117f1b4Smrg   _mesa_printf("  GL_OPERAND2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[2]));
1617117f1b4Smrg   _mesa_printf("  GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB);
1627117f1b4Smrg   _mesa_printf("  GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA);
1637117f1b4Smrg   _mesa_printf("  GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit->EnvColor[0], texUnit->EnvColor[1], texUnit->EnvColor[2], texUnit->EnvColor[3]);
1647117f1b4Smrg}
1657117f1b4Smrg
1667117f1b4Smrg
1677117f1b4Smrg
1687117f1b4Smrg/**********************************************************************/
1697117f1b4Smrg/*                       Texture Environment                          */
1707117f1b4Smrg/**********************************************************************/
1717117f1b4Smrg
1727117f1b4Smrg/**
1737117f1b4Smrg * Convert "classic" texture environment to ARB_texture_env_combine style
1747117f1b4Smrg * environments.
1757117f1b4Smrg *
1767117f1b4Smrg * \param state  texture_env_combine state vector to be filled-in.
1777117f1b4Smrg * \param mode   Classic texture environment mode (i.e., \c GL_REPLACE,
1787117f1b4Smrg *               \c GL_BLEND, \c GL_DECAL, etc.).
1797117f1b4Smrg * \param texBaseFormat  Base format of the texture associated with the
1807117f1b4Smrg *               texture unit.
1817117f1b4Smrg */
1827117f1b4Smrgstatic void
1837117f1b4Smrgcalculate_derived_texenv( struct gl_tex_env_combine_state *state,
1847117f1b4Smrg			  GLenum mode, GLenum texBaseFormat )
1857117f1b4Smrg{
1867117f1b4Smrg   GLenum mode_rgb;
1877117f1b4Smrg   GLenum mode_a;
1887117f1b4Smrg
1897117f1b4Smrg   *state = default_combine_state;
1907117f1b4Smrg
1917117f1b4Smrg   switch (texBaseFormat) {
1927117f1b4Smrg   case GL_ALPHA:
1937117f1b4Smrg      state->SourceRGB[0] = GL_PREVIOUS;
1947117f1b4Smrg      break;
1957117f1b4Smrg
1967117f1b4Smrg   case GL_LUMINANCE_ALPHA:
1977117f1b4Smrg   case GL_INTENSITY:
1987117f1b4Smrg   case GL_RGBA:
1997117f1b4Smrg      break;
2007117f1b4Smrg
2017117f1b4Smrg   case GL_LUMINANCE:
2027117f1b4Smrg   case GL_RGB:
2037117f1b4Smrg   case GL_YCBCR_MESA:
2047117f1b4Smrg      state->SourceA[0] = GL_PREVIOUS;
2057117f1b4Smrg      break;
2067117f1b4Smrg
2077117f1b4Smrg   default:
2087117f1b4Smrg      _mesa_problem(NULL, "Invalid texBaseFormat in calculate_derived_texenv");
2097117f1b4Smrg      return;
2107117f1b4Smrg   }
2117117f1b4Smrg
2127117f1b4Smrg   switch (mode) {
2137117f1b4Smrg   case GL_REPLACE:
2147117f1b4Smrg   case GL_MODULATE:
2157117f1b4Smrg      mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : mode;
2167117f1b4Smrg      mode_a   = mode;
2177117f1b4Smrg      break;
2187117f1b4Smrg
2197117f1b4Smrg   case GL_DECAL:
2207117f1b4Smrg      mode_rgb = GL_INTERPOLATE;
2217117f1b4Smrg      mode_a   = GL_REPLACE;
2227117f1b4Smrg
2237117f1b4Smrg      state->SourceA[0] = GL_PREVIOUS;
2247117f1b4Smrg
2257117f1b4Smrg      /* Having alpha / luminance / intensity textures replace using the
2267117f1b4Smrg       * incoming fragment color matches the definition in NV_texture_shader.
2277117f1b4Smrg       * The 1.5 spec simply marks these as "undefined".
2287117f1b4Smrg       */
2297117f1b4Smrg      switch (texBaseFormat) {
2307117f1b4Smrg      case GL_ALPHA:
2317117f1b4Smrg      case GL_LUMINANCE:
2327117f1b4Smrg      case GL_LUMINANCE_ALPHA:
2337117f1b4Smrg      case GL_INTENSITY:
2347117f1b4Smrg	 state->SourceRGB[0] = GL_PREVIOUS;
2357117f1b4Smrg	 break;
2367117f1b4Smrg      case GL_RGB:
2377117f1b4Smrg      case GL_YCBCR_MESA:
2387117f1b4Smrg	 mode_rgb = GL_REPLACE;
2397117f1b4Smrg	 break;
2407117f1b4Smrg      case GL_RGBA:
2417117f1b4Smrg	 state->SourceRGB[2] = GL_TEXTURE;
2427117f1b4Smrg	 break;
2437117f1b4Smrg      }
2447117f1b4Smrg      break;
2457117f1b4Smrg
2467117f1b4Smrg   case GL_BLEND:
2477117f1b4Smrg      mode_rgb = GL_INTERPOLATE;
2487117f1b4Smrg      mode_a   = GL_MODULATE;
2497117f1b4Smrg
2507117f1b4Smrg      switch (texBaseFormat) {
2517117f1b4Smrg      case GL_ALPHA:
2527117f1b4Smrg	 mode_rgb = GL_REPLACE;
2537117f1b4Smrg	 break;
2547117f1b4Smrg      case GL_INTENSITY:
2557117f1b4Smrg	 mode_a = GL_INTERPOLATE;
2567117f1b4Smrg	 state->SourceA[0] = GL_CONSTANT;
2577117f1b4Smrg	 state->OperandA[2] = GL_SRC_ALPHA;
2587117f1b4Smrg	 /* FALLTHROUGH */
2597117f1b4Smrg      case GL_LUMINANCE:
2607117f1b4Smrg      case GL_RGB:
2617117f1b4Smrg      case GL_LUMINANCE_ALPHA:
2627117f1b4Smrg      case GL_RGBA:
2637117f1b4Smrg      case GL_YCBCR_MESA:
2647117f1b4Smrg	 state->SourceRGB[2] = GL_TEXTURE;
2657117f1b4Smrg	 state->SourceA[2]   = GL_TEXTURE;
2667117f1b4Smrg	 state->SourceRGB[0] = GL_CONSTANT;
2677117f1b4Smrg	 state->OperandRGB[2] = GL_SRC_COLOR;
2687117f1b4Smrg	 break;
2697117f1b4Smrg      }
2707117f1b4Smrg      break;
2717117f1b4Smrg
2727117f1b4Smrg   case GL_ADD:
2737117f1b4Smrg      mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : GL_ADD;
2747117f1b4Smrg      mode_a   = (texBaseFormat == GL_INTENSITY) ? GL_ADD : GL_MODULATE;
2757117f1b4Smrg      break;
2767117f1b4Smrg
2777117f1b4Smrg   default:
2787117f1b4Smrg      _mesa_problem(NULL,
2797117f1b4Smrg                    "Invalid texture env mode in calculate_derived_texenv");
2807117f1b4Smrg      return;
2817117f1b4Smrg   }
2827117f1b4Smrg
2837117f1b4Smrg   state->ModeRGB = (state->SourceRGB[0] != GL_PREVIOUS)
2847117f1b4Smrg       ? mode_rgb : GL_REPLACE;
2857117f1b4Smrg   state->ModeA   = (state->SourceA[0]   != GL_PREVIOUS)
2867117f1b4Smrg       ? mode_a   : GL_REPLACE;
2877117f1b4Smrg}
2887117f1b4Smrg
2897117f1b4Smrg
2907117f1b4Smrgvoid GLAPIENTRY
2917117f1b4Smrg_mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
2927117f1b4Smrg{
2937117f1b4Smrg   GLuint maxUnit;
2947117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
2957117f1b4Smrg   struct gl_texture_unit *texUnit;
2967117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
2977117f1b4Smrg
2987117f1b4Smrg   maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
2997117f1b4Smrg      ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits;
3007117f1b4Smrg   if (ctx->Texture.CurrentUnit >= maxUnit) {
3017117f1b4Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexEnvfv(current unit)");
3027117f1b4Smrg      return;
3037117f1b4Smrg   }
3047117f1b4Smrg
3057117f1b4Smrg   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
3067117f1b4Smrg
3077117f1b4Smrg#define TE_ERROR(errCode, msg, value)				\
3087117f1b4Smrg   _mesa_error(ctx, errCode, msg, _mesa_lookup_enum_by_nr(value));
3097117f1b4Smrg
3107117f1b4Smrg   if (target == GL_TEXTURE_ENV) {
3117117f1b4Smrg      switch (pname) {
3127117f1b4Smrg      case GL_TEXTURE_ENV_MODE:
3137117f1b4Smrg         {
3147117f1b4Smrg            const GLenum mode = (GLenum) (GLint) *param;
3157117f1b4Smrg	    if (texUnit->EnvMode == mode)
3167117f1b4Smrg	       return;
3177117f1b4Smrg            if (mode == GL_MODULATE ||
3187117f1b4Smrg                mode == GL_BLEND ||
3197117f1b4Smrg                mode == GL_DECAL ||
3207117f1b4Smrg                mode == GL_REPLACE ||
3217117f1b4Smrg                (mode == GL_ADD && ctx->Extensions.EXT_texture_env_add) ||
3227117f1b4Smrg                (mode == GL_COMBINE &&
3237117f1b4Smrg                 (ctx->Extensions.EXT_texture_env_combine ||
3247117f1b4Smrg                  ctx->Extensions.ARB_texture_env_combine))) {
3257117f1b4Smrg               /* legal */
3267117f1b4Smrg               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
3277117f1b4Smrg               texUnit->EnvMode = mode;
3287117f1b4Smrg            }
3297117f1b4Smrg            else {
3307117f1b4Smrg               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
3317117f1b4Smrg               return;
3327117f1b4Smrg            }
3337117f1b4Smrg         }
3347117f1b4Smrg         break;
3357117f1b4Smrg      case GL_TEXTURE_ENV_COLOR:
3367117f1b4Smrg         {
3377117f1b4Smrg            GLfloat tmp[4];
3387117f1b4Smrg            tmp[0] = CLAMP( param[0], 0.0F, 1.0F );
3397117f1b4Smrg            tmp[1] = CLAMP( param[1], 0.0F, 1.0F );
3407117f1b4Smrg            tmp[2] = CLAMP( param[2], 0.0F, 1.0F );
3417117f1b4Smrg            tmp[3] = CLAMP( param[3], 0.0F, 1.0F );
3427117f1b4Smrg            if (TEST_EQ_4V(tmp, texUnit->EnvColor))
3437117f1b4Smrg               return;
3447117f1b4Smrg            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
3457117f1b4Smrg            COPY_4FV(texUnit->EnvColor, tmp);
3467117f1b4Smrg         }
3477117f1b4Smrg         break;
3487117f1b4Smrg      case GL_COMBINE_RGB:
3497117f1b4Smrg	 if (ctx->Extensions.EXT_texture_env_combine ||
3507117f1b4Smrg             ctx->Extensions.ARB_texture_env_combine) {
3517117f1b4Smrg	    const GLenum mode = (GLenum) (GLint) *param;
3527117f1b4Smrg	    if (texUnit->Combine.ModeRGB == mode)
3537117f1b4Smrg	       return;
3547117f1b4Smrg	    switch (mode) {
3557117f1b4Smrg	    case GL_REPLACE:
3567117f1b4Smrg	    case GL_MODULATE:
3577117f1b4Smrg	    case GL_ADD:
3587117f1b4Smrg	    case GL_ADD_SIGNED:
3597117f1b4Smrg	    case GL_INTERPOLATE:
3607117f1b4Smrg               /* OK */
3617117f1b4Smrg	       break;
3627117f1b4Smrg            case GL_SUBTRACT:
3637117f1b4Smrg               if (!ctx->Extensions.ARB_texture_env_combine) {
3647117f1b4Smrg                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
3657117f1b4Smrg                  return;
3667117f1b4Smrg               }
3677117f1b4Smrg               break;
3687117f1b4Smrg	    case GL_DOT3_RGB_EXT:
3697117f1b4Smrg	    case GL_DOT3_RGBA_EXT:
3707117f1b4Smrg	       if (!ctx->Extensions.EXT_texture_env_dot3) {
3717117f1b4Smrg                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
3727117f1b4Smrg		  return;
3737117f1b4Smrg	       }
3747117f1b4Smrg	       break;
3757117f1b4Smrg	    case GL_DOT3_RGB:
3767117f1b4Smrg	    case GL_DOT3_RGBA:
3777117f1b4Smrg	       if (!ctx->Extensions.ARB_texture_env_dot3) {
3787117f1b4Smrg                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
3797117f1b4Smrg		  return;
3807117f1b4Smrg	       }
3817117f1b4Smrg	       break;
3827117f1b4Smrg	    case GL_MODULATE_ADD_ATI:
3837117f1b4Smrg	    case GL_MODULATE_SIGNED_ADD_ATI:
3847117f1b4Smrg	    case GL_MODULATE_SUBTRACT_ATI:
3857117f1b4Smrg	       if (!ctx->Extensions.ATI_texture_env_combine3) {
3867117f1b4Smrg                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
3877117f1b4Smrg		  return;
3887117f1b4Smrg	       }
3897117f1b4Smrg	       break;
3907117f1b4Smrg	    default:
3917117f1b4Smrg               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
3927117f1b4Smrg	       return;
3937117f1b4Smrg	    }
3947117f1b4Smrg	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
3957117f1b4Smrg	    texUnit->Combine.ModeRGB = mode;
3967117f1b4Smrg	 }
3977117f1b4Smrg	 else {
3987117f1b4Smrg            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
3997117f1b4Smrg	    return;
4007117f1b4Smrg	 }
4017117f1b4Smrg         break;
4027117f1b4Smrg      case GL_COMBINE_ALPHA:
4037117f1b4Smrg	 if (ctx->Extensions.EXT_texture_env_combine ||
4047117f1b4Smrg             ctx->Extensions.ARB_texture_env_combine) {
4057117f1b4Smrg	    const GLenum mode = (GLenum) (GLint) *param;
4067117f1b4Smrg	    if (texUnit->Combine.ModeA == mode)
4077117f1b4Smrg	       return;
4087117f1b4Smrg            switch (mode) {
4097117f1b4Smrg	    case GL_REPLACE:
4107117f1b4Smrg	    case GL_MODULATE:
4117117f1b4Smrg	    case GL_ADD:
4127117f1b4Smrg	    case GL_ADD_SIGNED:
4137117f1b4Smrg	    case GL_INTERPOLATE:
4147117f1b4Smrg	       /* OK */
4157117f1b4Smrg	       break;
4167117f1b4Smrg	    case GL_SUBTRACT:
4177117f1b4Smrg	       if (!ctx->Extensions.ARB_texture_env_combine) {
4187117f1b4Smrg		  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
4197117f1b4Smrg		  return;
4207117f1b4Smrg	       }
4217117f1b4Smrg	       break;
4227117f1b4Smrg	    case GL_MODULATE_ADD_ATI:
4237117f1b4Smrg	    case GL_MODULATE_SIGNED_ADD_ATI:
4247117f1b4Smrg	    case GL_MODULATE_SUBTRACT_ATI:
4257117f1b4Smrg	       if (!ctx->Extensions.ATI_texture_env_combine3) {
4267117f1b4Smrg                  TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
4277117f1b4Smrg		  return;
4287117f1b4Smrg	       }
4297117f1b4Smrg	       break;
4307117f1b4Smrg	    default:
4317117f1b4Smrg	       TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
4327117f1b4Smrg	       return;
4337117f1b4Smrg	    }
4347117f1b4Smrg	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
4357117f1b4Smrg	    texUnit->Combine.ModeA = mode;
4367117f1b4Smrg	 }
4377117f1b4Smrg	 else {
4387117f1b4Smrg            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
4397117f1b4Smrg	    return;
4407117f1b4Smrg	 }
4417117f1b4Smrg	 break;
4427117f1b4Smrg      case GL_SOURCE0_RGB:
4437117f1b4Smrg      case GL_SOURCE1_RGB:
4447117f1b4Smrg      case GL_SOURCE2_RGB:
4457117f1b4Smrg	 if (ctx->Extensions.EXT_texture_env_combine ||
4467117f1b4Smrg	     ctx->Extensions.ARB_texture_env_combine) {
4477117f1b4Smrg	    const GLenum source = (GLenum) (GLint) *param;
4487117f1b4Smrg	    const GLuint s = pname - GL_SOURCE0_RGB;
4497117f1b4Smrg	    if (texUnit->Combine.SourceRGB[s] == source)
4507117f1b4Smrg	       return;
4517117f1b4Smrg            if (source == GL_TEXTURE ||
4527117f1b4Smrg                source == GL_CONSTANT ||
4537117f1b4Smrg                source == GL_PRIMARY_COLOR ||
4547117f1b4Smrg                source == GL_PREVIOUS ||
4557117f1b4Smrg                (ctx->Extensions.ARB_texture_env_crossbar &&
4567117f1b4Smrg                 source >= GL_TEXTURE0 &&
4577117f1b4Smrg                 source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) ||
4587117f1b4Smrg                (ctx->Extensions.ATI_texture_env_combine3 &&
4597117f1b4Smrg                 (source == GL_ZERO || source == GL_ONE))) {
4607117f1b4Smrg               /* legal */
4617117f1b4Smrg	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
4627117f1b4Smrg	       texUnit->Combine.SourceRGB[s] = source;
4637117f1b4Smrg            }
4647117f1b4Smrg            else {
4657117f1b4Smrg               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
4667117f1b4Smrg	       return;
4677117f1b4Smrg	    }
4687117f1b4Smrg	 }
4697117f1b4Smrg	 else {
4707117f1b4Smrg            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
4717117f1b4Smrg	    return;
4727117f1b4Smrg	 }
4737117f1b4Smrg	 break;
4747117f1b4Smrg      case GL_SOURCE0_ALPHA:
4757117f1b4Smrg      case GL_SOURCE1_ALPHA:
4767117f1b4Smrg      case GL_SOURCE2_ALPHA:
4777117f1b4Smrg	 if (ctx->Extensions.EXT_texture_env_combine ||
4787117f1b4Smrg             ctx->Extensions.ARB_texture_env_combine) {
4797117f1b4Smrg	    const GLenum source = (GLenum) (GLint) *param;
4807117f1b4Smrg	    const GLuint s = pname - GL_SOURCE0_ALPHA;
4817117f1b4Smrg	    if (texUnit->Combine.SourceA[s] == source)
4827117f1b4Smrg	       return;
4837117f1b4Smrg            if (source == GL_TEXTURE ||
4847117f1b4Smrg                source == GL_CONSTANT ||
4857117f1b4Smrg                source == GL_PRIMARY_COLOR ||
4867117f1b4Smrg                source == GL_PREVIOUS ||
4877117f1b4Smrg                (ctx->Extensions.ARB_texture_env_crossbar &&
4887117f1b4Smrg                 source >= GL_TEXTURE0 &&
4897117f1b4Smrg                 source < GL_TEXTURE0 + ctx->Const.MaxTextureUnits) ||
4907117f1b4Smrg		(ctx->Extensions.ATI_texture_env_combine3 &&
4917117f1b4Smrg                 (source == GL_ZERO || source == GL_ONE))) {
4927117f1b4Smrg               /* legal */
4937117f1b4Smrg	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
4947117f1b4Smrg	       texUnit->Combine.SourceA[s] = source;
4957117f1b4Smrg            }
4967117f1b4Smrg            else {
4977117f1b4Smrg               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
4987117f1b4Smrg	       return;
4997117f1b4Smrg	    }
5007117f1b4Smrg	 }
5017117f1b4Smrg	 else {
5027117f1b4Smrg            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
5037117f1b4Smrg	    return;
5047117f1b4Smrg	 }
5057117f1b4Smrg	 break;
5067117f1b4Smrg      case GL_OPERAND0_RGB:
5077117f1b4Smrg      case GL_OPERAND1_RGB:
5087117f1b4Smrg	 if (ctx->Extensions.EXT_texture_env_combine ||
5097117f1b4Smrg	     ctx->Extensions.ARB_texture_env_combine) {
5107117f1b4Smrg	    const GLenum operand = (GLenum) (GLint) *param;
5117117f1b4Smrg	    const GLuint s = pname - GL_OPERAND0_RGB;
5127117f1b4Smrg	    if (texUnit->Combine.OperandRGB[s] == operand)
5137117f1b4Smrg	       return;
5147117f1b4Smrg	    switch (operand) {
5157117f1b4Smrg	    case GL_SRC_COLOR:
5167117f1b4Smrg	    case GL_ONE_MINUS_SRC_COLOR:
5177117f1b4Smrg	    case GL_SRC_ALPHA:
5187117f1b4Smrg	    case GL_ONE_MINUS_SRC_ALPHA:
5197117f1b4Smrg	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
5207117f1b4Smrg	       texUnit->Combine.OperandRGB[s] = operand;
5217117f1b4Smrg	       break;
5227117f1b4Smrg	    default:
5237117f1b4Smrg               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
5247117f1b4Smrg	       return;
5257117f1b4Smrg	    }
5267117f1b4Smrg	 }
5277117f1b4Smrg	 else {
5287117f1b4Smrg            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
5297117f1b4Smrg	    return;
5307117f1b4Smrg	 }
5317117f1b4Smrg	 break;
5327117f1b4Smrg      case GL_OPERAND0_ALPHA:
5337117f1b4Smrg      case GL_OPERAND1_ALPHA:
5347117f1b4Smrg	 if (ctx->Extensions.EXT_texture_env_combine ||
5357117f1b4Smrg             ctx->Extensions.ARB_texture_env_combine) {
5367117f1b4Smrg	    const GLenum operand = (GLenum) (GLint) *param;
5377117f1b4Smrg	    if (texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] == operand)
5387117f1b4Smrg	       return;
5397117f1b4Smrg	    switch (operand) {
5407117f1b4Smrg	    case GL_SRC_ALPHA:
5417117f1b4Smrg	    case GL_ONE_MINUS_SRC_ALPHA:
5427117f1b4Smrg	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
5437117f1b4Smrg	       texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] = operand;
5447117f1b4Smrg	       break;
5457117f1b4Smrg	    default:
5467117f1b4Smrg               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
5477117f1b4Smrg	       return;
5487117f1b4Smrg	    }
5497117f1b4Smrg	 }
5507117f1b4Smrg	 else {
5517117f1b4Smrg            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
5527117f1b4Smrg	    return;
5537117f1b4Smrg	 }
5547117f1b4Smrg	 break;
5557117f1b4Smrg      case GL_OPERAND2_RGB:
5567117f1b4Smrg	 if (ctx->Extensions.ARB_texture_env_combine) {
5577117f1b4Smrg	    const GLenum operand = (GLenum) (GLint) *param;
5587117f1b4Smrg	    if (texUnit->Combine.OperandRGB[2] == operand)
5597117f1b4Smrg	       return;
5607117f1b4Smrg	    switch (operand) {
5617117f1b4Smrg	    case GL_SRC_COLOR:           /* ARB combine only */
5627117f1b4Smrg	    case GL_ONE_MINUS_SRC_COLOR: /* ARB combine only */
5637117f1b4Smrg	    case GL_SRC_ALPHA:
5647117f1b4Smrg	    case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
5657117f1b4Smrg	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
5667117f1b4Smrg	       texUnit->Combine.OperandRGB[2] = operand;
5677117f1b4Smrg               break;
5687117f1b4Smrg	    default:
5697117f1b4Smrg               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
5707117f1b4Smrg	       return;
5717117f1b4Smrg	    }
5727117f1b4Smrg	 }
5737117f1b4Smrg	 else if (ctx->Extensions.EXT_texture_env_combine) {
5747117f1b4Smrg	    const GLenum operand = (GLenum) (GLint) *param;
5757117f1b4Smrg	    if (texUnit->Combine.OperandRGB[2] == operand)
5767117f1b4Smrg	       return;
5777117f1b4Smrg	    /* operand must be GL_SRC_ALPHA which is the initial value - thus
5787117f1b4Smrg	       don't need to actually compare the operand to the possible value */
5797117f1b4Smrg	    else {
5807117f1b4Smrg               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
5817117f1b4Smrg	       return;
5827117f1b4Smrg	    }
5837117f1b4Smrg	 }
5847117f1b4Smrg	 else {
5857117f1b4Smrg            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
5867117f1b4Smrg	    return;
5877117f1b4Smrg	 }
5887117f1b4Smrg	 break;
5897117f1b4Smrg      case GL_OPERAND2_ALPHA:
5907117f1b4Smrg	 if (ctx->Extensions.ARB_texture_env_combine) {
5917117f1b4Smrg	    const GLenum operand = (GLenum) (GLint) *param;
5927117f1b4Smrg	    if (texUnit->Combine.OperandA[2] == operand)
5937117f1b4Smrg	       return;
5947117f1b4Smrg	    switch (operand) {
5957117f1b4Smrg	    case GL_SRC_ALPHA:
5967117f1b4Smrg	    case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
5977117f1b4Smrg	       FLUSH_VERTICES(ctx, _NEW_TEXTURE);
5987117f1b4Smrg	       texUnit->Combine.OperandA[2] = operand;
5997117f1b4Smrg	       break;
6007117f1b4Smrg	    default:
6017117f1b4Smrg               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
6027117f1b4Smrg	       return;
6037117f1b4Smrg	    }
6047117f1b4Smrg	 }
6057117f1b4Smrg	 else if (ctx->Extensions.EXT_texture_env_combine) {
6067117f1b4Smrg	    const GLenum operand = (GLenum) (GLint) *param;
6077117f1b4Smrg	    if (texUnit->Combine.OperandA[2] == operand)
6087117f1b4Smrg	       return;
6097117f1b4Smrg	    /* operand must be GL_SRC_ALPHA which is the initial value - thus
6107117f1b4Smrg	       don't need to actually compare the operand to the possible value */
6117117f1b4Smrg	    else {
6127117f1b4Smrg               TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand);
6137117f1b4Smrg	       return;
6147117f1b4Smrg	    }
6157117f1b4Smrg	 }
6167117f1b4Smrg	 else {
6177117f1b4Smrg            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
6187117f1b4Smrg	    return;
6197117f1b4Smrg	 }
6207117f1b4Smrg	 break;
6217117f1b4Smrg      case GL_RGB_SCALE:
6227117f1b4Smrg	 if (ctx->Extensions.EXT_texture_env_combine ||
6237117f1b4Smrg             ctx->Extensions.ARB_texture_env_combine) {
6247117f1b4Smrg	    GLuint newshift;
6257117f1b4Smrg	    if (*param == 1.0) {
6267117f1b4Smrg	       newshift = 0;
6277117f1b4Smrg	    }
6287117f1b4Smrg	    else if (*param == 2.0) {
6297117f1b4Smrg	       newshift = 1;
6307117f1b4Smrg	    }
6317117f1b4Smrg	    else if (*param == 4.0) {
6327117f1b4Smrg	       newshift = 2;
6337117f1b4Smrg	    }
6347117f1b4Smrg	    else {
6357117f1b4Smrg	       _mesa_error( ctx, GL_INVALID_VALUE,
6367117f1b4Smrg                            "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" );
6377117f1b4Smrg	       return;
6387117f1b4Smrg	    }
6397117f1b4Smrg	    if (texUnit->Combine.ScaleShiftRGB == newshift)
6407117f1b4Smrg	       return;
6417117f1b4Smrg	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
6427117f1b4Smrg	    texUnit->Combine.ScaleShiftRGB = newshift;
6437117f1b4Smrg	 }
6447117f1b4Smrg	 else {
6457117f1b4Smrg            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
6467117f1b4Smrg	    return;
6477117f1b4Smrg	 }
6487117f1b4Smrg	 break;
6497117f1b4Smrg      case GL_ALPHA_SCALE:
6507117f1b4Smrg	 if (ctx->Extensions.EXT_texture_env_combine ||
6517117f1b4Smrg             ctx->Extensions.ARB_texture_env_combine) {
6527117f1b4Smrg	    GLuint newshift;
6537117f1b4Smrg	    if (*param == 1.0) {
6547117f1b4Smrg	       newshift = 0;
6557117f1b4Smrg	    }
6567117f1b4Smrg	    else if (*param == 2.0) {
6577117f1b4Smrg	       newshift = 1;
6587117f1b4Smrg	    }
6597117f1b4Smrg	    else if (*param == 4.0) {
6607117f1b4Smrg	       newshift = 2;
6617117f1b4Smrg	    }
6627117f1b4Smrg	    else {
6637117f1b4Smrg	       _mesa_error( ctx, GL_INVALID_VALUE,
6647117f1b4Smrg                            "glTexEnv(GL_ALPHA_SCALE not 1, 2 or 4)" );
6657117f1b4Smrg	       return;
6667117f1b4Smrg	    }
6677117f1b4Smrg	    if (texUnit->Combine.ScaleShiftA == newshift)
6687117f1b4Smrg	       return;
6697117f1b4Smrg	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
6707117f1b4Smrg	    texUnit->Combine.ScaleShiftA = newshift;
6717117f1b4Smrg	 }
6727117f1b4Smrg	 else {
6737117f1b4Smrg            TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
6747117f1b4Smrg	    return;
6757117f1b4Smrg	 }
6767117f1b4Smrg	 break;
6777117f1b4Smrg      default:
6787117f1b4Smrg	 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname)" );
6797117f1b4Smrg	 return;
6807117f1b4Smrg      }
6817117f1b4Smrg   }
6827117f1b4Smrg   else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
6837117f1b4Smrg      /* GL_EXT_texture_lod_bias */
6847117f1b4Smrg      if (!ctx->Extensions.EXT_texture_lod_bias) {
6857117f1b4Smrg	 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
6867117f1b4Smrg	 return;
6877117f1b4Smrg      }
6887117f1b4Smrg      if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
6897117f1b4Smrg	 if (texUnit->LodBias == param[0])
6907117f1b4Smrg	    return;
6917117f1b4Smrg	 FLUSH_VERTICES(ctx, _NEW_TEXTURE);
6927117f1b4Smrg         texUnit->LodBias = param[0];
6937117f1b4Smrg      }
6947117f1b4Smrg      else {
6957117f1b4Smrg         TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
6967117f1b4Smrg	 return;
6977117f1b4Smrg      }
6987117f1b4Smrg   }
6997117f1b4Smrg   else if (target == GL_POINT_SPRITE_NV) {
7007117f1b4Smrg      /* GL_ARB_point_sprite / GL_NV_point_sprite */
7017117f1b4Smrg      if (!ctx->Extensions.NV_point_sprite
7027117f1b4Smrg	  && !ctx->Extensions.ARB_point_sprite) {
7037117f1b4Smrg	 _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target );
7047117f1b4Smrg	 return;
7057117f1b4Smrg      }
7067117f1b4Smrg      if (pname == GL_COORD_REPLACE_NV) {
7077117f1b4Smrg         const GLenum value = (GLenum) param[0];
7087117f1b4Smrg         if (value == GL_TRUE || value == GL_FALSE) {
7097117f1b4Smrg            /* It's kind of weird to set point state via glTexEnv,
7107117f1b4Smrg             * but that's what the spec calls for.
7117117f1b4Smrg             */
7127117f1b4Smrg            const GLboolean state = (GLboolean) value;
7137117f1b4Smrg            if (ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] == state)
7147117f1b4Smrg               return;
7157117f1b4Smrg            FLUSH_VERTICES(ctx, _NEW_POINT);
7167117f1b4Smrg            ctx->Point.CoordReplace[ctx->Texture.CurrentUnit] = state;
7177117f1b4Smrg         }
7187117f1b4Smrg         else {
7197117f1b4Smrg            _mesa_error( ctx, GL_INVALID_VALUE, "glTexEnv(param=0x%x)", value);
7207117f1b4Smrg            return;
7217117f1b4Smrg         }
7227117f1b4Smrg      }
7237117f1b4Smrg      else {
7247117f1b4Smrg         _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(pname=0x%x)", pname );
7257117f1b4Smrg         return;
7267117f1b4Smrg      }
7277117f1b4Smrg   }
7287117f1b4Smrg   else {
7297117f1b4Smrg      _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)",target );
7307117f1b4Smrg      return;
7317117f1b4Smrg   }
7327117f1b4Smrg
7337117f1b4Smrg   if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
7347117f1b4Smrg      _mesa_debug(ctx, "glTexEnv %s %s %.1f(%s) ...\n",
7357117f1b4Smrg                  _mesa_lookup_enum_by_nr(target),
7367117f1b4Smrg                  _mesa_lookup_enum_by_nr(pname),
7377117f1b4Smrg                  *param,
7387117f1b4Smrg                  _mesa_lookup_enum_by_nr((GLenum) (GLint) *param));
7397117f1b4Smrg
7407117f1b4Smrg   /* Tell device driver about the new texture environment */
7417117f1b4Smrg   if (ctx->Driver.TexEnv) {
7427117f1b4Smrg      (*ctx->Driver.TexEnv)( ctx, target, pname, param );
7437117f1b4Smrg   }
7447117f1b4Smrg}
7457117f1b4Smrg
7467117f1b4Smrg
7477117f1b4Smrgvoid GLAPIENTRY
7487117f1b4Smrg_mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param )
7497117f1b4Smrg{
7507117f1b4Smrg   _mesa_TexEnvfv( target, pname, &param );
7517117f1b4Smrg}
7527117f1b4Smrg
7537117f1b4Smrg
7547117f1b4Smrg
7557117f1b4Smrgvoid GLAPIENTRY
7567117f1b4Smrg_mesa_TexEnvi( GLenum target, GLenum pname, GLint param )
7577117f1b4Smrg{
7587117f1b4Smrg   GLfloat p[4];
7597117f1b4Smrg   p[0] = (GLfloat) param;
7607117f1b4Smrg   p[1] = p[2] = p[3] = 0.0;
7617117f1b4Smrg   _mesa_TexEnvfv( target, pname, p );
7627117f1b4Smrg}
7637117f1b4Smrg
7647117f1b4Smrg
7657117f1b4Smrgvoid GLAPIENTRY
7667117f1b4Smrg_mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param )
7677117f1b4Smrg{
7687117f1b4Smrg   GLfloat p[4];
7697117f1b4Smrg   if (pname == GL_TEXTURE_ENV_COLOR) {
7707117f1b4Smrg      p[0] = INT_TO_FLOAT( param[0] );
7717117f1b4Smrg      p[1] = INT_TO_FLOAT( param[1] );
7727117f1b4Smrg      p[2] = INT_TO_FLOAT( param[2] );
7737117f1b4Smrg      p[3] = INT_TO_FLOAT( param[3] );
7747117f1b4Smrg   }
7757117f1b4Smrg   else {
7767117f1b4Smrg      p[0] = (GLfloat) param[0];
7777117f1b4Smrg      p[1] = p[2] = p[3] = 0;  /* init to zero, just to be safe */
7787117f1b4Smrg   }
7797117f1b4Smrg   _mesa_TexEnvfv( target, pname, p );
7807117f1b4Smrg}
7817117f1b4Smrg
7827117f1b4Smrg
7837117f1b4Smrgvoid GLAPIENTRY
7847117f1b4Smrg_mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
7857117f1b4Smrg{
7867117f1b4Smrg   GLuint maxUnit;
7877117f1b4Smrg   const struct gl_texture_unit *texUnit;
7887117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
7897117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
7907117f1b4Smrg
7917117f1b4Smrg   maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
7927117f1b4Smrg      ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits;
7937117f1b4Smrg   if (ctx->Texture.CurrentUnit >= maxUnit) {
7947117f1b4Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnvfv(current unit)");
7957117f1b4Smrg      return;
7967117f1b4Smrg   }
7977117f1b4Smrg
7987117f1b4Smrg   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
7997117f1b4Smrg
8007117f1b4Smrg   if (target == GL_TEXTURE_ENV) {
8017117f1b4Smrg      switch (pname) {
8027117f1b4Smrg         case GL_TEXTURE_ENV_MODE:
8037117f1b4Smrg            *params = ENUM_TO_FLOAT(texUnit->EnvMode);
8047117f1b4Smrg            break;
8057117f1b4Smrg         case GL_TEXTURE_ENV_COLOR:
8067117f1b4Smrg            COPY_4FV( params, texUnit->EnvColor );
8077117f1b4Smrg            break;
8087117f1b4Smrg         case GL_COMBINE_RGB:
8097117f1b4Smrg            if (ctx->Extensions.EXT_texture_env_combine ||
8107117f1b4Smrg                ctx->Extensions.ARB_texture_env_combine) {
8117117f1b4Smrg               *params = (GLfloat) texUnit->Combine.ModeRGB;
8127117f1b4Smrg            }
8137117f1b4Smrg            else {
8147117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
8157117f1b4Smrg            }
8167117f1b4Smrg            break;
8177117f1b4Smrg         case GL_COMBINE_ALPHA:
8187117f1b4Smrg            if (ctx->Extensions.EXT_texture_env_combine ||
8197117f1b4Smrg                ctx->Extensions.ARB_texture_env_combine) {
8207117f1b4Smrg               *params = (GLfloat) texUnit->Combine.ModeA;
8217117f1b4Smrg            }
8227117f1b4Smrg            else {
8237117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
8247117f1b4Smrg            }
8257117f1b4Smrg            break;
8267117f1b4Smrg         case GL_SOURCE0_RGB:
8277117f1b4Smrg         case GL_SOURCE1_RGB:
8287117f1b4Smrg         case GL_SOURCE2_RGB:
8297117f1b4Smrg            if (ctx->Extensions.EXT_texture_env_combine ||
8307117f1b4Smrg                ctx->Extensions.ARB_texture_env_combine) {
8317117f1b4Smrg	       const unsigned rgb_idx = pname - GL_SOURCE0_RGB;
8327117f1b4Smrg               *params = (GLfloat) texUnit->Combine.SourceRGB[rgb_idx];
8337117f1b4Smrg            }
8347117f1b4Smrg            else {
8357117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
8367117f1b4Smrg            }
8377117f1b4Smrg            break;
8387117f1b4Smrg         case GL_SOURCE0_ALPHA:
8397117f1b4Smrg         case GL_SOURCE1_ALPHA:
8407117f1b4Smrg         case GL_SOURCE2_ALPHA:
8417117f1b4Smrg            if (ctx->Extensions.EXT_texture_env_combine ||
8427117f1b4Smrg                ctx->Extensions.ARB_texture_env_combine) {
8437117f1b4Smrg	       const unsigned alpha_idx = pname - GL_SOURCE0_ALPHA;
8447117f1b4Smrg               *params = (GLfloat) texUnit->Combine.SourceA[alpha_idx];
8457117f1b4Smrg            }
8467117f1b4Smrg            else {
8477117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
8487117f1b4Smrg            }
8497117f1b4Smrg            break;
8507117f1b4Smrg         case GL_OPERAND0_RGB:
8517117f1b4Smrg         case GL_OPERAND1_RGB:
8527117f1b4Smrg         case GL_OPERAND2_RGB:
8537117f1b4Smrg            if (ctx->Extensions.EXT_texture_env_combine ||
8547117f1b4Smrg                ctx->Extensions.ARB_texture_env_combine) {
8557117f1b4Smrg	       const unsigned op_rgb = pname - GL_OPERAND0_RGB;
8567117f1b4Smrg               *params = (GLfloat) texUnit->Combine.OperandRGB[op_rgb];
8577117f1b4Smrg            }
8587117f1b4Smrg            else {
8597117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
8607117f1b4Smrg            }
8617117f1b4Smrg            break;
8627117f1b4Smrg         case GL_OPERAND0_ALPHA:
8637117f1b4Smrg         case GL_OPERAND1_ALPHA:
8647117f1b4Smrg         case GL_OPERAND2_ALPHA:
8657117f1b4Smrg            if (ctx->Extensions.EXT_texture_env_combine ||
8667117f1b4Smrg                ctx->Extensions.ARB_texture_env_combine) {
8677117f1b4Smrg	       const unsigned op_alpha = pname - GL_OPERAND0_ALPHA;
8687117f1b4Smrg               *params = (GLfloat) texUnit->Combine.OperandA[op_alpha];
8697117f1b4Smrg            }
8707117f1b4Smrg            else {
8717117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
8727117f1b4Smrg            }
8737117f1b4Smrg            break;
8747117f1b4Smrg         case GL_RGB_SCALE:
8757117f1b4Smrg            if (ctx->Extensions.EXT_texture_env_combine ||
8767117f1b4Smrg                ctx->Extensions.ARB_texture_env_combine) {
8777117f1b4Smrg               if (texUnit->Combine.ScaleShiftRGB == 0)
8787117f1b4Smrg                  *params = 1.0;
8797117f1b4Smrg               else if (texUnit->Combine.ScaleShiftRGB == 1)
8807117f1b4Smrg                  *params = 2.0;
8817117f1b4Smrg               else
8827117f1b4Smrg                  *params = 4.0;
8837117f1b4Smrg            }
8847117f1b4Smrg            else {
8857117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
8867117f1b4Smrg               return;
8877117f1b4Smrg            }
8887117f1b4Smrg            break;
8897117f1b4Smrg         case GL_ALPHA_SCALE:
8907117f1b4Smrg            if (ctx->Extensions.EXT_texture_env_combine ||
8917117f1b4Smrg                ctx->Extensions.ARB_texture_env_combine) {
8927117f1b4Smrg               if (texUnit->Combine.ScaleShiftA == 0)
8937117f1b4Smrg                  *params = 1.0;
8947117f1b4Smrg               else if (texUnit->Combine.ScaleShiftA == 1)
8957117f1b4Smrg                  *params = 2.0;
8967117f1b4Smrg               else
8977117f1b4Smrg                  *params = 4.0;
8987117f1b4Smrg            }
8997117f1b4Smrg            else {
9007117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)");
9017117f1b4Smrg               return;
9027117f1b4Smrg            }
9037117f1b4Smrg            break;
9047117f1b4Smrg         default:
9057117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname=0x%x)", pname);
9067117f1b4Smrg      }
9077117f1b4Smrg   }
9087117f1b4Smrg   else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
9097117f1b4Smrg      /* GL_EXT_texture_lod_bias */
9107117f1b4Smrg      if (!ctx->Extensions.EXT_texture_lod_bias) {
9117117f1b4Smrg	 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
9127117f1b4Smrg	 return;
9137117f1b4Smrg      }
9147117f1b4Smrg      if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
9157117f1b4Smrg         *params = texUnit->LodBias;
9167117f1b4Smrg      }
9177117f1b4Smrg      else {
9187117f1b4Smrg         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
9197117f1b4Smrg	 return;
9207117f1b4Smrg      }
9217117f1b4Smrg   }
9227117f1b4Smrg   else if (target == GL_POINT_SPRITE_NV) {
9237117f1b4Smrg      /* GL_ARB_point_sprite / GL_NV_point_sprite */
9247117f1b4Smrg      if (!ctx->Extensions.NV_point_sprite
9257117f1b4Smrg	  && !ctx->Extensions.ARB_point_sprite) {
9267117f1b4Smrg         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
9277117f1b4Smrg         return;
9287117f1b4Smrg      }
9297117f1b4Smrg      if (pname == GL_COORD_REPLACE_NV) {
9307117f1b4Smrg         *params = (GLfloat) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit];
9317117f1b4Smrg      }
9327117f1b4Smrg      else {
9337117f1b4Smrg         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)" );
9347117f1b4Smrg         return;
9357117f1b4Smrg      }
9367117f1b4Smrg   }
9377117f1b4Smrg   else {
9387117f1b4Smrg      _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" );
9397117f1b4Smrg      return;
9407117f1b4Smrg   }
9417117f1b4Smrg}
9427117f1b4Smrg
9437117f1b4Smrg
9447117f1b4Smrgvoid GLAPIENTRY
9457117f1b4Smrg_mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
9467117f1b4Smrg{
9477117f1b4Smrg   GLuint maxUnit;
9487117f1b4Smrg   const struct gl_texture_unit *texUnit;
9497117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
9507117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
9517117f1b4Smrg
9527117f1b4Smrg   maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV)
9537117f1b4Smrg      ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits;
9547117f1b4Smrg   if (ctx->Texture.CurrentUnit >= maxUnit) {
9557117f1b4Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnviv(current unit)");
9567117f1b4Smrg      return;
9577117f1b4Smrg   }
9587117f1b4Smrg
9597117f1b4Smrg   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
9607117f1b4Smrg
9617117f1b4Smrg   if (target == GL_TEXTURE_ENV) {
9627117f1b4Smrg      switch (pname) {
9637117f1b4Smrg         case GL_TEXTURE_ENV_MODE:
9647117f1b4Smrg            *params = (GLint) texUnit->EnvMode;
9657117f1b4Smrg            break;
9667117f1b4Smrg         case GL_TEXTURE_ENV_COLOR:
9677117f1b4Smrg            params[0] = FLOAT_TO_INT( texUnit->EnvColor[0] );
9687117f1b4Smrg            params[1] = FLOAT_TO_INT( texUnit->EnvColor[1] );
9697117f1b4Smrg            params[2] = FLOAT_TO_INT( texUnit->EnvColor[2] );
9707117f1b4Smrg            params[3] = FLOAT_TO_INT( texUnit->EnvColor[3] );
9717117f1b4Smrg            break;
9727117f1b4Smrg         case GL_COMBINE_RGB:
9737117f1b4Smrg            if (ctx->Extensions.EXT_texture_env_combine ||
9747117f1b4Smrg                ctx->Extensions.ARB_texture_env_combine) {
9757117f1b4Smrg               *params = (GLint) texUnit->Combine.ModeRGB;
9767117f1b4Smrg            }
9777117f1b4Smrg            else {
9787117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
9797117f1b4Smrg            }
9807117f1b4Smrg            break;
9817117f1b4Smrg         case GL_COMBINE_ALPHA:
9827117f1b4Smrg            if (ctx->Extensions.EXT_texture_env_combine ||
9837117f1b4Smrg                ctx->Extensions.ARB_texture_env_combine) {
9847117f1b4Smrg               *params = (GLint) texUnit->Combine.ModeA;
9857117f1b4Smrg            }
9867117f1b4Smrg            else {
9877117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
9887117f1b4Smrg            }
9897117f1b4Smrg            break;
9907117f1b4Smrg         case GL_SOURCE0_RGB:
9917117f1b4Smrg         case GL_SOURCE1_RGB:
9927117f1b4Smrg         case GL_SOURCE2_RGB:
9937117f1b4Smrg            if (ctx->Extensions.EXT_texture_env_combine ||
9947117f1b4Smrg                ctx->Extensions.ARB_texture_env_combine) {
9957117f1b4Smrg	       const unsigned rgb_idx = pname - GL_SOURCE0_RGB;
9967117f1b4Smrg               *params = (GLint) texUnit->Combine.SourceRGB[rgb_idx];
9977117f1b4Smrg            }
9987117f1b4Smrg            else {
9997117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
10007117f1b4Smrg            }
10017117f1b4Smrg            break;
10027117f1b4Smrg         case GL_SOURCE0_ALPHA:
10037117f1b4Smrg         case GL_SOURCE1_ALPHA:
10047117f1b4Smrg         case GL_SOURCE2_ALPHA:
10057117f1b4Smrg            if (ctx->Extensions.EXT_texture_env_combine ||
10067117f1b4Smrg                ctx->Extensions.ARB_texture_env_combine) {
10077117f1b4Smrg	       const unsigned alpha_idx = pname - GL_SOURCE0_ALPHA;
10087117f1b4Smrg               *params = (GLint) texUnit->Combine.SourceA[alpha_idx];
10097117f1b4Smrg            }
10107117f1b4Smrg            else {
10117117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
10127117f1b4Smrg            }
10137117f1b4Smrg            break;
10147117f1b4Smrg         case GL_OPERAND0_RGB:
10157117f1b4Smrg         case GL_OPERAND1_RGB:
10167117f1b4Smrg         case GL_OPERAND2_RGB:
10177117f1b4Smrg            if (ctx->Extensions.EXT_texture_env_combine ||
10187117f1b4Smrg                ctx->Extensions.ARB_texture_env_combine) {
10197117f1b4Smrg	       const unsigned op_rgb = pname - GL_OPERAND0_RGB;
10207117f1b4Smrg               *params = (GLint) texUnit->Combine.OperandRGB[op_rgb];
10217117f1b4Smrg            }
10227117f1b4Smrg            else {
10237117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
10247117f1b4Smrg            }
10257117f1b4Smrg            break;
10267117f1b4Smrg         case GL_OPERAND0_ALPHA:
10277117f1b4Smrg         case GL_OPERAND1_ALPHA:
10287117f1b4Smrg         case GL_OPERAND2_ALPHA:
10297117f1b4Smrg            if (ctx->Extensions.EXT_texture_env_combine ||
10307117f1b4Smrg                ctx->Extensions.ARB_texture_env_combine) {
10317117f1b4Smrg	       const unsigned op_alpha = pname - GL_OPERAND0_ALPHA;
10327117f1b4Smrg               *params = (GLint) texUnit->Combine.OperandA[op_alpha];
10337117f1b4Smrg            }
10347117f1b4Smrg            else {
10357117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
10367117f1b4Smrg            }
10377117f1b4Smrg            break;
10387117f1b4Smrg         case GL_RGB_SCALE:
10397117f1b4Smrg            if (ctx->Extensions.EXT_texture_env_combine ||
10407117f1b4Smrg                ctx->Extensions.ARB_texture_env_combine) {
10417117f1b4Smrg               if (texUnit->Combine.ScaleShiftRGB == 0)
10427117f1b4Smrg                  *params = 1;
10437117f1b4Smrg               else if (texUnit->Combine.ScaleShiftRGB == 1)
10447117f1b4Smrg                  *params = 2;
10457117f1b4Smrg               else
10467117f1b4Smrg                  *params = 4;
10477117f1b4Smrg            }
10487117f1b4Smrg            else {
10497117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
10507117f1b4Smrg               return;
10517117f1b4Smrg            }
10527117f1b4Smrg            break;
10537117f1b4Smrg         case GL_ALPHA_SCALE:
10547117f1b4Smrg            if (ctx->Extensions.EXT_texture_env_combine ||
10557117f1b4Smrg                ctx->Extensions.ARB_texture_env_combine) {
10567117f1b4Smrg               if (texUnit->Combine.ScaleShiftA == 0)
10577117f1b4Smrg                  *params = 1;
10587117f1b4Smrg               else if (texUnit->Combine.ScaleShiftA == 1)
10597117f1b4Smrg                  *params = 2;
10607117f1b4Smrg               else
10617117f1b4Smrg                  *params = 4;
10627117f1b4Smrg            }
10637117f1b4Smrg            else {
10647117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)");
10657117f1b4Smrg               return;
10667117f1b4Smrg            }
10677117f1b4Smrg            break;
10687117f1b4Smrg         default:
10697117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname=0x%x)",
10707117f1b4Smrg                        pname);
10717117f1b4Smrg      }
10727117f1b4Smrg   }
10737117f1b4Smrg   else if (target == GL_TEXTURE_FILTER_CONTROL_EXT) {
10747117f1b4Smrg      /* GL_EXT_texture_lod_bias */
10757117f1b4Smrg      if (!ctx->Extensions.EXT_texture_lod_bias) {
10767117f1b4Smrg	 _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
10777117f1b4Smrg	 return;
10787117f1b4Smrg      }
10797117f1b4Smrg      if (pname == GL_TEXTURE_LOD_BIAS_EXT) {
10807117f1b4Smrg         *params = (GLint) texUnit->LodBias;
10817117f1b4Smrg      }
10827117f1b4Smrg      else {
10837117f1b4Smrg         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
10847117f1b4Smrg	 return;
10857117f1b4Smrg      }
10867117f1b4Smrg   }
10877117f1b4Smrg   else if (target == GL_POINT_SPRITE_NV) {
10887117f1b4Smrg      /* GL_ARB_point_sprite / GL_NV_point_sprite */
10897117f1b4Smrg      if (!ctx->Extensions.NV_point_sprite
10907117f1b4Smrg	  && !ctx->Extensions.ARB_point_sprite) {
10917117f1b4Smrg         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
10927117f1b4Smrg         return;
10937117f1b4Smrg      }
10947117f1b4Smrg      if (pname == GL_COORD_REPLACE_NV) {
10957117f1b4Smrg         *params = (GLint) ctx->Point.CoordReplace[ctx->Texture.CurrentUnit];
10967117f1b4Smrg      }
10977117f1b4Smrg      else {
10987117f1b4Smrg         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)" );
10997117f1b4Smrg         return;
11007117f1b4Smrg      }
11017117f1b4Smrg   }
11027117f1b4Smrg   else {
11037117f1b4Smrg      _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" );
11047117f1b4Smrg      return;
11057117f1b4Smrg   }
11067117f1b4Smrg}
11077117f1b4Smrg
11087117f1b4Smrg
11097117f1b4Smrg
11107117f1b4Smrg
11117117f1b4Smrg/**********************************************************************/
11127117f1b4Smrg/*                       Texture Parameters                           */
11137117f1b4Smrg/**********************************************************************/
11147117f1b4Smrg
11157117f1b4Smrgstatic GLboolean
11167117f1b4Smrg_mesa_validate_texture_wrap_mode(GLcontext * ctx,
11177117f1b4Smrg				 GLenum target, GLenum eparam)
11187117f1b4Smrg{
11197117f1b4Smrg   const struct gl_extensions * const e = & ctx->Extensions;
11207117f1b4Smrg
11217117f1b4Smrg   if (eparam == GL_CLAMP || eparam == GL_CLAMP_TO_EDGE ||
11227117f1b4Smrg       (eparam == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) {
11237117f1b4Smrg      /* any texture target */
11247117f1b4Smrg      return GL_TRUE;
11257117f1b4Smrg   }
11267117f1b4Smrg   else if (target != GL_TEXTURE_RECTANGLE_NV &&
11277117f1b4Smrg	    (eparam == GL_REPEAT ||
11287117f1b4Smrg	     (eparam == GL_MIRRORED_REPEAT &&
11297117f1b4Smrg	      e->ARB_texture_mirrored_repeat) ||
11307117f1b4Smrg	     (eparam == GL_MIRROR_CLAMP_EXT &&
11317117f1b4Smrg	      (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
11327117f1b4Smrg	     (eparam == GL_MIRROR_CLAMP_TO_EDGE_EXT &&
11337117f1b4Smrg	      (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
11347117f1b4Smrg	     (eparam == GL_MIRROR_CLAMP_TO_BORDER_EXT &&
11357117f1b4Smrg	      (e->EXT_texture_mirror_clamp)))) {
11367117f1b4Smrg      /* non-rectangle texture */
11377117f1b4Smrg      return GL_TRUE;
11387117f1b4Smrg   }
11397117f1b4Smrg
11407117f1b4Smrg   _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
11417117f1b4Smrg   return GL_FALSE;
11427117f1b4Smrg}
11437117f1b4Smrg
11447117f1b4Smrg
11457117f1b4Smrgvoid GLAPIENTRY
11467117f1b4Smrg_mesa_TexParameterf( GLenum target, GLenum pname, GLfloat param )
11477117f1b4Smrg{
11487117f1b4Smrg   _mesa_TexParameterfv(target, pname, &param);
11497117f1b4Smrg}
11507117f1b4Smrg
11517117f1b4Smrg
11527117f1b4Smrgvoid GLAPIENTRY
11537117f1b4Smrg_mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
11547117f1b4Smrg{
11557117f1b4Smrg   const GLenum eparam = (GLenum) (GLint) params[0];
11567117f1b4Smrg   struct gl_texture_unit *texUnit;
11577117f1b4Smrg   struct gl_texture_object *texObj;
11587117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
11597117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
11607117f1b4Smrg
11617117f1b4Smrg   if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
11627117f1b4Smrg      _mesa_debug(ctx, "glTexParameter %s %s %.1f(%s)...\n",
11637117f1b4Smrg                  _mesa_lookup_enum_by_nr(target),
11647117f1b4Smrg                  _mesa_lookup_enum_by_nr(pname),
11657117f1b4Smrg                  *params,
11667117f1b4Smrg		  _mesa_lookup_enum_by_nr(eparam));
11677117f1b4Smrg
11687117f1b4Smrg   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
11697117f1b4Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameterfv(current unit)");
11707117f1b4Smrg      return;
11717117f1b4Smrg   }
11727117f1b4Smrg
11737117f1b4Smrg   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
11747117f1b4Smrg
11757117f1b4Smrg   switch (target) {
11767117f1b4Smrg      case GL_TEXTURE_1D:
11777117f1b4Smrg         texObj = texUnit->Current1D;
11787117f1b4Smrg         break;
11797117f1b4Smrg      case GL_TEXTURE_2D:
11807117f1b4Smrg         texObj = texUnit->Current2D;
11817117f1b4Smrg         break;
11827117f1b4Smrg      case GL_TEXTURE_3D:
11837117f1b4Smrg         texObj = texUnit->Current3D;
11847117f1b4Smrg         break;
11857117f1b4Smrg      case GL_TEXTURE_CUBE_MAP:
11867117f1b4Smrg         if (!ctx->Extensions.ARB_texture_cube_map) {
11877117f1b4Smrg            _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
11887117f1b4Smrg            return;
11897117f1b4Smrg         }
11907117f1b4Smrg         texObj = texUnit->CurrentCubeMap;
11917117f1b4Smrg         break;
11927117f1b4Smrg      case GL_TEXTURE_RECTANGLE_NV:
11937117f1b4Smrg         if (!ctx->Extensions.NV_texture_rectangle) {
11947117f1b4Smrg            _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
11957117f1b4Smrg            return;
11967117f1b4Smrg         }
11977117f1b4Smrg         texObj = texUnit->CurrentRect;
11987117f1b4Smrg         break;
11997117f1b4Smrg      default:
12007117f1b4Smrg         _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
12017117f1b4Smrg         return;
12027117f1b4Smrg   }
12037117f1b4Smrg
12047117f1b4Smrg   switch (pname) {
12057117f1b4Smrg      case GL_TEXTURE_MIN_FILTER:
12067117f1b4Smrg         /* A small optimization */
12077117f1b4Smrg         if (texObj->MinFilter == eparam)
12087117f1b4Smrg            return;
12097117f1b4Smrg         if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
12107117f1b4Smrg            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
12117117f1b4Smrg            texObj->MinFilter = eparam;
12127117f1b4Smrg         }
12137117f1b4Smrg         else if ((eparam==GL_NEAREST_MIPMAP_NEAREST ||
12147117f1b4Smrg                   eparam==GL_LINEAR_MIPMAP_NEAREST ||
12157117f1b4Smrg                   eparam==GL_NEAREST_MIPMAP_LINEAR ||
12167117f1b4Smrg                   eparam==GL_LINEAR_MIPMAP_LINEAR) &&
12177117f1b4Smrg                  texObj->Target != GL_TEXTURE_RECTANGLE_NV) {
12187117f1b4Smrg            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
12197117f1b4Smrg            texObj->MinFilter = eparam;
12207117f1b4Smrg         }
12217117f1b4Smrg         else {
12227117f1b4Smrg            _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
12237117f1b4Smrg            return;
12247117f1b4Smrg         }
12257117f1b4Smrg         break;
12267117f1b4Smrg      case GL_TEXTURE_MAG_FILTER:
12277117f1b4Smrg         /* A small optimization */
12287117f1b4Smrg         if (texObj->MagFilter == eparam)
12297117f1b4Smrg            return;
12307117f1b4Smrg
12317117f1b4Smrg         if (eparam==GL_NEAREST || eparam==GL_LINEAR) {
12327117f1b4Smrg            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
12337117f1b4Smrg            texObj->MagFilter = eparam;
12347117f1b4Smrg         }
12357117f1b4Smrg         else {
12367117f1b4Smrg            _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
12377117f1b4Smrg            return;
12387117f1b4Smrg         }
12397117f1b4Smrg         break;
12407117f1b4Smrg      case GL_TEXTURE_WRAP_S:
12417117f1b4Smrg         if (texObj->WrapS == eparam)
12427117f1b4Smrg            return;
12437117f1b4Smrg         if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
12447117f1b4Smrg            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
12457117f1b4Smrg            texObj->WrapS = eparam;
12467117f1b4Smrg         }
12477117f1b4Smrg         else {
12487117f1b4Smrg            return;
12497117f1b4Smrg         }
12507117f1b4Smrg         break;
12517117f1b4Smrg      case GL_TEXTURE_WRAP_T:
12527117f1b4Smrg         if (texObj->WrapT == eparam)
12537117f1b4Smrg            return;
12547117f1b4Smrg         if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
12557117f1b4Smrg            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
12567117f1b4Smrg            texObj->WrapT = eparam;
12577117f1b4Smrg         }
12587117f1b4Smrg         else {
12597117f1b4Smrg            return;
12607117f1b4Smrg         }
12617117f1b4Smrg         break;
12627117f1b4Smrg      case GL_TEXTURE_WRAP_R:
12637117f1b4Smrg         if (texObj->WrapR == eparam)
12647117f1b4Smrg            return;
12657117f1b4Smrg         if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
12667117f1b4Smrg            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
12677117f1b4Smrg            texObj->WrapR = eparam;
12687117f1b4Smrg         }
12697117f1b4Smrg         else {
12707117f1b4Smrg	    return;
12717117f1b4Smrg         }
12727117f1b4Smrg         break;
12737117f1b4Smrg      case GL_TEXTURE_BORDER_COLOR:
12747117f1b4Smrg         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
12757117f1b4Smrg         texObj->BorderColor[RCOMP] = params[0];
12767117f1b4Smrg         texObj->BorderColor[GCOMP] = params[1];
12777117f1b4Smrg         texObj->BorderColor[BCOMP] = params[2];
12787117f1b4Smrg         texObj->BorderColor[ACOMP] = params[3];
12797117f1b4Smrg         UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[RCOMP], params[0]);
12807117f1b4Smrg         UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[GCOMP], params[1]);
12817117f1b4Smrg         UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[BCOMP], params[2]);
12827117f1b4Smrg         UNCLAMPED_FLOAT_TO_CHAN(texObj->_BorderChan[ACOMP], params[3]);
12837117f1b4Smrg         break;
12847117f1b4Smrg      case GL_TEXTURE_MIN_LOD:
12857117f1b4Smrg         if (texObj->MinLod == params[0])
12867117f1b4Smrg            return;
12877117f1b4Smrg         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
12887117f1b4Smrg         texObj->MinLod = params[0];
12897117f1b4Smrg         break;
12907117f1b4Smrg      case GL_TEXTURE_MAX_LOD:
12917117f1b4Smrg         if (texObj->MaxLod == params[0])
12927117f1b4Smrg            return;
12937117f1b4Smrg         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
12947117f1b4Smrg         texObj->MaxLod = params[0];
12957117f1b4Smrg         break;
12967117f1b4Smrg      case GL_TEXTURE_BASE_LEVEL:
12977117f1b4Smrg         if (params[0] < 0.0) {
12987117f1b4Smrg            _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)");
12997117f1b4Smrg            return;
13007117f1b4Smrg         }
13017117f1b4Smrg         if (target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0.0) {
13027117f1b4Smrg            _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)");
13037117f1b4Smrg            return;
13047117f1b4Smrg         }
13057117f1b4Smrg         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
13067117f1b4Smrg         texObj->BaseLevel = (GLint) params[0];
13077117f1b4Smrg         break;
13087117f1b4Smrg      case GL_TEXTURE_MAX_LEVEL:
13097117f1b4Smrg         if (params[0] < 0.0) {
13107117f1b4Smrg            _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)");
13117117f1b4Smrg            return;
13127117f1b4Smrg         }
13137117f1b4Smrg         if (target == GL_TEXTURE_RECTANGLE_ARB) {
13147117f1b4Smrg            _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(param)");
13157117f1b4Smrg            return;
13167117f1b4Smrg         }
13177117f1b4Smrg         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
13187117f1b4Smrg         texObj->MaxLevel = (GLint) params[0];
13197117f1b4Smrg         break;
13207117f1b4Smrg      case GL_TEXTURE_PRIORITY:
13217117f1b4Smrg         FLUSH_VERTICES(ctx, _NEW_TEXTURE);
13227117f1b4Smrg         texObj->Priority = CLAMP( params[0], 0.0F, 1.0F );
13237117f1b4Smrg         break;
13247117f1b4Smrg      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
13257117f1b4Smrg         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
13267117f1b4Smrg	    if (params[0] < 1.0) {
13277117f1b4Smrg	       _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
13287117f1b4Smrg	       return;
13297117f1b4Smrg	    }
13307117f1b4Smrg            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
13317117f1b4Smrg            /* clamp to max, that's what NVIDIA does */
13327117f1b4Smrg            texObj->MaxAnisotropy = MIN2(params[0],
13337117f1b4Smrg                                         ctx->Const.MaxTextureMaxAnisotropy);
13347117f1b4Smrg         }
13357117f1b4Smrg         else {
13367117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
13377117f1b4Smrg                        "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
13387117f1b4Smrg            return;
13397117f1b4Smrg         }
13407117f1b4Smrg         break;
13417117f1b4Smrg      case GL_TEXTURE_COMPARE_SGIX:
13427117f1b4Smrg         if (ctx->Extensions.SGIX_shadow) {
13437117f1b4Smrg            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
13447117f1b4Smrg            texObj->CompareFlag = params[0] ? GL_TRUE : GL_FALSE;
13457117f1b4Smrg         }
13467117f1b4Smrg         else {
13477117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
13487117f1b4Smrg                        "glTexParameter(pname=GL_TEXTURE_COMPARE_SGIX)");
13497117f1b4Smrg            return;
13507117f1b4Smrg         }
13517117f1b4Smrg         break;
13527117f1b4Smrg      case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
13537117f1b4Smrg         if (ctx->Extensions.SGIX_shadow) {
13547117f1b4Smrg            GLenum op = (GLenum) params[0];
13557117f1b4Smrg            if (op == GL_TEXTURE_LEQUAL_R_SGIX ||
13567117f1b4Smrg                op == GL_TEXTURE_GEQUAL_R_SGIX) {
13577117f1b4Smrg               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
13587117f1b4Smrg               texObj->CompareOperator = op;
13597117f1b4Smrg            }
13607117f1b4Smrg            else {
13617117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)");
13627117f1b4Smrg            }
13637117f1b4Smrg         }
13647117f1b4Smrg         else {
13657117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
13667117f1b4Smrg                    "glTexParameter(pname=GL_TEXTURE_COMPARE_OPERATOR_SGIX)");
13677117f1b4Smrg            return;
13687117f1b4Smrg         }
13697117f1b4Smrg         break;
13707117f1b4Smrg      case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
13717117f1b4Smrg         if (ctx->Extensions.SGIX_shadow_ambient) {
13727117f1b4Smrg            FLUSH_VERTICES(ctx, _NEW_TEXTURE);
13737117f1b4Smrg            texObj->ShadowAmbient = CLAMP(params[0], 0.0F, 1.0F);
13747117f1b4Smrg         }
13757117f1b4Smrg         else {
13767117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
13777117f1b4Smrg                        "glTexParameter(pname=GL_SHADOW_AMBIENT_SGIX)");
13787117f1b4Smrg            return;
13797117f1b4Smrg         }
13807117f1b4Smrg         break;
13817117f1b4Smrg      case GL_GENERATE_MIPMAP_SGIS:
13827117f1b4Smrg         if (ctx->Extensions.SGIS_generate_mipmap) {
13837117f1b4Smrg            texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
13847117f1b4Smrg         }
13857117f1b4Smrg         else {
13867117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
13877117f1b4Smrg                        "glTexParameter(pname=GL_GENERATE_MIPMAP_SGIS)");
13887117f1b4Smrg            return;
13897117f1b4Smrg         }
13907117f1b4Smrg         break;
13917117f1b4Smrg      case GL_TEXTURE_COMPARE_MODE_ARB:
13927117f1b4Smrg         if (ctx->Extensions.ARB_shadow) {
13937117f1b4Smrg            const GLenum mode = (GLenum) params[0];
13947117f1b4Smrg            if (mode == GL_NONE || mode == GL_COMPARE_R_TO_TEXTURE_ARB) {
13957117f1b4Smrg               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
13967117f1b4Smrg               texObj->CompareMode = mode;
13977117f1b4Smrg            }
13987117f1b4Smrg            else {
13997117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM,
14007117f1b4Smrg                           "glTexParameter(bad GL_TEXTURE_COMPARE_MODE_ARB: 0x%x)", mode);
14017117f1b4Smrg               return;
14027117f1b4Smrg            }
14037117f1b4Smrg         }
14047117f1b4Smrg         else {
14057117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
14067117f1b4Smrg                        "glTexParameter(pname=GL_TEXTURE_COMPARE_MODE_ARB)");
14077117f1b4Smrg            return;
14087117f1b4Smrg         }
14097117f1b4Smrg         break;
14107117f1b4Smrg      case GL_TEXTURE_COMPARE_FUNC_ARB:
14117117f1b4Smrg         if (ctx->Extensions.ARB_shadow) {
14127117f1b4Smrg            const GLenum func = (GLenum) params[0];
14137117f1b4Smrg            if (func == GL_LEQUAL || func == GL_GEQUAL) {
14147117f1b4Smrg               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
14157117f1b4Smrg               texObj->CompareFunc = func;
14167117f1b4Smrg            }
14177117f1b4Smrg            else if (ctx->Extensions.EXT_shadow_funcs &&
14187117f1b4Smrg                     (func == GL_EQUAL ||
14197117f1b4Smrg                      func == GL_NOTEQUAL ||
14207117f1b4Smrg                      func == GL_LESS ||
14217117f1b4Smrg                      func == GL_GREATER ||
14227117f1b4Smrg                      func == GL_ALWAYS ||
14237117f1b4Smrg                      func == GL_NEVER)) {
14247117f1b4Smrg               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
14257117f1b4Smrg               texObj->CompareFunc = func;
14267117f1b4Smrg            }
14277117f1b4Smrg            else {
14287117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM,
14297117f1b4Smrg                           "glTexParameter(bad GL_TEXTURE_COMPARE_FUNC_ARB)");
14307117f1b4Smrg               return;
14317117f1b4Smrg            }
14327117f1b4Smrg         }
14337117f1b4Smrg         else {
14347117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
14357117f1b4Smrg                        "glTexParameter(pname=GL_TEXTURE_COMPARE_FUNC_ARB)");
14367117f1b4Smrg            return;
14377117f1b4Smrg         }
14387117f1b4Smrg         break;
14397117f1b4Smrg      case GL_DEPTH_TEXTURE_MODE_ARB:
14407117f1b4Smrg         if (ctx->Extensions.ARB_depth_texture) {
14417117f1b4Smrg            const GLenum result = (GLenum) params[0];
14427117f1b4Smrg            if (result == GL_LUMINANCE || result == GL_INTENSITY
14437117f1b4Smrg                || result == GL_ALPHA) {
14447117f1b4Smrg               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
14457117f1b4Smrg               texObj->DepthMode = result;
14467117f1b4Smrg            }
14477117f1b4Smrg            else {
14487117f1b4Smrg               _mesa_error(ctx, GL_INVALID_ENUM,
14497117f1b4Smrg                          "glTexParameter(bad GL_DEPTH_TEXTURE_MODE_ARB)");
14507117f1b4Smrg               return;
14517117f1b4Smrg            }
14527117f1b4Smrg         }
14537117f1b4Smrg         else {
14547117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
14557117f1b4Smrg                        "glTexParameter(pname=GL_DEPTH_TEXTURE_MODE_ARB)");
14567117f1b4Smrg            return;
14577117f1b4Smrg         }
14587117f1b4Smrg         break;
14597117f1b4Smrg      case GL_TEXTURE_LOD_BIAS:
14607117f1b4Smrg         /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias*/
14617117f1b4Smrg         if (ctx->Extensions.EXT_texture_lod_bias) {
14627117f1b4Smrg            if (texObj->LodBias != params[0]) {
14637117f1b4Smrg               FLUSH_VERTICES(ctx, _NEW_TEXTURE);
14647117f1b4Smrg               texObj->LodBias = params[0];
14657117f1b4Smrg            }
14667117f1b4Smrg         }
14677117f1b4Smrg         break;
14687117f1b4Smrg
14697117f1b4Smrg      default:
14707117f1b4Smrg         _mesa_error(ctx, GL_INVALID_ENUM,
14717117f1b4Smrg                     "glTexParameter(pname=0x%x)", pname);
14727117f1b4Smrg         return;
14737117f1b4Smrg   }
14747117f1b4Smrg
14757117f1b4Smrg   texObj->Complete = GL_FALSE;
14767117f1b4Smrg
14777117f1b4Smrg   if (ctx->Driver.TexParameter) {
14787117f1b4Smrg      (*ctx->Driver.TexParameter)( ctx, target, texObj, pname, params );
14797117f1b4Smrg   }
14807117f1b4Smrg}
14817117f1b4Smrg
14827117f1b4Smrg
14837117f1b4Smrgvoid GLAPIENTRY
14847117f1b4Smrg_mesa_TexParameteri( GLenum target, GLenum pname, GLint param )
14857117f1b4Smrg{
14867117f1b4Smrg   GLfloat fparam[4];
14877117f1b4Smrg   if (pname == GL_TEXTURE_PRIORITY)
14887117f1b4Smrg      fparam[0] = INT_TO_FLOAT(param);
14897117f1b4Smrg   else
14907117f1b4Smrg      fparam[0] = (GLfloat) param;
14917117f1b4Smrg   fparam[1] = fparam[2] = fparam[3] = 0.0;
14927117f1b4Smrg   _mesa_TexParameterfv(target, pname, fparam);
14937117f1b4Smrg}
14947117f1b4Smrg
14957117f1b4Smrg
14967117f1b4Smrgvoid GLAPIENTRY
14977117f1b4Smrg_mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params )
14987117f1b4Smrg{
14997117f1b4Smrg   GLfloat fparam[4];
15007117f1b4Smrg   if (pname == GL_TEXTURE_BORDER_COLOR) {
15017117f1b4Smrg      fparam[0] = INT_TO_FLOAT(params[0]);
15027117f1b4Smrg      fparam[1] = INT_TO_FLOAT(params[1]);
15037117f1b4Smrg      fparam[2] = INT_TO_FLOAT(params[2]);
15047117f1b4Smrg      fparam[3] = INT_TO_FLOAT(params[3]);
15057117f1b4Smrg   }
15067117f1b4Smrg   else {
15077117f1b4Smrg      if (pname == GL_TEXTURE_PRIORITY)
15087117f1b4Smrg         fparam[0] = INT_TO_FLOAT(params[0]);
15097117f1b4Smrg      else
15107117f1b4Smrg         fparam[0] = (GLfloat) params[0];
15117117f1b4Smrg      fparam[1] = fparam[2] = fparam[3] = 0.0F;
15127117f1b4Smrg   }
15137117f1b4Smrg   _mesa_TexParameterfv(target, pname, fparam);
15147117f1b4Smrg}
15157117f1b4Smrg
15167117f1b4Smrg
15177117f1b4Smrgvoid GLAPIENTRY
15187117f1b4Smrg_mesa_GetTexLevelParameterfv( GLenum target, GLint level,
15197117f1b4Smrg                              GLenum pname, GLfloat *params )
15207117f1b4Smrg{
15217117f1b4Smrg   GLint iparam;
15227117f1b4Smrg   _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
15237117f1b4Smrg   *params = (GLfloat) iparam;
15247117f1b4Smrg}
15257117f1b4Smrg
15267117f1b4Smrg
15277117f1b4Smrgstatic GLuint
15287117f1b4Smrgtex_image_dimensions(GLcontext *ctx, GLenum target)
15297117f1b4Smrg{
15307117f1b4Smrg   switch (target) {
15317117f1b4Smrg      case GL_TEXTURE_1D:
15327117f1b4Smrg      case GL_PROXY_TEXTURE_1D:
15337117f1b4Smrg         return 1;
15347117f1b4Smrg      case GL_TEXTURE_2D:
15357117f1b4Smrg      case GL_PROXY_TEXTURE_2D:
15367117f1b4Smrg         return 2;
15377117f1b4Smrg      case GL_TEXTURE_3D:
15387117f1b4Smrg      case GL_PROXY_TEXTURE_3D:
15397117f1b4Smrg         return 3;
15407117f1b4Smrg      case GL_TEXTURE_CUBE_MAP:
15417117f1b4Smrg      case GL_PROXY_TEXTURE_CUBE_MAP:
15427117f1b4Smrg      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
15437117f1b4Smrg      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
15447117f1b4Smrg      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
15457117f1b4Smrg      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
15467117f1b4Smrg      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
15477117f1b4Smrg      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
15487117f1b4Smrg         return ctx->Extensions.ARB_texture_cube_map ? 2 : 0;
15497117f1b4Smrg      case GL_TEXTURE_RECTANGLE_NV:
15507117f1b4Smrg      case GL_PROXY_TEXTURE_RECTANGLE_NV:
15517117f1b4Smrg         return ctx->Extensions.NV_texture_rectangle ? 2 : 0;
15527117f1b4Smrg      default:
15537117f1b4Smrg         _mesa_problem(ctx, "bad target in _mesa_tex_target_dimensions()");
15547117f1b4Smrg         return 0;
15557117f1b4Smrg   }
15567117f1b4Smrg}
15577117f1b4Smrg
15587117f1b4Smrg
15597117f1b4Smrgvoid GLAPIENTRY
15607117f1b4Smrg_mesa_GetTexLevelParameteriv( GLenum target, GLint level,
15617117f1b4Smrg                              GLenum pname, GLint *params )
15627117f1b4Smrg{
15637117f1b4Smrg   const struct gl_texture_unit *texUnit;
15647117f1b4Smrg   struct gl_texture_object *texObj;
15657117f1b4Smrg   const struct gl_texture_image *img = NULL;
15667117f1b4Smrg   GLuint dimensions;
15677117f1b4Smrg   GLboolean isProxy;
15687117f1b4Smrg   GLint maxLevels;
15697117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
15707117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
15717117f1b4Smrg
15727117f1b4Smrg   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
15737117f1b4Smrg      _mesa_error(ctx, GL_INVALID_OPERATION,
15747117f1b4Smrg                  "glGetTexLevelParameteriv(current unit)");
15757117f1b4Smrg      return;
15767117f1b4Smrg   }
15777117f1b4Smrg
15787117f1b4Smrg   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
15797117f1b4Smrg
15807117f1b4Smrg   /* this will catch bad target values */
15817117f1b4Smrg   dimensions = tex_image_dimensions(ctx, target);  /* 1, 2 or 3 */
15827117f1b4Smrg   if (dimensions == 0) {
15837117f1b4Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
15847117f1b4Smrg      return;
15857117f1b4Smrg   }
15867117f1b4Smrg
15877117f1b4Smrg   maxLevels = _mesa_max_texture_levels(ctx, target);
15887117f1b4Smrg   if (maxLevels == 0) {
15897117f1b4Smrg      /* should not happen since <target> was just checked above */
15907117f1b4Smrg      _mesa_problem(ctx, "maxLevels=0 in _mesa_GetTexLevelParameter");
15917117f1b4Smrg      return;
15927117f1b4Smrg   }
15937117f1b4Smrg
15947117f1b4Smrg   if (level < 0 || level >= maxLevels) {
15957117f1b4Smrg      _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
15967117f1b4Smrg      return;
15977117f1b4Smrg   }
15987117f1b4Smrg
15997117f1b4Smrg   texObj = _mesa_select_tex_object(ctx, texUnit, target);
16007117f1b4Smrg   _mesa_lock_texture(ctx, texObj);
16017117f1b4Smrg
16027117f1b4Smrg   img = _mesa_select_tex_image(ctx, texObj, target, level);
16037117f1b4Smrg   if (!img || !img->TexFormat) {
16047117f1b4Smrg      /* undefined texture image */
16057117f1b4Smrg      if (pname == GL_TEXTURE_COMPONENTS)
16067117f1b4Smrg         *params = 1;
16077117f1b4Smrg      else
16087117f1b4Smrg         *params = 0;
16097117f1b4Smrg      goto out;
16107117f1b4Smrg   }
16117117f1b4Smrg
16127117f1b4Smrg   isProxy = _mesa_is_proxy_texture(target);
16137117f1b4Smrg
16147117f1b4Smrg   switch (pname) {
16157117f1b4Smrg      case GL_TEXTURE_WIDTH:
16167117f1b4Smrg         *params = img->Width;
16177117f1b4Smrg         break;
16187117f1b4Smrg      case GL_TEXTURE_HEIGHT:
16197117f1b4Smrg         *params = img->Height;
16207117f1b4Smrg         break;
16217117f1b4Smrg      case GL_TEXTURE_DEPTH:
16227117f1b4Smrg         *params = img->Depth;
16237117f1b4Smrg         break;
16247117f1b4Smrg      case GL_TEXTURE_INTERNAL_FORMAT:
16257117f1b4Smrg         *params = img->InternalFormat;
16267117f1b4Smrg         break;
16277117f1b4Smrg      case GL_TEXTURE_BORDER:
16287117f1b4Smrg         *params = img->Border;
16297117f1b4Smrg         break;
16307117f1b4Smrg      case GL_TEXTURE_RED_SIZE:
16317117f1b4Smrg         if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
16327117f1b4Smrg            *params = img->TexFormat->RedBits;
16337117f1b4Smrg         else
16347117f1b4Smrg            *params = 0;
16357117f1b4Smrg         break;
16367117f1b4Smrg      case GL_TEXTURE_GREEN_SIZE:
16377117f1b4Smrg         if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
16387117f1b4Smrg            *params = img->TexFormat->GreenBits;
16397117f1b4Smrg         else
16407117f1b4Smrg            *params = 0;
16417117f1b4Smrg         break;
16427117f1b4Smrg      case GL_TEXTURE_BLUE_SIZE:
16437117f1b4Smrg         if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
16447117f1b4Smrg            *params = img->TexFormat->BlueBits;
16457117f1b4Smrg         else
16467117f1b4Smrg            *params = 0;
16477117f1b4Smrg         break;
16487117f1b4Smrg      case GL_TEXTURE_ALPHA_SIZE:
16497117f1b4Smrg         if (img->_BaseFormat == GL_ALPHA ||
16507117f1b4Smrg             img->_BaseFormat == GL_LUMINANCE_ALPHA ||
16517117f1b4Smrg             img->_BaseFormat == GL_RGBA)
16527117f1b4Smrg            *params = img->TexFormat->AlphaBits;
16537117f1b4Smrg         else
16547117f1b4Smrg            *params = 0;
16557117f1b4Smrg         break;
16567117f1b4Smrg      case GL_TEXTURE_INTENSITY_SIZE:
16577117f1b4Smrg         if (img->_BaseFormat != GL_INTENSITY)
16587117f1b4Smrg            *params = 0;
16597117f1b4Smrg         else if (img->TexFormat->IntensityBits > 0)
16607117f1b4Smrg            *params = img->TexFormat->IntensityBits;
16617117f1b4Smrg         else /* intensity probably stored as rgb texture */
16627117f1b4Smrg            *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
16637117f1b4Smrg         break;
16647117f1b4Smrg      case GL_TEXTURE_LUMINANCE_SIZE:
16657117f1b4Smrg         if (img->_BaseFormat != GL_LUMINANCE &&
16667117f1b4Smrg             img->_BaseFormat != GL_LUMINANCE_ALPHA)
16677117f1b4Smrg            *params = 0;
16687117f1b4Smrg         else if (img->TexFormat->LuminanceBits > 0)
16697117f1b4Smrg            *params = img->TexFormat->LuminanceBits;
16707117f1b4Smrg         else /* luminance probably stored as rgb texture */
16717117f1b4Smrg            *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits);
16727117f1b4Smrg         break;
16737117f1b4Smrg      case GL_TEXTURE_INDEX_SIZE_EXT:
16747117f1b4Smrg         if (img->_BaseFormat == GL_COLOR_INDEX)
16757117f1b4Smrg            *params = img->TexFormat->IndexBits;
16767117f1b4Smrg         else
16777117f1b4Smrg            *params = 0;
16787117f1b4Smrg         break;
16797117f1b4Smrg      case GL_TEXTURE_DEPTH_SIZE_ARB:
16807117f1b4Smrg         if (ctx->Extensions.SGIX_depth_texture ||
16817117f1b4Smrg             ctx->Extensions.ARB_depth_texture)
16827117f1b4Smrg            *params = img->TexFormat->DepthBits;
16837117f1b4Smrg         else
16847117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
16857117f1b4Smrg                        "glGetTexLevelParameter[if]v(pname)");
16867117f1b4Smrg         break;
16877117f1b4Smrg      case GL_TEXTURE_STENCIL_SIZE_EXT:
16887117f1b4Smrg         if (ctx->Extensions.EXT_packed_depth_stencil) {
16897117f1b4Smrg            *params = img->TexFormat->StencilBits;
16907117f1b4Smrg         }
16917117f1b4Smrg         else {
16927117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
16937117f1b4Smrg                        "glGetTexLevelParameter[if]v(pname)");
16947117f1b4Smrg         }
16957117f1b4Smrg         break;
16967117f1b4Smrg
16977117f1b4Smrg      /* GL_ARB_texture_compression */
16987117f1b4Smrg      case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
16997117f1b4Smrg         if (ctx->Extensions.ARB_texture_compression) {
17007117f1b4Smrg            if (img->IsCompressed && !isProxy) {
17017117f1b4Smrg               /* Don't use ctx->Driver.CompressedTextureSize() since that
17027117f1b4Smrg                * may returned a padded hardware size.
17037117f1b4Smrg                */
17047117f1b4Smrg               *params = _mesa_compressed_texture_size(ctx, img->Width,
17057117f1b4Smrg                                                   img->Height, img->Depth,
17067117f1b4Smrg                                                   img->TexFormat->MesaFormat);
17077117f1b4Smrg            }
17087117f1b4Smrg            else {
17097117f1b4Smrg               _mesa_error(ctx, GL_INVALID_OPERATION,
17107117f1b4Smrg                           "glGetTexLevelParameter[if]v(pname)");
17117117f1b4Smrg            }
17127117f1b4Smrg         }
17137117f1b4Smrg         else {
17147117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
17157117f1b4Smrg                        "glGetTexLevelParameter[if]v(pname)");
17167117f1b4Smrg         }
17177117f1b4Smrg         break;
17187117f1b4Smrg      case GL_TEXTURE_COMPRESSED:
17197117f1b4Smrg         if (ctx->Extensions.ARB_texture_compression) {
17207117f1b4Smrg            *params = (GLint) img->IsCompressed;
17217117f1b4Smrg         }
17227117f1b4Smrg         else {
17237117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
17247117f1b4Smrg                        "glGetTexLevelParameter[if]v(pname)");
17257117f1b4Smrg         }
17267117f1b4Smrg         break;
17277117f1b4Smrg
17287117f1b4Smrg      /* GL_ARB_texture_float */
17297117f1b4Smrg      case GL_TEXTURE_RED_TYPE_ARB:
17307117f1b4Smrg         if (ctx->Extensions.ARB_texture_float) {
17317117f1b4Smrg            *params = img->TexFormat->RedBits ? img->TexFormat->DataType : GL_NONE;
17327117f1b4Smrg         }
17337117f1b4Smrg         else {
17347117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
17357117f1b4Smrg                        "glGetTexLevelParameter[if]v(pname)");
17367117f1b4Smrg         }
17377117f1b4Smrg         break;
17387117f1b4Smrg      case GL_TEXTURE_GREEN_TYPE_ARB:
17397117f1b4Smrg         if (ctx->Extensions.ARB_texture_float) {
17407117f1b4Smrg            *params = img->TexFormat->GreenBits ? img->TexFormat->DataType : GL_NONE;
17417117f1b4Smrg         }
17427117f1b4Smrg         else {
17437117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
17447117f1b4Smrg                        "glGetTexLevelParameter[if]v(pname)");
17457117f1b4Smrg         }
17467117f1b4Smrg         break;
17477117f1b4Smrg      case GL_TEXTURE_BLUE_TYPE_ARB:
17487117f1b4Smrg         if (ctx->Extensions.ARB_texture_float) {
17497117f1b4Smrg            *params = img->TexFormat->BlueBits ? img->TexFormat->DataType : GL_NONE;
17507117f1b4Smrg         }
17517117f1b4Smrg         else {
17527117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
17537117f1b4Smrg                        "glGetTexLevelParameter[if]v(pname)");
17547117f1b4Smrg         }
17557117f1b4Smrg         break;
17567117f1b4Smrg      case GL_TEXTURE_ALPHA_TYPE_ARB:
17577117f1b4Smrg         if (ctx->Extensions.ARB_texture_float) {
17587117f1b4Smrg            *params = img->TexFormat->AlphaBits ? img->TexFormat->DataType : GL_NONE;
17597117f1b4Smrg         }
17607117f1b4Smrg         else {
17617117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
17627117f1b4Smrg                        "glGetTexLevelParameter[if]v(pname)");
17637117f1b4Smrg         }
17647117f1b4Smrg         break;
17657117f1b4Smrg      case GL_TEXTURE_LUMINANCE_TYPE_ARB:
17667117f1b4Smrg         if (ctx->Extensions.ARB_texture_float) {
17677117f1b4Smrg            *params = img->TexFormat->LuminanceBits ? img->TexFormat->DataType : GL_NONE;
17687117f1b4Smrg         }
17697117f1b4Smrg         else {
17707117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
17717117f1b4Smrg                        "glGetTexLevelParameter[if]v(pname)");
17727117f1b4Smrg         }
17737117f1b4Smrg         break;
17747117f1b4Smrg      case GL_TEXTURE_INTENSITY_TYPE_ARB:
17757117f1b4Smrg         if (ctx->Extensions.ARB_texture_float) {
17767117f1b4Smrg            *params = img->TexFormat->IntensityBits ? img->TexFormat->DataType : GL_NONE;
17777117f1b4Smrg         }
17787117f1b4Smrg         else {
17797117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
17807117f1b4Smrg                        "glGetTexLevelParameter[if]v(pname)");
17817117f1b4Smrg         }
17827117f1b4Smrg         break;
17837117f1b4Smrg      case GL_TEXTURE_DEPTH_TYPE_ARB:
17847117f1b4Smrg         if (ctx->Extensions.ARB_texture_float) {
17857117f1b4Smrg            *params = img->TexFormat->DepthBits ? img->TexFormat->DataType : GL_NONE;
17867117f1b4Smrg         }
17877117f1b4Smrg         else {
17887117f1b4Smrg            _mesa_error(ctx, GL_INVALID_ENUM,
17897117f1b4Smrg                        "glGetTexLevelParameter[if]v(pname)");
17907117f1b4Smrg         }
17917117f1b4Smrg         break;
17927117f1b4Smrg
17937117f1b4Smrg      default:
17947117f1b4Smrg         _mesa_error(ctx, GL_INVALID_ENUM,
17957117f1b4Smrg                     "glGetTexLevelParameter[if]v(pname)");
17967117f1b4Smrg   }
17977117f1b4Smrg
17987117f1b4Smrg out:
17997117f1b4Smrg   _mesa_unlock_texture(ctx, texObj);
18007117f1b4Smrg}
18017117f1b4Smrg
18027117f1b4Smrg
18037117f1b4Smrg
18047117f1b4Smrgvoid GLAPIENTRY
18057117f1b4Smrg_mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
18067117f1b4Smrg{
18077117f1b4Smrg   struct gl_texture_unit *texUnit;
18087117f1b4Smrg   struct gl_texture_object *obj;
18097117f1b4Smrg   GLboolean error = GL_FALSE;
18107117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
18117117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
18127117f1b4Smrg
18137117f1b4Smrg   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
18147117f1b4Smrg      _mesa_error(ctx, GL_INVALID_OPERATION,
18157117f1b4Smrg                  "glGetTexParameterfv(current unit)");
18167117f1b4Smrg      return;
18177117f1b4Smrg   }
18187117f1b4Smrg
18197117f1b4Smrg   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
18207117f1b4Smrg
18217117f1b4Smrg   obj = _mesa_select_tex_object(ctx, texUnit, target);
18227117f1b4Smrg   if (!obj) {
18237117f1b4Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)");
18247117f1b4Smrg      return;
18257117f1b4Smrg   }
18267117f1b4Smrg
18277117f1b4Smrg   _mesa_lock_texture(ctx, obj);
18287117f1b4Smrg   switch (pname) {
18297117f1b4Smrg      case GL_TEXTURE_MAG_FILTER:
18307117f1b4Smrg	 *params = ENUM_TO_FLOAT(obj->MagFilter);
18317117f1b4Smrg	 break;
18327117f1b4Smrg      case GL_TEXTURE_MIN_FILTER:
18337117f1b4Smrg         *params = ENUM_TO_FLOAT(obj->MinFilter);
18347117f1b4Smrg         break;
18357117f1b4Smrg      case GL_TEXTURE_WRAP_S:
18367117f1b4Smrg         *params = ENUM_TO_FLOAT(obj->WrapS);
18377117f1b4Smrg         break;
18387117f1b4Smrg      case GL_TEXTURE_WRAP_T:
18397117f1b4Smrg         *params = ENUM_TO_FLOAT(obj->WrapT);
18407117f1b4Smrg         break;
18417117f1b4Smrg      case GL_TEXTURE_WRAP_R:
18427117f1b4Smrg         *params = ENUM_TO_FLOAT(obj->WrapR);
18437117f1b4Smrg         break;
18447117f1b4Smrg      case GL_TEXTURE_BORDER_COLOR:
18457117f1b4Smrg         params[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
18467117f1b4Smrg         params[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
18477117f1b4Smrg         params[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
18487117f1b4Smrg         params[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
18497117f1b4Smrg         break;
18507117f1b4Smrg      case GL_TEXTURE_RESIDENT:
18517117f1b4Smrg         {
18527117f1b4Smrg            GLboolean resident;
18537117f1b4Smrg            if (ctx->Driver.IsTextureResident)
18547117f1b4Smrg               resident = ctx->Driver.IsTextureResident(ctx, obj);
18557117f1b4Smrg            else
18567117f1b4Smrg               resident = GL_TRUE;
18577117f1b4Smrg            *params = ENUM_TO_FLOAT(resident);
18587117f1b4Smrg         }
18597117f1b4Smrg         break;
18607117f1b4Smrg      case GL_TEXTURE_PRIORITY:
18617117f1b4Smrg         *params = obj->Priority;
18627117f1b4Smrg         break;
18637117f1b4Smrg      case GL_TEXTURE_MIN_LOD:
18647117f1b4Smrg         *params = obj->MinLod;
18657117f1b4Smrg         break;
18667117f1b4Smrg      case GL_TEXTURE_MAX_LOD:
18677117f1b4Smrg         *params = obj->MaxLod;
18687117f1b4Smrg         break;
18697117f1b4Smrg      case GL_TEXTURE_BASE_LEVEL:
18707117f1b4Smrg         *params = (GLfloat) obj->BaseLevel;
18717117f1b4Smrg         break;
18727117f1b4Smrg      case GL_TEXTURE_MAX_LEVEL:
18737117f1b4Smrg         *params = (GLfloat) obj->MaxLevel;
18747117f1b4Smrg         break;
18757117f1b4Smrg      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
18767117f1b4Smrg         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
18777117f1b4Smrg            *params = obj->MaxAnisotropy;
18787117f1b4Smrg         }
18797117f1b4Smrg	 else
18807117f1b4Smrg	    error = 1;
18817117f1b4Smrg         break;
18827117f1b4Smrg      case GL_TEXTURE_COMPARE_SGIX:
18837117f1b4Smrg         if (ctx->Extensions.SGIX_shadow) {
18847117f1b4Smrg            *params = (GLfloat) obj->CompareFlag;
18857117f1b4Smrg         }
18867117f1b4Smrg	 else
18877117f1b4Smrg	    error = 1;
18887117f1b4Smrg         break;
18897117f1b4Smrg      case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
18907117f1b4Smrg         if (ctx->Extensions.SGIX_shadow) {
18917117f1b4Smrg            *params = (GLfloat) obj->CompareOperator;
18927117f1b4Smrg         }
18937117f1b4Smrg	 else
18947117f1b4Smrg	    error = 1;
18957117f1b4Smrg         break;
18967117f1b4Smrg      case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
18977117f1b4Smrg         if (ctx->Extensions.SGIX_shadow_ambient) {
18987117f1b4Smrg            *params = obj->ShadowAmbient;
18997117f1b4Smrg         }
19007117f1b4Smrg	 else
19017117f1b4Smrg	    error = 1;
19027117f1b4Smrg         break;
19037117f1b4Smrg      case GL_GENERATE_MIPMAP_SGIS:
19047117f1b4Smrg         if (ctx->Extensions.SGIS_generate_mipmap) {
19057117f1b4Smrg            *params = (GLfloat) obj->GenerateMipmap;
19067117f1b4Smrg         }
19077117f1b4Smrg	 else
19087117f1b4Smrg	    error = 1;
19097117f1b4Smrg         break;
19107117f1b4Smrg      case GL_TEXTURE_COMPARE_MODE_ARB:
19117117f1b4Smrg         if (ctx->Extensions.ARB_shadow) {
19127117f1b4Smrg            *params = (GLfloat) obj->CompareMode;
19137117f1b4Smrg         }
19147117f1b4Smrg	 else
19157117f1b4Smrg	    error = 1;
19167117f1b4Smrg         break;
19177117f1b4Smrg      case GL_TEXTURE_COMPARE_FUNC_ARB:
19187117f1b4Smrg         if (ctx->Extensions.ARB_shadow) {
19197117f1b4Smrg            *params = (GLfloat) obj->CompareFunc;
19207117f1b4Smrg         }
19217117f1b4Smrg	 else
19227117f1b4Smrg	    error = 1;
19237117f1b4Smrg         break;
19247117f1b4Smrg      case GL_DEPTH_TEXTURE_MODE_ARB:
19257117f1b4Smrg         if (ctx->Extensions.ARB_depth_texture) {
19267117f1b4Smrg            *params = (GLfloat) obj->DepthMode;
19277117f1b4Smrg         }
19287117f1b4Smrg	 else
19297117f1b4Smrg	    error = 1;
19307117f1b4Smrg         break;
19317117f1b4Smrg      case GL_TEXTURE_LOD_BIAS:
19327117f1b4Smrg         if (ctx->Extensions.EXT_texture_lod_bias) {
19337117f1b4Smrg            *params = obj->LodBias;
19347117f1b4Smrg         }
19357117f1b4Smrg	 else
19367117f1b4Smrg	    error = 1;
19377117f1b4Smrg         break;
19387117f1b4Smrg      default:
19397117f1b4Smrg	 error = 1;
19407117f1b4Smrg	 break;
19417117f1b4Smrg   }
19427117f1b4Smrg   if (error)
19437117f1b4Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)",
19447117f1b4Smrg		  pname);
19457117f1b4Smrg
19467117f1b4Smrg   _mesa_unlock_texture(ctx, obj);
19477117f1b4Smrg}
19487117f1b4Smrg
19497117f1b4Smrg
19507117f1b4Smrgvoid GLAPIENTRY
19517117f1b4Smrg_mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
19527117f1b4Smrg{
19537117f1b4Smrg   struct gl_texture_unit *texUnit;
19547117f1b4Smrg   struct gl_texture_object *obj;
19557117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
19567117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
19577117f1b4Smrg
19587117f1b4Smrg   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) {
19597117f1b4Smrg      _mesa_error(ctx, GL_INVALID_OPERATION,
19607117f1b4Smrg                  "glGetTexParameteriv(current unit)");
19617117f1b4Smrg      return;
19627117f1b4Smrg   }
19637117f1b4Smrg
19647117f1b4Smrg   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
19657117f1b4Smrg
19667117f1b4Smrg   obj = _mesa_select_tex_object(ctx, texUnit, target);
19677117f1b4Smrg   if (!obj) {
19687117f1b4Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(target)");
19697117f1b4Smrg      return;
19707117f1b4Smrg   }
19717117f1b4Smrg
19727117f1b4Smrg   switch (pname) {
19737117f1b4Smrg      case GL_TEXTURE_MAG_FILTER:
19747117f1b4Smrg         *params = (GLint) obj->MagFilter;
19757117f1b4Smrg         return;
19767117f1b4Smrg      case GL_TEXTURE_MIN_FILTER:
19777117f1b4Smrg         *params = (GLint) obj->MinFilter;
19787117f1b4Smrg         return;
19797117f1b4Smrg      case GL_TEXTURE_WRAP_S:
19807117f1b4Smrg         *params = (GLint) obj->WrapS;
19817117f1b4Smrg         return;
19827117f1b4Smrg      case GL_TEXTURE_WRAP_T:
19837117f1b4Smrg         *params = (GLint) obj->WrapT;
19847117f1b4Smrg         return;
19857117f1b4Smrg      case GL_TEXTURE_WRAP_R:
19867117f1b4Smrg         *params = (GLint) obj->WrapR;
19877117f1b4Smrg         return;
19887117f1b4Smrg      case GL_TEXTURE_BORDER_COLOR:
19897117f1b4Smrg         {
19907117f1b4Smrg            GLfloat b[4];
19917117f1b4Smrg            b[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F);
19927117f1b4Smrg            b[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F);
19937117f1b4Smrg            b[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F);
19947117f1b4Smrg            b[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F);
19957117f1b4Smrg            params[0] = FLOAT_TO_INT(b[0]);
19967117f1b4Smrg            params[1] = FLOAT_TO_INT(b[1]);
19977117f1b4Smrg            params[2] = FLOAT_TO_INT(b[2]);
19987117f1b4Smrg            params[3] = FLOAT_TO_INT(b[3]);
19997117f1b4Smrg         }
20007117f1b4Smrg         return;
20017117f1b4Smrg      case GL_TEXTURE_RESIDENT:
20027117f1b4Smrg         {
20037117f1b4Smrg            GLboolean resident;
20047117f1b4Smrg            if (ctx->Driver.IsTextureResident)
20057117f1b4Smrg               resident = ctx->Driver.IsTextureResident(ctx, obj);
20067117f1b4Smrg            else
20077117f1b4Smrg               resident = GL_TRUE;
20087117f1b4Smrg            *params = (GLint) resident;
20097117f1b4Smrg         }
20107117f1b4Smrg         return;
20117117f1b4Smrg      case GL_TEXTURE_PRIORITY:
20127117f1b4Smrg         *params = FLOAT_TO_INT(obj->Priority);
20137117f1b4Smrg         return;
20147117f1b4Smrg      case GL_TEXTURE_MIN_LOD:
20157117f1b4Smrg         *params = (GLint) obj->MinLod;
20167117f1b4Smrg         return;
20177117f1b4Smrg      case GL_TEXTURE_MAX_LOD:
20187117f1b4Smrg         *params = (GLint) obj->MaxLod;
20197117f1b4Smrg         return;
20207117f1b4Smrg      case GL_TEXTURE_BASE_LEVEL:
20217117f1b4Smrg         *params = obj->BaseLevel;
20227117f1b4Smrg         return;
20237117f1b4Smrg      case GL_TEXTURE_MAX_LEVEL:
20247117f1b4Smrg         *params = obj->MaxLevel;
20257117f1b4Smrg         return;
20267117f1b4Smrg      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
20277117f1b4Smrg         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
20287117f1b4Smrg            *params = (GLint) obj->MaxAnisotropy;
20297117f1b4Smrg            return;
20307117f1b4Smrg         }
20317117f1b4Smrg         break;
20327117f1b4Smrg      case GL_TEXTURE_COMPARE_SGIX:
20337117f1b4Smrg         if (ctx->Extensions.SGIX_shadow) {
20347117f1b4Smrg            *params = (GLint) obj->CompareFlag;
20357117f1b4Smrg            return;
20367117f1b4Smrg         }
20377117f1b4Smrg         break;
20387117f1b4Smrg      case GL_TEXTURE_COMPARE_OPERATOR_SGIX:
20397117f1b4Smrg         if (ctx->Extensions.SGIX_shadow) {
20407117f1b4Smrg            *params = (GLint) obj->CompareOperator;
20417117f1b4Smrg            return;
20427117f1b4Smrg         }
20437117f1b4Smrg         break;
20447117f1b4Smrg      case GL_SHADOW_AMBIENT_SGIX: /* aka GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
20457117f1b4Smrg         if (ctx->Extensions.SGIX_shadow_ambient) {
20467117f1b4Smrg            *params = (GLint) FLOAT_TO_INT(obj->ShadowAmbient);
20477117f1b4Smrg            return;
20487117f1b4Smrg         }
20497117f1b4Smrg         break;
20507117f1b4Smrg      case GL_GENERATE_MIPMAP_SGIS:
20517117f1b4Smrg         if (ctx->Extensions.SGIS_generate_mipmap) {
20527117f1b4Smrg            *params = (GLint) obj->GenerateMipmap;
20537117f1b4Smrg            return;
20547117f1b4Smrg         }
20557117f1b4Smrg         break;
20567117f1b4Smrg      case GL_TEXTURE_COMPARE_MODE_ARB:
20577117f1b4Smrg         if (ctx->Extensions.ARB_shadow) {
20587117f1b4Smrg            *params = (GLint) obj->CompareMode;
20597117f1b4Smrg            return;
20607117f1b4Smrg         }
20617117f1b4Smrg         break;
20627117f1b4Smrg      case GL_TEXTURE_COMPARE_FUNC_ARB:
20637117f1b4Smrg         if (ctx->Extensions.ARB_shadow) {
20647117f1b4Smrg            *params = (GLint) obj->CompareFunc;
20657117f1b4Smrg            return;
20667117f1b4Smrg         }
20677117f1b4Smrg         break;
20687117f1b4Smrg      case GL_DEPTH_TEXTURE_MODE_ARB:
20697117f1b4Smrg         if (ctx->Extensions.ARB_depth_texture) {
20707117f1b4Smrg            *params = (GLint) obj->DepthMode;
20717117f1b4Smrg            return;
20727117f1b4Smrg         }
20737117f1b4Smrg         break;
20747117f1b4Smrg      case GL_TEXTURE_LOD_BIAS:
20757117f1b4Smrg         if (ctx->Extensions.EXT_texture_lod_bias) {
20767117f1b4Smrg            *params = (GLint) obj->LodBias;
20777117f1b4Smrg            return;
20787117f1b4Smrg         }
20797117f1b4Smrg         break;
20807117f1b4Smrg      default:
20817117f1b4Smrg         ; /* silence warnings */
20827117f1b4Smrg   }
20837117f1b4Smrg   /* If we get here, pname was an unrecognized enum */
20847117f1b4Smrg   _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname);
20857117f1b4Smrg}
20867117f1b4Smrg
20877117f1b4Smrg
20887117f1b4Smrg
20897117f1b4Smrg
20907117f1b4Smrg/**********************************************************************/
20917117f1b4Smrg/*                    Texture Coord Generation                        */
20927117f1b4Smrg/**********************************************************************/
20937117f1b4Smrg
20947117f1b4Smrg#if FEATURE_texgen
20957117f1b4Smrgvoid GLAPIENTRY
20967117f1b4Smrg_mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
20977117f1b4Smrg{
20987117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
20997117f1b4Smrg   struct gl_texture_unit *texUnit;
21007117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
21017117f1b4Smrg
21027117f1b4Smrg   if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE))
21037117f1b4Smrg      _mesa_debug(ctx, "glTexGen %s %s %.1f(%s)...\n",
21047117f1b4Smrg                  _mesa_lookup_enum_by_nr(coord),
21057117f1b4Smrg                  _mesa_lookup_enum_by_nr(pname),
21067117f1b4Smrg                  *params,
21077117f1b4Smrg		  _mesa_lookup_enum_by_nr((GLenum) (GLint) *params));
21087117f1b4Smrg
21097117f1b4Smrg   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
21107117f1b4Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexGen(current unit)");
21117117f1b4Smrg      return;
21127117f1b4Smrg   }
21137117f1b4Smrg
21147117f1b4Smrg   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
21157117f1b4Smrg
21167117f1b4Smrg   switch (coord) {
21177117f1b4Smrg      case GL_S:
21187117f1b4Smrg         if (pname==GL_TEXTURE_GEN_MODE) {
21197117f1b4Smrg	    GLenum mode = (GLenum) (GLint) *params;
21207117f1b4Smrg	    GLbitfield bits;
21217117f1b4Smrg	    switch (mode) {
21227117f1b4Smrg	    case GL_OBJECT_LINEAR:
21237117f1b4Smrg	       bits = TEXGEN_OBJ_LINEAR;
21247117f1b4Smrg	       break;
21257117f1b4Smrg	    case GL_EYE_LINEAR:
21267117f1b4Smrg	       bits = TEXGEN_EYE_LINEAR;
21277117f1b4Smrg	       break;
21287117f1b4Smrg	    case GL_REFLECTION_MAP_NV:
21297117f1b4Smrg	       bits = TEXGEN_REFLECTION_MAP_NV;
21307117f1b4Smrg	       break;
21317117f1b4Smrg	    case GL_NORMAL_MAP_NV:
21327117f1b4Smrg	       bits = TEXGEN_NORMAL_MAP_NV;
21337117f1b4Smrg	       break;
21347117f1b4Smrg	    case GL_SPHERE_MAP:
21357117f1b4Smrg	       bits = TEXGEN_SPHERE_MAP;
21367117f1b4Smrg	       break;
21377117f1b4Smrg	    default:
21387117f1b4Smrg	       _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
21397117f1b4Smrg	       return;
21407117f1b4Smrg	    }
21417117f1b4Smrg	    if (texUnit->GenModeS == mode)
21427117f1b4Smrg	       return;
21437117f1b4Smrg	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
21447117f1b4Smrg	    texUnit->GenModeS = mode;
21457117f1b4Smrg	    texUnit->_GenBitS = bits;
21467117f1b4Smrg	 }
21477117f1b4Smrg	 else if (pname==GL_OBJECT_PLANE) {
21487117f1b4Smrg	    if (TEST_EQ_4V(texUnit->ObjectPlaneS, params))
21497117f1b4Smrg		return;
21507117f1b4Smrg	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
21517117f1b4Smrg            COPY_4FV(texUnit->ObjectPlaneS, params);
21527117f1b4Smrg	 }
21537117f1b4Smrg	 else if (pname==GL_EYE_PLANE) {
21547117f1b4Smrg	    GLfloat tmp[4];
21557117f1b4Smrg            /* Transform plane equation by the inverse modelview matrix */
21567117f1b4Smrg            if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
21577117f1b4Smrg               _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
21587117f1b4Smrg            }
21597117f1b4Smrg            _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
21607117f1b4Smrg	    if (TEST_EQ_4V(texUnit->EyePlaneS, tmp))
21617117f1b4Smrg	       return;
21627117f1b4Smrg	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
21637117f1b4Smrg	    COPY_4FV(texUnit->EyePlaneS, tmp);
21647117f1b4Smrg	 }
21657117f1b4Smrg	 else {
21667117f1b4Smrg	    _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
21677117f1b4Smrg	    return;
21687117f1b4Smrg	 }
21697117f1b4Smrg	 break;
21707117f1b4Smrg      case GL_T:
21717117f1b4Smrg         if (pname==GL_TEXTURE_GEN_MODE) {
21727117f1b4Smrg	    GLenum mode = (GLenum) (GLint) *params;
21737117f1b4Smrg	    GLbitfield bitt;
21747117f1b4Smrg	    switch (mode) {
21757117f1b4Smrg               case GL_OBJECT_LINEAR:
21767117f1b4Smrg                  bitt = TEXGEN_OBJ_LINEAR;
21777117f1b4Smrg                  break;
21787117f1b4Smrg               case GL_EYE_LINEAR:
21797117f1b4Smrg                  bitt = TEXGEN_EYE_LINEAR;
21807117f1b4Smrg                  break;
21817117f1b4Smrg               case GL_REFLECTION_MAP_NV:
21827117f1b4Smrg                  bitt = TEXGEN_REFLECTION_MAP_NV;
21837117f1b4Smrg                  break;
21847117f1b4Smrg               case GL_NORMAL_MAP_NV:
21857117f1b4Smrg                  bitt = TEXGEN_NORMAL_MAP_NV;
21867117f1b4Smrg                  break;
21877117f1b4Smrg               case GL_SPHERE_MAP:
21887117f1b4Smrg                  bitt = TEXGEN_SPHERE_MAP;
21897117f1b4Smrg                  break;
21907117f1b4Smrg               default:
21917117f1b4Smrg                  _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
21927117f1b4Smrg                  return;
21937117f1b4Smrg	    }
21947117f1b4Smrg	    if (texUnit->GenModeT == mode)
21957117f1b4Smrg	       return;
21967117f1b4Smrg	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
21977117f1b4Smrg	    texUnit->GenModeT = mode;
21987117f1b4Smrg	    texUnit->_GenBitT = bitt;
21997117f1b4Smrg	 }
22007117f1b4Smrg	 else if (pname==GL_OBJECT_PLANE) {
22017117f1b4Smrg	    if (TEST_EQ_4V(texUnit->ObjectPlaneT, params))
22027117f1b4Smrg		return;
22037117f1b4Smrg	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
22047117f1b4Smrg            COPY_4FV(texUnit->ObjectPlaneT, params);
22057117f1b4Smrg	 }
22067117f1b4Smrg	 else if (pname==GL_EYE_PLANE) {
22077117f1b4Smrg	    GLfloat tmp[4];
22087117f1b4Smrg            /* Transform plane equation by the inverse modelview matrix */
22097117f1b4Smrg	    if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
22107117f1b4Smrg               _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
22117117f1b4Smrg            }
22127117f1b4Smrg            _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
22137117f1b4Smrg	    if (TEST_EQ_4V(texUnit->EyePlaneT, tmp))
22147117f1b4Smrg		return;
22157117f1b4Smrg	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
22167117f1b4Smrg	    COPY_4FV(texUnit->EyePlaneT, tmp);
22177117f1b4Smrg	 }
22187117f1b4Smrg	 else {
22197117f1b4Smrg	    _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
22207117f1b4Smrg	    return;
22217117f1b4Smrg	 }
22227117f1b4Smrg	 break;
22237117f1b4Smrg      case GL_R:
22247117f1b4Smrg         if (pname==GL_TEXTURE_GEN_MODE) {
22257117f1b4Smrg	    GLenum mode = (GLenum) (GLint) *params;
22267117f1b4Smrg	    GLbitfield bitr;
22277117f1b4Smrg	    switch (mode) {
22287117f1b4Smrg	    case GL_OBJECT_LINEAR:
22297117f1b4Smrg	       bitr = TEXGEN_OBJ_LINEAR;
22307117f1b4Smrg	       break;
22317117f1b4Smrg	    case GL_REFLECTION_MAP_NV:
22327117f1b4Smrg	       bitr = TEXGEN_REFLECTION_MAP_NV;
22337117f1b4Smrg	       break;
22347117f1b4Smrg	    case GL_NORMAL_MAP_NV:
22357117f1b4Smrg	       bitr = TEXGEN_NORMAL_MAP_NV;
22367117f1b4Smrg	       break;
22377117f1b4Smrg	    case GL_EYE_LINEAR:
22387117f1b4Smrg	       bitr = TEXGEN_EYE_LINEAR;
22397117f1b4Smrg	       break;
22407117f1b4Smrg	    default:
22417117f1b4Smrg	       _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
22427117f1b4Smrg	       return;
22437117f1b4Smrg	    }
22447117f1b4Smrg	    if (texUnit->GenModeR == mode)
22457117f1b4Smrg	       return;
22467117f1b4Smrg	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
22477117f1b4Smrg	    texUnit->GenModeR = mode;
22487117f1b4Smrg	    texUnit->_GenBitR = bitr;
22497117f1b4Smrg	 }
22507117f1b4Smrg	 else if (pname==GL_OBJECT_PLANE) {
22517117f1b4Smrg	    if (TEST_EQ_4V(texUnit->ObjectPlaneR, params))
22527117f1b4Smrg		return;
22537117f1b4Smrg	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
22547117f1b4Smrg	    COPY_4FV(texUnit->ObjectPlaneR, params);
22557117f1b4Smrg	 }
22567117f1b4Smrg	 else if (pname==GL_EYE_PLANE) {
22577117f1b4Smrg	    GLfloat tmp[4];
22587117f1b4Smrg            /* Transform plane equation by the inverse modelview matrix */
22597117f1b4Smrg            if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
22607117f1b4Smrg               _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
22617117f1b4Smrg            }
22627117f1b4Smrg            _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
22637117f1b4Smrg	    if (TEST_EQ_4V(texUnit->EyePlaneR, tmp))
22647117f1b4Smrg	       return;
22657117f1b4Smrg	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
22667117f1b4Smrg	    COPY_4FV(texUnit->EyePlaneR, tmp);
22677117f1b4Smrg	 }
22687117f1b4Smrg	 else {
22697117f1b4Smrg	    _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
22707117f1b4Smrg	    return;
22717117f1b4Smrg	 }
22727117f1b4Smrg	 break;
22737117f1b4Smrg      case GL_Q:
22747117f1b4Smrg         if (pname==GL_TEXTURE_GEN_MODE) {
22757117f1b4Smrg	    GLenum mode = (GLenum) (GLint) *params;
22767117f1b4Smrg	    GLbitfield bitq;
22777117f1b4Smrg	    switch (mode) {
22787117f1b4Smrg	    case GL_OBJECT_LINEAR:
22797117f1b4Smrg	       bitq = TEXGEN_OBJ_LINEAR;
22807117f1b4Smrg	       break;
22817117f1b4Smrg	    case GL_EYE_LINEAR:
22827117f1b4Smrg	       bitq = TEXGEN_EYE_LINEAR;
22837117f1b4Smrg	       break;
22847117f1b4Smrg	    default:
22857117f1b4Smrg	       _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(param)" );
22867117f1b4Smrg	       return;
22877117f1b4Smrg	    }
22887117f1b4Smrg	    if (texUnit->GenModeQ == mode)
22897117f1b4Smrg	       return;
22907117f1b4Smrg	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
22917117f1b4Smrg	    texUnit->GenModeQ = mode;
22927117f1b4Smrg	    texUnit->_GenBitQ = bitq;
22937117f1b4Smrg	 }
22947117f1b4Smrg	 else if (pname==GL_OBJECT_PLANE) {
22957117f1b4Smrg	    if (TEST_EQ_4V(texUnit->ObjectPlaneQ, params))
22967117f1b4Smrg		return;
22977117f1b4Smrg	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
22987117f1b4Smrg            COPY_4FV(texUnit->ObjectPlaneQ, params);
22997117f1b4Smrg	 }
23007117f1b4Smrg	 else if (pname==GL_EYE_PLANE) {
23017117f1b4Smrg	    GLfloat tmp[4];
23027117f1b4Smrg            /* Transform plane equation by the inverse modelview matrix */
23037117f1b4Smrg            if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
23047117f1b4Smrg               _math_matrix_analyse( ctx->ModelviewMatrixStack.Top );
23057117f1b4Smrg            }
23067117f1b4Smrg            _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv );
23077117f1b4Smrg	    if (TEST_EQ_4V(texUnit->EyePlaneQ, tmp))
23087117f1b4Smrg	       return;
23097117f1b4Smrg	    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
23107117f1b4Smrg	    COPY_4FV(texUnit->EyePlaneQ, tmp);
23117117f1b4Smrg	 }
23127117f1b4Smrg	 else {
23137117f1b4Smrg	    _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" );
23147117f1b4Smrg	    return;
23157117f1b4Smrg	 }
23167117f1b4Smrg	 break;
23177117f1b4Smrg      default:
23187117f1b4Smrg         _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(coord)" );
23197117f1b4Smrg	 return;
23207117f1b4Smrg   }
23217117f1b4Smrg
23227117f1b4Smrg   if (ctx->Driver.TexGen)
23237117f1b4Smrg      ctx->Driver.TexGen( ctx, coord, pname, params );
23247117f1b4Smrg}
23257117f1b4Smrg
23267117f1b4Smrg
23277117f1b4Smrgvoid GLAPIENTRY
23287117f1b4Smrg_mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params )
23297117f1b4Smrg{
23307117f1b4Smrg   GLfloat p[4];
23317117f1b4Smrg   p[0] = (GLfloat) params[0];
23327117f1b4Smrg   if (pname == GL_TEXTURE_GEN_MODE) {
23337117f1b4Smrg      p[1] = p[2] = p[3] = 0.0F;
23347117f1b4Smrg   }
23357117f1b4Smrg   else {
23367117f1b4Smrg      p[1] = (GLfloat) params[1];
23377117f1b4Smrg      p[2] = (GLfloat) params[2];
23387117f1b4Smrg      p[3] = (GLfloat) params[3];
23397117f1b4Smrg   }
23407117f1b4Smrg   _mesa_TexGenfv(coord, pname, p);
23417117f1b4Smrg}
23427117f1b4Smrg
23437117f1b4Smrg
23447117f1b4Smrgvoid GLAPIENTRY
23457117f1b4Smrg_mesa_TexGend(GLenum coord, GLenum pname, GLdouble param )
23467117f1b4Smrg{
23477117f1b4Smrg   GLfloat p = (GLfloat) param;
23487117f1b4Smrg   _mesa_TexGenfv( coord, pname, &p );
23497117f1b4Smrg}
23507117f1b4Smrg
23517117f1b4Smrg
23527117f1b4Smrgvoid GLAPIENTRY
23537117f1b4Smrg_mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params )
23547117f1b4Smrg{
23557117f1b4Smrg   GLfloat p[4];
23567117f1b4Smrg   p[0] = (GLfloat) params[0];
23577117f1b4Smrg   if (pname == GL_TEXTURE_GEN_MODE) {
23587117f1b4Smrg      p[1] = p[2] = p[3] = 0.0F;
23597117f1b4Smrg   }
23607117f1b4Smrg   else {
23617117f1b4Smrg      p[1] = (GLfloat) params[1];
23627117f1b4Smrg      p[2] = (GLfloat) params[2];
23637117f1b4Smrg      p[3] = (GLfloat) params[3];
23647117f1b4Smrg   }
23657117f1b4Smrg   _mesa_TexGenfv( coord, pname, p );
23667117f1b4Smrg}
23677117f1b4Smrg
23687117f1b4Smrg
23697117f1b4Smrgvoid GLAPIENTRY
23707117f1b4Smrg_mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param )
23717117f1b4Smrg{
23727117f1b4Smrg   _mesa_TexGenfv(coord, pname, &param);
23737117f1b4Smrg}
23747117f1b4Smrg
23757117f1b4Smrg
23767117f1b4Smrgvoid GLAPIENTRY
23777117f1b4Smrg_mesa_TexGeni( GLenum coord, GLenum pname, GLint param )
23787117f1b4Smrg{
23797117f1b4Smrg   _mesa_TexGeniv( coord, pname, &param );
23807117f1b4Smrg}
23817117f1b4Smrg
23827117f1b4Smrg
23837117f1b4Smrg
23847117f1b4Smrgvoid GLAPIENTRY
23857117f1b4Smrg_mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params )
23867117f1b4Smrg{
23877117f1b4Smrg   const struct gl_texture_unit *texUnit;
23887117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
23897117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
23907117f1b4Smrg
23917117f1b4Smrg   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
23927117f1b4Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGendv(current unit)");
23937117f1b4Smrg      return;
23947117f1b4Smrg   }
23957117f1b4Smrg
23967117f1b4Smrg   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
23977117f1b4Smrg
23987117f1b4Smrg   switch (coord) {
23997117f1b4Smrg      case GL_S:
24007117f1b4Smrg         if (pname==GL_TEXTURE_GEN_MODE) {
24017117f1b4Smrg            params[0] = ENUM_TO_DOUBLE(texUnit->GenModeS);
24027117f1b4Smrg	 }
24037117f1b4Smrg	 else if (pname==GL_OBJECT_PLANE) {
24047117f1b4Smrg            COPY_4V( params, texUnit->ObjectPlaneS );
24057117f1b4Smrg	 }
24067117f1b4Smrg	 else if (pname==GL_EYE_PLANE) {
24077117f1b4Smrg            COPY_4V( params, texUnit->EyePlaneS );
24087117f1b4Smrg	 }
24097117f1b4Smrg	 else {
24107117f1b4Smrg	    _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
24117117f1b4Smrg	    return;
24127117f1b4Smrg	 }
24137117f1b4Smrg	 break;
24147117f1b4Smrg      case GL_T:
24157117f1b4Smrg         if (pname==GL_TEXTURE_GEN_MODE) {
24167117f1b4Smrg            params[0] = ENUM_TO_DOUBLE(texUnit->GenModeT);
24177117f1b4Smrg	 }
24187117f1b4Smrg	 else if (pname==GL_OBJECT_PLANE) {
24197117f1b4Smrg            COPY_4V( params, texUnit->ObjectPlaneT );
24207117f1b4Smrg	 }
24217117f1b4Smrg	 else if (pname==GL_EYE_PLANE) {
24227117f1b4Smrg            COPY_4V( params, texUnit->EyePlaneT );
24237117f1b4Smrg	 }
24247117f1b4Smrg	 else {
24257117f1b4Smrg	    _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
24267117f1b4Smrg	    return;
24277117f1b4Smrg	 }
24287117f1b4Smrg	 break;
24297117f1b4Smrg      case GL_R:
24307117f1b4Smrg         if (pname==GL_TEXTURE_GEN_MODE) {
24317117f1b4Smrg            params[0] = ENUM_TO_DOUBLE(texUnit->GenModeR);
24327117f1b4Smrg	 }
24337117f1b4Smrg	 else if (pname==GL_OBJECT_PLANE) {
24347117f1b4Smrg            COPY_4V( params, texUnit->ObjectPlaneR );
24357117f1b4Smrg	 }
24367117f1b4Smrg	 else if (pname==GL_EYE_PLANE) {
24377117f1b4Smrg            COPY_4V( params, texUnit->EyePlaneR );
24387117f1b4Smrg	 }
24397117f1b4Smrg	 else {
24407117f1b4Smrg	    _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
24417117f1b4Smrg	    return;
24427117f1b4Smrg	 }
24437117f1b4Smrg	 break;
24447117f1b4Smrg      case GL_Q:
24457117f1b4Smrg         if (pname==GL_TEXTURE_GEN_MODE) {
24467117f1b4Smrg            params[0] = ENUM_TO_DOUBLE(texUnit->GenModeQ);
24477117f1b4Smrg	 }
24487117f1b4Smrg	 else if (pname==GL_OBJECT_PLANE) {
24497117f1b4Smrg            COPY_4V( params, texUnit->ObjectPlaneQ );
24507117f1b4Smrg	 }
24517117f1b4Smrg	 else if (pname==GL_EYE_PLANE) {
24527117f1b4Smrg            COPY_4V( params, texUnit->EyePlaneQ );
24537117f1b4Smrg	 }
24547117f1b4Smrg	 else {
24557117f1b4Smrg	    _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(pname)" );
24567117f1b4Smrg	    return;
24577117f1b4Smrg	 }
24587117f1b4Smrg	 break;
24597117f1b4Smrg      default:
24607117f1b4Smrg         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGendv(coord)" );
24617117f1b4Smrg	 return;
24627117f1b4Smrg   }
24637117f1b4Smrg}
24647117f1b4Smrg
24657117f1b4Smrg
24667117f1b4Smrg
24677117f1b4Smrgvoid GLAPIENTRY
24687117f1b4Smrg_mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params )
24697117f1b4Smrg{
24707117f1b4Smrg   const struct gl_texture_unit *texUnit;
24717117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
24727117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
24737117f1b4Smrg
24747117f1b4Smrg   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
24757117f1b4Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGenfv(current unit)");
24767117f1b4Smrg      return;
24777117f1b4Smrg   }
24787117f1b4Smrg
24797117f1b4Smrg   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
24807117f1b4Smrg
24817117f1b4Smrg   switch (coord) {
24827117f1b4Smrg      case GL_S:
24837117f1b4Smrg         if (pname==GL_TEXTURE_GEN_MODE) {
24847117f1b4Smrg            params[0] = ENUM_TO_FLOAT(texUnit->GenModeS);
24857117f1b4Smrg	 }
24867117f1b4Smrg	 else if (pname==GL_OBJECT_PLANE) {
24877117f1b4Smrg            COPY_4V( params, texUnit->ObjectPlaneS );
24887117f1b4Smrg	 }
24897117f1b4Smrg	 else if (pname==GL_EYE_PLANE) {
24907117f1b4Smrg            COPY_4V( params, texUnit->EyePlaneS );
24917117f1b4Smrg	 }
24927117f1b4Smrg	 else {
24937117f1b4Smrg	    _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
24947117f1b4Smrg	    return;
24957117f1b4Smrg	 }
24967117f1b4Smrg	 break;
24977117f1b4Smrg      case GL_T:
24987117f1b4Smrg         if (pname==GL_TEXTURE_GEN_MODE) {
24997117f1b4Smrg            params[0] = ENUM_TO_FLOAT(texUnit->GenModeT);
25007117f1b4Smrg	 }
25017117f1b4Smrg	 else if (pname==GL_OBJECT_PLANE) {
25027117f1b4Smrg            COPY_4V( params, texUnit->ObjectPlaneT );
25037117f1b4Smrg	 }
25047117f1b4Smrg	 else if (pname==GL_EYE_PLANE) {
25057117f1b4Smrg            COPY_4V( params, texUnit->EyePlaneT );
25067117f1b4Smrg	 }
25077117f1b4Smrg	 else {
25087117f1b4Smrg	    _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
25097117f1b4Smrg	    return;
25107117f1b4Smrg	 }
25117117f1b4Smrg	 break;
25127117f1b4Smrg      case GL_R:
25137117f1b4Smrg         if (pname==GL_TEXTURE_GEN_MODE) {
25147117f1b4Smrg            params[0] = ENUM_TO_FLOAT(texUnit->GenModeR);
25157117f1b4Smrg	 }
25167117f1b4Smrg	 else if (pname==GL_OBJECT_PLANE) {
25177117f1b4Smrg            COPY_4V( params, texUnit->ObjectPlaneR );
25187117f1b4Smrg	 }
25197117f1b4Smrg	 else if (pname==GL_EYE_PLANE) {
25207117f1b4Smrg            COPY_4V( params, texUnit->EyePlaneR );
25217117f1b4Smrg	 }
25227117f1b4Smrg	 else {
25237117f1b4Smrg	    _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
25247117f1b4Smrg	    return;
25257117f1b4Smrg	 }
25267117f1b4Smrg	 break;
25277117f1b4Smrg      case GL_Q:
25287117f1b4Smrg         if (pname==GL_TEXTURE_GEN_MODE) {
25297117f1b4Smrg            params[0] = ENUM_TO_FLOAT(texUnit->GenModeQ);
25307117f1b4Smrg	 }
25317117f1b4Smrg	 else if (pname==GL_OBJECT_PLANE) {
25327117f1b4Smrg            COPY_4V( params, texUnit->ObjectPlaneQ );
25337117f1b4Smrg	 }
25347117f1b4Smrg	 else if (pname==GL_EYE_PLANE) {
25357117f1b4Smrg            COPY_4V( params, texUnit->EyePlaneQ );
25367117f1b4Smrg	 }
25377117f1b4Smrg	 else {
25387117f1b4Smrg	    _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(pname)" );
25397117f1b4Smrg	    return;
25407117f1b4Smrg	 }
25417117f1b4Smrg	 break;
25427117f1b4Smrg      default:
25437117f1b4Smrg         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGenfv(coord)" );
25447117f1b4Smrg	 return;
25457117f1b4Smrg   }
25467117f1b4Smrg}
25477117f1b4Smrg
25487117f1b4Smrg
25497117f1b4Smrg
25507117f1b4Smrgvoid GLAPIENTRY
25517117f1b4Smrg_mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params )
25527117f1b4Smrg{
25537117f1b4Smrg   const struct gl_texture_unit *texUnit;
25547117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
25557117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
25567117f1b4Smrg
25577117f1b4Smrg   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) {
25587117f1b4Smrg      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGeniv(current unit)");
25597117f1b4Smrg      return;
25607117f1b4Smrg   }
25617117f1b4Smrg
25627117f1b4Smrg   texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
25637117f1b4Smrg
25647117f1b4Smrg   switch (coord) {
25657117f1b4Smrg      case GL_S:
25667117f1b4Smrg         if (pname==GL_TEXTURE_GEN_MODE) {
25677117f1b4Smrg            params[0] = texUnit->GenModeS;
25687117f1b4Smrg	 }
25697117f1b4Smrg	 else if (pname==GL_OBJECT_PLANE) {
25707117f1b4Smrg            params[0] = (GLint) texUnit->ObjectPlaneS[0];
25717117f1b4Smrg            params[1] = (GLint) texUnit->ObjectPlaneS[1];
25727117f1b4Smrg            params[2] = (GLint) texUnit->ObjectPlaneS[2];
25737117f1b4Smrg            params[3] = (GLint) texUnit->ObjectPlaneS[3];
25747117f1b4Smrg	 }
25757117f1b4Smrg	 else if (pname==GL_EYE_PLANE) {
25767117f1b4Smrg            params[0] = (GLint) texUnit->EyePlaneS[0];
25777117f1b4Smrg            params[1] = (GLint) texUnit->EyePlaneS[1];
25787117f1b4Smrg            params[2] = (GLint) texUnit->EyePlaneS[2];
25797117f1b4Smrg            params[3] = (GLint) texUnit->EyePlaneS[3];
25807117f1b4Smrg	 }
25817117f1b4Smrg	 else {
25827117f1b4Smrg	    _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
25837117f1b4Smrg	    return;
25847117f1b4Smrg	 }
25857117f1b4Smrg	 break;
25867117f1b4Smrg      case GL_T:
25877117f1b4Smrg         if (pname==GL_TEXTURE_GEN_MODE) {
25887117f1b4Smrg            params[0] = texUnit->GenModeT;
25897117f1b4Smrg	 }
25907117f1b4Smrg	 else if (pname==GL_OBJECT_PLANE) {
25917117f1b4Smrg            params[0] = (GLint) texUnit->ObjectPlaneT[0];
25927117f1b4Smrg            params[1] = (GLint) texUnit->ObjectPlaneT[1];
25937117f1b4Smrg            params[2] = (GLint) texUnit->ObjectPlaneT[2];
25947117f1b4Smrg            params[3] = (GLint) texUnit->ObjectPlaneT[3];
25957117f1b4Smrg	 }
25967117f1b4Smrg	 else if (pname==GL_EYE_PLANE) {
25977117f1b4Smrg            params[0] = (GLint) texUnit->EyePlaneT[0];
25987117f1b4Smrg            params[1] = (GLint) texUnit->EyePlaneT[1];
25997117f1b4Smrg            params[2] = (GLint) texUnit->EyePlaneT[2];
26007117f1b4Smrg            params[3] = (GLint) texUnit->EyePlaneT[3];
26017117f1b4Smrg	 }
26027117f1b4Smrg	 else {
26037117f1b4Smrg	    _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
26047117f1b4Smrg	    return;
26057117f1b4Smrg	 }
26067117f1b4Smrg	 break;
26077117f1b4Smrg      case GL_R:
26087117f1b4Smrg         if (pname==GL_TEXTURE_GEN_MODE) {
26097117f1b4Smrg            params[0] = texUnit->GenModeR;
26107117f1b4Smrg	 }
26117117f1b4Smrg	 else if (pname==GL_OBJECT_PLANE) {
26127117f1b4Smrg            params[0] = (GLint) texUnit->ObjectPlaneR[0];
26137117f1b4Smrg            params[1] = (GLint) texUnit->ObjectPlaneR[1];
26147117f1b4Smrg            params[2] = (GLint) texUnit->ObjectPlaneR[2];
26157117f1b4Smrg            params[3] = (GLint) texUnit->ObjectPlaneR[3];
26167117f1b4Smrg	 }
26177117f1b4Smrg	 else if (pname==GL_EYE_PLANE) {
26187117f1b4Smrg            params[0] = (GLint) texUnit->EyePlaneR[0];
26197117f1b4Smrg            params[1] = (GLint) texUnit->EyePlaneR[1];
26207117f1b4Smrg            params[2] = (GLint) texUnit->EyePlaneR[2];
26217117f1b4Smrg            params[3] = (GLint) texUnit->EyePlaneR[3];
26227117f1b4Smrg	 }
26237117f1b4Smrg	 else {
26247117f1b4Smrg	    _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
26257117f1b4Smrg	    return;
26267117f1b4Smrg	 }
26277117f1b4Smrg	 break;
26287117f1b4Smrg      case GL_Q:
26297117f1b4Smrg         if (pname==GL_TEXTURE_GEN_MODE) {
26307117f1b4Smrg            params[0] = texUnit->GenModeQ;
26317117f1b4Smrg	 }
26327117f1b4Smrg	 else if (pname==GL_OBJECT_PLANE) {
26337117f1b4Smrg            params[0] = (GLint) texUnit->ObjectPlaneQ[0];
26347117f1b4Smrg            params[1] = (GLint) texUnit->ObjectPlaneQ[1];
26357117f1b4Smrg            params[2] = (GLint) texUnit->ObjectPlaneQ[2];
26367117f1b4Smrg            params[3] = (GLint) texUnit->ObjectPlaneQ[3];
26377117f1b4Smrg	 }
26387117f1b4Smrg	 else if (pname==GL_EYE_PLANE) {
26397117f1b4Smrg            params[0] = (GLint) texUnit->EyePlaneQ[0];
26407117f1b4Smrg            params[1] = (GLint) texUnit->EyePlaneQ[1];
26417117f1b4Smrg            params[2] = (GLint) texUnit->EyePlaneQ[2];
26427117f1b4Smrg            params[3] = (GLint) texUnit->EyePlaneQ[3];
26437117f1b4Smrg         }
26447117f1b4Smrg	 else {
26457117f1b4Smrg	    _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(pname)" );
26467117f1b4Smrg	    return;
26477117f1b4Smrg	 }
26487117f1b4Smrg	 break;
26497117f1b4Smrg      default:
26507117f1b4Smrg         _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexGeniv(coord)" );
26517117f1b4Smrg	 return;
26527117f1b4Smrg   }
26537117f1b4Smrg}
26547117f1b4Smrg#endif
26557117f1b4Smrg
26567117f1b4Smrg
26577117f1b4Smrg/* GL_ARB_multitexture */
26587117f1b4Smrgvoid GLAPIENTRY
26597117f1b4Smrg_mesa_ActiveTextureARB(GLenum texture)
26607117f1b4Smrg{
26617117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
26627117f1b4Smrg   const GLuint texUnit = texture - GL_TEXTURE0;
26637117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
26647117f1b4Smrg
26657117f1b4Smrg   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
26667117f1b4Smrg      _mesa_debug(ctx, "glActiveTexture %s\n",
26677117f1b4Smrg                  _mesa_lookup_enum_by_nr(texture));
26687117f1b4Smrg
26697117f1b4Smrg   /* XXX error-check against max(coordunits, imageunits) */
26707117f1b4Smrg   if (texUnit >= ctx->Const.MaxTextureUnits) {
26717117f1b4Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture)");
26727117f1b4Smrg      return;
26737117f1b4Smrg   }
26747117f1b4Smrg
26757117f1b4Smrg   if (ctx->Texture.CurrentUnit == texUnit)
26767117f1b4Smrg      return;
26777117f1b4Smrg
26787117f1b4Smrg   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
26797117f1b4Smrg
26807117f1b4Smrg   ctx->Texture.CurrentUnit = texUnit;
26817117f1b4Smrg   if (ctx->Transform.MatrixMode == GL_TEXTURE) {
26827117f1b4Smrg      /* update current stack pointer */
26837117f1b4Smrg      ctx->CurrentStack = &ctx->TextureMatrixStack[texUnit];
26847117f1b4Smrg   }
26857117f1b4Smrg
26867117f1b4Smrg   if (ctx->Driver.ActiveTexture) {
26877117f1b4Smrg      (*ctx->Driver.ActiveTexture)( ctx, (GLuint) texUnit );
26887117f1b4Smrg   }
26897117f1b4Smrg}
26907117f1b4Smrg
26917117f1b4Smrg
26927117f1b4Smrg/* GL_ARB_multitexture */
26937117f1b4Smrgvoid GLAPIENTRY
26947117f1b4Smrg_mesa_ClientActiveTextureARB(GLenum texture)
26957117f1b4Smrg{
26967117f1b4Smrg   GET_CURRENT_CONTEXT(ctx);
26977117f1b4Smrg   GLuint texUnit = texture - GL_TEXTURE0;
26987117f1b4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
26997117f1b4Smrg
27007117f1b4Smrg   if (texUnit >= ctx->Const.MaxTextureCoordUnits) {
27017117f1b4Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(texture)");
27027117f1b4Smrg      return;
27037117f1b4Smrg   }
27047117f1b4Smrg
27057117f1b4Smrg   FLUSH_VERTICES(ctx, _NEW_ARRAY);
27067117f1b4Smrg   ctx->Array.ActiveTexture = texUnit;
27077117f1b4Smrg}
27087117f1b4Smrg
27097117f1b4Smrg
27107117f1b4Smrg
27117117f1b4Smrg/**********************************************************************/
27127117f1b4Smrg/*****                    State management                        *****/
27137117f1b4Smrg/**********************************************************************/
27147117f1b4Smrg
27157117f1b4Smrg
27167117f1b4Smrg/**
27177117f1b4Smrg * \note This routine refers to derived texture attribute values to
27187117f1b4Smrg * compute the ENABLE_TEXMAT flags, but is only called on
27197117f1b4Smrg * _NEW_TEXTURE_MATRIX.  On changes to _NEW_TEXTURE, the ENABLE_TEXMAT
27207117f1b4Smrg * flags are updated by _mesa_update_textures(), below.
27217117f1b4Smrg *
27227117f1b4Smrg * \param ctx GL context.
27237117f1b4Smrg */
27247117f1b4Smrgstatic void
27257117f1b4Smrgupdate_texture_matrices( GLcontext *ctx )
27267117f1b4Smrg{
27277117f1b4Smrg   GLuint i;
27287117f1b4Smrg
27297117f1b4Smrg   ctx->Texture._TexMatEnabled = 0;
27307117f1b4Smrg
27317117f1b4Smrg   for (i=0; i < ctx->Const.MaxTextureUnits; i++) {
27327117f1b4Smrg      if (_math_matrix_is_dirty(ctx->TextureMatrixStack[i].Top)) {
27337117f1b4Smrg	 _math_matrix_analyse( ctx->TextureMatrixStack[i].Top );
27347117f1b4Smrg
27357117f1b4Smrg	 if (ctx->Texture.Unit[i]._ReallyEnabled &&
27367117f1b4Smrg	     ctx->TextureMatrixStack[i].Top->type != MATRIX_IDENTITY)
27377117f1b4Smrg	    ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(i);
27387117f1b4Smrg
27397117f1b4Smrg	 if (ctx->Driver.TextureMatrix)
27407117f1b4Smrg	    ctx->Driver.TextureMatrix( ctx, i, ctx->TextureMatrixStack[i].Top);
27417117f1b4Smrg      }
27427117f1b4Smrg   }
27437117f1b4Smrg}
27447117f1b4Smrg
27457117f1b4Smrg
27467117f1b4Smrg/**
27477117f1b4Smrg * Helper function for determining which texture object (1D, 2D, cube, etc)
27487117f1b4Smrg * should actually be used.
27497117f1b4Smrg */
27507117f1b4Smrgstatic void
27517117f1b4Smrgtexture_override(GLcontext *ctx,
27527117f1b4Smrg                 struct gl_texture_unit *texUnit, GLbitfield enableBits,
27537117f1b4Smrg                 struct gl_texture_object *texObj, GLuint textureBit)
27547117f1b4Smrg{
27557117f1b4Smrg   if (!texUnit->_ReallyEnabled && (enableBits & textureBit)) {
27567117f1b4Smrg      if (!texObj->Complete) {
27577117f1b4Smrg         _mesa_test_texobj_completeness(ctx, texObj);
27587117f1b4Smrg      }
27597117f1b4Smrg      if (texObj->Complete) {
27607117f1b4Smrg         texUnit->_ReallyEnabled = textureBit;
27617117f1b4Smrg         texUnit->_Current = texObj;
27627117f1b4Smrg      }
27637117f1b4Smrg   }
27647117f1b4Smrg}
27657117f1b4Smrg
27667117f1b4Smrg
27677117f1b4Smrg/**
27687117f1b4Smrg * \note This routine refers to derived texture matrix values to
27697117f1b4Smrg * compute the ENABLE_TEXMAT flags, but is only called on
27707117f1b4Smrg * _NEW_TEXTURE.  On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT
27717117f1b4Smrg * flags are updated by _mesa_update_texture_matrices, above.
27727117f1b4Smrg *
27737117f1b4Smrg * \param ctx GL context.
27747117f1b4Smrg */
27757117f1b4Smrgstatic void
27767117f1b4Smrgupdate_texture_state( GLcontext *ctx )
27777117f1b4Smrg{
27787117f1b4Smrg   GLuint unit;
27797117f1b4Smrg   struct gl_fragment_program *fprog = NULL;
27807117f1b4Smrg   struct gl_vertex_program *vprog = NULL;
27817117f1b4Smrg
27827117f1b4Smrg   if (ctx->Shader.CurrentProgram &&
27837117f1b4Smrg       ctx->Shader.CurrentProgram->LinkStatus) {
27847117f1b4Smrg      fprog = ctx->Shader.CurrentProgram->FragmentProgram;
27857117f1b4Smrg      vprog = ctx->Shader.CurrentProgram->VertexProgram;
27867117f1b4Smrg   }
27877117f1b4Smrg   else {
27887117f1b4Smrg      if (ctx->FragmentProgram._Enabled) {
27897117f1b4Smrg         fprog = ctx->FragmentProgram.Current;
27907117f1b4Smrg      }
27917117f1b4Smrg      if (ctx->VertexProgram._Enabled) {
27927117f1b4Smrg         /* XXX enable this if/when non-shader vertex programs get
27937117f1b4Smrg          * texture fetches:
27947117f1b4Smrg         vprog = ctx->VertexProgram.Current;
27957117f1b4Smrg         */
27967117f1b4Smrg      }
27977117f1b4Smrg   }
27987117f1b4Smrg
27997117f1b4Smrg   ctx->NewState |= _NEW_TEXTURE; /* TODO: only set this if there are
28007117f1b4Smrg				   * actual changes.
28017117f1b4Smrg				   */
28027117f1b4Smrg
28037117f1b4Smrg   ctx->Texture._EnabledUnits = 0;
28047117f1b4Smrg   ctx->Texture._GenFlags = 0;
28057117f1b4Smrg   ctx->Texture._TexMatEnabled = 0;
28067117f1b4Smrg   ctx->Texture._TexGenEnabled = 0;
28077117f1b4Smrg
28087117f1b4Smrg   /*
28097117f1b4Smrg    * Update texture unit state.
28107117f1b4Smrg    */
28117117f1b4Smrg   for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
28127117f1b4Smrg      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
28137117f1b4Smrg      GLbitfield enableBits;
28147117f1b4Smrg
28157117f1b4Smrg      texUnit->_Current = NULL;
28167117f1b4Smrg      texUnit->_ReallyEnabled = 0;
28177117f1b4Smrg      texUnit->_GenFlags = 0;
28187117f1b4Smrg
28197117f1b4Smrg      /* Get the bitmask of texture enables.
28207117f1b4Smrg       * enableBits will be a mask of the TEXTURE_*_BIT flags indicating
28217117f1b4Smrg       * which texture targets are enabled (fixed function) or referenced
28227117f1b4Smrg       * by a fragment shader/program.  When multiple flags are set, we'll
28237117f1b4Smrg       * settle on the one with highest priority (see texture_override below).
28247117f1b4Smrg       */
28257117f1b4Smrg      if (fprog || vprog) {
28267117f1b4Smrg         enableBits = 0x0;
28277117f1b4Smrg         if (fprog)
28287117f1b4Smrg            enableBits |= fprog->Base.TexturesUsed[unit];
28297117f1b4Smrg         if (vprog)
28307117f1b4Smrg            enableBits |= vprog->Base.TexturesUsed[unit];
28317117f1b4Smrg      }
28327117f1b4Smrg      else {
28337117f1b4Smrg         if (!texUnit->Enabled)
28347117f1b4Smrg            continue;
28357117f1b4Smrg         enableBits = texUnit->Enabled;
28367117f1b4Smrg      }
28377117f1b4Smrg
28387117f1b4Smrg      /* Look for the highest-priority texture target that's enabled and
28397117f1b4Smrg       * complete.  That's the one we'll use for texturing.  If we're using
28407117f1b4Smrg       * a fragment program we're guaranteed that bitcount(enabledBits) <= 1.
28417117f1b4Smrg       */
28427117f1b4Smrg      texture_override(ctx, texUnit, enableBits,
28437117f1b4Smrg                       texUnit->CurrentCubeMap, TEXTURE_CUBE_BIT);
28447117f1b4Smrg      texture_override(ctx, texUnit, enableBits,
28457117f1b4Smrg                       texUnit->Current3D, TEXTURE_3D_BIT);
28467117f1b4Smrg      texture_override(ctx, texUnit, enableBits,
28477117f1b4Smrg                       texUnit->CurrentRect, TEXTURE_RECT_BIT);
28487117f1b4Smrg      texture_override(ctx, texUnit, enableBits,
28497117f1b4Smrg                       texUnit->Current2D, TEXTURE_2D_BIT);
28507117f1b4Smrg      texture_override(ctx, texUnit, enableBits,
28517117f1b4Smrg                       texUnit->Current1D, TEXTURE_1D_BIT);
28527117f1b4Smrg
28537117f1b4Smrg      if (!texUnit->_ReallyEnabled) {
28547117f1b4Smrg         continue;
28557117f1b4Smrg      }
28567117f1b4Smrg
28577117f1b4Smrg      if (texUnit->_ReallyEnabled)
28587117f1b4Smrg         ctx->Texture._EnabledUnits |= (1 << unit);
28597117f1b4Smrg
28607117f1b4Smrg      if (texUnit->EnvMode == GL_COMBINE) {
28617117f1b4Smrg	 texUnit->_CurrentCombine = & texUnit->Combine;
28627117f1b4Smrg      }
28637117f1b4Smrg      else {
28647117f1b4Smrg         const struct gl_texture_object *texObj = texUnit->_Current;
28657117f1b4Smrg         GLenum format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
28667117f1b4Smrg         if (format == GL_COLOR_INDEX) {
28677117f1b4Smrg            format = GL_RGBA;  /* a bit of a hack */
28687117f1b4Smrg         }
28697117f1b4Smrg         else if (format == GL_DEPTH_COMPONENT
28707117f1b4Smrg                  || format == GL_DEPTH_STENCIL_EXT) {
28717117f1b4Smrg            format = texObj->DepthMode;
28727117f1b4Smrg         }
28737117f1b4Smrg	 calculate_derived_texenv(&texUnit->_EnvMode, texUnit->EnvMode, format);
28747117f1b4Smrg	 texUnit->_CurrentCombine = & texUnit->_EnvMode;
28757117f1b4Smrg      }
28767117f1b4Smrg
28777117f1b4Smrg      switch (texUnit->_CurrentCombine->ModeRGB) {
28787117f1b4Smrg      case GL_REPLACE:
28797117f1b4Smrg	 texUnit->_CurrentCombine->_NumArgsRGB = 1;
28807117f1b4Smrg	 break;
28817117f1b4Smrg      case GL_MODULATE:
28827117f1b4Smrg      case GL_ADD:
28837117f1b4Smrg      case GL_ADD_SIGNED:
28847117f1b4Smrg      case GL_SUBTRACT:
28857117f1b4Smrg      case GL_DOT3_RGB:
28867117f1b4Smrg      case GL_DOT3_RGBA:
28877117f1b4Smrg      case GL_DOT3_RGB_EXT:
28887117f1b4Smrg      case GL_DOT3_RGBA_EXT:
28897117f1b4Smrg	 texUnit->_CurrentCombine->_NumArgsRGB = 2;
28907117f1b4Smrg	 break;
28917117f1b4Smrg      case GL_INTERPOLATE:
28927117f1b4Smrg      case GL_MODULATE_ADD_ATI:
28937117f1b4Smrg      case GL_MODULATE_SIGNED_ADD_ATI:
28947117f1b4Smrg      case GL_MODULATE_SUBTRACT_ATI:
28957117f1b4Smrg	 texUnit->_CurrentCombine->_NumArgsRGB = 3;
28967117f1b4Smrg	 break;
28977117f1b4Smrg      default:
28987117f1b4Smrg	 texUnit->_CurrentCombine->_NumArgsRGB = 0;
28997117f1b4Smrg         _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state");
29007117f1b4Smrg         return;
29017117f1b4Smrg      }
29027117f1b4Smrg
29037117f1b4Smrg      switch (texUnit->_CurrentCombine->ModeA) {
29047117f1b4Smrg      case GL_REPLACE:
29057117f1b4Smrg	 texUnit->_CurrentCombine->_NumArgsA = 1;
29067117f1b4Smrg	 break;
29077117f1b4Smrg      case GL_MODULATE:
29087117f1b4Smrg      case GL_ADD:
29097117f1b4Smrg      case GL_ADD_SIGNED:
29107117f1b4Smrg      case GL_SUBTRACT:
29117117f1b4Smrg	 texUnit->_CurrentCombine->_NumArgsA = 2;
29127117f1b4Smrg	 break;
29137117f1b4Smrg      case GL_INTERPOLATE:
29147117f1b4Smrg      case GL_MODULATE_ADD_ATI:
29157117f1b4Smrg      case GL_MODULATE_SIGNED_ADD_ATI:
29167117f1b4Smrg      case GL_MODULATE_SUBTRACT_ATI:
29177117f1b4Smrg	 texUnit->_CurrentCombine->_NumArgsA = 3;
29187117f1b4Smrg	 break;
29197117f1b4Smrg      default:
29207117f1b4Smrg	 texUnit->_CurrentCombine->_NumArgsA = 0;
29217117f1b4Smrg         _mesa_problem(ctx, "invalid Alpha combine mode in update_texture_state");
29227117f1b4Smrg	 break;
29237117f1b4Smrg      }
29247117f1b4Smrg
29257117f1b4Smrg      if (texUnit->TexGenEnabled) {
29267117f1b4Smrg	 if (texUnit->TexGenEnabled & S_BIT) {
29277117f1b4Smrg	    texUnit->_GenFlags |= texUnit->_GenBitS;
29287117f1b4Smrg	 }
29297117f1b4Smrg	 if (texUnit->TexGenEnabled & T_BIT) {
29307117f1b4Smrg	    texUnit->_GenFlags |= texUnit->_GenBitT;
29317117f1b4Smrg	 }
29327117f1b4Smrg	 if (texUnit->TexGenEnabled & Q_BIT) {
29337117f1b4Smrg	    texUnit->_GenFlags |= texUnit->_GenBitQ;
29347117f1b4Smrg	 }
29357117f1b4Smrg	 if (texUnit->TexGenEnabled & R_BIT) {
29367117f1b4Smrg	    texUnit->_GenFlags |= texUnit->_GenBitR;
29377117f1b4Smrg	 }
29387117f1b4Smrg
29397117f1b4Smrg	 ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(unit);
29407117f1b4Smrg	 ctx->Texture._GenFlags |= texUnit->_GenFlags;
29417117f1b4Smrg      }
29427117f1b4Smrg
29437117f1b4Smrg      if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY)
29447117f1b4Smrg	 ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
29457117f1b4Smrg   }
29467117f1b4Smrg
29477117f1b4Smrg   /* Determine which texture coordinate sets are actually needed */
29487117f1b4Smrg   if (fprog) {
29497117f1b4Smrg      const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
29507117f1b4Smrg      ctx->Texture._EnabledCoordUnits
29517117f1b4Smrg         = (fprog->Base.InputsRead >> FRAG_ATTRIB_TEX0) & coordMask;
29527117f1b4Smrg   }
29537117f1b4Smrg   else {
29547117f1b4Smrg      ctx->Texture._EnabledCoordUnits = ctx->Texture._EnabledUnits;
29557117f1b4Smrg   }
29567117f1b4Smrg}
29577117f1b4Smrg
29587117f1b4Smrg
29597117f1b4Smrg/**
29607117f1b4Smrg * Update texture-related derived state.
29617117f1b4Smrg */
29627117f1b4Smrgvoid
29637117f1b4Smrg_mesa_update_texture( GLcontext *ctx, GLuint new_state )
29647117f1b4Smrg{
29657117f1b4Smrg   if (new_state & _NEW_TEXTURE_MATRIX)
29667117f1b4Smrg      update_texture_matrices( ctx );
29677117f1b4Smrg
29687117f1b4Smrg   if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM))
29697117f1b4Smrg      update_texture_state( ctx );
29707117f1b4Smrg}
29717117f1b4Smrg
29727117f1b4Smrg
29737117f1b4Smrg/**********************************************************************/
29747117f1b4Smrg/*****                      Initialization                        *****/
29757117f1b4Smrg/**********************************************************************/
29767117f1b4Smrg
29777117f1b4Smrg/**
29787117f1b4Smrg * Allocate the proxy textures for the given context.
29797117f1b4Smrg *
29807117f1b4Smrg * \param ctx the context to allocate proxies for.
29817117f1b4Smrg *
29827117f1b4Smrg * \return GL_TRUE on success, or GL_FALSE on failure
29837117f1b4Smrg *
29847117f1b4Smrg * If run out of memory part way through the allocations, clean up and return
29857117f1b4Smrg * GL_FALSE.
29867117f1b4Smrg */
29877117f1b4Smrgstatic GLboolean
29887117f1b4Smrgalloc_proxy_textures( GLcontext *ctx )
29897117f1b4Smrg{
29907117f1b4Smrg   ctx->Texture.Proxy1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
29917117f1b4Smrg   if (!ctx->Texture.Proxy1D)
29927117f1b4Smrg      goto cleanup;
29937117f1b4Smrg
29947117f1b4Smrg   ctx->Texture.Proxy2D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D);
29957117f1b4Smrg   if (!ctx->Texture.Proxy2D)
29967117f1b4Smrg      goto cleanup;
29977117f1b4Smrg
29987117f1b4Smrg   ctx->Texture.Proxy3D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_3D);
29997117f1b4Smrg   if (!ctx->Texture.Proxy3D)
30007117f1b4Smrg      goto cleanup;
30017117f1b4Smrg
30027117f1b4Smrg   ctx->Texture.ProxyCubeMap = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_CUBE_MAP_ARB);
30037117f1b4Smrg   if (!ctx->Texture.ProxyCubeMap)
30047117f1b4Smrg      goto cleanup;
30057117f1b4Smrg
30067117f1b4Smrg   ctx->Texture.ProxyRect = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_RECTANGLE_NV);
30077117f1b4Smrg   if (!ctx->Texture.ProxyRect)
30087117f1b4Smrg      goto cleanup;
30097117f1b4Smrg
30107117f1b4Smrg   assert(ctx->Texture.Proxy1D->RefCount == 1);
30117117f1b4Smrg
30127117f1b4Smrg   return GL_TRUE;
30137117f1b4Smrg
30147117f1b4Smrg cleanup:
30157117f1b4Smrg   if (ctx->Texture.Proxy1D)
30167117f1b4Smrg      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D);
30177117f1b4Smrg   if (ctx->Texture.Proxy2D)
30187117f1b4Smrg      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2D);
30197117f1b4Smrg   if (ctx->Texture.Proxy3D)
30207117f1b4Smrg      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D);
30217117f1b4Smrg   if (ctx->Texture.ProxyCubeMap)
30227117f1b4Smrg      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap);
30237117f1b4Smrg   if (ctx->Texture.ProxyRect)
30247117f1b4Smrg      (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect);
30257117f1b4Smrg   return GL_FALSE;
30267117f1b4Smrg}
30277117f1b4Smrg
30287117f1b4Smrg
30297117f1b4Smrg/**
30307117f1b4Smrg * Initialize a texture unit.
30317117f1b4Smrg *
30327117f1b4Smrg * \param ctx GL context.
30337117f1b4Smrg * \param unit texture unit number to be initialized.
30347117f1b4Smrg */
30357117f1b4Smrgstatic void
30367117f1b4Smrginit_texture_unit( GLcontext *ctx, GLuint unit )
30377117f1b4Smrg{
30387117f1b4Smrg   struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
30397117f1b4Smrg
30407117f1b4Smrg   texUnit->EnvMode = GL_MODULATE;
30417117f1b4Smrg   ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
30427117f1b4Smrg
30437117f1b4Smrg   texUnit->Combine = default_combine_state;
30447117f1b4Smrg   texUnit->_EnvMode = default_combine_state;
30457117f1b4Smrg   texUnit->_CurrentCombine = & texUnit->_EnvMode;
30467117f1b4Smrg
30477117f1b4Smrg   texUnit->TexGenEnabled = 0;
30487117f1b4Smrg   texUnit->GenModeS = GL_EYE_LINEAR;
30497117f1b4Smrg   texUnit->GenModeT = GL_EYE_LINEAR;
30507117f1b4Smrg   texUnit->GenModeR = GL_EYE_LINEAR;
30517117f1b4Smrg   texUnit->GenModeQ = GL_EYE_LINEAR;
30527117f1b4Smrg   texUnit->_GenBitS = TEXGEN_EYE_LINEAR;
30537117f1b4Smrg   texUnit->_GenBitT = TEXGEN_EYE_LINEAR;
30547117f1b4Smrg   texUnit->_GenBitR = TEXGEN_EYE_LINEAR;
30557117f1b4Smrg   texUnit->_GenBitQ = TEXGEN_EYE_LINEAR;
30567117f1b4Smrg
30577117f1b4Smrg   /* Yes, these plane coefficients are correct! */
30587117f1b4Smrg   ASSIGN_4V( texUnit->ObjectPlaneS, 1.0, 0.0, 0.0, 0.0 );
30597117f1b4Smrg   ASSIGN_4V( texUnit->ObjectPlaneT, 0.0, 1.0, 0.0, 0.0 );
30607117f1b4Smrg   ASSIGN_4V( texUnit->ObjectPlaneR, 0.0, 0.0, 0.0, 0.0 );
30617117f1b4Smrg   ASSIGN_4V( texUnit->ObjectPlaneQ, 0.0, 0.0, 0.0, 0.0 );
30627117f1b4Smrg   ASSIGN_4V( texUnit->EyePlaneS, 1.0, 0.0, 0.0, 0.0 );
30637117f1b4Smrg   ASSIGN_4V( texUnit->EyePlaneT, 0.0, 1.0, 0.0, 0.0 );
30647117f1b4Smrg   ASSIGN_4V( texUnit->EyePlaneR, 0.0, 0.0, 0.0, 0.0 );
30657117f1b4Smrg   ASSIGN_4V( texUnit->EyePlaneQ, 0.0, 0.0, 0.0, 0.0 );
30667117f1b4Smrg
30677117f1b4Smrg   /* initialize current texture object ptrs to the shared default objects */
30687117f1b4Smrg   _mesa_reference_texobj(&texUnit->Current1D, ctx->Shared->Default1D);
30697117f1b4Smrg   _mesa_reference_texobj(&texUnit->Current2D, ctx->Shared->Default2D);
30707117f1b4Smrg   _mesa_reference_texobj(&texUnit->Current3D, ctx->Shared->Default3D);
30717117f1b4Smrg   _mesa_reference_texobj(&texUnit->CurrentCubeMap, ctx->Shared->DefaultCubeMap);
30727117f1b4Smrg   _mesa_reference_texobj(&texUnit->CurrentRect, ctx->Shared->DefaultRect);
30737117f1b4Smrg}
30747117f1b4Smrg
30757117f1b4Smrg
30767117f1b4Smrg/**
30777117f1b4Smrg * Initialize texture state for the given context.
30787117f1b4Smrg */
30797117f1b4SmrgGLboolean
30807117f1b4Smrg_mesa_init_texture(GLcontext *ctx)
30817117f1b4Smrg{
30827117f1b4Smrg   GLuint i;
30837117f1b4Smrg
30847117f1b4Smrg   assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS);
30857117f1b4Smrg   assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS);
30867117f1b4Smrg
30877117f1b4Smrg   /* Texture group */
30887117f1b4Smrg   ctx->Texture.CurrentUnit = 0;      /* multitexture */
30897117f1b4Smrg   ctx->Texture._EnabledUnits = 0;
30907117f1b4Smrg   ctx->Texture.SharedPalette = GL_FALSE;
30917117f1b4Smrg   _mesa_init_colortable(&ctx->Texture.Palette);
30927117f1b4Smrg
30937117f1b4Smrg   for (i = 0; i < MAX_TEXTURE_UNITS; i++)
30947117f1b4Smrg      init_texture_unit( ctx, i );
30957117f1b4Smrg
30967117f1b4Smrg   /* After we're done initializing the context's texture state the default
30977117f1b4Smrg    * texture objects' refcounts should be at least MAX_TEXTURE_UNITS + 1.
30987117f1b4Smrg    */
30997117f1b4Smrg   assert(ctx->Shared->Default1D->RefCount >= MAX_TEXTURE_UNITS + 1);
31007117f1b4Smrg
31017117f1b4Smrg   _mesa_TexEnvProgramCacheInit( ctx );
31027117f1b4Smrg
31037117f1b4Smrg   /* Allocate proxy textures */
31047117f1b4Smrg   if (!alloc_proxy_textures( ctx ))
31057117f1b4Smrg      return GL_FALSE;
31067117f1b4Smrg
31077117f1b4Smrg   return GL_TRUE;
31087117f1b4Smrg}
31097117f1b4Smrg
31107117f1b4Smrg
31117117f1b4Smrg/**
31127117f1b4Smrg * Free dynamically-allocated texture data attached to the given context.
31137117f1b4Smrg */
31147117f1b4Smrgvoid
31157117f1b4Smrg_mesa_free_texture_data(GLcontext *ctx)
31167117f1b4Smrg{
31177117f1b4Smrg   GLuint u;
31187117f1b4Smrg
31197117f1b4Smrg   /* unreference current textures */
31207117f1b4Smrg   for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
31217117f1b4Smrg      struct gl_texture_unit *unit = ctx->Texture.Unit + u;
31227117f1b4Smrg      _mesa_reference_texobj(&unit->Current1D, NULL);
31237117f1b4Smrg      _mesa_reference_texobj(&unit->Current2D, NULL);
31247117f1b4Smrg      _mesa_reference_texobj(&unit->Current3D, NULL);
31257117f1b4Smrg      _mesa_reference_texobj(&unit->CurrentCubeMap, NULL);
31267117f1b4Smrg      _mesa_reference_texobj(&unit->CurrentRect, NULL);
31277117f1b4Smrg   }
31287117f1b4Smrg
31297117f1b4Smrg   /* Free proxy texture objects */
31307117f1b4Smrg   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy1D );
31317117f1b4Smrg   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy2D );
31327117f1b4Smrg   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.Proxy3D );
31337117f1b4Smrg   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.ProxyCubeMap );
31347117f1b4Smrg   (ctx->Driver.DeleteTexture)(ctx,  ctx->Texture.ProxyRect );
31357117f1b4Smrg
31367117f1b4Smrg   for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++)
31377117f1b4Smrg      _mesa_free_colortable_data( &ctx->Texture.Unit[u].ColorTable );
31387117f1b4Smrg
31397117f1b4Smrg   _mesa_TexEnvProgramCacheDestroy( ctx );
31407117f1b4Smrg}
3141