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