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