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