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