texparam.c revision 848b8605
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/colormac.h" 36#include "main/context.h" 37#include "main/enums.h" 38#include "main/formats.h" 39#include "main/glformats.h" 40#include "main/macros.h" 41#include "main/mtypes.h" 42#include "main/state.h" 43#include "main/texcompress.h" 44#include "main/texobj.h" 45#include "main/texparam.h" 46#include "main/teximage.h" 47#include "main/texstate.h" 48#include "program/prog_instruction.h" 49 50 51/** 52 * Check if a coordinate wrap mode is supported for the texture target. 53 * \return GL_TRUE if legal, GL_FALSE otherwise 54 */ 55static GLboolean 56validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap) 57{ 58 const struct gl_extensions * const e = & ctx->Extensions; 59 const bool is_desktop_gl = _mesa_is_desktop_gl(ctx); 60 bool supported; 61 62 switch (wrap) { 63 case GL_CLAMP: 64 /* GL_CLAMP was removed in the core profile, and it has never existed in 65 * OpenGL ES. 66 */ 67 supported = (ctx->API == API_OPENGL_COMPAT) 68 && (target != GL_TEXTURE_EXTERNAL_OES); 69 break; 70 71 case GL_CLAMP_TO_EDGE: 72 supported = true; 73 break; 74 75 case GL_CLAMP_TO_BORDER: 76 supported = is_desktop_gl && e->ARB_texture_border_clamp 77 && (target != GL_TEXTURE_EXTERNAL_OES); 78 break; 79 80 case GL_REPEAT: 81 case GL_MIRRORED_REPEAT: 82 supported = (target != GL_TEXTURE_RECTANGLE_NV) 83 && (target != GL_TEXTURE_EXTERNAL_OES); 84 break; 85 86 case GL_MIRROR_CLAMP_EXT: 87 supported = is_desktop_gl 88 && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp) 89 && (target != GL_TEXTURE_RECTANGLE_NV) 90 && (target != GL_TEXTURE_EXTERNAL_OES); 91 break; 92 93 case GL_MIRROR_CLAMP_TO_EDGE_EXT: 94 supported = is_desktop_gl 95 && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp || e->ARB_texture_mirror_clamp_to_edge) 96 && (target != GL_TEXTURE_RECTANGLE_NV) 97 && (target != GL_TEXTURE_EXTERNAL_OES); 98 break; 99 100 case GL_MIRROR_CLAMP_TO_BORDER_EXT: 101 supported = is_desktop_gl && e->EXT_texture_mirror_clamp 102 && (target != GL_TEXTURE_RECTANGLE_NV) 103 && (target != GL_TEXTURE_EXTERNAL_OES); 104 break; 105 106 default: 107 supported = false; 108 break; 109 } 110 111 if (!supported) 112 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap ); 113 114 return supported; 115} 116 117 118/** 119 * Get current texture object for given target. 120 * Return NULL if any error (and record the error). 121 * Note that this is different from _mesa_get_current_tex_object() in that 122 * proxy targets are not accepted. 123 * Only the glGetTexLevelParameter() functions accept proxy targets. 124 */ 125static struct gl_texture_object * 126get_texobj(struct gl_context *ctx, GLenum target, GLboolean get) 127{ 128 struct gl_texture_unit *texUnit; 129 int targetIndex; 130 131 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) { 132 _mesa_error(ctx, GL_INVALID_OPERATION, 133 "gl%sTexParameter(current unit)", get ? "Get" : ""); 134 return NULL; 135 } 136 137 texUnit = _mesa_get_current_tex_unit(ctx); 138 139 targetIndex = _mesa_tex_target_to_index(ctx, target); 140 if (targetIndex < 0 || targetIndex == TEXTURE_BUFFER_INDEX) { 141 _mesa_error(ctx, GL_INVALID_ENUM, 142 "gl%sTexParameter(target)", get ? "Get" : ""); 143 return NULL; 144 } 145 assert(targetIndex < NUM_TEXTURE_TARGETS); 146 147 return texUnit->CurrentTex[targetIndex]; 148} 149 150 151/** 152 * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE. 153 * \return -1 if error. 154 */ 155static GLint 156comp_to_swizzle(GLenum comp) 157{ 158 switch (comp) { 159 case GL_RED: 160 return SWIZZLE_X; 161 case GL_GREEN: 162 return SWIZZLE_Y; 163 case GL_BLUE: 164 return SWIZZLE_Z; 165 case GL_ALPHA: 166 return SWIZZLE_W; 167 case GL_ZERO: 168 return SWIZZLE_ZERO; 169 case GL_ONE: 170 return SWIZZLE_ONE; 171 default: 172 return -1; 173 } 174} 175 176 177static void 178set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz) 179{ 180 ASSERT(comp < 4); 181 ASSERT(swz <= SWIZZLE_NIL); 182 { 183 GLuint mask = 0x7 << (3 * comp); 184 GLuint s = (*swizzle & ~mask) | (swz << (3 * comp)); 185 *swizzle = s; 186 } 187} 188 189 190/** 191 * This is called just prior to changing any texture object state which 192 * will not effect texture completeness. 193 */ 194static inline void 195flush(struct gl_context *ctx) 196{ 197 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 198} 199 200 201/** 202 * This is called just prior to changing any texture object state which 203 * can effect texture completeness (texture base level, max level). 204 * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE 205 * state flag and then mark the texture object as 'incomplete' so that any 206 * per-texture derived state gets recomputed. 207 */ 208static inline void 209incomplete(struct gl_context *ctx, struct gl_texture_object *texObj) 210{ 211 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 212 _mesa_dirty_texobj(ctx, texObj); 213} 214 215 216static GLboolean 217target_allows_setting_sampler_parameters(GLenum target) 218{ 219 switch (target) { 220 case GL_TEXTURE_2D_MULTISAMPLE: 221 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 222 return GL_FALSE; 223 224 default: 225 return GL_TRUE; 226 } 227} 228 229 230/** 231 * Set an integer-valued texture parameter 232 * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise 233 */ 234static GLboolean 235set_tex_parameteri(struct gl_context *ctx, 236 struct gl_texture_object *texObj, 237 GLenum pname, const GLint *params) 238{ 239 switch (pname) { 240 case GL_TEXTURE_MIN_FILTER: 241 if (!target_allows_setting_sampler_parameters(texObj->Target)) 242 goto invalid_operation; 243 244 if (texObj->Sampler.MinFilter == params[0]) 245 return GL_FALSE; 246 switch (params[0]) { 247 case GL_NEAREST: 248 case GL_LINEAR: 249 flush(ctx); 250 texObj->Sampler.MinFilter = params[0]; 251 return GL_TRUE; 252 case GL_NEAREST_MIPMAP_NEAREST: 253 case GL_LINEAR_MIPMAP_NEAREST: 254 case GL_NEAREST_MIPMAP_LINEAR: 255 case GL_LINEAR_MIPMAP_LINEAR: 256 if (texObj->Target != GL_TEXTURE_RECTANGLE_NV && 257 texObj->Target != GL_TEXTURE_EXTERNAL_OES) { 258 flush(ctx); 259 texObj->Sampler.MinFilter = params[0]; 260 return GL_TRUE; 261 } 262 /* fall-through */ 263 default: 264 goto invalid_param; 265 } 266 return GL_FALSE; 267 268 case GL_TEXTURE_MAG_FILTER: 269 if (!target_allows_setting_sampler_parameters(texObj->Target)) 270 goto invalid_operation; 271 272 if (texObj->Sampler.MagFilter == params[0]) 273 return GL_FALSE; 274 switch (params[0]) { 275 case GL_NEAREST: 276 case GL_LINEAR: 277 flush(ctx); /* does not effect completeness */ 278 texObj->Sampler.MagFilter = params[0]; 279 return GL_TRUE; 280 default: 281 goto invalid_param; 282 } 283 return GL_FALSE; 284 285 case GL_TEXTURE_WRAP_S: 286 if (!target_allows_setting_sampler_parameters(texObj->Target)) 287 goto invalid_operation; 288 289 if (texObj->Sampler.WrapS == params[0]) 290 return GL_FALSE; 291 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { 292 flush(ctx); 293 texObj->Sampler.WrapS = params[0]; 294 return GL_TRUE; 295 } 296 return GL_FALSE; 297 298 case GL_TEXTURE_WRAP_T: 299 if (!target_allows_setting_sampler_parameters(texObj->Target)) 300 goto invalid_operation; 301 302 if (texObj->Sampler.WrapT == params[0]) 303 return GL_FALSE; 304 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { 305 flush(ctx); 306 texObj->Sampler.WrapT = params[0]; 307 return GL_TRUE; 308 } 309 return GL_FALSE; 310 311 case GL_TEXTURE_WRAP_R: 312 if (!target_allows_setting_sampler_parameters(texObj->Target)) 313 goto invalid_operation; 314 315 if (texObj->Sampler.WrapR == params[0]) 316 return GL_FALSE; 317 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { 318 flush(ctx); 319 texObj->Sampler.WrapR = params[0]; 320 return GL_TRUE; 321 } 322 return GL_FALSE; 323 324 case GL_TEXTURE_BASE_LEVEL: 325 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 326 goto invalid_pname; 327 328 if (texObj->BaseLevel == params[0]) 329 return GL_FALSE; 330 331 if ((texObj->Target == GL_TEXTURE_2D_MULTISAMPLE || 332 texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) && params[0] != 0) 333 goto invalid_operation; 334 335 if (params[0] < 0 || 336 (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) { 337 _mesa_error(ctx, GL_INVALID_VALUE, 338 "glTexParameter(param=%d)", params[0]); 339 return GL_FALSE; 340 } 341 incomplete(ctx, texObj); 342 343 /** See note about ARB_texture_storage below */ 344 if (texObj->Immutable) 345 texObj->BaseLevel = MIN2(texObj->ImmutableLevels - 1, params[0]); 346 else 347 texObj->BaseLevel = params[0]; 348 349 return GL_TRUE; 350 351 case GL_TEXTURE_MAX_LEVEL: 352 if (texObj->MaxLevel == params[0]) 353 return GL_FALSE; 354 355 if (params[0] < 0 || 356 (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] > 0)) { 357 _mesa_error(ctx, GL_INVALID_VALUE, 358 "glTexParameter(param=%d)", params[0]); 359 return GL_FALSE; 360 } 361 incomplete(ctx, texObj); 362 363 /** From ARB_texture_storage: 364 * However, if TEXTURE_IMMUTABLE_FORMAT is TRUE, then level_base is 365 * clamped to the range [0, <levels> - 1] and level_max is then clamped to 366 * the range [level_base, <levels> - 1], where <levels> is the parameter 367 * passed the call to TexStorage* for the texture object. 368 */ 369 if (texObj->Immutable) 370 texObj->MaxLevel = CLAMP(params[0], texObj->BaseLevel, 371 texObj->ImmutableLevels - 1); 372 else 373 texObj->MaxLevel = params[0]; 374 375 return GL_TRUE; 376 377 case GL_GENERATE_MIPMAP_SGIS: 378 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) 379 goto invalid_pname; 380 381 if (params[0] && texObj->Target == GL_TEXTURE_EXTERNAL_OES) 382 goto invalid_param; 383 if (texObj->GenerateMipmap != params[0]) { 384 /* no flush() */ 385 texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE; 386 return GL_TRUE; 387 } 388 return GL_FALSE; 389 390 case GL_TEXTURE_COMPARE_MODE_ARB: 391 if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow) 392 || _mesa_is_gles3(ctx)) { 393 394 if (!target_allows_setting_sampler_parameters(texObj->Target)) 395 goto invalid_operation; 396 397 if (texObj->Sampler.CompareMode == params[0]) 398 return GL_FALSE; 399 if (params[0] == GL_NONE || 400 params[0] == GL_COMPARE_R_TO_TEXTURE_ARB) { 401 flush(ctx); 402 texObj->Sampler.CompareMode = params[0]; 403 return GL_TRUE; 404 } 405 goto invalid_param; 406 } 407 goto invalid_pname; 408 409 case GL_TEXTURE_COMPARE_FUNC_ARB: 410 if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow) 411 || _mesa_is_gles3(ctx)) { 412 413 if (!target_allows_setting_sampler_parameters(texObj->Target)) 414 goto invalid_operation; 415 416 if (texObj->Sampler.CompareFunc == params[0]) 417 return GL_FALSE; 418 switch (params[0]) { 419 case GL_LEQUAL: 420 case GL_GEQUAL: 421 case GL_EQUAL: 422 case GL_NOTEQUAL: 423 case GL_LESS: 424 case GL_GREATER: 425 case GL_ALWAYS: 426 case GL_NEVER: 427 flush(ctx); 428 texObj->Sampler.CompareFunc = params[0]; 429 return GL_TRUE; 430 default: 431 goto invalid_param; 432 } 433 } 434 goto invalid_pname; 435 436 case GL_DEPTH_TEXTURE_MODE_ARB: 437 /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has never 438 * existed in OpenGL ES. 439 */ 440 if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_depth_texture) { 441 if (texObj->DepthMode == params[0]) 442 return GL_FALSE; 443 if (params[0] == GL_LUMINANCE || 444 params[0] == GL_INTENSITY || 445 params[0] == GL_ALPHA || 446 (ctx->Extensions.ARB_texture_rg && params[0] == GL_RED)) { 447 flush(ctx); 448 texObj->DepthMode = params[0]; 449 return GL_TRUE; 450 } 451 goto invalid_param; 452 } 453 goto invalid_pname; 454 455 case GL_DEPTH_STENCIL_TEXTURE_MODE: 456 if (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_stencil_texturing) { 457 bool stencil = params[0] == GL_STENCIL_INDEX; 458 if (!stencil && params[0] != GL_DEPTH_COMPONENT) 459 goto invalid_param; 460 461 if (texObj->StencilSampling == stencil) 462 return GL_FALSE; 463 464 texObj->StencilSampling = stencil; 465 return GL_TRUE; 466 } 467 goto invalid_pname; 468 469 case GL_TEXTURE_CROP_RECT_OES: 470 if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture) 471 goto invalid_pname; 472 473 texObj->CropRect[0] = params[0]; 474 texObj->CropRect[1] = params[1]; 475 texObj->CropRect[2] = params[2]; 476 texObj->CropRect[3] = params[3]; 477 return GL_TRUE; 478 479 case GL_TEXTURE_SWIZZLE_R_EXT: 480 case GL_TEXTURE_SWIZZLE_G_EXT: 481 case GL_TEXTURE_SWIZZLE_B_EXT: 482 case GL_TEXTURE_SWIZZLE_A_EXT: 483 if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle) 484 || _mesa_is_gles3(ctx)) { 485 const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT; 486 const GLint swz = comp_to_swizzle(params[0]); 487 if (swz < 0) { 488 _mesa_error(ctx, GL_INVALID_ENUM, 489 "glTexParameter(swizzle 0x%x)", params[0]); 490 return GL_FALSE; 491 } 492 ASSERT(comp < 4); 493 494 flush(ctx); 495 texObj->Swizzle[comp] = params[0]; 496 set_swizzle_component(&texObj->_Swizzle, comp, swz); 497 return GL_TRUE; 498 } 499 goto invalid_pname; 500 501 case GL_TEXTURE_SWIZZLE_RGBA_EXT: 502 if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle) 503 || _mesa_is_gles3(ctx)) { 504 GLuint comp; 505 flush(ctx); 506 for (comp = 0; comp < 4; comp++) { 507 const GLint swz = comp_to_swizzle(params[comp]); 508 if (swz >= 0) { 509 texObj->Swizzle[comp] = params[comp]; 510 set_swizzle_component(&texObj->_Swizzle, comp, swz); 511 } 512 else { 513 _mesa_error(ctx, GL_INVALID_ENUM, 514 "glTexParameter(swizzle 0x%x)", params[comp]); 515 return GL_FALSE; 516 } 517 } 518 return GL_TRUE; 519 } 520 goto invalid_pname; 521 522 case GL_TEXTURE_SRGB_DECODE_EXT: 523 if (_mesa_is_desktop_gl(ctx) 524 && ctx->Extensions.EXT_texture_sRGB_decode) { 525 GLenum decode = params[0]; 526 527 if (!target_allows_setting_sampler_parameters(texObj->Target)) 528 goto invalid_operation; 529 530 if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) { 531 if (texObj->Sampler.sRGBDecode != decode) { 532 flush(ctx); 533 texObj->Sampler.sRGBDecode = decode; 534 } 535 return GL_TRUE; 536 } 537 } 538 goto invalid_pname; 539 540 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 541 if (_mesa_is_desktop_gl(ctx) 542 && ctx->Extensions.AMD_seamless_cubemap_per_texture) { 543 GLenum param = params[0]; 544 545 if (!target_allows_setting_sampler_parameters(texObj->Target)) 546 goto invalid_operation; 547 548 if (param != GL_TRUE && param != GL_FALSE) { 549 goto invalid_param; 550 } 551 if (param != texObj->Sampler.CubeMapSeamless) { 552 flush(ctx); 553 texObj->Sampler.CubeMapSeamless = param; 554 } 555 return GL_TRUE; 556 } 557 goto invalid_pname; 558 559 default: 560 goto invalid_pname; 561 } 562 563invalid_pname: 564 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)", 565 _mesa_lookup_enum_by_nr(pname)); 566 return GL_FALSE; 567 568invalid_param: 569 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param=%s)", 570 _mesa_lookup_enum_by_nr(params[0])); 571 return GL_FALSE; 572 573invalid_operation: 574 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)", 575 _mesa_lookup_enum_by_nr(pname)); 576 return GL_FALSE; 577} 578 579 580/** 581 * Set a float-valued texture parameter 582 * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise 583 */ 584static GLboolean 585set_tex_parameterf(struct gl_context *ctx, 586 struct gl_texture_object *texObj, 587 GLenum pname, const GLfloat *params) 588{ 589 switch (pname) { 590 case GL_TEXTURE_MIN_LOD: 591 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 592 goto invalid_pname; 593 594 if (!target_allows_setting_sampler_parameters(texObj->Target)) 595 goto invalid_operation; 596 597 if (texObj->Sampler.MinLod == params[0]) 598 return GL_FALSE; 599 flush(ctx); 600 texObj->Sampler.MinLod = params[0]; 601 return GL_TRUE; 602 603 case GL_TEXTURE_MAX_LOD: 604 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 605 goto invalid_pname; 606 607 if (!target_allows_setting_sampler_parameters(texObj->Target)) 608 goto invalid_operation; 609 610 if (texObj->Sampler.MaxLod == params[0]) 611 return GL_FALSE; 612 flush(ctx); 613 texObj->Sampler.MaxLod = params[0]; 614 return GL_TRUE; 615 616 case GL_TEXTURE_PRIORITY: 617 if (ctx->API != API_OPENGL_COMPAT) 618 goto invalid_pname; 619 620 flush(ctx); 621 texObj->Priority = CLAMP(params[0], 0.0F, 1.0F); 622 return GL_TRUE; 623 624 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 625 if (ctx->Extensions.EXT_texture_filter_anisotropic) { 626 if (!target_allows_setting_sampler_parameters(texObj->Target)) 627 goto invalid_operation; 628 629 if (texObj->Sampler.MaxAnisotropy == params[0]) 630 return GL_FALSE; 631 if (params[0] < 1.0) { 632 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); 633 return GL_FALSE; 634 } 635 flush(ctx); 636 /* clamp to max, that's what NVIDIA does */ 637 texObj->Sampler.MaxAnisotropy = MIN2(params[0], 638 ctx->Const.MaxTextureMaxAnisotropy); 639 return GL_TRUE; 640 } 641 else { 642 static GLuint count = 0; 643 if (count++ < 10) 644 goto invalid_pname; 645 } 646 return GL_FALSE; 647 648 case GL_TEXTURE_LOD_BIAS: 649 /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias. */ 650 if (_mesa_is_gles(ctx)) 651 goto invalid_pname; 652 653 if (!target_allows_setting_sampler_parameters(texObj->Target)) 654 goto invalid_operation; 655 656 if (texObj->Sampler.LodBias != params[0]) { 657 flush(ctx); 658 texObj->Sampler.LodBias = params[0]; 659 return GL_TRUE; 660 } 661 break; 662 663 case GL_TEXTURE_BORDER_COLOR: 664 if (!_mesa_is_desktop_gl(ctx)) 665 goto invalid_pname; 666 667 if (!target_allows_setting_sampler_parameters(texObj->Target)) 668 goto invalid_operation; 669 670 flush(ctx); 671 /* ARB_texture_float disables clamping */ 672 if (ctx->Extensions.ARB_texture_float) { 673 texObj->Sampler.BorderColor.f[RCOMP] = params[0]; 674 texObj->Sampler.BorderColor.f[GCOMP] = params[1]; 675 texObj->Sampler.BorderColor.f[BCOMP] = params[2]; 676 texObj->Sampler.BorderColor.f[ACOMP] = params[3]; 677 } else { 678 texObj->Sampler.BorderColor.f[RCOMP] = CLAMP(params[0], 0.0F, 1.0F); 679 texObj->Sampler.BorderColor.f[GCOMP] = CLAMP(params[1], 0.0F, 1.0F); 680 texObj->Sampler.BorderColor.f[BCOMP] = CLAMP(params[2], 0.0F, 1.0F); 681 texObj->Sampler.BorderColor.f[ACOMP] = CLAMP(params[3], 0.0F, 1.0F); 682 } 683 return GL_TRUE; 684 685 default: 686 goto invalid_pname; 687 } 688 return GL_FALSE; 689 690invalid_pname: 691 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=%s)", 692 _mesa_lookup_enum_by_nr(pname)); 693 return GL_FALSE; 694 695invalid_operation: 696 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(pname=%s)", 697 _mesa_lookup_enum_by_nr(pname)); 698 return GL_FALSE; 699} 700 701 702void GLAPIENTRY 703_mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) 704{ 705 GLboolean need_update; 706 struct gl_texture_object *texObj; 707 GET_CURRENT_CONTEXT(ctx); 708 709 texObj = get_texobj(ctx, target, GL_FALSE); 710 if (!texObj) 711 return; 712 713 switch (pname) { 714 case GL_TEXTURE_MIN_FILTER: 715 case GL_TEXTURE_MAG_FILTER: 716 case GL_TEXTURE_WRAP_S: 717 case GL_TEXTURE_WRAP_T: 718 case GL_TEXTURE_WRAP_R: 719 case GL_TEXTURE_BASE_LEVEL: 720 case GL_TEXTURE_MAX_LEVEL: 721 case GL_GENERATE_MIPMAP_SGIS: 722 case GL_TEXTURE_COMPARE_MODE_ARB: 723 case GL_TEXTURE_COMPARE_FUNC_ARB: 724 case GL_DEPTH_TEXTURE_MODE_ARB: 725 case GL_DEPTH_STENCIL_TEXTURE_MODE: 726 case GL_TEXTURE_SRGB_DECODE_EXT: 727 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 728 case GL_TEXTURE_SWIZZLE_R_EXT: 729 case GL_TEXTURE_SWIZZLE_G_EXT: 730 case GL_TEXTURE_SWIZZLE_B_EXT: 731 case GL_TEXTURE_SWIZZLE_A_EXT: 732 { 733 GLint p[4]; 734 p[0] = (param > 0) ? 735 ((param > INT_MAX) ? INT_MAX : (GLint) (param + 0.5)) : 736 ((param < INT_MIN) ? INT_MIN : (GLint) (param - 0.5)); 737 738 p[1] = p[2] = p[3] = 0; 739 need_update = set_tex_parameteri(ctx, texObj, pname, p); 740 } 741 break; 742 default: 743 { 744 /* this will generate an error if pname is illegal */ 745 GLfloat p[4]; 746 p[0] = param; 747 p[1] = p[2] = p[3] = 0.0F; 748 need_update = set_tex_parameterf(ctx, texObj, pname, p); 749 } 750 } 751 752 if (ctx->Driver.TexParameter && need_update) { 753 ctx->Driver.TexParameter(ctx, texObj, pname, ¶m); 754 } 755} 756 757 758void GLAPIENTRY 759_mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) 760{ 761 GLboolean need_update; 762 struct gl_texture_object *texObj; 763 GET_CURRENT_CONTEXT(ctx); 764 765 texObj = get_texobj(ctx, target, GL_FALSE); 766 if (!texObj) 767 return; 768 769 switch (pname) { 770 case GL_TEXTURE_MIN_FILTER: 771 case GL_TEXTURE_MAG_FILTER: 772 case GL_TEXTURE_WRAP_S: 773 case GL_TEXTURE_WRAP_T: 774 case GL_TEXTURE_WRAP_R: 775 case GL_TEXTURE_BASE_LEVEL: 776 case GL_TEXTURE_MAX_LEVEL: 777 case GL_GENERATE_MIPMAP_SGIS: 778 case GL_TEXTURE_COMPARE_MODE_ARB: 779 case GL_TEXTURE_COMPARE_FUNC_ARB: 780 case GL_DEPTH_TEXTURE_MODE_ARB: 781 case GL_DEPTH_STENCIL_TEXTURE_MODE: 782 case GL_TEXTURE_SRGB_DECODE_EXT: 783 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 784 { 785 /* convert float param to int */ 786 GLint p[4]; 787 p[0] = (GLint) params[0]; 788 p[1] = p[2] = p[3] = 0; 789 need_update = set_tex_parameteri(ctx, texObj, pname, p); 790 } 791 break; 792 case GL_TEXTURE_CROP_RECT_OES: 793 { 794 /* convert float params to int */ 795 GLint iparams[4]; 796 iparams[0] = (GLint) params[0]; 797 iparams[1] = (GLint) params[1]; 798 iparams[2] = (GLint) params[2]; 799 iparams[3] = (GLint) params[3]; 800 need_update = set_tex_parameteri(ctx, texObj, pname, iparams); 801 } 802 break; 803 case GL_TEXTURE_SWIZZLE_R_EXT: 804 case GL_TEXTURE_SWIZZLE_G_EXT: 805 case GL_TEXTURE_SWIZZLE_B_EXT: 806 case GL_TEXTURE_SWIZZLE_A_EXT: 807 case GL_TEXTURE_SWIZZLE_RGBA_EXT: 808 { 809 GLint p[4] = {0, 0, 0, 0}; 810 p[0] = (GLint) params[0]; 811 if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT) { 812 p[1] = (GLint) params[1]; 813 p[2] = (GLint) params[2]; 814 p[3] = (GLint) params[3]; 815 } 816 need_update = set_tex_parameteri(ctx, texObj, pname, p); 817 } 818 break; 819 default: 820 /* this will generate an error if pname is illegal */ 821 need_update = set_tex_parameterf(ctx, texObj, pname, params); 822 } 823 824 if (ctx->Driver.TexParameter && need_update) { 825 ctx->Driver.TexParameter(ctx, texObj, pname, params); 826 } 827} 828 829 830void GLAPIENTRY 831_mesa_TexParameteri(GLenum target, GLenum pname, GLint param) 832{ 833 GLboolean need_update; 834 struct gl_texture_object *texObj; 835 GET_CURRENT_CONTEXT(ctx); 836 837 texObj = get_texobj(ctx, target, GL_FALSE); 838 if (!texObj) 839 return; 840 841 switch (pname) { 842 case GL_TEXTURE_MIN_LOD: 843 case GL_TEXTURE_MAX_LOD: 844 case GL_TEXTURE_PRIORITY: 845 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 846 case GL_TEXTURE_LOD_BIAS: 847 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: 848 { 849 GLfloat fparam[4]; 850 fparam[0] = (GLfloat) param; 851 fparam[1] = fparam[2] = fparam[3] = 0.0F; 852 /* convert int param to float */ 853 need_update = set_tex_parameterf(ctx, texObj, pname, fparam); 854 } 855 break; 856 default: 857 /* this will generate an error if pname is illegal */ 858 { 859 GLint iparam[4]; 860 iparam[0] = param; 861 iparam[1] = iparam[2] = iparam[3] = 0; 862 need_update = set_tex_parameteri(ctx, texObj, pname, iparam); 863 } 864 } 865 866 if (ctx->Driver.TexParameter && need_update) { 867 GLfloat fparam = (GLfloat) param; 868 ctx->Driver.TexParameter(ctx, texObj, pname, &fparam); 869 } 870} 871 872 873void GLAPIENTRY 874_mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) 875{ 876 GLboolean need_update; 877 struct gl_texture_object *texObj; 878 GET_CURRENT_CONTEXT(ctx); 879 880 texObj = get_texobj(ctx, target, GL_FALSE); 881 if (!texObj) 882 return; 883 884 switch (pname) { 885 case GL_TEXTURE_BORDER_COLOR: 886 { 887 /* convert int params to float */ 888 GLfloat fparams[4]; 889 fparams[0] = INT_TO_FLOAT(params[0]); 890 fparams[1] = INT_TO_FLOAT(params[1]); 891 fparams[2] = INT_TO_FLOAT(params[2]); 892 fparams[3] = INT_TO_FLOAT(params[3]); 893 need_update = set_tex_parameterf(ctx, texObj, pname, fparams); 894 } 895 break; 896 case GL_TEXTURE_MIN_LOD: 897 case GL_TEXTURE_MAX_LOD: 898 case GL_TEXTURE_PRIORITY: 899 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 900 case GL_TEXTURE_LOD_BIAS: 901 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: 902 { 903 /* convert int param to float */ 904 GLfloat fparams[4]; 905 fparams[0] = (GLfloat) params[0]; 906 fparams[1] = fparams[2] = fparams[3] = 0.0F; 907 need_update = set_tex_parameterf(ctx, texObj, pname, fparams); 908 } 909 break; 910 default: 911 /* this will generate an error if pname is illegal */ 912 need_update = set_tex_parameteri(ctx, texObj, pname, params); 913 } 914 915 if (ctx->Driver.TexParameter && need_update) { 916 GLfloat fparams[4]; 917 fparams[0] = INT_TO_FLOAT(params[0]); 918 if (pname == GL_TEXTURE_BORDER_COLOR || 919 pname == GL_TEXTURE_CROP_RECT_OES) { 920 fparams[1] = INT_TO_FLOAT(params[1]); 921 fparams[2] = INT_TO_FLOAT(params[2]); 922 fparams[3] = INT_TO_FLOAT(params[3]); 923 } 924 ctx->Driver.TexParameter(ctx, texObj, pname, fparams); 925 } 926} 927 928 929/** 930 * Set tex parameter to integer value(s). Primarily intended to set 931 * integer-valued texture border color (for integer-valued textures). 932 * New in GL 3.0. 933 */ 934void GLAPIENTRY 935_mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params) 936{ 937 struct gl_texture_object *texObj; 938 GET_CURRENT_CONTEXT(ctx); 939 940 texObj = get_texobj(ctx, target, GL_FALSE); 941 if (!texObj) 942 return; 943 944 switch (pname) { 945 case GL_TEXTURE_BORDER_COLOR: 946 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 947 /* set the integer-valued border color */ 948 COPY_4V(texObj->Sampler.BorderColor.i, params); 949 break; 950 default: 951 _mesa_TexParameteriv(target, pname, params); 952 break; 953 } 954 /* XXX no driver hook for TexParameterIiv() yet */ 955} 956 957 958/** 959 * Set tex parameter to unsigned integer value(s). Primarily intended to set 960 * uint-valued texture border color (for integer-valued textures). 961 * New in GL 3.0 962 */ 963void GLAPIENTRY 964_mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params) 965{ 966 struct gl_texture_object *texObj; 967 GET_CURRENT_CONTEXT(ctx); 968 969 texObj = get_texobj(ctx, target, GL_FALSE); 970 if (!texObj) 971 return; 972 973 switch (pname) { 974 case GL_TEXTURE_BORDER_COLOR: 975 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 976 /* set the unsigned integer-valued border color */ 977 COPY_4V(texObj->Sampler.BorderColor.ui, params); 978 break; 979 default: 980 _mesa_TexParameteriv(target, pname, (const GLint *) params); 981 break; 982 } 983 /* XXX no driver hook for TexParameterIuiv() yet */ 984} 985 986 987static GLboolean 988legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target) 989{ 990 switch (target) { 991 case GL_TEXTURE_1D: 992 case GL_PROXY_TEXTURE_1D: 993 case GL_TEXTURE_2D: 994 case GL_PROXY_TEXTURE_2D: 995 case GL_TEXTURE_3D: 996 case GL_PROXY_TEXTURE_3D: 997 return GL_TRUE; 998 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB: 999 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB: 1000 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB: 1001 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: 1002 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: 1003 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: 1004 case GL_PROXY_TEXTURE_CUBE_MAP_ARB: 1005 return ctx->Extensions.ARB_texture_cube_map; 1006 case GL_TEXTURE_CUBE_MAP_ARRAY_ARB: 1007 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB: 1008 return ctx->Extensions.ARB_texture_cube_map_array; 1009 case GL_TEXTURE_RECTANGLE_NV: 1010 case GL_PROXY_TEXTURE_RECTANGLE_NV: 1011 return ctx->Extensions.NV_texture_rectangle; 1012 case GL_TEXTURE_1D_ARRAY_EXT: 1013 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 1014 case GL_TEXTURE_2D_ARRAY_EXT: 1015 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1016 return ctx->Extensions.EXT_texture_array; 1017 case GL_TEXTURE_BUFFER: 1018 /* GetTexLevelParameter accepts GL_TEXTURE_BUFFER in GL 3.1+ contexts, 1019 * but not in earlier versions that expose ARB_texture_buffer_object. 1020 * 1021 * From the ARB_texture_buffer_object spec: 1022 * "(7) Do buffer textures support texture parameters (TexParameter) or 1023 * queries (GetTexParameter, GetTexLevelParameter, GetTexImage)? 1024 * 1025 * RESOLVED: No. [...] Note that the spec edits above don't add 1026 * explicit error language for any of these cases. That is because 1027 * each of the functions enumerate the set of valid <target> 1028 * parameters. Not editing the spec to allow TEXTURE_BUFFER_ARB in 1029 * these cases means that target is not legal, and an INVALID_ENUM 1030 * error should be generated." 1031 * 1032 * From the OpenGL 3.1 spec: 1033 * "target may also be TEXTURE_BUFFER, indicating the texture buffer." 1034 */ 1035 return ctx->API == API_OPENGL_CORE && ctx->Version >= 31; 1036 case GL_TEXTURE_2D_MULTISAMPLE: 1037 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1038 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 1039 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 1040 return ctx->Extensions.ARB_texture_multisample; 1041 default: 1042 return GL_FALSE; 1043 } 1044} 1045 1046 1047static void 1048get_tex_level_parameter_image(struct gl_context *ctx, 1049 const struct gl_texture_object *texObj, 1050 GLenum target, GLint level, 1051 GLenum pname, GLint *params) 1052{ 1053 const struct gl_texture_image *img = NULL; 1054 struct gl_texture_image dummy_image; 1055 mesa_format texFormat; 1056 1057 img = _mesa_select_tex_image(ctx, texObj, target, level); 1058 if (!img || img->TexFormat == MESA_FORMAT_NONE) { 1059 /* In case of undefined texture image return the default values. 1060 * 1061 * From OpenGL 4.0 spec, page 398: 1062 * "The initial internal format of a texel array is RGBA 1063 * instead of 1. TEXTURE_COMPONENTS is deprecated; always 1064 * use TEXTURE_INTERNAL_FORMAT." 1065 */ 1066 memset(&dummy_image, 0, sizeof(dummy_image)); 1067 dummy_image.TexFormat = MESA_FORMAT_NONE; 1068 dummy_image.InternalFormat = GL_RGBA; 1069 dummy_image._BaseFormat = GL_NONE; 1070 1071 img = &dummy_image; 1072 } 1073 1074 texFormat = img->TexFormat; 1075 1076 switch (pname) { 1077 case GL_TEXTURE_WIDTH: 1078 *params = img->Width; 1079 break; 1080 case GL_TEXTURE_HEIGHT: 1081 *params = img->Height; 1082 break; 1083 case GL_TEXTURE_DEPTH: 1084 *params = img->Depth; 1085 break; 1086 case GL_TEXTURE_INTERNAL_FORMAT: 1087 if (_mesa_is_format_compressed(texFormat)) { 1088 /* need to return the actual compressed format */ 1089 *params = _mesa_compressed_format_to_glenum(ctx, texFormat); 1090 } 1091 else { 1092 /* If the true internal format is not compressed but the user 1093 * requested a generic compressed format, we have to return the 1094 * generic base format that matches. 1095 * 1096 * From page 119 (page 129 of the PDF) of the OpenGL 1.3 spec: 1097 * 1098 * "If no specific compressed format is available, 1099 * internalformat is instead replaced by the corresponding base 1100 * internal format." 1101 * 1102 * Otherwise just return the user's requested internal format 1103 */ 1104 const GLenum f = 1105 _mesa_gl_compressed_format_base_format(img->InternalFormat); 1106 1107 *params = (f != 0) ? f : img->InternalFormat; 1108 } 1109 break; 1110 case GL_TEXTURE_BORDER: 1111 if (ctx->API != API_OPENGL_COMPAT) 1112 goto invalid_pname; 1113 *params = img->Border; 1114 break; 1115 case GL_TEXTURE_RED_SIZE: 1116 case GL_TEXTURE_GREEN_SIZE: 1117 case GL_TEXTURE_BLUE_SIZE: 1118 case GL_TEXTURE_ALPHA_SIZE: 1119 if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) 1120 *params = _mesa_get_format_bits(texFormat, pname); 1121 else 1122 *params = 0; 1123 break; 1124 case GL_TEXTURE_INTENSITY_SIZE: 1125 case GL_TEXTURE_LUMINANCE_SIZE: 1126 if (ctx->API != API_OPENGL_COMPAT) 1127 goto invalid_pname; 1128 if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) { 1129 *params = _mesa_get_format_bits(texFormat, pname); 1130 if (*params == 0) { 1131 /* intensity or luminance is probably stored as RGB[A] */ 1132 *params = MIN2(_mesa_get_format_bits(texFormat, 1133 GL_TEXTURE_RED_SIZE), 1134 _mesa_get_format_bits(texFormat, 1135 GL_TEXTURE_GREEN_SIZE)); 1136 } 1137 } 1138 else { 1139 *params = 0; 1140 } 1141 break; 1142 case GL_TEXTURE_DEPTH_SIZE_ARB: 1143 if (!ctx->Extensions.ARB_depth_texture) 1144 goto invalid_pname; 1145 *params = _mesa_get_format_bits(texFormat, pname); 1146 break; 1147 case GL_TEXTURE_STENCIL_SIZE: 1148 *params = _mesa_get_format_bits(texFormat, pname); 1149 break; 1150 case GL_TEXTURE_SHARED_SIZE: 1151 if (ctx->Version < 30 && 1152 !ctx->Extensions.EXT_texture_shared_exponent) 1153 goto invalid_pname; 1154 *params = texFormat == MESA_FORMAT_R9G9B9E5_FLOAT ? 5 : 0; 1155 break; 1156 1157 /* GL_ARB_texture_compression */ 1158 case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: 1159 if (_mesa_is_format_compressed(texFormat) && 1160 !_mesa_is_proxy_texture(target)) { 1161 *params = _mesa_format_image_size(texFormat, img->Width, 1162 img->Height, img->Depth); 1163 } 1164 else { 1165 _mesa_error(ctx, GL_INVALID_OPERATION, 1166 "glGetTexLevelParameter[if]v(pname)"); 1167 } 1168 break; 1169 case GL_TEXTURE_COMPRESSED: 1170 *params = (GLint) _mesa_is_format_compressed(texFormat); 1171 break; 1172 1173 /* GL_ARB_texture_float */ 1174 case GL_TEXTURE_LUMINANCE_TYPE_ARB: 1175 case GL_TEXTURE_INTENSITY_TYPE_ARB: 1176 if (ctx->API != API_OPENGL_COMPAT) 1177 goto invalid_pname; 1178 /* FALLTHROUGH */ 1179 case GL_TEXTURE_RED_TYPE_ARB: 1180 case GL_TEXTURE_GREEN_TYPE_ARB: 1181 case GL_TEXTURE_BLUE_TYPE_ARB: 1182 case GL_TEXTURE_ALPHA_TYPE_ARB: 1183 case GL_TEXTURE_DEPTH_TYPE_ARB: 1184 if (!ctx->Extensions.ARB_texture_float) 1185 goto invalid_pname; 1186 if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) 1187 *params = _mesa_get_format_datatype(texFormat); 1188 else 1189 *params = GL_NONE; 1190 break; 1191 1192 /* GL_ARB_texture_multisample */ 1193 case GL_TEXTURE_SAMPLES: 1194 if (!ctx->Extensions.ARB_texture_multisample) 1195 goto invalid_pname; 1196 *params = img->NumSamples; 1197 break; 1198 1199 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS: 1200 if (!ctx->Extensions.ARB_texture_multisample) 1201 goto invalid_pname; 1202 *params = img->FixedSampleLocations; 1203 break; 1204 1205 default: 1206 goto invalid_pname; 1207 } 1208 1209 /* no error if we get here */ 1210 return; 1211 1212invalid_pname: 1213 _mesa_error(ctx, GL_INVALID_ENUM, 1214 "glGetTexLevelParameter[if]v(pname=%s)", 1215 _mesa_lookup_enum_by_nr(pname)); 1216} 1217 1218 1219static void 1220get_tex_level_parameter_buffer(struct gl_context *ctx, 1221 const struct gl_texture_object *texObj, 1222 GLenum pname, GLint *params) 1223{ 1224 const struct gl_buffer_object *bo = texObj->BufferObject; 1225 mesa_format texFormat = texObj->_BufferObjectFormat; 1226 GLenum internalFormat = texObj->BufferObjectFormat; 1227 GLenum baseFormat = _mesa_get_format_base_format(texFormat); 1228 1229 if (!bo) { 1230 /* undefined texture buffer object */ 1231 *params = pname == GL_TEXTURE_COMPONENTS ? 1 : 0; 1232 return; 1233 } 1234 1235 switch (pname) { 1236 case GL_TEXTURE_BUFFER_DATA_STORE_BINDING: 1237 *params = bo->Name; 1238 break; 1239 case GL_TEXTURE_WIDTH: 1240 *params = bo->Size; 1241 break; 1242 case GL_TEXTURE_HEIGHT: 1243 case GL_TEXTURE_DEPTH: 1244 case GL_TEXTURE_BORDER: 1245 case GL_TEXTURE_SHARED_SIZE: 1246 case GL_TEXTURE_COMPRESSED: 1247 *params = 0; 1248 break; 1249 case GL_TEXTURE_INTERNAL_FORMAT: 1250 *params = internalFormat; 1251 break; 1252 case GL_TEXTURE_RED_SIZE: 1253 case GL_TEXTURE_GREEN_SIZE: 1254 case GL_TEXTURE_BLUE_SIZE: 1255 case GL_TEXTURE_ALPHA_SIZE: 1256 if (_mesa_base_format_has_channel(baseFormat, pname)) 1257 *params = _mesa_get_format_bits(texFormat, pname); 1258 else 1259 *params = 0; 1260 break; 1261 case GL_TEXTURE_INTENSITY_SIZE: 1262 case GL_TEXTURE_LUMINANCE_SIZE: 1263 if (_mesa_base_format_has_channel(baseFormat, pname)) { 1264 *params = _mesa_get_format_bits(texFormat, pname); 1265 if (*params == 0) { 1266 /* intensity or luminance is probably stored as RGB[A] */ 1267 *params = MIN2(_mesa_get_format_bits(texFormat, 1268 GL_TEXTURE_RED_SIZE), 1269 _mesa_get_format_bits(texFormat, 1270 GL_TEXTURE_GREEN_SIZE)); 1271 } 1272 } else { 1273 *params = 0; 1274 } 1275 break; 1276 case GL_TEXTURE_DEPTH_SIZE_ARB: 1277 case GL_TEXTURE_STENCIL_SIZE_EXT: 1278 *params = _mesa_get_format_bits(texFormat, pname); 1279 break; 1280 1281 /* GL_ARB_texture_buffer_range */ 1282 case GL_TEXTURE_BUFFER_OFFSET: 1283 if (!ctx->Extensions.ARB_texture_buffer_range) 1284 goto invalid_pname; 1285 *params = texObj->BufferOffset; 1286 break; 1287 case GL_TEXTURE_BUFFER_SIZE: 1288 if (!ctx->Extensions.ARB_texture_buffer_range) 1289 goto invalid_pname; 1290 *params = (texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize; 1291 break; 1292 1293 /* GL_ARB_texture_compression */ 1294 case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: 1295 /* Always illegal for GL_TEXTURE_BUFFER */ 1296 _mesa_error(ctx, GL_INVALID_OPERATION, 1297 "glGetTexLevelParameter[if]v(pname)"); 1298 break; 1299 1300 /* GL_ARB_texture_float */ 1301 case GL_TEXTURE_RED_TYPE_ARB: 1302 case GL_TEXTURE_GREEN_TYPE_ARB: 1303 case GL_TEXTURE_BLUE_TYPE_ARB: 1304 case GL_TEXTURE_ALPHA_TYPE_ARB: 1305 case GL_TEXTURE_LUMINANCE_TYPE_ARB: 1306 case GL_TEXTURE_INTENSITY_TYPE_ARB: 1307 case GL_TEXTURE_DEPTH_TYPE_ARB: 1308 if (!ctx->Extensions.ARB_texture_float) 1309 goto invalid_pname; 1310 if (_mesa_base_format_has_channel(baseFormat, pname)) 1311 *params = _mesa_get_format_datatype(texFormat); 1312 else 1313 *params = GL_NONE; 1314 break; 1315 1316 default: 1317 goto invalid_pname; 1318 } 1319 1320 /* no error if we get here */ 1321 return; 1322 1323invalid_pname: 1324 _mesa_error(ctx, GL_INVALID_ENUM, 1325 "glGetTexLevelParameter[if]v(pname=%s)", 1326 _mesa_lookup_enum_by_nr(pname)); 1327} 1328 1329 1330void GLAPIENTRY 1331_mesa_GetTexLevelParameterfv( GLenum target, GLint level, 1332 GLenum pname, GLfloat *params ) 1333{ 1334 GLint iparam; 1335 _mesa_GetTexLevelParameteriv( target, level, pname, &iparam ); 1336 *params = (GLfloat) iparam; 1337} 1338 1339 1340void GLAPIENTRY 1341_mesa_GetTexLevelParameteriv( GLenum target, GLint level, 1342 GLenum pname, GLint *params ) 1343{ 1344 struct gl_texture_object *texObj; 1345 GLint maxLevels; 1346 GET_CURRENT_CONTEXT(ctx); 1347 1348 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) { 1349 _mesa_error(ctx, GL_INVALID_OPERATION, 1350 "glGetTexLevelParameteriv(current unit)"); 1351 return; 1352 } 1353 1354 if (!legal_get_tex_level_parameter_target(ctx, target)) { 1355 _mesa_error(ctx, GL_INVALID_ENUM, 1356 "glGetTexLevelParameter[if]v(target=0x%x)", target); 1357 return; 1358 } 1359 1360 maxLevels = _mesa_max_texture_levels(ctx, target); 1361 assert(maxLevels != 0); 1362 1363 if (level < 0 || level >= maxLevels) { 1364 _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" ); 1365 return; 1366 } 1367 1368 texObj = _mesa_get_current_tex_object(ctx, target); 1369 1370 if (target == GL_TEXTURE_BUFFER) 1371 get_tex_level_parameter_buffer(ctx, texObj, pname, params); 1372 else 1373 get_tex_level_parameter_image(ctx, texObj, target, level, pname, params); 1374} 1375 1376 1377void GLAPIENTRY 1378_mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) 1379{ 1380 struct gl_texture_object *obj; 1381 GET_CURRENT_CONTEXT(ctx); 1382 1383 obj = get_texobj(ctx, target, GL_TRUE); 1384 if (!obj) 1385 return; 1386 1387 _mesa_lock_context_textures(ctx); 1388 switch (pname) { 1389 case GL_TEXTURE_MAG_FILTER: 1390 *params = ENUM_TO_FLOAT(obj->Sampler.MagFilter); 1391 break; 1392 case GL_TEXTURE_MIN_FILTER: 1393 *params = ENUM_TO_FLOAT(obj->Sampler.MinFilter); 1394 break; 1395 case GL_TEXTURE_WRAP_S: 1396 *params = ENUM_TO_FLOAT(obj->Sampler.WrapS); 1397 break; 1398 case GL_TEXTURE_WRAP_T: 1399 *params = ENUM_TO_FLOAT(obj->Sampler.WrapT); 1400 break; 1401 case GL_TEXTURE_WRAP_R: 1402 *params = ENUM_TO_FLOAT(obj->Sampler.WrapR); 1403 break; 1404 case GL_TEXTURE_BORDER_COLOR: 1405 if (!_mesa_is_desktop_gl(ctx)) 1406 goto invalid_pname; 1407 1408 if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP)) 1409 _mesa_update_state_locked(ctx); 1410 if (_mesa_get_clamp_fragment_color(ctx)) { 1411 params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F); 1412 params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F); 1413 params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F); 1414 params[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F); 1415 } 1416 else { 1417 params[0] = obj->Sampler.BorderColor.f[0]; 1418 params[1] = obj->Sampler.BorderColor.f[1]; 1419 params[2] = obj->Sampler.BorderColor.f[2]; 1420 params[3] = obj->Sampler.BorderColor.f[3]; 1421 } 1422 break; 1423 case GL_TEXTURE_RESIDENT: 1424 if (ctx->API != API_OPENGL_COMPAT) 1425 goto invalid_pname; 1426 1427 *params = 1.0F; 1428 break; 1429 case GL_TEXTURE_PRIORITY: 1430 if (ctx->API != API_OPENGL_COMPAT) 1431 goto invalid_pname; 1432 1433 *params = obj->Priority; 1434 break; 1435 case GL_TEXTURE_MIN_LOD: 1436 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 1437 goto invalid_pname; 1438 1439 *params = obj->Sampler.MinLod; 1440 break; 1441 case GL_TEXTURE_MAX_LOD: 1442 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 1443 goto invalid_pname; 1444 1445 *params = obj->Sampler.MaxLod; 1446 break; 1447 case GL_TEXTURE_BASE_LEVEL: 1448 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 1449 goto invalid_pname; 1450 1451 *params = (GLfloat) obj->BaseLevel; 1452 break; 1453 case GL_TEXTURE_MAX_LEVEL: 1454 *params = (GLfloat) obj->MaxLevel; 1455 break; 1456 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1457 if (!ctx->Extensions.EXT_texture_filter_anisotropic) 1458 goto invalid_pname; 1459 *params = obj->Sampler.MaxAnisotropy; 1460 break; 1461 case GL_GENERATE_MIPMAP_SGIS: 1462 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) 1463 goto invalid_pname; 1464 1465 *params = (GLfloat) obj->GenerateMipmap; 1466 break; 1467 case GL_TEXTURE_COMPARE_MODE_ARB: 1468 if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow) 1469 && !_mesa_is_gles3(ctx)) 1470 goto invalid_pname; 1471 *params = (GLfloat) obj->Sampler.CompareMode; 1472 break; 1473 case GL_TEXTURE_COMPARE_FUNC_ARB: 1474 if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow) 1475 && !_mesa_is_gles3(ctx)) 1476 goto invalid_pname; 1477 *params = (GLfloat) obj->Sampler.CompareFunc; 1478 break; 1479 case GL_DEPTH_TEXTURE_MODE_ARB: 1480 /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has 1481 * never existed in OpenGL ES. 1482 */ 1483 if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture) 1484 goto invalid_pname; 1485 *params = (GLfloat) obj->DepthMode; 1486 break; 1487 case GL_DEPTH_STENCIL_TEXTURE_MODE: 1488 if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_stencil_texturing) 1489 goto invalid_pname; 1490 *params = (GLfloat) 1491 (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT); 1492 break; 1493 case GL_TEXTURE_LOD_BIAS: 1494 if (_mesa_is_gles(ctx)) 1495 goto invalid_pname; 1496 1497 *params = obj->Sampler.LodBias; 1498 break; 1499 case GL_TEXTURE_CROP_RECT_OES: 1500 if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture) 1501 goto invalid_pname; 1502 1503 params[0] = (GLfloat) obj->CropRect[0]; 1504 params[1] = (GLfloat) obj->CropRect[1]; 1505 params[2] = (GLfloat) obj->CropRect[2]; 1506 params[3] = (GLfloat) obj->CropRect[3]; 1507 break; 1508 1509 case GL_TEXTURE_SWIZZLE_R_EXT: 1510 case GL_TEXTURE_SWIZZLE_G_EXT: 1511 case GL_TEXTURE_SWIZZLE_B_EXT: 1512 case GL_TEXTURE_SWIZZLE_A_EXT: 1513 if ((!_mesa_is_desktop_gl(ctx) 1514 || !ctx->Extensions.EXT_texture_swizzle) 1515 && !_mesa_is_gles3(ctx)) 1516 goto invalid_pname; 1517 *params = (GLfloat) obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT]; 1518 break; 1519 1520 case GL_TEXTURE_SWIZZLE_RGBA_EXT: 1521 if ((!_mesa_is_desktop_gl(ctx) 1522 || !ctx->Extensions.EXT_texture_swizzle) 1523 && !_mesa_is_gles3(ctx)) { 1524 goto invalid_pname; 1525 } 1526 else { 1527 GLuint comp; 1528 for (comp = 0; comp < 4; comp++) { 1529 params[comp] = (GLfloat) obj->Swizzle[comp]; 1530 } 1531 } 1532 break; 1533 1534 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1535 if (!_mesa_is_desktop_gl(ctx) 1536 || !ctx->Extensions.AMD_seamless_cubemap_per_texture) 1537 goto invalid_pname; 1538 *params = (GLfloat) obj->Sampler.CubeMapSeamless; 1539 break; 1540 1541 case GL_TEXTURE_IMMUTABLE_FORMAT: 1542 *params = (GLfloat) obj->Immutable; 1543 break; 1544 1545 case GL_TEXTURE_IMMUTABLE_LEVELS: 1546 if (_mesa_is_gles3(ctx) || 1547 (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view)) 1548 *params = (GLfloat) obj->ImmutableLevels; 1549 else 1550 goto invalid_pname; 1551 break; 1552 1553 case GL_TEXTURE_VIEW_MIN_LEVEL: 1554 if (!ctx->Extensions.ARB_texture_view) 1555 goto invalid_pname; 1556 *params = (GLfloat) obj->MinLevel; 1557 break; 1558 1559 case GL_TEXTURE_VIEW_NUM_LEVELS: 1560 if (!ctx->Extensions.ARB_texture_view) 1561 goto invalid_pname; 1562 *params = (GLfloat) obj->NumLevels; 1563 break; 1564 1565 case GL_TEXTURE_VIEW_MIN_LAYER: 1566 if (!ctx->Extensions.ARB_texture_view) 1567 goto invalid_pname; 1568 *params = (GLfloat) obj->MinLayer; 1569 break; 1570 1571 case GL_TEXTURE_VIEW_NUM_LAYERS: 1572 if (!ctx->Extensions.ARB_texture_view) 1573 goto invalid_pname; 1574 *params = (GLfloat) obj->NumLayers; 1575 break; 1576 1577 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: 1578 if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external) 1579 goto invalid_pname; 1580 *params = (GLfloat) obj->RequiredTextureImageUnits; 1581 break; 1582 1583 case GL_TEXTURE_SRGB_DECODE_EXT: 1584 if (!ctx->Extensions.EXT_texture_sRGB_decode) 1585 goto invalid_pname; 1586 *params = (GLfloat) obj->Sampler.sRGBDecode; 1587 break; 1588 1589 default: 1590 goto invalid_pname; 1591 } 1592 1593 /* no error if we get here */ 1594 _mesa_unlock_context_textures(ctx); 1595 return; 1596 1597invalid_pname: 1598 _mesa_unlock_context_textures(ctx); 1599 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", pname); 1600} 1601 1602 1603void GLAPIENTRY 1604_mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) 1605{ 1606 struct gl_texture_object *obj; 1607 GET_CURRENT_CONTEXT(ctx); 1608 1609 obj = get_texobj(ctx, target, GL_TRUE); 1610 if (!obj) 1611 return; 1612 1613 _mesa_lock_texture(ctx, obj); 1614 switch (pname) { 1615 case GL_TEXTURE_MAG_FILTER: 1616 *params = (GLint) obj->Sampler.MagFilter; 1617 break; 1618 case GL_TEXTURE_MIN_FILTER: 1619 *params = (GLint) obj->Sampler.MinFilter; 1620 break; 1621 case GL_TEXTURE_WRAP_S: 1622 *params = (GLint) obj->Sampler.WrapS; 1623 break; 1624 case GL_TEXTURE_WRAP_T: 1625 *params = (GLint) obj->Sampler.WrapT; 1626 break; 1627 case GL_TEXTURE_WRAP_R: 1628 *params = (GLint) obj->Sampler.WrapR; 1629 break; 1630 case GL_TEXTURE_BORDER_COLOR: 1631 if (!_mesa_is_desktop_gl(ctx)) 1632 goto invalid_pname; 1633 1634 { 1635 GLfloat b[4]; 1636 b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F); 1637 b[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F); 1638 b[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F); 1639 b[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F); 1640 params[0] = FLOAT_TO_INT(b[0]); 1641 params[1] = FLOAT_TO_INT(b[1]); 1642 params[2] = FLOAT_TO_INT(b[2]); 1643 params[3] = FLOAT_TO_INT(b[3]); 1644 } 1645 break; 1646 case GL_TEXTURE_RESIDENT: 1647 if (ctx->API != API_OPENGL_COMPAT) 1648 goto invalid_pname; 1649 1650 *params = 1; 1651 break; 1652 case GL_TEXTURE_PRIORITY: 1653 if (ctx->API != API_OPENGL_COMPAT) 1654 goto invalid_pname; 1655 1656 *params = FLOAT_TO_INT(obj->Priority); 1657 break; 1658 case GL_TEXTURE_MIN_LOD: 1659 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 1660 goto invalid_pname; 1661 1662 *params = (GLint) obj->Sampler.MinLod; 1663 break; 1664 case GL_TEXTURE_MAX_LOD: 1665 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 1666 goto invalid_pname; 1667 1668 *params = (GLint) obj->Sampler.MaxLod; 1669 break; 1670 case GL_TEXTURE_BASE_LEVEL: 1671 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 1672 goto invalid_pname; 1673 1674 *params = obj->BaseLevel; 1675 break; 1676 case GL_TEXTURE_MAX_LEVEL: 1677 *params = obj->MaxLevel; 1678 break; 1679 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1680 if (!ctx->Extensions.EXT_texture_filter_anisotropic) 1681 goto invalid_pname; 1682 *params = (GLint) obj->Sampler.MaxAnisotropy; 1683 break; 1684 case GL_GENERATE_MIPMAP_SGIS: 1685 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) 1686 goto invalid_pname; 1687 1688 *params = (GLint) obj->GenerateMipmap; 1689 break; 1690 case GL_TEXTURE_COMPARE_MODE_ARB: 1691 if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow) 1692 && !_mesa_is_gles3(ctx)) 1693 goto invalid_pname; 1694 *params = (GLint) obj->Sampler.CompareMode; 1695 break; 1696 case GL_TEXTURE_COMPARE_FUNC_ARB: 1697 if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow) 1698 && !_mesa_is_gles3(ctx)) 1699 goto invalid_pname; 1700 *params = (GLint) obj->Sampler.CompareFunc; 1701 break; 1702 case GL_DEPTH_TEXTURE_MODE_ARB: 1703 if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture) 1704 goto invalid_pname; 1705 *params = (GLint) obj->DepthMode; 1706 break; 1707 case GL_DEPTH_STENCIL_TEXTURE_MODE: 1708 if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_stencil_texturing) 1709 goto invalid_pname; 1710 *params = (GLint) 1711 (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT); 1712 break; 1713 case GL_TEXTURE_LOD_BIAS: 1714 if (_mesa_is_gles(ctx)) 1715 goto invalid_pname; 1716 1717 /* GL spec 'Data Conversions' section specifies that floating-point 1718 * value in integer Get function is rounded to nearest integer 1719 */ 1720 *params = IROUND(obj->Sampler.LodBias); 1721 break; 1722 case GL_TEXTURE_CROP_RECT_OES: 1723 if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture) 1724 goto invalid_pname; 1725 1726 params[0] = obj->CropRect[0]; 1727 params[1] = obj->CropRect[1]; 1728 params[2] = obj->CropRect[2]; 1729 params[3] = obj->CropRect[3]; 1730 break; 1731 case GL_TEXTURE_SWIZZLE_R_EXT: 1732 case GL_TEXTURE_SWIZZLE_G_EXT: 1733 case GL_TEXTURE_SWIZZLE_B_EXT: 1734 case GL_TEXTURE_SWIZZLE_A_EXT: 1735 if ((!_mesa_is_desktop_gl(ctx) 1736 || !ctx->Extensions.EXT_texture_swizzle) 1737 && !_mesa_is_gles3(ctx)) 1738 goto invalid_pname; 1739 *params = obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT]; 1740 break; 1741 1742 case GL_TEXTURE_SWIZZLE_RGBA_EXT: 1743 if ((!_mesa_is_desktop_gl(ctx) 1744 || !ctx->Extensions.EXT_texture_swizzle) 1745 && !_mesa_is_gles3(ctx)) 1746 goto invalid_pname; 1747 COPY_4V(params, obj->Swizzle); 1748 break; 1749 1750 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1751 if (!_mesa_is_desktop_gl(ctx) 1752 || !ctx->Extensions.AMD_seamless_cubemap_per_texture) 1753 goto invalid_pname; 1754 *params = (GLint) obj->Sampler.CubeMapSeamless; 1755 break; 1756 1757 case GL_TEXTURE_IMMUTABLE_FORMAT: 1758 *params = (GLint) obj->Immutable; 1759 break; 1760 1761 case GL_TEXTURE_IMMUTABLE_LEVELS: 1762 if (_mesa_is_gles3(ctx) || 1763 (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view)) 1764 *params = obj->ImmutableLevels; 1765 else 1766 goto invalid_pname; 1767 break; 1768 1769 case GL_TEXTURE_VIEW_MIN_LEVEL: 1770 if (!ctx->Extensions.ARB_texture_view) 1771 goto invalid_pname; 1772 *params = (GLint) obj->MinLevel; 1773 break; 1774 1775 case GL_TEXTURE_VIEW_NUM_LEVELS: 1776 if (!ctx->Extensions.ARB_texture_view) 1777 goto invalid_pname; 1778 *params = (GLint) obj->NumLevels; 1779 break; 1780 1781 case GL_TEXTURE_VIEW_MIN_LAYER: 1782 if (!ctx->Extensions.ARB_texture_view) 1783 goto invalid_pname; 1784 *params = (GLint) obj->MinLayer; 1785 break; 1786 1787 case GL_TEXTURE_VIEW_NUM_LAYERS: 1788 if (!ctx->Extensions.ARB_texture_view) 1789 goto invalid_pname; 1790 *params = (GLint) obj->NumLayers; 1791 break; 1792 1793 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: 1794 if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external) 1795 goto invalid_pname; 1796 *params = obj->RequiredTextureImageUnits; 1797 break; 1798 1799 case GL_TEXTURE_SRGB_DECODE_EXT: 1800 if (!ctx->Extensions.EXT_texture_sRGB_decode) 1801 goto invalid_pname; 1802 *params = obj->Sampler.sRGBDecode; 1803 break; 1804 1805 case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: 1806 if (!ctx->Extensions.ARB_shader_image_load_store) 1807 goto invalid_pname; 1808 *params = obj->ImageFormatCompatibilityType; 1809 break; 1810 1811 default: 1812 goto invalid_pname; 1813 } 1814 1815 /* no error if we get here */ 1816 _mesa_unlock_texture(ctx, obj); 1817 return; 1818 1819invalid_pname: 1820 _mesa_unlock_texture(ctx, obj); 1821 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", pname); 1822} 1823 1824 1825/** New in GL 3.0 */ 1826void GLAPIENTRY 1827_mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params) 1828{ 1829 struct gl_texture_object *texObj; 1830 GET_CURRENT_CONTEXT(ctx); 1831 1832 texObj = get_texobj(ctx, target, GL_TRUE); 1833 if (!texObj) 1834 return; 1835 1836 switch (pname) { 1837 case GL_TEXTURE_BORDER_COLOR: 1838 COPY_4V(params, texObj->Sampler.BorderColor.i); 1839 break; 1840 default: 1841 _mesa_GetTexParameteriv(target, pname, params); 1842 } 1843} 1844 1845 1846/** New in GL 3.0 */ 1847void GLAPIENTRY 1848_mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params) 1849{ 1850 struct gl_texture_object *texObj; 1851 GET_CURRENT_CONTEXT(ctx); 1852 1853 texObj = get_texobj(ctx, target, GL_TRUE); 1854 if (!texObj) 1855 return; 1856 1857 switch (pname) { 1858 case GL_TEXTURE_BORDER_COLOR: 1859 COPY_4V(params, texObj->Sampler.BorderColor.i); 1860 break; 1861 default: 1862 { 1863 GLint ip[4]; 1864 _mesa_GetTexParameteriv(target, pname, ip); 1865 params[0] = ip[0]; 1866 if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT || 1867 pname == GL_TEXTURE_CROP_RECT_OES) { 1868 params[1] = ip[1]; 1869 params[2] = ip[2]; 1870 params[3] = ip[3]; 1871 } 1872 } 1873 } 1874} 1875