texparam.c revision af69d88d
1c1f859d4Smrg/*
2c1f859d4Smrg * Mesa 3-D graphics library
3c1f859d4Smrg *
4c1f859d4Smrg * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5c1f859d4Smrg * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
6c1f859d4Smrg *
7c1f859d4Smrg * Permission is hereby granted, free of charge, to any person obtaining a
8c1f859d4Smrg * copy of this software and associated documentation files (the "Software"),
9c1f859d4Smrg * to deal in the Software without restriction, including without limitation
10c1f859d4Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11c1f859d4Smrg * and/or sell copies of the Software, and to permit persons to whom the
12c1f859d4Smrg * Software is furnished to do so, subject to the following conditions:
13c1f859d4Smrg *
14c1f859d4Smrg * The above copyright notice and this permission notice shall be included
15c1f859d4Smrg * in all copies or substantial portions of the Software.
16c1f859d4Smrg *
17c1f859d4Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18c1f859d4Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19c1f859d4Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21af69d88dSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22af69d88dSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23af69d88dSmrg * OTHER DEALINGS IN THE SOFTWARE.
24c1f859d4Smrg */
25c1f859d4Smrg
26af69d88dSmrg/**
27c1f859d4Smrg * \file texparam.c
28c1f859d4Smrg *
29c1f859d4Smrg * glTexParameter-related functions
30c1f859d4Smrg */
31c1f859d4Smrg
32af69d88dSmrg#include <stdbool.h>
33c1f859d4Smrg#include "main/glheader.h"
34af69d88dSmrg#include "main/blend.h"
35c1f859d4Smrg#include "main/colormac.h"
364a49301eSmrg#include "main/context.h"
373464ebd5Sriastradh#include "main/enums.h"
384a49301eSmrg#include "main/formats.h"
39af69d88dSmrg#include "main/glformats.h"
40c1f859d4Smrg#include "main/macros.h"
413464ebd5Sriastradh#include "main/mtypes.h"
423464ebd5Sriastradh#include "main/state.h"
43c1f859d4Smrg#include "main/texcompress.h"
44af69d88dSmrg#include "main/texobj.h"
45c1f859d4Smrg#include "main/texparam.h"
46c1f859d4Smrg#include "main/teximage.h"
474a49301eSmrg#include "main/texstate.h"
483464ebd5Sriastradh#include "program/prog_instruction.h"
49c1f859d4Smrg
50c1f859d4Smrg
51c1f859d4Smrg/**
52c1f859d4Smrg * Check if a coordinate wrap mode is supported for the texture target.
53c1f859d4Smrg * \return GL_TRUE if legal, GL_FALSE otherwise
54c1f859d4Smrg */
55af69d88dSmrgstatic GLboolean
563464ebd5Sriastradhvalidate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap)
57c1f859d4Smrg{
58c1f859d4Smrg   const struct gl_extensions * const e = & ctx->Extensions;
59af69d88dSmrg   const bool is_desktop_gl = _mesa_is_desktop_gl(ctx);
60af69d88dSmrg   bool supported;
61af69d88dSmrg
62af69d88dSmrg   switch (wrap) {
63af69d88dSmrg   case GL_CLAMP:
64af69d88dSmrg      /* GL_CLAMP was removed in the core profile, and it has never existed in
65af69d88dSmrg       * OpenGL ES.
66af69d88dSmrg       */
67af69d88dSmrg      supported = (ctx->API == API_OPENGL_COMPAT)
68af69d88dSmrg         && (target != GL_TEXTURE_EXTERNAL_OES);
69af69d88dSmrg      break;
70c1f859d4Smrg
71af69d88dSmrg   case GL_CLAMP_TO_EDGE:
72af69d88dSmrg      supported = true;
73af69d88dSmrg      break;
74af69d88dSmrg
75af69d88dSmrg   case GL_CLAMP_TO_BORDER:
76af69d88dSmrg      supported = is_desktop_gl && e->ARB_texture_border_clamp
77af69d88dSmrg         && (target != GL_TEXTURE_EXTERNAL_OES);
78af69d88dSmrg      break;
79af69d88dSmrg
80af69d88dSmrg   case GL_REPEAT:
81af69d88dSmrg   case GL_MIRRORED_REPEAT:
82af69d88dSmrg      supported = (target != GL_TEXTURE_RECTANGLE_NV)
83af69d88dSmrg         && (target != GL_TEXTURE_EXTERNAL_OES);
84af69d88dSmrg      break;
85af69d88dSmrg
86af69d88dSmrg   case GL_MIRROR_CLAMP_EXT:
87af69d88dSmrg      supported = is_desktop_gl
88af69d88dSmrg         && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)
89af69d88dSmrg         && (target != GL_TEXTURE_RECTANGLE_NV)
90af69d88dSmrg         && (target != GL_TEXTURE_EXTERNAL_OES);
91af69d88dSmrg      break;
92af69d88dSmrg
93af69d88dSmrg   case GL_MIRROR_CLAMP_TO_EDGE_EXT:
94af69d88dSmrg      supported = is_desktop_gl
95af69d88dSmrg         && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp || e->ARB_texture_mirror_clamp_to_edge)
96af69d88dSmrg         && (target != GL_TEXTURE_RECTANGLE_NV)
97af69d88dSmrg         && (target != GL_TEXTURE_EXTERNAL_OES);
98af69d88dSmrg      break;
99af69d88dSmrg
100af69d88dSmrg   case GL_MIRROR_CLAMP_TO_BORDER_EXT:
101af69d88dSmrg      supported = is_desktop_gl && e->EXT_texture_mirror_clamp
102af69d88dSmrg         && (target != GL_TEXTURE_RECTANGLE_NV)
103af69d88dSmrg         && (target != GL_TEXTURE_EXTERNAL_OES);
104af69d88dSmrg      break;
105af69d88dSmrg
106af69d88dSmrg   default:
107af69d88dSmrg      supported = false;
108af69d88dSmrg      break;
109c1f859d4Smrg   }
110c1f859d4Smrg
111af69d88dSmrg   if (!supported)
112af69d88dSmrg      _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap );
113af69d88dSmrg
114af69d88dSmrg   return supported;
115c1f859d4Smrg}
116c1f859d4Smrg
117c1f859d4Smrg
118c1f859d4Smrg/**
119c1f859d4Smrg * Get current texture object for given target.
120cdc920a0Smrg * Return NULL if any error (and record the error).
121af69d88dSmrg * Note that this is different from _mesa_get_current_tex_object() in that
122af69d88dSmrg * proxy targets are not accepted.
123cdc920a0Smrg * Only the glGetTexLevelParameter() functions accept proxy targets.
124c1f859d4Smrg */
125c1f859d4Smrgstatic struct gl_texture_object *
1263464ebd5Sriastradhget_texobj(struct gl_context *ctx, GLenum target, GLboolean get)
127c1f859d4Smrg{
128c1f859d4Smrg   struct gl_texture_unit *texUnit;
129af69d88dSmrg   int targetIndex;
130c1f859d4Smrg
131cdc920a0Smrg   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
132cdc920a0Smrg      _mesa_error(ctx, GL_INVALID_OPERATION,
133cdc920a0Smrg                  "gl%sTexParameter(current unit)", get ? "Get" : "");
134c1f859d4Smrg      return NULL;
135c1f859d4Smrg   }
136c1f859d4Smrg
1374a49301eSmrg   texUnit = _mesa_get_current_tex_unit(ctx);
138c1f859d4Smrg
139af69d88dSmrg   targetIndex = _mesa_tex_target_to_index(ctx, target);
140af69d88dSmrg   if (targetIndex < 0 || targetIndex == TEXTURE_BUFFER_INDEX) {
141af69d88dSmrg      _mesa_error(ctx, GL_INVALID_ENUM,
142af69d88dSmrg                  "gl%sTexParameter(target)", get ? "Get" : "");
143af69d88dSmrg      return NULL;
144c1f859d4Smrg   }
145af69d88dSmrg   assert(targetIndex < NUM_TEXTURE_TARGETS);
146c1f859d4Smrg
147af69d88dSmrg   return texUnit->CurrentTex[targetIndex];
148c1f859d4Smrg}
149c1f859d4Smrg
150c1f859d4Smrg
1514a49301eSmrg/**
1524a49301eSmrg * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE.
1534a49301eSmrg * \return -1 if error.
1544a49301eSmrg */
1554a49301eSmrgstatic GLint
1564a49301eSmrgcomp_to_swizzle(GLenum comp)
1574a49301eSmrg{
1584a49301eSmrg   switch (comp) {
1594a49301eSmrg   case GL_RED:
1604a49301eSmrg      return SWIZZLE_X;
1614a49301eSmrg   case GL_GREEN:
1624a49301eSmrg      return SWIZZLE_Y;
1634a49301eSmrg   case GL_BLUE:
1644a49301eSmrg      return SWIZZLE_Z;
1654a49301eSmrg   case GL_ALPHA:
1664a49301eSmrg      return SWIZZLE_W;
1674a49301eSmrg   case GL_ZERO:
1684a49301eSmrg      return SWIZZLE_ZERO;
1694a49301eSmrg   case GL_ONE:
1704a49301eSmrg      return SWIZZLE_ONE;
1714a49301eSmrg   default:
1724a49301eSmrg      return -1;
1734a49301eSmrg   }
1744a49301eSmrg}
1754a49301eSmrg
1764a49301eSmrg
1774a49301eSmrgstatic void
1784a49301eSmrgset_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz)
1794a49301eSmrg{
1804a49301eSmrg   ASSERT(comp < 4);
1814a49301eSmrg   ASSERT(swz <= SWIZZLE_NIL);
1824a49301eSmrg   {
1834a49301eSmrg      GLuint mask = 0x7 << (3 * comp);
1844a49301eSmrg      GLuint s = (*swizzle & ~mask) | (swz << (3 * comp));
1854a49301eSmrg      *swizzle = s;
1864a49301eSmrg   }
1874a49301eSmrg}
1884a49301eSmrg
1894a49301eSmrg
190c1f859d4Smrg/**
1913464ebd5Sriastradh * This is called just prior to changing any texture object state which
1923464ebd5Sriastradh * will not effect texture completeness.
1933464ebd5Sriastradh */
194af69d88dSmrgstatic inline void
1953464ebd5Sriastradhflush(struct gl_context *ctx)
1963464ebd5Sriastradh{
1973464ebd5Sriastradh   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
1983464ebd5Sriastradh}
1993464ebd5Sriastradh
2003464ebd5Sriastradh
2013464ebd5Sriastradh/**
2023464ebd5Sriastradh * This is called just prior to changing any texture object state which
203af69d88dSmrg * can effect texture completeness (texture base level, max level).
204c1f859d4Smrg * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE
205c1f859d4Smrg * state flag and then mark the texture object as 'incomplete' so that any
206c1f859d4Smrg * per-texture derived state gets recomputed.
207c1f859d4Smrg */
208af69d88dSmrgstatic inline void
2093464ebd5Sriastradhincomplete(struct gl_context *ctx, struct gl_texture_object *texObj)
210c1f859d4Smrg{
211c1f859d4Smrg   FLUSH_VERTICES(ctx, _NEW_TEXTURE);
212af69d88dSmrg   _mesa_dirty_texobj(ctx, texObj);
213af69d88dSmrg}
214af69d88dSmrg
215af69d88dSmrg
216af69d88dSmrgstatic GLboolean
217af69d88dSmrgtarget_allows_setting_sampler_parameters(GLenum target)
218af69d88dSmrg{
219af69d88dSmrg   switch (target) {
220af69d88dSmrg   case GL_TEXTURE_2D_MULTISAMPLE:
221af69d88dSmrg   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
222af69d88dSmrg      return GL_FALSE;
223af69d88dSmrg
224af69d88dSmrg   default:
225af69d88dSmrg      return GL_TRUE;
226af69d88dSmrg   }
227c1f859d4Smrg}
228c1f859d4Smrg
229c1f859d4Smrg
230c1f859d4Smrg/**
231c1f859d4Smrg * Set an integer-valued texture parameter
232c1f859d4Smrg * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
233c1f859d4Smrg */
234c1f859d4Smrgstatic GLboolean
2353464ebd5Sriastradhset_tex_parameteri(struct gl_context *ctx,
236c1f859d4Smrg                   struct gl_texture_object *texObj,
237c1f859d4Smrg                   GLenum pname, const GLint *params)
238c1f859d4Smrg{
239c1f859d4Smrg   switch (pname) {
240c1f859d4Smrg   case GL_TEXTURE_MIN_FILTER:
241af69d88dSmrg      if (!target_allows_setting_sampler_parameters(texObj->Target))
242af69d88dSmrg         goto invalid_operation;
243af69d88dSmrg
2443464ebd5Sriastradh      if (texObj->Sampler.MinFilter == params[0])
245c1f859d4Smrg         return GL_FALSE;
246c1f859d4Smrg      switch (params[0]) {
247c1f859d4Smrg      case GL_NEAREST:
248c1f859d4Smrg      case GL_LINEAR:
249af69d88dSmrg         flush(ctx);
2503464ebd5Sriastradh         texObj->Sampler.MinFilter = params[0];
251c1f859d4Smrg         return GL_TRUE;
252c1f859d4Smrg      case GL_NEAREST_MIPMAP_NEAREST:
253c1f859d4Smrg      case GL_LINEAR_MIPMAP_NEAREST:
254c1f859d4Smrg      case GL_NEAREST_MIPMAP_LINEAR:
255c1f859d4Smrg      case GL_LINEAR_MIPMAP_LINEAR:
256af69d88dSmrg         if (texObj->Target != GL_TEXTURE_RECTANGLE_NV &&
257af69d88dSmrg             texObj->Target != GL_TEXTURE_EXTERNAL_OES) {
258af69d88dSmrg            flush(ctx);
2593464ebd5Sriastradh            texObj->Sampler.MinFilter = params[0];
260c1f859d4Smrg            return GL_TRUE;
261c1f859d4Smrg         }
262c1f859d4Smrg         /* fall-through */
263c1f859d4Smrg      default:
2643464ebd5Sriastradh         goto invalid_param;
265c1f859d4Smrg      }
266c1f859d4Smrg      return GL_FALSE;
267c1f859d4Smrg
268c1f859d4Smrg   case GL_TEXTURE_MAG_FILTER:
269af69d88dSmrg      if (!target_allows_setting_sampler_parameters(texObj->Target))
270af69d88dSmrg         goto invalid_operation;
271af69d88dSmrg
2723464ebd5Sriastradh      if (texObj->Sampler.MagFilter == params[0])
273c1f859d4Smrg         return GL_FALSE;
274c1f859d4Smrg      switch (params[0]) {
275c1f859d4Smrg      case GL_NEAREST:
276c1f859d4Smrg      case GL_LINEAR:
2773464ebd5Sriastradh         flush(ctx); /* does not effect completeness */
2783464ebd5Sriastradh         texObj->Sampler.MagFilter = params[0];
279c1f859d4Smrg         return GL_TRUE;
280c1f859d4Smrg      default:
2813464ebd5Sriastradh         goto invalid_param;
282c1f859d4Smrg      }
283c1f859d4Smrg      return GL_FALSE;
284c1f859d4Smrg
285c1f859d4Smrg   case GL_TEXTURE_WRAP_S:
286af69d88dSmrg      if (!target_allows_setting_sampler_parameters(texObj->Target))
287af69d88dSmrg         goto invalid_operation;
288af69d88dSmrg
2893464ebd5Sriastradh      if (texObj->Sampler.WrapS == params[0])
290c1f859d4Smrg         return GL_FALSE;
291c1f859d4Smrg      if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
2923464ebd5Sriastradh         flush(ctx);
2933464ebd5Sriastradh         texObj->Sampler.WrapS = params[0];
294c1f859d4Smrg         return GL_TRUE;
295c1f859d4Smrg      }
296c1f859d4Smrg      return GL_FALSE;
297c1f859d4Smrg
298c1f859d4Smrg   case GL_TEXTURE_WRAP_T:
299af69d88dSmrg      if (!target_allows_setting_sampler_parameters(texObj->Target))
300af69d88dSmrg         goto invalid_operation;
301af69d88dSmrg
3023464ebd5Sriastradh      if (texObj->Sampler.WrapT == params[0])
303c1f859d4Smrg         return GL_FALSE;
304c1f859d4Smrg      if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
3053464ebd5Sriastradh         flush(ctx);
3063464ebd5Sriastradh         texObj->Sampler.WrapT = params[0];
307c1f859d4Smrg         return GL_TRUE;
308c1f859d4Smrg      }
309c1f859d4Smrg      return GL_FALSE;
310c1f859d4Smrg
311c1f859d4Smrg   case GL_TEXTURE_WRAP_R:
312af69d88dSmrg      if (!target_allows_setting_sampler_parameters(texObj->Target))
313af69d88dSmrg         goto invalid_operation;
314af69d88dSmrg
3153464ebd5Sriastradh      if (texObj->Sampler.WrapR == params[0])
316c1f859d4Smrg         return GL_FALSE;
317c1f859d4Smrg      if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
3183464ebd5Sriastradh         flush(ctx);
3193464ebd5Sriastradh         texObj->Sampler.WrapR = params[0];
320c1f859d4Smrg         return GL_TRUE;
321c1f859d4Smrg      }
322c1f859d4Smrg      return GL_FALSE;
323c1f859d4Smrg
324c1f859d4Smrg   case GL_TEXTURE_BASE_LEVEL:
325af69d88dSmrg      if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
326af69d88dSmrg         goto invalid_pname;
327af69d88dSmrg
328c1f859d4Smrg      if (texObj->BaseLevel == params[0])
329c1f859d4Smrg         return GL_FALSE;
330af69d88dSmrg
331af69d88dSmrg      if ((texObj->Target == GL_TEXTURE_2D_MULTISAMPLE ||
332af69d88dSmrg           texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) && params[0] != 0)
333af69d88dSmrg         goto invalid_operation;
334af69d88dSmrg
335c1f859d4Smrg      if (params[0] < 0 ||
336c1f859d4Smrg          (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) {
3374a49301eSmrg         _mesa_error(ctx, GL_INVALID_VALUE,
3384a49301eSmrg                     "glTexParameter(param=%d)", params[0]);
339c1f859d4Smrg         return GL_FALSE;
340c1f859d4Smrg      }
3413464ebd5Sriastradh      incomplete(ctx, texObj);
342af69d88dSmrg
343af69d88dSmrg      /** See note about ARB_texture_storage below */
344af69d88dSmrg      if (texObj->Immutable)
345af69d88dSmrg         texObj->BaseLevel = MIN2(texObj->ImmutableLevels - 1, params[0]);
346af69d88dSmrg      else
347af69d88dSmrg         texObj->BaseLevel = params[0];
348af69d88dSmrg
349c1f859d4Smrg      return GL_TRUE;
350c1f859d4Smrg
351c1f859d4Smrg   case GL_TEXTURE_MAX_LEVEL:
352c1f859d4Smrg      if (texObj->MaxLevel == params[0])
353c1f859d4Smrg         return GL_FALSE;
354af69d88dSmrg
355af69d88dSmrg      if (params[0] < 0 ||
356af69d88dSmrg          (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] > 0)) {
357af69d88dSmrg         _mesa_error(ctx, GL_INVALID_VALUE,
3584a49301eSmrg                     "glTexParameter(param=%d)", params[0]);
359c1f859d4Smrg         return GL_FALSE;
360c1f859d4Smrg      }
3613464ebd5Sriastradh      incomplete(ctx, texObj);
362af69d88dSmrg
363af69d88dSmrg      /** From ARB_texture_storage:
364af69d88dSmrg       * However, if TEXTURE_IMMUTABLE_FORMAT is TRUE, then level_base is
365af69d88dSmrg       * clamped to the range [0, <levels> - 1] and level_max is then clamped to
366af69d88dSmrg       * the range [level_base, <levels> - 1], where <levels> is the parameter
367af69d88dSmrg       * passed the call to TexStorage* for the texture object.
368af69d88dSmrg       */
369af69d88dSmrg      if (texObj->Immutable)
370af69d88dSmrg          texObj->MaxLevel = CLAMP(params[0], texObj->BaseLevel,
371af69d88dSmrg                                   texObj->ImmutableLevels - 1);
372af69d88dSmrg      else
373af69d88dSmrg         texObj->MaxLevel = params[0];
374af69d88dSmrg
375c1f859d4Smrg      return GL_TRUE;
376c1f859d4Smrg
377c1f859d4Smrg   case GL_GENERATE_MIPMAP_SGIS:
378af69d88dSmrg      if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
379af69d88dSmrg         goto invalid_pname;
380af69d88dSmrg
381af69d88dSmrg      if (params[0] && texObj->Target == GL_TEXTURE_EXTERNAL_OES)
382af69d88dSmrg         goto invalid_param;
3833464ebd5Sriastradh      if (texObj->GenerateMipmap != params[0]) {
3843464ebd5Sriastradh         /* no flush() */
3853464ebd5Sriastradh	 texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
3863464ebd5Sriastradh	 return GL_TRUE;
387c1f859d4Smrg      }
388c1f859d4Smrg      return GL_FALSE;
389c1f859d4Smrg
390c1f859d4Smrg   case GL_TEXTURE_COMPARE_MODE_ARB:
391af69d88dSmrg      if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow)
392af69d88dSmrg          || _mesa_is_gles3(ctx)) {
393af69d88dSmrg
394af69d88dSmrg         if (!target_allows_setting_sampler_parameters(texObj->Target))
395af69d88dSmrg            goto invalid_operation;
396af69d88dSmrg
3973464ebd5Sriastradh         if (texObj->Sampler.CompareMode == params[0])
3983464ebd5Sriastradh            return GL_FALSE;
3993464ebd5Sriastradh         if (params[0] == GL_NONE ||
4003464ebd5Sriastradh             params[0] == GL_COMPARE_R_TO_TEXTURE_ARB) {
4013464ebd5Sriastradh            flush(ctx);
4023464ebd5Sriastradh            texObj->Sampler.CompareMode = params[0];
403c1f859d4Smrg            return GL_TRUE;
404c1f859d4Smrg         }
4053464ebd5Sriastradh         goto invalid_param;
406c1f859d4Smrg      }
4073464ebd5Sriastradh      goto invalid_pname;
408c1f859d4Smrg
409c1f859d4Smrg   case GL_TEXTURE_COMPARE_FUNC_ARB:
410af69d88dSmrg      if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow)
411af69d88dSmrg          || _mesa_is_gles3(ctx)) {
412af69d88dSmrg
413af69d88dSmrg         if (!target_allows_setting_sampler_parameters(texObj->Target))
414af69d88dSmrg            goto invalid_operation;
415af69d88dSmrg
4163464ebd5Sriastradh         if (texObj->Sampler.CompareFunc == params[0])
417c1f859d4Smrg            return GL_FALSE;
418c1f859d4Smrg         switch (params[0]) {
419c1f859d4Smrg         case GL_LEQUAL:
420c1f859d4Smrg         case GL_GEQUAL:
421c1f859d4Smrg         case GL_EQUAL:
422c1f859d4Smrg         case GL_NOTEQUAL:
423c1f859d4Smrg         case GL_LESS:
424c1f859d4Smrg         case GL_GREATER:
425c1f859d4Smrg         case GL_ALWAYS:
426c1f859d4Smrg         case GL_NEVER:
427af69d88dSmrg            flush(ctx);
428af69d88dSmrg            texObj->Sampler.CompareFunc = params[0];
429af69d88dSmrg            return GL_TRUE;
430c1f859d4Smrg         default:
4313464ebd5Sriastradh            goto invalid_param;
432c1f859d4Smrg         }
433c1f859d4Smrg      }
4343464ebd5Sriastradh      goto invalid_pname;
435c1f859d4Smrg
436c1f859d4Smrg   case GL_DEPTH_TEXTURE_MODE_ARB:
437af69d88dSmrg      /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has never
438af69d88dSmrg       * existed in OpenGL ES.
439af69d88dSmrg       */
440af69d88dSmrg      if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_depth_texture) {
441af69d88dSmrg         if (texObj->DepthMode == params[0])
4423464ebd5Sriastradh            return GL_FALSE;
4433464ebd5Sriastradh         if (params[0] == GL_LUMINANCE ||
4443464ebd5Sriastradh             params[0] == GL_INTENSITY ||
4453464ebd5Sriastradh             params[0] == GL_ALPHA ||
4463464ebd5Sriastradh             (ctx->Extensions.ARB_texture_rg && params[0] == GL_RED)) {
4473464ebd5Sriastradh            flush(ctx);
448af69d88dSmrg            texObj->DepthMode = params[0];
449c1f859d4Smrg            return GL_TRUE;
450c1f859d4Smrg         }
4513464ebd5Sriastradh         goto invalid_param;
452c1f859d4Smrg      }
4533464ebd5Sriastradh      goto invalid_pname;
454c1f859d4Smrg
455af69d88dSmrg   case GL_DEPTH_STENCIL_TEXTURE_MODE:
456af69d88dSmrg      if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_stencil_texturing) {
457af69d88dSmrg         bool stencil = params[0] == GL_STENCIL_INDEX;
458af69d88dSmrg         if (!stencil && params[0] != GL_DEPTH_COMPONENT)
459af69d88dSmrg            goto invalid_param;
460af69d88dSmrg
461af69d88dSmrg         if (texObj->StencilSampling == stencil)
462af69d88dSmrg            return GL_FALSE;
463af69d88dSmrg
464af69d88dSmrg         texObj->StencilSampling = stencil;
465af69d88dSmrg         return GL_TRUE;
466af69d88dSmrg      }
467af69d88dSmrg      goto invalid_pname;
468af69d88dSmrg
469c1f859d4Smrg   case GL_TEXTURE_CROP_RECT_OES:
470af69d88dSmrg      if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
471af69d88dSmrg         goto invalid_pname;
472af69d88dSmrg
473c1f859d4Smrg      texObj->CropRect[0] = params[0];
474c1f859d4Smrg      texObj->CropRect[1] = params[1];
475c1f859d4Smrg      texObj->CropRect[2] = params[2];
476c1f859d4Smrg      texObj->CropRect[3] = params[3];
477c1f859d4Smrg      return GL_TRUE;
478c1f859d4Smrg
4794a49301eSmrg   case GL_TEXTURE_SWIZZLE_R_EXT:
4804a49301eSmrg   case GL_TEXTURE_SWIZZLE_G_EXT:
4814a49301eSmrg   case GL_TEXTURE_SWIZZLE_B_EXT:
4824a49301eSmrg   case GL_TEXTURE_SWIZZLE_A_EXT:
483af69d88dSmrg      if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle)
484af69d88dSmrg          || _mesa_is_gles3(ctx)) {
4854a49301eSmrg         const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
4864a49301eSmrg         const GLint swz = comp_to_swizzle(params[0]);
4874a49301eSmrg         if (swz < 0) {
488af69d88dSmrg            _mesa_error(ctx, GL_INVALID_ENUM,
4894a49301eSmrg                        "glTexParameter(swizzle 0x%x)", params[0]);
4904a49301eSmrg            return GL_FALSE;
4914a49301eSmrg         }
4924a49301eSmrg         ASSERT(comp < 4);
493af69d88dSmrg
494af69d88dSmrg         flush(ctx);
495af69d88dSmrg         texObj->Swizzle[comp] = params[0];
496af69d88dSmrg         set_swizzle_component(&texObj->_Swizzle, comp, swz);
497af69d88dSmrg         return GL_TRUE;
4984a49301eSmrg      }
4993464ebd5Sriastradh      goto invalid_pname;
5004a49301eSmrg
5014a49301eSmrg   case GL_TEXTURE_SWIZZLE_RGBA_EXT:
502af69d88dSmrg      if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle)
503af69d88dSmrg          || _mesa_is_gles3(ctx)) {
5044a49301eSmrg         GLuint comp;
5053464ebd5Sriastradh         flush(ctx);
5064a49301eSmrg         for (comp = 0; comp < 4; comp++) {
5074a49301eSmrg            const GLint swz = comp_to_swizzle(params[comp]);
5084a49301eSmrg            if (swz >= 0) {
5094a49301eSmrg               texObj->Swizzle[comp] = params[comp];
5104a49301eSmrg               set_swizzle_component(&texObj->_Swizzle, comp, swz);
5114a49301eSmrg            }
5124a49301eSmrg            else {
513af69d88dSmrg               _mesa_error(ctx, GL_INVALID_ENUM,
5144a49301eSmrg                           "glTexParameter(swizzle 0x%x)", params[comp]);
5154a49301eSmrg               return GL_FALSE;
5164a49301eSmrg            }
5174a49301eSmrg         }
5184a49301eSmrg         return GL_TRUE;
5194a49301eSmrg      }
5203464ebd5Sriastradh      goto invalid_pname;
5213464ebd5Sriastradh
5223464ebd5Sriastradh   case GL_TEXTURE_SRGB_DECODE_EXT:
523af69d88dSmrg      if (_mesa_is_desktop_gl(ctx)
524af69d88dSmrg          && ctx->Extensions.EXT_texture_sRGB_decode) {
525af69d88dSmrg         GLenum decode = params[0];
526af69d88dSmrg
527af69d88dSmrg         if (!target_allows_setting_sampler_parameters(texObj->Target))
528af69d88dSmrg            goto invalid_operation;
529af69d88dSmrg
5303464ebd5Sriastradh	 if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) {
5313464ebd5Sriastradh	    if (texObj->Sampler.sRGBDecode != decode) {
5323464ebd5Sriastradh	       flush(ctx);
5333464ebd5Sriastradh	       texObj->Sampler.sRGBDecode = decode;
5343464ebd5Sriastradh	    }
5353464ebd5Sriastradh	    return GL_TRUE;
5363464ebd5Sriastradh	 }
5373464ebd5Sriastradh      }
5383464ebd5Sriastradh      goto invalid_pname;
5393464ebd5Sriastradh
5403464ebd5Sriastradh   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
541af69d88dSmrg      if (_mesa_is_desktop_gl(ctx)
542af69d88dSmrg          && ctx->Extensions.AMD_seamless_cubemap_per_texture) {
5433464ebd5Sriastradh         GLenum param = params[0];
544af69d88dSmrg
545af69d88dSmrg         if (!target_allows_setting_sampler_parameters(texObj->Target))
546af69d88dSmrg            goto invalid_operation;
547af69d88dSmrg
5483464ebd5Sriastradh         if (param != GL_TRUE && param != GL_FALSE) {
5493464ebd5Sriastradh            goto invalid_param;
5503464ebd5Sriastradh         }
5513464ebd5Sriastradh         if (param != texObj->Sampler.CubeMapSeamless) {
5523464ebd5Sriastradh            flush(ctx);
5533464ebd5Sriastradh            texObj->Sampler.CubeMapSeamless = param;
5543464ebd5Sriastradh         }
5553464ebd5Sriastradh         return GL_TRUE;
5563464ebd5Sriastradh      }
5573464ebd5Sriastradh      goto invalid_pname;
5584a49301eSmrg
559c1f859d4Smrg   default:
5603464ebd5Sriastradh      goto invalid_pname;
561c1f859d4Smrg   }
5623464ebd5Sriastradh
5633464ebd5Sriastradhinvalid_pname:
5643464ebd5Sriastradh   _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)",
5653464ebd5Sriastradh               _mesa_lookup_enum_by_nr(pname));
5663464ebd5Sriastradh   return GL_FALSE;
5673464ebd5Sriastradh
5683464ebd5Sriastradhinvalid_param:
5693464ebd5Sriastradh   _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param=%s)",
5703464ebd5Sriastradh               _mesa_lookup_enum_by_nr(params[0]));
571c1f859d4Smrg   return GL_FALSE;
572af69d88dSmrg
573af69d88dSmrginvalid_operation:
574af69d88dSmrg   _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)",
575af69d88dSmrg               _mesa_lookup_enum_by_nr(pname));
576af69d88dSmrg   return GL_FALSE;
577c1f859d4Smrg}
578c1f859d4Smrg
579c1f859d4Smrg
580c1f859d4Smrg/**
581c1f859d4Smrg * Set a float-valued texture parameter
582c1f859d4Smrg * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
583c1f859d4Smrg */
584c1f859d4Smrgstatic GLboolean
5853464ebd5Sriastradhset_tex_parameterf(struct gl_context *ctx,
586c1f859d4Smrg                   struct gl_texture_object *texObj,
587c1f859d4Smrg                   GLenum pname, const GLfloat *params)
588c1f859d4Smrg{
589c1f859d4Smrg   switch (pname) {
590c1f859d4Smrg   case GL_TEXTURE_MIN_LOD:
591af69d88dSmrg      if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
592af69d88dSmrg         goto invalid_pname;
593af69d88dSmrg
594af69d88dSmrg      if (!target_allows_setting_sampler_parameters(texObj->Target))
595af69d88dSmrg         goto invalid_operation;
596af69d88dSmrg
5973464ebd5Sriastradh      if (texObj->Sampler.MinLod == params[0])
598c1f859d4Smrg         return GL_FALSE;
5993464ebd5Sriastradh      flush(ctx);
6003464ebd5Sriastradh      texObj->Sampler.MinLod = params[0];
601c1f859d4Smrg      return GL_TRUE;
602c1f859d4Smrg
603c1f859d4Smrg   case GL_TEXTURE_MAX_LOD:
604af69d88dSmrg      if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
605af69d88dSmrg         goto invalid_pname;
606af69d88dSmrg
607af69d88dSmrg      if (!target_allows_setting_sampler_parameters(texObj->Target))
608af69d88dSmrg         goto invalid_operation;
609af69d88dSmrg
6103464ebd5Sriastradh      if (texObj->Sampler.MaxLod == params[0])
611c1f859d4Smrg         return GL_FALSE;
6123464ebd5Sriastradh      flush(ctx);
6133464ebd5Sriastradh      texObj->Sampler.MaxLod = params[0];
614c1f859d4Smrg      return GL_TRUE;
615c1f859d4Smrg
616c1f859d4Smrg   case GL_TEXTURE_PRIORITY:
617af69d88dSmrg      if (ctx->API != API_OPENGL_COMPAT)
618af69d88dSmrg         goto invalid_pname;
619af69d88dSmrg
6203464ebd5Sriastradh      flush(ctx);
621c1f859d4Smrg      texObj->Priority = CLAMP(params[0], 0.0F, 1.0F);
622c1f859d4Smrg      return GL_TRUE;
623c1f859d4Smrg
624c1f859d4Smrg   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
625c1f859d4Smrg      if (ctx->Extensions.EXT_texture_filter_anisotropic) {
626af69d88dSmrg         if (!target_allows_setting_sampler_parameters(texObj->Target))
627af69d88dSmrg            goto invalid_operation;
628af69d88dSmrg
6293464ebd5Sriastradh         if (texObj->Sampler.MaxAnisotropy == params[0])
630c1f859d4Smrg            return GL_FALSE;
631c1f859d4Smrg         if (params[0] < 1.0) {
632c1f859d4Smrg            _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
633c1f859d4Smrg            return GL_FALSE;
634c1f859d4Smrg         }
6353464ebd5Sriastradh         flush(ctx);
636c1f859d4Smrg         /* clamp to max, that's what NVIDIA does */
6373464ebd5Sriastradh         texObj->Sampler.MaxAnisotropy = MIN2(params[0],
638c1f859d4Smrg                                      ctx->Const.MaxTextureMaxAnisotropy);
639c1f859d4Smrg         return GL_TRUE;
640c1f859d4Smrg      }
641c1f859d4Smrg      else {
6424a49301eSmrg         static GLuint count = 0;
6434a49301eSmrg         if (count++ < 10)
644af69d88dSmrg            goto invalid_pname;
645c1f859d4Smrg      }
646c1f859d4Smrg      return GL_FALSE;
647c1f859d4Smrg
648c1f859d4Smrg   case GL_TEXTURE_LOD_BIAS:
649af69d88dSmrg      /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias. */
650af69d88dSmrg      if (_mesa_is_gles(ctx))
651af69d88dSmrg         goto invalid_pname;
652af69d88dSmrg
653af69d88dSmrg      if (!target_allows_setting_sampler_parameters(texObj->Target))
654af69d88dSmrg         goto invalid_operation;
655af69d88dSmrg
656af69d88dSmrg      if (texObj->Sampler.LodBias != params[0]) {
657af69d88dSmrg	 flush(ctx);
658af69d88dSmrg	 texObj->Sampler.LodBias = params[0];
659af69d88dSmrg	 return GL_TRUE;
660c1f859d4Smrg      }
661c1f859d4Smrg      break;
662c1f859d4Smrg
663c1f859d4Smrg   case GL_TEXTURE_BORDER_COLOR:
664af69d88dSmrg      if (!_mesa_is_desktop_gl(ctx))
665af69d88dSmrg         goto invalid_pname;
666af69d88dSmrg
667af69d88dSmrg      if (!target_allows_setting_sampler_parameters(texObj->Target))
668af69d88dSmrg         goto invalid_operation;
669af69d88dSmrg
6703464ebd5Sriastradh      flush(ctx);
6713464ebd5Sriastradh      /* ARB_texture_float disables clamping */
6723464ebd5Sriastradh      if (ctx->Extensions.ARB_texture_float) {
6733464ebd5Sriastradh         texObj->Sampler.BorderColor.f[RCOMP] = params[0];
6743464ebd5Sriastradh         texObj->Sampler.BorderColor.f[GCOMP] = params[1];
6753464ebd5Sriastradh         texObj->Sampler.BorderColor.f[BCOMP] = params[2];
6763464ebd5Sriastradh         texObj->Sampler.BorderColor.f[ACOMP] = params[3];
6773464ebd5Sriastradh      } else {
6783464ebd5Sriastradh         texObj->Sampler.BorderColor.f[RCOMP] = CLAMP(params[0], 0.0F, 1.0F);
6793464ebd5Sriastradh         texObj->Sampler.BorderColor.f[GCOMP] = CLAMP(params[1], 0.0F, 1.0F);
6803464ebd5Sriastradh         texObj->Sampler.BorderColor.f[BCOMP] = CLAMP(params[2], 0.0F, 1.0F);
6813464ebd5Sriastradh         texObj->Sampler.BorderColor.f[ACOMP] = CLAMP(params[3], 0.0F, 1.0F);
6823464ebd5Sriastradh      }
683c1f859d4Smrg      return GL_TRUE;
684c1f859d4Smrg
685c1f859d4Smrg   default:
686af69d88dSmrg      goto invalid_pname;
687c1f859d4Smrg   }
688c1f859d4Smrg   return GL_FALSE;
689af69d88dSmrg
690af69d88dSmrginvalid_pname:
691af69d88dSmrg   _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)",
692af69d88dSmrg               _mesa_lookup_enum_by_nr(pname));
693af69d88dSmrg   return GL_FALSE;
694af69d88dSmrg
695af69d88dSmrginvalid_operation:
696af69d88dSmrg   _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)",
697af69d88dSmrg               _mesa_lookup_enum_by_nr(pname));
698af69d88dSmrg   return GL_FALSE;
699c1f859d4Smrg}
700c1f859d4Smrg
701c1f859d4Smrg
702c1f859d4Smrgvoid GLAPIENTRY
703c1f859d4Smrg_mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
704c1f859d4Smrg{
705c1f859d4Smrg   GLboolean need_update;
706c1f859d4Smrg   struct gl_texture_object *texObj;
707c1f859d4Smrg   GET_CURRENT_CONTEXT(ctx);
708c1f859d4Smrg
709cdc920a0Smrg   texObj = get_texobj(ctx, target, GL_FALSE);
710c1f859d4Smrg   if (!texObj)
711c1f859d4Smrg      return;
712c1f859d4Smrg
713c1f859d4Smrg   switch (pname) {
714c1f859d4Smrg   case GL_TEXTURE_MIN_FILTER:
715c1f859d4Smrg   case GL_TEXTURE_MAG_FILTER:
716c1f859d4Smrg   case GL_TEXTURE_WRAP_S:
717c1f859d4Smrg   case GL_TEXTURE_WRAP_T:
718c1f859d4Smrg   case GL_TEXTURE_WRAP_R:
719c1f859d4Smrg   case GL_TEXTURE_BASE_LEVEL:
720c1f859d4Smrg   case GL_TEXTURE_MAX_LEVEL:
721c1f859d4Smrg   case GL_GENERATE_MIPMAP_SGIS:
722c1f859d4Smrg   case GL_TEXTURE_COMPARE_MODE_ARB:
723c1f859d4Smrg   case GL_TEXTURE_COMPARE_FUNC_ARB:
724c1f859d4Smrg   case GL_DEPTH_TEXTURE_MODE_ARB:
725af69d88dSmrg   case GL_DEPTH_STENCIL_TEXTURE_MODE:
7263464ebd5Sriastradh   case GL_TEXTURE_SRGB_DECODE_EXT:
7273464ebd5Sriastradh   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
728af69d88dSmrg   case GL_TEXTURE_SWIZZLE_R_EXT:
729af69d88dSmrg   case GL_TEXTURE_SWIZZLE_G_EXT:
730af69d88dSmrg   case GL_TEXTURE_SWIZZLE_B_EXT:
731af69d88dSmrg   case GL_TEXTURE_SWIZZLE_A_EXT:
732c1f859d4Smrg      {
7334a49301eSmrg         GLint p[4];
734af69d88dSmrg         p[0] = (param > 0) ?
735af69d88dSmrg                ((param > INT_MAX) ? INT_MAX : (GLint) (param + 0.5)) :
736af69d88dSmrg                ((param < INT_MIN) ? INT_MIN : (GLint) (param - 0.5));
737af69d88dSmrg
7384a49301eSmrg         p[1] = p[2] = p[3] = 0;
7394a49301eSmrg         need_update = set_tex_parameteri(ctx, texObj, pname, p);
740c1f859d4Smrg      }
741c1f859d4Smrg      break;
742c1f859d4Smrg   default:
7434a49301eSmrg      {
7444a49301eSmrg         /* this will generate an error if pname is illegal */
7454a49301eSmrg         GLfloat p[4];
7464a49301eSmrg         p[0] = param;
7474a49301eSmrg         p[1] = p[2] = p[3] = 0.0F;
7484a49301eSmrg         need_update = set_tex_parameterf(ctx, texObj, pname, p);
7494a49301eSmrg      }
750c1f859d4Smrg   }
751c1f859d4Smrg
752c1f859d4Smrg   if (ctx->Driver.TexParameter && need_update) {
753af69d88dSmrg      ctx->Driver.TexParameter(ctx, texObj, pname, &param);
754c1f859d4Smrg   }
755c1f859d4Smrg}
756c1f859d4Smrg
757c1f859d4Smrg
758c1f859d4Smrgvoid GLAPIENTRY
759c1f859d4Smrg_mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
760c1f859d4Smrg{
761c1f859d4Smrg   GLboolean need_update;
762c1f859d4Smrg   struct gl_texture_object *texObj;
763c1f859d4Smrg   GET_CURRENT_CONTEXT(ctx);
764c1f859d4Smrg
765cdc920a0Smrg   texObj = get_texobj(ctx, target, GL_FALSE);
766c1f859d4Smrg   if (!texObj)
767c1f859d4Smrg      return;
768c1f859d4Smrg
769c1f859d4Smrg   switch (pname) {
770c1f859d4Smrg   case GL_TEXTURE_MIN_FILTER:
771c1f859d4Smrg   case GL_TEXTURE_MAG_FILTER:
772c1f859d4Smrg   case GL_TEXTURE_WRAP_S:
773c1f859d4Smrg   case GL_TEXTURE_WRAP_T:
774c1f859d4Smrg   case GL_TEXTURE_WRAP_R:
775c1f859d4Smrg   case GL_TEXTURE_BASE_LEVEL:
776c1f859d4Smrg   case GL_TEXTURE_MAX_LEVEL:
777c1f859d4Smrg   case GL_GENERATE_MIPMAP_SGIS:
778c1f859d4Smrg   case GL_TEXTURE_COMPARE_MODE_ARB:
779c1f859d4Smrg   case GL_TEXTURE_COMPARE_FUNC_ARB:
780c1f859d4Smrg   case GL_DEPTH_TEXTURE_MODE_ARB:
781af69d88dSmrg   case GL_DEPTH_STENCIL_TEXTURE_MODE:
7823464ebd5Sriastradh   case GL_TEXTURE_SRGB_DECODE_EXT:
7833464ebd5Sriastradh   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
784c1f859d4Smrg      {
785c1f859d4Smrg         /* convert float param to int */
7864a49301eSmrg         GLint p[4];
7874a49301eSmrg         p[0] = (GLint) params[0];
7884a49301eSmrg         p[1] = p[2] = p[3] = 0;
7894a49301eSmrg         need_update = set_tex_parameteri(ctx, texObj, pname, p);
790c1f859d4Smrg      }
791c1f859d4Smrg      break;
792c1f859d4Smrg   case GL_TEXTURE_CROP_RECT_OES:
793c1f859d4Smrg      {
794c1f859d4Smrg         /* convert float params to int */
795c1f859d4Smrg         GLint iparams[4];
796c1f859d4Smrg         iparams[0] = (GLint) params[0];
797c1f859d4Smrg         iparams[1] = (GLint) params[1];
798c1f859d4Smrg         iparams[2] = (GLint) params[2];
799c1f859d4Smrg         iparams[3] = (GLint) params[3];
8004a49301eSmrg         need_update = set_tex_parameteri(ctx, texObj, pname, iparams);
801c1f859d4Smrg      }
802c1f859d4Smrg      break;
803af69d88dSmrg   case GL_TEXTURE_SWIZZLE_R_EXT:
804af69d88dSmrg   case GL_TEXTURE_SWIZZLE_G_EXT:
805af69d88dSmrg   case GL_TEXTURE_SWIZZLE_B_EXT:
806af69d88dSmrg   case GL_TEXTURE_SWIZZLE_A_EXT:
807af69d88dSmrg   case GL_TEXTURE_SWIZZLE_RGBA_EXT:
808af69d88dSmrg      {
809af69d88dSmrg         GLint p[4] = {0, 0, 0, 0};
810af69d88dSmrg         p[0] = (GLint) params[0];
811af69d88dSmrg         if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT) {
812af69d88dSmrg            p[1] = (GLint) params[1];
813af69d88dSmrg            p[2] = (GLint) params[2];
814af69d88dSmrg            p[3] = (GLint) params[3];
815af69d88dSmrg         }
816af69d88dSmrg         need_update = set_tex_parameteri(ctx, texObj, pname, p);
817af69d88dSmrg      }
818af69d88dSmrg      break;
819c1f859d4Smrg   default:
820c1f859d4Smrg      /* this will generate an error if pname is illegal */
821c1f859d4Smrg      need_update = set_tex_parameterf(ctx, texObj, pname, params);
822c1f859d4Smrg   }
823c1f859d4Smrg
824c1f859d4Smrg   if (ctx->Driver.TexParameter && need_update) {
825af69d88dSmrg      ctx->Driver.TexParameter(ctx, texObj, pname, params);
826c1f859d4Smrg   }
827c1f859d4Smrg}
828c1f859d4Smrg
829c1f859d4Smrg
830c1f859d4Smrgvoid GLAPIENTRY
831c1f859d4Smrg_mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
832c1f859d4Smrg{
833c1f859d4Smrg   GLboolean need_update;
834c1f859d4Smrg   struct gl_texture_object *texObj;
835c1f859d4Smrg   GET_CURRENT_CONTEXT(ctx);
836c1f859d4Smrg
837cdc920a0Smrg   texObj = get_texobj(ctx, target, GL_FALSE);
838c1f859d4Smrg   if (!texObj)
839c1f859d4Smrg      return;
840c1f859d4Smrg
841c1f859d4Smrg   switch (pname) {
842c1f859d4Smrg   case GL_TEXTURE_MIN_LOD:
843c1f859d4Smrg   case GL_TEXTURE_MAX_LOD:
844c1f859d4Smrg   case GL_TEXTURE_PRIORITY:
845c1f859d4Smrg   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
846c1f859d4Smrg   case GL_TEXTURE_LOD_BIAS:
8474a49301eSmrg   case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
848c1f859d4Smrg      {
8494a49301eSmrg         GLfloat fparam[4];
8504a49301eSmrg         fparam[0] = (GLfloat) param;
8514a49301eSmrg         fparam[1] = fparam[2] = fparam[3] = 0.0F;
852c1f859d4Smrg         /* convert int param to float */
8534a49301eSmrg         need_update = set_tex_parameterf(ctx, texObj, pname, fparam);
854c1f859d4Smrg      }
855c1f859d4Smrg      break;
856c1f859d4Smrg   default:
857c1f859d4Smrg      /* this will generate an error if pname is illegal */
8584a49301eSmrg      {
8594a49301eSmrg         GLint iparam[4];
8604a49301eSmrg         iparam[0] = param;
8614a49301eSmrg         iparam[1] = iparam[2] = iparam[3] = 0;
8624a49301eSmrg         need_update = set_tex_parameteri(ctx, texObj, pname, iparam);
8634a49301eSmrg      }
864c1f859d4Smrg   }
865c1f859d4Smrg
866c1f859d4Smrg   if (ctx->Driver.TexParameter && need_update) {
867c1f859d4Smrg      GLfloat fparam = (GLfloat) param;
868af69d88dSmrg      ctx->Driver.TexParameter(ctx, texObj, pname, &fparam);
869c1f859d4Smrg   }
870c1f859d4Smrg}
871c1f859d4Smrg
872c1f859d4Smrg
873c1f859d4Smrgvoid GLAPIENTRY
874c1f859d4Smrg_mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
875c1f859d4Smrg{
876c1f859d4Smrg   GLboolean need_update;
877c1f859d4Smrg   struct gl_texture_object *texObj;
878c1f859d4Smrg   GET_CURRENT_CONTEXT(ctx);
879c1f859d4Smrg
880cdc920a0Smrg   texObj = get_texobj(ctx, target, GL_FALSE);
881c1f859d4Smrg   if (!texObj)
882c1f859d4Smrg      return;
883c1f859d4Smrg
884c1f859d4Smrg   switch (pname) {
885c1f859d4Smrg   case GL_TEXTURE_BORDER_COLOR:
886c1f859d4Smrg      {
887c1f859d4Smrg         /* convert int params to float */
888c1f859d4Smrg         GLfloat fparams[4];
889c1f859d4Smrg         fparams[0] = INT_TO_FLOAT(params[0]);
890c1f859d4Smrg         fparams[1] = INT_TO_FLOAT(params[1]);
891c1f859d4Smrg         fparams[2] = INT_TO_FLOAT(params[2]);
892c1f859d4Smrg         fparams[3] = INT_TO_FLOAT(params[3]);
893c1f859d4Smrg         need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
894c1f859d4Smrg      }
895c1f859d4Smrg      break;
896c1f859d4Smrg   case GL_TEXTURE_MIN_LOD:
897c1f859d4Smrg   case GL_TEXTURE_MAX_LOD:
898c1f859d4Smrg   case GL_TEXTURE_PRIORITY:
899c1f859d4Smrg   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
900c1f859d4Smrg   case GL_TEXTURE_LOD_BIAS:
9014a49301eSmrg   case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
902c1f859d4Smrg      {
903c1f859d4Smrg         /* convert int param to float */
9044a49301eSmrg         GLfloat fparams[4];
9054a49301eSmrg         fparams[0] = (GLfloat) params[0];
9064a49301eSmrg         fparams[1] = fparams[2] = fparams[3] = 0.0F;
9074a49301eSmrg         need_update = set_tex_parameterf(ctx, texObj, pname, fparams);
908c1f859d4Smrg      }
909c1f859d4Smrg      break;
910c1f859d4Smrg   default:
911c1f859d4Smrg      /* this will generate an error if pname is illegal */
912c1f859d4Smrg      need_update = set_tex_parameteri(ctx, texObj, pname, params);
913c1f859d4Smrg   }
914c1f859d4Smrg
915c1f859d4Smrg   if (ctx->Driver.TexParameter && need_update) {
916c1f859d4Smrg      GLfloat fparams[4];
917c1f859d4Smrg      fparams[0] = INT_TO_FLOAT(params[0]);
918c1f859d4Smrg      if (pname == GL_TEXTURE_BORDER_COLOR ||
919c1f859d4Smrg          pname == GL_TEXTURE_CROP_RECT_OES) {
920c1f859d4Smrg         fparams[1] = INT_TO_FLOAT(params[1]);
921c1f859d4Smrg         fparams[2] = INT_TO_FLOAT(params[2]);
922c1f859d4Smrg         fparams[3] = INT_TO_FLOAT(params[3]);
923c1f859d4Smrg      }
924af69d88dSmrg      ctx->Driver.TexParameter(ctx, texObj, pname, fparams);
925c1f859d4Smrg   }
926c1f859d4Smrg}
927c1f859d4Smrg
928c1f859d4Smrg
929cdc920a0Smrg/**
930cdc920a0Smrg * Set tex parameter to integer value(s).  Primarily intended to set
931cdc920a0Smrg * integer-valued texture border color (for integer-valued textures).
932cdc920a0Smrg * New in GL 3.0.
933cdc920a0Smrg */
934cdc920a0Smrgvoid GLAPIENTRY
935cdc920a0Smrg_mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params)
936cdc920a0Smrg{
937cdc920a0Smrg   struct gl_texture_object *texObj;
938cdc920a0Smrg   GET_CURRENT_CONTEXT(ctx);
939cdc920a0Smrg
940cdc920a0Smrg   texObj = get_texobj(ctx, target, GL_FALSE);
941cdc920a0Smrg   if (!texObj)
942cdc920a0Smrg      return;
943cdc920a0Smrg
944cdc920a0Smrg   switch (pname) {
945cdc920a0Smrg   case GL_TEXTURE_BORDER_COLOR:
946cdc920a0Smrg      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
947cdc920a0Smrg      /* set the integer-valued border color */
9483464ebd5Sriastradh      COPY_4V(texObj->Sampler.BorderColor.i, params);
949cdc920a0Smrg      break;
950cdc920a0Smrg   default:
951cdc920a0Smrg      _mesa_TexParameteriv(target, pname, params);
952cdc920a0Smrg      break;
953cdc920a0Smrg   }
954cdc920a0Smrg   /* XXX no driver hook for TexParameterIiv() yet */
955cdc920a0Smrg}
956cdc920a0Smrg
957cdc920a0Smrg
958cdc920a0Smrg/**
959cdc920a0Smrg * Set tex parameter to unsigned integer value(s).  Primarily intended to set
960cdc920a0Smrg * uint-valued texture border color (for integer-valued textures).
961cdc920a0Smrg * New in GL 3.0
962cdc920a0Smrg */
963cdc920a0Smrgvoid GLAPIENTRY
964cdc920a0Smrg_mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
965cdc920a0Smrg{
966cdc920a0Smrg   struct gl_texture_object *texObj;
967cdc920a0Smrg   GET_CURRENT_CONTEXT(ctx);
968cdc920a0Smrg
969cdc920a0Smrg   texObj = get_texobj(ctx, target, GL_FALSE);
970cdc920a0Smrg   if (!texObj)
971cdc920a0Smrg      return;
972cdc920a0Smrg
973cdc920a0Smrg   switch (pname) {
974cdc920a0Smrg   case GL_TEXTURE_BORDER_COLOR:
975cdc920a0Smrg      FLUSH_VERTICES(ctx, _NEW_TEXTURE);
976cdc920a0Smrg      /* set the unsigned integer-valued border color */
9773464ebd5Sriastradh      COPY_4V(texObj->Sampler.BorderColor.ui, params);
978cdc920a0Smrg      break;
979cdc920a0Smrg   default:
980cdc920a0Smrg      _mesa_TexParameteriv(target, pname, (const GLint *) params);
981cdc920a0Smrg      break;
982cdc920a0Smrg   }
983cdc920a0Smrg   /* XXX no driver hook for TexParameterIuiv() yet */
984cdc920a0Smrg}
985cdc920a0Smrg
986cdc920a0Smrg
987af69d88dSmrgstatic GLboolean
988af69d88dSmrglegal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target)
989c1f859d4Smrg{
990af69d88dSmrg   switch (target) {
991af69d88dSmrg   case GL_TEXTURE_1D:
992af69d88dSmrg   case GL_PROXY_TEXTURE_1D:
993af69d88dSmrg   case GL_TEXTURE_2D:
994af69d88dSmrg   case GL_PROXY_TEXTURE_2D:
995af69d88dSmrg   case GL_TEXTURE_3D:
996af69d88dSmrg   case GL_PROXY_TEXTURE_3D:
997af69d88dSmrg      return GL_TRUE;
998af69d88dSmrg   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
999af69d88dSmrg   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
1000af69d88dSmrg   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
1001af69d88dSmrg   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
1002af69d88dSmrg   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
1003af69d88dSmrg   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
1004af69d88dSmrg   case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
1005af69d88dSmrg      return ctx->Extensions.ARB_texture_cube_map;
1006af69d88dSmrg   case GL_TEXTURE_CUBE_MAP_ARRAY_ARB:
1007af69d88dSmrg   case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB:
1008af69d88dSmrg      return ctx->Extensions.ARB_texture_cube_map_array;
1009af69d88dSmrg   case GL_TEXTURE_RECTANGLE_NV:
1010af69d88dSmrg   case GL_PROXY_TEXTURE_RECTANGLE_NV:
1011af69d88dSmrg      return ctx->Extensions.NV_texture_rectangle;
1012af69d88dSmrg   case GL_TEXTURE_1D_ARRAY_EXT:
1013af69d88dSmrg   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
1014af69d88dSmrg   case GL_TEXTURE_2D_ARRAY_EXT:
1015af69d88dSmrg   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1016af69d88dSmrg      return ctx->Extensions.EXT_texture_array;
1017af69d88dSmrg   case GL_TEXTURE_BUFFER:
1018af69d88dSmrg      /* GetTexLevelParameter accepts GL_TEXTURE_BUFFER in GL 3.1+ contexts,
1019af69d88dSmrg       * but not in earlier versions that expose ARB_texture_buffer_object.
1020af69d88dSmrg       *
1021af69d88dSmrg       * From the ARB_texture_buffer_object spec:
1022af69d88dSmrg       * "(7) Do buffer textures support texture parameters (TexParameter) or
1023af69d88dSmrg       *      queries (GetTexParameter, GetTexLevelParameter, GetTexImage)?
1024af69d88dSmrg       *
1025af69d88dSmrg       *    RESOLVED:  No. [...] Note that the spec edits above don't add
1026af69d88dSmrg       *    explicit error language for any of these cases.  That is because
1027af69d88dSmrg       *    each of the functions enumerate the set of valid <target>
1028af69d88dSmrg       *    parameters.  Not editing the spec to allow TEXTURE_BUFFER_ARB in
1029af69d88dSmrg       *    these cases means that target is not legal, and an INVALID_ENUM
1030af69d88dSmrg       *    error should be generated."
1031af69d88dSmrg       *
1032af69d88dSmrg       * From the OpenGL 3.1 spec:
1033af69d88dSmrg       * "target may also be TEXTURE_BUFFER, indicating the texture buffer."
1034af69d88dSmrg       */
1035af69d88dSmrg      return ctx->API == API_OPENGL_CORE && ctx->Version >= 31;
1036af69d88dSmrg   case GL_TEXTURE_2D_MULTISAMPLE:
1037af69d88dSmrg   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
1038af69d88dSmrg   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
1039af69d88dSmrg   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
1040af69d88dSmrg      return ctx->Extensions.ARB_texture_multisample;
1041af69d88dSmrg   default:
1042af69d88dSmrg      return GL_FALSE;
1043af69d88dSmrg   }
1044c1f859d4Smrg}
1045c1f859d4Smrg
1046c1f859d4Smrg
1047af69d88dSmrgstatic void
1048af69d88dSmrgget_tex_level_parameter_image(struct gl_context *ctx,
1049af69d88dSmrg                              const struct gl_texture_object *texObj,
1050af69d88dSmrg                              GLenum target, GLint level,
1051af69d88dSmrg                              GLenum pname, GLint *params)
1052c1f859d4Smrg{
1053c1f859d4Smrg   const struct gl_texture_image *img = NULL;
1054af69d88dSmrg   struct gl_texture_image dummy_image;
1055af69d88dSmrg   mesa_format texFormat;
1056c1f859d4Smrg
1057c1f859d4Smrg   img = _mesa_select_tex_image(ctx, texObj, target, level);
1058af69d88dSmrg   if (!img || img->TexFormat == MESA_FORMAT_NONE) {
1059af69d88dSmrg      /* In case of undefined texture image return the default values.
1060af69d88dSmrg       *
1061af69d88dSmrg       * From OpenGL 4.0 spec, page 398:
1062af69d88dSmrg       *    "The initial internal format of a texel array is RGBA
1063af69d88dSmrg       *     instead of 1. TEXTURE_COMPONENTS is deprecated; always
1064af69d88dSmrg       *     use TEXTURE_INTERNAL_FORMAT."
1065af69d88dSmrg       */
1066af69d88dSmrg      memset(&dummy_image, 0, sizeof(dummy_image));
1067af69d88dSmrg      dummy_image.TexFormat = MESA_FORMAT_NONE;
1068af69d88dSmrg      dummy_image.InternalFormat = GL_RGBA;
1069af69d88dSmrg      dummy_image._BaseFormat = GL_NONE;
1070af69d88dSmrg
1071af69d88dSmrg      img = &dummy_image;
1072c1f859d4Smrg   }
1073c1f859d4Smrg
10744a49301eSmrg   texFormat = img->TexFormat;
10754a49301eSmrg
1076c1f859d4Smrg   switch (pname) {
1077c1f859d4Smrg      case GL_TEXTURE_WIDTH:
1078c1f859d4Smrg         *params = img->Width;
1079c1f859d4Smrg         break;
1080c1f859d4Smrg      case GL_TEXTURE_HEIGHT:
1081c1f859d4Smrg         *params = img->Height;
1082c1f859d4Smrg         break;
1083c1f859d4Smrg      case GL_TEXTURE_DEPTH:
1084c1f859d4Smrg         *params = img->Depth;
1085c1f859d4Smrg         break;
1086c1f859d4Smrg      case GL_TEXTURE_INTERNAL_FORMAT:
10873464ebd5Sriastradh         if (_mesa_is_format_compressed(texFormat)) {
10884a49301eSmrg            /* need to return the actual compressed format */
10893464ebd5Sriastradh            *params = _mesa_compressed_format_to_glenum(ctx, texFormat);
10904a49301eSmrg         }
10914a49301eSmrg         else {
10923464ebd5Sriastradh	    /* If the true internal format is not compressed but the user
10933464ebd5Sriastradh	     * requested a generic compressed format, we have to return the
10943464ebd5Sriastradh	     * generic base format that matches.
10953464ebd5Sriastradh	     *
10963464ebd5Sriastradh	     * From page 119 (page 129 of the PDF) of the OpenGL 1.3 spec:
10973464ebd5Sriastradh	     *
10983464ebd5Sriastradh	     *     "If no specific compressed format is available,
10993464ebd5Sriastradh	     *     internalformat is instead replaced by the corresponding base
11003464ebd5Sriastradh	     *     internal format."
11013464ebd5Sriastradh	     *
11023464ebd5Sriastradh	     * Otherwise just return the user's requested internal format
11033464ebd5Sriastradh	     */
11043464ebd5Sriastradh	    const GLenum f =
11053464ebd5Sriastradh	       _mesa_gl_compressed_format_base_format(img->InternalFormat);
11063464ebd5Sriastradh
11073464ebd5Sriastradh	    *params = (f != 0) ? f : img->InternalFormat;
11083464ebd5Sriastradh	 }
1109c1f859d4Smrg         break;
1110c1f859d4Smrg      case GL_TEXTURE_BORDER:
1111af69d88dSmrg         if (ctx->API != API_OPENGL_COMPAT)
1112af69d88dSmrg            goto invalid_pname;
1113c1f859d4Smrg         *params = img->Border;
1114c1f859d4Smrg         break;
1115c1f859d4Smrg      case GL_TEXTURE_RED_SIZE:
1116c1f859d4Smrg      case GL_TEXTURE_GREEN_SIZE:
1117c1f859d4Smrg      case GL_TEXTURE_BLUE_SIZE:
1118c1f859d4Smrg      case GL_TEXTURE_ALPHA_SIZE:
1119af69d88dSmrg         if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
11204a49301eSmrg            *params = _mesa_get_format_bits(texFormat, pname);
1121c1f859d4Smrg         else
1122c1f859d4Smrg            *params = 0;
1123c1f859d4Smrg         break;
1124c1f859d4Smrg      case GL_TEXTURE_INTENSITY_SIZE:
1125c1f859d4Smrg      case GL_TEXTURE_LUMINANCE_SIZE:
1126af69d88dSmrg         if (ctx->API != API_OPENGL_COMPAT)
1127af69d88dSmrg            goto invalid_pname;
1128af69d88dSmrg         if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) {
11294a49301eSmrg            *params = _mesa_get_format_bits(texFormat, pname);
11304a49301eSmrg            if (*params == 0) {
1131af69d88dSmrg               /* intensity or luminance is probably stored as RGB[A] */
1132af69d88dSmrg               *params = MIN2(_mesa_get_format_bits(texFormat,
1133af69d88dSmrg                                                    GL_TEXTURE_RED_SIZE),
1134af69d88dSmrg                              _mesa_get_format_bits(texFormat,
1135af69d88dSmrg                                                    GL_TEXTURE_GREEN_SIZE));
11364a49301eSmrg            }
11374a49301eSmrg         }
1138af69d88dSmrg         else {
1139c1f859d4Smrg            *params = 0;
1140af69d88dSmrg         }
1141c1f859d4Smrg         break;
1142c1f859d4Smrg      case GL_TEXTURE_DEPTH_SIZE_ARB:
1143af69d88dSmrg         if (!ctx->Extensions.ARB_depth_texture)
11443464ebd5Sriastradh            goto invalid_pname;
1145af69d88dSmrg         *params = _mesa_get_format_bits(texFormat, pname);
1146c1f859d4Smrg         break;
1147af69d88dSmrg      case GL_TEXTURE_STENCIL_SIZE:
1148af69d88dSmrg         *params = _mesa_get_format_bits(texFormat, pname);
11493464ebd5Sriastradh         break;
11503464ebd5Sriastradh      case GL_TEXTURE_SHARED_SIZE:
1151af69d88dSmrg         if (ctx->Version < 30 &&
1152af69d88dSmrg             !ctx->Extensions.EXT_texture_shared_exponent)
11533464ebd5Sriastradh            goto invalid_pname;
1154af69d88dSmrg         *params = texFormat == MESA_FORMAT_R9G9B9E5_FLOAT ? 5 : 0;
1155c1f859d4Smrg         break;
1156c1f859d4Smrg
1157c1f859d4Smrg      /* GL_ARB_texture_compression */
1158c1f859d4Smrg      case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
11593464ebd5Sriastradh	 if (_mesa_is_format_compressed(texFormat) &&
11603464ebd5Sriastradh             !_mesa_is_proxy_texture(target)) {
11614a49301eSmrg            *params = _mesa_format_image_size(texFormat, img->Width,
11624a49301eSmrg                                              img->Height, img->Depth);
11634a49301eSmrg	 }
11644a49301eSmrg	 else {
11654a49301eSmrg	    _mesa_error(ctx, GL_INVALID_OPERATION,
11664a49301eSmrg			"glGetTexLevelParameter[if]v(pname)");
11674a49301eSmrg	 }
1168c1f859d4Smrg         break;
1169c1f859d4Smrg      case GL_TEXTURE_COMPRESSED:
11703464ebd5Sriastradh         *params = (GLint) _mesa_is_format_compressed(texFormat);
1171c1f859d4Smrg         break;
1172c1f859d4Smrg
1173c1f859d4Smrg      /* GL_ARB_texture_float */
1174af69d88dSmrg      case GL_TEXTURE_LUMINANCE_TYPE_ARB:
1175af69d88dSmrg      case GL_TEXTURE_INTENSITY_TYPE_ARB:
1176af69d88dSmrg         if (ctx->API != API_OPENGL_COMPAT)
11773464ebd5Sriastradh            goto invalid_pname;
1178af69d88dSmrg         /* FALLTHROUGH */
1179af69d88dSmrg      case GL_TEXTURE_RED_TYPE_ARB:
1180c1f859d4Smrg      case GL_TEXTURE_GREEN_TYPE_ARB:
1181af69d88dSmrg      case GL_TEXTURE_BLUE_TYPE_ARB:
1182af69d88dSmrg      case GL_TEXTURE_ALPHA_TYPE_ARB:
1183af69d88dSmrg      case GL_TEXTURE_DEPTH_TYPE_ARB:
1184af69d88dSmrg         if (!ctx->Extensions.ARB_texture_float)
11853464ebd5Sriastradh            goto invalid_pname;
1186af69d88dSmrg	 if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
1187af69d88dSmrg	    *params = _mesa_get_format_datatype(texFormat);
1188af69d88dSmrg	 else
1189af69d88dSmrg	    *params = GL_NONE;
1190c1f859d4Smrg         break;
1191af69d88dSmrg
1192af69d88dSmrg      /* GL_ARB_texture_multisample */
1193af69d88dSmrg      case GL_TEXTURE_SAMPLES:
1194af69d88dSmrg         if (!ctx->Extensions.ARB_texture_multisample)
11953464ebd5Sriastradh            goto invalid_pname;
1196af69d88dSmrg         *params = img->NumSamples;
1197c1f859d4Smrg         break;
1198af69d88dSmrg
1199af69d88dSmrg      case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
1200af69d88dSmrg         if (!ctx->Extensions.ARB_texture_multisample)
12013464ebd5Sriastradh            goto invalid_pname;
1202af69d88dSmrg         *params = img->FixedSampleLocations;
1203c1f859d4Smrg         break;
1204af69d88dSmrg
1205af69d88dSmrg      default:
1206af69d88dSmrg         goto invalid_pname;
1207af69d88dSmrg   }
1208af69d88dSmrg
1209af69d88dSmrg   /* no error if we get here */
1210af69d88dSmrg   return;
1211af69d88dSmrg
1212af69d88dSmrginvalid_pname:
1213af69d88dSmrg   _mesa_error(ctx, GL_INVALID_ENUM,
1214af69d88dSmrg               "glGetTexLevelParameter[if]v(pname=%s)",
1215af69d88dSmrg               _mesa_lookup_enum_by_nr(pname));
1216af69d88dSmrg}
1217af69d88dSmrg
1218af69d88dSmrg
1219af69d88dSmrgstatic void
1220af69d88dSmrgget_tex_level_parameter_buffer(struct gl_context *ctx,
1221af69d88dSmrg                               const struct gl_texture_object *texObj,
1222af69d88dSmrg                               GLenum pname, GLint *params)
1223af69d88dSmrg{
1224af69d88dSmrg   const struct gl_buffer_object *bo = texObj->BufferObject;
1225af69d88dSmrg   mesa_format texFormat = texObj->_BufferObjectFormat;
1226af69d88dSmrg   GLenum internalFormat = texObj->BufferObjectFormat;
1227af69d88dSmrg   GLenum baseFormat = _mesa_get_format_base_format(texFormat);
1228af69d88dSmrg
1229af69d88dSmrg   if (!bo) {
1230af69d88dSmrg      /* undefined texture buffer object */
1231af69d88dSmrg      *params = pname == GL_TEXTURE_COMPONENTS ? 1 : 0;
1232af69d88dSmrg      return;
1233af69d88dSmrg   }
1234af69d88dSmrg
1235af69d88dSmrg   switch (pname) {
1236af69d88dSmrg      case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
1237af69d88dSmrg         *params = bo->Name;
1238af69d88dSmrg         break;
1239af69d88dSmrg      case GL_TEXTURE_WIDTH:
1240af69d88dSmrg         *params = bo->Size;
1241af69d88dSmrg         break;
1242af69d88dSmrg      case GL_TEXTURE_HEIGHT:
1243af69d88dSmrg      case GL_TEXTURE_DEPTH:
1244af69d88dSmrg      case GL_TEXTURE_BORDER:
1245af69d88dSmrg      case GL_TEXTURE_SHARED_SIZE:
1246af69d88dSmrg      case GL_TEXTURE_COMPRESSED:
1247af69d88dSmrg         *params = 0;
1248af69d88dSmrg         break;
1249af69d88dSmrg      case GL_TEXTURE_INTERNAL_FORMAT:
1250af69d88dSmrg         *params = internalFormat;
1251af69d88dSmrg         break;
1252af69d88dSmrg      case GL_TEXTURE_RED_SIZE:
1253af69d88dSmrg      case GL_TEXTURE_GREEN_SIZE:
1254af69d88dSmrg      case GL_TEXTURE_BLUE_SIZE:
1255af69d88dSmrg      case GL_TEXTURE_ALPHA_SIZE:
1256af69d88dSmrg         if (_mesa_base_format_has_channel(baseFormat, pname))
1257af69d88dSmrg            *params = _mesa_get_format_bits(texFormat, pname);
1258af69d88dSmrg         else
1259af69d88dSmrg            *params = 0;
1260af69d88dSmrg         break;
1261af69d88dSmrg      case GL_TEXTURE_INTENSITY_SIZE:
1262af69d88dSmrg      case GL_TEXTURE_LUMINANCE_SIZE:
1263af69d88dSmrg         if (_mesa_base_format_has_channel(baseFormat, pname)) {
1264af69d88dSmrg            *params = _mesa_get_format_bits(texFormat, pname);
1265af69d88dSmrg            if (*params == 0) {
1266af69d88dSmrg               /* intensity or luminance is probably stored as RGB[A] */
1267af69d88dSmrg               *params = MIN2(_mesa_get_format_bits(texFormat,
1268af69d88dSmrg                                                    GL_TEXTURE_RED_SIZE),
1269af69d88dSmrg                              _mesa_get_format_bits(texFormat,
1270af69d88dSmrg                                                    GL_TEXTURE_GREEN_SIZE));
1271af69d88dSmrg            }
1272af69d88dSmrg         } else {
1273af69d88dSmrg            *params = 0;
1274c1f859d4Smrg         }
1275af69d88dSmrg         break;
1276af69d88dSmrg      case GL_TEXTURE_DEPTH_SIZE_ARB:
1277af69d88dSmrg      case GL_TEXTURE_STENCIL_SIZE_EXT:
1278af69d88dSmrg         *params = _mesa_get_format_bits(texFormat, pname);
1279af69d88dSmrg         break;
1280af69d88dSmrg
1281af69d88dSmrg      /* GL_ARB_texture_buffer_range */
1282af69d88dSmrg      case GL_TEXTURE_BUFFER_OFFSET:
1283af69d88dSmrg         if (!ctx->Extensions.ARB_texture_buffer_range)
12843464ebd5Sriastradh            goto invalid_pname;
1285af69d88dSmrg         *params = texObj->BufferOffset;
1286c1f859d4Smrg         break;
1287af69d88dSmrg      case GL_TEXTURE_BUFFER_SIZE:
1288af69d88dSmrg         if (!ctx->Extensions.ARB_texture_buffer_range)
12893464ebd5Sriastradh            goto invalid_pname;
1290af69d88dSmrg         *params = (texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize;
1291c1f859d4Smrg         break;
1292af69d88dSmrg
1293af69d88dSmrg      /* GL_ARB_texture_compression */
1294af69d88dSmrg      case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
1295af69d88dSmrg         /* Always illegal for GL_TEXTURE_BUFFER */
1296af69d88dSmrg         _mesa_error(ctx, GL_INVALID_OPERATION,
1297af69d88dSmrg                     "glGetTexLevelParameter[if]v(pname)");
1298af69d88dSmrg         break;
1299af69d88dSmrg
1300af69d88dSmrg      /* GL_ARB_texture_float */
1301af69d88dSmrg      case GL_TEXTURE_RED_TYPE_ARB:
1302af69d88dSmrg      case GL_TEXTURE_GREEN_TYPE_ARB:
1303af69d88dSmrg      case GL_TEXTURE_BLUE_TYPE_ARB:
1304af69d88dSmrg      case GL_TEXTURE_ALPHA_TYPE_ARB:
1305af69d88dSmrg      case GL_TEXTURE_LUMINANCE_TYPE_ARB:
1306af69d88dSmrg      case GL_TEXTURE_INTENSITY_TYPE_ARB:
1307c1f859d4Smrg      case GL_TEXTURE_DEPTH_TYPE_ARB:
1308af69d88dSmrg         if (!ctx->Extensions.ARB_texture_float)
13093464ebd5Sriastradh            goto invalid_pname;
1310af69d88dSmrg         if (_mesa_base_format_has_channel(baseFormat, pname))
1311af69d88dSmrg            *params = _mesa_get_format_datatype(texFormat);
1312af69d88dSmrg         else
1313af69d88dSmrg            *params = GL_NONE;
1314c1f859d4Smrg         break;
1315c1f859d4Smrg
1316c1f859d4Smrg      default:
13173464ebd5Sriastradh         goto invalid_pname;
1318c1f859d4Smrg   }
1319c1f859d4Smrg
13203464ebd5Sriastradh   /* no error if we get here */
13213464ebd5Sriastradh   return;
13223464ebd5Sriastradh
13233464ebd5Sriastradhinvalid_pname:
13243464ebd5Sriastradh   _mesa_error(ctx, GL_INVALID_ENUM,
13253464ebd5Sriastradh               "glGetTexLevelParameter[if]v(pname=%s)",
13263464ebd5Sriastradh               _mesa_lookup_enum_by_nr(pname));
1327c1f859d4Smrg}
1328c1f859d4Smrg
1329c1f859d4Smrg
1330af69d88dSmrgvoid GLAPIENTRY
1331af69d88dSmrg_mesa_GetTexLevelParameterfv( GLenum target, GLint level,
1332af69d88dSmrg                              GLenum pname, GLfloat *params )
1333af69d88dSmrg{
1334af69d88dSmrg   GLint iparam;
1335af69d88dSmrg   _mesa_GetTexLevelParameteriv( target, level, pname, &iparam );
1336af69d88dSmrg   *params = (GLfloat) iparam;
1337af69d88dSmrg}
1338af69d88dSmrg
1339af69d88dSmrg
1340af69d88dSmrgvoid GLAPIENTRY
1341af69d88dSmrg_mesa_GetTexLevelParameteriv( GLenum target, GLint level,
1342af69d88dSmrg                              GLenum pname, GLint *params )
1343af69d88dSmrg{
1344af69d88dSmrg   struct gl_texture_object *texObj;
1345af69d88dSmrg   GLint maxLevels;
1346af69d88dSmrg   GET_CURRENT_CONTEXT(ctx);
1347af69d88dSmrg
1348af69d88dSmrg   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
1349af69d88dSmrg      _mesa_error(ctx, GL_INVALID_OPERATION,
1350af69d88dSmrg                  "glGetTexLevelParameteriv(current unit)");
1351af69d88dSmrg      return;
1352af69d88dSmrg   }
1353af69d88dSmrg
1354af69d88dSmrg   if (!legal_get_tex_level_parameter_target(ctx, target)) {
1355af69d88dSmrg      _mesa_error(ctx, GL_INVALID_ENUM,
1356af69d88dSmrg                  "glGetTexLevelParameter[if]v(target=0x%x)", target);
1357af69d88dSmrg      return;
1358af69d88dSmrg   }
1359af69d88dSmrg
1360af69d88dSmrg   maxLevels = _mesa_max_texture_levels(ctx, target);
1361af69d88dSmrg   assert(maxLevels != 0);
1362af69d88dSmrg
1363af69d88dSmrg   if (level < 0 || level >= maxLevels) {
1364af69d88dSmrg      _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" );
1365af69d88dSmrg      return;
1366af69d88dSmrg   }
1367af69d88dSmrg
1368af69d88dSmrg   texObj = _mesa_get_current_tex_object(ctx, target);
1369af69d88dSmrg
1370af69d88dSmrg   if (target == GL_TEXTURE_BUFFER)
1371af69d88dSmrg      get_tex_level_parameter_buffer(ctx, texObj, pname, params);
1372af69d88dSmrg   else
1373af69d88dSmrg      get_tex_level_parameter_image(ctx, texObj, target, level, pname, params);
1374af69d88dSmrg}
1375af69d88dSmrg
1376c1f859d4Smrg
1377c1f859d4Smrgvoid GLAPIENTRY
1378c1f859d4Smrg_mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
1379c1f859d4Smrg{
1380c1f859d4Smrg   struct gl_texture_object *obj;
1381c1f859d4Smrg   GET_CURRENT_CONTEXT(ctx);
1382c1f859d4Smrg
1383cdc920a0Smrg   obj = get_texobj(ctx, target, GL_TRUE);
1384cdc920a0Smrg   if (!obj)
1385c1f859d4Smrg      return;
1386c1f859d4Smrg
1387af69d88dSmrg   _mesa_lock_context_textures(ctx);
1388c1f859d4Smrg   switch (pname) {
1389c1f859d4Smrg      case GL_TEXTURE_MAG_FILTER:
13903464ebd5Sriastradh	 *params = ENUM_TO_FLOAT(obj->Sampler.MagFilter);
1391c1f859d4Smrg	 break;
1392c1f859d4Smrg      case GL_TEXTURE_MIN_FILTER:
13933464ebd5Sriastradh         *params = ENUM_TO_FLOAT(obj->Sampler.MinFilter);
1394c1f859d4Smrg         break;
1395c1f859d4Smrg      case GL_TEXTURE_WRAP_S:
13963464ebd5Sriastradh         *params = ENUM_TO_FLOAT(obj->Sampler.WrapS);
1397c1f859d4Smrg         break;
1398c1f859d4Smrg      case GL_TEXTURE_WRAP_T:
13993464ebd5Sriastradh         *params = ENUM_TO_FLOAT(obj->Sampler.WrapT);
1400c1f859d4Smrg         break;
1401c1f859d4Smrg      case GL_TEXTURE_WRAP_R:
14023464ebd5Sriastradh         *params = ENUM_TO_FLOAT(obj->Sampler.WrapR);
1403c1f859d4Smrg         break;
1404c1f859d4Smrg      case GL_TEXTURE_BORDER_COLOR:
1405af69d88dSmrg         if (!_mesa_is_desktop_gl(ctx))
1406af69d88dSmrg            goto invalid_pname;
1407af69d88dSmrg
1408af69d88dSmrg         if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
14093464ebd5Sriastradh            _mesa_update_state_locked(ctx);
1410af69d88dSmrg         if (_mesa_get_clamp_fragment_color(ctx)) {
14113464ebd5Sriastradh            params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
14123464ebd5Sriastradh            params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
14133464ebd5Sriastradh            params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
14143464ebd5Sriastradh            params[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
14153464ebd5Sriastradh         }
1416af69d88dSmrg         else {
14173464ebd5Sriastradh            params[0] = obj->Sampler.BorderColor.f[0];
14183464ebd5Sriastradh            params[1] = obj->Sampler.BorderColor.f[1];
14193464ebd5Sriastradh            params[2] = obj->Sampler.BorderColor.f[2];
14203464ebd5Sriastradh            params[3] = obj->Sampler.BorderColor.f[3];
14213464ebd5Sriastradh         }
1422c1f859d4Smrg         break;
1423c1f859d4Smrg      case GL_TEXTURE_RESIDENT:
1424af69d88dSmrg         if (ctx->API != API_OPENGL_COMPAT)
1425af69d88dSmrg            goto invalid_pname;
1426af69d88dSmrg
1427af69d88dSmrg         *params = 1.0F;
1428c1f859d4Smrg         break;
1429c1f859d4Smrg      case GL_TEXTURE_PRIORITY:
1430af69d88dSmrg         if (ctx->API != API_OPENGL_COMPAT)
1431af69d88dSmrg            goto invalid_pname;
1432af69d88dSmrg
1433c1f859d4Smrg         *params = obj->Priority;
1434c1f859d4Smrg         break;
1435c1f859d4Smrg      case GL_TEXTURE_MIN_LOD:
1436af69d88dSmrg         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1437af69d88dSmrg            goto invalid_pname;
1438af69d88dSmrg
14393464ebd5Sriastradh         *params = obj->Sampler.MinLod;
1440c1f859d4Smrg         break;
1441c1f859d4Smrg      case GL_TEXTURE_MAX_LOD:
1442af69d88dSmrg         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1443af69d88dSmrg            goto invalid_pname;
1444af69d88dSmrg
14453464ebd5Sriastradh         *params = obj->Sampler.MaxLod;
1446c1f859d4Smrg         break;
1447c1f859d4Smrg      case GL_TEXTURE_BASE_LEVEL:
1448af69d88dSmrg         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1449af69d88dSmrg            goto invalid_pname;
1450af69d88dSmrg
1451c1f859d4Smrg         *params = (GLfloat) obj->BaseLevel;
1452c1f859d4Smrg         break;
1453c1f859d4Smrg      case GL_TEXTURE_MAX_LEVEL:
1454c1f859d4Smrg         *params = (GLfloat) obj->MaxLevel;
1455c1f859d4Smrg         break;
1456c1f859d4Smrg      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1457af69d88dSmrg         if (!ctx->Extensions.EXT_texture_filter_anisotropic)
1458af69d88dSmrg            goto invalid_pname;
1459af69d88dSmrg         *params = obj->Sampler.MaxAnisotropy;
1460c1f859d4Smrg         break;
1461c1f859d4Smrg      case GL_GENERATE_MIPMAP_SGIS:
1462af69d88dSmrg         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1463af69d88dSmrg            goto invalid_pname;
1464af69d88dSmrg
14653464ebd5Sriastradh	 *params = (GLfloat) obj->GenerateMipmap;
1466c1f859d4Smrg         break;
1467c1f859d4Smrg      case GL_TEXTURE_COMPARE_MODE_ARB:
1468af69d88dSmrg         if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
1469af69d88dSmrg             && !_mesa_is_gles3(ctx))
1470af69d88dSmrg            goto invalid_pname;
1471af69d88dSmrg         *params = (GLfloat) obj->Sampler.CompareMode;
1472c1f859d4Smrg         break;
1473c1f859d4Smrg      case GL_TEXTURE_COMPARE_FUNC_ARB:
1474af69d88dSmrg         if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
1475af69d88dSmrg             && !_mesa_is_gles3(ctx))
1476af69d88dSmrg            goto invalid_pname;
1477af69d88dSmrg         *params = (GLfloat) obj->Sampler.CompareFunc;
1478c1f859d4Smrg         break;
1479c1f859d4Smrg      case GL_DEPTH_TEXTURE_MODE_ARB:
1480af69d88dSmrg         /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has
1481af69d88dSmrg          * never existed in OpenGL ES.
1482af69d88dSmrg          */
1483af69d88dSmrg         if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture)
1484af69d88dSmrg            goto invalid_pname;
1485af69d88dSmrg         *params = (GLfloat) obj->DepthMode;
1486af69d88dSmrg         break;
1487af69d88dSmrg      case GL_DEPTH_STENCIL_TEXTURE_MODE:
1488af69d88dSmrg         if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_stencil_texturing)
1489af69d88dSmrg            goto invalid_pname;
1490af69d88dSmrg         *params = (GLfloat)
1491af69d88dSmrg            (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT);
1492c1f859d4Smrg         break;
1493c1f859d4Smrg      case GL_TEXTURE_LOD_BIAS:
1494af69d88dSmrg         if (_mesa_is_gles(ctx))
1495af69d88dSmrg            goto invalid_pname;
1496af69d88dSmrg
1497af69d88dSmrg         *params = obj->Sampler.LodBias;
1498c1f859d4Smrg         break;
1499c1f859d4Smrg      case GL_TEXTURE_CROP_RECT_OES:
1500af69d88dSmrg         if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
1501af69d88dSmrg            goto invalid_pname;
1502af69d88dSmrg
1503af69d88dSmrg         params[0] = (GLfloat) obj->CropRect[0];
1504af69d88dSmrg         params[1] = (GLfloat) obj->CropRect[1];
1505af69d88dSmrg         params[2] = (GLfloat) obj->CropRect[2];
1506af69d88dSmrg         params[3] = (GLfloat) obj->CropRect[3];
1507c1f859d4Smrg         break;
15084a49301eSmrg
15094a49301eSmrg      case GL_TEXTURE_SWIZZLE_R_EXT:
15104a49301eSmrg      case GL_TEXTURE_SWIZZLE_G_EXT:
15114a49301eSmrg      case GL_TEXTURE_SWIZZLE_B_EXT:
15124a49301eSmrg      case GL_TEXTURE_SWIZZLE_A_EXT:
1513af69d88dSmrg         if ((!_mesa_is_desktop_gl(ctx)
1514af69d88dSmrg              || !ctx->Extensions.EXT_texture_swizzle)
1515af69d88dSmrg             && !_mesa_is_gles3(ctx))
1516af69d88dSmrg            goto invalid_pname;
1517af69d88dSmrg         *params = (GLfloat) obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
15184a49301eSmrg         break;
15194a49301eSmrg
15204a49301eSmrg      case GL_TEXTURE_SWIZZLE_RGBA_EXT:
1521af69d88dSmrg         if ((!_mesa_is_desktop_gl(ctx)
1522af69d88dSmrg              || !ctx->Extensions.EXT_texture_swizzle)
1523af69d88dSmrg             && !_mesa_is_gles3(ctx)) {
1524af69d88dSmrg            goto invalid_pname;
1525af69d88dSmrg         }
1526af69d88dSmrg         else {
15274a49301eSmrg            GLuint comp;
15284a49301eSmrg            for (comp = 0; comp < 4; comp++) {
15294a49301eSmrg               params[comp] = (GLfloat) obj->Swizzle[comp];
15304a49301eSmrg            }
15314a49301eSmrg         }
15324a49301eSmrg         break;
15334a49301eSmrg
15343464ebd5Sriastradh      case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1535af69d88dSmrg         if (!_mesa_is_desktop_gl(ctx)
1536af69d88dSmrg             || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
1537af69d88dSmrg            goto invalid_pname;
1538af69d88dSmrg         *params = (GLfloat) obj->Sampler.CubeMapSeamless;
1539af69d88dSmrg         break;
1540af69d88dSmrg
1541af69d88dSmrg      case GL_TEXTURE_IMMUTABLE_FORMAT:
1542af69d88dSmrg         *params = (GLfloat) obj->Immutable;
1543af69d88dSmrg         break;
1544af69d88dSmrg
1545af69d88dSmrg      case GL_TEXTURE_IMMUTABLE_LEVELS:
1546af69d88dSmrg         if (_mesa_is_gles3(ctx) ||
1547af69d88dSmrg             (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view))
1548af69d88dSmrg            *params = (GLfloat) obj->ImmutableLevels;
1549af69d88dSmrg         else
1550af69d88dSmrg            goto invalid_pname;
1551af69d88dSmrg         break;
1552af69d88dSmrg
1553af69d88dSmrg      case GL_TEXTURE_VIEW_MIN_LEVEL:
1554af69d88dSmrg         if (!ctx->Extensions.ARB_texture_view)
1555af69d88dSmrg            goto invalid_pname;
1556af69d88dSmrg         *params = (GLfloat) obj->MinLevel;
1557af69d88dSmrg         break;
1558af69d88dSmrg
1559af69d88dSmrg      case GL_TEXTURE_VIEW_NUM_LEVELS:
1560af69d88dSmrg         if (!ctx->Extensions.ARB_texture_view)
1561af69d88dSmrg            goto invalid_pname;
1562af69d88dSmrg         *params = (GLfloat) obj->NumLevels;
1563af69d88dSmrg         break;
1564af69d88dSmrg
1565af69d88dSmrg      case GL_TEXTURE_VIEW_MIN_LAYER:
1566af69d88dSmrg         if (!ctx->Extensions.ARB_texture_view)
1567af69d88dSmrg            goto invalid_pname;
1568af69d88dSmrg         *params = (GLfloat) obj->MinLayer;
1569af69d88dSmrg         break;
1570af69d88dSmrg
1571af69d88dSmrg      case GL_TEXTURE_VIEW_NUM_LAYERS:
1572af69d88dSmrg         if (!ctx->Extensions.ARB_texture_view)
1573af69d88dSmrg            goto invalid_pname;
1574af69d88dSmrg         *params = (GLfloat) obj->NumLayers;
1575af69d88dSmrg         break;
1576af69d88dSmrg
1577af69d88dSmrg      case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
1578af69d88dSmrg         if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
1579af69d88dSmrg            goto invalid_pname;
1580af69d88dSmrg         *params = (GLfloat) obj->RequiredTextureImageUnits;
1581af69d88dSmrg         break;
1582af69d88dSmrg
1583af69d88dSmrg      case GL_TEXTURE_SRGB_DECODE_EXT:
1584af69d88dSmrg         if (!ctx->Extensions.EXT_texture_sRGB_decode)
1585af69d88dSmrg            goto invalid_pname;
1586af69d88dSmrg         *params = (GLfloat) obj->Sampler.sRGBDecode;
15873464ebd5Sriastradh         break;
15883464ebd5Sriastradh
1589c1f859d4Smrg      default:
1590af69d88dSmrg         goto invalid_pname;
1591c1f859d4Smrg   }
15924a49301eSmrg
1593af69d88dSmrg   /* no error if we get here */
1594af69d88dSmrg   _mesa_unlock_context_textures(ctx);
1595af69d88dSmrg   return;
1596c1f859d4Smrg
1597af69d88dSmrginvalid_pname:
1598af69d88dSmrg   _mesa_unlock_context_textures(ctx);
1599af69d88dSmrg   _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", pname);
1600c1f859d4Smrg}
1601c1f859d4Smrg
1602c1f859d4Smrg
1603c1f859d4Smrgvoid GLAPIENTRY
1604c1f859d4Smrg_mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
1605c1f859d4Smrg{
1606c1f859d4Smrg   struct gl_texture_object *obj;
1607c1f859d4Smrg   GET_CURRENT_CONTEXT(ctx);
1608c1f859d4Smrg
1609af69d88dSmrg   obj = get_texobj(ctx, target, GL_TRUE);
1610af69d88dSmrg   if (!obj)
1611af69d88dSmrg      return;
1612c1f859d4Smrg
16134a49301eSmrg   _mesa_lock_texture(ctx, obj);
1614c1f859d4Smrg   switch (pname) {
1615c1f859d4Smrg      case GL_TEXTURE_MAG_FILTER:
16163464ebd5Sriastradh         *params = (GLint) obj->Sampler.MagFilter;
1617af69d88dSmrg         break;
1618c1f859d4Smrg      case GL_TEXTURE_MIN_FILTER:
16193464ebd5Sriastradh         *params = (GLint) obj->Sampler.MinFilter;
1620af69d88dSmrg         break;
1621c1f859d4Smrg      case GL_TEXTURE_WRAP_S:
16223464ebd5Sriastradh         *params = (GLint) obj->Sampler.WrapS;
1623af69d88dSmrg         break;
1624c1f859d4Smrg      case GL_TEXTURE_WRAP_T:
16253464ebd5Sriastradh         *params = (GLint) obj->Sampler.WrapT;
1626af69d88dSmrg         break;
1627c1f859d4Smrg      case GL_TEXTURE_WRAP_R:
16283464ebd5Sriastradh         *params = (GLint) obj->Sampler.WrapR;
1629af69d88dSmrg         break;
1630c1f859d4Smrg      case GL_TEXTURE_BORDER_COLOR:
1631af69d88dSmrg         if (!_mesa_is_desktop_gl(ctx))
1632af69d88dSmrg            goto invalid_pname;
1633af69d88dSmrg
1634c1f859d4Smrg         {
1635c1f859d4Smrg            GLfloat b[4];
16363464ebd5Sriastradh            b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
16373464ebd5Sriastradh            b[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
16383464ebd5Sriastradh            b[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
16393464ebd5Sriastradh            b[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
1640c1f859d4Smrg            params[0] = FLOAT_TO_INT(b[0]);
1641c1f859d4Smrg            params[1] = FLOAT_TO_INT(b[1]);
1642c1f859d4Smrg            params[2] = FLOAT_TO_INT(b[2]);
1643c1f859d4Smrg            params[3] = FLOAT_TO_INT(b[3]);
1644c1f859d4Smrg         }
1645af69d88dSmrg         break;
1646c1f859d4Smrg      case GL_TEXTURE_RESIDENT:
1647af69d88dSmrg         if (ctx->API != API_OPENGL_COMPAT)
1648af69d88dSmrg            goto invalid_pname;
1649af69d88dSmrg
1650af69d88dSmrg         *params = 1;
1651af69d88dSmrg         break;
1652c1f859d4Smrg      case GL_TEXTURE_PRIORITY:
1653af69d88dSmrg         if (ctx->API != API_OPENGL_COMPAT)
1654af69d88dSmrg            goto invalid_pname;
1655af69d88dSmrg
1656c1f859d4Smrg         *params = FLOAT_TO_INT(obj->Priority);
1657af69d88dSmrg         break;
1658c1f859d4Smrg      case GL_TEXTURE_MIN_LOD:
1659af69d88dSmrg         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1660af69d88dSmrg            goto invalid_pname;
1661af69d88dSmrg
16623464ebd5Sriastradh         *params = (GLint) obj->Sampler.MinLod;
1663af69d88dSmrg         break;
1664c1f859d4Smrg      case GL_TEXTURE_MAX_LOD:
1665af69d88dSmrg         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1666af69d88dSmrg            goto invalid_pname;
1667af69d88dSmrg
16683464ebd5Sriastradh         *params = (GLint) obj->Sampler.MaxLod;
1669af69d88dSmrg         break;
1670c1f859d4Smrg      case GL_TEXTURE_BASE_LEVEL:
1671af69d88dSmrg         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1672af69d88dSmrg            goto invalid_pname;
1673af69d88dSmrg
1674c1f859d4Smrg         *params = obj->BaseLevel;
1675af69d88dSmrg         break;
1676c1f859d4Smrg      case GL_TEXTURE_MAX_LEVEL:
1677c1f859d4Smrg         *params = obj->MaxLevel;
1678c1f859d4Smrg         break;
1679af69d88dSmrg      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1680af69d88dSmrg         if (!ctx->Extensions.EXT_texture_filter_anisotropic)
1681af69d88dSmrg            goto invalid_pname;
1682af69d88dSmrg         *params = (GLint) obj->Sampler.MaxAnisotropy;
1683c1f859d4Smrg         break;
1684c1f859d4Smrg      case GL_GENERATE_MIPMAP_SGIS:
1685af69d88dSmrg         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1686af69d88dSmrg            goto invalid_pname;
1687af69d88dSmrg
16883464ebd5Sriastradh	 *params = (GLint) obj->GenerateMipmap;
1689c1f859d4Smrg         break;
1690c1f859d4Smrg      case GL_TEXTURE_COMPARE_MODE_ARB:
1691af69d88dSmrg         if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
1692af69d88dSmrg             && !_mesa_is_gles3(ctx))
1693af69d88dSmrg            goto invalid_pname;
1694af69d88dSmrg         *params = (GLint) obj->Sampler.CompareMode;
1695c1f859d4Smrg         break;
1696c1f859d4Smrg      case GL_TEXTURE_COMPARE_FUNC_ARB:
1697af69d88dSmrg         if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
1698af69d88dSmrg             && !_mesa_is_gles3(ctx))
1699af69d88dSmrg            goto invalid_pname;
1700af69d88dSmrg         *params = (GLint) obj->Sampler.CompareFunc;
1701c1f859d4Smrg         break;
1702c1f859d4Smrg      case GL_DEPTH_TEXTURE_MODE_ARB:
1703af69d88dSmrg         if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture)
1704af69d88dSmrg            goto invalid_pname;
1705af69d88dSmrg         *params = (GLint) obj->DepthMode;
1706af69d88dSmrg         break;
1707af69d88dSmrg      case GL_DEPTH_STENCIL_TEXTURE_MODE:
1708af69d88dSmrg         if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_stencil_texturing)
1709af69d88dSmrg            goto invalid_pname;
1710af69d88dSmrg         *params = (GLint)
1711af69d88dSmrg            (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT);
1712c1f859d4Smrg         break;
1713c1f859d4Smrg      case GL_TEXTURE_LOD_BIAS:
1714af69d88dSmrg         if (_mesa_is_gles(ctx))
1715af69d88dSmrg            goto invalid_pname;
1716af69d88dSmrg
1717af69d88dSmrg         /* GL spec 'Data Conversions' section specifies that floating-point
1718af69d88dSmrg          * value in integer Get function is rounded to nearest integer
1719af69d88dSmrg          */
1720af69d88dSmrg         *params = IROUND(obj->Sampler.LodBias);
1721c1f859d4Smrg         break;
1722c1f859d4Smrg      case GL_TEXTURE_CROP_RECT_OES:
1723af69d88dSmrg         if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
1724af69d88dSmrg            goto invalid_pname;
1725af69d88dSmrg
1726c1f859d4Smrg         params[0] = obj->CropRect[0];
1727c1f859d4Smrg         params[1] = obj->CropRect[1];
1728c1f859d4Smrg         params[2] = obj->CropRect[2];
1729c1f859d4Smrg         params[3] = obj->CropRect[3];
1730c1f859d4Smrg         break;
17314a49301eSmrg      case GL_TEXTURE_SWIZZLE_R_EXT:
17324a49301eSmrg      case GL_TEXTURE_SWIZZLE_G_EXT:
17334a49301eSmrg      case GL_TEXTURE_SWIZZLE_B_EXT:
17344a49301eSmrg      case GL_TEXTURE_SWIZZLE_A_EXT:
1735af69d88dSmrg         if ((!_mesa_is_desktop_gl(ctx)
1736af69d88dSmrg              || !ctx->Extensions.EXT_texture_swizzle)
1737af69d88dSmrg             && !_mesa_is_gles3(ctx))
1738af69d88dSmrg            goto invalid_pname;
1739af69d88dSmrg         *params = obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
17404a49301eSmrg         break;
17414a49301eSmrg
17424a49301eSmrg      case GL_TEXTURE_SWIZZLE_RGBA_EXT:
1743af69d88dSmrg         if ((!_mesa_is_desktop_gl(ctx)
1744af69d88dSmrg              || !ctx->Extensions.EXT_texture_swizzle)
1745af69d88dSmrg             && !_mesa_is_gles3(ctx))
1746af69d88dSmrg            goto invalid_pname;
1747af69d88dSmrg         COPY_4V(params, obj->Swizzle);
17484a49301eSmrg         break;
17494a49301eSmrg
17503464ebd5Sriastradh      case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1751af69d88dSmrg         if (!_mesa_is_desktop_gl(ctx)
1752af69d88dSmrg             || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
1753af69d88dSmrg            goto invalid_pname;
1754af69d88dSmrg         *params = (GLint) obj->Sampler.CubeMapSeamless;
1755af69d88dSmrg         break;
1756af69d88dSmrg
1757af69d88dSmrg      case GL_TEXTURE_IMMUTABLE_FORMAT:
1758af69d88dSmrg         *params = (GLint) obj->Immutable;
1759af69d88dSmrg         break;
1760af69d88dSmrg
1761af69d88dSmrg      case GL_TEXTURE_IMMUTABLE_LEVELS:
1762af69d88dSmrg         if (_mesa_is_gles3(ctx) ||
1763af69d88dSmrg             (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view))
1764af69d88dSmrg            *params = obj->ImmutableLevels;
1765af69d88dSmrg         else
1766af69d88dSmrg            goto invalid_pname;
1767af69d88dSmrg         break;
1768af69d88dSmrg
1769af69d88dSmrg      case GL_TEXTURE_VIEW_MIN_LEVEL:
1770af69d88dSmrg         if (!ctx->Extensions.ARB_texture_view)
1771af69d88dSmrg            goto invalid_pname;
1772af69d88dSmrg         *params = (GLint) obj->MinLevel;
1773af69d88dSmrg         break;
1774af69d88dSmrg
1775af69d88dSmrg      case GL_TEXTURE_VIEW_NUM_LEVELS:
1776af69d88dSmrg         if (!ctx->Extensions.ARB_texture_view)
1777af69d88dSmrg            goto invalid_pname;
1778af69d88dSmrg         *params = (GLint) obj->NumLevels;
1779af69d88dSmrg         break;
1780af69d88dSmrg
1781af69d88dSmrg      case GL_TEXTURE_VIEW_MIN_LAYER:
1782af69d88dSmrg         if (!ctx->Extensions.ARB_texture_view)
1783af69d88dSmrg            goto invalid_pname;
1784af69d88dSmrg         *params = (GLint) obj->MinLayer;
1785af69d88dSmrg         break;
1786af69d88dSmrg
1787af69d88dSmrg      case GL_TEXTURE_VIEW_NUM_LAYERS:
1788af69d88dSmrg         if (!ctx->Extensions.ARB_texture_view)
1789af69d88dSmrg            goto invalid_pname;
1790af69d88dSmrg         *params = (GLint) obj->NumLayers;
1791af69d88dSmrg         break;
1792af69d88dSmrg
1793af69d88dSmrg      case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
1794af69d88dSmrg         if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
1795af69d88dSmrg            goto invalid_pname;
1796af69d88dSmrg         *params = obj->RequiredTextureImageUnits;
1797af69d88dSmrg         break;
1798af69d88dSmrg
1799af69d88dSmrg      case GL_TEXTURE_SRGB_DECODE_EXT:
1800af69d88dSmrg         if (!ctx->Extensions.EXT_texture_sRGB_decode)
1801af69d88dSmrg            goto invalid_pname;
1802af69d88dSmrg         *params = obj->Sampler.sRGBDecode;
1803af69d88dSmrg         break;
1804af69d88dSmrg
1805af69d88dSmrg      case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
1806af69d88dSmrg         if (!ctx->Extensions.ARB_shader_image_load_store)
1807af69d88dSmrg            goto invalid_pname;
1808af69d88dSmrg         *params = obj->ImageFormatCompatibilityType;
18093464ebd5Sriastradh         break;
18103464ebd5Sriastradh
1811c1f859d4Smrg      default:
1812af69d88dSmrg         goto invalid_pname;
1813c1f859d4Smrg   }
18144a49301eSmrg
1815af69d88dSmrg   /* no error if we get here */
1816af69d88dSmrg   _mesa_unlock_texture(ctx, obj);
1817af69d88dSmrg   return;
18184a49301eSmrg
1819af69d88dSmrginvalid_pname:
18204a49301eSmrg   _mesa_unlock_texture(ctx, obj);
1821af69d88dSmrg   _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname);
1822c1f859d4Smrg}
1823cdc920a0Smrg
1824cdc920a0Smrg
1825cdc920a0Smrg/** New in GL 3.0 */
1826cdc920a0Smrgvoid GLAPIENTRY
1827cdc920a0Smrg_mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params)
1828cdc920a0Smrg{
1829cdc920a0Smrg   struct gl_texture_object *texObj;
1830cdc920a0Smrg   GET_CURRENT_CONTEXT(ctx);
1831cdc920a0Smrg
1832cdc920a0Smrg   texObj = get_texobj(ctx, target, GL_TRUE);
1833af69d88dSmrg   if (!texObj)
1834af69d88dSmrg      return;
1835af69d88dSmrg
1836cdc920a0Smrg   switch (pname) {
1837cdc920a0Smrg   case GL_TEXTURE_BORDER_COLOR:
18383464ebd5Sriastradh      COPY_4V(params, texObj->Sampler.BorderColor.i);
1839cdc920a0Smrg      break;
1840cdc920a0Smrg   default:
1841cdc920a0Smrg      _mesa_GetTexParameteriv(target, pname, params);
1842cdc920a0Smrg   }
1843cdc920a0Smrg}
1844cdc920a0Smrg
1845cdc920a0Smrg
1846cdc920a0Smrg/** New in GL 3.0 */
1847cdc920a0Smrgvoid GLAPIENTRY
1848cdc920a0Smrg_mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)
1849cdc920a0Smrg{
1850cdc920a0Smrg   struct gl_texture_object *texObj;
1851cdc920a0Smrg   GET_CURRENT_CONTEXT(ctx);
1852cdc920a0Smrg
1853cdc920a0Smrg   texObj = get_texobj(ctx, target, GL_TRUE);
1854af69d88dSmrg   if (!texObj)
1855af69d88dSmrg      return;
1856af69d88dSmrg
1857cdc920a0Smrg   switch (pname) {
1858cdc920a0Smrg   case GL_TEXTURE_BORDER_COLOR:
18593464ebd5Sriastradh      COPY_4V(params, texObj->Sampler.BorderColor.i);
1860cdc920a0Smrg      break;
1861cdc920a0Smrg   default:
1862cdc920a0Smrg      {
1863cdc920a0Smrg         GLint ip[4];
1864cdc920a0Smrg         _mesa_GetTexParameteriv(target, pname, ip);
1865cdc920a0Smrg         params[0] = ip[0];
1866af69d88dSmrg         if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT ||
1867cdc920a0Smrg             pname == GL_TEXTURE_CROP_RECT_OES) {
1868cdc920a0Smrg            params[1] = ip[1];
1869cdc920a0Smrg            params[2] = ip[2];
1870cdc920a0Smrg            params[3] = ip[3];
1871cdc920a0Smrg         }
1872cdc920a0Smrg      }
1873cdc920a0Smrg   }
1874cdc920a0Smrg}
1875