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 */ 59static GLboolean 60validate_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 123static bool 124is_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 */ 150static struct gl_texture_object * 151get_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 */ 172static GLint 173comp_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 194static void 195set_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 */ 211static inline void 212flush(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 */ 225static inline void 226incomplete(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 233GLboolean 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 247static inline GLboolean 248is_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 */ 257static GLboolean 258set_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 670invalid_pname: 671 _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)", 672 suffix, _mesa_enum_to_string(pname)); 673 return GL_FALSE; 674 675invalid_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 680invalid_dsa: 681 if (!dsa) 682 goto invalid_enum; 683 684invalid_operation: 685 _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sParameter(pname=%s)", 686 suffix, _mesa_enum_to_string(pname)); 687 return GL_FALSE; 688 689invalid_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 */ 700static GLboolean 701set_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 842invalid_pname: 843 _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)", 844 suffix, _mesa_enum_to_string(pname)); 845 return GL_FALSE; 846 847invalid_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; 853invalid_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 860void 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 918void 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 986void 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 1030void 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 1072void 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 1101void 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 1131void GLAPIENTRY 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 1147void GLAPIENTRY 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 1163void GLAPIENTRY 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 1179void GLAPIENTRY 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 */ 1200void GLAPIENTRY 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 */ 1221void GLAPIENTRY 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 1237void GLAPIENTRY 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 1256void GLAPIENTRY 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 1269void GLAPIENTRY 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 1290void GLAPIENTRY 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 1309void GLAPIENTRY 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 1331void GLAPIENTRY 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 1344void GLAPIENTRY 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 1363void GLAPIENTRY 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 1385void GLAPIENTRY 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 1398void GLAPIENTRY 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 1418void GLAPIENTRY 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 1440void GLAPIENTRY 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 1455void GLAPIENTRY 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 1468void GLAPIENTRY 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 1483void GLAPIENTRY 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 1500void GLAPIENTRY 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 1513void GLAPIENTRY 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 1528void GLAPIENTRY 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 1545GLboolean 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 1630static void 1631get_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 1826invalid_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 */ 1836static void 1837get_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 1971invalid_pname: 1972 _mesa_error(ctx, GL_INVALID_ENUM, 1973 "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, 1974 _mesa_enum_to_string(pname)); 1975} 1976 1977static bool 1978valid_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 */ 1995static void 1996get_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 2032void GLAPIENTRY 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 2053void GLAPIENTRY 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 2071void GLAPIENTRY 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 2093void GLAPIENTRY 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 2115void GLAPIENTRY 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 2139void GLAPIENTRY 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 2158void GLAPIENTRY 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 2177void GLAPIENTRY 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 */ 2203static void 2204get_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 2441invalid_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 2448static void 2449get_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 2714invalid_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 2720static void 2721get_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 2734void GLAPIENTRY 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 2750void GLAPIENTRY 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 */ 2767void GLAPIENTRY 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 */ 2785void GLAPIENTRY 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 2801void GLAPIENTRY 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 2820void GLAPIENTRY 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 2840void GLAPIENTRY 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 2853void GLAPIENTRY 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 2871void GLAPIENTRY 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 2891void GLAPIENTRY 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 2904void GLAPIENTRY 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 2917void GLAPIENTRY 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 2932void GLAPIENTRY 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 2949void GLAPIENTRY 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 2962void GLAPIENTRY 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 2977void GLAPIENTRY 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