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