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