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