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