1/*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5 * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26/**
27 * \file texparam.c
28 *
29 * glTexParameter-related functions
30 */
31
32#include <stdbool.h>
33#include "main/glheader.h"
34#include "main/blend.h"
35#include "main/context.h"
36#include "main/enums.h"
37#include "main/formats.h"
38#include "main/glformats.h"
39#include "main/macros.h"
40#include "main/mtypes.h"
41#include "main/state.h"
42#include "main/texcompress.h"
43#include "main/texobj.h"
44#include "main/texparam.h"
45#include "main/teximage.h"
46#include "main/texstate.h"
47#include "program/prog_instruction.h"
48#include "util/u_math.h"
49
50/**
51 * Use macro to resolve undefined clamping behaviour when using lroundf
52 */
53#define LCLAMPF(a, lmin, lmax) ((a) > (lmin) ? ( (a) >= (lmax) ? (lmax) : (lroundf(a)) ) : (lmin))
54
55/**
56 * Check if a coordinate wrap mode is supported for the texture target.
57 * \return GL_TRUE if legal, GL_FALSE otherwise
58 */
59static GLboolean
60validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap)
61{
62   const struct gl_extensions * const e = & ctx->Extensions;
63   const bool is_desktop_gl = _mesa_is_desktop_gl(ctx);
64   bool supported;
65
66   switch (wrap) {
67   case GL_CLAMP:
68      /* GL_CLAMP was removed in the core profile, and it has never existed in
69       * OpenGL ES.
70       */
71      supported = (ctx->API == API_OPENGL_COMPAT)
72         && (target != GL_TEXTURE_EXTERNAL_OES);
73      break;
74
75   case GL_CLAMP_TO_EDGE:
76      supported = true;
77      break;
78
79   case GL_CLAMP_TO_BORDER:
80      supported = ctx->API != API_OPENGLES && e->ARB_texture_border_clamp
81         && (target != GL_TEXTURE_EXTERNAL_OES);
82      break;
83
84   case GL_REPEAT:
85   case GL_MIRRORED_REPEAT:
86      supported = (target != GL_TEXTURE_RECTANGLE_NV)
87         && (target != GL_TEXTURE_EXTERNAL_OES);
88      break;
89
90   case GL_MIRROR_CLAMP_EXT:
91      supported = is_desktop_gl
92         && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)
93         && (target != GL_TEXTURE_RECTANGLE_NV)
94         && (target != GL_TEXTURE_EXTERNAL_OES);
95      break;
96
97   case GL_MIRROR_CLAMP_TO_EDGE_EXT:
98      supported = (target != GL_TEXTURE_RECTANGLE_NV)
99         && (target != GL_TEXTURE_EXTERNAL_OES)
100         && (_mesa_has_ARB_texture_mirror_clamp_to_edge(ctx) ||
101            _mesa_has_ATI_texture_mirror_once(ctx) ||
102            _mesa_has_EXT_texture_mirror_clamp(ctx));
103      break;
104
105   case GL_MIRROR_CLAMP_TO_BORDER_EXT:
106      supported = is_desktop_gl && e->EXT_texture_mirror_clamp
107         && (target != GL_TEXTURE_RECTANGLE_NV)
108         && (target != GL_TEXTURE_EXTERNAL_OES);
109      break;
110
111   default:
112      supported = false;
113      break;
114   }
115
116   if (!supported)
117      _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap );
118
119   return supported;
120}
121
122
123static bool
124is_texparameteri_target_valid(GLenum target)
125{
126   switch (target) {
127   case GL_TEXTURE_1D:
128   case GL_TEXTURE_1D_ARRAY:
129   case GL_TEXTURE_2D:
130   case GL_TEXTURE_2D_ARRAY:
131   case GL_TEXTURE_2D_MULTISAMPLE:
132   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
133   case GL_TEXTURE_3D:
134   case GL_TEXTURE_CUBE_MAP:
135   case GL_TEXTURE_CUBE_MAP_ARRAY:
136   case GL_TEXTURE_RECTANGLE:
137      return true;
138   default:
139      return false;
140   }
141}
142
143
144/**
145 * Get current texture object for given name.
146 * Return NULL if any error (and record the error).
147 * Note that proxy targets are not accepted.
148 * Only the glGetTexLevelParameter() functions accept proxy targets.
149 */
150static struct gl_texture_object *
151get_texobj_by_name(struct gl_context *ctx, GLuint texture, const char *name)
152{
153   struct gl_texture_object *texObj;
154
155   texObj = _mesa_lookup_texture_err(ctx, texture, name);
156   if (!texObj)
157      return NULL;
158
159   if (!is_texparameteri_target_valid(texObj->Target)) {
160      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(target)", name);
161      return NULL;
162   }
163
164   return texObj;
165}
166
167
168/**
169 * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE.
170 * \return -1 if error.
171 */
172static GLint
173comp_to_swizzle(GLenum comp)
174{
175   switch (comp) {
176   case GL_RED:
177      return SWIZZLE_X;
178   case GL_GREEN:
179      return SWIZZLE_Y;
180   case GL_BLUE:
181      return SWIZZLE_Z;
182   case GL_ALPHA:
183      return SWIZZLE_W;
184   case GL_ZERO:
185      return SWIZZLE_ZERO;
186   case GL_ONE:
187      return SWIZZLE_ONE;
188   default:
189      return -1;
190   }
191}
192
193
194static void
195set_swizzle_component(GLushort *swizzle, GLuint comp, GLuint swz)
196{
197   assert(comp < 4);
198   assert(swz <= SWIZZLE_NIL);
199   {
200      GLuint mask = 0x7 << (3 * comp);
201      GLuint s = (*swizzle & ~mask) | (swz << (3 * comp));
202      *swizzle = s;
203   }
204}
205
206
207/**
208 * This is called just prior to changing any texture object state which
209 * will not affect texture completeness.
210 */
211static inline void
212flush(struct gl_context *ctx)
213{
214   FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, GL_TEXTURE_BIT);
215}
216
217
218/**
219 * This is called just prior to changing any texture object state which
220 * could affect texture completeness (texture base level, max level).
221 * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE_OBJECT
222 * state flag and then mark the texture object as 'incomplete' so that any
223 * per-texture derived state gets recomputed.
224 */
225static inline void
226incomplete(struct gl_context *ctx, struct gl_texture_object *texObj)
227{
228   FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, GL_TEXTURE_BIT);
229   _mesa_dirty_texobj(ctx, texObj);
230}
231
232
233GLboolean
234_mesa_target_allows_setting_sampler_parameters(GLenum target)
235{
236   switch (target) {
237   case GL_TEXTURE_2D_MULTISAMPLE:
238   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
239      return GL_FALSE;
240
241   default:
242      return GL_TRUE;
243   }
244}
245
246
247static inline GLboolean
248is_wrap_gl_clamp(GLint param)
249{
250   return param == GL_CLAMP || param == GL_MIRROR_CLAMP_EXT;
251}
252
253/**
254 * Set an integer-valued texture parameter
255 * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
256 */
257static GLboolean
258set_tex_parameteri(struct gl_context *ctx,
259                   struct gl_texture_object *texObj,
260                   GLenum pname, const GLint *params, bool dsa)
261{
262   const char *suffix = dsa ? "ture" : "";
263
264   if (texObj->HandleAllocated) {
265      /* The ARB_bindless_texture spec says:
266       *
267       * "The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*,
268       * CompressedTexImage*, TexBuffer*, TexParameter*, as well as other
269       * functions defined in terms of these, if the texture object to be
270       * modified is referenced by one or more texture or image handles."
271       */
272      _mesa_error(ctx, GL_INVALID_OPERATION,
273                  "glTex%sParameter(immutable texture)", suffix);
274      return GL_FALSE;
275   }
276
277   switch (pname) {
278   case GL_TEXTURE_MIN_FILTER:
279      if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
280         goto invalid_dsa;
281
282      if (texObj->Sampler.Attrib.MinFilter == params[0])
283         return GL_FALSE;
284      switch (params[0]) {
285      case GL_NEAREST:
286      case GL_LINEAR:
287         flush(ctx);
288         texObj->Sampler.Attrib.MinFilter = params[0];
289         texObj->Sampler.Attrib.state.min_img_filter = filter_to_gallium(params[0]);
290         texObj->Sampler.Attrib.state.min_mip_filter = mipfilter_to_gallium(params[0]);
291         _mesa_lower_gl_clamp(ctx, &texObj->Sampler);
292         return GL_TRUE;
293      case GL_NEAREST_MIPMAP_NEAREST:
294      case GL_LINEAR_MIPMAP_NEAREST:
295      case GL_NEAREST_MIPMAP_LINEAR:
296      case GL_LINEAR_MIPMAP_LINEAR:
297         if (texObj->Target != GL_TEXTURE_RECTANGLE_NV &&
298             texObj->Target != GL_TEXTURE_EXTERNAL_OES) {
299            flush(ctx);
300            texObj->Sampler.Attrib.MinFilter = params[0];
301            texObj->Sampler.Attrib.state.min_img_filter = filter_to_gallium(params[0]);
302            texObj->Sampler.Attrib.state.min_mip_filter = mipfilter_to_gallium(params[0]);
303            _mesa_lower_gl_clamp(ctx, &texObj->Sampler);
304            return GL_TRUE;
305         }
306         FALLTHROUGH;
307      default:
308         goto invalid_param;
309      }
310      return GL_FALSE;
311
312   case GL_TEXTURE_MAG_FILTER:
313      if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
314         goto invalid_dsa;
315
316      if (texObj->Sampler.Attrib.MagFilter == params[0])
317         return GL_FALSE;
318      switch (params[0]) {
319      case GL_NEAREST:
320      case GL_LINEAR:
321         flush(ctx); /* does not effect completeness */
322         texObj->Sampler.Attrib.MagFilter = params[0];
323         texObj->Sampler.Attrib.state.mag_img_filter = filter_to_gallium(params[0]);
324         _mesa_lower_gl_clamp(ctx, &texObj->Sampler);
325         return GL_TRUE;
326      default:
327         goto invalid_param;
328      }
329      return GL_FALSE;
330
331   case GL_TEXTURE_WRAP_S:
332      if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
333         goto invalid_dsa;
334
335      if (texObj->Sampler.Attrib.WrapS == params[0])
336         return GL_FALSE;
337      if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
338         flush(ctx);
339         if (is_wrap_gl_clamp(texObj->Sampler.Attrib.WrapS) != is_wrap_gl_clamp(params[0]))
340            ctx->NewDriverState |= ctx->DriverFlags.NewSamplersWithClamp;
341         texObj->Sampler.Attrib.WrapS = params[0];
342         texObj->Sampler.Attrib.state.wrap_s = wrap_to_gallium(params[0]);
343         _mesa_lower_gl_clamp(ctx, &texObj->Sampler);
344         return GL_TRUE;
345      }
346      return GL_FALSE;
347
348   case GL_TEXTURE_WRAP_T:
349      if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
350         goto invalid_dsa;
351
352      if (texObj->Sampler.Attrib.WrapT == params[0])
353         return GL_FALSE;
354      if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
355         flush(ctx);
356         if (is_wrap_gl_clamp(texObj->Sampler.Attrib.WrapT) != is_wrap_gl_clamp(params[0]))
357            ctx->NewDriverState |= ctx->DriverFlags.NewSamplersWithClamp;
358         texObj->Sampler.Attrib.WrapT = params[0];
359         texObj->Sampler.Attrib.state.wrap_t = wrap_to_gallium(params[0]);
360         _mesa_lower_gl_clamp(ctx, &texObj->Sampler);
361         return GL_TRUE;
362      }
363      return GL_FALSE;
364
365   case GL_TEXTURE_WRAP_R:
366      if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
367         goto invalid_dsa;
368
369      if (texObj->Sampler.Attrib.WrapR == params[0])
370         return GL_FALSE;
371      if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
372         flush(ctx);
373         if (is_wrap_gl_clamp(texObj->Sampler.Attrib.WrapR) != is_wrap_gl_clamp(params[0]))
374            ctx->NewDriverState |= ctx->DriverFlags.NewSamplersWithClamp;
375         texObj->Sampler.Attrib.WrapR = params[0];
376         texObj->Sampler.Attrib.state.wrap_r = wrap_to_gallium(params[0]);
377         _mesa_lower_gl_clamp(ctx, &texObj->Sampler);
378         return GL_TRUE;
379      }
380      return GL_FALSE;
381
382   case GL_TEXTURE_BASE_LEVEL:
383      if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
384         goto invalid_pname;
385
386      if (texObj->Attrib.BaseLevel == params[0])
387         return GL_FALSE;
388
389      /* Section 8.10 (Texture Parameters) of the OpenGL 4.5 Core Profile spec
390       * says:
391       *
392       *    An INVALID_OPERATION error is generated if the effective target is
393       *    TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY, or
394       *    TEXTURE_RECTANGLE, and pname TEXTURE_BASE_LEVEL is set to a value
395       *    other than zero.
396       *
397       * Note that section 3.8.8 (Texture Parameters) of the OpenGL 3.3 Core
398       * Profile spec said:
399       *
400       *    The error INVALID_VALUE is generated if TEXTURE_BASE_LEVEL is set
401       *    to any value other than zero.
402       *
403       * We take the 4.5 language as a correction to 3.3, and we implement
404       * that on all GL versions.
405       */
406      if ((texObj->Target == GL_TEXTURE_2D_MULTISAMPLE ||
407           texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ||
408           texObj->Target == GL_TEXTURE_RECTANGLE) && params[0] != 0)
409         goto invalid_operation;
410
411      if (params[0] < 0) {
412         _mesa_error(ctx, GL_INVALID_VALUE,
413                     "glTex%sParameter(param=%d)", suffix, params[0]);
414         return GL_FALSE;
415      }
416      incomplete(ctx, texObj);
417
418      /** See note about ARB_texture_storage below */
419      if (texObj->Immutable)
420         texObj->Attrib.BaseLevel = MIN2(texObj->Attrib.ImmutableLevels - 1, params[0]);
421      else
422         texObj->Attrib.BaseLevel = params[0];
423
424      return GL_TRUE;
425
426   case GL_TEXTURE_MAX_LEVEL:
427      if (texObj->Attrib.MaxLevel == params[0])
428         return GL_FALSE;
429
430      if (params[0] < 0 ||
431          (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] > 0)) {
432         _mesa_error(ctx, GL_INVALID_VALUE,
433                     "glTex%sParameter(param=%d)", suffix,
434                     params[0]);
435         return GL_FALSE;
436      }
437      incomplete(ctx, texObj);
438
439      /** From ARB_texture_storage:
440       * However, if TEXTURE_IMMUTABLE_FORMAT is TRUE, then level_base is
441       * clamped to the range [0, <levels> - 1] and level_max is then clamped to
442       * the range [level_base, <levels> - 1], where <levels> is the parameter
443       * passed the call to TexStorage* for the texture object.
444       */
445      if (texObj->Immutable)
446          texObj->Attrib.MaxLevel = CLAMP(params[0], texObj->Attrib.BaseLevel,
447                                   texObj->Attrib.ImmutableLevels - 1);
448      else
449         texObj->Attrib.MaxLevel = params[0];
450
451      return GL_TRUE;
452
453   case GL_GENERATE_MIPMAP_SGIS:
454      if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
455         goto invalid_pname;
456
457      if (params[0] && texObj->Target == GL_TEXTURE_EXTERNAL_OES)
458         goto invalid_param;
459      if (texObj->Attrib.GenerateMipmap != params[0]) {
460         /* no flush() */
461	 texObj->Attrib.GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
462	 return GL_TRUE;
463      }
464      return GL_FALSE;
465
466   case GL_TEXTURE_COMPARE_MODE_ARB:
467      if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow)
468          || _mesa_is_gles3(ctx)) {
469
470         if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
471            goto invalid_dsa;
472
473         if (texObj->Sampler.Attrib.CompareMode == params[0])
474            return GL_FALSE;
475         if (params[0] == GL_NONE ||
476             params[0] == GL_COMPARE_R_TO_TEXTURE_ARB) {
477            flush(ctx);
478            texObj->Sampler.Attrib.CompareMode = params[0];
479            return GL_TRUE;
480         }
481         goto invalid_param;
482      }
483      goto invalid_pname;
484
485   case GL_TEXTURE_COMPARE_FUNC_ARB:
486      if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow)
487          || _mesa_is_gles3(ctx)) {
488
489         if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
490            goto invalid_dsa;
491
492         if (texObj->Sampler.Attrib.CompareFunc == params[0])
493            return GL_FALSE;
494         switch (params[0]) {
495         case GL_LEQUAL:
496         case GL_GEQUAL:
497         case GL_EQUAL:
498         case GL_NOTEQUAL:
499         case GL_LESS:
500         case GL_GREATER:
501         case GL_ALWAYS:
502         case GL_NEVER:
503            flush(ctx);
504            texObj->Sampler.Attrib.CompareFunc = params[0];
505            texObj->Sampler.Attrib.state.compare_func = func_to_gallium(params[0]);
506            return GL_TRUE;
507         default:
508            goto invalid_param;
509         }
510      }
511      goto invalid_pname;
512
513   case GL_DEPTH_TEXTURE_MODE_ARB:
514      /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has never
515       * existed in OpenGL ES.
516       */
517      if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_depth_texture) {
518         if (texObj->Attrib.DepthMode == params[0])
519            return GL_FALSE;
520         if (params[0] == GL_LUMINANCE ||
521             params[0] == GL_INTENSITY ||
522             params[0] == GL_ALPHA ||
523             (ctx->Extensions.ARB_texture_rg && params[0] == GL_RED)) {
524            flush(ctx);
525            texObj->Attrib.DepthMode = params[0];
526            return GL_TRUE;
527         }
528         goto invalid_param;
529      }
530      goto invalid_pname;
531
532   case GL_DEPTH_STENCIL_TEXTURE_MODE:
533      if (_mesa_has_ARB_stencil_texturing(ctx) || _mesa_is_gles31(ctx)) {
534         bool stencil = params[0] == GL_STENCIL_INDEX;
535         if (!stencil && params[0] != GL_DEPTH_COMPONENT)
536            goto invalid_param;
537
538         if (texObj->StencilSampling == stencil)
539            return GL_FALSE;
540
541         /* This should not be restored by glPopAttrib. */
542         FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, 0);
543         texObj->StencilSampling = stencil;
544         return GL_TRUE;
545      }
546      goto invalid_pname;
547
548   case GL_TEXTURE_CROP_RECT_OES:
549      if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
550         goto invalid_pname;
551
552      texObj->CropRect[0] = params[0];
553      texObj->CropRect[1] = params[1];
554      texObj->CropRect[2] = params[2];
555      texObj->CropRect[3] = params[3];
556      return GL_TRUE;
557
558   case GL_TEXTURE_SWIZZLE_R_EXT:
559   case GL_TEXTURE_SWIZZLE_G_EXT:
560   case GL_TEXTURE_SWIZZLE_B_EXT:
561   case GL_TEXTURE_SWIZZLE_A_EXT:
562      if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle)
563          || _mesa_is_gles3(ctx)) {
564         const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
565         const GLint swz = comp_to_swizzle(params[0]);
566         if (swz < 0) {
567            _mesa_error(ctx, GL_INVALID_ENUM,
568                        "glTex%sParameter(swizzle 0x%x)", suffix, params[0]);
569            return GL_FALSE;
570         }
571         assert(comp < 4);
572
573         flush(ctx);
574         texObj->Attrib.Swizzle[comp] = params[0];
575         set_swizzle_component(&texObj->Attrib._Swizzle, comp, swz);
576         return GL_TRUE;
577      }
578      goto invalid_pname;
579
580   case GL_TEXTURE_SWIZZLE_RGBA_EXT:
581      if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle)
582          || _mesa_is_gles3(ctx)) {
583         GLuint comp;
584         flush(ctx);
585         for (comp = 0; comp < 4; comp++) {
586            const GLint swz = comp_to_swizzle(params[comp]);
587            if (swz >= 0) {
588               texObj->Attrib.Swizzle[comp] = params[comp];
589               set_swizzle_component(&texObj->Attrib._Swizzle, comp, swz);
590            }
591            else {
592               _mesa_error(ctx, GL_INVALID_ENUM,
593                           "glTex%sParameter(swizzle 0x%x)",
594                           suffix, params[comp]);
595               return GL_FALSE;
596            }
597         }
598         return GL_TRUE;
599      }
600      goto invalid_pname;
601
602   case GL_TEXTURE_SRGB_DECODE_EXT:
603      if (ctx->Extensions.EXT_texture_sRGB_decode) {
604         GLenum decode = params[0];
605
606         if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
607            goto invalid_dsa;
608
609	 if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) {
610	    if (texObj->Sampler.Attrib.sRGBDecode != decode) {
611	       flush(ctx);
612	       texObj->Sampler.Attrib.sRGBDecode = decode;
613	    }
614	    return GL_TRUE;
615	 }
616      }
617      goto invalid_pname;
618
619   case GL_TEXTURE_REDUCTION_MODE_EXT:
620      if (ctx->Extensions.EXT_texture_filter_minmax ||
621          _mesa_has_ARB_texture_filter_minmax(ctx)) {
622         GLenum mode = params[0];
623
624         if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
625            goto invalid_dsa;
626
627         if (mode == GL_WEIGHTED_AVERAGE_EXT || mode == GL_MIN || mode == GL_MAX) {
628            if (texObj->Sampler.Attrib.ReductionMode != mode) {
629               flush(ctx);
630               texObj->Sampler.Attrib.ReductionMode = mode;
631               texObj->Sampler.Attrib.state.reduction_mode = reduction_to_gallium(mode);
632            }
633            return GL_TRUE;
634         }
635      }
636      goto invalid_pname;
637
638   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
639      if (_mesa_is_desktop_gl(ctx)
640          && ctx->Extensions.AMD_seamless_cubemap_per_texture) {
641         GLenum param = params[0];
642
643         if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
644            goto invalid_dsa;
645
646         if (param != GL_TRUE && param != GL_FALSE) {
647            goto invalid_param;
648         }
649         if (param != texObj->Sampler.Attrib.CubeMapSeamless) {
650            flush(ctx);
651            texObj->Sampler.Attrib.CubeMapSeamless = param;
652            texObj->Sampler.Attrib.state.seamless_cube_map = param;
653         }
654         return GL_TRUE;
655      }
656      goto invalid_pname;
657
658   case GL_TEXTURE_TILING_EXT:
659      if (ctx->Extensions.EXT_memory_object && !texObj->Immutable) {
660            texObj->TextureTiling = params[0];
661
662         return GL_TRUE;
663      }
664      goto invalid_pname;
665
666   default:
667      goto invalid_pname;
668   }
669
670invalid_pname:
671   _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)",
672               suffix, _mesa_enum_to_string(pname));
673   return GL_FALSE;
674
675invalid_param:
676   _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(param=%s)",
677               suffix, _mesa_enum_to_string(params[0]));
678   return GL_FALSE;
679
680invalid_dsa:
681   if (!dsa)
682      goto invalid_enum;
683
684invalid_operation:
685   _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sParameter(pname=%s)",
686               suffix, _mesa_enum_to_string(pname));
687   return GL_FALSE;
688
689invalid_enum:
690   _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)",
691               suffix, _mesa_enum_to_string(pname));
692   return GL_FALSE;
693}
694
695
696/**
697 * Set a float-valued texture parameter
698 * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
699 */
700static GLboolean
701set_tex_parameterf(struct gl_context *ctx,
702                   struct gl_texture_object *texObj,
703                   GLenum pname, const GLfloat *params, bool dsa)
704{
705   const char *suffix = dsa ? "ture" : "";
706
707   if (texObj->HandleAllocated) {
708      /* The ARB_bindless_texture spec says:
709       *
710       * "The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*,
711       * CompressedTexImage*, TexBuffer*, TexParameter*, as well as other
712       * functions defined in terms of these, if the texture object to be
713       * modified is referenced by one or more texture or image handles."
714       */
715      _mesa_error(ctx, GL_INVALID_OPERATION,
716                  "glTex%sParameter(immutable texture)", suffix);
717      return GL_FALSE;
718   }
719
720   switch (pname) {
721   case GL_TEXTURE_MIN_LOD:
722      if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
723         goto invalid_pname;
724
725      if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
726         goto invalid_dsa;
727
728      if (texObj->Sampler.Attrib.MinLod == params[0])
729         return GL_FALSE;
730      flush(ctx);
731      texObj->Sampler.Attrib.MinLod = params[0];
732      texObj->Sampler.Attrib.state.min_lod = MAX2(params[0], 0.0f); /* only positive vals */
733      return GL_TRUE;
734
735   case GL_TEXTURE_MAX_LOD:
736      if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
737         goto invalid_pname;
738
739      if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
740         goto invalid_dsa;
741
742      if (texObj->Sampler.Attrib.MaxLod == params[0])
743         return GL_FALSE;
744      flush(ctx);
745      texObj->Sampler.Attrib.MaxLod = params[0];
746      texObj->Sampler.Attrib.state.max_lod = params[0];
747      return GL_TRUE;
748
749   case GL_TEXTURE_PRIORITY:
750      if (ctx->API != API_OPENGL_COMPAT)
751         goto invalid_pname;
752
753      flush(ctx);
754      texObj->Attrib.Priority = CLAMP(params[0], 0.0F, 1.0F);
755      return GL_TRUE;
756
757   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
758      if (ctx->Extensions.EXT_texture_filter_anisotropic) {
759         if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
760            goto invalid_dsa;
761
762         if (texObj->Sampler.Attrib.MaxAnisotropy == params[0])
763            return GL_FALSE;
764         if (params[0] < 1.0F) {
765            _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sParameter(param)",
766                        suffix);
767            return GL_FALSE;
768         }
769         flush(ctx);
770         /* clamp to max, that's what NVIDIA does */
771         texObj->Sampler.Attrib.MaxAnisotropy = MIN2(params[0],
772                                      ctx->Const.MaxTextureMaxAnisotropy);
773         texObj->Sampler.Attrib.state.max_anisotropy =
774            texObj->Sampler.Attrib.MaxAnisotropy == 1 ?
775                  0 : texObj->Sampler.Attrib.MaxAnisotropy; /* gallium sets 0 for 1 */
776         return GL_TRUE;
777      }
778      else {
779         static GLuint count = 0;
780         if (count++ < 10)
781            goto invalid_pname;
782      }
783      return GL_FALSE;
784
785   case GL_TEXTURE_LOD_BIAS:
786      /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias. */
787      if (_mesa_is_gles(ctx))
788         goto invalid_pname;
789
790      if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
791         goto invalid_dsa;
792
793      if (texObj->Sampler.Attrib.LodBias != params[0]) {
794	 flush(ctx);
795	 texObj->Sampler.Attrib.LodBias = params[0];
796         texObj->Sampler.Attrib.state.lod_bias = util_quantize_lod_bias(params[0]);
797	 return GL_TRUE;
798      }
799      break;
800
801   case GL_TEXTURE_BORDER_COLOR:
802      /* Border color exists in desktop OpenGL since 1.0 for GL_CLAMP.  In
803       * OpenGL ES 2.0+, it only exists in when GL_OES_texture_border_clamp is
804       * enabled.  It is never available in OpenGL ES 1.x.
805       *
806       * FIXME: Every driver that supports GLES2 has this extension.  Elide
807       * the check?
808       */
809      if (ctx->API == API_OPENGLES ||
810          (ctx->API == API_OPENGLES2 &&
811           !ctx->Extensions.ARB_texture_border_clamp))
812         goto invalid_pname;
813
814      if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
815         goto invalid_enum;
816
817      flush(ctx);
818      /* ARB_texture_float disables clamping */
819      if (ctx->Extensions.ARB_texture_float) {
820         memcpy(texObj->Sampler.Attrib.state.border_color.f, params, 4 * sizeof(float));
821      } else {
822         texObj->Sampler.Attrib.state.border_color.f[RCOMP] = CLAMP(params[0], 0.0F, 1.0F);
823         texObj->Sampler.Attrib.state.border_color.f[GCOMP] = CLAMP(params[1], 0.0F, 1.0F);
824         texObj->Sampler.Attrib.state.border_color.f[BCOMP] = CLAMP(params[2], 0.0F, 1.0F);
825         texObj->Sampler.Attrib.state.border_color.f[ACOMP] = CLAMP(params[3], 0.0F, 1.0F);
826      }
827      _mesa_update_is_border_color_nonzero(&texObj->Sampler);
828      return GL_TRUE;
829
830   case GL_TEXTURE_TILING_EXT:
831      if (ctx->Extensions.EXT_memory_object) {
832         texObj->TextureTiling = params[0];
833         return GL_TRUE;
834      }
835      goto invalid_pname;
836
837   default:
838      goto invalid_pname;
839   }
840   return GL_FALSE;
841
842invalid_pname:
843   _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)",
844               suffix, _mesa_enum_to_string(pname));
845   return GL_FALSE;
846
847invalid_dsa:
848   if (!dsa)
849      goto invalid_enum;
850   _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sParameter(pname=%s)",
851               suffix, _mesa_enum_to_string(pname));
852   return GL_FALSE;
853invalid_enum:
854   _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)",
855               suffix, _mesa_enum_to_string(pname));
856   return GL_FALSE;
857}
858
859
860void
861_mesa_texture_parameterf(struct gl_context *ctx,
862                         struct gl_texture_object *texObj,
863                         GLenum pname, GLfloat param, bool dsa)
864{
865   GLboolean need_update;
866
867   switch (pname) {
868   case GL_TEXTURE_MIN_FILTER:
869   case GL_TEXTURE_MAG_FILTER:
870   case GL_TEXTURE_WRAP_S:
871   case GL_TEXTURE_WRAP_T:
872   case GL_TEXTURE_WRAP_R:
873   case GL_TEXTURE_BASE_LEVEL:
874   case GL_TEXTURE_MAX_LEVEL:
875   case GL_GENERATE_MIPMAP_SGIS:
876   case GL_TEXTURE_COMPARE_MODE_ARB:
877   case GL_TEXTURE_COMPARE_FUNC_ARB:
878   case GL_DEPTH_TEXTURE_MODE_ARB:
879   case GL_DEPTH_STENCIL_TEXTURE_MODE:
880   case GL_TEXTURE_SRGB_DECODE_EXT:
881   case GL_TEXTURE_REDUCTION_MODE_EXT:
882   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
883   case GL_TEXTURE_SWIZZLE_R_EXT:
884   case GL_TEXTURE_SWIZZLE_G_EXT:
885   case GL_TEXTURE_SWIZZLE_B_EXT:
886   case GL_TEXTURE_SWIZZLE_A_EXT:
887      {
888         GLint p[4];
889         p[0] = (param > 0) ?
890                ((param > INT_MAX) ? INT_MAX : (GLint) (param + 0.5)) :
891                ((param < INT_MIN) ? INT_MIN : (GLint) (param - 0.5));
892
893         p[1] = p[2] = p[3] = 0;
894         need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa);
895      }
896      break;
897   case GL_TEXTURE_BORDER_COLOR:
898   case GL_TEXTURE_SWIZZLE_RGBA:
899      _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameterf(non-scalar pname)",
900                  dsa ? "ture" : "");
901      return;
902   default:
903      {
904         /* this will generate an error if pname is illegal */
905         GLfloat p[4];
906         p[0] = param;
907         p[1] = p[2] = p[3] = 0.0F;
908         need_update = set_tex_parameterf(ctx, texObj, pname, p, dsa);
909      }
910   }
911
912   if (ctx->Driver.TexParameter && need_update) {
913      ctx->Driver.TexParameter(ctx, texObj, pname);
914   }
915}
916
917
918void
919_mesa_texture_parameterfv(struct gl_context *ctx,
920                          struct gl_texture_object *texObj,
921                          GLenum pname, const GLfloat *params, bool dsa)
922{
923   GLboolean need_update;
924   switch (pname) {
925   case GL_TEXTURE_MIN_FILTER:
926   case GL_TEXTURE_MAG_FILTER:
927   case GL_TEXTURE_WRAP_S:
928   case GL_TEXTURE_WRAP_T:
929   case GL_TEXTURE_WRAP_R:
930   case GL_TEXTURE_BASE_LEVEL:
931   case GL_TEXTURE_MAX_LEVEL:
932   case GL_GENERATE_MIPMAP_SGIS:
933   case GL_TEXTURE_COMPARE_MODE_ARB:
934   case GL_TEXTURE_COMPARE_FUNC_ARB:
935   case GL_DEPTH_TEXTURE_MODE_ARB:
936   case GL_DEPTH_STENCIL_TEXTURE_MODE:
937   case GL_TEXTURE_SRGB_DECODE_EXT:
938   case GL_TEXTURE_REDUCTION_MODE_EXT:
939   case GL_TEXTURE_CUBE_MAP_SEAMLESS:
940      {
941         /* convert float param to int */
942         GLint p[4];
943         p[0] = (GLint) params[0];
944         p[1] = p[2] = p[3] = 0;
945         need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa);
946      }
947      break;
948   case GL_TEXTURE_CROP_RECT_OES:
949      {
950         /* convert float params to int */
951         GLint iparams[4];
952         iparams[0] = (GLint) params[0];
953         iparams[1] = (GLint) params[1];
954         iparams[2] = (GLint) params[2];
955         iparams[3] = (GLint) params[3];
956         need_update = set_tex_parameteri(ctx, texObj, pname, iparams, dsa);
957      }
958      break;
959   case GL_TEXTURE_SWIZZLE_R_EXT:
960   case GL_TEXTURE_SWIZZLE_G_EXT:
961   case GL_TEXTURE_SWIZZLE_B_EXT:
962   case GL_TEXTURE_SWIZZLE_A_EXT:
963   case GL_TEXTURE_SWIZZLE_RGBA_EXT:
964      {
965         GLint p[4] = {0, 0, 0, 0};
966         p[0] = (GLint) params[0];
967         if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT) {
968            p[1] = (GLint) params[1];
969            p[2] = (GLint) params[2];
970            p[3] = (GLint) params[3];
971         }
972         need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa);
973      }
974      break;
975   default:
976      /* this will generate an error if pname is illegal */
977      need_update = set_tex_parameterf(ctx, texObj, pname, params, dsa);
978   }
979
980   if (ctx->Driver.TexParameter && need_update) {
981      ctx->Driver.TexParameter(ctx, texObj, pname);
982   }
983}
984
985
986void
987_mesa_texture_parameteri(struct gl_context *ctx,
988                         struct gl_texture_object *texObj,
989                         GLenum pname, GLint param, bool dsa)
990{
991   GLboolean need_update;
992   switch (pname) {
993   case GL_TEXTURE_MIN_LOD:
994   case GL_TEXTURE_MAX_LOD:
995   case GL_TEXTURE_PRIORITY:
996   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
997   case GL_TEXTURE_LOD_BIAS:
998      {
999         GLfloat fparam[4];
1000         fparam[0] = (GLfloat) param;
1001         fparam[1] = fparam[2] = fparam[3] = 0.0F;
1002         /* convert int param to float */
1003         need_update = set_tex_parameterf(ctx, texObj, pname, fparam, dsa);
1004      }
1005      break;
1006   case GL_TEXTURE_BORDER_COLOR:
1007   case GL_TEXTURE_SWIZZLE_RGBA:
1008      {
1009         _mesa_error(ctx, GL_INVALID_ENUM,
1010                     "glTex%sParameteri(non-scalar pname)",
1011                     dsa ? "ture" : "");
1012         return;
1013      }
1014   default:
1015      /* this will generate an error if pname is illegal */
1016      {
1017         GLint iparam[4];
1018         iparam[0] = param;
1019         iparam[1] = iparam[2] = iparam[3] = 0;
1020         need_update = set_tex_parameteri(ctx, texObj, pname, iparam, dsa);
1021      }
1022   }
1023
1024   if (ctx->Driver.TexParameter && need_update) {
1025      ctx->Driver.TexParameter(ctx, texObj, pname);
1026   }
1027}
1028
1029
1030void
1031_mesa_texture_parameteriv(struct gl_context *ctx,
1032                          struct gl_texture_object *texObj,
1033                          GLenum pname, const GLint *params, bool dsa)
1034{
1035   GLboolean need_update;
1036
1037   switch (pname) {
1038   case GL_TEXTURE_BORDER_COLOR:
1039      {
1040         /* convert int params to float */
1041         GLfloat fparams[4];
1042         fparams[0] = INT_TO_FLOAT(params[0]);
1043         fparams[1] = INT_TO_FLOAT(params[1]);
1044         fparams[2] = INT_TO_FLOAT(params[2]);
1045         fparams[3] = INT_TO_FLOAT(params[3]);
1046         need_update = set_tex_parameterf(ctx, texObj, pname, fparams, dsa);
1047      }
1048      break;
1049   case GL_TEXTURE_MIN_LOD:
1050   case GL_TEXTURE_MAX_LOD:
1051   case GL_TEXTURE_PRIORITY:
1052   case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1053   case GL_TEXTURE_LOD_BIAS:
1054      {
1055         /* convert int param to float */
1056         GLfloat fparams[4];
1057         fparams[0] = (GLfloat) params[0];
1058         fparams[1] = fparams[2] = fparams[3] = 0.0F;
1059         need_update = set_tex_parameterf(ctx, texObj, pname, fparams, dsa);
1060      }
1061      break;
1062   default:
1063      /* this will generate an error if pname is illegal */
1064      need_update = set_tex_parameteri(ctx, texObj, pname, params, dsa);
1065   }
1066
1067   if (ctx->Driver.TexParameter && need_update) {
1068      ctx->Driver.TexParameter(ctx, texObj, pname);
1069   }
1070}
1071
1072void
1073_mesa_texture_parameterIiv(struct gl_context *ctx,
1074                           struct gl_texture_object *texObj,
1075                           GLenum pname, const GLint *params, bool dsa)
1076{
1077   switch (pname) {
1078   case GL_TEXTURE_BORDER_COLOR:
1079      if (texObj->HandleAllocated) {
1080         _mesa_error(ctx, GL_INVALID_OPERATION,
1081                     "glTextureParameterIiv(immutable texture)");
1082         return;
1083      }
1084
1085      if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) {
1086         _mesa_error(ctx, dsa ? GL_INVALID_OPERATION : GL_INVALID_ENUM, "glTextureParameterIiv(texture)");
1087         return;
1088      }
1089      FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, GL_TEXTURE_BIT);
1090      /* set the integer-valued border color */
1091      COPY_4V(texObj->Sampler.Attrib.state.border_color.i, params);
1092      _mesa_update_is_border_color_nonzero(&texObj->Sampler);
1093      break;
1094   default:
1095      _mesa_texture_parameteriv(ctx, texObj, pname, params, dsa);
1096      break;
1097   }
1098   /* XXX no driver hook for TexParameterIiv() yet */
1099}
1100
1101void
1102_mesa_texture_parameterIuiv(struct gl_context *ctx,
1103                            struct gl_texture_object *texObj,
1104                            GLenum pname, const GLuint *params, bool dsa)
1105{
1106   switch (pname) {
1107   case GL_TEXTURE_BORDER_COLOR:
1108      if (texObj->HandleAllocated) {
1109         _mesa_error(ctx, GL_INVALID_OPERATION,
1110                     "glTextureParameterIuiv(immutable texture)");
1111         return;
1112      }
1113
1114      if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) {
1115         _mesa_error(ctx, dsa ? GL_INVALID_OPERATION : GL_INVALID_ENUM, "glTextureParameterIuiv(texture)");
1116         return;
1117      }
1118      FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, GL_TEXTURE_BIT);
1119      /* set the unsigned integer-valued border color */
1120      COPY_4V(texObj->Sampler.Attrib.state.border_color.ui, params);
1121      _mesa_update_is_border_color_nonzero(&texObj->Sampler);
1122      break;
1123   default:
1124      _mesa_texture_parameteriv(ctx, texObj, pname, (const GLint *) params,
1125                                dsa);
1126      break;
1127   }
1128   /* XXX no driver hook for TexParameterIuiv() yet */
1129}
1130
1131void GLAPIENTRY
1132_mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
1133{
1134   struct gl_texture_object *texObj;
1135   GET_CURRENT_CONTEXT(ctx);
1136
1137   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
1138                                                   ctx->Texture.CurrentUnit,
1139                                                   false,
1140                                                   "glTexParameterf");
1141   if (!texObj)
1142      return;
1143
1144   _mesa_texture_parameterf(ctx, texObj, pname, param, false);
1145}
1146
1147void GLAPIENTRY
1148_mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1149{
1150   struct gl_texture_object *texObj;
1151   GET_CURRENT_CONTEXT(ctx);
1152
1153   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
1154                                                   ctx->Texture.CurrentUnit,
1155                                                   false,
1156                                                   "glTexParameterfv");
1157   if (!texObj)
1158      return;
1159
1160   _mesa_texture_parameterfv(ctx, texObj, pname, params, false);
1161}
1162
1163void GLAPIENTRY
1164_mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
1165{
1166   struct gl_texture_object *texObj;
1167   GET_CURRENT_CONTEXT(ctx);
1168
1169   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
1170                                                   ctx->Texture.CurrentUnit,
1171                                                   false,
1172                                                   "glTexParameteri");
1173   if (!texObj)
1174      return;
1175
1176   _mesa_texture_parameteri(ctx, texObj, pname, param, false);
1177}
1178
1179void GLAPIENTRY
1180_mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
1181{
1182   struct gl_texture_object *texObj;
1183   GET_CURRENT_CONTEXT(ctx);
1184
1185   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
1186                                                   ctx->Texture.CurrentUnit,
1187                                                   false,
1188                                                   "glTexParameteriv");
1189   if (!texObj)
1190      return;
1191
1192   _mesa_texture_parameteriv(ctx, texObj, pname, params, false);
1193}
1194
1195/**
1196 * Set tex parameter to integer value(s).  Primarily intended to set
1197 * integer-valued texture border color (for integer-valued textures).
1198 * New in GL 3.0.
1199 */
1200void GLAPIENTRY
1201_mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params)
1202{
1203   struct gl_texture_object *texObj;
1204   GET_CURRENT_CONTEXT(ctx);
1205
1206   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
1207                                                   ctx->Texture.CurrentUnit,
1208                                                   false,
1209                                                   "glTexParameterIiv");
1210   if (!texObj)
1211      return;
1212
1213   _mesa_texture_parameterIiv(ctx, texObj, pname, params, false);
1214}
1215
1216/**
1217 * Set tex parameter to unsigned integer value(s).  Primarily intended to set
1218 * uint-valued texture border color (for integer-valued textures).
1219 * New in GL 3.0
1220 */
1221void GLAPIENTRY
1222_mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
1223{
1224   struct gl_texture_object *texObj;
1225   GET_CURRENT_CONTEXT(ctx);
1226
1227   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
1228                                                   ctx->Texture.CurrentUnit,
1229                                                   false,
1230                                                   "glTexParameterIuiv");
1231   if (!texObj)
1232      return;
1233
1234   _mesa_texture_parameterIuiv(ctx, texObj, pname, params, false);
1235}
1236
1237void GLAPIENTRY
1238_mesa_TextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, const GLfloat *params)
1239{
1240   struct gl_texture_object *texObj;
1241   GET_CURRENT_CONTEXT(ctx);
1242
1243   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
1244                                           "glTextureParameterfvEXT");
1245   if (!texObj)
1246      return;
1247
1248   if (!is_texparameteri_target_valid(texObj->Target)) {
1249      _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameterfvEXT");
1250      return;
1251   }
1252
1253   _mesa_texture_parameterfv(ctx, texObj, pname, params, true);
1254}
1255
1256void GLAPIENTRY
1257_mesa_TextureParameterfv(GLuint texture, GLenum pname, const GLfloat *params)
1258{
1259   struct gl_texture_object *texObj;
1260   GET_CURRENT_CONTEXT(ctx);
1261
1262   texObj = get_texobj_by_name(ctx, texture, "glTextureParameterfv");
1263   if (!texObj)
1264      return;
1265
1266   _mesa_texture_parameterfv(ctx, texObj, pname, params, true);
1267}
1268
1269void GLAPIENTRY
1270_mesa_MultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname, const GLfloat *params)
1271{
1272   struct gl_texture_object *texObj;
1273   GET_CURRENT_CONTEXT(ctx);
1274
1275   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
1276                                                   texunit - GL_TEXTURE0,
1277                                                   false,
1278                                                   "glMultiTexParameterfvEXT");
1279   if (!texObj)
1280      return;
1281
1282   if (!is_texparameteri_target_valid(texObj->Target)) {
1283      _mesa_error(ctx, GL_INVALID_OPERATION, "glMultiTexParameterifvEXT(target)");
1284      return;
1285   }
1286
1287   _mesa_texture_parameterfv(ctx, texObj, pname, params, true);
1288}
1289
1290void GLAPIENTRY
1291_mesa_TextureParameterfEXT(GLuint texture, GLenum target, GLenum pname, GLfloat param)
1292{
1293   struct gl_texture_object *texObj;
1294   GET_CURRENT_CONTEXT(ctx);
1295
1296   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
1297                                           "glTextureParameterfEXT");
1298   if (!texObj)
1299      return;
1300
1301   if (!is_texparameteri_target_valid(texObj->Target)) {
1302      _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameterfEXT");
1303      return;
1304   }
1305
1306   _mesa_texture_parameterf(ctx, texObj, pname, param, true);
1307}
1308
1309void GLAPIENTRY
1310_mesa_MultiTexParameterfEXT(GLenum texunit, GLenum target, GLenum pname,
1311                            GLfloat param)
1312{
1313   struct gl_texture_object *texObj;
1314   GET_CURRENT_CONTEXT(ctx);
1315
1316   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
1317                                                   texunit - GL_TEXTURE0,
1318                                                   false,
1319                                                   "glMultiTexParameterfEXT");
1320   if (!texObj)
1321      return;
1322
1323   if (!is_texparameteri_target_valid(texObj->Target)) {
1324      _mesa_error(ctx, GL_INVALID_OPERATION, "glMultiTexParameterfEXT");
1325      return;
1326   }
1327
1328   _mesa_texture_parameterf(ctx, texObj, pname, param, true);
1329}
1330
1331void GLAPIENTRY
1332_mesa_TextureParameterf(GLuint texture, GLenum pname, GLfloat param)
1333{
1334   struct gl_texture_object *texObj;
1335   GET_CURRENT_CONTEXT(ctx);
1336
1337   texObj = get_texobj_by_name(ctx, texture, "glTextureParameterf");
1338   if (!texObj)
1339      return;
1340
1341   _mesa_texture_parameterf(ctx, texObj, pname, param, true);
1342}
1343
1344void GLAPIENTRY
1345_mesa_TextureParameteriEXT(GLuint texture, GLenum target, GLenum pname, GLint param)
1346{
1347   struct gl_texture_object *texObj;
1348   GET_CURRENT_CONTEXT(ctx);
1349
1350   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
1351                                           "glTextureParameteriEXT");
1352   if (!texObj)
1353      return;
1354
1355   if (!is_texparameteri_target_valid(texObj->Target)) {
1356      _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameteriEXT(target)");
1357      return;
1358   }
1359
1360   _mesa_texture_parameteri(ctx, texObj, pname, param, true);
1361}
1362
1363void GLAPIENTRY
1364_mesa_MultiTexParameteriEXT(GLenum texunit, GLenum target, GLenum pname,
1365                            GLint param)
1366{
1367   struct gl_texture_object *texObj;
1368   GET_CURRENT_CONTEXT(ctx);
1369
1370   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
1371                                                   texunit - GL_TEXTURE0,
1372                                                   false,
1373                                                   "glMultiTexParameteriEXT");
1374   if (!texObj)
1375      return;
1376
1377   if (!is_texparameteri_target_valid(texObj->Target)) {
1378      _mesa_error(ctx, GL_INVALID_OPERATION, "glMultiTexParameteriEXT(target)");
1379      return;
1380   }
1381
1382   _mesa_texture_parameteri(ctx, texObj, pname, param, true);
1383}
1384
1385void GLAPIENTRY
1386_mesa_TextureParameteri(GLuint texture, GLenum pname, GLint param)
1387{
1388   struct gl_texture_object *texObj;
1389   GET_CURRENT_CONTEXT(ctx);
1390
1391   texObj = get_texobj_by_name(ctx, texture, "glTextureParameteri");
1392   if (!texObj)
1393      return;
1394
1395   _mesa_texture_parameteri(ctx, texObj, pname, param, true);
1396}
1397
1398void GLAPIENTRY
1399_mesa_TextureParameterivEXT(GLuint texture, GLenum target, GLenum pname,
1400                         const GLint *params)
1401{
1402   struct gl_texture_object *texObj;
1403   GET_CURRENT_CONTEXT(ctx);
1404
1405   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
1406                                           "glTextureParameterivEXT");
1407   if (!texObj)
1408      return;
1409
1410   if (!is_texparameteri_target_valid(texObj->Target)) {
1411      _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameterivEXT(target)");
1412      return;
1413   }
1414
1415   _mesa_texture_parameteriv(ctx, texObj, pname, params, true);
1416}
1417
1418void GLAPIENTRY
1419_mesa_MultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname,
1420                             const GLint *params)
1421{
1422   struct gl_texture_object *texObj;
1423   GET_CURRENT_CONTEXT(ctx);
1424
1425   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
1426                                                   texunit - GL_TEXTURE0,
1427                                                   false,
1428                                                   "glMultiTexParameterivEXT");
1429   if (!texObj)
1430      return;
1431
1432   if (!is_texparameteri_target_valid(texObj->Target)) {
1433      _mesa_error(ctx, GL_INVALID_OPERATION, "glMultiTexParameterivEXT(target)");
1434      return;
1435   }
1436
1437   _mesa_texture_parameteriv(ctx, texObj, pname, params, true);
1438}
1439
1440void GLAPIENTRY
1441_mesa_TextureParameteriv(GLuint texture, GLenum pname,
1442                         const GLint *params)
1443{
1444   struct gl_texture_object *texObj;
1445   GET_CURRENT_CONTEXT(ctx);
1446
1447   texObj = get_texobj_by_name(ctx, texture, "glTextureParameteriv");
1448   if (!texObj)
1449      return;
1450
1451   _mesa_texture_parameteriv(ctx, texObj, pname, params, true);
1452}
1453
1454
1455void GLAPIENTRY
1456_mesa_TextureParameterIiv(GLuint texture, GLenum pname, const GLint *params)
1457{
1458   struct gl_texture_object *texObj;
1459   GET_CURRENT_CONTEXT(ctx);
1460
1461   texObj = get_texobj_by_name(ctx, texture, "glTextureParameterIiv");
1462   if (!texObj)
1463      return;
1464
1465   _mesa_texture_parameterIiv(ctx, texObj, pname, params, true);
1466}
1467
1468void GLAPIENTRY
1469_mesa_TextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname,
1470                             const GLint *params)
1471{
1472   struct gl_texture_object *texObj;
1473   GET_CURRENT_CONTEXT(ctx);
1474
1475   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
1476                                           "glTextureParameterIivEXT");
1477   if (!texObj)
1478      return;
1479
1480   _mesa_texture_parameterIiv(ctx, texObj, pname, params, true);
1481}
1482
1483void GLAPIENTRY
1484_mesa_MultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname,
1485                              const GLint *params)
1486{
1487   struct gl_texture_object *texObj;
1488   GET_CURRENT_CONTEXT(ctx);
1489
1490   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
1491                                                   texunit - GL_TEXTURE0,
1492                                                   true,
1493                                                   "glMultiTexParameterIivEXT");
1494   if (!texObj)
1495      return;
1496
1497   _mesa_texture_parameterIiv(ctx, texObj, pname, params, true);
1498}
1499
1500void GLAPIENTRY
1501_mesa_TextureParameterIuiv(GLuint texture, GLenum pname, const GLuint *params)
1502{
1503   struct gl_texture_object *texObj;
1504   GET_CURRENT_CONTEXT(ctx);
1505
1506   texObj = get_texobj_by_name(ctx, texture, "glTextureParameterIuiv");
1507   if (!texObj)
1508      return;
1509
1510   _mesa_texture_parameterIuiv(ctx, texObj, pname, params, true);
1511}
1512
1513void GLAPIENTRY
1514_mesa_TextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname,
1515                              const GLuint *params)
1516{
1517   struct gl_texture_object *texObj;
1518   GET_CURRENT_CONTEXT(ctx);
1519
1520   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
1521                                           "glTextureParameterIuivEXT");
1522   if (!texObj)
1523      return;
1524
1525   _mesa_texture_parameterIuiv(ctx, texObj, pname, params, true);
1526}
1527
1528void GLAPIENTRY
1529_mesa_MultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname,
1530                               const GLuint *params)
1531{
1532   struct gl_texture_object *texObj;
1533   GET_CURRENT_CONTEXT(ctx);
1534
1535   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
1536                                                   texunit - GL_TEXTURE0,
1537                                                   true,
1538                                                   "glMultiTexParameterIuivEXT");
1539   if (!texObj)
1540      return;
1541
1542   _mesa_texture_parameterIuiv(ctx, texObj, pname, params, true);
1543}
1544
1545GLboolean
1546_mesa_legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target,
1547                                           bool dsa)
1548{
1549   /* Common targets for desktop GL and GLES 3.1. */
1550   switch (target) {
1551   case GL_TEXTURE_2D:
1552   case GL_TEXTURE_3D:
1553      return GL_TRUE;
1554   case GL_TEXTURE_2D_ARRAY_EXT:
1555      return ctx->Extensions.EXT_texture_array;
1556   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1557   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1558   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1559   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1560   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1561   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1562      return ctx->Extensions.ARB_texture_cube_map;
1563   case GL_TEXTURE_2D_MULTISAMPLE:
1564   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
1565      return ctx->Extensions.ARB_texture_multisample;
1566   case GL_TEXTURE_BUFFER:
1567      /* GetTexLevelParameter accepts GL_TEXTURE_BUFFER in GL 3.1+ contexts,
1568       * but not in earlier versions that expose ARB_texture_buffer_object.
1569       *
1570       * From the ARB_texture_buffer_object spec:
1571       * "(7) Do buffer textures support texture parameters (TexParameter) or
1572       *      queries (GetTexParameter, GetTexLevelParameter, GetTexImage)?
1573       *
1574       *    RESOLVED:  No. [...] Note that the spec edits above don't add
1575       *    explicit error language for any of these cases.  That is because
1576       *    each of the functions enumerate the set of valid <target>
1577       *    parameters.  Not editing the spec to allow TEXTURE_BUFFER_ARB in
1578       *    these cases means that target is not legal, and an INVALID_ENUM
1579       *    error should be generated."
1580       *
1581       * From the OpenGL 3.1 spec:
1582       * "target may also be TEXTURE_BUFFER, indicating the texture buffer."
1583       */
1584      return (_mesa_is_desktop_gl(ctx) && ctx->Version >= 31) ||
1585             _mesa_has_OES_texture_buffer(ctx);
1586   case GL_TEXTURE_CUBE_MAP_ARRAY:
1587      return _mesa_has_texture_cube_map_array(ctx);
1588   }
1589
1590   if (!_mesa_is_desktop_gl(ctx))
1591      return GL_FALSE;
1592
1593   /* Rest of the desktop GL targets. */
1594   switch (target) {
1595   case GL_TEXTURE_1D:
1596   case GL_PROXY_TEXTURE_1D:
1597   case GL_PROXY_TEXTURE_2D:
1598   case GL_PROXY_TEXTURE_3D:
1599      return GL_TRUE;
1600   case GL_PROXY_TEXTURE_CUBE_MAP:
1601      return ctx->Extensions.ARB_texture_cube_map;
1602   case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
1603      return ctx->Extensions.ARB_texture_cube_map_array;
1604   case GL_TEXTURE_RECTANGLE_NV:
1605   case GL_PROXY_TEXTURE_RECTANGLE_NV:
1606      return ctx->Extensions.NV_texture_rectangle;
1607   case GL_TEXTURE_1D_ARRAY_EXT:
1608   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
1609   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1610      return ctx->Extensions.EXT_texture_array;
1611   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
1612   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
1613      return ctx->Extensions.ARB_texture_multisample;
1614
1615   /*  This is a valid target for dsa, but the OpenGL 4.5 core spec
1616    *  (30.10.2014) Section 8.11 Texture Queries says:
1617    *       "For GetTextureLevelParameter* only, texture may also be a cube
1618    *       map texture object.  In this case the query is always performed
1619    *       for face zero (the TEXTURE_CUBE_MAP_POSITIVE_X face), since there
1620    *       is no way to specify another face."
1621    */
1622   case GL_TEXTURE_CUBE_MAP:
1623      return dsa;
1624   default:
1625      return GL_FALSE;
1626   }
1627}
1628
1629
1630static void
1631get_tex_level_parameter_image(struct gl_context *ctx,
1632                              const struct gl_texture_object *texObj,
1633                              GLenum target, GLint level,
1634                              GLenum pname, GLint *params,
1635                              bool dsa)
1636{
1637   const struct gl_texture_image *img = NULL;
1638   struct gl_texture_image dummy_image;
1639   mesa_format texFormat;
1640   const char *suffix = dsa ? "ture" : "";
1641
1642   img = _mesa_select_tex_image(texObj, target, level);
1643   if (!img || img->TexFormat == MESA_FORMAT_NONE) {
1644      /* In case of undefined texture image return the default values.
1645       *
1646       * From OpenGL 4.0 spec, page 398:
1647       *    "The initial internal format of a texel array is RGBA
1648       *     instead of 1. TEXTURE_COMPONENTS is deprecated; always
1649       *     use TEXTURE_INTERNAL_FORMAT."
1650       */
1651      memset(&dummy_image, 0, sizeof(dummy_image));
1652      dummy_image.TexFormat = MESA_FORMAT_NONE;
1653      dummy_image.InternalFormat = GL_RGBA;
1654      dummy_image._BaseFormat = GL_NONE;
1655      dummy_image.FixedSampleLocations = GL_TRUE;
1656
1657      img = &dummy_image;
1658   }
1659
1660   texFormat = img->TexFormat;
1661
1662   switch (pname) {
1663      case GL_TEXTURE_WIDTH:
1664         *params = img->Width;
1665         break;
1666      case GL_TEXTURE_HEIGHT:
1667         *params = img->Height;
1668         break;
1669      case GL_TEXTURE_DEPTH:
1670         *params = img->Depth;
1671         break;
1672      case GL_TEXTURE_INTERNAL_FORMAT:
1673         if (_mesa_is_format_compressed(texFormat)) {
1674            /* need to return the actual compressed format */
1675            *params = _mesa_compressed_format_to_glenum(ctx, texFormat);
1676         }
1677         else {
1678	    /* If the true internal format is not compressed but the user
1679	     * requested a generic compressed format, we have to return the
1680	     * generic base format that matches.
1681	     *
1682	     * From page 119 (page 129 of the PDF) of the OpenGL 1.3 spec:
1683	     *
1684	     *     "If no specific compressed format is available,
1685	     *     internalformat is instead replaced by the corresponding base
1686	     *     internal format."
1687	     *
1688	     * Otherwise just return the user's requested internal format
1689	     */
1690	    const GLenum f =
1691	       _mesa_gl_compressed_format_base_format(img->InternalFormat);
1692
1693	    *params = (f != 0) ? f : img->InternalFormat;
1694	 }
1695         break;
1696      case GL_TEXTURE_BORDER:
1697         if (ctx->API != API_OPENGL_COMPAT)
1698            goto invalid_pname;
1699         *params = img->Border;
1700         break;
1701      case GL_TEXTURE_RED_SIZE:
1702      case GL_TEXTURE_GREEN_SIZE:
1703      case GL_TEXTURE_BLUE_SIZE:
1704      case GL_TEXTURE_ALPHA_SIZE:
1705         if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
1706            *params = _mesa_get_format_bits(texFormat, pname);
1707         else
1708            *params = 0;
1709         break;
1710      case GL_TEXTURE_INTENSITY_SIZE:
1711      case GL_TEXTURE_LUMINANCE_SIZE:
1712         if (ctx->API != API_OPENGL_COMPAT)
1713            goto invalid_pname;
1714         if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) {
1715            *params = _mesa_get_format_bits(texFormat, pname);
1716            if (*params == 0) {
1717               /* intensity or luminance is probably stored as RGB[A] */
1718               *params = MIN2(_mesa_get_format_bits(texFormat,
1719                                                    GL_TEXTURE_RED_SIZE),
1720                              _mesa_get_format_bits(texFormat,
1721                                                    GL_TEXTURE_GREEN_SIZE));
1722            }
1723            if (*params == 0 && pname == GL_TEXTURE_INTENSITY_SIZE) {
1724               /* Gallium may store intensity as LA */
1725               *params = _mesa_get_format_bits(texFormat,
1726                                               GL_TEXTURE_ALPHA_SIZE);
1727            }
1728         }
1729         else {
1730            *params = 0;
1731         }
1732         break;
1733      case GL_TEXTURE_DEPTH_SIZE_ARB:
1734         if (!ctx->Extensions.ARB_depth_texture)
1735            goto invalid_pname;
1736         *params = _mesa_get_format_bits(texFormat, pname);
1737         break;
1738      case GL_TEXTURE_STENCIL_SIZE:
1739         *params = _mesa_get_format_bits(texFormat, pname);
1740         break;
1741      case GL_TEXTURE_SHARED_SIZE:
1742         if (ctx->Version < 30 &&
1743             !ctx->Extensions.EXT_texture_shared_exponent)
1744            goto invalid_pname;
1745         *params = texFormat == MESA_FORMAT_R9G9B9E5_FLOAT ? 5 : 0;
1746         break;
1747
1748      /* GL_ARB_texture_compression */
1749      case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
1750         if (_mesa_is_format_compressed(texFormat) &&
1751             !_mesa_is_proxy_texture(target)) {
1752            *params = _mesa_format_image_size(texFormat, img->Width,
1753                                              img->Height, img->Depth);
1754         } else {
1755            _mesa_error(ctx, GL_INVALID_OPERATION,
1756                        "glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
1757                        _mesa_enum_to_string(pname));
1758         }
1759         break;
1760      case GL_TEXTURE_COMPRESSED:
1761         *params = (GLint) _mesa_is_format_compressed(texFormat);
1762         break;
1763
1764      /* GL_ARB_texture_float */
1765      case GL_TEXTURE_LUMINANCE_TYPE_ARB:
1766      case GL_TEXTURE_INTENSITY_TYPE_ARB:
1767         if (ctx->API != API_OPENGL_COMPAT)
1768            goto invalid_pname;
1769         FALLTHROUGH;
1770      case GL_TEXTURE_RED_TYPE_ARB:
1771      case GL_TEXTURE_GREEN_TYPE_ARB:
1772      case GL_TEXTURE_BLUE_TYPE_ARB:
1773      case GL_TEXTURE_ALPHA_TYPE_ARB:
1774      case GL_TEXTURE_DEPTH_TYPE_ARB:
1775         if (!ctx->Extensions.ARB_texture_float)
1776            goto invalid_pname;
1777	 if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
1778	    *params = _mesa_get_format_datatype(texFormat);
1779	 else
1780	    *params = GL_NONE;
1781         break;
1782
1783      /* GL_ARB_texture_multisample */
1784      case GL_TEXTURE_SAMPLES:
1785         if (!ctx->Extensions.ARB_texture_multisample)
1786            goto invalid_pname;
1787         *params = img->NumSamples;
1788         break;
1789
1790      case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
1791         if (!ctx->Extensions.ARB_texture_multisample)
1792            goto invalid_pname;
1793         *params = img->FixedSampleLocations;
1794         break;
1795
1796      /* There is never a buffer data store here, but these pnames still have
1797       * to work.
1798       */
1799
1800      /* GL_ARB_texture_buffer_object */
1801      case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
1802         if (!ctx->Extensions.ARB_texture_buffer_object)
1803            goto invalid_pname;
1804         *params = 0;
1805         break;
1806
1807      /* GL_ARB_texture_buffer_range */
1808      case GL_TEXTURE_BUFFER_OFFSET:
1809         if (!ctx->Extensions.ARB_texture_buffer_range)
1810            goto invalid_pname;
1811         *params = 0;
1812         break;
1813      case GL_TEXTURE_BUFFER_SIZE:
1814         if (!ctx->Extensions.ARB_texture_buffer_range)
1815            goto invalid_pname;
1816         *params = 0;
1817         break;
1818
1819      default:
1820         goto invalid_pname;
1821   }
1822
1823   /* no error if we get here */
1824   return;
1825
1826invalid_pname:
1827   _mesa_error(ctx, GL_INVALID_ENUM,
1828               "glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
1829               _mesa_enum_to_string(pname));
1830}
1831
1832
1833/**
1834 * Handle a glGetTexLevelParamteriv() call for a texture buffer.
1835 */
1836static void
1837get_tex_level_parameter_buffer(struct gl_context *ctx,
1838                               const struct gl_texture_object *texObj,
1839                               GLenum pname, GLint *params, bool dsa)
1840{
1841   const struct gl_buffer_object *bo = texObj->BufferObject;
1842   mesa_format texFormat = texObj->_BufferObjectFormat;
1843   int bytes = MAX2(1, _mesa_get_format_bytes(texFormat));
1844   GLenum internalFormat = texObj->BufferObjectFormat;
1845   GLenum baseFormat = _mesa_get_format_base_format(texFormat);
1846   const char *suffix = dsa ? "ture" : "";
1847
1848   assert(texObj->Target == GL_TEXTURE_BUFFER);
1849
1850   if (!bo) {
1851      /* undefined texture buffer object */
1852      switch (pname) {
1853      case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
1854         *params = GL_TRUE;
1855         break;
1856      case GL_TEXTURE_INTERNAL_FORMAT:
1857         *params = internalFormat;
1858         break;
1859      default:
1860         *params = 0;
1861         break;
1862      }
1863      return;
1864   }
1865
1866   switch (pname) {
1867      case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
1868         *params = bo->Name;
1869         break;
1870      case GL_TEXTURE_WIDTH:
1871         *params = ((texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize)
1872            / bytes;
1873         break;
1874      case GL_TEXTURE_HEIGHT:
1875      case GL_TEXTURE_DEPTH:
1876         *params = 1;
1877         break;
1878      case GL_TEXTURE_BORDER:
1879      case GL_TEXTURE_SHARED_SIZE:
1880      case GL_TEXTURE_COMPRESSED:
1881         *params = 0;
1882         break;
1883      case GL_TEXTURE_INTERNAL_FORMAT:
1884         *params = internalFormat;
1885         break;
1886      case GL_TEXTURE_RED_SIZE:
1887      case GL_TEXTURE_GREEN_SIZE:
1888      case GL_TEXTURE_BLUE_SIZE:
1889      case GL_TEXTURE_ALPHA_SIZE:
1890         if (_mesa_base_format_has_channel(baseFormat, pname))
1891            *params = _mesa_get_format_bits(texFormat, pname);
1892         else
1893            *params = 0;
1894         break;
1895      case GL_TEXTURE_INTENSITY_SIZE:
1896      case GL_TEXTURE_LUMINANCE_SIZE:
1897         if (_mesa_base_format_has_channel(baseFormat, pname)) {
1898            *params = _mesa_get_format_bits(texFormat, pname);
1899            if (*params == 0) {
1900               /* intensity or luminance is probably stored as RGB[A] */
1901               *params = MIN2(_mesa_get_format_bits(texFormat,
1902                                                    GL_TEXTURE_RED_SIZE),
1903                              _mesa_get_format_bits(texFormat,
1904                                                    GL_TEXTURE_GREEN_SIZE));
1905            }
1906         } else {
1907            *params = 0;
1908         }
1909         break;
1910      case GL_TEXTURE_DEPTH_SIZE_ARB:
1911      case GL_TEXTURE_STENCIL_SIZE_EXT:
1912         *params = _mesa_get_format_bits(texFormat, pname);
1913         break;
1914
1915      /* GL_ARB_texture_buffer_range */
1916      case GL_TEXTURE_BUFFER_OFFSET:
1917         if (!ctx->Extensions.ARB_texture_buffer_range)
1918            goto invalid_pname;
1919         *params = texObj->BufferOffset;
1920         break;
1921      case GL_TEXTURE_BUFFER_SIZE:
1922         if (!ctx->Extensions.ARB_texture_buffer_range)
1923            goto invalid_pname;
1924         *params = (texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize;
1925         break;
1926
1927      /* GL_ARB_texture_multisample */
1928      case GL_TEXTURE_SAMPLES:
1929         if (!ctx->Extensions.ARB_texture_multisample)
1930            goto invalid_pname;
1931         *params = 0;
1932         break;
1933
1934      case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
1935         if (!ctx->Extensions.ARB_texture_multisample)
1936            goto invalid_pname;
1937         *params = GL_TRUE;
1938         break;
1939
1940      /* GL_ARB_texture_compression */
1941      case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
1942         /* Always illegal for GL_TEXTURE_BUFFER */
1943         _mesa_error(ctx, GL_INVALID_OPERATION,
1944                     "glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
1945                     _mesa_enum_to_string(pname));
1946         break;
1947
1948      /* GL_ARB_texture_float */
1949      case GL_TEXTURE_RED_TYPE_ARB:
1950      case GL_TEXTURE_GREEN_TYPE_ARB:
1951      case GL_TEXTURE_BLUE_TYPE_ARB:
1952      case GL_TEXTURE_ALPHA_TYPE_ARB:
1953      case GL_TEXTURE_LUMINANCE_TYPE_ARB:
1954      case GL_TEXTURE_INTENSITY_TYPE_ARB:
1955      case GL_TEXTURE_DEPTH_TYPE_ARB:
1956         if (!ctx->Extensions.ARB_texture_float)
1957            goto invalid_pname;
1958         if (_mesa_base_format_has_channel(baseFormat, pname))
1959            *params = _mesa_get_format_datatype(texFormat);
1960         else
1961            *params = GL_NONE;
1962         break;
1963
1964      default:
1965         goto invalid_pname;
1966   }
1967
1968   /* no error if we get here */
1969   return;
1970
1971invalid_pname:
1972   _mesa_error(ctx, GL_INVALID_ENUM,
1973               "glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
1974               _mesa_enum_to_string(pname));
1975}
1976
1977static bool
1978valid_tex_level_parameteriv_target(struct gl_context *ctx, GLenum target,
1979                                   bool dsa)
1980{
1981   const char *suffix = dsa ? "ture" : "";
1982   if (!_mesa_legal_get_tex_level_parameter_target(ctx, target, dsa)) {
1983      _mesa_error(ctx, GL_INVALID_ENUM,
1984                  "glGetTex%sLevelParameter[if]v(target=%s)", suffix,
1985                  _mesa_enum_to_string(target));
1986      return false;
1987   }
1988   return true;
1989}
1990
1991/**
1992 * This isn't exposed to the rest of the driver because it is a part of the
1993 * OpenGL API that is rarely used.
1994 */
1995static void
1996get_tex_level_parameteriv(struct gl_context *ctx,
1997                          struct gl_texture_object *texObj,
1998                          GLenum target, GLint level,
1999                          GLenum pname, GLint *params,
2000                          bool dsa)
2001{
2002   GLint maxLevels;
2003   const char *suffix = dsa ? "ture" : "";
2004
2005   /* Check for errors */
2006   if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
2007      _mesa_error(ctx, GL_INVALID_OPERATION,
2008                  "glGetTex%sLevelParameter[if]v("
2009                  "current unit >= max combined texture units)", suffix);
2010      return;
2011   }
2012
2013   maxLevels = _mesa_max_texture_levels(ctx, target);
2014   assert(maxLevels != 0);
2015
2016   if (level < 0 || level >= maxLevels) {
2017      _mesa_error(ctx, GL_INVALID_VALUE,
2018                  "glGetTex%sLevelParameter[if]v(level out of range)", suffix);
2019      return;
2020   }
2021
2022   /* Get the level parameter */
2023   if (target == GL_TEXTURE_BUFFER) {
2024      get_tex_level_parameter_buffer(ctx, texObj, pname, params, dsa);
2025   }
2026   else {
2027      get_tex_level_parameter_image(ctx, texObj, target,
2028                                    level, pname, params, dsa);
2029   }
2030}
2031
2032void GLAPIENTRY
2033_mesa_GetTexLevelParameterfv( GLenum target, GLint level,
2034                              GLenum pname, GLfloat *params )
2035{
2036   struct gl_texture_object *texObj;
2037   GLint iparam;
2038   GET_CURRENT_CONTEXT(ctx);
2039
2040   if (!valid_tex_level_parameteriv_target(ctx, target, false))
2041      return;
2042
2043   texObj = _mesa_get_current_tex_object(ctx, target);
2044   if (!texObj)
2045      return;
2046
2047   get_tex_level_parameteriv(ctx, texObj, target, level,
2048                             pname, &iparam, false);
2049
2050   *params = (GLfloat) iparam;
2051}
2052
2053void GLAPIENTRY
2054_mesa_GetTexLevelParameteriv( GLenum target, GLint level,
2055                              GLenum pname, GLint *params )
2056{
2057   struct gl_texture_object *texObj;
2058   GET_CURRENT_CONTEXT(ctx);
2059
2060   if (!valid_tex_level_parameteriv_target(ctx, target, false))
2061      return;
2062
2063   texObj = _mesa_get_current_tex_object(ctx, target);
2064   if (!texObj)
2065      return;
2066
2067   get_tex_level_parameteriv(ctx, texObj, target, level,
2068                             pname, params, false);
2069}
2070
2071void GLAPIENTRY
2072_mesa_GetTextureLevelParameterfv(GLuint texture, GLint level,
2073                                 GLenum pname, GLfloat *params)
2074{
2075   struct gl_texture_object *texObj;
2076   GLint iparam;
2077   GET_CURRENT_CONTEXT(ctx);
2078
2079   texObj = _mesa_lookup_texture_err(ctx, texture,
2080                                     "glGetTextureLevelParameterfv");
2081   if (!texObj)
2082      return;
2083
2084   if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true))
2085      return;
2086
2087   get_tex_level_parameteriv(ctx, texObj, texObj->Target, level,
2088                             pname, &iparam, true);
2089
2090   *params = (GLfloat) iparam;
2091}
2092
2093void GLAPIENTRY
2094_mesa_GetTextureLevelParameterfvEXT(GLuint texture, GLenum target, GLint level,
2095                                    GLenum pname, GLfloat *params)
2096{
2097   struct gl_texture_object *texObj;
2098   GLint iparam;
2099   GET_CURRENT_CONTEXT(ctx);
2100
2101   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
2102                                           "glGetTextureLevelParameterfvEXT");
2103   if (!texObj)
2104      return;
2105
2106   if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true))
2107      return;
2108
2109   get_tex_level_parameteriv(ctx, texObj, texObj->Target, level,
2110                             pname, &iparam, true);
2111
2112   *params = (GLfloat) iparam;
2113}
2114
2115void GLAPIENTRY
2116_mesa_GetMultiTexLevelParameterfvEXT(GLenum texunit, GLenum target, GLint level,
2117                                     GLenum pname, GLfloat *params)
2118{
2119   struct gl_texture_object *texObj;
2120   GLint iparam;
2121   GET_CURRENT_CONTEXT(ctx);
2122
2123   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
2124                                                   texunit - GL_TEXTURE0,
2125                                                   true,
2126                                                   "glGetMultiTexLevelParameterfvEXT");
2127   if (!texObj)
2128      return;
2129
2130   if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true))
2131      return;
2132
2133   get_tex_level_parameteriv(ctx, texObj, texObj->Target, level,
2134                             pname, &iparam, true);
2135
2136   *params = (GLfloat) iparam;
2137}
2138
2139void GLAPIENTRY
2140_mesa_GetTextureLevelParameteriv(GLuint texture, GLint level,
2141                                 GLenum pname, GLint *params)
2142{
2143   struct gl_texture_object *texObj;
2144   GET_CURRENT_CONTEXT(ctx);
2145
2146   texObj = _mesa_lookup_texture_err(ctx, texture,
2147                                     "glGetTextureLevelParameteriv");
2148   if (!texObj)
2149      return;
2150
2151   if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true))
2152      return;
2153
2154   get_tex_level_parameteriv(ctx, texObj, texObj->Target, level,
2155                             pname, params, true);
2156}
2157
2158void GLAPIENTRY
2159_mesa_GetTextureLevelParameterivEXT(GLuint texture, GLenum target, GLint level,
2160                                    GLenum pname, GLint *params)
2161{
2162   struct gl_texture_object *texObj;
2163   GET_CURRENT_CONTEXT(ctx);
2164
2165   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
2166                                           "glGetTextureLevelParameterivEXT");
2167   if (!texObj)
2168      return;
2169
2170   if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true))
2171      return;
2172
2173   get_tex_level_parameteriv(ctx, texObj, texObj->Target, level,
2174                             pname, params, true);
2175}
2176
2177void GLAPIENTRY
2178_mesa_GetMultiTexLevelParameterivEXT(GLenum texunit, GLenum target, GLint level,
2179                                     GLenum pname, GLint *params)
2180{
2181   struct gl_texture_object *texObj;
2182   GET_CURRENT_CONTEXT(ctx);
2183
2184   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
2185                                                   texunit - GL_TEXTURE0,
2186                                                   true,
2187                                                   "glGetMultiTexLevelParameterivEXT");
2188   if (!texObj)
2189      return;
2190
2191   if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true))
2192      return;
2193
2194   get_tex_level_parameteriv(ctx, texObj, texObj->Target, level,
2195                             pname, params, true);
2196}
2197
2198
2199/**
2200 * This isn't exposed to the rest of the driver because it is a part of the
2201 * OpenGL API that is rarely used.
2202 */
2203static void
2204get_tex_parameterfv(struct gl_context *ctx,
2205                    struct gl_texture_object *obj,
2206                    GLenum pname, GLfloat *params, bool dsa)
2207{
2208   _mesa_lock_context_textures(ctx);
2209   switch (pname) {
2210      case GL_TEXTURE_MAG_FILTER:
2211	 *params = ENUM_TO_FLOAT(obj->Sampler.Attrib.MagFilter);
2212	 break;
2213      case GL_TEXTURE_MIN_FILTER:
2214         *params = ENUM_TO_FLOAT(obj->Sampler.Attrib.MinFilter);
2215         break;
2216      case GL_TEXTURE_WRAP_S:
2217         *params = ENUM_TO_FLOAT(obj->Sampler.Attrib.WrapS);
2218         break;
2219      case GL_TEXTURE_WRAP_T:
2220         *params = ENUM_TO_FLOAT(obj->Sampler.Attrib.WrapT);
2221         break;
2222      case GL_TEXTURE_WRAP_R:
2223         *params = ENUM_TO_FLOAT(obj->Sampler.Attrib.WrapR);
2224         break;
2225      case GL_TEXTURE_BORDER_COLOR:
2226         if (ctx->API == API_OPENGLES ||
2227             !ctx->Extensions.ARB_texture_border_clamp)
2228            goto invalid_pname;
2229
2230         if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer)) {
2231            params[0] = CLAMP(obj->Sampler.Attrib.state.border_color.f[0], 0.0F, 1.0F);
2232            params[1] = CLAMP(obj->Sampler.Attrib.state.border_color.f[1], 0.0F, 1.0F);
2233            params[2] = CLAMP(obj->Sampler.Attrib.state.border_color.f[2], 0.0F, 1.0F);
2234            params[3] = CLAMP(obj->Sampler.Attrib.state.border_color.f[3], 0.0F, 1.0F);
2235         }
2236         else {
2237            params[0] = obj->Sampler.Attrib.state.border_color.f[0];
2238            params[1] = obj->Sampler.Attrib.state.border_color.f[1];
2239            params[2] = obj->Sampler.Attrib.state.border_color.f[2];
2240            params[3] = obj->Sampler.Attrib.state.border_color.f[3];
2241         }
2242         break;
2243      case GL_TEXTURE_RESIDENT:
2244         if (ctx->API != API_OPENGL_COMPAT)
2245            goto invalid_pname;
2246
2247         *params = 1.0F;
2248         break;
2249      case GL_TEXTURE_PRIORITY:
2250         if (ctx->API != API_OPENGL_COMPAT)
2251            goto invalid_pname;
2252
2253         *params = obj->Attrib.Priority;
2254         break;
2255      case GL_TEXTURE_MIN_LOD:
2256         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
2257            goto invalid_pname;
2258
2259         *params = obj->Sampler.Attrib.MinLod;
2260         break;
2261      case GL_TEXTURE_MAX_LOD:
2262         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
2263            goto invalid_pname;
2264
2265         *params = obj->Sampler.Attrib.MaxLod;
2266         break;
2267      case GL_TEXTURE_BASE_LEVEL:
2268         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
2269            goto invalid_pname;
2270
2271         *params = (GLfloat) obj->Attrib.BaseLevel;
2272         break;
2273      case GL_TEXTURE_MAX_LEVEL:
2274         *params = (GLfloat) obj->Attrib.MaxLevel;
2275         break;
2276      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
2277         if (!ctx->Extensions.EXT_texture_filter_anisotropic)
2278            goto invalid_pname;
2279         *params = obj->Sampler.Attrib.MaxAnisotropy;
2280         break;
2281      case GL_GENERATE_MIPMAP_SGIS:
2282         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
2283            goto invalid_pname;
2284
2285	 *params = (GLfloat) obj->Attrib.GenerateMipmap;
2286         break;
2287      case GL_TEXTURE_COMPARE_MODE_ARB:
2288         if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
2289             && !_mesa_is_gles3(ctx))
2290            goto invalid_pname;
2291         *params = (GLfloat) obj->Sampler.Attrib.CompareMode;
2292         break;
2293      case GL_TEXTURE_COMPARE_FUNC_ARB:
2294         if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
2295             && !_mesa_is_gles3(ctx))
2296            goto invalid_pname;
2297         *params = (GLfloat) obj->Sampler.Attrib.CompareFunc;
2298         break;
2299      case GL_DEPTH_TEXTURE_MODE_ARB:
2300         /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has
2301          * never existed in OpenGL ES.
2302          */
2303         if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture)
2304            goto invalid_pname;
2305         *params = (GLfloat) obj->Attrib.DepthMode;
2306         break;
2307      case GL_DEPTH_STENCIL_TEXTURE_MODE:
2308         if (!_mesa_has_ARB_stencil_texturing(ctx) && !_mesa_is_gles31(ctx))
2309            goto invalid_pname;
2310         *params = (GLfloat)
2311            (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT);
2312         break;
2313      case GL_TEXTURE_LOD_BIAS:
2314         if (_mesa_is_gles(ctx))
2315            goto invalid_pname;
2316
2317         *params = obj->Sampler.Attrib.LodBias;
2318         break;
2319      case GL_TEXTURE_CROP_RECT_OES:
2320         if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
2321            goto invalid_pname;
2322
2323         params[0] = (GLfloat) obj->CropRect[0];
2324         params[1] = (GLfloat) obj->CropRect[1];
2325         params[2] = (GLfloat) obj->CropRect[2];
2326         params[3] = (GLfloat) obj->CropRect[3];
2327         break;
2328
2329      case GL_TEXTURE_SWIZZLE_R_EXT:
2330      case GL_TEXTURE_SWIZZLE_G_EXT:
2331      case GL_TEXTURE_SWIZZLE_B_EXT:
2332      case GL_TEXTURE_SWIZZLE_A_EXT:
2333         if ((!_mesa_is_desktop_gl(ctx)
2334              || !ctx->Extensions.EXT_texture_swizzle)
2335             && !_mesa_is_gles3(ctx))
2336            goto invalid_pname;
2337         *params = (GLfloat) obj->Attrib.Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
2338         break;
2339
2340      case GL_TEXTURE_SWIZZLE_RGBA_EXT:
2341         if ((!_mesa_is_desktop_gl(ctx)
2342              || !ctx->Extensions.EXT_texture_swizzle)
2343             && !_mesa_is_gles3(ctx)) {
2344            goto invalid_pname;
2345         }
2346         else {
2347            GLuint comp;
2348            for (comp = 0; comp < 4; comp++) {
2349               params[comp] = (GLfloat) obj->Attrib.Swizzle[comp];
2350            }
2351         }
2352         break;
2353
2354      case GL_TEXTURE_CUBE_MAP_SEAMLESS:
2355         if (!_mesa_is_desktop_gl(ctx)
2356             || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
2357            goto invalid_pname;
2358         *params = (GLfloat) obj->Sampler.Attrib.CubeMapSeamless;
2359         break;
2360
2361      case GL_TEXTURE_IMMUTABLE_FORMAT:
2362         *params = (GLfloat) obj->Immutable;
2363         break;
2364
2365      case GL_TEXTURE_IMMUTABLE_LEVELS:
2366         if (_mesa_is_gles3(ctx) || _mesa_has_texture_view(ctx))
2367            *params = (GLfloat) obj->Attrib.ImmutableLevels;
2368         else
2369            goto invalid_pname;
2370         break;
2371
2372      case GL_TEXTURE_VIEW_MIN_LEVEL:
2373         if (!_mesa_has_texture_view(ctx))
2374            goto invalid_pname;
2375         *params = (GLfloat) obj->Attrib.MinLevel;
2376         break;
2377
2378      case GL_TEXTURE_VIEW_NUM_LEVELS:
2379         if (!_mesa_has_texture_view(ctx))
2380            goto invalid_pname;
2381         *params = (GLfloat) obj->Attrib.NumLevels;
2382         break;
2383
2384      case GL_TEXTURE_VIEW_MIN_LAYER:
2385         if (!_mesa_has_texture_view(ctx))
2386            goto invalid_pname;
2387         *params = (GLfloat) obj->Attrib.MinLayer;
2388         break;
2389
2390      case GL_TEXTURE_VIEW_NUM_LAYERS:
2391         if (!_mesa_has_texture_view(ctx))
2392            goto invalid_pname;
2393         *params = (GLfloat) obj->Attrib.NumLayers;
2394         break;
2395
2396      case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
2397         if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
2398            goto invalid_pname;
2399         *params = (GLfloat) obj->RequiredTextureImageUnits;
2400         break;
2401
2402      case GL_TEXTURE_SRGB_DECODE_EXT:
2403         if (!ctx->Extensions.EXT_texture_sRGB_decode)
2404            goto invalid_pname;
2405         *params = (GLfloat) obj->Sampler.Attrib.sRGBDecode;
2406         break;
2407
2408      case GL_TEXTURE_REDUCTION_MODE_EXT:
2409         if (!ctx->Extensions.EXT_texture_filter_minmax &&
2410             !_mesa_has_ARB_texture_filter_minmax(ctx))
2411            goto invalid_pname;
2412         *params = (GLfloat) obj->Sampler.Attrib.ReductionMode;
2413         break;
2414
2415      case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
2416         if (!ctx->Extensions.ARB_shader_image_load_store)
2417            goto invalid_pname;
2418         *params = (GLfloat) obj->Attrib.ImageFormatCompatibilityType;
2419         break;
2420
2421      case GL_TEXTURE_TARGET:
2422         if (ctx->API != API_OPENGL_CORE)
2423            goto invalid_pname;
2424         *params = ENUM_TO_FLOAT(obj->Target);
2425         break;
2426
2427      case GL_TEXTURE_TILING_EXT:
2428         if (!ctx->Extensions.EXT_memory_object)
2429            goto invalid_pname;
2430         *params = ENUM_TO_FLOAT(obj->TextureTiling);
2431         break;
2432
2433      default:
2434         goto invalid_pname;
2435   }
2436
2437   /* no error if we get here */
2438   _mesa_unlock_context_textures(ctx);
2439   return;
2440
2441invalid_pname:
2442   _mesa_unlock_context_textures(ctx);
2443   _mesa_error(ctx, GL_INVALID_ENUM, "glGetTex%sParameterfv(pname=0x%x)",
2444               dsa ? "ture" : "", pname);
2445}
2446
2447
2448static void
2449get_tex_parameteriv(struct gl_context *ctx,
2450                    struct gl_texture_object *obj,
2451                    GLenum pname, GLint *params, bool dsa)
2452{
2453   _mesa_lock_texture(ctx, obj);
2454   switch (pname) {
2455      case GL_TEXTURE_MAG_FILTER:
2456         *params = (GLint) obj->Sampler.Attrib.MagFilter;
2457         break;
2458      case GL_TEXTURE_MIN_FILTER:
2459         *params = (GLint) obj->Sampler.Attrib.MinFilter;
2460         break;
2461      case GL_TEXTURE_WRAP_S:
2462         *params = (GLint) obj->Sampler.Attrib.WrapS;
2463         break;
2464      case GL_TEXTURE_WRAP_T:
2465         *params = (GLint) obj->Sampler.Attrib.WrapT;
2466         break;
2467      case GL_TEXTURE_WRAP_R:
2468         *params = (GLint) obj->Sampler.Attrib.WrapR;
2469         break;
2470      case GL_TEXTURE_BORDER_COLOR:
2471         if (ctx->API == API_OPENGLES ||
2472             !ctx->Extensions.ARB_texture_border_clamp)
2473            goto invalid_pname;
2474
2475         {
2476            GLfloat b[4];
2477            b[0] = CLAMP(obj->Sampler.Attrib.state.border_color.f[0], 0.0F, 1.0F);
2478            b[1] = CLAMP(obj->Sampler.Attrib.state.border_color.f[1], 0.0F, 1.0F);
2479            b[2] = CLAMP(obj->Sampler.Attrib.state.border_color.f[2], 0.0F, 1.0F);
2480            b[3] = CLAMP(obj->Sampler.Attrib.state.border_color.f[3], 0.0F, 1.0F);
2481            params[0] = FLOAT_TO_INT(b[0]);
2482            params[1] = FLOAT_TO_INT(b[1]);
2483            params[2] = FLOAT_TO_INT(b[2]);
2484            params[3] = FLOAT_TO_INT(b[3]);
2485         }
2486         break;
2487      case GL_TEXTURE_RESIDENT:
2488         if (ctx->API != API_OPENGL_COMPAT)
2489            goto invalid_pname;
2490
2491         *params = 1;
2492         break;
2493      case GL_TEXTURE_PRIORITY:
2494         if (ctx->API != API_OPENGL_COMPAT)
2495            goto invalid_pname;
2496
2497         *params = FLOAT_TO_INT(obj->Attrib.Priority);
2498         break;
2499      case GL_TEXTURE_MIN_LOD:
2500         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
2501            goto invalid_pname;
2502         /* GL spec 'Data Conversions' section specifies that floating-point
2503          * value in integer Get function is rounded to nearest integer
2504          *
2505          * Section 2.2.2 (Data Conversions For State Query Commands) of the
2506          * OpenGL 4.5 spec says:
2507          *
2508          *   Following these steps, if a value is so large in magnitude that
2509          *   it cannot be represented by the returned data type, then the
2510          *   nearest value representable using that type is returned.
2511          */
2512         *params = LCLAMPF(obj->Sampler.Attrib.MinLod, INT_MIN, INT_MAX);
2513         break;
2514      case GL_TEXTURE_MAX_LOD:
2515         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
2516            goto invalid_pname;
2517         /* GL spec 'Data Conversions' section specifies that floating-point
2518          * value in integer Get function is rounded to nearest integer
2519          *
2520          * Section 2.2.2 (Data Conversions For State Query Commands) of the
2521          * OpenGL 4.5 spec says:
2522          *
2523          *   Following these steps, if a value is so large in magnitude that
2524          *   it cannot be represented by the returned data type, then the
2525          *   nearest value representable using that type is returned.
2526          */
2527         *params = LCLAMPF(obj->Sampler.Attrib.MaxLod, INT_MIN, INT_MAX);
2528         break;
2529      case GL_TEXTURE_BASE_LEVEL:
2530         if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
2531            goto invalid_pname;
2532
2533         *params = obj->Attrib.BaseLevel;
2534         break;
2535      case GL_TEXTURE_MAX_LEVEL:
2536         *params = obj->Attrib.MaxLevel;
2537         break;
2538      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
2539         if (!ctx->Extensions.EXT_texture_filter_anisotropic)
2540            goto invalid_pname;
2541         /* GL spec 'Data Conversions' section specifies that floating-point
2542          * value in integer Get function is rounded to nearest integer
2543          *
2544          * Section 2.2.2 (Data Conversions For State Query Commands) of the
2545          * OpenGL 4.5 spec says:
2546          *
2547          *   Following these steps, if a value is so large in magnitude that
2548          *   it cannot be represented by the returned data type, then the
2549          *   nearest value representable using that type is returned.
2550          */
2551         *params = LCLAMPF(obj->Sampler.Attrib.MaxAnisotropy, INT_MIN, INT_MAX);
2552         break;
2553      case GL_GENERATE_MIPMAP_SGIS:
2554         if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
2555            goto invalid_pname;
2556
2557	 *params = (GLint) obj->Attrib.GenerateMipmap;
2558         break;
2559      case GL_TEXTURE_COMPARE_MODE_ARB:
2560         if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
2561             && !_mesa_is_gles3(ctx))
2562            goto invalid_pname;
2563         *params = (GLint) obj->Sampler.Attrib.CompareMode;
2564         break;
2565      case GL_TEXTURE_COMPARE_FUNC_ARB:
2566         if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
2567             && !_mesa_is_gles3(ctx))
2568            goto invalid_pname;
2569         *params = (GLint) obj->Sampler.Attrib.CompareFunc;
2570         break;
2571      case GL_DEPTH_TEXTURE_MODE_ARB:
2572         if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture)
2573            goto invalid_pname;
2574         *params = (GLint) obj->Attrib.DepthMode;
2575         break;
2576      case GL_DEPTH_STENCIL_TEXTURE_MODE:
2577         if (!_mesa_has_ARB_stencil_texturing(ctx) && !_mesa_is_gles31(ctx))
2578            goto invalid_pname;
2579         *params = (GLint)
2580            (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT);
2581         break;
2582      case GL_TEXTURE_LOD_BIAS:
2583         if (_mesa_is_gles(ctx))
2584            goto invalid_pname;
2585
2586         /* GL spec 'Data Conversions' section specifies that floating-point
2587          * value in integer Get function is rounded to nearest integer
2588          *
2589          * Section 2.2.2 (Data Conversions For State Query Commands) of the
2590          * OpenGL 4.5 spec says:
2591          *
2592          *   Following these steps, if a value is so large in magnitude that
2593          *   it cannot be represented by the returned data type, then the
2594          *   nearest value representable using that type is returned.
2595          */
2596         *params = LCLAMPF(obj->Sampler.Attrib.LodBias, INT_MIN, INT_MAX);
2597         break;
2598      case GL_TEXTURE_CROP_RECT_OES:
2599         if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
2600            goto invalid_pname;
2601
2602         params[0] = obj->CropRect[0];
2603         params[1] = obj->CropRect[1];
2604         params[2] = obj->CropRect[2];
2605         params[3] = obj->CropRect[3];
2606         break;
2607      case GL_TEXTURE_SWIZZLE_R_EXT:
2608      case GL_TEXTURE_SWIZZLE_G_EXT:
2609      case GL_TEXTURE_SWIZZLE_B_EXT:
2610      case GL_TEXTURE_SWIZZLE_A_EXT:
2611         if ((!_mesa_is_desktop_gl(ctx)
2612              || !ctx->Extensions.EXT_texture_swizzle)
2613             && !_mesa_is_gles3(ctx))
2614            goto invalid_pname;
2615         *params = obj->Attrib.Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
2616         break;
2617
2618      case GL_TEXTURE_SWIZZLE_RGBA_EXT:
2619         if ((!_mesa_is_desktop_gl(ctx)
2620              || !ctx->Extensions.EXT_texture_swizzle)
2621             && !_mesa_is_gles3(ctx))
2622            goto invalid_pname;
2623         COPY_4V(params, obj->Attrib.Swizzle);
2624         break;
2625
2626      case GL_TEXTURE_CUBE_MAP_SEAMLESS:
2627         if (!_mesa_is_desktop_gl(ctx)
2628             || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
2629            goto invalid_pname;
2630         *params = (GLint) obj->Sampler.Attrib.CubeMapSeamless;
2631         break;
2632
2633      case GL_TEXTURE_IMMUTABLE_FORMAT:
2634         *params = (GLint) obj->Immutable;
2635         break;
2636
2637      case GL_TEXTURE_IMMUTABLE_LEVELS:
2638         if (_mesa_is_gles3(ctx) ||
2639             (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view))
2640            *params = obj->Attrib.ImmutableLevels;
2641         else
2642            goto invalid_pname;
2643         break;
2644
2645      case GL_TEXTURE_VIEW_MIN_LEVEL:
2646         if (!ctx->Extensions.ARB_texture_view)
2647            goto invalid_pname;
2648         *params = (GLint) obj->Attrib.MinLevel;
2649         break;
2650
2651      case GL_TEXTURE_VIEW_NUM_LEVELS:
2652         if (!ctx->Extensions.ARB_texture_view)
2653            goto invalid_pname;
2654         *params = (GLint) obj->Attrib.NumLevels;
2655         break;
2656
2657      case GL_TEXTURE_VIEW_MIN_LAYER:
2658         if (!ctx->Extensions.ARB_texture_view)
2659            goto invalid_pname;
2660         *params = (GLint) obj->Attrib.MinLayer;
2661         break;
2662
2663      case GL_TEXTURE_VIEW_NUM_LAYERS:
2664         if (!ctx->Extensions.ARB_texture_view)
2665            goto invalid_pname;
2666         *params = (GLint) obj->Attrib.NumLayers;
2667         break;
2668
2669      case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
2670         if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
2671            goto invalid_pname;
2672         *params = obj->RequiredTextureImageUnits;
2673         break;
2674
2675      case GL_TEXTURE_SRGB_DECODE_EXT:
2676         if (!ctx->Extensions.EXT_texture_sRGB_decode)
2677            goto invalid_pname;
2678         *params = obj->Sampler.Attrib.sRGBDecode;
2679         break;
2680
2681      case GL_TEXTURE_REDUCTION_MODE_EXT:
2682         if (!ctx->Extensions.EXT_texture_filter_minmax &&
2683             !_mesa_has_ARB_texture_filter_minmax(ctx))
2684            goto invalid_pname;
2685         *params = obj->Sampler.Attrib.ReductionMode;
2686         break;
2687
2688      case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
2689         if (!ctx->Extensions.ARB_shader_image_load_store)
2690            goto invalid_pname;
2691         *params = obj->Attrib.ImageFormatCompatibilityType;
2692         break;
2693
2694      case GL_TEXTURE_TARGET:
2695         if (ctx->API != API_OPENGL_CORE)
2696            goto invalid_pname;
2697         *params = (GLint) obj->Target;
2698         break;
2699
2700      case GL_TEXTURE_TILING_EXT:
2701         if (!ctx->Extensions.EXT_memory_object)
2702            goto invalid_pname;
2703         *params = (GLint) obj->TextureTiling;
2704         break;
2705
2706      default:
2707         goto invalid_pname;
2708   }
2709
2710   /* no error if we get here */
2711   _mesa_unlock_texture(ctx, obj);
2712   return;
2713
2714invalid_pname:
2715   _mesa_unlock_texture(ctx, obj);
2716   _mesa_error(ctx, GL_INVALID_ENUM, "glGetTex%sParameteriv(pname=0x%x)",
2717               dsa ? "ture" : "", pname);
2718}
2719
2720static void
2721get_tex_parameterIiv(struct gl_context *ctx,
2722                     struct gl_texture_object *obj,
2723                     GLenum pname, GLint *params, bool dsa)
2724{
2725   switch (pname) {
2726   case GL_TEXTURE_BORDER_COLOR:
2727      COPY_4V(params, obj->Sampler.Attrib.state.border_color.i);
2728      break;
2729   default:
2730      get_tex_parameteriv(ctx, obj, pname, params, dsa);
2731   }
2732}
2733
2734void GLAPIENTRY
2735_mesa_GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
2736{
2737   struct gl_texture_object *obj;
2738   GET_CURRENT_CONTEXT(ctx);
2739
2740   obj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
2741                                                ctx->Texture.CurrentUnit,
2742                                                false,
2743                                                "glGetTexParameterfv");
2744   if (!obj)
2745      return;
2746
2747   get_tex_parameterfv(ctx, obj, pname, params, false);
2748}
2749
2750void GLAPIENTRY
2751_mesa_GetTexParameteriv(GLenum target, GLenum pname, GLint *params)
2752{
2753   struct gl_texture_object *obj;
2754   GET_CURRENT_CONTEXT(ctx);
2755
2756   obj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
2757                                                ctx->Texture.CurrentUnit,
2758                                                false,
2759                                                "glGetTexParameteriv");
2760   if (!obj)
2761      return;
2762
2763   get_tex_parameteriv(ctx, obj, pname, params, false);
2764}
2765
2766/** New in GL 3.0 */
2767void GLAPIENTRY
2768_mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params)
2769{
2770   struct gl_texture_object *texObj;
2771   GET_CURRENT_CONTEXT(ctx);
2772
2773   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
2774                                                ctx->Texture.CurrentUnit,
2775                                                false,
2776                                                "glGetTexParameterIiv");
2777   if (!texObj)
2778      return;
2779
2780   get_tex_parameterIiv(ctx, texObj, pname, params, false);
2781}
2782
2783
2784/** New in GL 3.0 */
2785void GLAPIENTRY
2786_mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)
2787{
2788   struct gl_texture_object *texObj;
2789   GET_CURRENT_CONTEXT(ctx);
2790
2791   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
2792                                                ctx->Texture.CurrentUnit,
2793                                                false,
2794                                                "glGetTexParameterIuiv");
2795   if (!texObj)
2796      return;
2797
2798   get_tex_parameterIiv(ctx, texObj, pname, (GLint *) params, false);
2799}
2800
2801void GLAPIENTRY
2802_mesa_GetTextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, GLfloat *params)
2803{
2804   struct gl_texture_object *texObj;
2805   GET_CURRENT_CONTEXT(ctx);
2806
2807   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
2808                                           "glGetTextureParameterfvEXT");
2809   if (!texObj)
2810      return;
2811
2812   if (!is_texparameteri_target_valid(texObj->Target)) {
2813      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTextureParameterfvEXT");
2814      return;
2815   }
2816
2817   get_tex_parameterfv(ctx, texObj, pname, params, true);
2818}
2819
2820void GLAPIENTRY
2821_mesa_GetMultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat *params)
2822{
2823   struct gl_texture_object *texObj;
2824   GET_CURRENT_CONTEXT(ctx);
2825
2826   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
2827                                                   texunit - GL_TEXTURE0,
2828                                                   false,
2829                                                   "glGetMultiTexParameterfvEXT");
2830   if (!texObj)
2831      return;
2832
2833   if (!is_texparameteri_target_valid(texObj->Target)) {
2834      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMultiTexParameterfvEXT");
2835      return;
2836   }
2837   get_tex_parameterfv(ctx, texObj, pname, params, true);
2838}
2839
2840void GLAPIENTRY
2841_mesa_GetTextureParameterfv(GLuint texture, GLenum pname, GLfloat *params)
2842{
2843   struct gl_texture_object *obj;
2844   GET_CURRENT_CONTEXT(ctx);
2845
2846   obj = get_texobj_by_name(ctx, texture, "glGetTextureParameterfv");
2847   if (!obj)
2848      return;
2849
2850   get_tex_parameterfv(ctx, obj, pname, params, true);
2851}
2852
2853void GLAPIENTRY
2854_mesa_GetTextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, GLint *params)
2855{
2856   struct gl_texture_object *texObj;
2857   GET_CURRENT_CONTEXT(ctx);
2858
2859   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
2860                                           "glGetTextureParameterivEXT");
2861   if (!texObj)
2862      return;
2863
2864   if (!is_texparameteri_target_valid(texObj->Target)) {
2865      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTextureParameterivEXT");
2866      return;
2867   }
2868   get_tex_parameteriv(ctx, texObj, pname, params, true);
2869}
2870
2871void GLAPIENTRY
2872_mesa_GetMultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname, GLint *params)
2873{
2874   struct gl_texture_object *texObj;
2875   GET_CURRENT_CONTEXT(ctx);
2876
2877   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
2878                                                   texunit - GL_TEXTURE0,
2879                                                   false,
2880                                                   "glGetMultiTexParameterivEXT");
2881   if (!texObj)
2882      return;
2883
2884   if (!is_texparameteri_target_valid(texObj->Target)) {
2885      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMultiTexParameterivEXT");
2886      return;
2887   }
2888   get_tex_parameteriv(ctx, texObj, pname, params, true);
2889}
2890
2891void GLAPIENTRY
2892_mesa_GetTextureParameteriv(GLuint texture, GLenum pname, GLint *params)
2893{
2894   struct gl_texture_object *obj;
2895   GET_CURRENT_CONTEXT(ctx);
2896
2897   obj = get_texobj_by_name(ctx, texture, "glGetTextureParameteriv");
2898   if (!obj)
2899      return;
2900
2901   get_tex_parameteriv(ctx, obj, pname, params, true);
2902}
2903
2904void GLAPIENTRY
2905_mesa_GetTextureParameterIiv(GLuint texture, GLenum pname, GLint *params)
2906{
2907   struct gl_texture_object *texObj;
2908   GET_CURRENT_CONTEXT(ctx);
2909
2910   texObj = get_texobj_by_name(ctx, texture, "glGetTextureParameterIiv");
2911   if (!texObj)
2912      return;
2913
2914   get_tex_parameterIiv(ctx, texObj, pname, params, true);
2915}
2916
2917void GLAPIENTRY
2918_mesa_GetTextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, GLint *params)
2919{
2920   struct gl_texture_object *texObj;
2921   GET_CURRENT_CONTEXT(ctx);
2922
2923   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
2924                                           "glGetTextureParameterIivEXT");
2925   if (!texObj)
2926      return;
2927
2928
2929   get_tex_parameterIiv(ctx, texObj, pname, params, true);
2930}
2931
2932void GLAPIENTRY
2933_mesa_GetMultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname,
2934                                 GLint *params)
2935{
2936   struct gl_texture_object *texObj;
2937   GET_CURRENT_CONTEXT(ctx);
2938
2939   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
2940                                                   texunit - GL_TEXTURE0,
2941                                                   true,
2942                                                   "glGetMultiTexParameterIiv");
2943   if (!texObj)
2944      return;
2945
2946   get_tex_parameterIiv(ctx, texObj, pname, params, true);
2947}
2948
2949void GLAPIENTRY
2950_mesa_GetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint *params)
2951{
2952   struct gl_texture_object *texObj;
2953   GET_CURRENT_CONTEXT(ctx);
2954
2955   texObj = get_texobj_by_name(ctx, texture, "glGetTextureParameterIuiv");
2956   if (!texObj)
2957      return;
2958
2959   get_tex_parameterIiv(ctx, texObj, pname, (GLint *) params, true);
2960}
2961
2962void GLAPIENTRY
2963_mesa_GetTextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname,
2964                                 GLuint *params)
2965{
2966   struct gl_texture_object *texObj;
2967   GET_CURRENT_CONTEXT(ctx);
2968
2969   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
2970                                           "glGetTextureParameterIuvEXT");
2971   if (!texObj)
2972      return;
2973
2974   get_tex_parameterIiv(ctx, texObj, pname, (GLint *) params, true);
2975}
2976
2977void GLAPIENTRY
2978_mesa_GetMultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname,
2979                               GLuint *params)
2980{
2981   struct gl_texture_object *texObj;
2982   GET_CURRENT_CONTEXT(ctx);
2983
2984   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
2985                                                   texunit - GL_TEXTURE0,
2986                                                   true,
2987                                                   "glGetMultiTexParameterIuiv");
2988   if (!texObj)
2989      return;
2990
2991   get_tex_parameterIiv(ctx, texObj, pname, (GLint *) params, true);
2992}
2993