• 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 "main/glheader.h"
34 #include "main/blend.h"
35 #include "main/context.h"
36 #include "main/enums.h"
37 #include "main/formats.h"
38 #include "main/glformats.h"
39 #include "main/macros.h"
40 #include "main/mtypes.h"
41 #include "main/state.h"
42 #include "main/texcompress.h"
43 #include "main/texobj.h"
44 #include "main/texparam.h"
45 #include "main/teximage.h"
46 #include "main/texstate.h"
47 #include "program/prog_instruction.h"
48 
49 
50 /**
51  * Check if a coordinate wrap mode is supported for the texture target.
52  * \return GL_TRUE if legal, GL_FALSE otherwise
53  */
54 static GLboolean
validate_texture_wrap_mode(struct gl_context * ctx,GLenum target,GLenum wrap)55 validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap)
56 {
57    const struct gl_extensions * const e = & ctx->Extensions;
58    const bool is_desktop_gl = _mesa_is_desktop_gl(ctx);
59    bool supported;
60 
61    switch (wrap) {
62    case GL_CLAMP:
63       /* GL_CLAMP was removed in the core profile, and it has never existed in
64        * OpenGL ES.
65        */
66       supported = (ctx->API == API_OPENGL_COMPAT)
67          && (target != GL_TEXTURE_EXTERNAL_OES);
68       break;
69 
70    case GL_CLAMP_TO_EDGE:
71       supported = true;
72       break;
73 
74    case GL_CLAMP_TO_BORDER:
75       supported = ctx->API != API_OPENGLES && e->ARB_texture_border_clamp
76          && (target != GL_TEXTURE_EXTERNAL_OES);
77       break;
78 
79    case GL_REPEAT:
80    case GL_MIRRORED_REPEAT:
81       supported = (target != GL_TEXTURE_RECTANGLE_NV)
82          && (target != GL_TEXTURE_EXTERNAL_OES);
83       break;
84 
85    case GL_MIRROR_CLAMP_EXT:
86       supported = is_desktop_gl
87          && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)
88          && (target != GL_TEXTURE_RECTANGLE_NV)
89          && (target != GL_TEXTURE_EXTERNAL_OES);
90       break;
91 
92    case GL_MIRROR_CLAMP_TO_EDGE_EXT:
93       supported = is_desktop_gl
94          && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp || e->ARB_texture_mirror_clamp_to_edge)
95          && (target != GL_TEXTURE_RECTANGLE_NV)
96          && (target != GL_TEXTURE_EXTERNAL_OES);
97       break;
98 
99    case GL_MIRROR_CLAMP_TO_BORDER_EXT:
100       supported = is_desktop_gl && e->EXT_texture_mirror_clamp
101          && (target != GL_TEXTURE_RECTANGLE_NV)
102          && (target != GL_TEXTURE_EXTERNAL_OES);
103       break;
104 
105    default:
106       supported = false;
107       break;
108    }
109 
110    if (!supported)
111       _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap );
112 
113    return supported;
114 }
115 
116 
117 /**
118  * Get current texture object for given target.
119  * Return NULL if any error (and record the error).
120  * Note that this is different from _mesa_get_current_tex_object() in that
121  * proxy targets are not accepted.
122  * Only the glGetTexLevelParameter() functions accept proxy targets.
123  */
124 static struct gl_texture_object *
get_texobj_by_target(struct gl_context * ctx,GLenum target,GLboolean get)125 get_texobj_by_target(struct gl_context *ctx, GLenum target, GLboolean get)
126 {
127    struct gl_texture_unit *texUnit;
128    int targetIndex;
129 
130    if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
131       _mesa_error(ctx, GL_INVALID_OPERATION,
132                   "gl%sTexParameter(current unit)", get ? "Get" : "");
133       return NULL;
134    }
135 
136    texUnit = _mesa_get_current_tex_unit(ctx);
137 
138    targetIndex = _mesa_tex_target_to_index(ctx, target);
139    if (targetIndex < 0 || targetIndex == TEXTURE_BUFFER_INDEX) {
140       _mesa_error(ctx, GL_INVALID_ENUM,
141                   "gl%sTexParameter(target)", get ? "Get" : "");
142       return NULL;
143    }
144    assert(targetIndex < NUM_TEXTURE_TARGETS);
145 
146    return texUnit->CurrentTex[targetIndex];
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    switch (texObj->Target) {
165    case GL_TEXTURE_1D:
166    case GL_TEXTURE_1D_ARRAY:
167    case GL_TEXTURE_2D:
168    case GL_TEXTURE_2D_ARRAY:
169    case GL_TEXTURE_2D_MULTISAMPLE:
170    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
171    case GL_TEXTURE_3D:
172    case GL_TEXTURE_CUBE_MAP:
173    case GL_TEXTURE_CUBE_MAP_ARRAY:
174    case GL_TEXTURE_RECTANGLE:
175       return texObj;
176    default:
177       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(target)", name);
178       return NULL;
179    }
180 
181 }
182 
183 
184 /**
185  * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE.
186  * \return -1 if error.
187  */
188 static GLint
comp_to_swizzle(GLenum comp)189 comp_to_swizzle(GLenum comp)
190 {
191    switch (comp) {
192    case GL_RED:
193       return SWIZZLE_X;
194    case GL_GREEN:
195       return SWIZZLE_Y;
196    case GL_BLUE:
197       return SWIZZLE_Z;
198    case GL_ALPHA:
199       return SWIZZLE_W;
200    case GL_ZERO:
201       return SWIZZLE_ZERO;
202    case GL_ONE:
203       return SWIZZLE_ONE;
204    default:
205       return -1;
206    }
207 }
208 
209 
210 static void
set_swizzle_component(GLuint * swizzle,GLuint comp,GLuint swz)211 set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz)
212 {
213    assert(comp < 4);
214    assert(swz <= SWIZZLE_NIL);
215    {
216       GLuint mask = 0x7 << (3 * comp);
217       GLuint s = (*swizzle & ~mask) | (swz << (3 * comp));
218       *swizzle = s;
219    }
220 }
221 
222 
223 /**
224  * This is called just prior to changing any texture object state which
225  * will not affect texture completeness.
226  */
227 static inline void
flush(struct gl_context * ctx)228 flush(struct gl_context *ctx)
229 {
230    FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT);
231 }
232 
233 
234 /**
235  * This is called just prior to changing any texture object state which
236  * could affect texture completeness (texture base level, max level).
237  * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE_OBJECT
238  * state flag and then mark the texture object as 'incomplete' so that any
239  * per-texture derived state gets recomputed.
240  */
241 static inline void
incomplete(struct gl_context * ctx,struct gl_texture_object * texObj)242 incomplete(struct gl_context *ctx, struct gl_texture_object *texObj)
243 {
244    FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT);
245    _mesa_dirty_texobj(ctx, texObj);
246 }
247 
248 
249 GLboolean
_mesa_target_allows_setting_sampler_parameters(GLenum target)250 _mesa_target_allows_setting_sampler_parameters(GLenum target)
251 {
252    switch (target) {
253    case GL_TEXTURE_2D_MULTISAMPLE:
254    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
255       return GL_FALSE;
256 
257    default:
258       return GL_TRUE;
259    }
260 }
261 
262 
263 /**
264  * Set an integer-valued texture parameter
265  * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
266  */
267 static GLboolean
set_tex_parameteri(struct gl_context * ctx,struct gl_texture_object * texObj,GLenum pname,const GLint * params,bool dsa)268 set_tex_parameteri(struct gl_context *ctx,
269                    struct gl_texture_object *texObj,
270                    GLenum pname, const GLint *params, bool dsa)
271 {
272    const char *suffix = dsa ? "ture" : "";
273 
274    if (texObj->HandleAllocated) {
275       /* The ARB_bindless_texture spec says:
276        *
277        * "The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*,
278        * CompressedTexImage*, TexBuffer*, TexParameter*, as well as other
279        * functions defined in terms of these, if the texture object to be
280        * modified is referenced by one or more texture or image handles."
281        */
282       _mesa_error(ctx, GL_INVALID_OPERATION,
283                   "glTex%sParameter(immutable texture)", suffix);
284       return GL_FALSE;
285    }
286 
287    switch (pname) {
288    case GL_TEXTURE_MIN_FILTER:
289       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
290          goto invalid_enum;
291 
292       if (texObj->Sampler.MinFilter == params[0])
293          return GL_FALSE;
294       switch (params[0]) {
295       case GL_NEAREST:
296       case GL_LINEAR:
297          flush(ctx);
298          texObj->Sampler.MinFilter = params[0];
299          return GL_TRUE;
300       case GL_NEAREST_MIPMAP_NEAREST:
301       case GL_LINEAR_MIPMAP_NEAREST:
302       case GL_NEAREST_MIPMAP_LINEAR:
303       case GL_LINEAR_MIPMAP_LINEAR:
304          if (texObj->Target != GL_TEXTURE_RECTANGLE_NV &&
305              texObj->Target != GL_TEXTURE_EXTERNAL_OES) {
306             flush(ctx);
307             texObj->Sampler.MinFilter = params[0];
308             return GL_TRUE;
309          }
310          /* fall-through */
311       default:
312          goto invalid_param;
313       }
314       return GL_FALSE;
315 
316    case GL_TEXTURE_MAG_FILTER:
317       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
318          goto invalid_enum;
319 
320       if (texObj->Sampler.MagFilter == params[0])
321          return GL_FALSE;
322       switch (params[0]) {
323       case GL_NEAREST:
324       case GL_LINEAR:
325          flush(ctx); /* does not effect completeness */
326          texObj->Sampler.MagFilter = params[0];
327          return GL_TRUE;
328       default:
329          goto invalid_param;
330       }
331       return GL_FALSE;
332 
333    case GL_TEXTURE_WRAP_S:
334       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
335          goto invalid_enum;
336 
337       if (texObj->Sampler.WrapS == params[0])
338          return GL_FALSE;
339       if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
340          flush(ctx);
341          texObj->Sampler.WrapS = params[0];
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_enum;
349 
350       if (texObj->Sampler.WrapT == params[0])
351          return GL_FALSE;
352       if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
353          flush(ctx);
354          texObj->Sampler.WrapT = params[0];
355          return GL_TRUE;
356       }
357       return GL_FALSE;
358 
359    case GL_TEXTURE_WRAP_R:
360       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
361          goto invalid_enum;
362 
363       if (texObj->Sampler.WrapR == params[0])
364          return GL_FALSE;
365       if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) {
366          flush(ctx);
367          texObj->Sampler.WrapR = params[0];
368          return GL_TRUE;
369       }
370       return GL_FALSE;
371 
372    case GL_TEXTURE_BASE_LEVEL:
373       if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
374          goto invalid_pname;
375 
376       if (texObj->BaseLevel == params[0])
377          return GL_FALSE;
378 
379       /* Section 8.10 (Texture Parameters) of the OpenGL 4.5 Core Profile spec
380        * says:
381        *
382        *    An INVALID_OPERATION error is generated if the effective target is
383        *    TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY, or
384        *    TEXTURE_RECTANGLE, and pname TEXTURE_BASE_LEVEL is set to a value
385        *    other than zero.
386        *
387        * Note that section 3.8.8 (Texture Parameters) of the OpenGL 3.3 Core
388        * Profile spec said:
389        *
390        *    The error INVALID_VALUE is generated if TEXTURE_BASE_LEVEL is set
391        *    to any value other than zero.
392        *
393        * We take the 4.5 language as a correction to 3.3, and we implement
394        * that on all GL versions.
395        */
396       if ((texObj->Target == GL_TEXTURE_2D_MULTISAMPLE ||
397            texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ||
398            texObj->Target == GL_TEXTURE_RECTANGLE) && params[0] != 0)
399          goto invalid_operation;
400 
401       if (params[0] < 0) {
402          _mesa_error(ctx, GL_INVALID_VALUE,
403                      "glTex%sParameter(param=%d)", suffix, params[0]);
404          return GL_FALSE;
405       }
406       incomplete(ctx, texObj);
407 
408       /** See note about ARB_texture_storage below */
409       if (texObj->Immutable)
410          texObj->BaseLevel = MIN2(texObj->ImmutableLevels - 1, params[0]);
411       else
412          texObj->BaseLevel = params[0];
413 
414       return GL_TRUE;
415 
416    case GL_TEXTURE_MAX_LEVEL:
417       if (texObj->MaxLevel == params[0])
418          return GL_FALSE;
419 
420       if (params[0] < 0 ||
421           (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] > 0)) {
422          _mesa_error(ctx, GL_INVALID_VALUE,
423                      "glTex%sParameter(param=%d)", suffix,
424                      params[0]);
425          return GL_FALSE;
426       }
427       incomplete(ctx, texObj);
428 
429       /** From ARB_texture_storage:
430        * However, if TEXTURE_IMMUTABLE_FORMAT is TRUE, then level_base is
431        * clamped to the range [0, <levels> - 1] and level_max is then clamped to
432        * the range [level_base, <levels> - 1], where <levels> is the parameter
433        * passed the call to TexStorage* for the texture object.
434        */
435       if (texObj->Immutable)
436           texObj->MaxLevel = CLAMP(params[0], texObj->BaseLevel,
437                                    texObj->ImmutableLevels - 1);
438       else
439          texObj->MaxLevel = params[0];
440 
441       return GL_TRUE;
442 
443    case GL_GENERATE_MIPMAP_SGIS:
444       if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
445          goto invalid_pname;
446 
447       if (params[0] && texObj->Target == GL_TEXTURE_EXTERNAL_OES)
448          goto invalid_param;
449       if (texObj->GenerateMipmap != params[0]) {
450          /* no flush() */
451 	 texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE;
452 	 return GL_TRUE;
453       }
454       return GL_FALSE;
455 
456    case GL_TEXTURE_COMPARE_MODE_ARB:
457       if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow)
458           || _mesa_is_gles3(ctx)) {
459 
460          if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
461             goto invalid_enum;
462 
463          if (texObj->Sampler.CompareMode == params[0])
464             return GL_FALSE;
465          if (params[0] == GL_NONE ||
466              params[0] == GL_COMPARE_R_TO_TEXTURE_ARB) {
467             flush(ctx);
468             texObj->Sampler.CompareMode = params[0];
469             return GL_TRUE;
470          }
471          goto invalid_param;
472       }
473       goto invalid_pname;
474 
475    case GL_TEXTURE_COMPARE_FUNC_ARB:
476       if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow)
477           || _mesa_is_gles3(ctx)) {
478 
479          if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
480             goto invalid_enum;
481 
482          if (texObj->Sampler.CompareFunc == params[0])
483             return GL_FALSE;
484          switch (params[0]) {
485          case GL_LEQUAL:
486          case GL_GEQUAL:
487          case GL_EQUAL:
488          case GL_NOTEQUAL:
489          case GL_LESS:
490          case GL_GREATER:
491          case GL_ALWAYS:
492          case GL_NEVER:
493             flush(ctx);
494             texObj->Sampler.CompareFunc = params[0];
495             return GL_TRUE;
496          default:
497             goto invalid_param;
498          }
499       }
500       goto invalid_pname;
501 
502    case GL_DEPTH_TEXTURE_MODE_ARB:
503       /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has never
504        * existed in OpenGL ES.
505        */
506       if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_depth_texture) {
507          if (texObj->DepthMode == params[0])
508             return GL_FALSE;
509          if (params[0] == GL_LUMINANCE ||
510              params[0] == GL_INTENSITY ||
511              params[0] == GL_ALPHA ||
512              (ctx->Extensions.ARB_texture_rg && params[0] == GL_RED)) {
513             flush(ctx);
514             texObj->DepthMode = params[0];
515             return GL_TRUE;
516          }
517          goto invalid_param;
518       }
519       goto invalid_pname;
520 
521    case GL_DEPTH_STENCIL_TEXTURE_MODE:
522       if (_mesa_has_ARB_stencil_texturing(ctx) || _mesa_is_gles31(ctx)) {
523          bool stencil = params[0] == GL_STENCIL_INDEX;
524          if (!stencil && params[0] != GL_DEPTH_COMPONENT)
525             goto invalid_param;
526 
527          if (texObj->StencilSampling == stencil)
528             return GL_FALSE;
529 
530          texObj->StencilSampling = stencil;
531          return GL_TRUE;
532       }
533       goto invalid_pname;
534 
535    case GL_TEXTURE_CROP_RECT_OES:
536       if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
537          goto invalid_pname;
538 
539       texObj->CropRect[0] = params[0];
540       texObj->CropRect[1] = params[1];
541       texObj->CropRect[2] = params[2];
542       texObj->CropRect[3] = params[3];
543       return GL_TRUE;
544 
545    case GL_TEXTURE_SWIZZLE_R_EXT:
546    case GL_TEXTURE_SWIZZLE_G_EXT:
547    case GL_TEXTURE_SWIZZLE_B_EXT:
548    case GL_TEXTURE_SWIZZLE_A_EXT:
549       if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle)
550           || _mesa_is_gles3(ctx)) {
551          const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT;
552          const GLint swz = comp_to_swizzle(params[0]);
553          if (swz < 0) {
554             _mesa_error(ctx, GL_INVALID_ENUM,
555                         "glTex%sParameter(swizzle 0x%x)", suffix, params[0]);
556             return GL_FALSE;
557          }
558          assert(comp < 4);
559 
560          flush(ctx);
561          texObj->Swizzle[comp] = params[0];
562          set_swizzle_component(&texObj->_Swizzle, comp, swz);
563          return GL_TRUE;
564       }
565       goto invalid_pname;
566 
567    case GL_TEXTURE_SWIZZLE_RGBA_EXT:
568       if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle)
569           || _mesa_is_gles3(ctx)) {
570          GLuint comp;
571          flush(ctx);
572          for (comp = 0; comp < 4; comp++) {
573             const GLint swz = comp_to_swizzle(params[comp]);
574             if (swz >= 0) {
575                texObj->Swizzle[comp] = params[comp];
576                set_swizzle_component(&texObj->_Swizzle, comp, swz);
577             }
578             else {
579                _mesa_error(ctx, GL_INVALID_ENUM,
580                            "glTex%sParameter(swizzle 0x%x)",
581                            suffix, params[comp]);
582                return GL_FALSE;
583             }
584          }
585          return GL_TRUE;
586       }
587       goto invalid_pname;
588 
589    case GL_TEXTURE_SRGB_DECODE_EXT:
590       if (ctx->Extensions.EXT_texture_sRGB_decode) {
591          GLenum decode = params[0];
592 
593          if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
594             goto invalid_enum;
595 
596 	 if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) {
597 	    if (texObj->Sampler.sRGBDecode != decode) {
598 	       flush(ctx);
599 	       texObj->Sampler.sRGBDecode = decode;
600 	    }
601 	    return GL_TRUE;
602 	 }
603       }
604       goto invalid_pname;
605 
606    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
607       if (_mesa_is_desktop_gl(ctx)
608           && ctx->Extensions.AMD_seamless_cubemap_per_texture) {
609          GLenum param = params[0];
610 
611          if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
612             goto invalid_enum;
613 
614          if (param != GL_TRUE && param != GL_FALSE) {
615             goto invalid_param;
616          }
617          if (param != texObj->Sampler.CubeMapSeamless) {
618             flush(ctx);
619             texObj->Sampler.CubeMapSeamless = param;
620          }
621          return GL_TRUE;
622       }
623       goto invalid_pname;
624 
625    case GL_TEXTURE_TILING_EXT:
626       if (ctx->Extensions.EXT_memory_object) {
627          texObj->TextureTiling = params[0];
628 
629          return GL_TRUE;
630       }
631       goto invalid_pname;
632 
633    default:
634       goto invalid_pname;
635    }
636 
637 invalid_pname:
638    _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)",
639                suffix, _mesa_enum_to_string(pname));
640    return GL_FALSE;
641 
642 invalid_param:
643    _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(param=%s)",
644                suffix, _mesa_enum_to_string(params[0]));
645    return GL_FALSE;
646 
647 invalid_operation:
648    _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sParameter(pname=%s)",
649                suffix, _mesa_enum_to_string(pname));
650    return GL_FALSE;
651 
652 invalid_enum:
653    _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)",
654                suffix, _mesa_enum_to_string(pname));
655    return GL_FALSE;
656 }
657 
658 
659 /**
660  * Set a float-valued texture parameter
661  * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise
662  */
663 static GLboolean
set_tex_parameterf(struct gl_context * ctx,struct gl_texture_object * texObj,GLenum pname,const GLfloat * params,bool dsa)664 set_tex_parameterf(struct gl_context *ctx,
665                    struct gl_texture_object *texObj,
666                    GLenum pname, const GLfloat *params, bool dsa)
667 {
668    const char *suffix = dsa ? "ture" : "";
669 
670    if (texObj->HandleAllocated) {
671       /* The ARB_bindless_texture spec says:
672        *
673        * "The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*,
674        * CompressedTexImage*, TexBuffer*, TexParameter*, as well as other
675        * functions defined in terms of these, if the texture object to be
676        * modified is referenced by one or more texture or image handles."
677        */
678       _mesa_error(ctx, GL_INVALID_OPERATION,
679                   "glTex%sParameter(immutable texture)", suffix);
680       return GL_FALSE;
681    }
682 
683    switch (pname) {
684    case GL_TEXTURE_MIN_LOD:
685       if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
686          goto invalid_pname;
687 
688       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
689          goto invalid_enum;
690 
691       if (texObj->Sampler.MinLod == params[0])
692          return GL_FALSE;
693       flush(ctx);
694       texObj->Sampler.MinLod = params[0];
695       return GL_TRUE;
696 
697    case GL_TEXTURE_MAX_LOD:
698       if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
699          goto invalid_pname;
700 
701       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
702          goto invalid_enum;
703 
704       if (texObj->Sampler.MaxLod == params[0])
705          return GL_FALSE;
706       flush(ctx);
707       texObj->Sampler.MaxLod = params[0];
708       return GL_TRUE;
709 
710    case GL_TEXTURE_PRIORITY:
711       if (ctx->API != API_OPENGL_COMPAT)
712          goto invalid_pname;
713 
714       flush(ctx);
715       texObj->Priority = CLAMP(params[0], 0.0F, 1.0F);
716       return GL_TRUE;
717 
718    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
719       if (ctx->Extensions.EXT_texture_filter_anisotropic) {
720          if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
721             goto invalid_enum;
722 
723          if (texObj->Sampler.MaxAnisotropy == params[0])
724             return GL_FALSE;
725          if (params[0] < 1.0F) {
726             _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sParameter(param)",
727                         suffix);
728             return GL_FALSE;
729          }
730          flush(ctx);
731          /* clamp to max, that's what NVIDIA does */
732          texObj->Sampler.MaxAnisotropy = MIN2(params[0],
733                                       ctx->Const.MaxTextureMaxAnisotropy);
734          return GL_TRUE;
735       }
736       else {
737          static GLuint count = 0;
738          if (count++ < 10)
739             goto invalid_pname;
740       }
741       return GL_FALSE;
742 
743    case GL_TEXTURE_LOD_BIAS:
744       /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias. */
745       if (_mesa_is_gles(ctx))
746          goto invalid_pname;
747 
748       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
749          goto invalid_enum;
750 
751       if (texObj->Sampler.LodBias != params[0]) {
752 	 flush(ctx);
753 	 texObj->Sampler.LodBias = params[0];
754 	 return GL_TRUE;
755       }
756       break;
757 
758    case GL_TEXTURE_BORDER_COLOR:
759       /* Border color exists in desktop OpenGL since 1.0 for GL_CLAMP.  In
760        * OpenGL ES 2.0+, it only exists in when GL_OES_texture_border_clamp is
761        * enabled.  It is never available in OpenGL ES 1.x.
762        *
763        * FIXME: Every driver that supports GLES2 has this extension.  Elide
764        * the check?
765        */
766       if (ctx->API == API_OPENGLES ||
767           (ctx->API == API_OPENGLES2 &&
768            !ctx->Extensions.ARB_texture_border_clamp))
769          goto invalid_pname;
770 
771       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target))
772          goto invalid_enum;
773 
774       flush(ctx);
775       /* ARB_texture_float disables clamping */
776       if (ctx->Extensions.ARB_texture_float) {
777          texObj->Sampler.BorderColor.f[RCOMP] = params[0];
778          texObj->Sampler.BorderColor.f[GCOMP] = params[1];
779          texObj->Sampler.BorderColor.f[BCOMP] = params[2];
780          texObj->Sampler.BorderColor.f[ACOMP] = params[3];
781       } else {
782          texObj->Sampler.BorderColor.f[RCOMP] = CLAMP(params[0], 0.0F, 1.0F);
783          texObj->Sampler.BorderColor.f[GCOMP] = CLAMP(params[1], 0.0F, 1.0F);
784          texObj->Sampler.BorderColor.f[BCOMP] = CLAMP(params[2], 0.0F, 1.0F);
785          texObj->Sampler.BorderColor.f[ACOMP] = CLAMP(params[3], 0.0F, 1.0F);
786       }
787       return GL_TRUE;
788 
789    case GL_TEXTURE_TILING_EXT:
790       if (ctx->Extensions.EXT_memory_object) {
791          texObj->TextureTiling = params[0];
792          return GL_TRUE;
793       }
794       goto invalid_pname;
795 
796    default:
797       goto invalid_pname;
798    }
799    return GL_FALSE;
800 
801 invalid_pname:
802    _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)",
803                suffix, _mesa_enum_to_string(pname));
804    return GL_FALSE;
805 
806 invalid_enum:
807    _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)",
808                suffix, _mesa_enum_to_string(pname));
809    return GL_FALSE;
810 }
811 
812 
813 void
_mesa_texture_parameterf(struct gl_context * ctx,struct gl_texture_object * texObj,GLenum pname,GLfloat param,bool dsa)814 _mesa_texture_parameterf(struct gl_context *ctx,
815                          struct gl_texture_object *texObj,
816                          GLenum pname, GLfloat param, bool dsa)
817 {
818    GLboolean need_update;
819 
820    switch (pname) {
821    case GL_TEXTURE_MIN_FILTER:
822    case GL_TEXTURE_MAG_FILTER:
823    case GL_TEXTURE_WRAP_S:
824    case GL_TEXTURE_WRAP_T:
825    case GL_TEXTURE_WRAP_R:
826    case GL_TEXTURE_BASE_LEVEL:
827    case GL_TEXTURE_MAX_LEVEL:
828    case GL_GENERATE_MIPMAP_SGIS:
829    case GL_TEXTURE_COMPARE_MODE_ARB:
830    case GL_TEXTURE_COMPARE_FUNC_ARB:
831    case GL_DEPTH_TEXTURE_MODE_ARB:
832    case GL_DEPTH_STENCIL_TEXTURE_MODE:
833    case GL_TEXTURE_SRGB_DECODE_EXT:
834    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
835    case GL_TEXTURE_SWIZZLE_R_EXT:
836    case GL_TEXTURE_SWIZZLE_G_EXT:
837    case GL_TEXTURE_SWIZZLE_B_EXT:
838    case GL_TEXTURE_SWIZZLE_A_EXT:
839       {
840          GLint p[4];
841          p[0] = (param > 0) ?
842                 ((param > INT_MAX) ? INT_MAX : (GLint) (param + 0.5)) :
843                 ((param < INT_MIN) ? INT_MIN : (GLint) (param - 0.5));
844 
845          p[1] = p[2] = p[3] = 0;
846          need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa);
847       }
848       break;
849    case GL_TEXTURE_BORDER_COLOR:
850    case GL_TEXTURE_SWIZZLE_RGBA:
851       _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameterf(non-scalar pname)",
852                   dsa ? "ture" : "");
853       return;
854    default:
855       {
856          /* this will generate an error if pname is illegal */
857          GLfloat p[4];
858          p[0] = param;
859          p[1] = p[2] = p[3] = 0.0F;
860          need_update = set_tex_parameterf(ctx, texObj, pname, p, dsa);
861       }
862    }
863 
864    if (ctx->Driver.TexParameter && need_update) {
865       ctx->Driver.TexParameter(ctx, texObj, pname);
866    }
867 }
868 
869 
870 void
_mesa_texture_parameterfv(struct gl_context * ctx,struct gl_texture_object * texObj,GLenum pname,const GLfloat * params,bool dsa)871 _mesa_texture_parameterfv(struct gl_context *ctx,
872                           struct gl_texture_object *texObj,
873                           GLenum pname, const GLfloat *params, bool dsa)
874 {
875    GLboolean need_update;
876    switch (pname) {
877    case GL_TEXTURE_MIN_FILTER:
878    case GL_TEXTURE_MAG_FILTER:
879    case GL_TEXTURE_WRAP_S:
880    case GL_TEXTURE_WRAP_T:
881    case GL_TEXTURE_WRAP_R:
882    case GL_TEXTURE_BASE_LEVEL:
883    case GL_TEXTURE_MAX_LEVEL:
884    case GL_GENERATE_MIPMAP_SGIS:
885    case GL_TEXTURE_COMPARE_MODE_ARB:
886    case GL_TEXTURE_COMPARE_FUNC_ARB:
887    case GL_DEPTH_TEXTURE_MODE_ARB:
888    case GL_DEPTH_STENCIL_TEXTURE_MODE:
889    case GL_TEXTURE_SRGB_DECODE_EXT:
890    case GL_TEXTURE_CUBE_MAP_SEAMLESS:
891       {
892          /* convert float param to int */
893          GLint p[4];
894          p[0] = (GLint) params[0];
895          p[1] = p[2] = p[3] = 0;
896          need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa);
897       }
898       break;
899    case GL_TEXTURE_CROP_RECT_OES:
900       {
901          /* convert float params to int */
902          GLint iparams[4];
903          iparams[0] = (GLint) params[0];
904          iparams[1] = (GLint) params[1];
905          iparams[2] = (GLint) params[2];
906          iparams[3] = (GLint) params[3];
907          need_update = set_tex_parameteri(ctx, texObj, pname, iparams, dsa);
908       }
909       break;
910    case GL_TEXTURE_SWIZZLE_R_EXT:
911    case GL_TEXTURE_SWIZZLE_G_EXT:
912    case GL_TEXTURE_SWIZZLE_B_EXT:
913    case GL_TEXTURE_SWIZZLE_A_EXT:
914    case GL_TEXTURE_SWIZZLE_RGBA_EXT:
915       {
916          GLint p[4] = {0, 0, 0, 0};
917          p[0] = (GLint) params[0];
918          if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT) {
919             p[1] = (GLint) params[1];
920             p[2] = (GLint) params[2];
921             p[3] = (GLint) params[3];
922          }
923          need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa);
924       }
925       break;
926    default:
927       /* this will generate an error if pname is illegal */
928       need_update = set_tex_parameterf(ctx, texObj, pname, params, dsa);
929    }
930 
931    if (ctx->Driver.TexParameter && need_update) {
932       ctx->Driver.TexParameter(ctx, texObj, pname);
933    }
934 }
935 
936 
937 void
_mesa_texture_parameteri(struct gl_context * ctx,struct gl_texture_object * texObj,GLenum pname,GLint param,bool dsa)938 _mesa_texture_parameteri(struct gl_context *ctx,
939                          struct gl_texture_object *texObj,
940                          GLenum pname, GLint param, bool dsa)
941 {
942    GLboolean need_update;
943    switch (pname) {
944    case GL_TEXTURE_MIN_LOD:
945    case GL_TEXTURE_MAX_LOD:
946    case GL_TEXTURE_PRIORITY:
947    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
948    case GL_TEXTURE_LOD_BIAS:
949    case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
950       {
951          GLfloat fparam[4];
952          fparam[0] = (GLfloat) param;
953          fparam[1] = fparam[2] = fparam[3] = 0.0F;
954          /* convert int param to float */
955          need_update = set_tex_parameterf(ctx, texObj, pname, fparam, dsa);
956       }
957       break;
958    case GL_TEXTURE_BORDER_COLOR:
959    case GL_TEXTURE_SWIZZLE_RGBA:
960       {
961          _mesa_error(ctx, GL_INVALID_ENUM,
962                      "glTex%sParameteri(non-scalar pname)",
963                      dsa ? "ture" : "");
964          return;
965       }
966    default:
967       /* this will generate an error if pname is illegal */
968       {
969          GLint iparam[4];
970          iparam[0] = param;
971          iparam[1] = iparam[2] = iparam[3] = 0;
972          need_update = set_tex_parameteri(ctx, texObj, pname, iparam, dsa);
973       }
974    }
975 
976    if (ctx->Driver.TexParameter && need_update) {
977       ctx->Driver.TexParameter(ctx, texObj, pname);
978    }
979 }
980 
981 
982 void
_mesa_texture_parameteriv(struct gl_context * ctx,struct gl_texture_object * texObj,GLenum pname,const GLint * params,bool dsa)983 _mesa_texture_parameteriv(struct gl_context *ctx,
984                           struct gl_texture_object *texObj,
985                           GLenum pname, const GLint *params, bool dsa)
986 {
987    GLboolean need_update;
988 
989    switch (pname) {
990    case GL_TEXTURE_BORDER_COLOR:
991       {
992          /* convert int params to float */
993          GLfloat fparams[4];
994          fparams[0] = INT_TO_FLOAT(params[0]);
995          fparams[1] = INT_TO_FLOAT(params[1]);
996          fparams[2] = INT_TO_FLOAT(params[2]);
997          fparams[3] = INT_TO_FLOAT(params[3]);
998          need_update = set_tex_parameterf(ctx, texObj, pname, fparams, dsa);
999       }
1000       break;
1001    case GL_TEXTURE_MIN_LOD:
1002    case GL_TEXTURE_MAX_LOD:
1003    case GL_TEXTURE_PRIORITY:
1004    case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1005    case GL_TEXTURE_LOD_BIAS:
1006    case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB:
1007       {
1008          /* convert int param to float */
1009          GLfloat fparams[4];
1010          fparams[0] = (GLfloat) params[0];
1011          fparams[1] = fparams[2] = fparams[3] = 0.0F;
1012          need_update = set_tex_parameterf(ctx, texObj, pname, fparams, dsa);
1013       }
1014       break;
1015    default:
1016       /* this will generate an error if pname is illegal */
1017       need_update = set_tex_parameteri(ctx, texObj, pname, params, dsa);
1018    }
1019 
1020    if (ctx->Driver.TexParameter && need_update) {
1021       ctx->Driver.TexParameter(ctx, texObj, pname);
1022    }
1023 }
1024 
1025 void
_mesa_texture_parameterIiv(struct gl_context * ctx,struct gl_texture_object * texObj,GLenum pname,const GLint * params,bool dsa)1026 _mesa_texture_parameterIiv(struct gl_context *ctx,
1027                            struct gl_texture_object *texObj,
1028                            GLenum pname, const GLint *params, bool dsa)
1029 {
1030    switch (pname) {
1031    case GL_TEXTURE_BORDER_COLOR:
1032       if (texObj->HandleAllocated) {
1033          _mesa_error(ctx, GL_INVALID_OPERATION,
1034                      "glTextureParameterIiv(immutable texture)");
1035          return;
1036       }
1037 
1038       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) {
1039          _mesa_error(ctx, GL_INVALID_ENUM, "glTextureParameterIiv(texture)");
1040          return;
1041       }
1042       FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT);
1043       /* set the integer-valued border color */
1044       COPY_4V(texObj->Sampler.BorderColor.i, params);
1045       break;
1046    default:
1047       _mesa_texture_parameteriv(ctx, texObj, pname, params, dsa);
1048       break;
1049    }
1050    /* XXX no driver hook for TexParameterIiv() yet */
1051 }
1052 
1053 void
_mesa_texture_parameterIuiv(struct gl_context * ctx,struct gl_texture_object * texObj,GLenum pname,const GLuint * params,bool dsa)1054 _mesa_texture_parameterIuiv(struct gl_context *ctx,
1055                             struct gl_texture_object *texObj,
1056                             GLenum pname, const GLuint *params, bool dsa)
1057 {
1058    switch (pname) {
1059    case GL_TEXTURE_BORDER_COLOR:
1060       if (texObj->HandleAllocated) {
1061          _mesa_error(ctx, GL_INVALID_OPERATION,
1062                      "glTextureParameterIuiv(immutable texture)");
1063          return;
1064       }
1065 
1066       if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) {
1067          _mesa_error(ctx, GL_INVALID_ENUM, "glTextureParameterIuiv(texture)");
1068          return;
1069       }
1070       FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT);
1071       /* set the unsigned integer-valued border color */
1072       COPY_4V(texObj->Sampler.BorderColor.ui, params);
1073       break;
1074    default:
1075       _mesa_texture_parameteriv(ctx, texObj, pname, (const GLint *) params,
1076                                 dsa);
1077       break;
1078    }
1079    /* XXX no driver hook for TexParameterIuiv() yet */
1080 }
1081 
1082 void GLAPIENTRY
_mesa_TexParameterf(GLenum target,GLenum pname,GLfloat param)1083 _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param)
1084 {
1085    struct gl_texture_object *texObj;
1086    GET_CURRENT_CONTEXT(ctx);
1087 
1088    texObj = get_texobj_by_target(ctx, target, GL_FALSE);
1089    if (!texObj)
1090       return;
1091 
1092    _mesa_texture_parameterf(ctx, texObj, pname, param, false);
1093 }
1094 
1095 void GLAPIENTRY
_mesa_TexParameterfv(GLenum target,GLenum pname,const GLfloat * params)1096 _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
1097 {
1098    struct gl_texture_object *texObj;
1099    GET_CURRENT_CONTEXT(ctx);
1100 
1101    texObj = get_texobj_by_target(ctx, target, GL_FALSE);
1102    if (!texObj)
1103       return;
1104 
1105    _mesa_texture_parameterfv(ctx, texObj, pname, params, false);
1106 }
1107 
1108 void GLAPIENTRY
_mesa_TexParameteri(GLenum target,GLenum pname,GLint param)1109 _mesa_TexParameteri(GLenum target, GLenum pname, GLint param)
1110 {
1111    struct gl_texture_object *texObj;
1112    GET_CURRENT_CONTEXT(ctx);
1113 
1114    texObj = get_texobj_by_target(ctx, target, GL_FALSE);
1115    if (!texObj)
1116       return;
1117 
1118    _mesa_texture_parameteri(ctx, texObj, pname, param, false);
1119 }
1120 
1121 void GLAPIENTRY
_mesa_TexParameteriv(GLenum target,GLenum pname,const GLint * params)1122 _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params)
1123 {
1124    struct gl_texture_object *texObj;
1125    GET_CURRENT_CONTEXT(ctx);
1126 
1127    texObj = get_texobj_by_target(ctx, target, GL_FALSE);
1128    if (!texObj)
1129       return;
1130 
1131    _mesa_texture_parameteriv(ctx, texObj, pname, params, false);
1132 }
1133 
1134 /**
1135  * Set tex parameter to integer value(s).  Primarily intended to set
1136  * integer-valued texture border color (for integer-valued textures).
1137  * New in GL 3.0.
1138  */
1139 void GLAPIENTRY
_mesa_TexParameterIiv(GLenum target,GLenum pname,const GLint * params)1140 _mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params)
1141 {
1142    struct gl_texture_object *texObj;
1143    GET_CURRENT_CONTEXT(ctx);
1144 
1145    texObj = get_texobj_by_target(ctx, target, GL_FALSE);
1146    if (!texObj)
1147       return;
1148 
1149    _mesa_texture_parameterIiv(ctx, texObj, pname, params, false);
1150 }
1151 
1152 /**
1153  * Set tex parameter to unsigned integer value(s).  Primarily intended to set
1154  * uint-valued texture border color (for integer-valued textures).
1155  * New in GL 3.0
1156  */
1157 void GLAPIENTRY
_mesa_TexParameterIuiv(GLenum target,GLenum pname,const GLuint * params)1158 _mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params)
1159 {
1160    struct gl_texture_object *texObj;
1161    GET_CURRENT_CONTEXT(ctx);
1162 
1163    texObj = get_texobj_by_target(ctx, target, GL_FALSE);
1164    if (!texObj)
1165       return;
1166 
1167    _mesa_texture_parameterIuiv(ctx, texObj, pname, params, false);
1168 }
1169 
1170 
1171 void GLAPIENTRY
_mesa_TextureParameterfv(GLuint texture,GLenum pname,const GLfloat * params)1172 _mesa_TextureParameterfv(GLuint texture, GLenum pname, const GLfloat *params)
1173 {
1174    struct gl_texture_object *texObj;
1175    GET_CURRENT_CONTEXT(ctx);
1176 
1177    texObj = get_texobj_by_name(ctx, texture, "glTextureParameterfv");
1178    if (!texObj)
1179       return;
1180 
1181    _mesa_texture_parameterfv(ctx, texObj, pname, params, true);
1182 }
1183 
1184 void GLAPIENTRY
_mesa_TextureParameterf(GLuint texture,GLenum pname,GLfloat param)1185 _mesa_TextureParameterf(GLuint texture, GLenum pname, GLfloat param)
1186 {
1187    struct gl_texture_object *texObj;
1188    GET_CURRENT_CONTEXT(ctx);
1189 
1190    texObj = get_texobj_by_name(ctx, texture, "glTextureParameterf");
1191    if (!texObj)
1192       return;
1193 
1194    _mesa_texture_parameterf(ctx, texObj, pname, param, true);
1195 }
1196 
1197 void GLAPIENTRY
_mesa_TextureParameteri(GLuint texture,GLenum pname,GLint param)1198 _mesa_TextureParameteri(GLuint texture, GLenum pname, GLint param)
1199 {
1200    struct gl_texture_object *texObj;
1201    GET_CURRENT_CONTEXT(ctx);
1202 
1203    texObj = get_texobj_by_name(ctx, texture, "glTextureParameteri");
1204    if (!texObj)
1205       return;
1206 
1207    _mesa_texture_parameteri(ctx, texObj, pname, param, true);
1208 }
1209 
1210 void GLAPIENTRY
_mesa_TextureParameteriv(GLuint texture,GLenum pname,const GLint * params)1211 _mesa_TextureParameteriv(GLuint texture, GLenum pname,
1212                          const GLint *params)
1213 {
1214    struct gl_texture_object *texObj;
1215    GET_CURRENT_CONTEXT(ctx);
1216 
1217    texObj = get_texobj_by_name(ctx, texture, "glTextureParameteriv");
1218    if (!texObj)
1219       return;
1220 
1221    _mesa_texture_parameteriv(ctx, texObj, pname, params, true);
1222 }
1223 
1224 
1225 void GLAPIENTRY
_mesa_TextureParameterIiv(GLuint texture,GLenum pname,const GLint * params)1226 _mesa_TextureParameterIiv(GLuint texture, GLenum pname, const GLint *params)
1227 {
1228    struct gl_texture_object *texObj;
1229    GET_CURRENT_CONTEXT(ctx);
1230 
1231    texObj = get_texobj_by_name(ctx, texture, "glTextureParameterIiv");
1232    if (!texObj)
1233       return;
1234 
1235    _mesa_texture_parameterIiv(ctx, texObj, pname, params, true);
1236 }
1237 
1238 void GLAPIENTRY
_mesa_TextureParameterIuiv(GLuint texture,GLenum pname,const GLuint * params)1239 _mesa_TextureParameterIuiv(GLuint texture, GLenum pname, const GLuint *params)
1240 {
1241    struct gl_texture_object *texObj;
1242    GET_CURRENT_CONTEXT(ctx);
1243 
1244    texObj = get_texobj_by_name(ctx, texture, "glTextureParameterIuiv");
1245    if (!texObj)
1246       return;
1247 
1248    _mesa_texture_parameterIuiv(ctx, texObj, pname, params, true);
1249 }
1250 
1251 GLboolean
_mesa_legal_get_tex_level_parameter_target(struct gl_context * ctx,GLenum target,bool dsa)1252 _mesa_legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target,
1253                                            bool dsa)
1254 {
1255    /* Common targets for desktop GL and GLES 3.1. */
1256    switch (target) {
1257    case GL_TEXTURE_2D:
1258    case GL_TEXTURE_3D:
1259       return GL_TRUE;
1260    case GL_TEXTURE_2D_ARRAY_EXT:
1261       return ctx->Extensions.EXT_texture_array;
1262    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1263    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1264    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1265    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1266    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1267    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1268       return ctx->Extensions.ARB_texture_cube_map;
1269    case GL_TEXTURE_2D_MULTISAMPLE:
1270    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
1271       return ctx->Extensions.ARB_texture_multisample;
1272    case GL_TEXTURE_BUFFER:
1273       /* GetTexLevelParameter accepts GL_TEXTURE_BUFFER in GL 3.1+ contexts,
1274        * but not in earlier versions that expose ARB_texture_buffer_object.
1275        *
1276        * From the ARB_texture_buffer_object spec:
1277        * "(7) Do buffer textures support texture parameters (TexParameter) or
1278        *      queries (GetTexParameter, GetTexLevelParameter, GetTexImage)?
1279        *
1280        *    RESOLVED:  No. [...] Note that the spec edits above don't add
1281        *    explicit error language for any of these cases.  That is because
1282        *    each of the functions enumerate the set of valid <target>
1283        *    parameters.  Not editing the spec to allow TEXTURE_BUFFER_ARB in
1284        *    these cases means that target is not legal, and an INVALID_ENUM
1285        *    error should be generated."
1286        *
1287        * From the OpenGL 3.1 spec:
1288        * "target may also be TEXTURE_BUFFER, indicating the texture buffer."
1289        */
1290       return (_mesa_is_desktop_gl(ctx) && ctx->Version >= 31) ||
1291              _mesa_has_OES_texture_buffer(ctx);
1292    case GL_TEXTURE_CUBE_MAP_ARRAY:
1293       return _mesa_has_texture_cube_map_array(ctx);
1294    }
1295 
1296    if (!_mesa_is_desktop_gl(ctx))
1297       return GL_FALSE;
1298 
1299    /* Rest of the desktop GL targets. */
1300    switch (target) {
1301    case GL_TEXTURE_1D:
1302    case GL_PROXY_TEXTURE_1D:
1303    case GL_PROXY_TEXTURE_2D:
1304    case GL_PROXY_TEXTURE_3D:
1305       return GL_TRUE;
1306    case GL_PROXY_TEXTURE_CUBE_MAP:
1307       return ctx->Extensions.ARB_texture_cube_map;
1308    case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
1309       return ctx->Extensions.ARB_texture_cube_map_array;
1310    case GL_TEXTURE_RECTANGLE_NV:
1311    case GL_PROXY_TEXTURE_RECTANGLE_NV:
1312       return ctx->Extensions.NV_texture_rectangle;
1313    case GL_TEXTURE_1D_ARRAY_EXT:
1314    case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
1315    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1316       return ctx->Extensions.EXT_texture_array;
1317    case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
1318    case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
1319       return ctx->Extensions.ARB_texture_multisample;
1320 
1321    /*  This is a valid target for dsa, but the OpenGL 4.5 core spec
1322     *  (30.10.2014) Section 8.11 Texture Queries says:
1323     *       "For GetTextureLevelParameter* only, texture may also be a cube
1324     *       map texture object.  In this case the query is always performed
1325     *       for face zero (the TEXTURE_CUBE_MAP_POSITIVE_X face), since there
1326     *       is no way to specify another face."
1327     */
1328    case GL_TEXTURE_CUBE_MAP:
1329       return dsa;
1330    default:
1331       return GL_FALSE;
1332    }
1333 }
1334 
1335 
1336 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)1337 get_tex_level_parameter_image(struct gl_context *ctx,
1338                               const struct gl_texture_object *texObj,
1339                               GLenum target, GLint level,
1340                               GLenum pname, GLint *params,
1341                               bool dsa)
1342 {
1343    const struct gl_texture_image *img = NULL;
1344    struct gl_texture_image dummy_image;
1345    mesa_format texFormat;
1346    const char *suffix = dsa ? "ture" : "";
1347 
1348    img = _mesa_select_tex_image(texObj, target, level);
1349    if (!img || img->TexFormat == MESA_FORMAT_NONE) {
1350       /* In case of undefined texture image return the default values.
1351        *
1352        * From OpenGL 4.0 spec, page 398:
1353        *    "The initial internal format of a texel array is RGBA
1354        *     instead of 1. TEXTURE_COMPONENTS is deprecated; always
1355        *     use TEXTURE_INTERNAL_FORMAT."
1356        */
1357       memset(&dummy_image, 0, sizeof(dummy_image));
1358       dummy_image.TexFormat = MESA_FORMAT_NONE;
1359       dummy_image.InternalFormat = GL_RGBA;
1360       dummy_image._BaseFormat = GL_NONE;
1361       dummy_image.FixedSampleLocations = GL_TRUE;
1362 
1363       img = &dummy_image;
1364    }
1365 
1366    texFormat = img->TexFormat;
1367 
1368    switch (pname) {
1369       case GL_TEXTURE_WIDTH:
1370          *params = img->Width;
1371          break;
1372       case GL_TEXTURE_HEIGHT:
1373          *params = img->Height;
1374          break;
1375       case GL_TEXTURE_DEPTH:
1376          *params = img->Depth;
1377          break;
1378       case GL_TEXTURE_INTERNAL_FORMAT:
1379          if (_mesa_is_format_compressed(texFormat)) {
1380             /* need to return the actual compressed format */
1381             *params = _mesa_compressed_format_to_glenum(ctx, texFormat);
1382          }
1383          else {
1384 	    /* If the true internal format is not compressed but the user
1385 	     * requested a generic compressed format, we have to return the
1386 	     * generic base format that matches.
1387 	     *
1388 	     * From page 119 (page 129 of the PDF) of the OpenGL 1.3 spec:
1389 	     *
1390 	     *     "If no specific compressed format is available,
1391 	     *     internalformat is instead replaced by the corresponding base
1392 	     *     internal format."
1393 	     *
1394 	     * Otherwise just return the user's requested internal format
1395 	     */
1396 	    const GLenum f =
1397 	       _mesa_gl_compressed_format_base_format(img->InternalFormat);
1398 
1399 	    *params = (f != 0) ? f : img->InternalFormat;
1400 	 }
1401          break;
1402       case GL_TEXTURE_BORDER:
1403          if (ctx->API != API_OPENGL_COMPAT)
1404             goto invalid_pname;
1405          *params = img->Border;
1406          break;
1407       case GL_TEXTURE_RED_SIZE:
1408       case GL_TEXTURE_GREEN_SIZE:
1409       case GL_TEXTURE_BLUE_SIZE:
1410       case GL_TEXTURE_ALPHA_SIZE:
1411          if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
1412             *params = _mesa_get_format_bits(texFormat, pname);
1413          else
1414             *params = 0;
1415          break;
1416       case GL_TEXTURE_INTENSITY_SIZE:
1417       case GL_TEXTURE_LUMINANCE_SIZE:
1418          if (ctx->API != API_OPENGL_COMPAT)
1419             goto invalid_pname;
1420          if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) {
1421             *params = _mesa_get_format_bits(texFormat, pname);
1422             if (*params == 0) {
1423                /* intensity or luminance is probably stored as RGB[A] */
1424                *params = MIN2(_mesa_get_format_bits(texFormat,
1425                                                     GL_TEXTURE_RED_SIZE),
1426                               _mesa_get_format_bits(texFormat,
1427                                                     GL_TEXTURE_GREEN_SIZE));
1428             }
1429          }
1430          else {
1431             *params = 0;
1432          }
1433          break;
1434       case GL_TEXTURE_DEPTH_SIZE_ARB:
1435          if (!ctx->Extensions.ARB_depth_texture)
1436             goto invalid_pname;
1437          *params = _mesa_get_format_bits(texFormat, pname);
1438          break;
1439       case GL_TEXTURE_STENCIL_SIZE:
1440          *params = _mesa_get_format_bits(texFormat, pname);
1441          break;
1442       case GL_TEXTURE_SHARED_SIZE:
1443          if (ctx->Version < 30 &&
1444              !ctx->Extensions.EXT_texture_shared_exponent)
1445             goto invalid_pname;
1446          *params = texFormat == MESA_FORMAT_R9G9B9E5_FLOAT ? 5 : 0;
1447          break;
1448 
1449       /* GL_ARB_texture_compression */
1450       case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
1451          if (_mesa_is_format_compressed(texFormat) &&
1452              !_mesa_is_proxy_texture(target)) {
1453             *params = _mesa_format_image_size(texFormat, img->Width,
1454                                               img->Height, img->Depth);
1455          } else {
1456             _mesa_error(ctx, GL_INVALID_OPERATION,
1457                         "glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
1458                         _mesa_enum_to_string(pname));
1459          }
1460          break;
1461       case GL_TEXTURE_COMPRESSED:
1462          *params = (GLint) _mesa_is_format_compressed(texFormat);
1463          break;
1464 
1465       /* GL_ARB_texture_float */
1466       case GL_TEXTURE_LUMINANCE_TYPE_ARB:
1467       case GL_TEXTURE_INTENSITY_TYPE_ARB:
1468          if (ctx->API != API_OPENGL_COMPAT)
1469             goto invalid_pname;
1470          /* FALLTHROUGH */
1471       case GL_TEXTURE_RED_TYPE_ARB:
1472       case GL_TEXTURE_GREEN_TYPE_ARB:
1473       case GL_TEXTURE_BLUE_TYPE_ARB:
1474       case GL_TEXTURE_ALPHA_TYPE_ARB:
1475       case GL_TEXTURE_DEPTH_TYPE_ARB:
1476          if (!ctx->Extensions.ARB_texture_float)
1477             goto invalid_pname;
1478 	 if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
1479 	    *params = _mesa_get_format_datatype(texFormat);
1480 	 else
1481 	    *params = GL_NONE;
1482          break;
1483 
1484       /* GL_ARB_texture_multisample */
1485       case GL_TEXTURE_SAMPLES:
1486          if (!ctx->Extensions.ARB_texture_multisample)
1487             goto invalid_pname;
1488          *params = img->NumSamples;
1489          break;
1490 
1491       case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
1492          if (!ctx->Extensions.ARB_texture_multisample)
1493             goto invalid_pname;
1494          *params = img->FixedSampleLocations;
1495          break;
1496 
1497       /* There is never a buffer data store here, but these pnames still have
1498        * to work.
1499        */
1500 
1501       /* GL_ARB_texture_buffer_object */
1502       case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
1503          if (!ctx->Extensions.ARB_texture_buffer_object)
1504             goto invalid_pname;
1505          *params = 0;
1506          break;
1507 
1508       /* GL_ARB_texture_buffer_range */
1509       case GL_TEXTURE_BUFFER_OFFSET:
1510          if (!ctx->Extensions.ARB_texture_buffer_range)
1511             goto invalid_pname;
1512          *params = 0;
1513          break;
1514       case GL_TEXTURE_BUFFER_SIZE:
1515          if (!ctx->Extensions.ARB_texture_buffer_range)
1516             goto invalid_pname;
1517          *params = 0;
1518          break;
1519 
1520       default:
1521          goto invalid_pname;
1522    }
1523 
1524    /* no error if we get here */
1525    return;
1526 
1527 invalid_pname:
1528    _mesa_error(ctx, GL_INVALID_ENUM,
1529                "glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
1530                _mesa_enum_to_string(pname));
1531 }
1532 
1533 
1534 /**
1535  * Handle a glGetTexLevelParamteriv() call for a texture buffer.
1536  */
1537 static void
get_tex_level_parameter_buffer(struct gl_context * ctx,const struct gl_texture_object * texObj,GLenum pname,GLint * params,bool dsa)1538 get_tex_level_parameter_buffer(struct gl_context *ctx,
1539                                const struct gl_texture_object *texObj,
1540                                GLenum pname, GLint *params, bool dsa)
1541 {
1542    const struct gl_buffer_object *bo = texObj->BufferObject;
1543    mesa_format texFormat = texObj->_BufferObjectFormat;
1544    int bytes = MAX2(1, _mesa_get_format_bytes(texFormat));
1545    GLenum internalFormat = texObj->BufferObjectFormat;
1546    GLenum baseFormat = _mesa_get_format_base_format(texFormat);
1547    const char *suffix = dsa ? "ture" : "";
1548 
1549    assert(texObj->Target == GL_TEXTURE_BUFFER);
1550 
1551    if (!bo) {
1552       /* undefined texture buffer object */
1553       switch (pname) {
1554       case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
1555          *params = GL_TRUE;
1556          break;
1557       case GL_TEXTURE_INTERNAL_FORMAT:
1558          *params = internalFormat;
1559          break;
1560       default:
1561          *params = 0;
1562          break;
1563       }
1564       return;
1565    }
1566 
1567    switch (pname) {
1568       case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
1569          *params = bo->Name;
1570          break;
1571       case GL_TEXTURE_WIDTH:
1572          *params = ((texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize)
1573             / bytes;
1574          break;
1575       case GL_TEXTURE_HEIGHT:
1576       case GL_TEXTURE_DEPTH:
1577          *params = 1;
1578          break;
1579       case GL_TEXTURE_BORDER:
1580       case GL_TEXTURE_SHARED_SIZE:
1581       case GL_TEXTURE_COMPRESSED:
1582          *params = 0;
1583          break;
1584       case GL_TEXTURE_INTERNAL_FORMAT:
1585          *params = internalFormat;
1586          break;
1587       case GL_TEXTURE_RED_SIZE:
1588       case GL_TEXTURE_GREEN_SIZE:
1589       case GL_TEXTURE_BLUE_SIZE:
1590       case GL_TEXTURE_ALPHA_SIZE:
1591          if (_mesa_base_format_has_channel(baseFormat, pname))
1592             *params = _mesa_get_format_bits(texFormat, pname);
1593          else
1594             *params = 0;
1595          break;
1596       case GL_TEXTURE_INTENSITY_SIZE:
1597       case GL_TEXTURE_LUMINANCE_SIZE:
1598          if (_mesa_base_format_has_channel(baseFormat, pname)) {
1599             *params = _mesa_get_format_bits(texFormat, pname);
1600             if (*params == 0) {
1601                /* intensity or luminance is probably stored as RGB[A] */
1602                *params = MIN2(_mesa_get_format_bits(texFormat,
1603                                                     GL_TEXTURE_RED_SIZE),
1604                               _mesa_get_format_bits(texFormat,
1605                                                     GL_TEXTURE_GREEN_SIZE));
1606             }
1607          } else {
1608             *params = 0;
1609          }
1610          break;
1611       case GL_TEXTURE_DEPTH_SIZE_ARB:
1612       case GL_TEXTURE_STENCIL_SIZE_EXT:
1613          *params = _mesa_get_format_bits(texFormat, pname);
1614          break;
1615 
1616       /* GL_ARB_texture_buffer_range */
1617       case GL_TEXTURE_BUFFER_OFFSET:
1618          if (!ctx->Extensions.ARB_texture_buffer_range)
1619             goto invalid_pname;
1620          *params = texObj->BufferOffset;
1621          break;
1622       case GL_TEXTURE_BUFFER_SIZE:
1623          if (!ctx->Extensions.ARB_texture_buffer_range)
1624             goto invalid_pname;
1625          *params = (texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize;
1626          break;
1627 
1628       /* GL_ARB_texture_multisample */
1629       case GL_TEXTURE_SAMPLES:
1630          if (!ctx->Extensions.ARB_texture_multisample)
1631             goto invalid_pname;
1632          *params = 0;
1633          break;
1634 
1635       case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
1636          if (!ctx->Extensions.ARB_texture_multisample)
1637             goto invalid_pname;
1638          *params = GL_TRUE;
1639          break;
1640 
1641       /* GL_ARB_texture_compression */
1642       case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
1643          /* Always illegal for GL_TEXTURE_BUFFER */
1644          _mesa_error(ctx, GL_INVALID_OPERATION,
1645                      "glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
1646                      _mesa_enum_to_string(pname));
1647          break;
1648 
1649       /* GL_ARB_texture_float */
1650       case GL_TEXTURE_RED_TYPE_ARB:
1651       case GL_TEXTURE_GREEN_TYPE_ARB:
1652       case GL_TEXTURE_BLUE_TYPE_ARB:
1653       case GL_TEXTURE_ALPHA_TYPE_ARB:
1654       case GL_TEXTURE_LUMINANCE_TYPE_ARB:
1655       case GL_TEXTURE_INTENSITY_TYPE_ARB:
1656       case GL_TEXTURE_DEPTH_TYPE_ARB:
1657          if (!ctx->Extensions.ARB_texture_float)
1658             goto invalid_pname;
1659          if (_mesa_base_format_has_channel(baseFormat, pname))
1660             *params = _mesa_get_format_datatype(texFormat);
1661          else
1662             *params = GL_NONE;
1663          break;
1664 
1665       default:
1666          goto invalid_pname;
1667    }
1668 
1669    /* no error if we get here */
1670    return;
1671 
1672 invalid_pname:
1673    _mesa_error(ctx, GL_INVALID_ENUM,
1674                "glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
1675                _mesa_enum_to_string(pname));
1676 }
1677 
1678 static bool
valid_tex_level_parameteriv_target(struct gl_context * ctx,GLenum target,bool dsa)1679 valid_tex_level_parameteriv_target(struct gl_context *ctx, GLenum target,
1680                                    bool dsa)
1681 {
1682    const char *suffix = dsa ? "ture" : "";
1683    if (!_mesa_legal_get_tex_level_parameter_target(ctx, target, dsa)) {
1684       _mesa_error(ctx, GL_INVALID_ENUM,
1685                   "glGetTex%sLevelParameter[if]v(target=%s)", suffix,
1686                   _mesa_enum_to_string(target));
1687       return false;
1688    }
1689    return true;
1690 }
1691 
1692 /**
1693  * This isn't exposed to the rest of the driver because it is a part of the
1694  * OpenGL API that is rarely used.
1695  */
1696 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)1697 get_tex_level_parameteriv(struct gl_context *ctx,
1698                           struct gl_texture_object *texObj,
1699                           GLenum target, GLint level,
1700                           GLenum pname, GLint *params,
1701                           bool dsa)
1702 {
1703    GLint maxLevels;
1704    const char *suffix = dsa ? "ture" : "";
1705 
1706    /* Check for errors */
1707    if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
1708       _mesa_error(ctx, GL_INVALID_OPERATION,
1709                   "glGetTex%sLevelParameter[if]v("
1710                   "current unit >= max combined texture units)", suffix);
1711       return;
1712    }
1713 
1714    maxLevels = _mesa_max_texture_levels(ctx, target);
1715    assert(maxLevels != 0);
1716 
1717    if (level < 0 || level >= maxLevels) {
1718       _mesa_error(ctx, GL_INVALID_VALUE,
1719                   "glGetTex%sLevelParameter[if]v(level out of range)", suffix);
1720       return;
1721    }
1722 
1723    /* Get the level parameter */
1724    if (target == GL_TEXTURE_BUFFER) {
1725       get_tex_level_parameter_buffer(ctx, texObj, pname, params, dsa);
1726    }
1727    else {
1728       get_tex_level_parameter_image(ctx, texObj, target,
1729                                     level, pname, params, dsa);
1730    }
1731 }
1732 
1733 void GLAPIENTRY
_mesa_GetTexLevelParameterfv(GLenum target,GLint level,GLenum pname,GLfloat * params)1734 _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
1735                               GLenum pname, GLfloat *params )
1736 {
1737    struct gl_texture_object *texObj;
1738    GLint iparam;
1739    GET_CURRENT_CONTEXT(ctx);
1740 
1741    if (!valid_tex_level_parameteriv_target(ctx, target, false))
1742       return;
1743 
1744    texObj = _mesa_get_current_tex_object(ctx, target);
1745    if (!texObj)
1746       return;
1747 
1748    get_tex_level_parameteriv(ctx, texObj, target, level,
1749                              pname, &iparam, false);
1750 
1751    *params = (GLfloat) iparam;
1752 }
1753 
1754 void GLAPIENTRY
_mesa_GetTexLevelParameteriv(GLenum target,GLint level,GLenum pname,GLint * params)1755 _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
1756                               GLenum pname, GLint *params )
1757 {
1758    struct gl_texture_object *texObj;
1759    GET_CURRENT_CONTEXT(ctx);
1760 
1761    if (!valid_tex_level_parameteriv_target(ctx, target, false))
1762       return;
1763 
1764    texObj = _mesa_get_current_tex_object(ctx, target);
1765    if (!texObj)
1766       return;
1767 
1768    get_tex_level_parameteriv(ctx, texObj, target, level,
1769                              pname, params, false);
1770 }
1771 
1772 void GLAPIENTRY
_mesa_GetTextureLevelParameterfv(GLuint texture,GLint level,GLenum pname,GLfloat * params)1773 _mesa_GetTextureLevelParameterfv(GLuint texture, GLint level,
1774                                  GLenum pname, GLfloat *params)
1775 {
1776    struct gl_texture_object *texObj;
1777    GLint iparam;
1778    GET_CURRENT_CONTEXT(ctx);
1779 
1780    texObj = _mesa_lookup_texture_err(ctx, texture,
1781                                      "glGetTextureLevelParameterfv");
1782    if (!texObj)
1783       return;
1784 
1785    if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true))
1786       return;
1787 
1788    get_tex_level_parameteriv(ctx, texObj, texObj->Target, level,
1789                              pname, &iparam, true);
1790 
1791    *params = (GLfloat) iparam;
1792 }
1793 
1794 void GLAPIENTRY
_mesa_GetTextureLevelParameteriv(GLuint texture,GLint level,GLenum pname,GLint * params)1795 _mesa_GetTextureLevelParameteriv(GLuint texture, GLint level,
1796                                  GLenum pname, GLint *params)
1797 {
1798    struct gl_texture_object *texObj;
1799    GET_CURRENT_CONTEXT(ctx);
1800 
1801    texObj = _mesa_lookup_texture_err(ctx, texture,
1802                                      "glGetTextureLevelParameteriv");
1803    if (!texObj)
1804       return;
1805 
1806    if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true))
1807       return;
1808 
1809    get_tex_level_parameteriv(ctx, texObj, texObj->Target, level,
1810                              pname, params, true);
1811 }
1812 
1813 /**
1814  * This isn't exposed to the rest of the driver because it is a part of the
1815  * OpenGL API that is rarely used.
1816  */
1817 static void
get_tex_parameterfv(struct gl_context * ctx,struct gl_texture_object * obj,GLenum pname,GLfloat * params,bool dsa)1818 get_tex_parameterfv(struct gl_context *ctx,
1819                     struct gl_texture_object *obj,
1820                     GLenum pname, GLfloat *params, bool dsa)
1821 {
1822    _mesa_lock_context_textures(ctx);
1823    switch (pname) {
1824       case GL_TEXTURE_MAG_FILTER:
1825 	 *params = ENUM_TO_FLOAT(obj->Sampler.MagFilter);
1826 	 break;
1827       case GL_TEXTURE_MIN_FILTER:
1828          *params = ENUM_TO_FLOAT(obj->Sampler.MinFilter);
1829          break;
1830       case GL_TEXTURE_WRAP_S:
1831          *params = ENUM_TO_FLOAT(obj->Sampler.WrapS);
1832          break;
1833       case GL_TEXTURE_WRAP_T:
1834          *params = ENUM_TO_FLOAT(obj->Sampler.WrapT);
1835          break;
1836       case GL_TEXTURE_WRAP_R:
1837          *params = ENUM_TO_FLOAT(obj->Sampler.WrapR);
1838          break;
1839       case GL_TEXTURE_BORDER_COLOR:
1840          if (ctx->API == API_OPENGLES ||
1841              !ctx->Extensions.ARB_texture_border_clamp)
1842             goto invalid_pname;
1843 
1844          if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
1845             _mesa_update_state_locked(ctx);
1846          if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer)) {
1847             params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
1848             params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
1849             params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
1850             params[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
1851          }
1852          else {
1853             params[0] = obj->Sampler.BorderColor.f[0];
1854             params[1] = obj->Sampler.BorderColor.f[1];
1855             params[2] = obj->Sampler.BorderColor.f[2];
1856             params[3] = obj->Sampler.BorderColor.f[3];
1857          }
1858          break;
1859       case GL_TEXTURE_RESIDENT:
1860          if (ctx->API != API_OPENGL_COMPAT)
1861             goto invalid_pname;
1862 
1863          *params = 1.0F;
1864          break;
1865       case GL_TEXTURE_PRIORITY:
1866          if (ctx->API != API_OPENGL_COMPAT)
1867             goto invalid_pname;
1868 
1869          *params = obj->Priority;
1870          break;
1871       case GL_TEXTURE_MIN_LOD:
1872          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1873             goto invalid_pname;
1874 
1875          *params = obj->Sampler.MinLod;
1876          break;
1877       case GL_TEXTURE_MAX_LOD:
1878          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1879             goto invalid_pname;
1880 
1881          *params = obj->Sampler.MaxLod;
1882          break;
1883       case GL_TEXTURE_BASE_LEVEL:
1884          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1885             goto invalid_pname;
1886 
1887          *params = (GLfloat) obj->BaseLevel;
1888          break;
1889       case GL_TEXTURE_MAX_LEVEL:
1890          *params = (GLfloat) obj->MaxLevel;
1891          break;
1892       case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1893          if (!ctx->Extensions.EXT_texture_filter_anisotropic)
1894             goto invalid_pname;
1895          *params = obj->Sampler.MaxAnisotropy;
1896          break;
1897       case GL_GENERATE_MIPMAP_SGIS:
1898          if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1899             goto invalid_pname;
1900 
1901 	 *params = (GLfloat) obj->GenerateMipmap;
1902          break;
1903       case GL_TEXTURE_COMPARE_MODE_ARB:
1904          if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
1905              && !_mesa_is_gles3(ctx))
1906             goto invalid_pname;
1907          *params = (GLfloat) obj->Sampler.CompareMode;
1908          break;
1909       case GL_TEXTURE_COMPARE_FUNC_ARB:
1910          if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
1911              && !_mesa_is_gles3(ctx))
1912             goto invalid_pname;
1913          *params = (GLfloat) obj->Sampler.CompareFunc;
1914          break;
1915       case GL_DEPTH_TEXTURE_MODE_ARB:
1916          /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has
1917           * never existed in OpenGL ES.
1918           */
1919          if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture)
1920             goto invalid_pname;
1921          *params = (GLfloat) obj->DepthMode;
1922          break;
1923       case GL_DEPTH_STENCIL_TEXTURE_MODE:
1924          if (!_mesa_has_ARB_stencil_texturing(ctx) && !_mesa_is_gles31(ctx))
1925             goto invalid_pname;
1926          *params = (GLfloat)
1927             (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT);
1928          break;
1929       case GL_TEXTURE_LOD_BIAS:
1930          if (_mesa_is_gles(ctx))
1931             goto invalid_pname;
1932 
1933          *params = obj->Sampler.LodBias;
1934          break;
1935       case GL_TEXTURE_CROP_RECT_OES:
1936          if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
1937             goto invalid_pname;
1938 
1939          params[0] = (GLfloat) obj->CropRect[0];
1940          params[1] = (GLfloat) obj->CropRect[1];
1941          params[2] = (GLfloat) obj->CropRect[2];
1942          params[3] = (GLfloat) obj->CropRect[3];
1943          break;
1944 
1945       case GL_TEXTURE_SWIZZLE_R_EXT:
1946       case GL_TEXTURE_SWIZZLE_G_EXT:
1947       case GL_TEXTURE_SWIZZLE_B_EXT:
1948       case GL_TEXTURE_SWIZZLE_A_EXT:
1949          if ((!_mesa_is_desktop_gl(ctx)
1950               || !ctx->Extensions.EXT_texture_swizzle)
1951              && !_mesa_is_gles3(ctx))
1952             goto invalid_pname;
1953          *params = (GLfloat) obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
1954          break;
1955 
1956       case GL_TEXTURE_SWIZZLE_RGBA_EXT:
1957          if ((!_mesa_is_desktop_gl(ctx)
1958               || !ctx->Extensions.EXT_texture_swizzle)
1959              && !_mesa_is_gles3(ctx)) {
1960             goto invalid_pname;
1961          }
1962          else {
1963             GLuint comp;
1964             for (comp = 0; comp < 4; comp++) {
1965                params[comp] = (GLfloat) obj->Swizzle[comp];
1966             }
1967          }
1968          break;
1969 
1970       case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1971          if (!_mesa_is_desktop_gl(ctx)
1972              || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
1973             goto invalid_pname;
1974          *params = (GLfloat) obj->Sampler.CubeMapSeamless;
1975          break;
1976 
1977       case GL_TEXTURE_IMMUTABLE_FORMAT:
1978          *params = (GLfloat) obj->Immutable;
1979          break;
1980 
1981       case GL_TEXTURE_IMMUTABLE_LEVELS:
1982          if (_mesa_is_gles3(ctx) ||
1983              (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view))
1984             *params = (GLfloat) obj->ImmutableLevels;
1985          else
1986             goto invalid_pname;
1987          break;
1988 
1989       case GL_TEXTURE_VIEW_MIN_LEVEL:
1990          if (!ctx->Extensions.ARB_texture_view)
1991             goto invalid_pname;
1992          *params = (GLfloat) obj->MinLevel;
1993          break;
1994 
1995       case GL_TEXTURE_VIEW_NUM_LEVELS:
1996          if (!ctx->Extensions.ARB_texture_view)
1997             goto invalid_pname;
1998          *params = (GLfloat) obj->NumLevels;
1999          break;
2000 
2001       case GL_TEXTURE_VIEW_MIN_LAYER:
2002          if (!ctx->Extensions.ARB_texture_view)
2003             goto invalid_pname;
2004          *params = (GLfloat) obj->MinLayer;
2005          break;
2006 
2007       case GL_TEXTURE_VIEW_NUM_LAYERS:
2008          if (!ctx->Extensions.ARB_texture_view)
2009             goto invalid_pname;
2010          *params = (GLfloat) obj->NumLayers;
2011          break;
2012 
2013       case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
2014          if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
2015             goto invalid_pname;
2016          *params = (GLfloat) obj->RequiredTextureImageUnits;
2017          break;
2018 
2019       case GL_TEXTURE_SRGB_DECODE_EXT:
2020          if (!ctx->Extensions.EXT_texture_sRGB_decode)
2021             goto invalid_pname;
2022          *params = (GLfloat) obj->Sampler.sRGBDecode;
2023          break;
2024 
2025       case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
2026          if (!ctx->Extensions.ARB_shader_image_load_store)
2027             goto invalid_pname;
2028          *params = (GLfloat) obj->ImageFormatCompatibilityType;
2029          break;
2030 
2031       case GL_TEXTURE_TARGET:
2032          if (ctx->API != API_OPENGL_CORE)
2033             goto invalid_pname;
2034          *params = ENUM_TO_FLOAT(obj->Target);
2035          break;
2036 
2037       case GL_TEXTURE_TILING_EXT:
2038          if (!ctx->Extensions.EXT_memory_object)
2039             goto invalid_pname;
2040          *params = ENUM_TO_FLOAT(obj->TextureTiling);
2041          break;
2042 
2043       default:
2044          goto invalid_pname;
2045    }
2046 
2047    /* no error if we get here */
2048    _mesa_unlock_context_textures(ctx);
2049    return;
2050 
2051 invalid_pname:
2052    _mesa_unlock_context_textures(ctx);
2053    _mesa_error(ctx, GL_INVALID_ENUM, "glGetTex%sParameterfv(pname=0x%x)",
2054                dsa ? "ture" : "", pname);
2055 }
2056 
2057 
2058 static void
get_tex_parameteriv(struct gl_context * ctx,struct gl_texture_object * obj,GLenum pname,GLint * params,bool dsa)2059 get_tex_parameteriv(struct gl_context *ctx,
2060                     struct gl_texture_object *obj,
2061                     GLenum pname, GLint *params, bool dsa)
2062 {
2063    _mesa_lock_texture(ctx, obj);
2064    switch (pname) {
2065       case GL_TEXTURE_MAG_FILTER:
2066          *params = (GLint) obj->Sampler.MagFilter;
2067          break;
2068       case GL_TEXTURE_MIN_FILTER:
2069          *params = (GLint) obj->Sampler.MinFilter;
2070          break;
2071       case GL_TEXTURE_WRAP_S:
2072          *params = (GLint) obj->Sampler.WrapS;
2073          break;
2074       case GL_TEXTURE_WRAP_T:
2075          *params = (GLint) obj->Sampler.WrapT;
2076          break;
2077       case GL_TEXTURE_WRAP_R:
2078          *params = (GLint) obj->Sampler.WrapR;
2079          break;
2080       case GL_TEXTURE_BORDER_COLOR:
2081          if (ctx->API == API_OPENGLES ||
2082              !ctx->Extensions.ARB_texture_border_clamp)
2083             goto invalid_pname;
2084 
2085          {
2086             GLfloat b[4];
2087             b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
2088             b[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
2089             b[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
2090             b[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
2091             params[0] = FLOAT_TO_INT(b[0]);
2092             params[1] = FLOAT_TO_INT(b[1]);
2093             params[2] = FLOAT_TO_INT(b[2]);
2094             params[3] = FLOAT_TO_INT(b[3]);
2095          }
2096          break;
2097       case GL_TEXTURE_RESIDENT:
2098          if (ctx->API != API_OPENGL_COMPAT)
2099             goto invalid_pname;
2100 
2101          *params = 1;
2102          break;
2103       case GL_TEXTURE_PRIORITY:
2104          if (ctx->API != API_OPENGL_COMPAT)
2105             goto invalid_pname;
2106 
2107          *params = FLOAT_TO_INT(obj->Priority);
2108          break;
2109       case GL_TEXTURE_MIN_LOD:
2110          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
2111             goto invalid_pname;
2112          /* GL spec 'Data Conversions' section specifies that floating-point
2113           * value in integer Get function is rounded to nearest integer
2114           */
2115          *params = IROUND(obj->Sampler.MinLod);
2116          break;
2117       case GL_TEXTURE_MAX_LOD:
2118          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
2119             goto invalid_pname;
2120          /* GL spec 'Data Conversions' section specifies that floating-point
2121           * value in integer Get function is rounded to nearest integer
2122           */
2123          *params = IROUND(obj->Sampler.MaxLod);
2124          break;
2125       case GL_TEXTURE_BASE_LEVEL:
2126          if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
2127             goto invalid_pname;
2128 
2129          *params = obj->BaseLevel;
2130          break;
2131       case GL_TEXTURE_MAX_LEVEL:
2132          *params = obj->MaxLevel;
2133          break;
2134       case GL_TEXTURE_MAX_ANISOTROPY_EXT:
2135          if (!ctx->Extensions.EXT_texture_filter_anisotropic)
2136             goto invalid_pname;
2137          /* GL spec 'Data Conversions' section specifies that floating-point
2138           * value in integer Get function is rounded to nearest integer
2139           */
2140          *params = IROUND(obj->Sampler.MaxAnisotropy);
2141          break;
2142       case GL_GENERATE_MIPMAP_SGIS:
2143          if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
2144             goto invalid_pname;
2145 
2146 	 *params = (GLint) obj->GenerateMipmap;
2147          break;
2148       case GL_TEXTURE_COMPARE_MODE_ARB:
2149          if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
2150              && !_mesa_is_gles3(ctx))
2151             goto invalid_pname;
2152          *params = (GLint) obj->Sampler.CompareMode;
2153          break;
2154       case GL_TEXTURE_COMPARE_FUNC_ARB:
2155          if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
2156              && !_mesa_is_gles3(ctx))
2157             goto invalid_pname;
2158          *params = (GLint) obj->Sampler.CompareFunc;
2159          break;
2160       case GL_DEPTH_TEXTURE_MODE_ARB:
2161          if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture)
2162             goto invalid_pname;
2163          *params = (GLint) obj->DepthMode;
2164          break;
2165       case GL_DEPTH_STENCIL_TEXTURE_MODE:
2166          if (!_mesa_has_ARB_stencil_texturing(ctx) && !_mesa_is_gles31(ctx))
2167             goto invalid_pname;
2168          *params = (GLint)
2169             (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT);
2170          break;
2171       case GL_TEXTURE_LOD_BIAS:
2172          if (_mesa_is_gles(ctx))
2173             goto invalid_pname;
2174 
2175          /* GL spec 'Data Conversions' section specifies that floating-point
2176           * value in integer Get function is rounded to nearest integer
2177           */
2178          *params = IROUND(obj->Sampler.LodBias);
2179          break;
2180       case GL_TEXTURE_CROP_RECT_OES:
2181          if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
2182             goto invalid_pname;
2183 
2184          params[0] = obj->CropRect[0];
2185          params[1] = obj->CropRect[1];
2186          params[2] = obj->CropRect[2];
2187          params[3] = obj->CropRect[3];
2188          break;
2189       case GL_TEXTURE_SWIZZLE_R_EXT:
2190       case GL_TEXTURE_SWIZZLE_G_EXT:
2191       case GL_TEXTURE_SWIZZLE_B_EXT:
2192       case GL_TEXTURE_SWIZZLE_A_EXT:
2193          if ((!_mesa_is_desktop_gl(ctx)
2194               || !ctx->Extensions.EXT_texture_swizzle)
2195              && !_mesa_is_gles3(ctx))
2196             goto invalid_pname;
2197          *params = obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
2198          break;
2199 
2200       case GL_TEXTURE_SWIZZLE_RGBA_EXT:
2201          if ((!_mesa_is_desktop_gl(ctx)
2202               || !ctx->Extensions.EXT_texture_swizzle)
2203              && !_mesa_is_gles3(ctx))
2204             goto invalid_pname;
2205          COPY_4V(params, obj->Swizzle);
2206          break;
2207 
2208       case GL_TEXTURE_CUBE_MAP_SEAMLESS:
2209          if (!_mesa_is_desktop_gl(ctx)
2210              || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
2211             goto invalid_pname;
2212          *params = (GLint) obj->Sampler.CubeMapSeamless;
2213          break;
2214 
2215       case GL_TEXTURE_IMMUTABLE_FORMAT:
2216          *params = (GLint) obj->Immutable;
2217          break;
2218 
2219       case GL_TEXTURE_IMMUTABLE_LEVELS:
2220          if (_mesa_is_gles3(ctx) ||
2221              (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view))
2222             *params = obj->ImmutableLevels;
2223          else
2224             goto invalid_pname;
2225          break;
2226 
2227       case GL_TEXTURE_VIEW_MIN_LEVEL:
2228          if (!ctx->Extensions.ARB_texture_view)
2229             goto invalid_pname;
2230          *params = (GLint) obj->MinLevel;
2231          break;
2232 
2233       case GL_TEXTURE_VIEW_NUM_LEVELS:
2234          if (!ctx->Extensions.ARB_texture_view)
2235             goto invalid_pname;
2236          *params = (GLint) obj->NumLevels;
2237          break;
2238 
2239       case GL_TEXTURE_VIEW_MIN_LAYER:
2240          if (!ctx->Extensions.ARB_texture_view)
2241             goto invalid_pname;
2242          *params = (GLint) obj->MinLayer;
2243          break;
2244 
2245       case GL_TEXTURE_VIEW_NUM_LAYERS:
2246          if (!ctx->Extensions.ARB_texture_view)
2247             goto invalid_pname;
2248          *params = (GLint) obj->NumLayers;
2249          break;
2250 
2251       case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
2252          if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
2253             goto invalid_pname;
2254          *params = obj->RequiredTextureImageUnits;
2255          break;
2256 
2257       case GL_TEXTURE_SRGB_DECODE_EXT:
2258          if (!ctx->Extensions.EXT_texture_sRGB_decode)
2259             goto invalid_pname;
2260          *params = obj->Sampler.sRGBDecode;
2261          break;
2262 
2263       case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
2264          if (!ctx->Extensions.ARB_shader_image_load_store)
2265             goto invalid_pname;
2266          *params = obj->ImageFormatCompatibilityType;
2267          break;
2268 
2269       case GL_TEXTURE_TARGET:
2270          if (ctx->API != API_OPENGL_CORE)
2271             goto invalid_pname;
2272          *params = (GLint) obj->Target;
2273          break;
2274 
2275       case GL_TEXTURE_TILING_EXT:
2276          if (!ctx->Extensions.EXT_memory_object)
2277             goto invalid_pname;
2278          *params = (GLint) obj->TextureTiling;
2279          break;
2280 
2281       default:
2282          goto invalid_pname;
2283    }
2284 
2285    /* no error if we get here */
2286    _mesa_unlock_texture(ctx, obj);
2287    return;
2288 
2289 invalid_pname:
2290    _mesa_unlock_texture(ctx, obj);
2291    _mesa_error(ctx, GL_INVALID_ENUM, "glGetTex%sParameteriv(pname=0x%x)",
2292                dsa ? "ture" : "", pname);
2293 }
2294 
2295 static void
get_tex_parameterIiv(struct gl_context * ctx,struct gl_texture_object * obj,GLenum pname,GLint * params,bool dsa)2296 get_tex_parameterIiv(struct gl_context *ctx,
2297                      struct gl_texture_object *obj,
2298                      GLenum pname, GLint *params, bool dsa)
2299 {
2300    switch (pname) {
2301    case GL_TEXTURE_BORDER_COLOR:
2302       COPY_4V(params, obj->Sampler.BorderColor.i);
2303       break;
2304    default:
2305       get_tex_parameteriv(ctx, obj, pname, params, dsa);
2306    }
2307 }
2308 
2309 void GLAPIENTRY
_mesa_GetTexParameterfv(GLenum target,GLenum pname,GLfloat * params)2310 _mesa_GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
2311 {
2312    struct gl_texture_object *obj;
2313    GET_CURRENT_CONTEXT(ctx);
2314 
2315    obj = get_texobj_by_target(ctx, target, GL_TRUE);
2316    if (!obj)
2317       return;
2318 
2319    get_tex_parameterfv(ctx, obj, pname, params, false);
2320 }
2321 
2322 void GLAPIENTRY
_mesa_GetTexParameteriv(GLenum target,GLenum pname,GLint * params)2323 _mesa_GetTexParameteriv(GLenum target, GLenum pname, GLint *params)
2324 {
2325    struct gl_texture_object *obj;
2326    GET_CURRENT_CONTEXT(ctx);
2327 
2328    obj = get_texobj_by_target(ctx, target, GL_TRUE);
2329    if (!obj)
2330       return;
2331 
2332    get_tex_parameteriv(ctx, obj, pname, params, false);
2333 }
2334 
2335 /** New in GL 3.0 */
2336 void GLAPIENTRY
_mesa_GetTexParameterIiv(GLenum target,GLenum pname,GLint * params)2337 _mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params)
2338 {
2339    struct gl_texture_object *texObj;
2340    GET_CURRENT_CONTEXT(ctx);
2341 
2342    texObj = get_texobj_by_target(ctx, target, GL_TRUE);
2343    if (!texObj)
2344       return;
2345 
2346    get_tex_parameterIiv(ctx, texObj, pname, params, false);
2347 }
2348 
2349 
2350 /** New in GL 3.0 */
2351 void GLAPIENTRY
_mesa_GetTexParameterIuiv(GLenum target,GLenum pname,GLuint * params)2352 _mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)
2353 {
2354    struct gl_texture_object *texObj;
2355    GET_CURRENT_CONTEXT(ctx);
2356 
2357    texObj = get_texobj_by_target(ctx, target, GL_TRUE);
2358    if (!texObj)
2359       return;
2360 
2361    get_tex_parameterIiv(ctx, texObj, pname, (GLint *) params, false);
2362 }
2363 
2364 
2365 void GLAPIENTRY
_mesa_GetTextureParameterfv(GLuint texture,GLenum pname,GLfloat * params)2366 _mesa_GetTextureParameterfv(GLuint texture, GLenum pname, GLfloat *params)
2367 {
2368    struct gl_texture_object *obj;
2369    GET_CURRENT_CONTEXT(ctx);
2370 
2371    obj = get_texobj_by_name(ctx, texture, "glGetTextureParameterfv");
2372    if (!obj)
2373       return;
2374 
2375    get_tex_parameterfv(ctx, obj, pname, params, true);
2376 }
2377 
2378 void GLAPIENTRY
_mesa_GetTextureParameteriv(GLuint texture,GLenum pname,GLint * params)2379 _mesa_GetTextureParameteriv(GLuint texture, GLenum pname, GLint *params)
2380 {
2381    struct gl_texture_object *obj;
2382    GET_CURRENT_CONTEXT(ctx);
2383 
2384    obj = get_texobj_by_name(ctx, texture, "glGetTextureParameteriv");
2385    if (!obj)
2386       return;
2387 
2388    get_tex_parameteriv(ctx, obj, pname, params, true);
2389 }
2390 
2391 void GLAPIENTRY
_mesa_GetTextureParameterIiv(GLuint texture,GLenum pname,GLint * params)2392 _mesa_GetTextureParameterIiv(GLuint texture, GLenum pname, GLint *params)
2393 {
2394    struct gl_texture_object *texObj;
2395    GET_CURRENT_CONTEXT(ctx);
2396 
2397    texObj = get_texobj_by_name(ctx, texture, "glGetTextureParameterIiv");
2398    if (!texObj)
2399       return;
2400 
2401    get_tex_parameterIiv(ctx, texObj, pname, params, true);
2402 }
2403 
2404 
2405 void GLAPIENTRY
_mesa_GetTextureParameterIuiv(GLuint texture,GLenum pname,GLuint * params)2406 _mesa_GetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint *params)
2407 {
2408    struct gl_texture_object *texObj;
2409    GET_CURRENT_CONTEXT(ctx);
2410 
2411    texObj = get_texobj_by_name(ctx, texture, "glGetTextureParameterIuiv");
2412    if (!texObj)
2413       return;
2414 
2415    get_tex_parameterIiv(ctx, texObj, pname, (GLint *) params, true);
2416 }
2417