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