mesa: enable enums for OES_texture_storage_multisample_2d_array
[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 /* Common targets for desktop GL and GLES 3.1. */
1212 switch (target) {
1213 case GL_TEXTURE_2D:
1214 case GL_TEXTURE_3D:
1215 return GL_TRUE;
1216 case GL_TEXTURE_2D_ARRAY_EXT:
1217 return ctx->Extensions.EXT_texture_array;
1218 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
1219 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
1220 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
1221 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
1222 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
1223 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
1224 return ctx->Extensions.ARB_texture_cube_map;
1225 case GL_TEXTURE_2D_MULTISAMPLE:
1226 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
1227 return ctx->Extensions.ARB_texture_multisample;
1228 }
1229
1230 if (!_mesa_is_desktop_gl(ctx))
1231 return GL_FALSE;
1232
1233 /* Rest of the desktop GL targets. */
1234 switch (target) {
1235 case GL_TEXTURE_1D:
1236 case GL_PROXY_TEXTURE_1D:
1237 case GL_PROXY_TEXTURE_2D:
1238 case GL_PROXY_TEXTURE_3D:
1239 return GL_TRUE;
1240 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
1241 return ctx->Extensions.ARB_texture_cube_map;
1242 case GL_TEXTURE_CUBE_MAP_ARRAY_ARB:
1243 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB:
1244 return ctx->Extensions.ARB_texture_cube_map_array;
1245 case GL_TEXTURE_RECTANGLE_NV:
1246 case GL_PROXY_TEXTURE_RECTANGLE_NV:
1247 return ctx->Extensions.NV_texture_rectangle;
1248 case GL_TEXTURE_1D_ARRAY_EXT:
1249 case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
1250 case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1251 return ctx->Extensions.EXT_texture_array;
1252 case GL_TEXTURE_BUFFER:
1253 /* GetTexLevelParameter accepts GL_TEXTURE_BUFFER in GL 3.1+ contexts,
1254 * but not in earlier versions that expose ARB_texture_buffer_object.
1255 *
1256 * From the ARB_texture_buffer_object spec:
1257 * "(7) Do buffer textures support texture parameters (TexParameter) or
1258 * queries (GetTexParameter, GetTexLevelParameter, GetTexImage)?
1259 *
1260 * RESOLVED: No. [...] Note that the spec edits above don't add
1261 * explicit error language for any of these cases. That is because
1262 * each of the functions enumerate the set of valid <target>
1263 * parameters. Not editing the spec to allow TEXTURE_BUFFER_ARB in
1264 * these cases means that target is not legal, and an INVALID_ENUM
1265 * error should be generated."
1266 *
1267 * From the OpenGL 3.1 spec:
1268 * "target may also be TEXTURE_BUFFER, indicating the texture buffer."
1269 */
1270 return ctx->API == API_OPENGL_CORE && ctx->Version >= 31;
1271 case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
1272 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
1273 return ctx->Extensions.ARB_texture_multisample;
1274
1275 /* This is a valid target for dsa, but the OpenGL 4.5 core spec
1276 * (30.10.2014) Section 8.11 Texture Queries says:
1277 * "For GetTextureLevelParameter* only, texture may also be a cube
1278 * map texture object. In this case the query is always performed
1279 * for face zero (the TEXTURE_CUBE_MAP_POSITIVE_X face), since there
1280 * is no way to specify another face."
1281 */
1282 case GL_TEXTURE_CUBE_MAP:
1283 return dsa;
1284 default:
1285 return GL_FALSE;
1286 }
1287 }
1288
1289
1290 static void
1291 get_tex_level_parameter_image(struct gl_context *ctx,
1292 const struct gl_texture_object *texObj,
1293 GLenum target, GLint level,
1294 GLenum pname, GLint *params,
1295 bool dsa)
1296 {
1297 const struct gl_texture_image *img = NULL;
1298 struct gl_texture_image dummy_image;
1299 mesa_format texFormat;
1300 const char *suffix = dsa ? "ture" : "";
1301
1302 img = _mesa_select_tex_image(texObj, target, level);
1303 if (!img || img->TexFormat == MESA_FORMAT_NONE) {
1304 /* In case of undefined texture image return the default values.
1305 *
1306 * From OpenGL 4.0 spec, page 398:
1307 * "The initial internal format of a texel array is RGBA
1308 * instead of 1. TEXTURE_COMPONENTS is deprecated; always
1309 * use TEXTURE_INTERNAL_FORMAT."
1310 */
1311 memset(&dummy_image, 0, sizeof(dummy_image));
1312 dummy_image.TexFormat = MESA_FORMAT_NONE;
1313 dummy_image.InternalFormat = GL_RGBA;
1314 dummy_image._BaseFormat = GL_NONE;
1315
1316 img = &dummy_image;
1317 }
1318
1319 texFormat = img->TexFormat;
1320
1321 switch (pname) {
1322 case GL_TEXTURE_WIDTH:
1323 *params = img->Width;
1324 break;
1325 case GL_TEXTURE_HEIGHT:
1326 *params = img->Height;
1327 break;
1328 case GL_TEXTURE_DEPTH:
1329 *params = img->Depth;
1330 break;
1331 case GL_TEXTURE_INTERNAL_FORMAT:
1332 if (_mesa_is_format_compressed(texFormat)) {
1333 /* need to return the actual compressed format */
1334 *params = _mesa_compressed_format_to_glenum(ctx, texFormat);
1335 }
1336 else {
1337 /* If the true internal format is not compressed but the user
1338 * requested a generic compressed format, we have to return the
1339 * generic base format that matches.
1340 *
1341 * From page 119 (page 129 of the PDF) of the OpenGL 1.3 spec:
1342 *
1343 * "If no specific compressed format is available,
1344 * internalformat is instead replaced by the corresponding base
1345 * internal format."
1346 *
1347 * Otherwise just return the user's requested internal format
1348 */
1349 const GLenum f =
1350 _mesa_gl_compressed_format_base_format(img->InternalFormat);
1351
1352 *params = (f != 0) ? f : img->InternalFormat;
1353 }
1354 break;
1355 case GL_TEXTURE_BORDER:
1356 if (ctx->API != API_OPENGL_COMPAT)
1357 goto invalid_pname;
1358 *params = img->Border;
1359 break;
1360 case GL_TEXTURE_RED_SIZE:
1361 case GL_TEXTURE_GREEN_SIZE:
1362 case GL_TEXTURE_BLUE_SIZE:
1363 case GL_TEXTURE_ALPHA_SIZE:
1364 if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
1365 *params = _mesa_get_format_bits(texFormat, pname);
1366 else
1367 *params = 0;
1368 break;
1369 case GL_TEXTURE_INTENSITY_SIZE:
1370 case GL_TEXTURE_LUMINANCE_SIZE:
1371 if (ctx->API != API_OPENGL_COMPAT)
1372 goto invalid_pname;
1373 if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) {
1374 *params = _mesa_get_format_bits(texFormat, pname);
1375 if (*params == 0) {
1376 /* intensity or luminance is probably stored as RGB[A] */
1377 *params = MIN2(_mesa_get_format_bits(texFormat,
1378 GL_TEXTURE_RED_SIZE),
1379 _mesa_get_format_bits(texFormat,
1380 GL_TEXTURE_GREEN_SIZE));
1381 }
1382 }
1383 else {
1384 *params = 0;
1385 }
1386 break;
1387 case GL_TEXTURE_DEPTH_SIZE_ARB:
1388 if (!ctx->Extensions.ARB_depth_texture)
1389 goto invalid_pname;
1390 *params = _mesa_get_format_bits(texFormat, pname);
1391 break;
1392 case GL_TEXTURE_STENCIL_SIZE:
1393 *params = _mesa_get_format_bits(texFormat, pname);
1394 break;
1395 case GL_TEXTURE_SHARED_SIZE:
1396 if (ctx->Version < 30 &&
1397 !ctx->Extensions.EXT_texture_shared_exponent)
1398 goto invalid_pname;
1399 *params = texFormat == MESA_FORMAT_R9G9B9E5_FLOAT ? 5 : 0;
1400 break;
1401
1402 /* GL_ARB_texture_compression */
1403 case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
1404 if (_mesa_is_format_compressed(texFormat) &&
1405 !_mesa_is_proxy_texture(target)) {
1406 *params = _mesa_format_image_size(texFormat, img->Width,
1407 img->Height, img->Depth);
1408 }
1409 else {
1410 _mesa_error(ctx, GL_INVALID_OPERATION,
1411 "glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
1412 _mesa_enum_to_string(pname));
1413 }
1414 break;
1415 case GL_TEXTURE_COMPRESSED:
1416 *params = (GLint) _mesa_is_format_compressed(texFormat);
1417 break;
1418
1419 /* GL_ARB_texture_float */
1420 case GL_TEXTURE_LUMINANCE_TYPE_ARB:
1421 case GL_TEXTURE_INTENSITY_TYPE_ARB:
1422 if (ctx->API != API_OPENGL_COMPAT)
1423 goto invalid_pname;
1424 /* FALLTHROUGH */
1425 case GL_TEXTURE_RED_TYPE_ARB:
1426 case GL_TEXTURE_GREEN_TYPE_ARB:
1427 case GL_TEXTURE_BLUE_TYPE_ARB:
1428 case GL_TEXTURE_ALPHA_TYPE_ARB:
1429 case GL_TEXTURE_DEPTH_TYPE_ARB:
1430 if (!ctx->Extensions.ARB_texture_float)
1431 goto invalid_pname;
1432 if (_mesa_base_format_has_channel(img->_BaseFormat, pname))
1433 *params = _mesa_get_format_datatype(texFormat);
1434 else
1435 *params = GL_NONE;
1436 break;
1437
1438 /* GL_ARB_texture_multisample */
1439 case GL_TEXTURE_SAMPLES:
1440 if (!ctx->Extensions.ARB_texture_multisample)
1441 goto invalid_pname;
1442 *params = img->NumSamples;
1443 break;
1444
1445 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
1446 if (!ctx->Extensions.ARB_texture_multisample)
1447 goto invalid_pname;
1448 *params = img->FixedSampleLocations;
1449 break;
1450
1451 default:
1452 goto invalid_pname;
1453 }
1454
1455 /* no error if we get here */
1456 return;
1457
1458 invalid_pname:
1459 _mesa_error(ctx, GL_INVALID_ENUM,
1460 "glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
1461 _mesa_enum_to_string(pname));
1462 }
1463
1464
1465 static void
1466 get_tex_level_parameter_buffer(struct gl_context *ctx,
1467 const struct gl_texture_object *texObj,
1468 GLenum pname, GLint *params, bool dsa)
1469 {
1470 const struct gl_buffer_object *bo = texObj->BufferObject;
1471 mesa_format texFormat = texObj->_BufferObjectFormat;
1472 GLenum internalFormat = texObj->BufferObjectFormat;
1473 GLenum baseFormat = _mesa_get_format_base_format(texFormat);
1474 const char *suffix = dsa ? "ture" : "";
1475
1476 if (!bo) {
1477 /* undefined texture buffer object */
1478 *params = pname == GL_TEXTURE_COMPONENTS ? 1 : 0;
1479 return;
1480 }
1481
1482 switch (pname) {
1483 case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
1484 *params = bo->Name;
1485 break;
1486 case GL_TEXTURE_WIDTH:
1487 *params = bo->Size;
1488 break;
1489 case GL_TEXTURE_HEIGHT:
1490 case GL_TEXTURE_DEPTH:
1491 case GL_TEXTURE_BORDER:
1492 case GL_TEXTURE_SHARED_SIZE:
1493 case GL_TEXTURE_COMPRESSED:
1494 *params = 0;
1495 break;
1496 case GL_TEXTURE_INTERNAL_FORMAT:
1497 *params = internalFormat;
1498 break;
1499 case GL_TEXTURE_RED_SIZE:
1500 case GL_TEXTURE_GREEN_SIZE:
1501 case GL_TEXTURE_BLUE_SIZE:
1502 case GL_TEXTURE_ALPHA_SIZE:
1503 if (_mesa_base_format_has_channel(baseFormat, pname))
1504 *params = _mesa_get_format_bits(texFormat, pname);
1505 else
1506 *params = 0;
1507 break;
1508 case GL_TEXTURE_INTENSITY_SIZE:
1509 case GL_TEXTURE_LUMINANCE_SIZE:
1510 if (_mesa_base_format_has_channel(baseFormat, pname)) {
1511 *params = _mesa_get_format_bits(texFormat, pname);
1512 if (*params == 0) {
1513 /* intensity or luminance is probably stored as RGB[A] */
1514 *params = MIN2(_mesa_get_format_bits(texFormat,
1515 GL_TEXTURE_RED_SIZE),
1516 _mesa_get_format_bits(texFormat,
1517 GL_TEXTURE_GREEN_SIZE));
1518 }
1519 } else {
1520 *params = 0;
1521 }
1522 break;
1523 case GL_TEXTURE_DEPTH_SIZE_ARB:
1524 case GL_TEXTURE_STENCIL_SIZE_EXT:
1525 *params = _mesa_get_format_bits(texFormat, pname);
1526 break;
1527
1528 /* GL_ARB_texture_buffer_range */
1529 case GL_TEXTURE_BUFFER_OFFSET:
1530 if (!ctx->Extensions.ARB_texture_buffer_range)
1531 goto invalid_pname;
1532 *params = texObj->BufferOffset;
1533 break;
1534 case GL_TEXTURE_BUFFER_SIZE:
1535 if (!ctx->Extensions.ARB_texture_buffer_range)
1536 goto invalid_pname;
1537 *params = (texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize;
1538 break;
1539
1540 /* GL_ARB_texture_compression */
1541 case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
1542 /* Always illegal for GL_TEXTURE_BUFFER */
1543 _mesa_error(ctx, GL_INVALID_OPERATION,
1544 "glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
1545 _mesa_enum_to_string(pname));
1546 break;
1547
1548 /* GL_ARB_texture_float */
1549 case GL_TEXTURE_RED_TYPE_ARB:
1550 case GL_TEXTURE_GREEN_TYPE_ARB:
1551 case GL_TEXTURE_BLUE_TYPE_ARB:
1552 case GL_TEXTURE_ALPHA_TYPE_ARB:
1553 case GL_TEXTURE_LUMINANCE_TYPE_ARB:
1554 case GL_TEXTURE_INTENSITY_TYPE_ARB:
1555 case GL_TEXTURE_DEPTH_TYPE_ARB:
1556 if (!ctx->Extensions.ARB_texture_float)
1557 goto invalid_pname;
1558 if (_mesa_base_format_has_channel(baseFormat, pname))
1559 *params = _mesa_get_format_datatype(texFormat);
1560 else
1561 *params = GL_NONE;
1562 break;
1563
1564 default:
1565 goto invalid_pname;
1566 }
1567
1568 /* no error if we get here */
1569 return;
1570
1571 invalid_pname:
1572 _mesa_error(ctx, GL_INVALID_ENUM,
1573 "glGetTex%sLevelParameter[if]v(pname=%s)", suffix,
1574 _mesa_enum_to_string(pname));
1575 }
1576
1577 static bool
1578 valid_tex_level_parameteriv_target(struct gl_context *ctx, GLenum target,
1579 bool dsa)
1580 {
1581 const char *suffix = dsa ? "ture" : "";
1582 if (!legal_get_tex_level_parameter_target(ctx, target, dsa)) {
1583 _mesa_error(ctx, GL_INVALID_ENUM,
1584 "glGetTex%sLevelParameter[if]v(target=%s)", suffix,
1585 _mesa_enum_to_string(target));
1586 return false;
1587 }
1588 return true;
1589 }
1590
1591 /**
1592 * This isn't exposed to the rest of the driver because it is a part of the
1593 * OpenGL API that is rarely used.
1594 */
1595 static void
1596 get_tex_level_parameteriv(struct gl_context *ctx,
1597 struct gl_texture_object *texObj,
1598 GLenum target, GLint level,
1599 GLenum pname, GLint *params,
1600 bool dsa)
1601 {
1602 GLint maxLevels;
1603 const char *suffix = dsa ? "ture" : "";
1604
1605 /* Check for errors */
1606 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) {
1607 _mesa_error(ctx, GL_INVALID_OPERATION,
1608 "glGetTex%sLevelParameter[if]v("
1609 "current unit >= max combined texture units)", suffix);
1610 return;
1611 }
1612
1613 maxLevels = _mesa_max_texture_levels(ctx, target);
1614 assert(maxLevels != 0);
1615
1616 if (level < 0 || level >= maxLevels) {
1617 _mesa_error(ctx, GL_INVALID_VALUE,
1618 "glGetTex%sLevelParameter[if]v(level out of range)", suffix);
1619 return;
1620 }
1621
1622 /* Get the level parameter */
1623 if (target == GL_TEXTURE_BUFFER) {
1624 get_tex_level_parameter_buffer(ctx, texObj, pname, params, dsa);
1625 }
1626 else {
1627 get_tex_level_parameter_image(ctx, texObj, target,
1628 level, pname, params, dsa);
1629 }
1630 }
1631
1632 void GLAPIENTRY
1633 _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
1634 GLenum pname, GLfloat *params )
1635 {
1636 struct gl_texture_object *texObj;
1637 GLint iparam;
1638 GET_CURRENT_CONTEXT(ctx);
1639
1640 if (!valid_tex_level_parameteriv_target(ctx, target, false))
1641 return;
1642
1643 texObj = _mesa_get_current_tex_object(ctx, target);
1644 if (!texObj)
1645 return;
1646
1647 get_tex_level_parameteriv(ctx, texObj, target, level,
1648 pname, &iparam, false);
1649
1650 *params = (GLfloat) iparam;
1651 }
1652
1653 void GLAPIENTRY
1654 _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
1655 GLenum pname, GLint *params )
1656 {
1657 struct gl_texture_object *texObj;
1658 GET_CURRENT_CONTEXT(ctx);
1659
1660 if (!valid_tex_level_parameteriv_target(ctx, target, false))
1661 return;
1662
1663 texObj = _mesa_get_current_tex_object(ctx, target);
1664 if (!texObj)
1665 return;
1666
1667 get_tex_level_parameteriv(ctx, texObj, target, level,
1668 pname, params, false);
1669 }
1670
1671 void GLAPIENTRY
1672 _mesa_GetTextureLevelParameterfv(GLuint texture, GLint level,
1673 GLenum pname, GLfloat *params)
1674 {
1675 struct gl_texture_object *texObj;
1676 GLint iparam;
1677 GET_CURRENT_CONTEXT(ctx);
1678
1679 texObj = _mesa_lookup_texture_err(ctx, texture,
1680 "glGetTextureLevelParameterfv");
1681 if (!texObj)
1682 return;
1683
1684 if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true))
1685 return;
1686
1687 get_tex_level_parameteriv(ctx, texObj, texObj->Target, level,
1688 pname, &iparam, true);
1689
1690 *params = (GLfloat) iparam;
1691 }
1692
1693 void GLAPIENTRY
1694 _mesa_GetTextureLevelParameteriv(GLuint texture, GLint level,
1695 GLenum pname, GLint *params)
1696 {
1697 struct gl_texture_object *texObj;
1698 GET_CURRENT_CONTEXT(ctx);
1699
1700 texObj = _mesa_lookup_texture_err(ctx, texture,
1701 "glGetTextureLevelParameteriv");
1702 if (!texObj)
1703 return;
1704
1705 if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true))
1706 return;
1707
1708 get_tex_level_parameteriv(ctx, texObj, texObj->Target, level,
1709 pname, params, true);
1710 }
1711
1712 /**
1713 * This isn't exposed to the rest of the driver because it is a part of the
1714 * OpenGL API that is rarely used.
1715 */
1716 static void
1717 get_tex_parameterfv(struct gl_context *ctx,
1718 struct gl_texture_object *obj,
1719 GLenum pname, GLfloat *params, bool dsa)
1720 {
1721 _mesa_lock_context_textures(ctx);
1722 switch (pname) {
1723 case GL_TEXTURE_MAG_FILTER:
1724 *params = ENUM_TO_FLOAT(obj->Sampler.MagFilter);
1725 break;
1726 case GL_TEXTURE_MIN_FILTER:
1727 *params = ENUM_TO_FLOAT(obj->Sampler.MinFilter);
1728 break;
1729 case GL_TEXTURE_WRAP_S:
1730 *params = ENUM_TO_FLOAT(obj->Sampler.WrapS);
1731 break;
1732 case GL_TEXTURE_WRAP_T:
1733 *params = ENUM_TO_FLOAT(obj->Sampler.WrapT);
1734 break;
1735 case GL_TEXTURE_WRAP_R:
1736 *params = ENUM_TO_FLOAT(obj->Sampler.WrapR);
1737 break;
1738 case GL_TEXTURE_BORDER_COLOR:
1739 if (!_mesa_is_desktop_gl(ctx))
1740 goto invalid_pname;
1741
1742 if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP))
1743 _mesa_update_state_locked(ctx);
1744 if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer)) {
1745 params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
1746 params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
1747 params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
1748 params[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
1749 }
1750 else {
1751 params[0] = obj->Sampler.BorderColor.f[0];
1752 params[1] = obj->Sampler.BorderColor.f[1];
1753 params[2] = obj->Sampler.BorderColor.f[2];
1754 params[3] = obj->Sampler.BorderColor.f[3];
1755 }
1756 break;
1757 case GL_TEXTURE_RESIDENT:
1758 if (ctx->API != API_OPENGL_COMPAT)
1759 goto invalid_pname;
1760
1761 *params = 1.0F;
1762 break;
1763 case GL_TEXTURE_PRIORITY:
1764 if (ctx->API != API_OPENGL_COMPAT)
1765 goto invalid_pname;
1766
1767 *params = obj->Priority;
1768 break;
1769 case GL_TEXTURE_MIN_LOD:
1770 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1771 goto invalid_pname;
1772
1773 *params = obj->Sampler.MinLod;
1774 break;
1775 case GL_TEXTURE_MAX_LOD:
1776 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1777 goto invalid_pname;
1778
1779 *params = obj->Sampler.MaxLod;
1780 break;
1781 case GL_TEXTURE_BASE_LEVEL:
1782 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1783 goto invalid_pname;
1784
1785 *params = (GLfloat) obj->BaseLevel;
1786 break;
1787 case GL_TEXTURE_MAX_LEVEL:
1788 *params = (GLfloat) obj->MaxLevel;
1789 break;
1790 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
1791 if (!ctx->Extensions.EXT_texture_filter_anisotropic)
1792 goto invalid_pname;
1793 *params = obj->Sampler.MaxAnisotropy;
1794 break;
1795 case GL_GENERATE_MIPMAP_SGIS:
1796 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
1797 goto invalid_pname;
1798
1799 *params = (GLfloat) obj->GenerateMipmap;
1800 break;
1801 case GL_TEXTURE_COMPARE_MODE_ARB:
1802 if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
1803 && !_mesa_is_gles3(ctx))
1804 goto invalid_pname;
1805 *params = (GLfloat) obj->Sampler.CompareMode;
1806 break;
1807 case GL_TEXTURE_COMPARE_FUNC_ARB:
1808 if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
1809 && !_mesa_is_gles3(ctx))
1810 goto invalid_pname;
1811 *params = (GLfloat) obj->Sampler.CompareFunc;
1812 break;
1813 case GL_DEPTH_TEXTURE_MODE_ARB:
1814 /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has
1815 * never existed in OpenGL ES.
1816 */
1817 if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture)
1818 goto invalid_pname;
1819 *params = (GLfloat) obj->DepthMode;
1820 break;
1821 case GL_DEPTH_STENCIL_TEXTURE_MODE:
1822 if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_stencil_texturing)
1823 goto invalid_pname;
1824 *params = (GLfloat)
1825 (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT);
1826 break;
1827 case GL_TEXTURE_LOD_BIAS:
1828 if (_mesa_is_gles(ctx))
1829 goto invalid_pname;
1830
1831 *params = obj->Sampler.LodBias;
1832 break;
1833 case GL_TEXTURE_CROP_RECT_OES:
1834 if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
1835 goto invalid_pname;
1836
1837 params[0] = (GLfloat) obj->CropRect[0];
1838 params[1] = (GLfloat) obj->CropRect[1];
1839 params[2] = (GLfloat) obj->CropRect[2];
1840 params[3] = (GLfloat) obj->CropRect[3];
1841 break;
1842
1843 case GL_TEXTURE_SWIZZLE_R_EXT:
1844 case GL_TEXTURE_SWIZZLE_G_EXT:
1845 case GL_TEXTURE_SWIZZLE_B_EXT:
1846 case GL_TEXTURE_SWIZZLE_A_EXT:
1847 if ((!_mesa_is_desktop_gl(ctx)
1848 || !ctx->Extensions.EXT_texture_swizzle)
1849 && !_mesa_is_gles3(ctx))
1850 goto invalid_pname;
1851 *params = (GLfloat) obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
1852 break;
1853
1854 case GL_TEXTURE_SWIZZLE_RGBA_EXT:
1855 if ((!_mesa_is_desktop_gl(ctx)
1856 || !ctx->Extensions.EXT_texture_swizzle)
1857 && !_mesa_is_gles3(ctx)) {
1858 goto invalid_pname;
1859 }
1860 else {
1861 GLuint comp;
1862 for (comp = 0; comp < 4; comp++) {
1863 params[comp] = (GLfloat) obj->Swizzle[comp];
1864 }
1865 }
1866 break;
1867
1868 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
1869 if (!_mesa_is_desktop_gl(ctx)
1870 || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
1871 goto invalid_pname;
1872 *params = (GLfloat) obj->Sampler.CubeMapSeamless;
1873 break;
1874
1875 case GL_TEXTURE_IMMUTABLE_FORMAT:
1876 *params = (GLfloat) obj->Immutable;
1877 break;
1878
1879 case GL_TEXTURE_IMMUTABLE_LEVELS:
1880 if (_mesa_is_gles3(ctx) ||
1881 (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view))
1882 *params = (GLfloat) obj->ImmutableLevels;
1883 else
1884 goto invalid_pname;
1885 break;
1886
1887 case GL_TEXTURE_VIEW_MIN_LEVEL:
1888 if (!ctx->Extensions.ARB_texture_view)
1889 goto invalid_pname;
1890 *params = (GLfloat) obj->MinLevel;
1891 break;
1892
1893 case GL_TEXTURE_VIEW_NUM_LEVELS:
1894 if (!ctx->Extensions.ARB_texture_view)
1895 goto invalid_pname;
1896 *params = (GLfloat) obj->NumLevels;
1897 break;
1898
1899 case GL_TEXTURE_VIEW_MIN_LAYER:
1900 if (!ctx->Extensions.ARB_texture_view)
1901 goto invalid_pname;
1902 *params = (GLfloat) obj->MinLayer;
1903 break;
1904
1905 case GL_TEXTURE_VIEW_NUM_LAYERS:
1906 if (!ctx->Extensions.ARB_texture_view)
1907 goto invalid_pname;
1908 *params = (GLfloat) obj->NumLayers;
1909 break;
1910
1911 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
1912 if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
1913 goto invalid_pname;
1914 *params = (GLfloat) obj->RequiredTextureImageUnits;
1915 break;
1916
1917 case GL_TEXTURE_SRGB_DECODE_EXT:
1918 if (!ctx->Extensions.EXT_texture_sRGB_decode)
1919 goto invalid_pname;
1920 *params = (GLfloat) obj->Sampler.sRGBDecode;
1921 break;
1922
1923 case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
1924 if (!ctx->Extensions.ARB_shader_image_load_store)
1925 goto invalid_pname;
1926 *params = (GLfloat) obj->ImageFormatCompatibilityType;
1927 break;
1928
1929 default:
1930 goto invalid_pname;
1931 }
1932
1933 /* no error if we get here */
1934 _mesa_unlock_context_textures(ctx);
1935 return;
1936
1937 invalid_pname:
1938 _mesa_unlock_context_textures(ctx);
1939 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTex%sParameterfv(pname=0x%x)",
1940 dsa ? "ture" : "", pname);
1941 }
1942
1943
1944 static void
1945 get_tex_parameteriv(struct gl_context *ctx,
1946 struct gl_texture_object *obj,
1947 GLenum pname, GLint *params, bool dsa)
1948 {
1949 _mesa_lock_texture(ctx, obj);
1950 switch (pname) {
1951 case GL_TEXTURE_MAG_FILTER:
1952 *params = (GLint) obj->Sampler.MagFilter;
1953 break;
1954 case GL_TEXTURE_MIN_FILTER:
1955 *params = (GLint) obj->Sampler.MinFilter;
1956 break;
1957 case GL_TEXTURE_WRAP_S:
1958 *params = (GLint) obj->Sampler.WrapS;
1959 break;
1960 case GL_TEXTURE_WRAP_T:
1961 *params = (GLint) obj->Sampler.WrapT;
1962 break;
1963 case GL_TEXTURE_WRAP_R:
1964 *params = (GLint) obj->Sampler.WrapR;
1965 break;
1966 case GL_TEXTURE_BORDER_COLOR:
1967 if (!_mesa_is_desktop_gl(ctx))
1968 goto invalid_pname;
1969
1970 {
1971 GLfloat b[4];
1972 b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F);
1973 b[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F);
1974 b[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F);
1975 b[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F);
1976 params[0] = FLOAT_TO_INT(b[0]);
1977 params[1] = FLOAT_TO_INT(b[1]);
1978 params[2] = FLOAT_TO_INT(b[2]);
1979 params[3] = FLOAT_TO_INT(b[3]);
1980 }
1981 break;
1982 case GL_TEXTURE_RESIDENT:
1983 if (ctx->API != API_OPENGL_COMPAT)
1984 goto invalid_pname;
1985
1986 *params = 1;
1987 break;
1988 case GL_TEXTURE_PRIORITY:
1989 if (ctx->API != API_OPENGL_COMPAT)
1990 goto invalid_pname;
1991
1992 *params = FLOAT_TO_INT(obj->Priority);
1993 break;
1994 case GL_TEXTURE_MIN_LOD:
1995 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
1996 goto invalid_pname;
1997 /* GL spec 'Data Conversions' section specifies that floating-point
1998 * value in integer Get function is rounded to nearest integer
1999 */
2000 *params = IROUND(obj->Sampler.MinLod);
2001 break;
2002 case GL_TEXTURE_MAX_LOD:
2003 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
2004 goto invalid_pname;
2005 /* GL spec 'Data Conversions' section specifies that floating-point
2006 * value in integer Get function is rounded to nearest integer
2007 */
2008 *params = IROUND(obj->Sampler.MaxLod);
2009 break;
2010 case GL_TEXTURE_BASE_LEVEL:
2011 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx))
2012 goto invalid_pname;
2013
2014 *params = obj->BaseLevel;
2015 break;
2016 case GL_TEXTURE_MAX_LEVEL:
2017 *params = obj->MaxLevel;
2018 break;
2019 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
2020 if (!ctx->Extensions.EXT_texture_filter_anisotropic)
2021 goto invalid_pname;
2022 /* GL spec 'Data Conversions' section specifies that floating-point
2023 * value in integer Get function is rounded to nearest integer
2024 */
2025 *params = IROUND(obj->Sampler.MaxAnisotropy);
2026 break;
2027 case GL_GENERATE_MIPMAP_SGIS:
2028 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES)
2029 goto invalid_pname;
2030
2031 *params = (GLint) obj->GenerateMipmap;
2032 break;
2033 case GL_TEXTURE_COMPARE_MODE_ARB:
2034 if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
2035 && !_mesa_is_gles3(ctx))
2036 goto invalid_pname;
2037 *params = (GLint) obj->Sampler.CompareMode;
2038 break;
2039 case GL_TEXTURE_COMPARE_FUNC_ARB:
2040 if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow)
2041 && !_mesa_is_gles3(ctx))
2042 goto invalid_pname;
2043 *params = (GLint) obj->Sampler.CompareFunc;
2044 break;
2045 case GL_DEPTH_TEXTURE_MODE_ARB:
2046 if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture)
2047 goto invalid_pname;
2048 *params = (GLint) obj->DepthMode;
2049 break;
2050 case GL_DEPTH_STENCIL_TEXTURE_MODE:
2051 if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_stencil_texturing)
2052 goto invalid_pname;
2053 *params = (GLint)
2054 (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT);
2055 break;
2056 case GL_TEXTURE_LOD_BIAS:
2057 if (_mesa_is_gles(ctx))
2058 goto invalid_pname;
2059
2060 /* GL spec 'Data Conversions' section specifies that floating-point
2061 * value in integer Get function is rounded to nearest integer
2062 */
2063 *params = IROUND(obj->Sampler.LodBias);
2064 break;
2065 case GL_TEXTURE_CROP_RECT_OES:
2066 if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture)
2067 goto invalid_pname;
2068
2069 params[0] = obj->CropRect[0];
2070 params[1] = obj->CropRect[1];
2071 params[2] = obj->CropRect[2];
2072 params[3] = obj->CropRect[3];
2073 break;
2074 case GL_TEXTURE_SWIZZLE_R_EXT:
2075 case GL_TEXTURE_SWIZZLE_G_EXT:
2076 case GL_TEXTURE_SWIZZLE_B_EXT:
2077 case GL_TEXTURE_SWIZZLE_A_EXT:
2078 if ((!_mesa_is_desktop_gl(ctx)
2079 || !ctx->Extensions.EXT_texture_swizzle)
2080 && !_mesa_is_gles3(ctx))
2081 goto invalid_pname;
2082 *params = obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT];
2083 break;
2084
2085 case GL_TEXTURE_SWIZZLE_RGBA_EXT:
2086 if ((!_mesa_is_desktop_gl(ctx)
2087 || !ctx->Extensions.EXT_texture_swizzle)
2088 && !_mesa_is_gles3(ctx))
2089 goto invalid_pname;
2090 COPY_4V(params, obj->Swizzle);
2091 break;
2092
2093 case GL_TEXTURE_CUBE_MAP_SEAMLESS:
2094 if (!_mesa_is_desktop_gl(ctx)
2095 || !ctx->Extensions.AMD_seamless_cubemap_per_texture)
2096 goto invalid_pname;
2097 *params = (GLint) obj->Sampler.CubeMapSeamless;
2098 break;
2099
2100 case GL_TEXTURE_IMMUTABLE_FORMAT:
2101 *params = (GLint) obj->Immutable;
2102 break;
2103
2104 case GL_TEXTURE_IMMUTABLE_LEVELS:
2105 if (_mesa_is_gles3(ctx) ||
2106 (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view))
2107 *params = obj->ImmutableLevels;
2108 else
2109 goto invalid_pname;
2110 break;
2111
2112 case GL_TEXTURE_VIEW_MIN_LEVEL:
2113 if (!ctx->Extensions.ARB_texture_view)
2114 goto invalid_pname;
2115 *params = (GLint) obj->MinLevel;
2116 break;
2117
2118 case GL_TEXTURE_VIEW_NUM_LEVELS:
2119 if (!ctx->Extensions.ARB_texture_view)
2120 goto invalid_pname;
2121 *params = (GLint) obj->NumLevels;
2122 break;
2123
2124 case GL_TEXTURE_VIEW_MIN_LAYER:
2125 if (!ctx->Extensions.ARB_texture_view)
2126 goto invalid_pname;
2127 *params = (GLint) obj->MinLayer;
2128 break;
2129
2130 case GL_TEXTURE_VIEW_NUM_LAYERS:
2131 if (!ctx->Extensions.ARB_texture_view)
2132 goto invalid_pname;
2133 *params = (GLint) obj->NumLayers;
2134 break;
2135
2136 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
2137 if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external)
2138 goto invalid_pname;
2139 *params = obj->RequiredTextureImageUnits;
2140 break;
2141
2142 case GL_TEXTURE_SRGB_DECODE_EXT:
2143 if (!ctx->Extensions.EXT_texture_sRGB_decode)
2144 goto invalid_pname;
2145 *params = obj->Sampler.sRGBDecode;
2146 break;
2147
2148 case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
2149 if (!ctx->Extensions.ARB_shader_image_load_store)
2150 goto invalid_pname;
2151 *params = obj->ImageFormatCompatibilityType;
2152 break;
2153
2154 default:
2155 goto invalid_pname;
2156 }
2157
2158 /* no error if we get here */
2159 _mesa_unlock_texture(ctx, obj);
2160 return;
2161
2162 invalid_pname:
2163 _mesa_unlock_texture(ctx, obj);
2164 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTex%sParameteriv(pname=0x%x)",
2165 dsa ? "ture" : "", pname);
2166 }
2167
2168 static void
2169 get_tex_parameterIiv(struct gl_context *ctx,
2170 struct gl_texture_object *obj,
2171 GLenum pname, GLint *params, bool dsa)
2172 {
2173 switch (pname) {
2174 case GL_TEXTURE_BORDER_COLOR:
2175 COPY_4V(params, obj->Sampler.BorderColor.i);
2176 break;
2177 default:
2178 get_tex_parameteriv(ctx, obj, pname, params, dsa);
2179 }
2180 }
2181
2182 static void
2183 get_tex_parameterIuiv(struct gl_context *ctx,
2184 struct gl_texture_object *obj,
2185 GLenum pname, GLuint *params, bool dsa)
2186 {
2187 switch (pname) {
2188 case GL_TEXTURE_BORDER_COLOR:
2189 COPY_4V(params, obj->Sampler.BorderColor.i);
2190 break;
2191 default:
2192 {
2193 GLint ip[4];
2194 get_tex_parameteriv(ctx, obj, pname, ip, dsa);
2195 params[0] = ip[0];
2196 if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT ||
2197 pname == GL_TEXTURE_CROP_RECT_OES) {
2198 params[1] = ip[1];
2199 params[2] = ip[2];
2200 params[3] = ip[3];
2201 }
2202 }
2203 }
2204 }
2205
2206 void GLAPIENTRY
2207 _mesa_GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
2208 {
2209 struct gl_texture_object *obj;
2210 GET_CURRENT_CONTEXT(ctx);
2211
2212 obj = get_texobj_by_target(ctx, target, GL_TRUE);
2213 if (!obj)
2214 return;
2215
2216 get_tex_parameterfv(ctx, obj, pname, params, false);
2217 }
2218
2219 void GLAPIENTRY
2220 _mesa_GetTexParameteriv(GLenum target, GLenum pname, GLint *params)
2221 {
2222 struct gl_texture_object *obj;
2223 GET_CURRENT_CONTEXT(ctx);
2224
2225 obj = get_texobj_by_target(ctx, target, GL_TRUE);
2226 if (!obj)
2227 return;
2228
2229 get_tex_parameteriv(ctx, obj, pname, params, false);
2230 }
2231
2232 /** New in GL 3.0 */
2233 void GLAPIENTRY
2234 _mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params)
2235 {
2236 struct gl_texture_object *texObj;
2237 GET_CURRENT_CONTEXT(ctx);
2238
2239 texObj = get_texobj_by_target(ctx, target, GL_TRUE);
2240 if (!texObj)
2241 return;
2242
2243 get_tex_parameterIiv(ctx, texObj, pname, params, false);
2244 }
2245
2246
2247 /** New in GL 3.0 */
2248 void GLAPIENTRY
2249 _mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params)
2250 {
2251 struct gl_texture_object *texObj;
2252 GET_CURRENT_CONTEXT(ctx);
2253
2254 texObj = get_texobj_by_target(ctx, target, GL_TRUE);
2255 if (!texObj)
2256 return;
2257
2258 get_tex_parameterIuiv(ctx, texObj, pname, params, false);
2259 }
2260
2261
2262 void GLAPIENTRY
2263 _mesa_GetTextureParameterfv(GLuint texture, GLenum pname, GLfloat *params)
2264 {
2265 struct gl_texture_object *obj;
2266 GET_CURRENT_CONTEXT(ctx);
2267
2268 obj = get_texobj_by_name(ctx, texture, GL_TRUE);
2269 if (!obj) {
2270 /* User passed a non-generated name. */
2271 _mesa_error(ctx, GL_INVALID_OPERATION,
2272 "glGetTextureParameterfv(texture)");
2273 return;
2274 }
2275
2276 get_tex_parameterfv(ctx, obj, pname, params, true);
2277 }
2278
2279 void GLAPIENTRY
2280 _mesa_GetTextureParameteriv(GLuint texture, GLenum pname, GLint *params)
2281 {
2282 struct gl_texture_object *obj;
2283 GET_CURRENT_CONTEXT(ctx);
2284
2285 obj = get_texobj_by_name(ctx, texture, GL_TRUE);
2286 if (!obj) {
2287 /* User passed a non-generated name. */
2288 _mesa_error(ctx, GL_INVALID_OPERATION,
2289 "glGetTextureParameteriv(texture)");
2290 return;
2291 }
2292
2293 get_tex_parameteriv(ctx, obj, pname, params, true);
2294 }
2295
2296 void GLAPIENTRY
2297 _mesa_GetTextureParameterIiv(GLuint texture, GLenum pname, GLint *params)
2298 {
2299 struct gl_texture_object *texObj;
2300 GET_CURRENT_CONTEXT(ctx);
2301
2302 texObj = get_texobj_by_name(ctx, texture, GL_TRUE);
2303 if (!texObj) {
2304 /* User passed a non-generated name. */
2305 _mesa_error(ctx, GL_INVALID_OPERATION,
2306 "glGetTextureParameterIiv(texture)");
2307 return;
2308 }
2309
2310 get_tex_parameterIiv(ctx, texObj, pname, params, true);
2311 }
2312
2313
2314 void GLAPIENTRY
2315 _mesa_GetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint *params)
2316 {
2317 struct gl_texture_object *texObj;
2318 GET_CURRENT_CONTEXT(ctx);
2319
2320 texObj = get_texobj_by_name(ctx, texture, GL_TRUE);
2321 if (!texObj) {
2322 /* User passed a non-generated name. */
2323 _mesa_error(ctx, GL_INVALID_OPERATION,
2324 "glGetTextureParameterIuiv(texture)");
2325 return;
2326 }
2327
2328 get_tex_parameterIuiv(ctx, texObj, pname, params, true);
2329 }