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