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