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