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