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