1 /* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5 * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice shall be included 15 * in all copies or substantial portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * 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/blend.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/mtypes.h" 41 #include "main/state.h" 42 #include "main/texcompress.h" 43 #include "main/texobj.h" 44 #include "main/texparam.h" 45 #include "main/teximage.h" 46 #include "main/texstate.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 */ 54 static GLboolean 55 validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap) 56 { 57 const struct gl_extensions * const e = & ctx->Extensions; 58 const bool is_desktop_gl = _mesa_is_desktop_gl(ctx); 59 bool supported; 60 61 switch (wrap) { 62 case GL_CLAMP: 63 /* GL_CLAMP was removed in the core profile, and it has never existed in 64 * OpenGL ES. 65 */ 66 supported = (ctx->API == API_OPENGL_COMPAT) 67 && (target != GL_TEXTURE_EXTERNAL_OES); 68 break; 69 70 case GL_CLAMP_TO_EDGE: 71 supported = true; 72 break; 73 74 case GL_CLAMP_TO_BORDER: 75 supported = ctx->API != API_OPENGLES && e->ARB_texture_border_clamp 76 && (target != GL_TEXTURE_EXTERNAL_OES); 77 break; 78 79 case GL_REPEAT: 80 case GL_MIRRORED_REPEAT: 81 supported = (target != GL_TEXTURE_RECTANGLE_NV) 82 && (target != GL_TEXTURE_EXTERNAL_OES); 83 break; 84 85 case GL_MIRROR_CLAMP_EXT: 86 supported = is_desktop_gl 87 && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp) 88 && (target != GL_TEXTURE_RECTANGLE_NV) 89 && (target != GL_TEXTURE_EXTERNAL_OES); 90 break; 91 92 case GL_MIRROR_CLAMP_TO_EDGE_EXT: 93 supported = is_desktop_gl 94 && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp || e->ARB_texture_mirror_clamp_to_edge) 95 && (target != GL_TEXTURE_RECTANGLE_NV) 96 && (target != GL_TEXTURE_EXTERNAL_OES); 97 break; 98 99 case GL_MIRROR_CLAMP_TO_BORDER_EXT: 100 supported = is_desktop_gl && e->EXT_texture_mirror_clamp 101 && (target != GL_TEXTURE_RECTANGLE_NV) 102 && (target != GL_TEXTURE_EXTERNAL_OES); 103 break; 104 105 default: 106 supported = false; 107 break; 108 } 109 110 if (!supported) 111 _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap ); 112 113 return supported; 114 } 115 116 117 /** 118 * Get current texture object for given target. 119 * Return NULL if any error (and record the error). 120 * Note that this is different from _mesa_get_current_tex_object() in that 121 * proxy targets are not accepted. 122 * Only the glGetTexLevelParameter() functions accept proxy targets. 123 */ 124 static struct gl_texture_object * 125 get_texobj_by_target(struct gl_context *ctx, GLenum target, GLboolean get) 126 { 127 struct gl_texture_unit *texUnit; 128 int targetIndex; 129 130 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) { 131 _mesa_error(ctx, GL_INVALID_OPERATION, 132 "gl%sTexParameter(current unit)", get ? "Get" : ""); 133 return NULL; 134 } 135 136 texUnit = _mesa_get_current_tex_unit(ctx); 137 138 targetIndex = _mesa_tex_target_to_index(ctx, target); 139 if (targetIndex < 0 || targetIndex == TEXTURE_BUFFER_INDEX) { 140 _mesa_error(ctx, GL_INVALID_ENUM, 141 "gl%sTexParameter(target)", get ? "Get" : ""); 142 return NULL; 143 } 144 assert(targetIndex < NUM_TEXTURE_TARGETS); 145 146 return texUnit->CurrentTex[targetIndex]; 147 } 148 149 /** 150 * Get current texture object for given name. 151 * Return NULL if any error (and record the error). 152 * Note that proxy targets are not accepted. 153 * Only the glGetTexLevelParameter() functions accept proxy targets. 154 */ 155 static struct gl_texture_object * 156 get_texobj_by_name(struct gl_context *ctx, GLuint texture, GLboolean get) 157 { 158 struct gl_texture_object *texObj; 159 160 texObj = _mesa_lookup_texture(ctx, texture); 161 if (!texObj) { 162 /* 163 * User passed a non-generated name. 164 * Throw the error in the caller. 165 */ 166 return NULL; 167 } 168 169 switch (texObj->Target) { 170 case GL_TEXTURE_1D: 171 case GL_TEXTURE_1D_ARRAY: 172 case GL_TEXTURE_2D: 173 case GL_TEXTURE_2D_ARRAY: 174 case GL_TEXTURE_2D_MULTISAMPLE: 175 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 176 case GL_TEXTURE_3D: 177 case GL_TEXTURE_CUBE_MAP: 178 case GL_TEXTURE_CUBE_MAP_ARRAY: 179 case GL_TEXTURE_RECTANGLE: 180 return texObj; 181 default: 182 _mesa_error(ctx, GL_INVALID_ENUM, 183 "gl%sTextureParameter(target)", get ? "Get" : ""); 184 return NULL; 185 } 186 187 } 188 189 190 /** 191 * Convert GL_RED/GREEN/BLUE/ALPHA/ZERO/ONE to SWIZZLE_X/Y/Z/W/ZERO/ONE. 192 * \return -1 if error. 193 */ 194 static GLint 195 comp_to_swizzle(GLenum comp) 196 { 197 switch (comp) { 198 case GL_RED: 199 return SWIZZLE_X; 200 case GL_GREEN: 201 return SWIZZLE_Y; 202 case GL_BLUE: 203 return SWIZZLE_Z; 204 case GL_ALPHA: 205 return SWIZZLE_W; 206 case GL_ZERO: 207 return SWIZZLE_ZERO; 208 case GL_ONE: 209 return SWIZZLE_ONE; 210 default: 211 return -1; 212 } 213 } 214 215 216 static void 217 set_swizzle_component(GLuint *swizzle, GLuint comp, GLuint swz) 218 { 219 assert(comp < 4); 220 assert(swz <= SWIZZLE_NIL); 221 { 222 GLuint mask = 0x7 << (3 * comp); 223 GLuint s = (*swizzle & ~mask) | (swz << (3 * comp)); 224 *swizzle = s; 225 } 226 } 227 228 229 /** 230 * This is called just prior to changing any texture object state which 231 * will not affect texture completeness. 232 */ 233 static inline void 234 flush(struct gl_context *ctx) 235 { 236 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 237 } 238 239 240 /** 241 * This is called just prior to changing any texture object state which 242 * could affect texture completeness (texture base level, max level). 243 * Any pending rendering will be flushed out, we'll set the _NEW_TEXTURE 244 * state flag and then mark the texture object as 'incomplete' so that any 245 * per-texture derived state gets recomputed. 246 */ 247 static inline void 248 incomplete(struct gl_context *ctx, struct gl_texture_object *texObj) 249 { 250 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 251 _mesa_dirty_texobj(ctx, texObj); 252 } 253 254 255 GLboolean 256 _mesa_target_allows_setting_sampler_parameters(GLenum target) 257 { 258 switch (target) { 259 case GL_TEXTURE_2D_MULTISAMPLE: 260 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 261 return GL_FALSE; 262 263 default: 264 return GL_TRUE; 265 } 266 } 267 268 269 /** 270 * Set an integer-valued texture parameter 271 * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise 272 */ 273 static GLboolean 274 set_tex_parameteri(struct gl_context *ctx, 275 struct gl_texture_object *texObj, 276 GLenum pname, const GLint *params, bool dsa) 277 { 278 const char *suffix = dsa ? "ture" : ""; 279 280 switch (pname) { 281 case GL_TEXTURE_MIN_FILTER: 282 if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 283 goto invalid_enum; 284 285 if (texObj->Sampler.MinFilter == params[0]) 286 return GL_FALSE; 287 switch (params[0]) { 288 case GL_NEAREST: 289 case GL_LINEAR: 290 flush(ctx); 291 texObj->Sampler.MinFilter = params[0]; 292 return GL_TRUE; 293 case GL_NEAREST_MIPMAP_NEAREST: 294 case GL_LINEAR_MIPMAP_NEAREST: 295 case GL_NEAREST_MIPMAP_LINEAR: 296 case GL_LINEAR_MIPMAP_LINEAR: 297 if (texObj->Target != GL_TEXTURE_RECTANGLE_NV && 298 texObj->Target != GL_TEXTURE_EXTERNAL_OES) { 299 flush(ctx); 300 texObj->Sampler.MinFilter = params[0]; 301 return GL_TRUE; 302 } 303 /* fall-through */ 304 default: 305 goto invalid_param; 306 } 307 return GL_FALSE; 308 309 case GL_TEXTURE_MAG_FILTER: 310 if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 311 goto invalid_enum; 312 313 if (texObj->Sampler.MagFilter == params[0]) 314 return GL_FALSE; 315 switch (params[0]) { 316 case GL_NEAREST: 317 case GL_LINEAR: 318 flush(ctx); /* does not effect completeness */ 319 texObj->Sampler.MagFilter = params[0]; 320 return GL_TRUE; 321 default: 322 goto invalid_param; 323 } 324 return GL_FALSE; 325 326 case GL_TEXTURE_WRAP_S: 327 if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 328 goto invalid_enum; 329 330 if (texObj->Sampler.WrapS == params[0]) 331 return GL_FALSE; 332 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { 333 flush(ctx); 334 texObj->Sampler.WrapS = params[0]; 335 return GL_TRUE; 336 } 337 return GL_FALSE; 338 339 case GL_TEXTURE_WRAP_T: 340 if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 341 goto invalid_enum; 342 343 if (texObj->Sampler.WrapT == params[0]) 344 return GL_FALSE; 345 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { 346 flush(ctx); 347 texObj->Sampler.WrapT = params[0]; 348 return GL_TRUE; 349 } 350 return GL_FALSE; 351 352 case GL_TEXTURE_WRAP_R: 353 if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 354 goto invalid_enum; 355 356 if (texObj->Sampler.WrapR == params[0]) 357 return GL_FALSE; 358 if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { 359 flush(ctx); 360 texObj->Sampler.WrapR = params[0]; 361 return GL_TRUE; 362 } 363 return GL_FALSE; 364 365 case GL_TEXTURE_BASE_LEVEL: 366 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 367 goto invalid_pname; 368 369 if (texObj->BaseLevel == params[0]) 370 return GL_FALSE; 371 372 if ((texObj->Target == GL_TEXTURE_2D_MULTISAMPLE || 373 texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) && params[0] != 0) 374 goto invalid_operation; 375 376 if (params[0] < 0) { 377 _mesa_error(ctx, GL_INVALID_VALUE, 378 "glTex%sParameter(param=%d)", suffix, params[0]); 379 return GL_FALSE; 380 } 381 if (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] != 0) { 382 _mesa_error(ctx, GL_INVALID_OPERATION, 383 "glTex%sParameter(target=%s, param=%d)", suffix, 384 _mesa_enum_to_string(texObj->Target), params[0]); 385 return GL_FALSE; 386 } 387 incomplete(ctx, texObj); 388 389 /** See note about ARB_texture_storage below */ 390 if (texObj->Immutable) 391 texObj->BaseLevel = MIN2(texObj->ImmutableLevels - 1, params[0]); 392 else 393 texObj->BaseLevel = params[0]; 394 395 return GL_TRUE; 396 397 case GL_TEXTURE_MAX_LEVEL: 398 if (texObj->MaxLevel == params[0]) 399 return GL_FALSE; 400 401 if (params[0] < 0 || 402 (texObj->Target == GL_TEXTURE_RECTANGLE_ARB && params[0] > 0)) { 403 _mesa_error(ctx, GL_INVALID_VALUE, 404 "glTex%sParameter(param=%d)", suffix, 405 params[0]); 406 return GL_FALSE; 407 } 408 incomplete(ctx, texObj); 409 410 /** From ARB_texture_storage: 411 * However, if TEXTURE_IMMUTABLE_FORMAT is TRUE, then level_base is 412 * clamped to the range [0, <levels> - 1] and level_max is then clamped to 413 * the range [level_base, <levels> - 1], where <levels> is the parameter 414 * passed the call to TexStorage* for the texture object. 415 */ 416 if (texObj->Immutable) 417 texObj->MaxLevel = CLAMP(params[0], texObj->BaseLevel, 418 texObj->ImmutableLevels - 1); 419 else 420 texObj->MaxLevel = params[0]; 421 422 return GL_TRUE; 423 424 case GL_GENERATE_MIPMAP_SGIS: 425 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) 426 goto invalid_pname; 427 428 if (params[0] && texObj->Target == GL_TEXTURE_EXTERNAL_OES) 429 goto invalid_param; 430 if (texObj->GenerateMipmap != params[0]) { 431 /* no flush() */ 432 texObj->GenerateMipmap = params[0] ? GL_TRUE : GL_FALSE; 433 return GL_TRUE; 434 } 435 return GL_FALSE; 436 437 case GL_TEXTURE_COMPARE_MODE_ARB: 438 if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow) 439 || _mesa_is_gles3(ctx)) { 440 441 if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 442 goto invalid_enum; 443 444 if (texObj->Sampler.CompareMode == params[0]) 445 return GL_FALSE; 446 if (params[0] == GL_NONE || 447 params[0] == GL_COMPARE_R_TO_TEXTURE_ARB) { 448 flush(ctx); 449 texObj->Sampler.CompareMode = params[0]; 450 return GL_TRUE; 451 } 452 goto invalid_param; 453 } 454 goto invalid_pname; 455 456 case GL_TEXTURE_COMPARE_FUNC_ARB: 457 if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_shadow) 458 || _mesa_is_gles3(ctx)) { 459 460 if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 461 goto invalid_enum; 462 463 if (texObj->Sampler.CompareFunc == params[0]) 464 return GL_FALSE; 465 switch (params[0]) { 466 case GL_LEQUAL: 467 case GL_GEQUAL: 468 case GL_EQUAL: 469 case GL_NOTEQUAL: 470 case GL_LESS: 471 case GL_GREATER: 472 case GL_ALWAYS: 473 case GL_NEVER: 474 flush(ctx); 475 texObj->Sampler.CompareFunc = params[0]; 476 return GL_TRUE; 477 default: 478 goto invalid_param; 479 } 480 } 481 goto invalid_pname; 482 483 case GL_DEPTH_TEXTURE_MODE_ARB: 484 /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has never 485 * existed in OpenGL ES. 486 */ 487 if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_depth_texture) { 488 if (texObj->DepthMode == params[0]) 489 return GL_FALSE; 490 if (params[0] == GL_LUMINANCE || 491 params[0] == GL_INTENSITY || 492 params[0] == GL_ALPHA || 493 (ctx->Extensions.ARB_texture_rg && params[0] == GL_RED)) { 494 flush(ctx); 495 texObj->DepthMode = params[0]; 496 return GL_TRUE; 497 } 498 goto invalid_param; 499 } 500 goto invalid_pname; 501 502 case GL_DEPTH_STENCIL_TEXTURE_MODE: 503 if (_mesa_has_ARB_stencil_texturing(ctx) || _mesa_is_gles31(ctx)) { 504 bool stencil = params[0] == GL_STENCIL_INDEX; 505 if (!stencil && params[0] != GL_DEPTH_COMPONENT) 506 goto invalid_param; 507 508 if (texObj->StencilSampling == stencil) 509 return GL_FALSE; 510 511 texObj->StencilSampling = stencil; 512 return GL_TRUE; 513 } 514 goto invalid_pname; 515 516 case GL_TEXTURE_CROP_RECT_OES: 517 if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture) 518 goto invalid_pname; 519 520 texObj->CropRect[0] = params[0]; 521 texObj->CropRect[1] = params[1]; 522 texObj->CropRect[2] = params[2]; 523 texObj->CropRect[3] = params[3]; 524 return GL_TRUE; 525 526 case GL_TEXTURE_SWIZZLE_R_EXT: 527 case GL_TEXTURE_SWIZZLE_G_EXT: 528 case GL_TEXTURE_SWIZZLE_B_EXT: 529 case GL_TEXTURE_SWIZZLE_A_EXT: 530 if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle) 531 || _mesa_is_gles3(ctx)) { 532 const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT; 533 const GLint swz = comp_to_swizzle(params[0]); 534 if (swz < 0) { 535 _mesa_error(ctx, GL_INVALID_ENUM, 536 "glTex%sParameter(swizzle 0x%x)", suffix, params[0]); 537 return GL_FALSE; 538 } 539 assert(comp < 4); 540 541 flush(ctx); 542 texObj->Swizzle[comp] = params[0]; 543 set_swizzle_component(&texObj->_Swizzle, comp, swz); 544 return GL_TRUE; 545 } 546 goto invalid_pname; 547 548 case GL_TEXTURE_SWIZZLE_RGBA_EXT: 549 if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle) 550 || _mesa_is_gles3(ctx)) { 551 GLuint comp; 552 flush(ctx); 553 for (comp = 0; comp < 4; comp++) { 554 const GLint swz = comp_to_swizzle(params[comp]); 555 if (swz >= 0) { 556 texObj->Swizzle[comp] = params[comp]; 557 set_swizzle_component(&texObj->_Swizzle, comp, swz); 558 } 559 else { 560 _mesa_error(ctx, GL_INVALID_ENUM, 561 "glTex%sParameter(swizzle 0x%x)", 562 suffix, params[comp]); 563 return GL_FALSE; 564 } 565 } 566 return GL_TRUE; 567 } 568 goto invalid_pname; 569 570 case GL_TEXTURE_SRGB_DECODE_EXT: 571 if (ctx->Extensions.EXT_texture_sRGB_decode) { 572 GLenum decode = params[0]; 573 574 if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 575 goto invalid_enum; 576 577 if (decode == GL_DECODE_EXT || decode == GL_SKIP_DECODE_EXT) { 578 if (texObj->Sampler.sRGBDecode != decode) { 579 flush(ctx); 580 texObj->Sampler.sRGBDecode = decode; 581 } 582 return GL_TRUE; 583 } 584 } 585 goto invalid_pname; 586 587 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 588 if (_mesa_is_desktop_gl(ctx) 589 && ctx->Extensions.AMD_seamless_cubemap_per_texture) { 590 GLenum param = params[0]; 591 592 if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 593 goto invalid_enum; 594 595 if (param != GL_TRUE && param != GL_FALSE) { 596 goto invalid_param; 597 } 598 if (param != texObj->Sampler.CubeMapSeamless) { 599 flush(ctx); 600 texObj->Sampler.CubeMapSeamless = param; 601 } 602 return GL_TRUE; 603 } 604 goto invalid_pname; 605 606 default: 607 goto invalid_pname; 608 } 609 610 invalid_pname: 611 _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)", 612 suffix, _mesa_enum_to_string(pname)); 613 return GL_FALSE; 614 615 invalid_param: 616 _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(param=%s)", 617 suffix, _mesa_enum_to_string(params[0])); 618 return GL_FALSE; 619 620 invalid_operation: 621 _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sParameter(pname=%s)", 622 suffix, _mesa_enum_to_string(pname)); 623 return GL_FALSE; 624 625 invalid_enum: 626 _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)", 627 suffix, _mesa_enum_to_string(pname)); 628 return GL_FALSE; 629 } 630 631 632 /** 633 * Set a float-valued texture parameter 634 * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise 635 */ 636 static GLboolean 637 set_tex_parameterf(struct gl_context *ctx, 638 struct gl_texture_object *texObj, 639 GLenum pname, const GLfloat *params, bool dsa) 640 { 641 const char *suffix = dsa ? "ture" : ""; 642 643 switch (pname) { 644 case GL_TEXTURE_MIN_LOD: 645 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 646 goto invalid_pname; 647 648 if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 649 goto invalid_enum; 650 651 if (texObj->Sampler.MinLod == params[0]) 652 return GL_FALSE; 653 flush(ctx); 654 texObj->Sampler.MinLod = params[0]; 655 return GL_TRUE; 656 657 case GL_TEXTURE_MAX_LOD: 658 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 659 goto invalid_pname; 660 661 if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 662 goto invalid_enum; 663 664 if (texObj->Sampler.MaxLod == params[0]) 665 return GL_FALSE; 666 flush(ctx); 667 texObj->Sampler.MaxLod = params[0]; 668 return GL_TRUE; 669 670 case GL_TEXTURE_PRIORITY: 671 if (ctx->API != API_OPENGL_COMPAT) 672 goto invalid_pname; 673 674 flush(ctx); 675 texObj->Priority = CLAMP(params[0], 0.0F, 1.0F); 676 return GL_TRUE; 677 678 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 679 if (ctx->Extensions.EXT_texture_filter_anisotropic) { 680 if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 681 goto invalid_enum; 682 683 if (texObj->Sampler.MaxAnisotropy == params[0]) 684 return GL_FALSE; 685 if (params[0] < 1.0F) { 686 _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sParameter(param)", 687 suffix); 688 return GL_FALSE; 689 } 690 flush(ctx); 691 /* clamp to max, that's what NVIDIA does */ 692 texObj->Sampler.MaxAnisotropy = MIN2(params[0], 693 ctx->Const.MaxTextureMaxAnisotropy); 694 return GL_TRUE; 695 } 696 else { 697 static GLuint count = 0; 698 if (count++ < 10) 699 goto invalid_pname; 700 } 701 return GL_FALSE; 702 703 case GL_TEXTURE_LOD_BIAS: 704 /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias. */ 705 if (_mesa_is_gles(ctx)) 706 goto invalid_pname; 707 708 if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 709 goto invalid_enum; 710 711 if (texObj->Sampler.LodBias != params[0]) { 712 flush(ctx); 713 texObj->Sampler.LodBias = params[0]; 714 return GL_TRUE; 715 } 716 break; 717 718 case GL_TEXTURE_BORDER_COLOR: 719 if (ctx->API == API_OPENGLES || 720 !ctx->Extensions.ARB_texture_border_clamp) 721 goto invalid_pname; 722 723 if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) 724 goto invalid_enum; 725 726 flush(ctx); 727 /* ARB_texture_float disables clamping */ 728 if (ctx->Extensions.ARB_texture_float) { 729 texObj->Sampler.BorderColor.f[RCOMP] = params[0]; 730 texObj->Sampler.BorderColor.f[GCOMP] = params[1]; 731 texObj->Sampler.BorderColor.f[BCOMP] = params[2]; 732 texObj->Sampler.BorderColor.f[ACOMP] = params[3]; 733 } else { 734 texObj->Sampler.BorderColor.f[RCOMP] = CLAMP(params[0], 0.0F, 1.0F); 735 texObj->Sampler.BorderColor.f[GCOMP] = CLAMP(params[1], 0.0F, 1.0F); 736 texObj->Sampler.BorderColor.f[BCOMP] = CLAMP(params[2], 0.0F, 1.0F); 737 texObj->Sampler.BorderColor.f[ACOMP] = CLAMP(params[3], 0.0F, 1.0F); 738 } 739 return GL_TRUE; 740 741 default: 742 goto invalid_pname; 743 } 744 return GL_FALSE; 745 746 invalid_pname: 747 _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)", 748 suffix, _mesa_enum_to_string(pname)); 749 return GL_FALSE; 750 751 invalid_enum: 752 _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameter(pname=%s)", 753 suffix, _mesa_enum_to_string(pname)); 754 return GL_FALSE; 755 } 756 757 758 void 759 _mesa_texture_parameterf(struct gl_context *ctx, 760 struct gl_texture_object *texObj, 761 GLenum pname, GLfloat param, bool dsa) 762 { 763 GLboolean need_update; 764 765 switch (pname) { 766 case GL_TEXTURE_MIN_FILTER: 767 case GL_TEXTURE_MAG_FILTER: 768 case GL_TEXTURE_WRAP_S: 769 case GL_TEXTURE_WRAP_T: 770 case GL_TEXTURE_WRAP_R: 771 case GL_TEXTURE_BASE_LEVEL: 772 case GL_TEXTURE_MAX_LEVEL: 773 case GL_GENERATE_MIPMAP_SGIS: 774 case GL_TEXTURE_COMPARE_MODE_ARB: 775 case GL_TEXTURE_COMPARE_FUNC_ARB: 776 case GL_DEPTH_TEXTURE_MODE_ARB: 777 case GL_DEPTH_STENCIL_TEXTURE_MODE: 778 case GL_TEXTURE_SRGB_DECODE_EXT: 779 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 780 case GL_TEXTURE_SWIZZLE_R_EXT: 781 case GL_TEXTURE_SWIZZLE_G_EXT: 782 case GL_TEXTURE_SWIZZLE_B_EXT: 783 case GL_TEXTURE_SWIZZLE_A_EXT: 784 { 785 GLint p[4]; 786 p[0] = (param > 0) ? 787 ((param > INT_MAX) ? INT_MAX : (GLint) (param + 0.5)) : 788 ((param < INT_MIN) ? INT_MIN : (GLint) (param - 0.5)); 789 790 p[1] = p[2] = p[3] = 0; 791 need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa); 792 } 793 break; 794 case GL_TEXTURE_BORDER_COLOR: 795 case GL_TEXTURE_SWIZZLE_RGBA: 796 _mesa_error(ctx, GL_INVALID_ENUM, "glTex%sParameterf(non-scalar pname)", 797 dsa ? "ture" : ""); 798 return; 799 default: 800 { 801 /* this will generate an error if pname is illegal */ 802 GLfloat p[4]; 803 p[0] = param; 804 p[1] = p[2] = p[3] = 0.0F; 805 need_update = set_tex_parameterf(ctx, texObj, pname, p, dsa); 806 } 807 } 808 809 if (ctx->Driver.TexParameter && need_update) { 810 ctx->Driver.TexParameter(ctx, texObj, pname); 811 } 812 } 813 814 815 void 816 _mesa_texture_parameterfv(struct gl_context *ctx, 817 struct gl_texture_object *texObj, 818 GLenum pname, const GLfloat *params, bool dsa) 819 { 820 GLboolean need_update; 821 switch (pname) { 822 case GL_TEXTURE_MIN_FILTER: 823 case GL_TEXTURE_MAG_FILTER: 824 case GL_TEXTURE_WRAP_S: 825 case GL_TEXTURE_WRAP_T: 826 case GL_TEXTURE_WRAP_R: 827 case GL_TEXTURE_BASE_LEVEL: 828 case GL_TEXTURE_MAX_LEVEL: 829 case GL_GENERATE_MIPMAP_SGIS: 830 case GL_TEXTURE_COMPARE_MODE_ARB: 831 case GL_TEXTURE_COMPARE_FUNC_ARB: 832 case GL_DEPTH_TEXTURE_MODE_ARB: 833 case GL_DEPTH_STENCIL_TEXTURE_MODE: 834 case GL_TEXTURE_SRGB_DECODE_EXT: 835 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 836 { 837 /* convert float param to int */ 838 GLint p[4]; 839 p[0] = (GLint) params[0]; 840 p[1] = p[2] = p[3] = 0; 841 need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa); 842 } 843 break; 844 case GL_TEXTURE_CROP_RECT_OES: 845 { 846 /* convert float params to int */ 847 GLint iparams[4]; 848 iparams[0] = (GLint) params[0]; 849 iparams[1] = (GLint) params[1]; 850 iparams[2] = (GLint) params[2]; 851 iparams[3] = (GLint) params[3]; 852 need_update = set_tex_parameteri(ctx, texObj, pname, iparams, dsa); 853 } 854 break; 855 case GL_TEXTURE_SWIZZLE_R_EXT: 856 case GL_TEXTURE_SWIZZLE_G_EXT: 857 case GL_TEXTURE_SWIZZLE_B_EXT: 858 case GL_TEXTURE_SWIZZLE_A_EXT: 859 case GL_TEXTURE_SWIZZLE_RGBA_EXT: 860 { 861 GLint p[4] = {0, 0, 0, 0}; 862 p[0] = (GLint) params[0]; 863 if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT) { 864 p[1] = (GLint) params[1]; 865 p[2] = (GLint) params[2]; 866 p[3] = (GLint) params[3]; 867 } 868 need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa); 869 } 870 break; 871 default: 872 /* this will generate an error if pname is illegal */ 873 need_update = set_tex_parameterf(ctx, texObj, pname, params, dsa); 874 } 875 876 if (ctx->Driver.TexParameter && need_update) { 877 ctx->Driver.TexParameter(ctx, texObj, pname); 878 } 879 } 880 881 882 void 883 _mesa_texture_parameteri(struct gl_context *ctx, 884 struct gl_texture_object *texObj, 885 GLenum pname, GLint param, bool dsa) 886 { 887 GLboolean need_update; 888 switch (pname) { 889 case GL_TEXTURE_MIN_LOD: 890 case GL_TEXTURE_MAX_LOD: 891 case GL_TEXTURE_PRIORITY: 892 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 893 case GL_TEXTURE_LOD_BIAS: 894 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: 895 { 896 GLfloat fparam[4]; 897 fparam[0] = (GLfloat) param; 898 fparam[1] = fparam[2] = fparam[3] = 0.0F; 899 /* convert int param to float */ 900 need_update = set_tex_parameterf(ctx, texObj, pname, fparam, dsa); 901 } 902 break; 903 case GL_TEXTURE_BORDER_COLOR: 904 case GL_TEXTURE_SWIZZLE_RGBA: 905 { 906 _mesa_error(ctx, GL_INVALID_ENUM, 907 "glTex%sParameteri(non-scalar pname)", 908 dsa ? "ture" : ""); 909 return; 910 } 911 default: 912 /* this will generate an error if pname is illegal */ 913 { 914 GLint iparam[4]; 915 iparam[0] = param; 916 iparam[1] = iparam[2] = iparam[3] = 0; 917 need_update = set_tex_parameteri(ctx, texObj, pname, iparam, dsa); 918 } 919 } 920 921 if (ctx->Driver.TexParameter && need_update) { 922 ctx->Driver.TexParameter(ctx, texObj, pname); 923 } 924 } 925 926 927 void 928 _mesa_texture_parameteriv(struct gl_context *ctx, 929 struct gl_texture_object *texObj, 930 GLenum pname, const GLint *params, bool dsa) 931 { 932 GLboolean need_update; 933 934 switch (pname) { 935 case GL_TEXTURE_BORDER_COLOR: 936 { 937 if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) { 938 _mesa_error(ctx, GL_INVALID_ENUM, "glTextureParameteriv(texture)"); 939 return; 940 } 941 /* convert int params to float */ 942 GLfloat fparams[4]; 943 fparams[0] = INT_TO_FLOAT(params[0]); 944 fparams[1] = INT_TO_FLOAT(params[1]); 945 fparams[2] = INT_TO_FLOAT(params[2]); 946 fparams[3] = INT_TO_FLOAT(params[3]); 947 need_update = set_tex_parameterf(ctx, texObj, pname, fparams, dsa); 948 } 949 break; 950 case GL_TEXTURE_MIN_LOD: 951 case GL_TEXTURE_MAX_LOD: 952 case GL_TEXTURE_PRIORITY: 953 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 954 case GL_TEXTURE_LOD_BIAS: 955 case GL_TEXTURE_COMPARE_FAIL_VALUE_ARB: 956 { 957 /* convert int param to float */ 958 GLfloat fparams[4]; 959 fparams[0] = (GLfloat) params[0]; 960 fparams[1] = fparams[2] = fparams[3] = 0.0F; 961 need_update = set_tex_parameterf(ctx, texObj, pname, fparams, dsa); 962 } 963 break; 964 default: 965 /* this will generate an error if pname is illegal */ 966 need_update = set_tex_parameteri(ctx, texObj, pname, params, dsa); 967 } 968 969 if (ctx->Driver.TexParameter && need_update) { 970 ctx->Driver.TexParameter(ctx, texObj, pname); 971 } 972 } 973 974 void 975 _mesa_texture_parameterIiv(struct gl_context *ctx, 976 struct gl_texture_object *texObj, 977 GLenum pname, const GLint *params, bool dsa) 978 { 979 switch (pname) { 980 case GL_TEXTURE_BORDER_COLOR: 981 if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) { 982 _mesa_error(ctx, GL_INVALID_ENUM, "glTextureParameterIiv(texture)"); 983 return; 984 } 985 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 986 /* set the integer-valued border color */ 987 COPY_4V(texObj->Sampler.BorderColor.i, params); 988 break; 989 default: 990 _mesa_texture_parameteriv(ctx, texObj, pname, params, dsa); 991 break; 992 } 993 /* XXX no driver hook for TexParameterIiv() yet */ 994 } 995 996 void 997 _mesa_texture_parameterIuiv(struct gl_context *ctx, 998 struct gl_texture_object *texObj, 999 GLenum pname, const GLuint *params, bool dsa) 1000 { 1001 switch (pname) { 1002 case GL_TEXTURE_BORDER_COLOR: 1003 if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) { 1004 _mesa_error(ctx, GL_INVALID_ENUM, "glTextureParameterIuiv(texture)"); 1005 return; 1006 } 1007 FLUSH_VERTICES(ctx, _NEW_TEXTURE); 1008 /* set the unsigned integer-valued border color */ 1009 COPY_4V(texObj->Sampler.BorderColor.ui, params); 1010 break; 1011 default: 1012 _mesa_texture_parameteriv(ctx, texObj, pname, (const GLint *) params, 1013 dsa); 1014 break; 1015 } 1016 /* XXX no driver hook for TexParameterIuiv() yet */ 1017 } 1018 1019 void GLAPIENTRY 1020 _mesa_TexParameterf(GLenum target, GLenum pname, GLfloat param) 1021 { 1022 struct gl_texture_object *texObj; 1023 GET_CURRENT_CONTEXT(ctx); 1024 1025 texObj = get_texobj_by_target(ctx, target, GL_FALSE); 1026 if (!texObj) 1027 return; 1028 1029 _mesa_texture_parameterf(ctx, texObj, pname, param, false); 1030 } 1031 1032 void GLAPIENTRY 1033 _mesa_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) 1034 { 1035 struct gl_texture_object *texObj; 1036 GET_CURRENT_CONTEXT(ctx); 1037 1038 texObj = get_texobj_by_target(ctx, target, GL_FALSE); 1039 if (!texObj) 1040 return; 1041 1042 _mesa_texture_parameterfv(ctx, texObj, pname, params, false); 1043 } 1044 1045 void GLAPIENTRY 1046 _mesa_TexParameteri(GLenum target, GLenum pname, GLint param) 1047 { 1048 struct gl_texture_object *texObj; 1049 GET_CURRENT_CONTEXT(ctx); 1050 1051 texObj = get_texobj_by_target(ctx, target, GL_FALSE); 1052 if (!texObj) 1053 return; 1054 1055 _mesa_texture_parameteri(ctx, texObj, pname, param, false); 1056 } 1057 1058 void GLAPIENTRY 1059 _mesa_TexParameteriv(GLenum target, GLenum pname, const GLint *params) 1060 { 1061 struct gl_texture_object *texObj; 1062 GET_CURRENT_CONTEXT(ctx); 1063 1064 texObj = get_texobj_by_target(ctx, target, GL_FALSE); 1065 if (!texObj) 1066 return; 1067 1068 _mesa_texture_parameteriv(ctx, texObj, pname, params, false); 1069 } 1070 1071 /** 1072 * Set tex parameter to integer value(s). Primarily intended to set 1073 * integer-valued texture border color (for integer-valued textures). 1074 * New in GL 3.0. 1075 */ 1076 void GLAPIENTRY 1077 _mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params) 1078 { 1079 struct gl_texture_object *texObj; 1080 GET_CURRENT_CONTEXT(ctx); 1081 1082 texObj = get_texobj_by_target(ctx, target, GL_FALSE); 1083 if (!texObj) 1084 return; 1085 1086 _mesa_texture_parameterIiv(ctx, texObj, pname, params, false); 1087 } 1088 1089 /** 1090 * Set tex parameter to unsigned integer value(s). Primarily intended to set 1091 * uint-valued texture border color (for integer-valued textures). 1092 * New in GL 3.0 1093 */ 1094 void GLAPIENTRY 1095 _mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params) 1096 { 1097 struct gl_texture_object *texObj; 1098 GET_CURRENT_CONTEXT(ctx); 1099 1100 texObj = get_texobj_by_target(ctx, target, GL_FALSE); 1101 if (!texObj) 1102 return; 1103 1104 _mesa_texture_parameterIuiv(ctx, texObj, pname, params, false); 1105 } 1106 1107 1108 void GLAPIENTRY 1109 _mesa_TextureParameterfv(GLuint texture, GLenum pname, const GLfloat *params) 1110 { 1111 struct gl_texture_object *texObj; 1112 GET_CURRENT_CONTEXT(ctx); 1113 1114 texObj = get_texobj_by_name(ctx, texture, GL_FALSE); 1115 if (!texObj) { 1116 /* User passed a non-generated name. */ 1117 _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameterfv(texture)"); 1118 return; 1119 } 1120 1121 _mesa_texture_parameterfv(ctx, texObj, pname, params, true); 1122 } 1123 1124 void GLAPIENTRY 1125 _mesa_TextureParameterf(GLuint texture, GLenum pname, GLfloat param) 1126 { 1127 struct gl_texture_object *texObj; 1128 GET_CURRENT_CONTEXT(ctx); 1129 1130 texObj = get_texobj_by_name(ctx, texture, GL_FALSE); 1131 if (!texObj) { 1132 /* User passed a non-generated name. */ 1133 _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameterf(texture)"); 1134 return; 1135 } 1136 1137 _mesa_texture_parameterf(ctx, texObj, pname, param, true); 1138 } 1139 1140 void GLAPIENTRY 1141 _mesa_TextureParameteri(GLuint texture, GLenum pname, GLint param) 1142 { 1143 struct gl_texture_object *texObj; 1144 GET_CURRENT_CONTEXT(ctx); 1145 1146 texObj = get_texobj_by_name(ctx, texture, GL_FALSE); 1147 if (!texObj) { 1148 /* User passed a non-generated name. */ 1149 _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameteri(texture)"); 1150 return; 1151 } 1152 1153 _mesa_texture_parameteri(ctx, texObj, pname, param, true); 1154 } 1155 1156 void GLAPIENTRY 1157 _mesa_TextureParameteriv(GLuint texture, GLenum pname, 1158 const GLint *params) 1159 { 1160 struct gl_texture_object *texObj; 1161 GET_CURRENT_CONTEXT(ctx); 1162 1163 texObj = get_texobj_by_name(ctx, texture, GL_FALSE); 1164 if (!texObj) { 1165 /* User passed a non-generated name. */ 1166 _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureParameteriv(texture)"); 1167 return; 1168 } 1169 1170 _mesa_texture_parameteriv(ctx, texObj, pname, params, true); 1171 } 1172 1173 1174 void GLAPIENTRY 1175 _mesa_TextureParameterIiv(GLuint texture, GLenum pname, const GLint *params) 1176 { 1177 struct gl_texture_object *texObj; 1178 GET_CURRENT_CONTEXT(ctx); 1179 1180 texObj = get_texobj_by_name(ctx, texture, GL_FALSE); 1181 if (!texObj) { 1182 /* User passed a non-generated name. */ 1183 _mesa_error(ctx, GL_INVALID_OPERATION, 1184 "glTextureParameterIiv(texture)"); 1185 return; 1186 } 1187 1188 _mesa_texture_parameterIiv(ctx, texObj, pname, params, true); 1189 } 1190 1191 void GLAPIENTRY 1192 _mesa_TextureParameterIuiv(GLuint texture, GLenum pname, const GLuint *params) 1193 { 1194 struct gl_texture_object *texObj; 1195 GET_CURRENT_CONTEXT(ctx); 1196 1197 texObj = get_texobj_by_name(ctx, texture, GL_FALSE); 1198 if (!texObj) { 1199 /* User passed a non-generated name. */ 1200 _mesa_error(ctx, GL_INVALID_OPERATION, 1201 "glTextureParameterIuiv(texture)"); 1202 return; 1203 } 1204 1205 _mesa_texture_parameterIuiv(ctx, texObj, pname, params, true); 1206 } 1207 1208 GLboolean 1209 _mesa_legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target, 1210 bool dsa) 1211 { 1212 /* Common targets for desktop GL and GLES 3.1. */ 1213 switch (target) { 1214 case GL_TEXTURE_2D: 1215 case GL_TEXTURE_3D: 1216 return GL_TRUE; 1217 case GL_TEXTURE_2D_ARRAY_EXT: 1218 return ctx->Extensions.EXT_texture_array; 1219 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1220 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1221 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1222 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1223 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1224 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1225 return ctx->Extensions.ARB_texture_cube_map; 1226 case GL_TEXTURE_2D_MULTISAMPLE: 1227 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 1228 return ctx->Extensions.ARB_texture_multisample; 1229 case GL_TEXTURE_BUFFER: 1230 /* GetTexLevelParameter accepts GL_TEXTURE_BUFFER in GL 3.1+ contexts, 1231 * but not in earlier versions that expose ARB_texture_buffer_object. 1232 * 1233 * From the ARB_texture_buffer_object spec: 1234 * "(7) Do buffer textures support texture parameters (TexParameter) or 1235 * queries (GetTexParameter, GetTexLevelParameter, GetTexImage)? 1236 * 1237 * RESOLVED: No. [...] Note that the spec edits above don't add 1238 * explicit error language for any of these cases. That is because 1239 * each of the functions enumerate the set of valid <target> 1240 * parameters. Not editing the spec to allow TEXTURE_BUFFER_ARB in 1241 * these cases means that target is not legal, and an INVALID_ENUM 1242 * error should be generated." 1243 * 1244 * From the OpenGL 3.1 spec: 1245 * "target may also be TEXTURE_BUFFER, indicating the texture buffer." 1246 */ 1247 return (ctx->API == API_OPENGL_CORE && ctx->Version >= 31) || 1248 _mesa_has_OES_texture_buffer(ctx); 1249 case GL_TEXTURE_CUBE_MAP_ARRAY: 1250 return _mesa_has_texture_cube_map_array(ctx); 1251 } 1252 1253 if (!_mesa_is_desktop_gl(ctx)) 1254 return GL_FALSE; 1255 1256 /* Rest of the desktop GL targets. */ 1257 switch (target) { 1258 case GL_TEXTURE_1D: 1259 case GL_PROXY_TEXTURE_1D: 1260 case GL_PROXY_TEXTURE_2D: 1261 case GL_PROXY_TEXTURE_3D: 1262 return GL_TRUE; 1263 case GL_PROXY_TEXTURE_CUBE_MAP: 1264 return ctx->Extensions.ARB_texture_cube_map; 1265 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: 1266 return ctx->Extensions.ARB_texture_cube_map_array; 1267 case GL_TEXTURE_RECTANGLE_NV: 1268 case GL_PROXY_TEXTURE_RECTANGLE_NV: 1269 return ctx->Extensions.NV_texture_rectangle; 1270 case GL_TEXTURE_1D_ARRAY_EXT: 1271 case GL_PROXY_TEXTURE_1D_ARRAY_EXT: 1272 case GL_PROXY_TEXTURE_2D_ARRAY_EXT: 1273 return ctx->Extensions.EXT_texture_array; 1274 case GL_PROXY_TEXTURE_2D_MULTISAMPLE: 1275 case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: 1276 return ctx->Extensions.ARB_texture_multisample; 1277 1278 /* This is a valid target for dsa, but the OpenGL 4.5 core spec 1279 * (30.10.2014) Section 8.11 Texture Queries says: 1280 * "For GetTextureLevelParameter* only, texture may also be a cube 1281 * map texture object. In this case the query is always performed 1282 * for face zero (the TEXTURE_CUBE_MAP_POSITIVE_X face), since there 1283 * is no way to specify another face." 1284 */ 1285 case GL_TEXTURE_CUBE_MAP: 1286 return dsa; 1287 default: 1288 return GL_FALSE; 1289 } 1290 } 1291 1292 1293 static void 1294 get_tex_level_parameter_image(struct gl_context *ctx, 1295 const struct gl_texture_object *texObj, 1296 GLenum target, GLint level, 1297 GLenum pname, GLint *params, 1298 bool dsa) 1299 { 1300 const struct gl_texture_image *img = NULL; 1301 struct gl_texture_image dummy_image; 1302 mesa_format texFormat; 1303 const char *suffix = dsa ? "ture" : ""; 1304 1305 img = _mesa_select_tex_image(texObj, target, level); 1306 if (!img || img->TexFormat == MESA_FORMAT_NONE) { 1307 /* In case of undefined texture image return the default values. 1308 * 1309 * From OpenGL 4.0 spec, page 398: 1310 * "The initial internal format of a texel array is RGBA 1311 * instead of 1. TEXTURE_COMPONENTS is deprecated; always 1312 * use TEXTURE_INTERNAL_FORMAT." 1313 */ 1314 memset(&dummy_image, 0, sizeof(dummy_image)); 1315 dummy_image.TexFormat = MESA_FORMAT_NONE; 1316 dummy_image.InternalFormat = GL_RGBA; 1317 dummy_image._BaseFormat = GL_NONE; 1318 dummy_image.FixedSampleLocations = GL_TRUE; 1319 1320 img = &dummy_image; 1321 } 1322 1323 texFormat = img->TexFormat; 1324 1325 switch (pname) { 1326 case GL_TEXTURE_WIDTH: 1327 *params = img->Width; 1328 break; 1329 case GL_TEXTURE_HEIGHT: 1330 *params = img->Height; 1331 break; 1332 case GL_TEXTURE_DEPTH: 1333 *params = img->Depth; 1334 break; 1335 case GL_TEXTURE_INTERNAL_FORMAT: 1336 if (_mesa_is_format_compressed(texFormat)) { 1337 /* need to return the actual compressed format */ 1338 *params = _mesa_compressed_format_to_glenum(ctx, texFormat); 1339 } 1340 else { 1341 /* If the true internal format is not compressed but the user 1342 * requested a generic compressed format, we have to return the 1343 * generic base format that matches. 1344 * 1345 * From page 119 (page 129 of the PDF) of the OpenGL 1.3 spec: 1346 * 1347 * "If no specific compressed format is available, 1348 * internalformat is instead replaced by the corresponding base 1349 * internal format." 1350 * 1351 * Otherwise just return the user's requested internal format 1352 */ 1353 const GLenum f = 1354 _mesa_gl_compressed_format_base_format(img->InternalFormat); 1355 1356 *params = (f != 0) ? f : img->InternalFormat; 1357 } 1358 break; 1359 case GL_TEXTURE_BORDER: 1360 if (ctx->API != API_OPENGL_COMPAT) 1361 goto invalid_pname; 1362 *params = img->Border; 1363 break; 1364 case GL_TEXTURE_RED_SIZE: 1365 case GL_TEXTURE_GREEN_SIZE: 1366 case GL_TEXTURE_BLUE_SIZE: 1367 case GL_TEXTURE_ALPHA_SIZE: 1368 if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) 1369 *params = _mesa_get_format_bits(texFormat, pname); 1370 else 1371 *params = 0; 1372 break; 1373 case GL_TEXTURE_INTENSITY_SIZE: 1374 case GL_TEXTURE_LUMINANCE_SIZE: 1375 if (ctx->API != API_OPENGL_COMPAT) 1376 goto invalid_pname; 1377 if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) { 1378 *params = _mesa_get_format_bits(texFormat, pname); 1379 if (*params == 0) { 1380 /* intensity or luminance is probably stored as RGB[A] */ 1381 *params = MIN2(_mesa_get_format_bits(texFormat, 1382 GL_TEXTURE_RED_SIZE), 1383 _mesa_get_format_bits(texFormat, 1384 GL_TEXTURE_GREEN_SIZE)); 1385 } 1386 } 1387 else { 1388 *params = 0; 1389 } 1390 break; 1391 case GL_TEXTURE_DEPTH_SIZE_ARB: 1392 if (!ctx->Extensions.ARB_depth_texture) 1393 goto invalid_pname; 1394 *params = _mesa_get_format_bits(texFormat, pname); 1395 break; 1396 case GL_TEXTURE_STENCIL_SIZE: 1397 *params = _mesa_get_format_bits(texFormat, pname); 1398 break; 1399 case GL_TEXTURE_SHARED_SIZE: 1400 if (ctx->Version < 30 && 1401 !ctx->Extensions.EXT_texture_shared_exponent) 1402 goto invalid_pname; 1403 *params = texFormat == MESA_FORMAT_R9G9B9E5_FLOAT ? 5 : 0; 1404 break; 1405 1406 /* GL_ARB_texture_compression */ 1407 case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: 1408 if (_mesa_is_format_compressed(texFormat) && 1409 !_mesa_is_proxy_texture(target)) { 1410 *params = _mesa_format_image_size(texFormat, img->Width, 1411 img->Height, img->Depth); 1412 } 1413 else { 1414 _mesa_error(ctx, GL_INVALID_OPERATION, 1415 "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, 1416 _mesa_enum_to_string(pname)); 1417 } 1418 break; 1419 case GL_TEXTURE_COMPRESSED: 1420 *params = (GLint) _mesa_is_format_compressed(texFormat); 1421 break; 1422 1423 /* GL_ARB_texture_float */ 1424 case GL_TEXTURE_LUMINANCE_TYPE_ARB: 1425 case GL_TEXTURE_INTENSITY_TYPE_ARB: 1426 if (ctx->API != API_OPENGL_COMPAT) 1427 goto invalid_pname; 1428 /* FALLTHROUGH */ 1429 case GL_TEXTURE_RED_TYPE_ARB: 1430 case GL_TEXTURE_GREEN_TYPE_ARB: 1431 case GL_TEXTURE_BLUE_TYPE_ARB: 1432 case GL_TEXTURE_ALPHA_TYPE_ARB: 1433 case GL_TEXTURE_DEPTH_TYPE_ARB: 1434 if (!ctx->Extensions.ARB_texture_float) 1435 goto invalid_pname; 1436 if (_mesa_base_format_has_channel(img->_BaseFormat, pname)) 1437 *params = _mesa_get_format_datatype(texFormat); 1438 else 1439 *params = GL_NONE; 1440 break; 1441 1442 /* GL_ARB_texture_multisample */ 1443 case GL_TEXTURE_SAMPLES: 1444 if (!ctx->Extensions.ARB_texture_multisample) 1445 goto invalid_pname; 1446 *params = img->NumSamples; 1447 break; 1448 1449 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS: 1450 if (!ctx->Extensions.ARB_texture_multisample) 1451 goto invalid_pname; 1452 *params = img->FixedSampleLocations; 1453 break; 1454 1455 /* There is never a buffer data store here, but these pnames still have 1456 * to work. 1457 */ 1458 1459 /* GL_ARB_texture_buffer_object */ 1460 case GL_TEXTURE_BUFFER_DATA_STORE_BINDING: 1461 if (!ctx->Extensions.ARB_texture_buffer_object) 1462 goto invalid_pname; 1463 *params = 0; 1464 break; 1465 1466 /* GL_ARB_texture_buffer_range */ 1467 case GL_TEXTURE_BUFFER_OFFSET: 1468 if (!ctx->Extensions.ARB_texture_buffer_range) 1469 goto invalid_pname; 1470 *params = 0; 1471 break; 1472 case GL_TEXTURE_BUFFER_SIZE: 1473 if (!ctx->Extensions.ARB_texture_buffer_range) 1474 goto invalid_pname; 1475 *params = 0; 1476 break; 1477 1478 default: 1479 goto invalid_pname; 1480 } 1481 1482 /* no error if we get here */ 1483 return; 1484 1485 invalid_pname: 1486 _mesa_error(ctx, GL_INVALID_ENUM, 1487 "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, 1488 _mesa_enum_to_string(pname)); 1489 } 1490 1491 1492 /** 1493 * Handle a glGetTexLevelParamteriv() call for a texture buffer. 1494 */ 1495 static void 1496 get_tex_level_parameter_buffer(struct gl_context *ctx, 1497 const struct gl_texture_object *texObj, 1498 GLenum pname, GLint *params, bool dsa) 1499 { 1500 const struct gl_buffer_object *bo = texObj->BufferObject; 1501 mesa_format texFormat = texObj->_BufferObjectFormat; 1502 int bytes = MAX2(1, _mesa_get_format_bytes(texFormat)); 1503 GLenum internalFormat = texObj->BufferObjectFormat; 1504 GLenum baseFormat = _mesa_get_format_base_format(texFormat); 1505 const char *suffix = dsa ? "ture" : ""; 1506 1507 assert(texObj->Target == GL_TEXTURE_BUFFER); 1508 1509 if (!bo) { 1510 /* undefined texture buffer object */ 1511 switch (pname) { 1512 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS: 1513 *params = GL_TRUE; 1514 break; 1515 case GL_TEXTURE_INTERNAL_FORMAT: 1516 *params = internalFormat; 1517 break; 1518 default: 1519 *params = 0; 1520 break; 1521 } 1522 return; 1523 } 1524 1525 switch (pname) { 1526 case GL_TEXTURE_BUFFER_DATA_STORE_BINDING: 1527 *params = bo->Name; 1528 break; 1529 case GL_TEXTURE_WIDTH: 1530 *params = ((texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize) 1531 / bytes; 1532 break; 1533 case GL_TEXTURE_HEIGHT: 1534 case GL_TEXTURE_DEPTH: 1535 *params = 1; 1536 break; 1537 case GL_TEXTURE_BORDER: 1538 case GL_TEXTURE_SHARED_SIZE: 1539 case GL_TEXTURE_COMPRESSED: 1540 *params = 0; 1541 break; 1542 case GL_TEXTURE_INTERNAL_FORMAT: 1543 *params = internalFormat; 1544 break; 1545 case GL_TEXTURE_RED_SIZE: 1546 case GL_TEXTURE_GREEN_SIZE: 1547 case GL_TEXTURE_BLUE_SIZE: 1548 case GL_TEXTURE_ALPHA_SIZE: 1549 if (_mesa_base_format_has_channel(baseFormat, pname)) 1550 *params = _mesa_get_format_bits(texFormat, pname); 1551 else 1552 *params = 0; 1553 break; 1554 case GL_TEXTURE_INTENSITY_SIZE: 1555 case GL_TEXTURE_LUMINANCE_SIZE: 1556 if (_mesa_base_format_has_channel(baseFormat, pname)) { 1557 *params = _mesa_get_format_bits(texFormat, pname); 1558 if (*params == 0) { 1559 /* intensity or luminance is probably stored as RGB[A] */ 1560 *params = MIN2(_mesa_get_format_bits(texFormat, 1561 GL_TEXTURE_RED_SIZE), 1562 _mesa_get_format_bits(texFormat, 1563 GL_TEXTURE_GREEN_SIZE)); 1564 } 1565 } else { 1566 *params = 0; 1567 } 1568 break; 1569 case GL_TEXTURE_DEPTH_SIZE_ARB: 1570 case GL_TEXTURE_STENCIL_SIZE_EXT: 1571 *params = _mesa_get_format_bits(texFormat, pname); 1572 break; 1573 1574 /* GL_ARB_texture_buffer_range */ 1575 case GL_TEXTURE_BUFFER_OFFSET: 1576 if (!ctx->Extensions.ARB_texture_buffer_range) 1577 goto invalid_pname; 1578 *params = texObj->BufferOffset; 1579 break; 1580 case GL_TEXTURE_BUFFER_SIZE: 1581 if (!ctx->Extensions.ARB_texture_buffer_range) 1582 goto invalid_pname; 1583 *params = (texObj->BufferSize == -1) ? bo->Size : texObj->BufferSize; 1584 break; 1585 1586 /* GL_ARB_texture_multisample */ 1587 case GL_TEXTURE_SAMPLES: 1588 if (!ctx->Extensions.ARB_texture_multisample) 1589 goto invalid_pname; 1590 *params = 0; 1591 break; 1592 1593 case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS: 1594 if (!ctx->Extensions.ARB_texture_multisample) 1595 goto invalid_pname; 1596 *params = GL_TRUE; 1597 break; 1598 1599 /* GL_ARB_texture_compression */ 1600 case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: 1601 /* Always illegal for GL_TEXTURE_BUFFER */ 1602 _mesa_error(ctx, GL_INVALID_OPERATION, 1603 "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, 1604 _mesa_enum_to_string(pname)); 1605 break; 1606 1607 /* GL_ARB_texture_float */ 1608 case GL_TEXTURE_RED_TYPE_ARB: 1609 case GL_TEXTURE_GREEN_TYPE_ARB: 1610 case GL_TEXTURE_BLUE_TYPE_ARB: 1611 case GL_TEXTURE_ALPHA_TYPE_ARB: 1612 case GL_TEXTURE_LUMINANCE_TYPE_ARB: 1613 case GL_TEXTURE_INTENSITY_TYPE_ARB: 1614 case GL_TEXTURE_DEPTH_TYPE_ARB: 1615 if (!ctx->Extensions.ARB_texture_float) 1616 goto invalid_pname; 1617 if (_mesa_base_format_has_channel(baseFormat, pname)) 1618 *params = _mesa_get_format_datatype(texFormat); 1619 else 1620 *params = GL_NONE; 1621 break; 1622 1623 default: 1624 goto invalid_pname; 1625 } 1626 1627 /* no error if we get here */ 1628 return; 1629 1630 invalid_pname: 1631 _mesa_error(ctx, GL_INVALID_ENUM, 1632 "glGetTex%sLevelParameter[if]v(pname=%s)", suffix, 1633 _mesa_enum_to_string(pname)); 1634 } 1635 1636 static bool 1637 valid_tex_level_parameteriv_target(struct gl_context *ctx, GLenum target, 1638 bool dsa) 1639 { 1640 const char *suffix = dsa ? "ture" : ""; 1641 if (!_mesa_legal_get_tex_level_parameter_target(ctx, target, dsa)) { 1642 _mesa_error(ctx, GL_INVALID_ENUM, 1643 "glGetTex%sLevelParameter[if]v(target=%s)", suffix, 1644 _mesa_enum_to_string(target)); 1645 return false; 1646 } 1647 return true; 1648 } 1649 1650 /** 1651 * This isn't exposed to the rest of the driver because it is a part of the 1652 * OpenGL API that is rarely used. 1653 */ 1654 static void 1655 get_tex_level_parameteriv(struct gl_context *ctx, 1656 struct gl_texture_object *texObj, 1657 GLenum target, GLint level, 1658 GLenum pname, GLint *params, 1659 bool dsa) 1660 { 1661 GLint maxLevels; 1662 const char *suffix = dsa ? "ture" : ""; 1663 1664 /* Check for errors */ 1665 if (ctx->Texture.CurrentUnit >= ctx->Const.MaxCombinedTextureImageUnits) { 1666 _mesa_error(ctx, GL_INVALID_OPERATION, 1667 "glGetTex%sLevelParameter[if]v(" 1668 "current unit >= max combined texture units)", suffix); 1669 return; 1670 } 1671 1672 maxLevels = _mesa_max_texture_levels(ctx, target); 1673 assert(maxLevels != 0); 1674 1675 if (level < 0 || level >= maxLevels) { 1676 _mesa_error(ctx, GL_INVALID_VALUE, 1677 "glGetTex%sLevelParameter[if]v(level out of range)", suffix); 1678 return; 1679 } 1680 1681 /* Get the level parameter */ 1682 if (target == GL_TEXTURE_BUFFER) { 1683 get_tex_level_parameter_buffer(ctx, texObj, pname, params, dsa); 1684 } 1685 else { 1686 get_tex_level_parameter_image(ctx, texObj, target, 1687 level, pname, params, dsa); 1688 } 1689 } 1690 1691 void GLAPIENTRY 1692 _mesa_GetTexLevelParameterfv( GLenum target, GLint level, 1693 GLenum pname, GLfloat *params ) 1694 { 1695 struct gl_texture_object *texObj; 1696 GLint iparam; 1697 GET_CURRENT_CONTEXT(ctx); 1698 1699 if (!valid_tex_level_parameteriv_target(ctx, target, false)) 1700 return; 1701 1702 texObj = _mesa_get_current_tex_object(ctx, target); 1703 if (!texObj) 1704 return; 1705 1706 get_tex_level_parameteriv(ctx, texObj, target, level, 1707 pname, &iparam, false); 1708 1709 *params = (GLfloat) iparam; 1710 } 1711 1712 void GLAPIENTRY 1713 _mesa_GetTexLevelParameteriv( GLenum target, GLint level, 1714 GLenum pname, GLint *params ) 1715 { 1716 struct gl_texture_object *texObj; 1717 GET_CURRENT_CONTEXT(ctx); 1718 1719 if (!valid_tex_level_parameteriv_target(ctx, target, false)) 1720 return; 1721 1722 texObj = _mesa_get_current_tex_object(ctx, target); 1723 if (!texObj) 1724 return; 1725 1726 get_tex_level_parameteriv(ctx, texObj, target, level, 1727 pname, params, false); 1728 } 1729 1730 void GLAPIENTRY 1731 _mesa_GetTextureLevelParameterfv(GLuint texture, GLint level, 1732 GLenum pname, GLfloat *params) 1733 { 1734 struct gl_texture_object *texObj; 1735 GLint iparam; 1736 GET_CURRENT_CONTEXT(ctx); 1737 1738 texObj = _mesa_lookup_texture_err(ctx, texture, 1739 "glGetTextureLevelParameterfv"); 1740 if (!texObj) 1741 return; 1742 1743 if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true)) 1744 return; 1745 1746 get_tex_level_parameteriv(ctx, texObj, texObj->Target, level, 1747 pname, &iparam, true); 1748 1749 *params = (GLfloat) iparam; 1750 } 1751 1752 void GLAPIENTRY 1753 _mesa_GetTextureLevelParameteriv(GLuint texture, GLint level, 1754 GLenum pname, GLint *params) 1755 { 1756 struct gl_texture_object *texObj; 1757 GET_CURRENT_CONTEXT(ctx); 1758 1759 texObj = _mesa_lookup_texture_err(ctx, texture, 1760 "glGetTextureLevelParameteriv"); 1761 if (!texObj) 1762 return; 1763 1764 if (!valid_tex_level_parameteriv_target(ctx, texObj->Target, true)) 1765 return; 1766 1767 get_tex_level_parameteriv(ctx, texObj, texObj->Target, level, 1768 pname, params, true); 1769 } 1770 1771 /** 1772 * This isn't exposed to the rest of the driver because it is a part of the 1773 * OpenGL API that is rarely used. 1774 */ 1775 static void 1776 get_tex_parameterfv(struct gl_context *ctx, 1777 struct gl_texture_object *obj, 1778 GLenum pname, GLfloat *params, bool dsa) 1779 { 1780 _mesa_lock_context_textures(ctx); 1781 switch (pname) { 1782 case GL_TEXTURE_MAG_FILTER: 1783 *params = ENUM_TO_FLOAT(obj->Sampler.MagFilter); 1784 break; 1785 case GL_TEXTURE_MIN_FILTER: 1786 *params = ENUM_TO_FLOAT(obj->Sampler.MinFilter); 1787 break; 1788 case GL_TEXTURE_WRAP_S: 1789 *params = ENUM_TO_FLOAT(obj->Sampler.WrapS); 1790 break; 1791 case GL_TEXTURE_WRAP_T: 1792 *params = ENUM_TO_FLOAT(obj->Sampler.WrapT); 1793 break; 1794 case GL_TEXTURE_WRAP_R: 1795 *params = ENUM_TO_FLOAT(obj->Sampler.WrapR); 1796 break; 1797 case GL_TEXTURE_BORDER_COLOR: 1798 if (ctx->API == API_OPENGLES || 1799 !ctx->Extensions.ARB_texture_border_clamp) 1800 goto invalid_pname; 1801 1802 if (ctx->NewState & (_NEW_BUFFERS | _NEW_FRAG_CLAMP)) 1803 _mesa_update_state_locked(ctx); 1804 if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer)) { 1805 params[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F); 1806 params[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F); 1807 params[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F); 1808 params[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F); 1809 } 1810 else { 1811 params[0] = obj->Sampler.BorderColor.f[0]; 1812 params[1] = obj->Sampler.BorderColor.f[1]; 1813 params[2] = obj->Sampler.BorderColor.f[2]; 1814 params[3] = obj->Sampler.BorderColor.f[3]; 1815 } 1816 break; 1817 case GL_TEXTURE_RESIDENT: 1818 if (ctx->API != API_OPENGL_COMPAT) 1819 goto invalid_pname; 1820 1821 *params = 1.0F; 1822 break; 1823 case GL_TEXTURE_PRIORITY: 1824 if (ctx->API != API_OPENGL_COMPAT) 1825 goto invalid_pname; 1826 1827 *params = obj->Priority; 1828 break; 1829 case GL_TEXTURE_MIN_LOD: 1830 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 1831 goto invalid_pname; 1832 1833 *params = obj->Sampler.MinLod; 1834 break; 1835 case GL_TEXTURE_MAX_LOD: 1836 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 1837 goto invalid_pname; 1838 1839 *params = obj->Sampler.MaxLod; 1840 break; 1841 case GL_TEXTURE_BASE_LEVEL: 1842 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 1843 goto invalid_pname; 1844 1845 *params = (GLfloat) obj->BaseLevel; 1846 break; 1847 case GL_TEXTURE_MAX_LEVEL: 1848 *params = (GLfloat) obj->MaxLevel; 1849 break; 1850 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 1851 if (!ctx->Extensions.EXT_texture_filter_anisotropic) 1852 goto invalid_pname; 1853 *params = obj->Sampler.MaxAnisotropy; 1854 break; 1855 case GL_GENERATE_MIPMAP_SGIS: 1856 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) 1857 goto invalid_pname; 1858 1859 *params = (GLfloat) obj->GenerateMipmap; 1860 break; 1861 case GL_TEXTURE_COMPARE_MODE_ARB: 1862 if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow) 1863 && !_mesa_is_gles3(ctx)) 1864 goto invalid_pname; 1865 *params = (GLfloat) obj->Sampler.CompareMode; 1866 break; 1867 case GL_TEXTURE_COMPARE_FUNC_ARB: 1868 if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow) 1869 && !_mesa_is_gles3(ctx)) 1870 goto invalid_pname; 1871 *params = (GLfloat) obj->Sampler.CompareFunc; 1872 break; 1873 case GL_DEPTH_TEXTURE_MODE_ARB: 1874 /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has 1875 * never existed in OpenGL ES. 1876 */ 1877 if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture) 1878 goto invalid_pname; 1879 *params = (GLfloat) obj->DepthMode; 1880 break; 1881 case GL_DEPTH_STENCIL_TEXTURE_MODE: 1882 if (!_mesa_has_ARB_stencil_texturing(ctx) && !_mesa_is_gles31(ctx)) 1883 goto invalid_pname; 1884 *params = (GLfloat) 1885 (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT); 1886 break; 1887 case GL_TEXTURE_LOD_BIAS: 1888 if (_mesa_is_gles(ctx)) 1889 goto invalid_pname; 1890 1891 *params = obj->Sampler.LodBias; 1892 break; 1893 case GL_TEXTURE_CROP_RECT_OES: 1894 if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture) 1895 goto invalid_pname; 1896 1897 params[0] = (GLfloat) obj->CropRect[0]; 1898 params[1] = (GLfloat) obj->CropRect[1]; 1899 params[2] = (GLfloat) obj->CropRect[2]; 1900 params[3] = (GLfloat) obj->CropRect[3]; 1901 break; 1902 1903 case GL_TEXTURE_SWIZZLE_R_EXT: 1904 case GL_TEXTURE_SWIZZLE_G_EXT: 1905 case GL_TEXTURE_SWIZZLE_B_EXT: 1906 case GL_TEXTURE_SWIZZLE_A_EXT: 1907 if ((!_mesa_is_desktop_gl(ctx) 1908 || !ctx->Extensions.EXT_texture_swizzle) 1909 && !_mesa_is_gles3(ctx)) 1910 goto invalid_pname; 1911 *params = (GLfloat) obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT]; 1912 break; 1913 1914 case GL_TEXTURE_SWIZZLE_RGBA_EXT: 1915 if ((!_mesa_is_desktop_gl(ctx) 1916 || !ctx->Extensions.EXT_texture_swizzle) 1917 && !_mesa_is_gles3(ctx)) { 1918 goto invalid_pname; 1919 } 1920 else { 1921 GLuint comp; 1922 for (comp = 0; comp < 4; comp++) { 1923 params[comp] = (GLfloat) obj->Swizzle[comp]; 1924 } 1925 } 1926 break; 1927 1928 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 1929 if (!_mesa_is_desktop_gl(ctx) 1930 || !ctx->Extensions.AMD_seamless_cubemap_per_texture) 1931 goto invalid_pname; 1932 *params = (GLfloat) obj->Sampler.CubeMapSeamless; 1933 break; 1934 1935 case GL_TEXTURE_IMMUTABLE_FORMAT: 1936 *params = (GLfloat) obj->Immutable; 1937 break; 1938 1939 case GL_TEXTURE_IMMUTABLE_LEVELS: 1940 if (_mesa_is_gles3(ctx) || 1941 (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view)) 1942 *params = (GLfloat) obj->ImmutableLevels; 1943 else 1944 goto invalid_pname; 1945 break; 1946 1947 case GL_TEXTURE_VIEW_MIN_LEVEL: 1948 if (!ctx->Extensions.ARB_texture_view) 1949 goto invalid_pname; 1950 *params = (GLfloat) obj->MinLevel; 1951 break; 1952 1953 case GL_TEXTURE_VIEW_NUM_LEVELS: 1954 if (!ctx->Extensions.ARB_texture_view) 1955 goto invalid_pname; 1956 *params = (GLfloat) obj->NumLevels; 1957 break; 1958 1959 case GL_TEXTURE_VIEW_MIN_LAYER: 1960 if (!ctx->Extensions.ARB_texture_view) 1961 goto invalid_pname; 1962 *params = (GLfloat) obj->MinLayer; 1963 break; 1964 1965 case GL_TEXTURE_VIEW_NUM_LAYERS: 1966 if (!ctx->Extensions.ARB_texture_view) 1967 goto invalid_pname; 1968 *params = (GLfloat) obj->NumLayers; 1969 break; 1970 1971 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: 1972 if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external) 1973 goto invalid_pname; 1974 *params = (GLfloat) obj->RequiredTextureImageUnits; 1975 break; 1976 1977 case GL_TEXTURE_SRGB_DECODE_EXT: 1978 if (!ctx->Extensions.EXT_texture_sRGB_decode) 1979 goto invalid_pname; 1980 *params = (GLfloat) obj->Sampler.sRGBDecode; 1981 break; 1982 1983 case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: 1984 if (!ctx->Extensions.ARB_shader_image_load_store) 1985 goto invalid_pname; 1986 *params = (GLfloat) obj->ImageFormatCompatibilityType; 1987 break; 1988 1989 case GL_TEXTURE_TARGET: 1990 if (ctx->API != API_OPENGL_CORE) 1991 goto invalid_pname; 1992 *params = ENUM_TO_FLOAT(obj->Target); 1993 break; 1994 1995 default: 1996 goto invalid_pname; 1997 } 1998 1999 /* no error if we get here */ 2000 _mesa_unlock_context_textures(ctx); 2001 return; 2002 2003 invalid_pname: 2004 _mesa_unlock_context_textures(ctx); 2005 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTex%sParameterfv(pname=0x%x)", 2006 dsa ? "ture" : "", pname); 2007 } 2008 2009 2010 static void 2011 get_tex_parameteriv(struct gl_context *ctx, 2012 struct gl_texture_object *obj, 2013 GLenum pname, GLint *params, bool dsa) 2014 { 2015 _mesa_lock_texture(ctx, obj); 2016 switch (pname) { 2017 case GL_TEXTURE_MAG_FILTER: 2018 *params = (GLint) obj->Sampler.MagFilter; 2019 break; 2020 case GL_TEXTURE_MIN_FILTER: 2021 *params = (GLint) obj->Sampler.MinFilter; 2022 break; 2023 case GL_TEXTURE_WRAP_S: 2024 *params = (GLint) obj->Sampler.WrapS; 2025 break; 2026 case GL_TEXTURE_WRAP_T: 2027 *params = (GLint) obj->Sampler.WrapT; 2028 break; 2029 case GL_TEXTURE_WRAP_R: 2030 *params = (GLint) obj->Sampler.WrapR; 2031 break; 2032 case GL_TEXTURE_BORDER_COLOR: 2033 if (ctx->API == API_OPENGLES || 2034 !ctx->Extensions.ARB_texture_border_clamp) 2035 goto invalid_pname; 2036 2037 { 2038 GLfloat b[4]; 2039 b[0] = CLAMP(obj->Sampler.BorderColor.f[0], 0.0F, 1.0F); 2040 b[1] = CLAMP(obj->Sampler.BorderColor.f[1], 0.0F, 1.0F); 2041 b[2] = CLAMP(obj->Sampler.BorderColor.f[2], 0.0F, 1.0F); 2042 b[3] = CLAMP(obj->Sampler.BorderColor.f[3], 0.0F, 1.0F); 2043 params[0] = FLOAT_TO_INT(b[0]); 2044 params[1] = FLOAT_TO_INT(b[1]); 2045 params[2] = FLOAT_TO_INT(b[2]); 2046 params[3] = FLOAT_TO_INT(b[3]); 2047 } 2048 break; 2049 case GL_TEXTURE_RESIDENT: 2050 if (ctx->API != API_OPENGL_COMPAT) 2051 goto invalid_pname; 2052 2053 *params = 1; 2054 break; 2055 case GL_TEXTURE_PRIORITY: 2056 if (ctx->API != API_OPENGL_COMPAT) 2057 goto invalid_pname; 2058 2059 *params = FLOAT_TO_INT(obj->Priority); 2060 break; 2061 case GL_TEXTURE_MIN_LOD: 2062 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 2063 goto invalid_pname; 2064 /* GL spec 'Data Conversions' section specifies that floating-point 2065 * value in integer Get function is rounded to nearest integer 2066 */ 2067 *params = IROUND(obj->Sampler.MinLod); 2068 break; 2069 case GL_TEXTURE_MAX_LOD: 2070 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 2071 goto invalid_pname; 2072 /* GL spec 'Data Conversions' section specifies that floating-point 2073 * value in integer Get function is rounded to nearest integer 2074 */ 2075 *params = IROUND(obj->Sampler.MaxLod); 2076 break; 2077 case GL_TEXTURE_BASE_LEVEL: 2078 if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) 2079 goto invalid_pname; 2080 2081 *params = obj->BaseLevel; 2082 break; 2083 case GL_TEXTURE_MAX_LEVEL: 2084 *params = obj->MaxLevel; 2085 break; 2086 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 2087 if (!ctx->Extensions.EXT_texture_filter_anisotropic) 2088 goto invalid_pname; 2089 /* GL spec 'Data Conversions' section specifies that floating-point 2090 * value in integer Get function is rounded to nearest integer 2091 */ 2092 *params = IROUND(obj->Sampler.MaxAnisotropy); 2093 break; 2094 case GL_GENERATE_MIPMAP_SGIS: 2095 if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) 2096 goto invalid_pname; 2097 2098 *params = (GLint) obj->GenerateMipmap; 2099 break; 2100 case GL_TEXTURE_COMPARE_MODE_ARB: 2101 if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow) 2102 && !_mesa_is_gles3(ctx)) 2103 goto invalid_pname; 2104 *params = (GLint) obj->Sampler.CompareMode; 2105 break; 2106 case GL_TEXTURE_COMPARE_FUNC_ARB: 2107 if ((!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.ARB_shadow) 2108 && !_mesa_is_gles3(ctx)) 2109 goto invalid_pname; 2110 *params = (GLint) obj->Sampler.CompareFunc; 2111 break; 2112 case GL_DEPTH_TEXTURE_MODE_ARB: 2113 if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture) 2114 goto invalid_pname; 2115 *params = (GLint) obj->DepthMode; 2116 break; 2117 case GL_DEPTH_STENCIL_TEXTURE_MODE: 2118 if (!_mesa_has_ARB_stencil_texturing(ctx) && !_mesa_is_gles31(ctx)) 2119 goto invalid_pname; 2120 *params = (GLint) 2121 (obj->StencilSampling ? GL_STENCIL_INDEX : GL_DEPTH_COMPONENT); 2122 break; 2123 case GL_TEXTURE_LOD_BIAS: 2124 if (_mesa_is_gles(ctx)) 2125 goto invalid_pname; 2126 2127 /* GL spec 'Data Conversions' section specifies that floating-point 2128 * value in integer Get function is rounded to nearest integer 2129 */ 2130 *params = IROUND(obj->Sampler.LodBias); 2131 break; 2132 case GL_TEXTURE_CROP_RECT_OES: 2133 if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture) 2134 goto invalid_pname; 2135 2136 params[0] = obj->CropRect[0]; 2137 params[1] = obj->CropRect[1]; 2138 params[2] = obj->CropRect[2]; 2139 params[3] = obj->CropRect[3]; 2140 break; 2141 case GL_TEXTURE_SWIZZLE_R_EXT: 2142 case GL_TEXTURE_SWIZZLE_G_EXT: 2143 case GL_TEXTURE_SWIZZLE_B_EXT: 2144 case GL_TEXTURE_SWIZZLE_A_EXT: 2145 if ((!_mesa_is_desktop_gl(ctx) 2146 || !ctx->Extensions.EXT_texture_swizzle) 2147 && !_mesa_is_gles3(ctx)) 2148 goto invalid_pname; 2149 *params = obj->Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT]; 2150 break; 2151 2152 case GL_TEXTURE_SWIZZLE_RGBA_EXT: 2153 if ((!_mesa_is_desktop_gl(ctx) 2154 || !ctx->Extensions.EXT_texture_swizzle) 2155 && !_mesa_is_gles3(ctx)) 2156 goto invalid_pname; 2157 COPY_4V(params, obj->Swizzle); 2158 break; 2159 2160 case GL_TEXTURE_CUBE_MAP_SEAMLESS: 2161 if (!_mesa_is_desktop_gl(ctx) 2162 || !ctx->Extensions.AMD_seamless_cubemap_per_texture) 2163 goto invalid_pname; 2164 *params = (GLint) obj->Sampler.CubeMapSeamless; 2165 break; 2166 2167 case GL_TEXTURE_IMMUTABLE_FORMAT: 2168 *params = (GLint) obj->Immutable; 2169 break; 2170 2171 case GL_TEXTURE_IMMUTABLE_LEVELS: 2172 if (_mesa_is_gles3(ctx) || 2173 (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view)) 2174 *params = obj->ImmutableLevels; 2175 else 2176 goto invalid_pname; 2177 break; 2178 2179 case GL_TEXTURE_VIEW_MIN_LEVEL: 2180 if (!ctx->Extensions.ARB_texture_view) 2181 goto invalid_pname; 2182 *params = (GLint) obj->MinLevel; 2183 break; 2184 2185 case GL_TEXTURE_VIEW_NUM_LEVELS: 2186 if (!ctx->Extensions.ARB_texture_view) 2187 goto invalid_pname; 2188 *params = (GLint) obj->NumLevels; 2189 break; 2190 2191 case GL_TEXTURE_VIEW_MIN_LAYER: 2192 if (!ctx->Extensions.ARB_texture_view) 2193 goto invalid_pname; 2194 *params = (GLint) obj->MinLayer; 2195 break; 2196 2197 case GL_TEXTURE_VIEW_NUM_LAYERS: 2198 if (!ctx->Extensions.ARB_texture_view) 2199 goto invalid_pname; 2200 *params = (GLint) obj->NumLayers; 2201 break; 2202 2203 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: 2204 if (!_mesa_is_gles(ctx) || !ctx->Extensions.OES_EGL_image_external) 2205 goto invalid_pname; 2206 *params = obj->RequiredTextureImageUnits; 2207 break; 2208 2209 case GL_TEXTURE_SRGB_DECODE_EXT: 2210 if (!ctx->Extensions.EXT_texture_sRGB_decode) 2211 goto invalid_pname; 2212 *params = obj->Sampler.sRGBDecode; 2213 break; 2214 2215 case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: 2216 if (!ctx->Extensions.ARB_shader_image_load_store) 2217 goto invalid_pname; 2218 *params = obj->ImageFormatCompatibilityType; 2219 break; 2220 2221 case GL_TEXTURE_TARGET: 2222 if (ctx->API != API_OPENGL_CORE) 2223 goto invalid_pname; 2224 *params = (GLint) obj->Target; 2225 break; 2226 2227 default: 2228 goto invalid_pname; 2229 } 2230 2231 /* no error if we get here */ 2232 _mesa_unlock_texture(ctx, obj); 2233 return; 2234 2235 invalid_pname: 2236 _mesa_unlock_texture(ctx, obj); 2237 _mesa_error(ctx, GL_INVALID_ENUM, "glGetTex%sParameteriv(pname=0x%x)", 2238 dsa ? "ture" : "", pname); 2239 } 2240 2241 static void 2242 get_tex_parameterIiv(struct gl_context *ctx, 2243 struct gl_texture_object *obj, 2244 GLenum pname, GLint *params, bool dsa) 2245 { 2246 switch (pname) { 2247 case GL_TEXTURE_BORDER_COLOR: 2248 COPY_4V(params, obj->Sampler.BorderColor.i); 2249 break; 2250 default: 2251 get_tex_parameteriv(ctx, obj, pname, params, dsa); 2252 } 2253 } 2254 2255 static void 2256 get_tex_parameterIuiv(struct gl_context *ctx, 2257 struct gl_texture_object *obj, 2258 GLenum pname, GLuint *params, bool dsa) 2259 { 2260 switch (pname) { 2261 case GL_TEXTURE_BORDER_COLOR: 2262 COPY_4V(params, obj->Sampler.BorderColor.i); 2263 break; 2264 default: 2265 { 2266 GLint ip[4]; 2267 get_tex_parameteriv(ctx, obj, pname, ip, dsa); 2268 params[0] = ip[0]; 2269 if (pname == GL_TEXTURE_SWIZZLE_RGBA_EXT || 2270 pname == GL_TEXTURE_CROP_RECT_OES) { 2271 params[1] = ip[1]; 2272 params[2] = ip[2]; 2273 params[3] = ip[3]; 2274 } 2275 } 2276 } 2277 } 2278 2279 void GLAPIENTRY 2280 _mesa_GetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) 2281 { 2282 struct gl_texture_object *obj; 2283 GET_CURRENT_CONTEXT(ctx); 2284 2285 obj = get_texobj_by_target(ctx, target, GL_TRUE); 2286 if (!obj) 2287 return; 2288 2289 get_tex_parameterfv(ctx, obj, pname, params, false); 2290 } 2291 2292 void GLAPIENTRY 2293 _mesa_GetTexParameteriv(GLenum target, GLenum pname, GLint *params) 2294 { 2295 struct gl_texture_object *obj; 2296 GET_CURRENT_CONTEXT(ctx); 2297 2298 obj = get_texobj_by_target(ctx, target, GL_TRUE); 2299 if (!obj) 2300 return; 2301 2302 get_tex_parameteriv(ctx, obj, pname, params, false); 2303 } 2304 2305 /** New in GL 3.0 */ 2306 void GLAPIENTRY 2307 _mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params) 2308 { 2309 struct gl_texture_object *texObj; 2310 GET_CURRENT_CONTEXT(ctx); 2311 2312 texObj = get_texobj_by_target(ctx, target, GL_TRUE); 2313 if (!texObj) 2314 return; 2315 2316 get_tex_parameterIiv(ctx, texObj, pname, params, false); 2317 } 2318 2319 2320 /** New in GL 3.0 */ 2321 void GLAPIENTRY 2322 _mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params) 2323 { 2324 struct gl_texture_object *texObj; 2325 GET_CURRENT_CONTEXT(ctx); 2326 2327 texObj = get_texobj_by_target(ctx, target, GL_TRUE); 2328 if (!texObj) 2329 return; 2330 2331 get_tex_parameterIuiv(ctx, texObj, pname, params, false); 2332 } 2333 2334 2335 void GLAPIENTRY 2336 _mesa_GetTextureParameterfv(GLuint texture, GLenum pname, GLfloat *params) 2337 { 2338 struct gl_texture_object *obj; 2339 GET_CURRENT_CONTEXT(ctx); 2340 2341 obj = get_texobj_by_name(ctx, texture, GL_TRUE); 2342 if (!obj) { 2343 /* User passed a non-generated name. */ 2344 _mesa_error(ctx, GL_INVALID_OPERATION, 2345 "glGetTextureParameterfv(texture)"); 2346 return; 2347 } 2348 2349 get_tex_parameterfv(ctx, obj, pname, params, true); 2350 } 2351 2352 void GLAPIENTRY 2353 _mesa_GetTextureParameteriv(GLuint texture, GLenum pname, GLint *params) 2354 { 2355 struct gl_texture_object *obj; 2356 GET_CURRENT_CONTEXT(ctx); 2357 2358 obj = get_texobj_by_name(ctx, texture, GL_TRUE); 2359 if (!obj) { 2360 /* User passed a non-generated name. */ 2361 _mesa_error(ctx, GL_INVALID_OPERATION, 2362 "glGetTextureParameteriv(texture)"); 2363 return; 2364 } 2365 2366 get_tex_parameteriv(ctx, obj, pname, params, true); 2367 } 2368 2369 void GLAPIENTRY 2370 _mesa_GetTextureParameterIiv(GLuint texture, GLenum pname, GLint *params) 2371 { 2372 struct gl_texture_object *texObj; 2373 GET_CURRENT_CONTEXT(ctx); 2374 2375 texObj = get_texobj_by_name(ctx, texture, GL_TRUE); 2376 if (!texObj) { 2377 /* User passed a non-generated name. */ 2378 _mesa_error(ctx, GL_INVALID_OPERATION, 2379 "glGetTextureParameterIiv(texture)"); 2380 return; 2381 } 2382 2383 get_tex_parameterIiv(ctx, texObj, pname, params, true); 2384 } 2385 2386 2387 void GLAPIENTRY 2388 _mesa_GetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint *params) 2389 { 2390 struct gl_texture_object *texObj; 2391 GET_CURRENT_CONTEXT(ctx); 2392 2393 texObj = get_texobj_by_name(ctx, texture, GL_TRUE); 2394 if (!texObj) { 2395 /* User passed a non-generated name. */ 2396 _mesa_error(ctx, GL_INVALID_OPERATION, 2397 "glGetTextureParameterIuiv(texture)"); 2398 return; 2399 } 2400 2401 get_tex_parameterIuiv(ctx, texObj, pname, params, true); 2402 } 2403