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