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