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