texparam.c revision 3464ebd5
1c1f859d4Smrg/*
2c1f859d4Smrg * Mesa 3-D graphics library
3c1f859d4Smrg * Version:  7.5
4c1f859d4Smrg *
5c1f859d4Smrg * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6c1f859d4Smrg * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
7c1f859d4Smrg *
8c1f859d4Smrg * Permission is hereby granted, free of charge, to any person obtaining a
9c1f859d4Smrg * copy of this software and associated documentation files (the "Software"),
10c1f859d4Smrg * to deal in the Software without restriction, including without limitation
11c1f859d4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12c1f859d4Smrg * and/or sell copies of the Software, and to permit persons to whom the
13c1f859d4Smrg * Software is furnished to do so, subject to the following conditions:
14c1f859d4Smrg *
15c1f859d4Smrg * The above copyright notice and this permission notice shall be included
16c1f859d4Smrg * in all copies or substantial portions of the Software.
17c1f859d4Smrg *
18c1f859d4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19c1f859d4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20c1f859d4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21c1f859d4Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22c1f859d4Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23c1f859d4Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24c1f859d4Smrg */
25c1f859d4Smrg
26c1f859d4Smrg/**
27c1f859d4Smrg * \file texparam.c
28c1f859d4Smrg *
29c1f859d4Smrg * glTexParameter-related functions
30c1f859d4Smrg */
31c1f859d4Smrg
32c1f859d4Smrg
33c1f859d4Smrg#include "main/glheader.h"
34c1f859d4Smrg#include "main/colormac.h"
354a49301eSmrg#include "main/context.h"
363464ebd5Sriastradh#include "main/enums.h"
374a49301eSmrg#include "main/formats.h"
38c1f859d4Smrg#include "main/macros.h"
393464ebd5Sriastradh#include "main/mfeatures.h"
403464ebd5Sriastradh#include "main/mtypes.h"
413464ebd5Sriastradh#include "main/state.h"
42c1f859d4Smrg#include "main/texcompress.h"
43c1f859d4Smrg#include "main/texparam.h"
44c1f859d4Smrg#include "main/teximage.h"
454a49301eSmrg#include "main/texstate.h"
463464ebd5Sriastradh#include "main/texfetch.h"
473464ebd5Sriastradh#include "program/prog_instruction.h"
48c1f859d4Smrg
49c1f859d4Smrg
50c1f859d4Smrg/**
51c1f859d4Smrg * Check if a coordinate wrap mode is supported for the texture target.
52c1f859d4Smrg * \return GL_TRUE if legal, GL_FALSE otherwise
53c1f859d4Smrg */
54c1f859d4Smrgstatic GLboolean
553464ebd5Sriastradhvalidate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap)
56c1f859d4Smrg{
57c1f859d4Smrg   const struct gl_extensions * const e = & ctx->Extensions;
58c1f859d4Smrg
59c1f859d4Smrg   if (wrap == GL_CLAMP || wrap == GL_CLAMP_TO_EDGE ||
60c1f859d4Smrg       (wrap == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) {
61c1f859d4Smrg      /* any texture target */
62c1f859d4Smrg      return GL_TRUE;
63c1f859d4Smrg   }
64c1f859d4Smrg   else if (target != GL_TEXTURE_RECTANGLE_NV &&
65c1f859d4Smrg	    (wrap == GL_REPEAT ||
66c1f859d4Smrg	     (wrap == GL_MIRRORED_REPEAT &&
67c1f859d4Smrg	      e->ARB_texture_mirrored_repeat) ||
68c1f859d4Smrg	     (wrap == GL_MIRROR_CLAMP_EXT &&
69c1f859d4Smrg	      (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
70c1f859d4Smrg	     (wrap == GL_MIRROR_CLAMP_TO_EDGE_EXT &&
71c1f859d4Smrg	      (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
72c1f859d4Smrg	     (wrap == GL_MIRROR_CLAMP_TO_BORDER_EXT &&
73c1f859d4Smrg	      (e->EXT_texture_mirror_clamp)))) {
74c1f859d4Smrg      /* non-rectangle texture */
75c1f859d4Smrg      return GL_TRUE;
76c1f859d4Smrg   }
77c1f859d4Smrg
784a49301eSmrg   _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap );
79c1f859d4Smrg   return GL_FALSE;
80c1f859d4Smrg}
81c1f859d4Smrg
82c1f859d4Smrg
83c1f859d4Smrg/**
84c1f859d4Smrg * Get current texture object for given target.
85cdc920a0Smrg * Return NULL if any error (and record the error).
864a49301eSmrg * Note that this is different from _mesa_select_tex_object() in that proxy
874a49301eSmrg * targets are not accepted.
88cdc920a0Smrg * Only the glGetTexLevelParameter() functions accept proxy targets.
89c1f859d4Smrg */
90c1f859d4Smrgstatic struct gl_texture_object *
913464ebd5Sriastradhget_texobj(struct gl_context *ctx, GLenum target, GLboolean get)
92c1f859d4Smrg{
93c1f859d4Smrg   struct gl_texture_unit *texUnit;
94c1f859d4Smrg
95cdc920a0Smrg   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
96cdc920a0Smrg      _mesa_error(ctx, GL_INVALID_OPERATION,
97cdc920a0Smrg                  "gl%sTexParameter(current unit)", get ? "Get" : "");
98c1f859d4Smrg      return NULL;
99c1f859d4Smrg   }
100c1f859d4Smrg
1014a49301eSmrg   texUnit = _mesa_get_current_tex_unit(ctx);
102c1f859d4Smrg
103c1f859d4Smrg   switch (target) {
104c1f859d4Smrg   case GL_TEXTURE_1D:
105c1f859d4Smrg      return texUnit->CurrentTex[TEXTURE_1D_INDEX];
106c1f859d4Smrg   case GL_TEXTURE_2D:
107c1f859d4Smrg      return texUnit->CurrentTex[TEXTURE_2D_INDEX];
108c1f859d4Smrg   case GL_TEXTURE_3D:
109c1f859d4Smrg      return texUnit->CurrentTex[TEXTURE_3D_INDEX];
110c1f859d4Smrg   case GL_TEXTURE_CUBE_MAP:
111c1f859d4Smrg      if (ctx->Extensions.ARB_texture_cube_map) {
112c1f859d4Smrg         return texUnit->CurrentTex[TEXTURE_CUBE_INDEX];
113c1f859d4Smrg      }
114c1f859d4Smrg      break;
115c1f859d4Smrg   case GL_TEXTURE_RECTANGLE_NV:
116c1f859d4Smrg      if (ctx->Extensions.NV_texture_rectangle) {
117c1f859d4Smrg         return texUnit->CurrentTex[TEXTURE_RECT_INDEX];
118c1f859d4Smrg      }
119c1f859d4Smrg      break;
120c1f859d4Smrg   case GL_TEXTURE_1D_ARRAY_EXT:
1213464ebd5Sriastradh      if (ctx->Extensions.MESA_texture_array ||
1223464ebd5Sriastradh          ctx->Extensions.EXT_texture_array) {
123c1f859d4Smrg         return texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX];
124c1f859d4Smrg      }
125c1f859d4Smrg      break;
126c1f859d4Smrg   case GL_TEXTURE_2D_ARRAY_EXT:
1273464ebd5Sriastradh      if (ctx->Extensions.MESA_texture_array ||
1283464ebd5Sriastradh          ctx->Extensions.EXT_texture_array) {
129c1f859d4Smrg         return texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX];
130c1f859d4Smrg      }
131c1f859d4Smrg      break;
132c1f859d4Smrg   default:
133c1f859d4Smrg      ;
134c1f859d4Smrg   }
135c1f859d4Smrg
136cdc920a0Smrg   _mesa_error(ctx, GL_INVALID_ENUM,
137cdc920a0Smrg                  "gl%sTexParameter(target)", get ? "Get" : "");
138c1f859d4Smrg   return NULL;
139c1f859d4Smrg}
140c1f859d4Smrg
141c1f859d4Smrg
1424a49301eSmrg/**
1434a49301eSmrg * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE.
1444a49301eSmrg * \return -1 if error.
1454a49301eSmrg */
1464a49301eSmrgstatic GLint
1474a49301eSmrgcomp_to_swizzle(GLenum comp)
1484a49301eSmrg{
1494a49301eSmrg   switch (comp) {
1504a49301eSmrg   case GL_RED:
1514a49301eSmrg      return SWIZZLE_X;
1524a49301eSmrg   case GL_GREEN:
1534a49301eSmrg      return SWIZZLE_Y;
1544a49301eSmrg   case GL_BLUE:
1554a49301eSmrg      return SWIZZLE_Z;
1564a49301eSmrg   case GL_ALPHA:
1574a49301eSmrg      return SWIZZLE_W;
1584a49301eSmrg   case GL_ZERO:
1594a49301eSmrg      return SWIZZLE_ZERO;
1604a49301eSmrg   case GL_ONE:
1614a49301eSmrg      return SWIZZLE_ONE;
1624a49301eSmrg   default:
1634a49301eSmrg      return -1;
1644a49301eSmrg   }
1654a49301eSmrg}
1664a49301eSmrg
1674a49301eSmrg
1684a49301eSmrgstatic void
1694a49301eSmrgset_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz)
1704a49301eSmrg{
1714a49301eSmrg   ASSERT(comp < 4);
1724a49301eSmrg   ASSERT(swz <= SWIZZLE_NIL);
1734a49301eSmrg   {
1744a49301eSmrg      GLuint mask = 0x7 << (3 * comp);
1754a49301eSmrg      GLuint s = (*swizzle & ~mask) | (swz << (3 * comp));
1764a49301eSmrg      *swizzle = s;
1774a49301eSmrg   }
1784a49301eSmrg}
1794a49301eSmrg
1804a49301eSmrg
181c1f859d4Smrg/**
1823464ebd5Sriastradh * This is called just prior to changing any texture object state which
1833464ebd5Sriastradh * will not effect texture completeness.
1843464ebd5Sriastradh */
1853464ebd5Sriastradhstatic INLINE void
1863464ebd5Sriastradhflush(struct gl_context *ctx)
1873464ebd5Sriastradh{
1883464ebd5Sriastradh   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1893464ebd5Sriastradh}
1903464ebd5Sriastradh
1913464ebd5Sriastradh
1923464ebd5Sriastradh/**
1933464ebd5Sriastradh * This is called just prior to changing any texture object state which
1943464ebd5Sriastradh * can effect texture completeness (texture base level, max level,
1953464ebd5Sriastradh * minification filter).
196c1f859d4Smrg * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE
197c1f859d4Smrg * state flag and then mark the texture object as 'incomplete' so that any
198c1f859d4Smrg * per-texture derived state gets recomputed.
199c1f859d4Smrg */
200c1f859d4Smrgstatic INLINE void
2013464ebd5Sriastradhincomplete(struct gl_context *ctx, struct gl_texture_object *texObj)
202c1f859d4Smrg{
203c1f859d4Smrg   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
204c1f859d4Smrg   texObj->_Complete = GL_FALSE;
205c1f859d4Smrg}
206c1f859d4Smrg
207c1f859d4Smrg
208c1f859d4Smrg/**
209c1f859d4Smrg * Set an integer-valued texture parameter
210c1f859d4Smrg * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
211c1f859d4Smrg */
212c1f859d4Smrgstatic GLboolean
2133464ebd5Sriastradhset_tex_parameteri(struct gl_context *ctx,
214c1f859d4Smrg                   struct gl_texture_object *texObj,
215c1f859d4Smrg                   GLenum pname, const GLint *params)
216c1f859d4Smrg{
217c1f859d4Smrg   switch (pname) {
218c1f859d4Smrg   case GL_TEXTURE_MIN_FILTER:
2193464ebd5Sriastradh      if (texObj->Sampler.MinFilter == params[0])
220c1f859d4Smrg         return GL_FALSE;
221c1f859d4Smrg      switch (params[0]) {
222c1f859d4Smrg      case GL_NEAREST:
223c1f859d4Smrg      case GL_LINEAR:
2243464ebd5Sriastradh         incomplete(ctx, texObj);
2253464ebd5Sriastradh         texObj->Sampler.MinFilter = params[0];
226c1f859d4Smrg         return GL_TRUE;
227c1f859d4Smrg      case GL_NEAREST_MIPMAP_NEAREST:
228c1f859d4Smrg      case GL_LINEAR_MIPMAP_NEAREST:
229c1f859d4Smrg      case GL_NEAREST_MIPMAP_LINEAR:
230c1f859d4Smrg      case GL_LINEAR_MIPMAP_LINEAR:
231c1f859d4Smrg         if (texObj->Target != GL_TEXTURE_RECTANGLE_NV) {
2323464ebd5Sriastradh            incomplete(ctx, texObj);
2333464ebd5Sriastradh            texObj->Sampler.MinFilter = params[0];
234c1f859d4Smrg            return GL_TRUE;
235c1f859d4Smrg         }
236c1f859d4Smrg         /* fall-through */
237c1f859d4Smrg      default:
2383464ebd5Sriastradh         goto invalid_param;
239c1f859d4Smrg      }
240c1f859d4Smrg      return GL_FALSE;
241c1f859d4Smrg
242c1f859d4Smrg   case GL_TEXTURE_MAG_FILTER:
2433464ebd5Sriastradh      if (texObj->Sampler.MagFilter == params[0])
244c1f859d4Smrg         return GL_FALSE;
245c1f859d4Smrg      switch (params[0]) {
246c1f859d4Smrg      case GL_NEAREST:
247c1f859d4Smrg      case GL_LINEAR:
2483464ebd5Sriastradh         flush(ctx); /* does not effect completeness */
2493464ebd5Sriastradh         texObj->Sampler.MagFilter = params[0];
250c1f859d4Smrg         return GL_TRUE;
251c1f859d4Smrg      default:
2523464ebd5Sriastradh         goto invalid_param;
253c1f859d4Smrg      }
254c1f859d4Smrg      return GL_FALSE;
255c1f859d4Smrg
256c1f859d4Smrg   case GL_TEXTURE_WRAP_S:
2573464ebd5Sriastradh      if (texObj->Sampler.WrapS == params[0])
258c1f859d4Smrg         return GL_FALSE;
259c1f859d4Smrg      if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
2603464ebd5Sriastradh         flush(ctx);
2613464ebd5Sriastradh         texObj->Sampler.WrapS = params[0];
262c1f859d4Smrg         return GL_TRUE;
263c1f859d4Smrg      }
264c1f859d4Smrg      return GL_FALSE;
265c1f859d4Smrg
266c1f859d4Smrg   case GL_TEXTURE_WRAP_T:
2673464ebd5Sriastradh      if (texObj->Sampler.WrapT == params[0])
268c1f859d4Smrg         return GL_FALSE;
269c1f859d4Smrg      if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
2703464ebd5Sriastradh         flush(ctx);
2713464ebd5Sriastradh         texObj->Sampler.WrapT = params[0];
272c1f859d4Smrg         return GL_TRUE;
273c1f859d4Smrg      }
274c1f859d4Smrg      return GL_FALSE;
275c1f859d4Smrg
276c1f859d4Smrg   case GL_TEXTURE_WRAP_R:
2773464ebd5Sriastradh      if (texObj->Sampler.WrapR == params[0])
278c1f859d4Smrg         return GL_FALSE;
279c1f859d4Smrg      if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
2803464ebd5Sriastradh         flush(ctx);
2813464ebd5Sriastradh         texObj->Sampler.WrapR = params[0];
282c1f859d4Smrg         return GL_TRUE;
283c1f859d4Smrg      }
284c1f859d4Smrg      return GL_FALSE;
285c1f859d4Smrg
286c1f859d4Smrg   case GL_TEXTURE_BASE_LEVEL:
287c1f859d4Smrg      if (texObj->BaseLevel == params[0])
288c1f859d4Smrg         return GL_FALSE;
289c1f859d4Smrg      if (params[0] < 0 ||
290c1f859d4Smrg          (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) {
2914a49301eSmrg         _mesa_error(ctx, GL_INVALID_VALUE,
2924a49301eSmrg                     "glTexParameter(param=%d)", params[0]);
293c1f859d4Smrg         return GL_FALSE;
294c1f859d4Smrg      }
2953464ebd5Sriastradh      incomplete(ctx, texObj);
296c1f859d4Smrg      texObj->BaseLevel = params[0];
297c1f859d4Smrg      return GL_TRUE;
298c1f859d4Smrg
299c1f859d4Smrg   case GL_TEXTURE_MAX_LEVEL:
300c1f859d4Smrg      if (texObj->MaxLevel == params[0])
301c1f859d4Smrg         return GL_FALSE;
302c1f859d4Smrg      if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) {
3034a49301eSmrg         _mesa_error(ctx, GL_INVALID_OPERATION,
3044a49301eSmrg                     "glTexParameter(param=%d)", params[0]);
305c1f859d4Smrg         return GL_FALSE;
306c1f859d4Smrg      }
3073464ebd5Sriastradh      incomplete(ctx, texObj);
308c1f859d4Smrg      texObj->MaxLevel = params[0];
309c1f859d4Smrg      return GL_TRUE;
310c1f859d4Smrg
311c1f859d4Smrg   case GL_GENERATE_MIPMAP_SGIS:
3123464ebd5Sriastradh      if (texObj->GenerateMipmap != params[0]) {
3133464ebd5Sriastradh         /* no flush() */
3143464ebd5Sriastradh	 texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
3153464ebd5Sriastradh	 return GL_TRUE;
316c1f859d4Smrg      }
317c1f859d4Smrg      return GL_FALSE;
318c1f859d4Smrg
319c1f859d4Smrg   case GL_TEXTURE_COMPARE_MODE_ARB:
3203464ebd5Sriastradh      if (ctx->Extensions.ARB_shadow) {
3213464ebd5Sriastradh         if (texObj->Sampler.CompareMode == params[0])
3223464ebd5Sriastradh            return GL_FALSE;
3233464ebd5Sriastradh         if (params[0] == GL_NONE ||
3243464ebd5Sriastradh             params[0] == GL_COMPARE_R_TO_TEXTURE_ARB) {
3253464ebd5Sriastradh            flush(ctx);
3263464ebd5Sriastradh            texObj->Sampler.CompareMode = params[0];
327c1f859d4Smrg            return GL_TRUE;
328c1f859d4Smrg         }
3293464ebd5Sriastradh         goto invalid_param;
330c1f859d4Smrg      }
3313464ebd5Sriastradh      goto invalid_pname;
332c1f859d4Smrg
333c1f859d4Smrg   case GL_TEXTURE_COMPARE_FUNC_ARB:
334c1f859d4Smrg      if (ctx->Extensions.ARB_shadow) {
3353464ebd5Sriastradh         if (texObj->Sampler.CompareFunc == params[0])
336c1f859d4Smrg            return GL_FALSE;
337c1f859d4Smrg         switch (params[0]) {
338c1f859d4Smrg         case GL_LEQUAL:
339c1f859d4Smrg         case GL_GEQUAL:
3403464ebd5Sriastradh            flush(ctx);
3413464ebd5Sriastradh            texObj->Sampler.CompareFunc = params[0];
342c1f859d4Smrg            return GL_TRUE;
343c1f859d4Smrg         case GL_EQUAL:
344c1f859d4Smrg         case GL_NOTEQUAL:
345c1f859d4Smrg         case GL_LESS:
346c1f859d4Smrg         case GL_GREATER:
347c1f859d4Smrg         case GL_ALWAYS:
348c1f859d4Smrg         case GL_NEVER:
349c1f859d4Smrg            if (ctx->Extensions.EXT_shadow_funcs) {
3503464ebd5Sriastradh               flush(ctx);
3513464ebd5Sriastradh               texObj->Sampler.CompareFunc = params[0];
352c1f859d4Smrg               return GL_TRUE;
353c1f859d4Smrg            }
354c1f859d4Smrg            /* fall-through */
355c1f859d4Smrg         default:
3563464ebd5Sriastradh            goto invalid_param;
357c1f859d4Smrg         }
358c1f859d4Smrg      }
3593464ebd5Sriastradh      goto invalid_pname;
360c1f859d4Smrg
361c1f859d4Smrg   case GL_DEPTH_TEXTURE_MODE_ARB:
3623464ebd5Sriastradh      if (ctx->Extensions.ARB_depth_texture) {
3633464ebd5Sriastradh         if (texObj->Sampler.DepthMode == params[0])
3643464ebd5Sriastradh            return GL_FALSE;
3653464ebd5Sriastradh         if (params[0] == GL_LUMINANCE ||
3663464ebd5Sriastradh             params[0] == GL_INTENSITY ||
3673464ebd5Sriastradh             params[0] == GL_ALPHA ||
3683464ebd5Sriastradh             (ctx->Extensions.ARB_texture_rg && params[0] == GL_RED)) {
3693464ebd5Sriastradh            flush(ctx);
3703464ebd5Sriastradh            texObj->Sampler.DepthMode = params[0];
371c1f859d4Smrg            return GL_TRUE;
372c1f859d4Smrg         }
3733464ebd5Sriastradh         goto invalid_param;
374c1f859d4Smrg      }
3753464ebd5Sriastradh      goto invalid_pname;
376c1f859d4Smrg
3773464ebd5Sriastradh#if FEATURE_OES_draw_texture
378c1f859d4Smrg   case GL_TEXTURE_CROP_RECT_OES:
379c1f859d4Smrg      texObj->CropRect[0] = params[0];
380c1f859d4Smrg      texObj->CropRect[1] = params[1];
381c1f859d4Smrg      texObj->CropRect[2] = params[2];
382c1f859d4Smrg      texObj->CropRect[3] = params[3];
383c1f859d4Smrg      return GL_TRUE;
384c1f859d4Smrg#endif
385c1f859d4Smrg
3864a49301eSmrg   case GL_TEXTURE_SWIZZLE_R_EXT:
3874a49301eSmrg   case GL_TEXTURE_SWIZZLE_G_EXT:
3884a49301eSmrg   case GL_TEXTURE_SWIZZLE_B_EXT:
3894a49301eSmrg   case GL_TEXTURE_SWIZZLE_A_EXT:
3904a49301eSmrg      if (ctx->Extensions.EXT_texture_swizzle) {
3914a49301eSmrg         const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
3924a49301eSmrg         const GLint swz = comp_to_swizzle(params[0]);
3934a49301eSmrg         if (swz < 0) {
3944a49301eSmrg            _mesa_error(ctx, GL_INVALID_OPERATION,
3954a49301eSmrg                        "glTexParameter(swizzle 0x%x)", params[0]);
3964a49301eSmrg            return GL_FALSE;
3974a49301eSmrg         }
3984a49301eSmrg         ASSERT(comp < 4);
3994a49301eSmrg         if (swz >= 0) {
4003464ebd5Sriastradh            flush(ctx);
4014a49301eSmrg            texObj->Swizzle[comp] = params[0];
4024a49301eSmrg            set_swizzle_component(&texObj->_Swizzle, comp, swz);
4034a49301eSmrg            return GL_TRUE;
4044a49301eSmrg         }
4054a49301eSmrg      }
4063464ebd5Sriastradh      goto invalid_pname;
4074a49301eSmrg
4084a49301eSmrg   case GL_TEXTURE_SWIZZLE_RGBA_EXT:
4094a49301eSmrg      if (ctx->Extensions.EXT_texture_swizzle) {
4104a49301eSmrg         GLuint comp;
4113464ebd5Sriastradh         flush(ctx);
4124a49301eSmrg         for (comp = 0; comp < 4; comp++) {
4134a49301eSmrg            const GLint swz = comp_to_swizzle(params[comp]);
4144a49301eSmrg            if (swz >= 0) {
4154a49301eSmrg               texObj->Swizzle[comp] = params[comp];
4164a49301eSmrg               set_swizzle_component(&texObj->_Swizzle, comp, swz);
4174a49301eSmrg            }
4184a49301eSmrg            else {
4194a49301eSmrg               _mesa_error(ctx, GL_INVALID_OPERATION,
4204a49301eSmrg                           "glTexParameter(swizzle 0x%x)", params[comp]);
4214a49301eSmrg               return GL_FALSE;
4224a49301eSmrg            }
4234a49301eSmrg         }
4244a49301eSmrg         return GL_TRUE;
4254a49301eSmrg      }
4263464ebd5Sriastradh      goto invalid_pname;
4273464ebd5Sriastradh
4283464ebd5Sriastradh   case GL_TEXTURE_SRGB_DECODE_EXT:
4293464ebd5Sriastradh      if (ctx->Extensions.EXT_texture_sRGB_decode) {
4303464ebd5Sriastradh	 GLenum decode = params[0];
4313464ebd5Sriastradh	 if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) {
4323464ebd5Sriastradh	    if (texObj->Sampler.sRGBDecode != decode) {
4333464ebd5Sriastradh	       flush(ctx);
4343464ebd5Sriastradh	       texObj->Sampler.sRGBDecode = decode;
4353464ebd5Sriastradh	       _mesa_update_fetch_functions(texObj);
4363464ebd5Sriastradh	    }
4373464ebd5Sriastradh	    return GL_TRUE;
4383464ebd5Sriastradh	 }
4393464ebd5Sriastradh      }
4403464ebd5Sriastradh      goto invalid_pname;
4413464ebd5Sriastradh
4423464ebd5Sriastradh   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
4433464ebd5Sriastradh      if (ctx->Extensions.AMD_seamless_cubemap_per_texture) {
4443464ebd5Sriastradh         GLenum param = params[0];
4453464ebd5Sriastradh         if (param != GL_TRUE && param != GL_FALSE) {
4463464ebd5Sriastradh            goto invalid_param;
4473464ebd5Sriastradh         }
4483464ebd5Sriastradh         if (param != texObj->Sampler.CubeMapSeamless) {
4493464ebd5Sriastradh            flush(ctx);
4503464ebd5Sriastradh            texObj->Sampler.CubeMapSeamless = param;
4513464ebd5Sriastradh         }
4523464ebd5Sriastradh         return GL_TRUE;
4533464ebd5Sriastradh      }
4543464ebd5Sriastradh      goto invalid_pname;
4554a49301eSmrg
456c1f859d4Smrg   default:
4573464ebd5Sriastradh      goto invalid_pname;
458c1f859d4Smrg   }
4593464ebd5Sriastradh
4603464ebd5Sriastradhinvalid_pname:
4613464ebd5Sriastradh   _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)",
4623464ebd5Sriastradh               _mesa_lookup_enum_by_nr(pname));
4633464ebd5Sriastradh   return GL_FALSE;
4643464ebd5Sriastradh
4653464ebd5Sriastradhinvalid_param:
4663464ebd5Sriastradh   _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param=%s)",
4673464ebd5Sriastradh               _mesa_lookup_enum_by_nr(params[0]));
468c1f859d4Smrg   return GL_FALSE;
469c1f859d4Smrg}
470c1f859d4Smrg
471c1f859d4Smrg
472c1f859d4Smrg/**
473c1f859d4Smrg * Set a float-valued texture parameter
474c1f859d4Smrg * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
475c1f859d4Smrg */
476c1f859d4Smrgstatic GLboolean
4773464ebd5Sriastradhset_tex_parameterf(struct gl_context *ctx,
478c1f859d4Smrg                   struct gl_texture_object *texObj,
479c1f859d4Smrg                   GLenum pname, const GLfloat *params)
480c1f859d4Smrg{
481c1f859d4Smrg   switch (pname) {
482c1f859d4Smrg   case GL_TEXTURE_MIN_LOD:
4833464ebd5Sriastradh      if (texObj->Sampler.MinLod == params[0])
484c1f859d4Smrg         return GL_FALSE;
4853464ebd5Sriastradh      flush(ctx);
4863464ebd5Sriastradh      texObj->Sampler.MinLod = params[0];
487c1f859d4Smrg      return GL_TRUE;
488c1f859d4Smrg
489c1f859d4Smrg   case GL_TEXTURE_MAX_LOD:
4903464ebd5Sriastradh      if (texObj->Sampler.MaxLod == params[0])
491c1f859d4Smrg         return GL_FALSE;
4923464ebd5Sriastradh      flush(ctx);
4933464ebd5Sriastradh      texObj->Sampler.MaxLod = params[0];
494c1f859d4Smrg      return GL_TRUE;
495c1f859d4Smrg
496c1f859d4Smrg   case GL_TEXTURE_PRIORITY:
4973464ebd5Sriastradh      flush(ctx);
498c1f859d4Smrg      texObj->Priority = CLAMP(params[0], 0.0F, 1.0F);
499c1f859d4Smrg      return GL_TRUE;
500c1f859d4Smrg
501c1f859d4Smrg   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
502c1f859d4Smrg      if (ctx->Extensions.EXT_texture_filter_anisotropic) {
5033464ebd5Sriastradh         if (texObj->Sampler.MaxAnisotropy == params[0])
504c1f859d4Smrg            return GL_FALSE;
505c1f859d4Smrg         if (params[0] < 1.0) {
506c1f859d4Smrg            _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
507c1f859d4Smrg            return GL_FALSE;
508c1f859d4Smrg         }
5093464ebd5Sriastradh         flush(ctx);
510c1f859d4Smrg         /* clamp to max, that's what NVIDIA does */
5113464ebd5Sriastradh         texObj->Sampler.MaxAnisotropy = MIN2(params[0],
512c1f859d4Smrg                                      ctx->Const.MaxTextureMaxAnisotropy);
513c1f859d4Smrg         return GL_TRUE;
514c1f859d4Smrg      }
515c1f859d4Smrg      else {
5164a49301eSmrg         static GLuint count = 0;
5174a49301eSmrg         if (count++ < 10)
5184a49301eSmrg            _mesa_error(ctx, GL_INVALID_ENUM,
5194a49301eSmrg                        "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)");
520c1f859d4Smrg      }
521c1f859d4Smrg      return GL_FALSE;
522c1f859d4Smrg
523c1f859d4Smrg   case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
5244a49301eSmrg      if (ctx->Extensions.ARB_shadow_ambient) {
5253464ebd5Sriastradh         if (texObj->Sampler.CompareFailValue != params[0]) {
5263464ebd5Sriastradh            flush(ctx);
5273464ebd5Sriastradh            texObj->Sampler.CompareFailValue = CLAMP(params[0], 0.0F, 1.0F);
528c1f859d4Smrg            return GL_TRUE;
529c1f859d4Smrg         }
530c1f859d4Smrg      }
531c1f859d4Smrg      else {
532c1f859d4Smrg         _mesa_error(ctx, GL_INVALID_ENUM,
5334a49301eSmrg                    "glTexParameter(pname=GL_TEXTURE_COMPARE_FAIL_VALUE_ARB)");
534c1f859d4Smrg      }
535c1f859d4Smrg      return GL_FALSE;
536c1f859d4Smrg
537c1f859d4Smrg   case GL_TEXTURE_LOD_BIAS:
538c1f859d4Smrg      /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias */
539c1f859d4Smrg      if (ctx->Extensions.EXT_texture_lod_bias) {
5403464ebd5Sriastradh         if (texObj->Sampler.LodBias != params[0]) {
5413464ebd5Sriastradh            flush(ctx);
5423464ebd5Sriastradh            texObj->Sampler.LodBias = params[0];
543c1f859d4Smrg            return GL_TRUE;
544c1f859d4Smrg         }
545c1f859d4Smrg         return GL_FALSE;
546c1f859d4Smrg      }
547c1f859d4Smrg      break;
548c1f859d4Smrg
549c1f859d4Smrg   case GL_TEXTURE_BORDER_COLOR:
5503464ebd5Sriastradh      flush(ctx);
5513464ebd5Sriastradh      /* ARB_texture_float disables clamping */
5523464ebd5Sriastradh      if (ctx->Extensions.ARB_texture_float) {
5533464ebd5Sriastradh         texObj->Sampler.BorderColor.f[RCOMP] = params[0];
5543464ebd5Sriastradh         texObj->Sampler.BorderColor.f[GCOMP] = params[1];
5553464ebd5Sriastradh         texObj->Sampler.BorderColor.f[BCOMP] = params[2];
5563464ebd5Sriastradh         texObj->Sampler.BorderColor.f[ACOMP] = params[3];
5573464ebd5Sriastradh      } else {
5583464ebd5Sriastradh         texObj->Sampler.BorderColor.f[RCOMP] = CLAMP(params[0], 0.0F, 1.0F);
5593464ebd5Sriastradh         texObj->Sampler.BorderColor.f[GCOMP] = CLAMP(params[1], 0.0F, 1.0F);
5603464ebd5Sriastradh         texObj->Sampler.BorderColor.f[BCOMP] = CLAMP(params[2], 0.0F, 1.0F);
5613464ebd5Sriastradh         texObj->Sampler.BorderColor.f[ACOMP] = CLAMP(params[3], 0.0F, 1.0F);
5623464ebd5Sriastradh      }
563c1f859d4Smrg      return GL_TRUE;
564c1f859d4Smrg
565c1f859d4Smrg   default:
566c1f859d4Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname);
567c1f859d4Smrg   }
568c1f859d4Smrg   return GL_FALSE;
569c1f859d4Smrg}
570c1f859d4Smrg
571c1f859d4Smrg
572c1f859d4Smrgvoid GLAPIENTRY
573c1f859d4Smrg_mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
574c1f859d4Smrg{
575c1f859d4Smrg   GLboolean need_update;
576c1f859d4Smrg   struct gl_texture_object *texObj;
577c1f859d4Smrg   GET_CURRENT_CONTEXT(ctx);
578c1f859d4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
579c1f859d4Smrg
580cdc920a0Smrg   texObj = get_texobj(ctx, target, GL_FALSE);
581c1f859d4Smrg   if (!texObj)
582c1f859d4Smrg      return;
583c1f859d4Smrg
584c1f859d4Smrg   switch (pname) {
585c1f859d4Smrg   case GL_TEXTURE_MIN_FILTER:
586c1f859d4Smrg   case GL_TEXTURE_MAG_FILTER:
587c1f859d4Smrg   case GL_TEXTURE_WRAP_S:
588c1f859d4Smrg   case GL_TEXTURE_WRAP_T:
589c1f859d4Smrg   case GL_TEXTURE_WRAP_R:
590c1f859d4Smrg   case GL_TEXTURE_BASE_LEVEL:
591c1f859d4Smrg   case GL_TEXTURE_MAX_LEVEL:
592c1f859d4Smrg   case GL_GENERATE_MIPMAP_SGIS:
593c1f859d4Smrg   case GL_TEXTURE_COMPARE_MODE_ARB:
594c1f859d4Smrg   case GL_TEXTURE_COMPARE_FUNC_ARB:
595c1f859d4Smrg   case GL_DEPTH_TEXTURE_MODE_ARB:
5963464ebd5Sriastradh   case GL_TEXTURE_SRGB_DECODE_EXT:
5973464ebd5Sriastradh   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
598c1f859d4Smrg      {
599c1f859d4Smrg         /* convert float param to int */
6004a49301eSmrg         GLint p[4];
6014a49301eSmrg         p[0] = (GLint) param;
6024a49301eSmrg         p[1] = p[2] = p[3] = 0;
6034a49301eSmrg         need_update = set_tex_parameteri(ctx, texObj, pname, p);
604c1f859d4Smrg      }
605c1f859d4Smrg      break;
606c1f859d4Smrg   default:
6074a49301eSmrg      {
6084a49301eSmrg         /* this will generate an error if pname is illegal */
6094a49301eSmrg         GLfloat p[4];
6104a49301eSmrg         p[0] = param;
6114a49301eSmrg         p[1] = p[2] = p[3] = 0.0F;
6124a49301eSmrg         need_update = set_tex_parameterf(ctx, texObj, pname, p);
6134a49301eSmrg      }
614c1f859d4Smrg   }
615c1f859d4Smrg
616c1f859d4Smrg   if (ctx->Driver.TexParameter && need_update) {
617c1f859d4Smrg      ctx->Driver.TexParameter(ctx, target, texObj, pname, &param);
618c1f859d4Smrg   }
619c1f859d4Smrg}
620c1f859d4Smrg
621c1f859d4Smrg
622c1f859d4Smrgvoid GLAPIENTRY
623c1f859d4Smrg_mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
624c1f859d4Smrg{
625c1f859d4Smrg   GLboolean need_update;
626c1f859d4Smrg   struct gl_texture_object *texObj;
627c1f859d4Smrg   GET_CURRENT_CONTEXT(ctx);
628c1f859d4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
629c1f859d4Smrg
630cdc920a0Smrg   texObj = get_texobj(ctx, target, GL_FALSE);
631c1f859d4Smrg   if (!texObj)
632c1f859d4Smrg      return;
633c1f859d4Smrg
634c1f859d4Smrg   switch (pname) {
635c1f859d4Smrg   case GL_TEXTURE_MIN_FILTER:
636c1f859d4Smrg   case GL_TEXTURE_MAG_FILTER:
637c1f859d4Smrg   case GL_TEXTURE_WRAP_S:
638c1f859d4Smrg   case GL_TEXTURE_WRAP_T:
639c1f859d4Smrg   case GL_TEXTURE_WRAP_R:
640c1f859d4Smrg   case GL_TEXTURE_BASE_LEVEL:
641c1f859d4Smrg   case GL_TEXTURE_MAX_LEVEL:
642c1f859d4Smrg   case GL_GENERATE_MIPMAP_SGIS:
643c1f859d4Smrg   case GL_TEXTURE_COMPARE_MODE_ARB:
644c1f859d4Smrg   case GL_TEXTURE_COMPARE_FUNC_ARB:
645c1f859d4Smrg   case GL_DEPTH_TEXTURE_MODE_ARB:
6463464ebd5Sriastradh   case GL_TEXTURE_SRGB_DECODE_EXT:
6473464ebd5Sriastradh   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
648c1f859d4Smrg      {
649c1f859d4Smrg         /* convert float param to int */
6504a49301eSmrg         GLint p[4];
6514a49301eSmrg         p[0] = (GLint) params[0];
6524a49301eSmrg         p[1] = p[2] = p[3] = 0;
6534a49301eSmrg         need_update = set_tex_parameteri(ctx, texObj, pname, p);
654c1f859d4Smrg      }
655c1f859d4Smrg      break;
656c1f859d4Smrg
6573464ebd5Sriastradh#if FEATURE_OES_draw_texture
658c1f859d4Smrg   case GL_TEXTURE_CROP_RECT_OES:
659c1f859d4Smrg      {
660c1f859d4Smrg         /* convert float params to int */
661c1f859d4Smrg         GLint iparams[4];
662c1f859d4Smrg         iparams[0] = (GLint) params[0];
663c1f859d4Smrg         iparams[1] = (GLint) params[1];
664c1f859d4Smrg         iparams[2] = (GLint) params[2];
665c1f859d4Smrg         iparams[3] = (GLint) params[3];
6664a49301eSmrg         need_update = set_tex_parameteri(ctx, texObj, pname, iparams);
667c1f859d4Smrg      }
668c1f859d4Smrg      break;
669c1f859d4Smrg#endif
670c1f859d4Smrg
671c1f859d4Smrg   default:
672c1f859d4Smrg      /* this will generate an error if pname is illegal */
673c1f859d4Smrg      need_update = set_tex_parameterf(ctx, texObj, pname, params);
674c1f859d4Smrg   }
675c1f859d4Smrg
676c1f859d4Smrg   if (ctx->Driver.TexParameter && need_update) {
677c1f859d4Smrg      ctx->Driver.TexParameter(ctx, target, texObj, pname, params);
678c1f859d4Smrg   }
679c1f859d4Smrg}
680c1f859d4Smrg
681c1f859d4Smrg
682c1f859d4Smrgvoid GLAPIENTRY
683c1f859d4Smrg_mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
684c1f859d4Smrg{
685c1f859d4Smrg   GLboolean need_update;
686c1f859d4Smrg   struct gl_texture_object *texObj;
687c1f859d4Smrg   GET_CURRENT_CONTEXT(ctx);
688c1f859d4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
689c1f859d4Smrg
690cdc920a0Smrg   texObj = get_texobj(ctx, target, GL_FALSE);
691c1f859d4Smrg   if (!texObj)
692c1f859d4Smrg      return;
693c1f859d4Smrg
694c1f859d4Smrg   switch (pname) {
695c1f859d4Smrg   case GL_TEXTURE_MIN_LOD:
696c1f859d4Smrg   case GL_TEXTURE_MAX_LOD:
697c1f859d4Smrg   case GL_TEXTURE_PRIORITY:
698c1f859d4Smrg   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
699c1f859d4Smrg   case GL_TEXTURE_LOD_BIAS:
7004a49301eSmrg   case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
701c1f859d4Smrg      {
7024a49301eSmrg         GLfloat fparam[4];
7034a49301eSmrg         fparam[0] = (GLfloat) param;
7044a49301eSmrg         fparam[1] = fparam[2] = fparam[3] = 0.0F;
705c1f859d4Smrg         /* convert int param to float */
7064a49301eSmrg         need_update = set_tex_parameterf(ctx, texObj, pname, fparam);
707c1f859d4Smrg      }
708c1f859d4Smrg      break;
709c1f859d4Smrg   default:
710c1f859d4Smrg      /* this will generate an error if pname is illegal */
7114a49301eSmrg      {
7124a49301eSmrg         GLint iparam[4];
7134a49301eSmrg         iparam[0] = param;
7144a49301eSmrg         iparam[1] = iparam[2] = iparam[3] = 0;
7154a49301eSmrg         need_update = set_tex_parameteri(ctx, texObj, pname, iparam);
7164a49301eSmrg      }
717c1f859d4Smrg   }
718c1f859d4Smrg
719c1f859d4Smrg   if (ctx->Driver.TexParameter && need_update) {
720c1f859d4Smrg      GLfloat fparam = (GLfloat) param;
721c1f859d4Smrg      ctx->Driver.TexParameter(ctx, target, texObj, pname, &fparam);
722c1f859d4Smrg   }
723c1f859d4Smrg}
724c1f859d4Smrg
725c1f859d4Smrg
726c1f859d4Smrgvoid GLAPIENTRY
727c1f859d4Smrg_mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
728c1f859d4Smrg{
729c1f859d4Smrg   GLboolean need_update;
730c1f859d4Smrg   struct gl_texture_object *texObj;
731c1f859d4Smrg   GET_CURRENT_CONTEXT(ctx);
732c1f859d4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
733c1f859d4Smrg
734cdc920a0Smrg   texObj = get_texobj(ctx, target, GL_FALSE);
735c1f859d4Smrg   if (!texObj)
736c1f859d4Smrg      return;
737c1f859d4Smrg
738c1f859d4Smrg   switch (pname) {
739c1f859d4Smrg   case GL_TEXTURE_BORDER_COLOR:
740c1f859d4Smrg      {
741c1f859d4Smrg         /* convert int params to float */
742c1f859d4Smrg         GLfloat fparams[4];
743c1f859d4Smrg         fparams[0] = INT_TO_FLOAT(params[0]);
744c1f859d4Smrg         fparams[1] = INT_TO_FLOAT(params[1]);
745c1f859d4Smrg         fparams[2] = INT_TO_FLOAT(params[2]);
746c1f859d4Smrg         fparams[3] = INT_TO_FLOAT(params[3]);
747c1f859d4Smrg         need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
748c1f859d4Smrg      }
749c1f859d4Smrg      break;
750c1f859d4Smrg   case GL_TEXTURE_MIN_LOD:
751c1f859d4Smrg   case GL_TEXTURE_MAX_LOD:
752c1f859d4Smrg   case GL_TEXTURE_PRIORITY:
753c1f859d4Smrg   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
754c1f859d4Smrg   case GL_TEXTURE_LOD_BIAS:
7554a49301eSmrg   case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
756c1f859d4Smrg      {
757c1f859d4Smrg         /* convert int param to float */
7584a49301eSmrg         GLfloat fparams[4];
7594a49301eSmrg         fparams[0] = (GLfloat) params[0];
7604a49301eSmrg         fparams[1] = fparams[2] = fparams[3] = 0.0F;
7614a49301eSmrg         need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
762c1f859d4Smrg      }
763c1f859d4Smrg      break;
764c1f859d4Smrg   default:
765c1f859d4Smrg      /* this will generate an error if pname is illegal */
766c1f859d4Smrg      need_update = set_tex_parameteri(ctx, texObj, pname, params);
767c1f859d4Smrg   }
768c1f859d4Smrg
769c1f859d4Smrg   if (ctx->Driver.TexParameter && need_update) {
770c1f859d4Smrg      GLfloat fparams[4];
771c1f859d4Smrg      fparams[0] = INT_TO_FLOAT(params[0]);
772c1f859d4Smrg      if (pname == GL_TEXTURE_BORDER_COLOR ||
773c1f859d4Smrg          pname == GL_TEXTURE_CROP_RECT_OES) {
774c1f859d4Smrg         fparams[1] = INT_TO_FLOAT(params[1]);
775c1f859d4Smrg         fparams[2] = INT_TO_FLOAT(params[2]);
776c1f859d4Smrg         fparams[3] = INT_TO_FLOAT(params[3]);
777c1f859d4Smrg      }
778c1f859d4Smrg      ctx->Driver.TexParameter(ctx, target, texObj, pname, fparams);
779c1f859d4Smrg   }
780c1f859d4Smrg}
781c1f859d4Smrg
782c1f859d4Smrg
783cdc920a0Smrg/**
784cdc920a0Smrg * Set tex parameter to integer value(s).  Primarily intended to set
785cdc920a0Smrg * integer-valued texture border color (for integer-valued textures).
786cdc920a0Smrg * New in GL 3.0.
787cdc920a0Smrg */
788cdc920a0Smrgvoid GLAPIENTRY
789cdc920a0Smrg_mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params)
790cdc920a0Smrg{
791cdc920a0Smrg   struct gl_texture_object *texObj;
792cdc920a0Smrg   GET_CURRENT_CONTEXT(ctx);
793cdc920a0Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
794cdc920a0Smrg
795cdc920a0Smrg   texObj = get_texobj(ctx, target, GL_FALSE);
796cdc920a0Smrg   if (!texObj)
797cdc920a0Smrg      return;
798cdc920a0Smrg
799cdc920a0Smrg   switch (pname) {
800cdc920a0Smrg   case GL_TEXTURE_BORDER_COLOR:
801cdc920a0Smrg      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
802cdc920a0Smrg      /* set the integer-valued border color */
8033464ebd5Sriastradh      COPY_4V(texObj->Sampler.BorderColor.i, params);
804cdc920a0Smrg      break;
805cdc920a0Smrg   default:
806cdc920a0Smrg      _mesa_TexParameteriv(target, pname, params);
807cdc920a0Smrg      break;
808cdc920a0Smrg   }
809cdc920a0Smrg   /* XXX no driver hook for TexParameterIiv() yet */
810cdc920a0Smrg}
811cdc920a0Smrg
812cdc920a0Smrg
813cdc920a0Smrg/**
814cdc920a0Smrg * Set tex parameter to unsigned integer value(s).  Primarily intended to set
815cdc920a0Smrg * uint-valued texture border color (for integer-valued textures).
816cdc920a0Smrg * New in GL 3.0
817cdc920a0Smrg */
818cdc920a0Smrgvoid GLAPIENTRY
819cdc920a0Smrg_mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
820cdc920a0Smrg{
821cdc920a0Smrg   struct gl_texture_object *texObj;
822cdc920a0Smrg   GET_CURRENT_CONTEXT(ctx);
823cdc920a0Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
824cdc920a0Smrg
825cdc920a0Smrg   texObj = get_texobj(ctx, target, GL_FALSE);
826cdc920a0Smrg   if (!texObj)
827cdc920a0Smrg      return;
828cdc920a0Smrg
829cdc920a0Smrg   switch (pname) {
830cdc920a0Smrg   case GL_TEXTURE_BORDER_COLOR:
831cdc920a0Smrg      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
832cdc920a0Smrg      /* set the unsigned integer-valued border color */
8333464ebd5Sriastradh      COPY_4V(texObj->Sampler.BorderColor.ui, params);
834cdc920a0Smrg      break;
835cdc920a0Smrg   default:
836cdc920a0Smrg      _mesa_TexParameteriv(target, pname, (const GLint *) params);
837cdc920a0Smrg      break;
838cdc920a0Smrg   }
839cdc920a0Smrg   /* XXX no driver hook for TexParameterIuiv() yet */
840cdc920a0Smrg}
841cdc920a0Smrg
842cdc920a0Smrg
843cdc920a0Smrg
844cdc920a0Smrg
845c1f859d4Smrgvoid GLAPIENTRY
846c1f859d4Smrg_mesa_GetTexLevelParameterfv( GLenum target, GLint level,
847c1f859d4Smrg                              GLenum pname, GLfloat *params )
848c1f859d4Smrg{
849c1f859d4Smrg   GLint iparam;
850c1f859d4Smrg   _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
851c1f859d4Smrg   *params = (GLfloat) iparam;
852c1f859d4Smrg}
853c1f859d4Smrg
854c1f859d4Smrg
855c1f859d4Smrgvoid GLAPIENTRY
856c1f859d4Smrg_mesa_GetTexLevelParameteriv( GLenum target, GLint level,
857c1f859d4Smrg                              GLenum pname, GLint *params )
858c1f859d4Smrg{
859c1f859d4Smrg   const struct gl_texture_unit *texUnit;
860c1f859d4Smrg   struct gl_texture_object *texObj;
861c1f859d4Smrg   const struct gl_texture_image *img = NULL;
862c1f859d4Smrg   GLint maxLevels;
8634a49301eSmrg   gl_format texFormat;
864c1f859d4Smrg   GET_CURRENT_CONTEXT(ctx);
865c1f859d4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
866c1f859d4Smrg
867cdc920a0Smrg   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
868c1f859d4Smrg      _mesa_error(ctx, GL_INVALID_OPERATION,
869c1f859d4Smrg                  "glGetTexLevelParameteriv(current unit)");
870c1f859d4Smrg      return;
871c1f859d4Smrg   }
872c1f859d4Smrg
8734a49301eSmrg   texUnit = _mesa_get_current_tex_unit(ctx);
874c1f859d4Smrg
875c1f859d4Smrg   /* this will catch bad target values */
876c1f859d4Smrg   maxLevels = _mesa_max_texture_levels(ctx, target);
877c1f859d4Smrg   if (maxLevels == 0) {
8784a49301eSmrg      _mesa_error(ctx, GL_INVALID_ENUM,
8794a49301eSmrg                  "glGetTexLevelParameter[if]v(target=0x%x)", target);
880c1f859d4Smrg      return;
881c1f859d4Smrg   }
882c1f859d4Smrg
883c1f859d4Smrg   if (level < 0 || level >= maxLevels) {
884c1f859d4Smrg      _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
885c1f859d4Smrg      return;
886c1f859d4Smrg   }
887c1f859d4Smrg
888c1f859d4Smrg   texObj = _mesa_select_tex_object(ctx, texUnit, target);
889c1f859d4Smrg
890c1f859d4Smrg   img = _mesa_select_tex_image(ctx, texObj, target, level);
891c1f859d4Smrg   if (!img || !img->TexFormat) {
892c1f859d4Smrg      /* undefined texture image */
893c1f859d4Smrg      if (pname == GL_TEXTURE_COMPONENTS)
894c1f859d4Smrg         *params = 1;
895c1f859d4Smrg      else
896c1f859d4Smrg         *params = 0;
8973464ebd5Sriastradh      return;
898c1f859d4Smrg   }
899c1f859d4Smrg
9004a49301eSmrg   texFormat = img->TexFormat;
9014a49301eSmrg
902c1f859d4Smrg   switch (pname) {
903c1f859d4Smrg      case GL_TEXTURE_WIDTH:
904c1f859d4Smrg         *params = img->Width;
905c1f859d4Smrg         break;
906c1f859d4Smrg      case GL_TEXTURE_HEIGHT:
907c1f859d4Smrg         *params = img->Height;
908c1f859d4Smrg         break;
909c1f859d4Smrg      case GL_TEXTURE_DEPTH:
910c1f859d4Smrg         *params = img->Depth;
911c1f859d4Smrg         break;
912c1f859d4Smrg      case GL_TEXTURE_INTERNAL_FORMAT:
9133464ebd5Sriastradh         if (_mesa_is_format_compressed(texFormat)) {
9144a49301eSmrg            /* need to return the actual compressed format */
9153464ebd5Sriastradh            *params = _mesa_compressed_format_to_glenum(ctx, texFormat);
9164a49301eSmrg         }
9174a49301eSmrg         else {
9183464ebd5Sriastradh	    /* If the true internal format is not compressed but the user
9193464ebd5Sriastradh	     * requested a generic compressed format, we have to return the
9203464ebd5Sriastradh	     * generic base format that matches.
9213464ebd5Sriastradh	     *
9223464ebd5Sriastradh	     * From page 119 (page 129 of the PDF) of the OpenGL 1.3 spec:
9233464ebd5Sriastradh	     *
9243464ebd5Sriastradh	     *     "If no specific compressed format is available,
9253464ebd5Sriastradh	     *     internalformat is instead replaced by the corresponding base
9263464ebd5Sriastradh	     *     internal format."
9273464ebd5Sriastradh	     *
9283464ebd5Sriastradh	     * Otherwise just return the user's requested internal format
9293464ebd5Sriastradh	     */
9303464ebd5Sriastradh	    const GLenum f =
9313464ebd5Sriastradh	       _mesa_gl_compressed_format_base_format(img->InternalFormat);
9323464ebd5Sriastradh
9333464ebd5Sriastradh	    *params = (f != 0) ? f : img->InternalFormat;
9343464ebd5Sriastradh	 }
935c1f859d4Smrg         break;
936c1f859d4Smrg      case GL_TEXTURE_BORDER:
937c1f859d4Smrg         *params = img->Border;
938c1f859d4Smrg         break;
939c1f859d4Smrg      case GL_TEXTURE_RED_SIZE:
9403464ebd5Sriastradh         if (img->_BaseFormat == GL_RED) {
9413464ebd5Sriastradh            *params = _mesa_get_format_bits(texFormat, pname);
9423464ebd5Sriastradh	    break;
9433464ebd5Sriastradh	 }
9443464ebd5Sriastradh	 /* FALLTHROUGH */
945c1f859d4Smrg      case GL_TEXTURE_GREEN_SIZE:
9463464ebd5Sriastradh         if (img->_BaseFormat == GL_RG) {
9473464ebd5Sriastradh            *params = _mesa_get_format_bits(texFormat, pname);
9483464ebd5Sriastradh	    break;
9493464ebd5Sriastradh	 }
9503464ebd5Sriastradh	 /* FALLTHROUGH */
951c1f859d4Smrg      case GL_TEXTURE_BLUE_SIZE:
952c1f859d4Smrg         if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA)
9534a49301eSmrg            *params = _mesa_get_format_bits(texFormat, pname);
954c1f859d4Smrg         else
955c1f859d4Smrg            *params = 0;
956c1f859d4Smrg         break;
957c1f859d4Smrg      case GL_TEXTURE_ALPHA_SIZE:
958c1f859d4Smrg         if (img->_BaseFormat == GL_ALPHA ||
959c1f859d4Smrg             img->_BaseFormat == GL_LUMINANCE_ALPHA ||
960c1f859d4Smrg             img->_BaseFormat == GL_RGBA)
9614a49301eSmrg            *params = _mesa_get_format_bits(texFormat, pname);
962c1f859d4Smrg         else
963c1f859d4Smrg            *params = 0;
964c1f859d4Smrg         break;
965c1f859d4Smrg      case GL_TEXTURE_INTENSITY_SIZE:
966c1f859d4Smrg         if (img->_BaseFormat != GL_INTENSITY)
967c1f859d4Smrg            *params = 0;
9684a49301eSmrg         else {
9694a49301eSmrg            *params = _mesa_get_format_bits(texFormat, pname);
9704a49301eSmrg            if (*params == 0) {
9714a49301eSmrg               /* intensity probably stored as rgb texture */
9724a49301eSmrg               *params = MIN2(_mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE),
9734a49301eSmrg                              _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE));
9744a49301eSmrg            }
9754a49301eSmrg         }
976c1f859d4Smrg         break;
977c1f859d4Smrg      case GL_TEXTURE_LUMINANCE_SIZE:
978c1f859d4Smrg         if (img->_BaseFormat != GL_LUMINANCE &&
979c1f859d4Smrg             img->_BaseFormat != GL_LUMINANCE_ALPHA)
980c1f859d4Smrg            *params = 0;
9814a49301eSmrg         else {
9824a49301eSmrg            *params = _mesa_get_format_bits(texFormat, pname);
9834a49301eSmrg            if (*params == 0) {
9844a49301eSmrg               /* luminance probably stored as rgb texture */
9854a49301eSmrg               *params = MIN2(_mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE),
9864a49301eSmrg                              _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE));
9874a49301eSmrg            }
9884a49301eSmrg         }
989c1f859d4Smrg         break;
990c1f859d4Smrg      case GL_TEXTURE_INDEX_SIZE_EXT:
991c1f859d4Smrg         if (img->_BaseFormat == GL_COLOR_INDEX)
9924a49301eSmrg            *params = _mesa_get_format_bits(texFormat, pname);
993c1f859d4Smrg         else
994c1f859d4Smrg            *params = 0;
995c1f859d4Smrg         break;
996c1f859d4Smrg      case GL_TEXTURE_DEPTH_SIZE_ARB:
997c1f859d4Smrg         if (ctx->Extensions.ARB_depth_texture)
9984a49301eSmrg            *params = _mesa_get_format_bits(texFormat, pname);
999c1f859d4Smrg         else
10003464ebd5Sriastradh            goto invalid_pname;
1001c1f859d4Smrg         break;
1002c1f859d4Smrg      case GL_TEXTURE_STENCIL_SIZE_EXT:
10034a49301eSmrg         if (ctx->Extensions.EXT_packed_depth_stencil ||
10044a49301eSmrg             ctx->Extensions.ARB_framebuffer_object) {
10054a49301eSmrg            *params = _mesa_get_format_bits(texFormat, pname);
1006c1f859d4Smrg         }
1007c1f859d4Smrg         else {
10083464ebd5Sriastradh            goto invalid_pname;
10093464ebd5Sriastradh         }
10103464ebd5Sriastradh         break;
10113464ebd5Sriastradh      case GL_TEXTURE_SHARED_SIZE:
10123464ebd5Sriastradh         if (ctx->VersionMajor >= 3 ||
10133464ebd5Sriastradh             ctx->Extensions.EXT_texture_shared_exponent) {
10143464ebd5Sriastradh            *params = texFormat == MESA_FORMAT_RGB9_E5_FLOAT ? 5 : 0;
10153464ebd5Sriastradh         }
10163464ebd5Sriastradh         else {
10173464ebd5Sriastradh            goto invalid_pname;
1018c1f859d4Smrg         }
1019c1f859d4Smrg         break;
1020c1f859d4Smrg
1021c1f859d4Smrg      /* GL_ARB_texture_compression */
1022c1f859d4Smrg      case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
10233464ebd5Sriastradh	 if (_mesa_is_format_compressed(texFormat) &&
10243464ebd5Sriastradh             !_mesa_is_proxy_texture(target)) {
10254a49301eSmrg            *params = _mesa_format_image_size(texFormat, img->Width,
10264a49301eSmrg                                              img->Height, img->Depth);
10274a49301eSmrg	 }
10284a49301eSmrg	 else {
10294a49301eSmrg	    _mesa_error(ctx, GL_INVALID_OPERATION,
10304a49301eSmrg			"glGetTexLevelParameter[if]v(pname)");
10314a49301eSmrg	 }
1032c1f859d4Smrg         break;
1033c1f859d4Smrg      case GL_TEXTURE_COMPRESSED:
10343464ebd5Sriastradh         *params = (GLint) _mesa_is_format_compressed(texFormat);
1035c1f859d4Smrg         break;
1036c1f859d4Smrg
1037c1f859d4Smrg      /* GL_ARB_texture_float */
1038c1f859d4Smrg      case GL_TEXTURE_RED_TYPE_ARB:
1039c1f859d4Smrg         if (ctx->Extensions.ARB_texture_float) {
10404a49301eSmrg            *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE) ?
10414a49301eSmrg               _mesa_get_format_datatype(texFormat) : GL_NONE;
1042c1f859d4Smrg         }
1043c1f859d4Smrg         else {
10443464ebd5Sriastradh            goto invalid_pname;
1045c1f859d4Smrg         }
1046c1f859d4Smrg         break;
1047c1f859d4Smrg      case GL_TEXTURE_GREEN_TYPE_ARB:
1048c1f859d4Smrg         if (ctx->Extensions.ARB_texture_float) {
10494a49301eSmrg            *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE) ?
10504a49301eSmrg               _mesa_get_format_datatype(texFormat) : GL_NONE;
1051c1f859d4Smrg         }
1052c1f859d4Smrg         else {
10533464ebd5Sriastradh            goto invalid_pname;
1054c1f859d4Smrg         }
1055c1f859d4Smrg         break;
1056c1f859d4Smrg      case GL_TEXTURE_BLUE_TYPE_ARB:
1057c1f859d4Smrg         if (ctx->Extensions.ARB_texture_float) {
10584a49301eSmrg            *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_BLUE_SIZE) ?
10594a49301eSmrg               _mesa_get_format_datatype(texFormat) : GL_NONE;
1060c1f859d4Smrg         }
1061c1f859d4Smrg         else {
10623464ebd5Sriastradh            goto invalid_pname;
1063c1f859d4Smrg         }
1064c1f859d4Smrg         break;
1065c1f859d4Smrg      case GL_TEXTURE_ALPHA_TYPE_ARB:
1066c1f859d4Smrg         if (ctx->Extensions.ARB_texture_float) {
10674a49301eSmrg            *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_ALPHA_SIZE) ?
10684a49301eSmrg               _mesa_get_format_datatype(texFormat) : GL_NONE;
1069c1f859d4Smrg         }
1070c1f859d4Smrg         else {
10713464ebd5Sriastradh            goto invalid_pname;
1072c1f859d4Smrg         }
1073c1f859d4Smrg         break;
1074c1f859d4Smrg      case GL_TEXTURE_LUMINANCE_TYPE_ARB:
1075c1f859d4Smrg         if (ctx->Extensions.ARB_texture_float) {
10764a49301eSmrg            *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_LUMINANCE_SIZE) ?
10774a49301eSmrg               _mesa_get_format_datatype(texFormat) : GL_NONE;
1078c1f859d4Smrg         }
1079c1f859d4Smrg         else {
10803464ebd5Sriastradh            goto invalid_pname;
1081c1f859d4Smrg         }
1082c1f859d4Smrg         break;
1083c1f859d4Smrg      case GL_TEXTURE_INTENSITY_TYPE_ARB:
1084c1f859d4Smrg         if (ctx->Extensions.ARB_texture_float) {
10854a49301eSmrg            *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_INTENSITY_SIZE) ?
10864a49301eSmrg               _mesa_get_format_datatype(texFormat) : GL_NONE;
1087c1f859d4Smrg         }
1088c1f859d4Smrg         else {
10893464ebd5Sriastradh            goto invalid_pname;
1090c1f859d4Smrg         }
1091c1f859d4Smrg         break;
1092c1f859d4Smrg      case GL_TEXTURE_DEPTH_TYPE_ARB:
1093c1f859d4Smrg         if (ctx->Extensions.ARB_texture_float) {
10944a49301eSmrg            *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_DEPTH_SIZE) ?
10954a49301eSmrg               _mesa_get_format_datatype(texFormat) : GL_NONE;
1096c1f859d4Smrg         }
1097c1f859d4Smrg         else {
10983464ebd5Sriastradh            goto invalid_pname;
1099c1f859d4Smrg         }
1100c1f859d4Smrg         break;
1101c1f859d4Smrg
1102c1f859d4Smrg      default:
11033464ebd5Sriastradh         goto invalid_pname;
1104c1f859d4Smrg   }
1105c1f859d4Smrg
11063464ebd5Sriastradh   /* no error if we get here */
11073464ebd5Sriastradh   return;
11083464ebd5Sriastradh
11093464ebd5Sriastradhinvalid_pname:
11103464ebd5Sriastradh   _mesa_error(ctx, GL_INVALID_ENUM,
11113464ebd5Sriastradh               "glGetTexLevelParameter[if]v(pname=%s)",
11123464ebd5Sriastradh               _mesa_lookup_enum_by_nr(pname));
1113c1f859d4Smrg}
1114c1f859d4Smrg
1115c1f859d4Smrg
1116c1f859d4Smrg
1117c1f859d4Smrgvoid GLAPIENTRY
1118c1f859d4Smrg_mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
1119c1f859d4Smrg{
1120c1f859d4Smrg   struct gl_texture_object *obj;
1121c1f859d4Smrg   GLboolean error = GL_FALSE;
1122c1f859d4Smrg   GET_CURRENT_CONTEXT(ctx);
1123c1f859d4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
1124c1f859d4Smrg
1125cdc920a0Smrg   obj = get_texobj(ctx, target, GL_TRUE);
1126cdc920a0Smrg   if (!obj)
1127c1f859d4Smrg      return;
1128c1f859d4Smrg
1129c1f859d4Smrg   _mesa_lock_texture(ctx, obj);
1130c1f859d4Smrg   switch (pname) {
1131c1f859d4Smrg      case GL_TEXTURE_MAG_FILTER:
11323464ebd5Sriastradh	 *params = ENUM_TO_FLOAT(obj->Sampler.MagFilter);
1133c1f859d4Smrg	 break;
1134c1f859d4Smrg      case GL_TEXTURE_MIN_FILTER:
11353464ebd5Sriastradh         *params = ENUM_TO_FLOAT(obj->Sampler.MinFilter);
1136c1f859d4Smrg         break;
1137c1f859d4Smrg      case GL_TEXTURE_WRAP_S:
11383464ebd5Sriastradh         *params = ENUM_TO_FLOAT(obj->Sampler.WrapS);
1139c1f859d4Smrg         break;
1140c1f859d4Smrg      case GL_TEXTURE_WRAP_T:
11413464ebd5Sriastradh         *params = ENUM_TO_FLOAT(obj->Sampler.WrapT);
1142c1f859d4Smrg         break;
1143c1f859d4Smrg      case GL_TEXTURE_WRAP_R:
11443464ebd5Sriastradh         *params = ENUM_TO_FLOAT(obj->Sampler.WrapR);
1145c1f859d4Smrg         break;
1146c1f859d4Smrg      case GL_TEXTURE_BORDER_COLOR:
11473464ebd5Sriastradh         if(ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
11483464ebd5Sriastradh            _mesa_update_state_locked(ctx);
11493464ebd5Sriastradh         if(ctx->Color._ClampFragmentColor)
11503464ebd5Sriastradh         {
11513464ebd5Sriastradh            params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
11523464ebd5Sriastradh            params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
11533464ebd5Sriastradh            params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
11543464ebd5Sriastradh            params[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
11553464ebd5Sriastradh         }
11563464ebd5Sriastradh         else
11573464ebd5Sriastradh         {
11583464ebd5Sriastradh            params[0] = obj->Sampler.BorderColor.f[0];
11593464ebd5Sriastradh            params[1] = obj->Sampler.BorderColor.f[1];
11603464ebd5Sriastradh            params[2] = obj->Sampler.BorderColor.f[2];
11613464ebd5Sriastradh            params[3] = obj->Sampler.BorderColor.f[3];
11623464ebd5Sriastradh         }
1163c1f859d4Smrg         break;
1164c1f859d4Smrg      case GL_TEXTURE_RESIDENT:
1165c1f859d4Smrg         {
1166c1f859d4Smrg            GLboolean resident;
1167c1f859d4Smrg            if (ctx->Driver.IsTextureResident)
1168c1f859d4Smrg               resident = ctx->Driver.IsTextureResident(ctx, obj);
1169c1f859d4Smrg            else
1170c1f859d4Smrg               resident = GL_TRUE;
1171c1f859d4Smrg            *params = ENUM_TO_FLOAT(resident);
1172c1f859d4Smrg         }
1173c1f859d4Smrg         break;
1174c1f859d4Smrg      case GL_TEXTURE_PRIORITY:
1175c1f859d4Smrg         *params = obj->Priority;
1176c1f859d4Smrg         break;
1177c1f859d4Smrg      case GL_TEXTURE_MIN_LOD:
11783464ebd5Sriastradh         *params = obj->Sampler.MinLod;
1179c1f859d4Smrg         break;
1180c1f859d4Smrg      case GL_TEXTURE_MAX_LOD:
11813464ebd5Sriastradh         *params = obj->Sampler.MaxLod;
1182c1f859d4Smrg         break;
1183c1f859d4Smrg      case GL_TEXTURE_BASE_LEVEL:
1184c1f859d4Smrg         *params = (GLfloat) obj->BaseLevel;
1185c1f859d4Smrg         break;
1186c1f859d4Smrg      case GL_TEXTURE_MAX_LEVEL:
1187c1f859d4Smrg         *params = (GLfloat) obj->MaxLevel;
1188c1f859d4Smrg         break;
1189c1f859d4Smrg      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1190c1f859d4Smrg         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
11913464ebd5Sriastradh            *params = obj->Sampler.MaxAnisotropy;
1192c1f859d4Smrg         }
1193c1f859d4Smrg	 else
11944a49301eSmrg	    error = GL_TRUE;
1195c1f859d4Smrg         break;
11964a49301eSmrg      case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
11974a49301eSmrg         if (ctx->Extensions.ARB_shadow_ambient) {
11983464ebd5Sriastradh            *params = obj->Sampler.CompareFailValue;
1199c1f859d4Smrg         }
1200c1f859d4Smrg	 else
12014a49301eSmrg	    error = GL_TRUE;
1202c1f859d4Smrg         break;
1203c1f859d4Smrg      case GL_GENERATE_MIPMAP_SGIS:
12043464ebd5Sriastradh	 *params = (GLfloat) obj->GenerateMipmap;
1205c1f859d4Smrg         break;
1206c1f859d4Smrg      case GL_TEXTURE_COMPARE_MODE_ARB:
1207c1f859d4Smrg         if (ctx->Extensions.ARB_shadow) {
12083464ebd5Sriastradh            *params = (GLfloat) obj->Sampler.CompareMode;
1209c1f859d4Smrg         }
1210c1f859d4Smrg	 else
12114a49301eSmrg	    error = GL_TRUE;
1212c1f859d4Smrg         break;
1213c1f859d4Smrg      case GL_TEXTURE_COMPARE_FUNC_ARB:
1214c1f859d4Smrg         if (ctx->Extensions.ARB_shadow) {
12153464ebd5Sriastradh            *params = (GLfloat) obj->Sampler.CompareFunc;
1216c1f859d4Smrg         }
1217c1f859d4Smrg	 else
12184a49301eSmrg	    error = GL_TRUE;
1219c1f859d4Smrg         break;
1220c1f859d4Smrg      case GL_DEPTH_TEXTURE_MODE_ARB:
1221c1f859d4Smrg         if (ctx->Extensions.ARB_depth_texture) {
12223464ebd5Sriastradh            *params = (GLfloat) obj->Sampler.DepthMode;
1223c1f859d4Smrg         }
1224c1f859d4Smrg	 else
12254a49301eSmrg	    error = GL_TRUE;
1226c1f859d4Smrg         break;
1227c1f859d4Smrg      case GL_TEXTURE_LOD_BIAS:
1228c1f859d4Smrg         if (ctx->Extensions.EXT_texture_lod_bias) {
12293464ebd5Sriastradh            *params = obj->Sampler.LodBias;
1230c1f859d4Smrg         }
1231c1f859d4Smrg	 else
12324a49301eSmrg	    error = GL_TRUE;
1233c1f859d4Smrg         break;
12343464ebd5Sriastradh#if FEATURE_OES_draw_texture
1235c1f859d4Smrg      case GL_TEXTURE_CROP_RECT_OES:
1236c1f859d4Smrg         params[0] = obj->CropRect[0];
1237c1f859d4Smrg         params[1] = obj->CropRect[1];
1238c1f859d4Smrg         params[2] = obj->CropRect[2];
1239c1f859d4Smrg         params[3] = obj->CropRect[3];
1240c1f859d4Smrg         break;
1241c1f859d4Smrg#endif
12424a49301eSmrg
12434a49301eSmrg      case GL_TEXTURE_SWIZZLE_R_EXT:
12444a49301eSmrg      case GL_TEXTURE_SWIZZLE_G_EXT:
12454a49301eSmrg      case GL_TEXTURE_SWIZZLE_B_EXT:
12464a49301eSmrg      case GL_TEXTURE_SWIZZLE_A_EXT:
12474a49301eSmrg         if (ctx->Extensions.EXT_texture_swizzle) {
12484a49301eSmrg            GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
12494a49301eSmrg            *params = (GLfloat) obj->Swizzle[comp];
12504a49301eSmrg         }
12514a49301eSmrg         else {
12524a49301eSmrg            error = GL_TRUE;
12534a49301eSmrg         }
12544a49301eSmrg         break;
12554a49301eSmrg
12564a49301eSmrg      case GL_TEXTURE_SWIZZLE_RGBA_EXT:
12574a49301eSmrg         if (ctx->Extensions.EXT_texture_swizzle) {
12584a49301eSmrg            GLuint comp;
12594a49301eSmrg            for (comp = 0; comp < 4; comp++) {
12604a49301eSmrg               params[comp] = (GLfloat) obj->Swizzle[comp];
12614a49301eSmrg            }
12624a49301eSmrg         }
12634a49301eSmrg         else {
12644a49301eSmrg            error = GL_TRUE;
12654a49301eSmrg         }
12664a49301eSmrg         break;
12674a49301eSmrg
12683464ebd5Sriastradh      case GL_TEXTURE_CUBE_MAP_SEAMLESS:
12693464ebd5Sriastradh         if (ctx->Extensions.AMD_seamless_cubemap_per_texture) {
12703464ebd5Sriastradh            *params = (GLfloat) obj->Sampler.CubeMapSeamless;
12713464ebd5Sriastradh         }
12723464ebd5Sriastradh         else {
12733464ebd5Sriastradh            error = GL_TRUE;
12743464ebd5Sriastradh         }
12753464ebd5Sriastradh         break;
12763464ebd5Sriastradh
1277c1f859d4Smrg      default:
12784a49301eSmrg	 error = GL_TRUE;
1279c1f859d4Smrg	 break;
1280c1f859d4Smrg   }
12814a49301eSmrg
1282c1f859d4Smrg   if (error)
1283c1f859d4Smrg      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)",
1284c1f859d4Smrg		  pname);
1285c1f859d4Smrg
1286c1f859d4Smrg   _mesa_unlock_texture(ctx, obj);
1287c1f859d4Smrg}
1288c1f859d4Smrg
1289c1f859d4Smrg
1290c1f859d4Smrgvoid GLAPIENTRY
1291c1f859d4Smrg_mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
1292c1f859d4Smrg{
1293c1f859d4Smrg   struct gl_texture_object *obj;
12944a49301eSmrg   GLboolean error = GL_FALSE;
1295c1f859d4Smrg   GET_CURRENT_CONTEXT(ctx);
1296c1f859d4Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
1297c1f859d4Smrg
1298cdc920a0Smrg    obj = get_texobj(ctx, target, GL_TRUE);
1299cdc920a0Smrg    if (!obj)
1300cdc920a0Smrg       return;
1301c1f859d4Smrg
13024a49301eSmrg   _mesa_lock_texture(ctx, obj);
1303c1f859d4Smrg   switch (pname) {
1304c1f859d4Smrg      case GL_TEXTURE_MAG_FILTER:
13053464ebd5Sriastradh         *params = (GLint) obj->Sampler.MagFilter;
13064a49301eSmrg         break;;
1307c1f859d4Smrg      case GL_TEXTURE_MIN_FILTER:
13083464ebd5Sriastradh         *params = (GLint) obj->Sampler.MinFilter;
13094a49301eSmrg         break;;
1310c1f859d4Smrg      case GL_TEXTURE_WRAP_S:
13113464ebd5Sriastradh         *params = (GLint) obj->Sampler.WrapS;
13124a49301eSmrg         break;;
1313c1f859d4Smrg      case GL_TEXTURE_WRAP_T:
13143464ebd5Sriastradh         *params = (GLint) obj->Sampler.WrapT;
13154a49301eSmrg         break;;
1316c1f859d4Smrg      case GL_TEXTURE_WRAP_R:
13173464ebd5Sriastradh         *params = (GLint) obj->Sampler.WrapR;
13184a49301eSmrg         break;;
1319c1f859d4Smrg      case GL_TEXTURE_BORDER_COLOR:
1320c1f859d4Smrg         {
1321c1f859d4Smrg            GLfloat b[4];
13223464ebd5Sriastradh            b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
13233464ebd5Sriastradh            b[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
13243464ebd5Sriastradh            b[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
13253464ebd5Sriastradh            b[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
1326c1f859d4Smrg            params[0] = FLOAT_TO_INT(b[0]);
1327c1f859d4Smrg            params[1] = FLOAT_TO_INT(b[1]);
1328c1f859d4Smrg            params[2] = FLOAT_TO_INT(b[2]);
1329c1f859d4Smrg            params[3] = FLOAT_TO_INT(b[3]);
1330c1f859d4Smrg         }
13314a49301eSmrg         break;;
1332c1f859d4Smrg      case GL_TEXTURE_RESIDENT:
1333c1f859d4Smrg         {
1334c1f859d4Smrg            GLboolean resident;
1335c1f859d4Smrg            if (ctx->Driver.IsTextureResident)
1336c1f859d4Smrg               resident = ctx->Driver.IsTextureResident(ctx, obj);
1337c1f859d4Smrg            else
1338c1f859d4Smrg               resident = GL_TRUE;
1339c1f859d4Smrg            *params = (GLint) resident;
1340c1f859d4Smrg         }
13414a49301eSmrg         break;;
1342c1f859d4Smrg      case GL_TEXTURE_PRIORITY:
1343c1f859d4Smrg         *params = FLOAT_TO_INT(obj->Priority);
13444a49301eSmrg         break;;
1345c1f859d4Smrg      case GL_TEXTURE_MIN_LOD:
13463464ebd5Sriastradh         *params = (GLint) obj->Sampler.MinLod;
13474a49301eSmrg         break;;
1348c1f859d4Smrg      case GL_TEXTURE_MAX_LOD:
13493464ebd5Sriastradh         *params = (GLint) obj->Sampler.MaxLod;
13504a49301eSmrg         break;;
1351c1f859d4Smrg      case GL_TEXTURE_BASE_LEVEL:
1352c1f859d4Smrg         *params = obj->BaseLevel;
13534a49301eSmrg         break;;
1354c1f859d4Smrg      case GL_TEXTURE_MAX_LEVEL:
1355c1f859d4Smrg         *params = obj->MaxLevel;
13564a49301eSmrg         break;;
1357c1f859d4Smrg      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1358c1f859d4Smrg         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
13593464ebd5Sriastradh            *params = (GLint) obj->Sampler.MaxAnisotropy;
1360c1f859d4Smrg         }
13614a49301eSmrg         else {
13624a49301eSmrg            error = GL_TRUE;
1363c1f859d4Smrg         }
1364c1f859d4Smrg         break;
13654a49301eSmrg      case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
13664a49301eSmrg         if (ctx->Extensions.ARB_shadow_ambient) {
13673464ebd5Sriastradh            *params = (GLint) FLOAT_TO_INT(obj->Sampler.CompareFailValue);
1368c1f859d4Smrg         }
13694a49301eSmrg         else {
13704a49301eSmrg            error = GL_TRUE;
1371c1f859d4Smrg         }
1372c1f859d4Smrg         break;
1373c1f859d4Smrg      case GL_GENERATE_MIPMAP_SGIS:
13743464ebd5Sriastradh	 *params = (GLint) obj->GenerateMipmap;
1375c1f859d4Smrg         break;
1376c1f859d4Smrg      case GL_TEXTURE_COMPARE_MODE_ARB:
1377c1f859d4Smrg         if (ctx->Extensions.ARB_shadow) {
13783464ebd5Sriastradh            *params = (GLint) obj->Sampler.CompareMode;
13794a49301eSmrg         }
13804a49301eSmrg         else {
13814a49301eSmrg            error = GL_TRUE;
1382c1f859d4Smrg         }
1383c1f859d4Smrg         break;
1384c1f859d4Smrg      case GL_TEXTURE_COMPARE_FUNC_ARB:
1385c1f859d4Smrg         if (ctx->Extensions.ARB_shadow) {
13863464ebd5Sriastradh            *params = (GLint) obj->Sampler.CompareFunc;
13874a49301eSmrg         }
13884a49301eSmrg         else {
13894a49301eSmrg            error = GL_TRUE;
1390c1f859d4Smrg         }
1391c1f859d4Smrg         break;
1392c1f859d4Smrg      case GL_DEPTH_TEXTURE_MODE_ARB:
1393c1f859d4Smrg         if (ctx->Extensions.ARB_depth_texture) {
13943464ebd5Sriastradh            *params = (GLint) obj->Sampler.DepthMode;
13954a49301eSmrg         }
13964a49301eSmrg         else {
13974a49301eSmrg            error = GL_TRUE;
1398c1f859d4Smrg         }
1399c1f859d4Smrg         break;
1400c1f859d4Smrg      case GL_TEXTURE_LOD_BIAS:
1401c1f859d4Smrg         if (ctx->Extensions.EXT_texture_lod_bias) {
14023464ebd5Sriastradh            *params = (GLint) obj->Sampler.LodBias;
14034a49301eSmrg         }
14044a49301eSmrg         else {
14054a49301eSmrg            error = GL_TRUE;
1406c1f859d4Smrg         }
1407c1f859d4Smrg         break;
14083464ebd5Sriastradh#if FEATURE_OES_draw_texture
1409c1f859d4Smrg      case GL_TEXTURE_CROP_RECT_OES:
1410c1f859d4Smrg         params[0] = obj->CropRect[0];
1411c1f859d4Smrg         params[1] = obj->CropRect[1];
1412c1f859d4Smrg         params[2] = obj->CropRect[2];
1413c1f859d4Smrg         params[3] = obj->CropRect[3];
1414c1f859d4Smrg         break;
1415c1f859d4Smrg#endif
14164a49301eSmrg      case GL_TEXTURE_SWIZZLE_R_EXT:
14174a49301eSmrg      case GL_TEXTURE_SWIZZLE_G_EXT:
14184a49301eSmrg      case GL_TEXTURE_SWIZZLE_B_EXT:
14194a49301eSmrg      case GL_TEXTURE_SWIZZLE_A_EXT:
14204a49301eSmrg         if (ctx->Extensions.EXT_texture_swizzle) {
14214a49301eSmrg            GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
14224a49301eSmrg            *params = obj->Swizzle[comp];
14234a49301eSmrg         }
14244a49301eSmrg         else {
14254a49301eSmrg            error = GL_TRUE;
14264a49301eSmrg         }
14274a49301eSmrg         break;
14284a49301eSmrg
14294a49301eSmrg      case GL_TEXTURE_SWIZZLE_RGBA_EXT:
14304a49301eSmrg         if (ctx->Extensions.EXT_texture_swizzle) {
14314a49301eSmrg            COPY_4V(params, obj->Swizzle);
14324a49301eSmrg         }
14334a49301eSmrg         else {
14344a49301eSmrg            error = GL_TRUE;
14354a49301eSmrg         }
14364a49301eSmrg         break;
14374a49301eSmrg
14383464ebd5Sriastradh      case GL_TEXTURE_CUBE_MAP_SEAMLESS:
14393464ebd5Sriastradh         if (ctx->Extensions.AMD_seamless_cubemap_per_texture) {
14403464ebd5Sriastradh            *params = (GLint) obj->Sampler.CubeMapSeamless;
14413464ebd5Sriastradh         }
14423464ebd5Sriastradh         else {
14433464ebd5Sriastradh            error = GL_TRUE;
14443464ebd5Sriastradh         }
14453464ebd5Sriastradh         break;
14463464ebd5Sriastradh
1447c1f859d4Smrg      default:
1448c1f859d4Smrg         ; /* silence warnings */
1449c1f859d4Smrg   }
14504a49301eSmrg
14514a49301eSmrg   if (error)
14524a49301eSmrg      _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)",
14534a49301eSmrg		  pname);
14544a49301eSmrg
14554a49301eSmrg   _mesa_unlock_texture(ctx, obj);
1456c1f859d4Smrg}
1457cdc920a0Smrg
1458cdc920a0Smrg
1459cdc920a0Smrg/** New in GL 3.0 */
1460cdc920a0Smrgvoid GLAPIENTRY
1461cdc920a0Smrg_mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params)
1462cdc920a0Smrg{
1463cdc920a0Smrg   struct gl_texture_object *texObj;
1464cdc920a0Smrg   GET_CURRENT_CONTEXT(ctx);
1465cdc920a0Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
1466cdc920a0Smrg
1467cdc920a0Smrg   texObj = get_texobj(ctx, target, GL_TRUE);
1468cdc920a0Smrg
1469cdc920a0Smrg   switch (pname) {
1470cdc920a0Smrg   case GL_TEXTURE_BORDER_COLOR:
14713464ebd5Sriastradh      COPY_4V(params, texObj->Sampler.BorderColor.i);
1472cdc920a0Smrg      break;
1473cdc920a0Smrg   default:
1474cdc920a0Smrg      _mesa_GetTexParameteriv(target, pname, params);
1475cdc920a0Smrg   }
1476cdc920a0Smrg}
1477cdc920a0Smrg
1478cdc920a0Smrg
1479cdc920a0Smrg/** New in GL 3.0 */
1480cdc920a0Smrgvoid GLAPIENTRY
1481cdc920a0Smrg_mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)
1482cdc920a0Smrg{
1483cdc920a0Smrg   struct gl_texture_object *texObj;
1484cdc920a0Smrg   GET_CURRENT_CONTEXT(ctx);
1485cdc920a0Smrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
1486cdc920a0Smrg
1487cdc920a0Smrg   texObj = get_texobj(ctx, target, GL_TRUE);
1488cdc920a0Smrg
1489cdc920a0Smrg   switch (pname) {
1490cdc920a0Smrg   case GL_TEXTURE_BORDER_COLOR:
14913464ebd5Sriastradh      COPY_4V(params, texObj->Sampler.BorderColor.i);
1492cdc920a0Smrg      break;
1493cdc920a0Smrg   default:
1494cdc920a0Smrg      {
1495cdc920a0Smrg         GLint ip[4];
1496cdc920a0Smrg         _mesa_GetTexParameteriv(target, pname, ip);
1497cdc920a0Smrg         params[0] = ip[0];
1498cdc920a0Smrg         if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT ||
1499cdc920a0Smrg             pname == GL_TEXTURE_CROP_RECT_OES) {
1500cdc920a0Smrg            params[1] = ip[1];
1501cdc920a0Smrg            params[2] = ip[2];
1502cdc920a0Smrg            params[3] = ip[3];
1503cdc920a0Smrg         }
1504cdc920a0Smrg      }
1505cdc920a0Smrg   }
1506cdc920a0Smrg}
1507