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