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