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