texparam.c revision 644d8fd363ca7d8f40f4fa319919985cc002df9e
1/* 2 * Mesa 3-D graphics library 3 * Version: 7.5 4 * 5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26/** 27 * \file texparam.c 28 * 29 * glTexParameter-related functions 30 */ 31 32 33#include "main/glheader.h" 34#include "main/colormac.h" 35#include "main/context.h" 36#include "main/enums.h" 37#include "main/formats.h" 38#include "main/macros.h" 39#include "main/texcompress.h" 40#include "main/texparam.h" 41#include "main/teximage.h" 42#include "main/texstate.h" 43#include "shader/prog_instruction.h" 44 45 46/** 47 * Check if a coordinate wrap mode is supported for the texture target. 48 * \return GL_TRUE if legal, GL_FALSE otherwise 49 */ 50static GLboolean 51validate_texture_wrap_mode(GLcontext * ctx, GLenum target, GLenum wrap) 52{ 53 const struct gl_extensions * const e = & ctx->Extensions; 54 55 if (wrap == GL_CLAMP || wrap == GL_CLAMP_TO_EDGE || 56 (wrap == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) { 57 /* any texture target */ 58 return GL_TRUE; 59 } 60 else if (target != GL_TEXTURE_RECTANGLE_NV && 61 (wrap == GL_REPEAT || 62 (wrap == GL_MIRRORED_REPEAT && 63 e->ARB_texture_mirrored_repeat) || 64 (wrap == GL_MIRROR_CLAMP_EXT && 65 (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) || 66 (wrap == GL_MIRROR_CLAMP_TO_EDGE_EXT && 67 (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) || 68 (wrap == GL_MIRROR_CLAMP_TO_BORDER_EXT && 69 (e->EXT_texture_mirror_clamp)))) { 70 /* non-rectangle texture */ 71 return GL_TRUE; 72 } 73 74 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap ); 75 return GL_FALSE; 76} 77 78 79/** 80 * Get current texture object for given target. 81 * Return NULL if any error. 82 * Note that this is different from _mesa_select_tex_object() in that proxy 83 * targets are not accepted. 84 */ 85static struct gl_texture_object * 86get_texobj(GLcontext *ctx, GLenum target) 87{ 88 struct gl_texture_unit *texUnit; 89 90 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) { 91 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameter(current unit)"); 92 return NULL; 93 } 94 95 texUnit = _mesa_get_current_tex_unit(ctx); 96 97 switch (target) { 98 case GL_TEXTURE_1D: 99 return texUnit->CurrentTex[TEXTURE_1D_INDEX]; 100 case GL_TEXTURE_2D: 101 return texUnit->CurrentTex[TEXTURE_2D_INDEX]; 102 case GL_TEXTURE_3D: 103 return texUnit->CurrentTex[TEXTURE_3D_INDEX]; 104 case GL_TEXTURE_CUBE_MAP: 105 if (ctx->Extensions.ARB_texture_cube_map) { 106 return texUnit->CurrentTex[TEXTURE_CUBE_INDEX]; 107 } 108 break; 109 case GL_TEXTURE_RECTANGLE_NV: 110 if (ctx->Extensions.NV_texture_rectangle) { 111 return texUnit->CurrentTex[TEXTURE_RECT_INDEX]; 112 } 113 break; 114 case GL_TEXTURE_1D_ARRAY_EXT: 115 if (ctx->Extensions.MESA_texture_array) { 116 return texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX]; 117 } 118 break; 119 case GL_TEXTURE_2D_ARRAY_EXT: 120 if (ctx->Extensions.MESA_texture_array) { 121 return texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX]; 122 } 123 break; 124 default: 125 ; 126 } 127 128 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(target)"); 129 return NULL; 130} 131 132 133/** 134 * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE. 135 * \return -1 if error. 136 */ 137static GLint 138comp_to_swizzle(GLenum comp) 139{ 140 switch (comp) { 141 case GL_RED: 142 return SWIZZLE_X; 143 case GL_GREEN: 144 return SWIZZLE_Y; 145 case GL_BLUE: 146 return SWIZZLE_Z; 147 case GL_ALPHA: 148 return SWIZZLE_W; 149 case GL_ZERO: 150 return SWIZZLE_ZERO; 151 case GL_ONE: 152 return SWIZZLE_ONE; 153 default: 154 return -1; 155 } 156} 157 158 159static void 160set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz) 161{ 162 ASSERT(comp < 4); 163 ASSERT(swz <= SWIZZLE_NIL); 164 { 165 GLuint mask = 0x7 << (3 * comp); 166 GLuint s = (*swizzle & ~mask) | (swz << (3 * comp)); 167 *swizzle = s; 168 } 169} 170 171 172/** 173 * This is called just prior to changing any texture object state. 174 * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE 175 * state flag and then mark the texture object as 'incomplete' so that any 176 * per-texture derived state gets recomputed. 177 */ 178static INLINE void 179flush(GLcontext *ctx, struct gl_texture_object *texObj) 180{ 181 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 182 texObj->_Complete = GL_FALSE; 183} 184 185 186/** 187 * Set an integer-valued texture parameter 188 * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise 189 */ 190static GLboolean 191set_tex_parameteri(GLcontext *ctx, 192 struct gl_texture_object *texObj, 193 GLenum pname, const GLint *params) 194{ 195 switch (pname) { 196 case GL_TEXTURE_MIN_FILTER: 197 if (texObj->MinFilter == params[0]) 198 return GL_FALSE; 199 switch (params[0]) { 200 case GL_NEAREST: 201 case GL_LINEAR: 202 flush(ctx, texObj); 203 texObj->MinFilter = params[0]; 204 return GL_TRUE; 205 case GL_NEAREST_MIPMAP_NEAREST: 206 case GL_LINEAR_MIPMAP_NEAREST: 207 case GL_NEAREST_MIPMAP_LINEAR: 208 case GL_LINEAR_MIPMAP_LINEAR: 209 if (texObj->Target != GL_TEXTURE_RECTANGLE_NV) { 210 flush(ctx, texObj); 211 texObj->MinFilter = params[0]; 212 return GL_TRUE; 213 } 214 /* fall-through */ 215 default: 216 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", 217 params[0] ); 218 } 219 return GL_FALSE; 220 221 case GL_TEXTURE_MAG_FILTER: 222 if (texObj->MagFilter == params[0]) 223 return GL_FALSE; 224 switch (params[0]) { 225 case GL_NEAREST: 226 case GL_LINEAR: 227 flush(ctx, texObj); 228 texObj->MagFilter = params[0]; 229 return GL_TRUE; 230 default: 231 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", 232 params[0]); 233 } 234 return GL_FALSE; 235 236 case GL_TEXTURE_WRAP_S: 237 if (texObj->WrapS == params[0]) 238 return GL_FALSE; 239 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { 240 flush(ctx, texObj); 241 texObj->WrapS = params[0]; 242 return GL_TRUE; 243 } 244 return GL_FALSE; 245 246 case GL_TEXTURE_WRAP_T: 247 if (texObj->WrapT == params[0]) 248 return GL_FALSE; 249 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { 250 flush(ctx, texObj); 251 texObj->WrapT = params[0]; 252 return GL_TRUE; 253 } 254 return GL_FALSE; 255 256 case GL_TEXTURE_WRAP_R: 257 if (texObj->WrapR == params[0]) 258 return GL_FALSE; 259 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { 260 flush(ctx, texObj); 261 texObj->WrapR = params[0]; 262 return GL_TRUE; 263 } 264 return GL_FALSE; 265 266 case GL_TEXTURE_BASE_LEVEL: 267 if (texObj->BaseLevel == params[0]) 268 return GL_FALSE; 269 if (params[0] < 0 || 270 (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0)) { 271 _mesa_error(ctx, GL_INVALID_VALUE, 272 "glTexParameter(param=%d)", params[0]); 273 return GL_FALSE; 274 } 275 flush(ctx, texObj); 276 texObj->BaseLevel = params[0]; 277 return GL_TRUE; 278 279 case GL_TEXTURE_MAX_LEVEL: 280 if (texObj->MaxLevel == params[0]) 281 return GL_FALSE; 282 if (params[0] < 0 || texObj->Target == GL_TEXTURE_RECTANGLE_ARB) { 283 _mesa_error(ctx, GL_INVALID_OPERATION, 284 "glTexParameter(param=%d)", params[0]); 285 return GL_FALSE; 286 } 287 flush(ctx, texObj); 288 texObj->MaxLevel = params[0]; 289 return GL_TRUE; 290 291 case GL_GENERATE_MIPMAP_SGIS: 292 if (ctx->Extensions.SGIS_generate_mipmap) { 293 if (texObj->GenerateMipmap != params[0]) { 294 flush(ctx, texObj); 295 texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE; 296 return GL_TRUE; 297 } 298 return GL_FALSE; 299 } 300 else { 301 _mesa_error(ctx, GL_INVALID_ENUM, 302 "glTexParameter(pname=GL_GENERATE_MIPMAP_SGIS)"); 303 } 304 return GL_FALSE; 305 306 case GL_TEXTURE_COMPARE_MODE_ARB: 307 if (ctx->Extensions.ARB_shadow && 308 (params[0] == GL_NONE || 309 params[0] == GL_COMPARE_R_TO_TEXTURE_ARB)) { 310 if (texObj->CompareMode != params[0]) { 311 flush(ctx, texObj); 312 texObj->CompareMode = params[0]; 313 return GL_TRUE; 314 } 315 return GL_FALSE; 316 } 317 else { 318 _mesa_error(ctx, GL_INVALID_ENUM, 319 "glTexParameter(GL_TEXTURE_COMPARE_MODE_ARB)"); 320 } 321 return GL_FALSE; 322 323 case GL_TEXTURE_COMPARE_FUNC_ARB: 324 if (ctx->Extensions.ARB_shadow) { 325 if (texObj->CompareFunc == params[0]) 326 return GL_FALSE; 327 switch (params[0]) { 328 case GL_LEQUAL: 329 case GL_GEQUAL: 330 flush(ctx, texObj); 331 texObj->CompareFunc = params[0]; 332 return GL_TRUE; 333 case GL_EQUAL: 334 case GL_NOTEQUAL: 335 case GL_LESS: 336 case GL_GREATER: 337 case GL_ALWAYS: 338 case GL_NEVER: 339 if (ctx->Extensions.EXT_shadow_funcs) { 340 flush(ctx, texObj); 341 texObj->CompareFunc = params[0]; 342 return GL_TRUE; 343 } 344 /* fall-through */ 345 default: 346 _mesa_error(ctx, GL_INVALID_ENUM, 347 "glTexParameter(GL_TEXTURE_COMPARE_FUNC_ARB)"); 348 } 349 } 350 else { 351 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname); 352 } 353 return GL_FALSE; 354 355 case GL_DEPTH_TEXTURE_MODE_ARB: 356 if (ctx->Extensions.ARB_depth_texture && 357 (params[0] == GL_LUMINANCE || 358 params[0] == GL_INTENSITY || 359 params[0] == GL_ALPHA)) { 360 if (texObj->DepthMode != params[0]) { 361 flush(ctx, texObj); 362 texObj->DepthMode = params[0]; 363 return GL_TRUE; 364 } 365 } 366 else { 367 _mesa_error(ctx, GL_INVALID_ENUM, 368 "glTexParameter(GL_DEPTH_TEXTURE_MODE_ARB)"); 369 } 370 return GL_FALSE; 371 372#ifdef FEATURE_OES_draw_texture 373 case GL_TEXTURE_CROP_RECT_OES: 374 texObj->CropRect[0] = params[0]; 375 texObj->CropRect[1] = params[1]; 376 texObj->CropRect[2] = params[2]; 377 texObj->CropRect[3] = params[3]; 378 return GL_TRUE; 379#endif 380 381 case GL_TEXTURE_SWIZZLE_R_EXT: 382 case GL_TEXTURE_SWIZZLE_G_EXT: 383 case GL_TEXTURE_SWIZZLE_B_EXT: 384 case GL_TEXTURE_SWIZZLE_A_EXT: 385 if (ctx->Extensions.EXT_texture_swizzle) { 386 const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT; 387 const GLint swz = comp_to_swizzle(params[0]); 388 if (swz < 0) { 389 _mesa_error(ctx, GL_INVALID_OPERATION, 390 "glTexParameter(swizzle 0x%x)", params[0]); 391 return GL_FALSE; 392 } 393 ASSERT(comp < 4); 394 if (swz >= 0) { 395 flush(ctx, texObj); 396 texObj->Swizzle[comp] = params[0]; 397 set_swizzle_component(&texObj->_Swizzle, comp, swz); 398 return GL_TRUE; 399 } 400 } 401 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname); 402 return GL_FALSE; 403 404 case GL_TEXTURE_SWIZZLE_RGBA_EXT: 405 if (ctx->Extensions.EXT_texture_swizzle) { 406 GLuint comp; 407 flush(ctx, texObj); 408 for (comp = 0; comp < 4; comp++) { 409 const GLint swz = comp_to_swizzle(params[comp]); 410 if (swz >= 0) { 411 texObj->Swizzle[comp] = params[comp]; 412 set_swizzle_component(&texObj->_Swizzle, comp, swz); 413 } 414 else { 415 _mesa_error(ctx, GL_INVALID_OPERATION, 416 "glTexParameter(swizzle 0x%x)", params[comp]); 417 return GL_FALSE; 418 } 419 } 420 return GL_TRUE; 421 } 422 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname); 423 return GL_FALSE; 424 425 default: 426 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname); 427 } 428 return GL_FALSE; 429} 430 431 432/** 433 * Set a float-valued texture parameter 434 * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise 435 */ 436static GLboolean 437set_tex_parameterf(GLcontext *ctx, 438 struct gl_texture_object *texObj, 439 GLenum pname, const GLfloat *params) 440{ 441 switch (pname) { 442 case GL_TEXTURE_MIN_LOD: 443 if (texObj->MinLod == params[0]) 444 return GL_FALSE; 445 flush(ctx, texObj); 446 texObj->MinLod = params[0]; 447 return GL_TRUE; 448 449 case GL_TEXTURE_MAX_LOD: 450 if (texObj->MaxLod == params[0]) 451 return GL_FALSE; 452 flush(ctx, texObj); 453 texObj->MaxLod = params[0]; 454 return GL_TRUE; 455 456 case GL_TEXTURE_PRIORITY: 457 flush(ctx, texObj); 458 texObj->Priority = CLAMP(params[0], 0.0F, 1.0F); 459 return GL_TRUE; 460 461 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 462 if (ctx->Extensions.EXT_texture_filter_anisotropic) { 463 if (texObj->MaxAnisotropy == params[0]) 464 return GL_FALSE; 465 if (params[0] < 1.0) { 466 _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); 467 return GL_FALSE; 468 } 469 flush(ctx, texObj); 470 /* clamp to max, that's what NVIDIA does */ 471 texObj->MaxAnisotropy = MIN2(params[0], 472 ctx->Const.MaxTextureMaxAnisotropy); 473 return GL_TRUE; 474 } 475 else { 476 static GLuint count = 0; 477 if (count++ < 10) 478 _mesa_error(ctx, GL_INVALID_ENUM, 479 "glTexParameter(pname=GL_TEXTURE_MAX_ANISOTROPY_EXT)"); 480 } 481 return GL_FALSE; 482 483 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: 484 if (ctx->Extensions.ARB_shadow_ambient) { 485 if (texObj->CompareFailValue != params[0]) { 486 flush(ctx, texObj); 487 texObj->CompareFailValue = CLAMP(params[0], 0.0F, 1.0F); 488 return GL_TRUE; 489 } 490 } 491 else { 492 _mesa_error(ctx, GL_INVALID_ENUM, 493 "glTexParameter(pname=GL_TEXTURE_COMPARE_FAIL_VALUE_ARB)"); 494 } 495 return GL_FALSE; 496 497 case GL_TEXTURE_LOD_BIAS: 498 /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias */ 499 if (ctx->Extensions.EXT_texture_lod_bias) { 500 if (texObj->LodBias != params[0]) { 501 flush(ctx, texObj); 502 texObj->LodBias = params[0]; 503 return GL_TRUE; 504 } 505 return GL_FALSE; 506 } 507 break; 508 509 case GL_TEXTURE_BORDER_COLOR: 510 flush(ctx, texObj); 511 texObj->BorderColor[RCOMP] = params[0]; 512 texObj->BorderColor[GCOMP] = params[1]; 513 texObj->BorderColor[BCOMP] = params[2]; 514 texObj->BorderColor[ACOMP] = params[3]; 515 return GL_TRUE; 516 517 default: 518 _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname=0x%x)", pname); 519 } 520 return GL_FALSE; 521} 522 523 524void GLAPIENTRY 525_mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) 526{ 527 GLboolean need_update; 528 struct gl_texture_object *texObj; 529 GET_CURRENT_CONTEXT(ctx); 530 ASSERT_OUTSIDE_BEGIN_END(ctx); 531 532 texObj = get_texobj(ctx, target); 533 if (!texObj) 534 return; 535 536 switch (pname) { 537 case GL_TEXTURE_MIN_FILTER: 538 case GL_TEXTURE_MAG_FILTER: 539 case GL_TEXTURE_WRAP_S: 540 case GL_TEXTURE_WRAP_T: 541 case GL_TEXTURE_WRAP_R: 542 case GL_TEXTURE_BASE_LEVEL: 543 case GL_TEXTURE_MAX_LEVEL: 544 case GL_GENERATE_MIPMAP_SGIS: 545 case GL_TEXTURE_COMPARE_MODE_ARB: 546 case GL_TEXTURE_COMPARE_FUNC_ARB: 547 case GL_DEPTH_TEXTURE_MODE_ARB: 548 { 549 /* convert float param to int */ 550 GLint p = (GLint) param; 551 need_update = set_tex_parameteri(ctx, texObj, pname, &p); 552 } 553 break; 554 default: 555 /* this will generate an error if pname is illegal */ 556 need_update = set_tex_parameterf(ctx, texObj, pname, ¶m); 557 } 558 559 if (ctx->Driver.TexParameter && need_update) { 560 ctx->Driver.TexParameter(ctx, target, texObj, pname, ¶m); 561 } 562} 563 564 565void GLAPIENTRY 566_mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) 567{ 568 GLboolean need_update; 569 struct gl_texture_object *texObj; 570 GET_CURRENT_CONTEXT(ctx); 571 ASSERT_OUTSIDE_BEGIN_END(ctx); 572 573 texObj = get_texobj(ctx, target); 574 if (!texObj) 575 return; 576 577 switch (pname) { 578 case GL_TEXTURE_MIN_FILTER: 579 case GL_TEXTURE_MAG_FILTER: 580 case GL_TEXTURE_WRAP_S: 581 case GL_TEXTURE_WRAP_T: 582 case GL_TEXTURE_WRAP_R: 583 case GL_TEXTURE_BASE_LEVEL: 584 case GL_TEXTURE_MAX_LEVEL: 585 case GL_GENERATE_MIPMAP_SGIS: 586 case GL_TEXTURE_COMPARE_MODE_ARB: 587 case GL_TEXTURE_COMPARE_FUNC_ARB: 588 case GL_DEPTH_TEXTURE_MODE_ARB: 589 { 590 /* convert float param to int */ 591 GLint p = (GLint) params[0]; 592 need_update = set_tex_parameteri(ctx, texObj, pname, &p); 593 } 594 break; 595 596#ifdef FEATURE_OES_draw_texture 597 case GL_TEXTURE_CROP_RECT_OES: 598 { 599 /* convert float params to int */ 600 GLint iparams[4]; 601 iparams[0] = (GLint) params[0]; 602 iparams[1] = (GLint) params[1]; 603 iparams[2] = (GLint) params[2]; 604 iparams[3] = (GLint) params[3]; 605 need_update = set_tex_parameteri(ctx, texObj, pname, iparams); 606 } 607 break; 608#endif 609 610 default: 611 /* this will generate an error if pname is illegal */ 612 need_update = set_tex_parameterf(ctx, texObj, pname, params); 613 } 614 615 if (ctx->Driver.TexParameter && need_update) { 616 ctx->Driver.TexParameter(ctx, target, texObj, pname, params); 617 } 618} 619 620 621void GLAPIENTRY 622_mesa_TexParameteri(GLenum target, GLenum pname, GLint param) 623{ 624 GLboolean need_update; 625 struct gl_texture_object *texObj; 626 GET_CURRENT_CONTEXT(ctx); 627 ASSERT_OUTSIDE_BEGIN_END(ctx); 628 629 texObj = get_texobj(ctx, target); 630 if (!texObj) 631 return; 632 633 switch (pname) { 634 case GL_TEXTURE_MIN_LOD: 635 case GL_TEXTURE_MAX_LOD: 636 case GL_TEXTURE_PRIORITY: 637 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 638 case GL_TEXTURE_LOD_BIAS: 639 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: 640 { 641 GLfloat fparam = (GLfloat) param; 642 /* convert int param to float */ 643 need_update = set_tex_parameterf(ctx, texObj, pname, &fparam); 644 } 645 break; 646 default: 647 /* this will generate an error if pname is illegal */ 648 need_update = set_tex_parameteri(ctx, texObj, pname, ¶m); 649 } 650 651 if (ctx->Driver.TexParameter && need_update) { 652 GLfloat fparam = (GLfloat) param; 653 ctx->Driver.TexParameter(ctx, target, texObj, pname, &fparam); 654 } 655} 656 657 658void GLAPIENTRY 659_mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) 660{ 661 GLboolean need_update; 662 struct gl_texture_object *texObj; 663 GET_CURRENT_CONTEXT(ctx); 664 ASSERT_OUTSIDE_BEGIN_END(ctx); 665 666 texObj = get_texobj(ctx, target); 667 if (!texObj) 668 return; 669 670 switch (pname) { 671 case GL_TEXTURE_BORDER_COLOR: 672 { 673 /* convert int params to float */ 674 GLfloat fparams[4]; 675 fparams[0] = INT_TO_FLOAT(params[0]); 676 fparams[1] = INT_TO_FLOAT(params[1]); 677 fparams[2] = INT_TO_FLOAT(params[2]); 678 fparams[3] = INT_TO_FLOAT(params[3]); 679 need_update = set_tex_parameterf(ctx, texObj, pname, fparams); 680 } 681 break; 682 case GL_TEXTURE_MIN_LOD: 683 case GL_TEXTURE_MAX_LOD: 684 case GL_TEXTURE_PRIORITY: 685 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 686 case GL_TEXTURE_LOD_BIAS: 687 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: 688 { 689 /* convert int param to float */ 690 GLfloat fparam = (GLfloat) params[0]; 691 need_update = set_tex_parameterf(ctx, texObj, pname, &fparam); 692 } 693 break; 694 default: 695 /* this will generate an error if pname is illegal */ 696 need_update = set_tex_parameteri(ctx, texObj, pname, params); 697 } 698 699 if (ctx->Driver.TexParameter && need_update) { 700 GLfloat fparams[4]; 701 fparams[0] = INT_TO_FLOAT(params[0]); 702 if (pname == GL_TEXTURE_BORDER_COLOR || 703 pname == GL_TEXTURE_CROP_RECT_OES) { 704 fparams[1] = INT_TO_FLOAT(params[1]); 705 fparams[2] = INT_TO_FLOAT(params[2]); 706 fparams[3] = INT_TO_FLOAT(params[3]); 707 } 708 ctx->Driver.TexParameter(ctx, target, texObj, pname, fparams); 709 } 710} 711 712 713void GLAPIENTRY 714_mesa_GetTexLevelParameterfv( GLenum target, GLint level, 715 GLenum pname, GLfloat *params ) 716{ 717 GLint iparam; 718 _mesa_GetTexLevelParameteriv( target, level, pname, &iparam ); 719 *params = (GLfloat) iparam; 720} 721 722 723void GLAPIENTRY 724_mesa_GetTexLevelParameteriv( GLenum target, GLint level, 725 GLenum pname, GLint *params ) 726{ 727 const struct gl_texture_unit *texUnit; 728 struct gl_texture_object *texObj; 729 const struct gl_texture_image *img = NULL; 730 GLboolean isProxy; 731 GLint maxLevels; 732 gl_format texFormat; 733 GET_CURRENT_CONTEXT(ctx); 734 ASSERT_OUTSIDE_BEGIN_END(ctx); 735 736 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) { 737 _mesa_error(ctx, GL_INVALID_OPERATION, 738 "glGetTexLevelParameteriv(current unit)"); 739 return; 740 } 741 742 texUnit = _mesa_get_current_tex_unit(ctx); 743 744 /* this will catch bad target values */ 745 maxLevels = _mesa_max_texture_levels(ctx, target); 746 if (maxLevels == 0) { 747 _mesa_error(ctx, GL_INVALID_ENUM, 748 "glGetTexLevelParameter[if]v(target=0x%x)", target); 749 return; 750 } 751 752 if (level < 0 || level >= maxLevels) { 753 _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexLevelParameter[if]v" ); 754 return; 755 } 756 757 texObj = _mesa_select_tex_object(ctx, texUnit, target); 758 _mesa_lock_texture(ctx, texObj); 759 760 img = _mesa_select_tex_image(ctx, texObj, target, level); 761 if (!img || !img->TexFormat) { 762 /* undefined texture image */ 763 if (pname == GL_TEXTURE_COMPONENTS) 764 *params = 1; 765 else 766 *params = 0; 767 goto out; 768 } 769 770 texFormat = img->TexFormat; 771 772 isProxy = _mesa_is_proxy_texture(target); 773 774 switch (pname) { 775 case GL_TEXTURE_WIDTH: 776 *params = img->Width; 777 break; 778 case GL_TEXTURE_HEIGHT: 779 *params = img->Height; 780 break; 781 case GL_TEXTURE_DEPTH: 782 *params = img->Depth; 783 break; 784 case GL_TEXTURE_INTERNAL_FORMAT: 785 if (_mesa_is_format_compressed(img->TexFormat)) { 786 /* need to return the actual compressed format */ 787 *params = _mesa_compressed_format_to_glenum(ctx, img->TexFormat); 788 } 789 else { 790 /* return the user's requested internal format */ 791 *params = img->InternalFormat; 792 } 793 break; 794 case GL_TEXTURE_BORDER: 795 *params = img->Border; 796 break; 797 case GL_TEXTURE_RED_SIZE: 798 case GL_TEXTURE_GREEN_SIZE: 799 case GL_TEXTURE_BLUE_SIZE: 800 if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) 801 *params = _mesa_get_format_bits(texFormat, pname); 802 else 803 *params = 0; 804 break; 805 case GL_TEXTURE_ALPHA_SIZE: 806 if (img->_BaseFormat == GL_ALPHA || 807 img->_BaseFormat == GL_LUMINANCE_ALPHA || 808 img->_BaseFormat == GL_RGBA) 809 *params = _mesa_get_format_bits(texFormat, pname); 810 else 811 *params = 0; 812 break; 813 case GL_TEXTURE_INTENSITY_SIZE: 814 if (img->_BaseFormat != GL_INTENSITY) 815 *params = 0; 816 else { 817 *params = _mesa_get_format_bits(texFormat, pname); 818 if (*params == 0) { 819 /* intensity probably stored as rgb texture */ 820 *params = MIN2(_mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE), 821 _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE)); 822 } 823 } 824 break; 825 case GL_TEXTURE_LUMINANCE_SIZE: 826 if (img->_BaseFormat != GL_LUMINANCE && 827 img->_BaseFormat != GL_LUMINANCE_ALPHA) 828 *params = 0; 829 else { 830 *params = _mesa_get_format_bits(texFormat, pname); 831 if (*params == 0) { 832 /* luminance probably stored as rgb texture */ 833 *params = MIN2(_mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE), 834 _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE)); 835 } 836 } 837 break; 838 case GL_TEXTURE_INDEX_SIZE_EXT: 839 if (img->_BaseFormat == GL_COLOR_INDEX) 840 *params = _mesa_get_format_bits(texFormat, pname); 841 else 842 *params = 0; 843 break; 844 case GL_TEXTURE_DEPTH_SIZE_ARB: 845 if (ctx->Extensions.ARB_depth_texture) 846 *params = _mesa_get_format_bits(texFormat, pname); 847 else 848 _mesa_error(ctx, GL_INVALID_ENUM, 849 "glGetTexLevelParameter[if]v(pname)"); 850 break; 851 case GL_TEXTURE_STENCIL_SIZE_EXT: 852 if (ctx->Extensions.EXT_packed_depth_stencil || 853 ctx->Extensions.ARB_framebuffer_object) { 854 *params = _mesa_get_format_bits(texFormat, pname); 855 } 856 else { 857 _mesa_error(ctx, GL_INVALID_ENUM, 858 "glGetTexLevelParameter[if]v(pname)"); 859 } 860 break; 861 862 /* GL_ARB_texture_compression */ 863 case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: 864 if (_mesa_is_format_compressed(img->TexFormat) && !isProxy) { 865 *params = _mesa_format_image_size(texFormat, img->Width, 866 img->Height, img->Depth); 867 } 868 else { 869 _mesa_error(ctx, GL_INVALID_OPERATION, 870 "glGetTexLevelParameter[if]v(pname)"); 871 } 872 break; 873 case GL_TEXTURE_COMPRESSED: 874 *params = (GLint) _mesa_is_format_compressed(img->TexFormat); 875 break; 876 877 /* GL_ARB_texture_float */ 878 case GL_TEXTURE_RED_TYPE_ARB: 879 if (ctx->Extensions.ARB_texture_float) { 880 *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_RED_SIZE) ? 881 _mesa_get_format_datatype(texFormat) : GL_NONE; 882 } 883 else { 884 _mesa_error(ctx, GL_INVALID_ENUM, 885 "glGetTexLevelParameter[if]v(pname)"); 886 } 887 break; 888 case GL_TEXTURE_GREEN_TYPE_ARB: 889 if (ctx->Extensions.ARB_texture_float) { 890 *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_GREEN_SIZE) ? 891 _mesa_get_format_datatype(texFormat) : GL_NONE; 892 } 893 else { 894 _mesa_error(ctx, GL_INVALID_ENUM, 895 "glGetTexLevelParameter[if]v(pname)"); 896 } 897 break; 898 case GL_TEXTURE_BLUE_TYPE_ARB: 899 if (ctx->Extensions.ARB_texture_float) { 900 *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_BLUE_SIZE) ? 901 _mesa_get_format_datatype(texFormat) : GL_NONE; 902 } 903 else { 904 _mesa_error(ctx, GL_INVALID_ENUM, 905 "glGetTexLevelParameter[if]v(pname)"); 906 } 907 break; 908 case GL_TEXTURE_ALPHA_TYPE_ARB: 909 if (ctx->Extensions.ARB_texture_float) { 910 *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_ALPHA_SIZE) ? 911 _mesa_get_format_datatype(texFormat) : GL_NONE; 912 } 913 else { 914 _mesa_error(ctx, GL_INVALID_ENUM, 915 "glGetTexLevelParameter[if]v(pname)"); 916 } 917 break; 918 case GL_TEXTURE_LUMINANCE_TYPE_ARB: 919 if (ctx->Extensions.ARB_texture_float) { 920 *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_LUMINANCE_SIZE) ? 921 _mesa_get_format_datatype(texFormat) : GL_NONE; 922 } 923 else { 924 _mesa_error(ctx, GL_INVALID_ENUM, 925 "glGetTexLevelParameter[if]v(pname)"); 926 } 927 break; 928 case GL_TEXTURE_INTENSITY_TYPE_ARB: 929 if (ctx->Extensions.ARB_texture_float) { 930 *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_INTENSITY_SIZE) ? 931 _mesa_get_format_datatype(texFormat) : GL_NONE; 932 } 933 else { 934 _mesa_error(ctx, GL_INVALID_ENUM, 935 "glGetTexLevelParameter[if]v(pname)"); 936 } 937 break; 938 case GL_TEXTURE_DEPTH_TYPE_ARB: 939 if (ctx->Extensions.ARB_texture_float) { 940 *params = _mesa_get_format_bits(texFormat, GL_TEXTURE_DEPTH_SIZE) ? 941 _mesa_get_format_datatype(texFormat) : GL_NONE; 942 } 943 else { 944 _mesa_error(ctx, GL_INVALID_ENUM, 945 "glGetTexLevelParameter[if]v(pname)"); 946 } 947 break; 948 949 default: 950 _mesa_error(ctx, GL_INVALID_ENUM, 951 "glGetTexLevelParameter[if]v(pname)"); 952 } 953 954 out: 955 _mesa_unlock_texture(ctx, texObj); 956} 957 958 959 960void GLAPIENTRY 961_mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) 962{ 963 struct gl_texture_unit *texUnit; 964 struct gl_texture_object *obj; 965 GLboolean error = GL_FALSE; 966 GET_CURRENT_CONTEXT(ctx); 967 ASSERT_OUTSIDE_BEGIN_END(ctx); 968 969 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) { 970 _mesa_error(ctx, GL_INVALID_OPERATION, 971 "glGetTexParameterfv(current unit)"); 972 return; 973 } 974 975 texUnit = _mesa_get_current_tex_unit(ctx); 976 977 obj = _mesa_select_tex_object(ctx, texUnit, target); 978 if (!obj) { 979 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)"); 980 return; 981 } 982 983 _mesa_lock_texture(ctx, obj); 984 switch (pname) { 985 case GL_TEXTURE_MAG_FILTER: 986 *params = ENUM_TO_FLOAT(obj->MagFilter); 987 break; 988 case GL_TEXTURE_MIN_FILTER: 989 *params = ENUM_TO_FLOAT(obj->MinFilter); 990 break; 991 case GL_TEXTURE_WRAP_S: 992 *params = ENUM_TO_FLOAT(obj->WrapS); 993 break; 994 case GL_TEXTURE_WRAP_T: 995 *params = ENUM_TO_FLOAT(obj->WrapT); 996 break; 997 case GL_TEXTURE_WRAP_R: 998 *params = ENUM_TO_FLOAT(obj->WrapR); 999 break; 1000 case GL_TEXTURE_BORDER_COLOR: 1001 params[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F); 1002 params[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F); 1003 params[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F); 1004 params[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F); 1005 break; 1006 case GL_TEXTURE_RESIDENT: 1007 { 1008 GLboolean resident; 1009 if (ctx->Driver.IsTextureResident) 1010 resident = ctx->Driver.IsTextureResident(ctx, obj); 1011 else 1012 resident = GL_TRUE; 1013 *params = ENUM_TO_FLOAT(resident); 1014 } 1015 break; 1016 case GL_TEXTURE_PRIORITY: 1017 *params = obj->Priority; 1018 break; 1019 case GL_TEXTURE_MIN_LOD: 1020 *params = obj->MinLod; 1021 break; 1022 case GL_TEXTURE_MAX_LOD: 1023 *params = obj->MaxLod; 1024 break; 1025 case GL_TEXTURE_BASE_LEVEL: 1026 *params = (GLfloat) obj->BaseLevel; 1027 break; 1028 case GL_TEXTURE_MAX_LEVEL: 1029 *params = (GLfloat) obj->MaxLevel; 1030 break; 1031 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1032 if (ctx->Extensions.EXT_texture_filter_anisotropic) { 1033 *params = obj->MaxAnisotropy; 1034 } 1035 else 1036 error = GL_TRUE; 1037 break; 1038 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: 1039 if (ctx->Extensions.ARB_shadow_ambient) { 1040 *params = obj->CompareFailValue; 1041 } 1042 else 1043 error = GL_TRUE; 1044 break; 1045 case GL_GENERATE_MIPMAP_SGIS: 1046 if (ctx->Extensions.SGIS_generate_mipmap) { 1047 *params = (GLfloat) obj->GenerateMipmap; 1048 } 1049 else 1050 error = GL_TRUE; 1051 break; 1052 case GL_TEXTURE_COMPARE_MODE_ARB: 1053 if (ctx->Extensions.ARB_shadow) { 1054 *params = (GLfloat) obj->CompareMode; 1055 } 1056 else 1057 error = GL_TRUE; 1058 break; 1059 case GL_TEXTURE_COMPARE_FUNC_ARB: 1060 if (ctx->Extensions.ARB_shadow) { 1061 *params = (GLfloat) obj->CompareFunc; 1062 } 1063 else 1064 error = GL_TRUE; 1065 break; 1066 case GL_DEPTH_TEXTURE_MODE_ARB: 1067 if (ctx->Extensions.ARB_depth_texture) { 1068 *params = (GLfloat) obj->DepthMode; 1069 } 1070 else 1071 error = GL_TRUE; 1072 break; 1073 case GL_TEXTURE_LOD_BIAS: 1074 if (ctx->Extensions.EXT_texture_lod_bias) { 1075 *params = obj->LodBias; 1076 } 1077 else 1078 error = GL_TRUE; 1079 break; 1080#ifdef FEATURE_OES_draw_texture 1081 case GL_TEXTURE_CROP_RECT_OES: 1082 params[0] = obj->CropRect[0]; 1083 params[1] = obj->CropRect[1]; 1084 params[2] = obj->CropRect[2]; 1085 params[3] = obj->CropRect[3]; 1086 break; 1087#endif 1088 1089 case GL_TEXTURE_SWIZZLE_R_EXT: 1090 case GL_TEXTURE_SWIZZLE_G_EXT: 1091 case GL_TEXTURE_SWIZZLE_B_EXT: 1092 case GL_TEXTURE_SWIZZLE_A_EXT: 1093 if (ctx->Extensions.EXT_texture_swizzle) { 1094 GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT; 1095 *params = (GLfloat) obj->Swizzle[comp]; 1096 } 1097 else { 1098 error = GL_TRUE; 1099 } 1100 break; 1101 1102 case GL_TEXTURE_SWIZZLE_RGBA_EXT: 1103 if (ctx->Extensions.EXT_texture_swizzle) { 1104 GLuint comp; 1105 for (comp = 0; comp < 4; comp++) { 1106 params[comp] = (GLfloat) obj->Swizzle[comp]; 1107 } 1108 } 1109 else { 1110 error = GL_TRUE; 1111 } 1112 break; 1113 1114 default: 1115 error = GL_TRUE; 1116 break; 1117 } 1118 1119 if (error) 1120 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(pname=0x%x)", 1121 pname); 1122 1123 _mesa_unlock_texture(ctx, obj); 1124} 1125 1126 1127void GLAPIENTRY 1128_mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) 1129{ 1130 struct gl_texture_unit *texUnit; 1131 struct gl_texture_object *obj; 1132 GLboolean error = GL_FALSE; 1133 GET_CURRENT_CONTEXT(ctx); 1134 ASSERT_OUTSIDE_BEGIN_END(ctx); 1135 1136 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) { 1137 _mesa_error(ctx, GL_INVALID_OPERATION, 1138 "glGetTexParameteriv(current unit)"); 1139 return; 1140 } 1141 1142 texUnit = _mesa_get_current_tex_unit(ctx); 1143 1144 obj = _mesa_select_tex_object(ctx, texUnit, target); 1145 if (!obj) { 1146 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(target)"); 1147 return; 1148 } 1149 1150 switch (pname) { 1151 case GL_TEXTURE_MAG_FILTER: 1152 *params = (GLint) obj->MagFilter; 1153 break;; 1154 case GL_TEXTURE_MIN_FILTER: 1155 *params = (GLint) obj->MinFilter; 1156 break;; 1157 case GL_TEXTURE_WRAP_S: 1158 *params = (GLint) obj->WrapS; 1159 break;; 1160 case GL_TEXTURE_WRAP_T: 1161 *params = (GLint) obj->WrapT; 1162 break;; 1163 case GL_TEXTURE_WRAP_R: 1164 *params = (GLint) obj->WrapR; 1165 break;; 1166 case GL_TEXTURE_BORDER_COLOR: 1167 { 1168 GLfloat b[4]; 1169 b[0] = CLAMP(obj->BorderColor[0], 0.0F, 1.0F); 1170 b[1] = CLAMP(obj->BorderColor[1], 0.0F, 1.0F); 1171 b[2] = CLAMP(obj->BorderColor[2], 0.0F, 1.0F); 1172 b[3] = CLAMP(obj->BorderColor[3], 0.0F, 1.0F); 1173 params[0] = FLOAT_TO_INT(b[0]); 1174 params[1] = FLOAT_TO_INT(b[1]); 1175 params[2] = FLOAT_TO_INT(b[2]); 1176 params[3] = FLOAT_TO_INT(b[3]); 1177 } 1178 break;; 1179 case GL_TEXTURE_RESIDENT: 1180 { 1181 GLboolean resident; 1182 if (ctx->Driver.IsTextureResident) 1183 resident = ctx->Driver.IsTextureResident(ctx, obj); 1184 else 1185 resident = GL_TRUE; 1186 *params = (GLint) resident; 1187 } 1188 break;; 1189 case GL_TEXTURE_PRIORITY: 1190 *params = FLOAT_TO_INT(obj->Priority); 1191 break;; 1192 case GL_TEXTURE_MIN_LOD: 1193 *params = (GLint) obj->MinLod; 1194 break;; 1195 case GL_TEXTURE_MAX_LOD: 1196 *params = (GLint) obj->MaxLod; 1197 break;; 1198 case GL_TEXTURE_BASE_LEVEL: 1199 *params = obj->BaseLevel; 1200 break;; 1201 case GL_TEXTURE_MAX_LEVEL: 1202 *params = obj->MaxLevel; 1203 break;; 1204 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1205 if (ctx->Extensions.EXT_texture_filter_anisotropic) { 1206 *params = (GLint) obj->MaxAnisotropy; 1207 } 1208 else { 1209 error = GL_TRUE; 1210 } 1211 break; 1212 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: 1213 if (ctx->Extensions.ARB_shadow_ambient) { 1214 *params = (GLint) FLOAT_TO_INT(obj->CompareFailValue); 1215 } 1216 else { 1217 error = GL_TRUE; 1218 } 1219 break; 1220 case GL_GENERATE_MIPMAP_SGIS: 1221 if (ctx->Extensions.SGIS_generate_mipmap) { 1222 *params = (GLint) obj->GenerateMipmap; 1223 } 1224 else { 1225 error = GL_TRUE; 1226 } 1227 break; 1228 case GL_TEXTURE_COMPARE_MODE_ARB: 1229 if (ctx->Extensions.ARB_shadow) { 1230 *params = (GLint) obj->CompareMode; 1231 } 1232 else { 1233 error = GL_TRUE; 1234 } 1235 break; 1236 case GL_TEXTURE_COMPARE_FUNC_ARB: 1237 if (ctx->Extensions.ARB_shadow) { 1238 *params = (GLint) obj->CompareFunc; 1239 } 1240 else { 1241 error = GL_TRUE; 1242 } 1243 break; 1244 case GL_DEPTH_TEXTURE_MODE_ARB: 1245 if (ctx->Extensions.ARB_depth_texture) { 1246 *params = (GLint) obj->DepthMode; 1247 } 1248 else { 1249 error = GL_TRUE; 1250 } 1251 break; 1252 case GL_TEXTURE_LOD_BIAS: 1253 if (ctx->Extensions.EXT_texture_lod_bias) { 1254 *params = (GLint) obj->LodBias; 1255 } 1256 else { 1257 error = GL_TRUE; 1258 } 1259 break; 1260#ifdef FEATURE_OES_draw_texture 1261 case GL_TEXTURE_CROP_RECT_OES: 1262 params[0] = obj->CropRect[0]; 1263 params[1] = obj->CropRect[1]; 1264 params[2] = obj->CropRect[2]; 1265 params[3] = obj->CropRect[3]; 1266 break; 1267#endif 1268 case GL_TEXTURE_SWIZZLE_R_EXT: 1269 case GL_TEXTURE_SWIZZLE_G_EXT: 1270 case GL_TEXTURE_SWIZZLE_B_EXT: 1271 case GL_TEXTURE_SWIZZLE_A_EXT: 1272 if (ctx->Extensions.EXT_texture_swizzle) { 1273 GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT; 1274 *params = obj->Swizzle[comp]; 1275 } 1276 else { 1277 error = GL_TRUE; 1278 } 1279 break; 1280 1281 case GL_TEXTURE_SWIZZLE_RGBA_EXT: 1282 if (ctx->Extensions.EXT_texture_swizzle) { 1283 COPY_4V(params, obj->Swizzle); 1284 } 1285 else { 1286 error = GL_TRUE; 1287 } 1288 break; 1289 1290 default: 1291 ; /* silence warnings */ 1292 } 1293 1294 if (error) 1295 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(pname=0x%x)", 1296 pname); 1297 1298 _mesa_unlock_texture(ctx, obj); 1299} 1300