1/* 2 * Copyright © 2012 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24#include "mtypes.h" 25#include "context.h" 26#include "glformats.h" 27#include "macros.h" 28#include "enums.h" 29#include "fbobject.h" 30#include "formatquery.h" 31#include "teximage.h" 32#include "texparam.h" 33#include "texobj.h" 34#include "get.h" 35#include "genmipmap.h" 36#include "shaderimage.h" 37#include "texcompress.h" 38#include "textureview.h" 39 40static bool 41_is_renderable(struct gl_context *ctx, GLenum internalformat) 42{ 43 /* Section 4.4.4 on page 212 of the GLES 3.0.4 spec says: 44 * 45 * "An internal format is color-renderable if it is one of the 46 * formats from table 3.13 noted as color-renderable or if it 47 * is unsized format RGBA or RGB." 48 * 49 * Therefore, we must accept GL_RGB and GL_RGBA here. 50 */ 51 if (internalformat != GL_RGB && internalformat != GL_RGBA && 52 _mesa_base_fbo_format(ctx, internalformat) == 0) 53 return false; 54 55 return true; 56} 57 58/* Handles the cases where either ARB_internalformat_query or 59 * ARB_internalformat_query2 have to return an error. 60 */ 61static bool 62_legal_parameters(struct gl_context *ctx, GLenum target, GLenum internalformat, 63 GLenum pname, GLsizei bufSize, GLint *params) 64 65{ 66 bool query2 = _mesa_has_ARB_internalformat_query2(ctx); 67 68 /* The ARB_internalformat_query2 spec says: 69 * 70 * "The INVALID_ENUM error is generated if the <target> parameter to 71 * GetInternalformati*v is not one of the targets listed in Table 6.xx. 72 */ 73 switch(target){ 74 case GL_TEXTURE_1D: 75 case GL_TEXTURE_1D_ARRAY: 76 case GL_TEXTURE_2D: 77 case GL_TEXTURE_2D_ARRAY: 78 case GL_TEXTURE_3D: 79 case GL_TEXTURE_CUBE_MAP: 80 case GL_TEXTURE_CUBE_MAP_ARRAY: 81 case GL_TEXTURE_RECTANGLE: 82 case GL_TEXTURE_BUFFER: 83 if (!query2) { 84 /* The ARB_internalformat_query spec says: 85 * 86 * "If the <target> parameter to GetInternalformativ is not one of 87 * TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY 88 * or RENDERBUFFER then an INVALID_ENUM error is generated. 89 */ 90 _mesa_error(ctx, GL_INVALID_ENUM, 91 "glGetInternalformativ(target=%s)", 92 _mesa_enum_to_string(target)); 93 94 return false; 95 } 96 break; 97 98 case GL_RENDERBUFFER: 99 break; 100 101 case GL_TEXTURE_2D_MULTISAMPLE: 102 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 103 /* The non-existence of ARB_texture_multisample is treated in 104 * ARB_internalformat_query implementation like an error. 105 */ 106 if (!query2 && 107 !(_mesa_has_ARB_texture_multisample(ctx) || _mesa_is_gles31(ctx))) { 108 _mesa_error(ctx, GL_INVALID_ENUM, 109 "glGetInternalformativ(target=%s)", 110 _mesa_enum_to_string(target)); 111 112 return false; 113 } 114 break; 115 116 default: 117 _mesa_error(ctx, GL_INVALID_ENUM, 118 "glGetInternalformativ(target=%s)", 119 _mesa_enum_to_string(target)); 120 return false; 121 } 122 123 124 /* The ARB_internalformat_query2 spec says: 125 * 126 * "The INVALID_ENUM error is generated if the <pname> parameter is 127 * not one of the listed possibilities. 128 */ 129 switch(pname){ 130 case GL_SAMPLES: 131 case GL_NUM_SAMPLE_COUNTS: 132 break; 133 134 case GL_SRGB_DECODE_ARB: 135 /* The ARB_internalformat_query2 spec says: 136 * 137 * "If ARB_texture_sRGB_decode or EXT_texture_sRGB_decode or 138 * equivalent functionality is not supported, queries for the 139 * SRGB_DECODE_ARB <pname> set the INVALID_ENUM error. 140 */ 141 if (!_mesa_has_EXT_texture_sRGB_decode(ctx)) { 142 _mesa_error(ctx, GL_INVALID_ENUM, 143 "glGetInternalformativ(pname=%s)", 144 _mesa_enum_to_string(pname)); 145 return false; 146 } 147 /* fallthrough */ 148 case GL_INTERNALFORMAT_SUPPORTED: 149 case GL_INTERNALFORMAT_PREFERRED: 150 case GL_INTERNALFORMAT_RED_SIZE: 151 case GL_INTERNALFORMAT_GREEN_SIZE: 152 case GL_INTERNALFORMAT_BLUE_SIZE: 153 case GL_INTERNALFORMAT_ALPHA_SIZE: 154 case GL_INTERNALFORMAT_DEPTH_SIZE: 155 case GL_INTERNALFORMAT_STENCIL_SIZE: 156 case GL_INTERNALFORMAT_SHARED_SIZE: 157 case GL_INTERNALFORMAT_RED_TYPE: 158 case GL_INTERNALFORMAT_GREEN_TYPE: 159 case GL_INTERNALFORMAT_BLUE_TYPE: 160 case GL_INTERNALFORMAT_ALPHA_TYPE: 161 case GL_INTERNALFORMAT_DEPTH_TYPE: 162 case GL_INTERNALFORMAT_STENCIL_TYPE: 163 case GL_MAX_WIDTH: 164 case GL_MAX_HEIGHT: 165 case GL_MAX_DEPTH: 166 case GL_MAX_LAYERS: 167 case GL_MAX_COMBINED_DIMENSIONS: 168 case GL_COLOR_COMPONENTS: 169 case GL_DEPTH_COMPONENTS: 170 case GL_STENCIL_COMPONENTS: 171 case GL_COLOR_RENDERABLE: 172 case GL_DEPTH_RENDERABLE: 173 case GL_STENCIL_RENDERABLE: 174 case GL_FRAMEBUFFER_RENDERABLE: 175 case GL_FRAMEBUFFER_RENDERABLE_LAYERED: 176 case GL_FRAMEBUFFER_BLEND: 177 case GL_READ_PIXELS: 178 case GL_READ_PIXELS_FORMAT: 179 case GL_READ_PIXELS_TYPE: 180 case GL_TEXTURE_IMAGE_FORMAT: 181 case GL_TEXTURE_IMAGE_TYPE: 182 case GL_GET_TEXTURE_IMAGE_FORMAT: 183 case GL_GET_TEXTURE_IMAGE_TYPE: 184 case GL_MIPMAP: 185 case GL_MANUAL_GENERATE_MIPMAP: 186 case GL_AUTO_GENERATE_MIPMAP: 187 case GL_COLOR_ENCODING: 188 case GL_SRGB_READ: 189 case GL_SRGB_WRITE: 190 case GL_FILTER: 191 case GL_VERTEX_TEXTURE: 192 case GL_TESS_CONTROL_TEXTURE: 193 case GL_TESS_EVALUATION_TEXTURE: 194 case GL_GEOMETRY_TEXTURE: 195 case GL_FRAGMENT_TEXTURE: 196 case GL_COMPUTE_TEXTURE: 197 case GL_TEXTURE_SHADOW: 198 case GL_TEXTURE_GATHER: 199 case GL_TEXTURE_GATHER_SHADOW: 200 case GL_SHADER_IMAGE_LOAD: 201 case GL_SHADER_IMAGE_STORE: 202 case GL_SHADER_IMAGE_ATOMIC: 203 case GL_IMAGE_TEXEL_SIZE: 204 case GL_IMAGE_COMPATIBILITY_CLASS: 205 case GL_IMAGE_PIXEL_FORMAT: 206 case GL_IMAGE_PIXEL_TYPE: 207 case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: 208 case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST: 209 case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST: 210 case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE: 211 case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE: 212 case GL_TEXTURE_COMPRESSED: 213 case GL_TEXTURE_COMPRESSED_BLOCK_WIDTH: 214 case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT: 215 case GL_TEXTURE_COMPRESSED_BLOCK_SIZE: 216 case GL_CLEAR_BUFFER: 217 case GL_TEXTURE_VIEW: 218 case GL_VIEW_COMPATIBILITY_CLASS: 219 case GL_NUM_TILING_TYPES_EXT: 220 case GL_TILING_TYPES_EXT: 221 /* The ARB_internalformat_query spec says: 222 * 223 * "If the <pname> parameter to GetInternalformativ is not SAMPLES 224 * or NUM_SAMPLE_COUNTS, then an INVALID_ENUM error is generated." 225 */ 226 if (!query2) { 227 _mesa_error(ctx, GL_INVALID_ENUM, 228 "glGetInternalformativ(pname=%s)", 229 _mesa_enum_to_string(pname)); 230 231 return false; 232 } 233 break; 234 235 default: 236 _mesa_error(ctx, GL_INVALID_ENUM, 237 "glGetInternalformativ(pname=%s)", 238 _mesa_enum_to_string(pname)); 239 return false; 240 } 241 242 /* The ARB_internalformat_query spec says: 243 * 244 * "If the <bufSize> parameter to GetInternalformativ is negative, then 245 * an INVALID_VALUE error is generated." 246 * 247 * Nothing is said in ARB_internalformat_query2 but we assume the same. 248 */ 249 if (bufSize < 0) { 250 _mesa_error(ctx, GL_INVALID_VALUE, 251 "glGetInternalformativ(target=%s)", 252 _mesa_enum_to_string(target)); 253 return false; 254 } 255 256 /* The ARB_internalformat_query spec says: 257 * 258 * "If the <internalformat> parameter to GetInternalformativ is not 259 * color-, depth- or stencil-renderable, then an INVALID_ENUM error is 260 * generated." 261 */ 262 if (!query2 && !_is_renderable(ctx, internalformat)) { 263 _mesa_error(ctx, GL_INVALID_ENUM, 264 "glGetInternalformativ(internalformat=%s)", 265 _mesa_enum_to_string(internalformat)); 266 return false; 267 } 268 269 return true; 270} 271 272/* Sets the appropriate "unsupported" response as defined by the 273 * ARB_internalformat_query2 spec for each each <pname>. 274 */ 275static void 276_set_default_response(GLenum pname, GLint buffer[16]) 277{ 278 /* The ARB_internalformat_query2 defines which is the reponse best 279 * representing "not supported" or "not applicable" for each <pname>. 280 * 281 * " In general: 282 * - size- or count-based queries will return zero, 283 * - support-, format- or type-based queries will return NONE, 284 * - boolean-based queries will return FALSE, and 285 * - list-based queries return no entries." 286 */ 287 switch(pname) { 288 case GL_SAMPLES: 289 case GL_TILING_TYPES_EXT: 290 break; 291 292 case GL_MAX_COMBINED_DIMENSIONS: 293 /* This value can be a 64-bit value. As the default is the 32-bit query, 294 * we pack 2 32-bit integers. So we need to clean both */ 295 buffer[0] = 0; 296 buffer[1] = 0; 297 break; 298 299 case GL_NUM_SAMPLE_COUNTS: 300 case GL_INTERNALFORMAT_RED_SIZE: 301 case GL_INTERNALFORMAT_GREEN_SIZE: 302 case GL_INTERNALFORMAT_BLUE_SIZE: 303 case GL_INTERNALFORMAT_ALPHA_SIZE: 304 case GL_INTERNALFORMAT_DEPTH_SIZE: 305 case GL_INTERNALFORMAT_STENCIL_SIZE: 306 case GL_INTERNALFORMAT_SHARED_SIZE: 307 case GL_MAX_WIDTH: 308 case GL_MAX_HEIGHT: 309 case GL_MAX_DEPTH: 310 case GL_MAX_LAYERS: 311 case GL_IMAGE_TEXEL_SIZE: 312 case GL_TEXTURE_COMPRESSED_BLOCK_WIDTH: 313 case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT: 314 case GL_TEXTURE_COMPRESSED_BLOCK_SIZE: 315 case GL_NUM_TILING_TYPES_EXT: 316 buffer[0] = 0; 317 break; 318 319 case GL_INTERNALFORMAT_PREFERRED: 320 case GL_INTERNALFORMAT_RED_TYPE: 321 case GL_INTERNALFORMAT_GREEN_TYPE: 322 case GL_INTERNALFORMAT_BLUE_TYPE: 323 case GL_INTERNALFORMAT_ALPHA_TYPE: 324 case GL_INTERNALFORMAT_DEPTH_TYPE: 325 case GL_INTERNALFORMAT_STENCIL_TYPE: 326 case GL_FRAMEBUFFER_RENDERABLE: 327 case GL_FRAMEBUFFER_RENDERABLE_LAYERED: 328 case GL_FRAMEBUFFER_BLEND: 329 case GL_READ_PIXELS: 330 case GL_READ_PIXELS_FORMAT: 331 case GL_READ_PIXELS_TYPE: 332 case GL_TEXTURE_IMAGE_FORMAT: 333 case GL_TEXTURE_IMAGE_TYPE: 334 case GL_GET_TEXTURE_IMAGE_FORMAT: 335 case GL_GET_TEXTURE_IMAGE_TYPE: 336 case GL_MANUAL_GENERATE_MIPMAP: 337 case GL_AUTO_GENERATE_MIPMAP: 338 case GL_COLOR_ENCODING: 339 case GL_SRGB_READ: 340 case GL_SRGB_WRITE: 341 case GL_SRGB_DECODE_ARB: 342 case GL_FILTER: 343 case GL_VERTEX_TEXTURE: 344 case GL_TESS_CONTROL_TEXTURE: 345 case GL_TESS_EVALUATION_TEXTURE: 346 case GL_GEOMETRY_TEXTURE: 347 case GL_FRAGMENT_TEXTURE: 348 case GL_COMPUTE_TEXTURE: 349 case GL_TEXTURE_SHADOW: 350 case GL_TEXTURE_GATHER: 351 case GL_TEXTURE_GATHER_SHADOW: 352 case GL_SHADER_IMAGE_LOAD: 353 case GL_SHADER_IMAGE_STORE: 354 case GL_SHADER_IMAGE_ATOMIC: 355 case GL_IMAGE_COMPATIBILITY_CLASS: 356 case GL_IMAGE_PIXEL_FORMAT: 357 case GL_IMAGE_PIXEL_TYPE: 358 case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: 359 case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST: 360 case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST: 361 case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE: 362 case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE: 363 case GL_CLEAR_BUFFER: 364 case GL_TEXTURE_VIEW: 365 case GL_VIEW_COMPATIBILITY_CLASS: 366 buffer[0] = GL_NONE; 367 break; 368 369 case GL_INTERNALFORMAT_SUPPORTED: 370 case GL_COLOR_COMPONENTS: 371 case GL_DEPTH_COMPONENTS: 372 case GL_STENCIL_COMPONENTS: 373 case GL_COLOR_RENDERABLE: 374 case GL_DEPTH_RENDERABLE: 375 case GL_STENCIL_RENDERABLE: 376 case GL_MIPMAP: 377 case GL_TEXTURE_COMPRESSED: 378 buffer[0] = GL_FALSE; 379 break; 380 381 default: 382 unreachable("invalid 'pname'"); 383 } 384} 385 386static bool 387_is_target_supported(struct gl_context *ctx, GLenum target) 388{ 389 /* The ARB_internalformat_query2 spec says: 390 * 391 * "if a particular type of <target> is not supported by the 392 * implementation the "unsupported" answer should be given. 393 * This is not an error." 394 * 395 * Note that legality of targets has already been verified. 396 */ 397 switch(target){ 398 case GL_TEXTURE_1D: 399 case GL_TEXTURE_2D: 400 case GL_TEXTURE_3D: 401 break; 402 403 case GL_TEXTURE_1D_ARRAY: 404 if (!_mesa_has_EXT_texture_array(ctx)) 405 return false; 406 break; 407 408 case GL_TEXTURE_2D_ARRAY: 409 if (!_mesa_has_EXT_texture_array(ctx)) 410 return false; 411 break; 412 413 case GL_TEXTURE_CUBE_MAP: 414 if (ctx->API != API_OPENGL_CORE && !_mesa_has_ARB_texture_cube_map(ctx)) 415 return false; 416 break; 417 418 case GL_TEXTURE_CUBE_MAP_ARRAY: 419 if (!_mesa_has_ARB_texture_cube_map_array(ctx)) 420 return false; 421 break; 422 423 case GL_TEXTURE_RECTANGLE: 424 if (!_mesa_has_ARB_texture_rectangle(ctx)) 425 return false; 426 break; 427 428 case GL_TEXTURE_BUFFER: 429 if (!_mesa_has_ARB_texture_buffer_object(ctx)) 430 return false; 431 break; 432 433 case GL_RENDERBUFFER: 434 if (!(_mesa_has_ARB_framebuffer_object(ctx) || 435 _mesa_is_gles3(ctx))) 436 return false; 437 break; 438 439 case GL_TEXTURE_2D_MULTISAMPLE: 440 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 441 if (!(_mesa_has_ARB_texture_multisample(ctx) || 442 _mesa_is_gles31(ctx))) 443 return false; 444 break; 445 446 default: 447 unreachable("invalid target"); 448 } 449 450 return true; 451} 452 453static bool 454_is_resource_supported(struct gl_context *ctx, GLenum target, 455 GLenum internalformat, GLenum pname) 456{ 457 /* From the ARB_internalformat_query2 spec: 458 * 459 * In the following descriptions, the term /resource/ is used to generically 460 * refer to an object of the appropriate type that has been created with 461 * <internalformat> and <target>. If the particular <target> and 462 * <internalformat> combination do not make sense, ... the "unsupported" 463 * answer should be given. This is not an error. 464 */ 465 466 /* In the ARB_internalformat_query2 spec wording, some <pnames> do not care 467 * about the /resource/ being supported or not, we return 'true' for those. 468 */ 469 switch (pname) { 470 case GL_INTERNALFORMAT_SUPPORTED: 471 case GL_INTERNALFORMAT_PREFERRED: 472 case GL_COLOR_COMPONENTS: 473 case GL_DEPTH_COMPONENTS: 474 case GL_STENCIL_COMPONENTS: 475 case GL_COLOR_RENDERABLE: 476 case GL_DEPTH_RENDERABLE: 477 case GL_STENCIL_RENDERABLE: 478 return true; 479 default: 480 break; 481 } 482 483 switch(target){ 484 case GL_TEXTURE_1D: 485 case GL_TEXTURE_1D_ARRAY: 486 case GL_TEXTURE_2D: 487 case GL_TEXTURE_2D_ARRAY: 488 case GL_TEXTURE_3D: 489 case GL_TEXTURE_CUBE_MAP: 490 case GL_TEXTURE_CUBE_MAP_ARRAY: 491 case GL_TEXTURE_RECTANGLE: 492 /* Based on what Mesa does for glTexImage1D/2D/3D and 493 * glCompressedTexImage1D/2D/3D functions. 494 */ 495 if (_mesa_base_tex_format(ctx, internalformat) < 0) 496 return false; 497 498 /* additional checks for depth textures */ 499 if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat)) 500 return false; 501 502 /* additional checks for compressed textures */ 503 if (_mesa_is_compressed_format(ctx, internalformat) && 504 !_mesa_target_can_be_compressed(ctx, target, internalformat, NULL)) 505 return false; 506 507 break; 508 case GL_TEXTURE_2D_MULTISAMPLE: 509 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 510 /* Based on what Mesa does for glTexImage2D/3DMultisample, 511 * glTexStorage2D/3DMultisample and 512 * glTextureStorage2D/3DMultisample functions. 513 */ 514 if (!_mesa_is_renderable_texture_format(ctx, internalformat)) 515 return false; 516 517 break; 518 case GL_TEXTURE_BUFFER: 519 /* Based on what Mesa does for the glTexBuffer function. */ 520 if (_mesa_validate_texbuffer_format(ctx, internalformat) == 521 MESA_FORMAT_NONE) 522 return false; 523 524 break; 525 case GL_RENDERBUFFER: 526 /* Based on what Mesa does for glRenderbufferStorage(Multisample) and 527 * glNamedRenderbufferStorage functions. 528 */ 529 if (!_mesa_base_fbo_format(ctx, internalformat)) 530 return false; 531 532 break; 533 default: 534 unreachable("bad target"); 535 } 536 537 return true; 538} 539 540static bool 541_is_internalformat_supported(struct gl_context *ctx, GLenum target, 542 GLenum internalformat) 543{ 544 /* From the ARB_internalformat_query2 specification: 545 * 546 * "- INTERNALFORMAT_SUPPORTED: If <internalformat> is an internal format 547 * that is supported by the implementation in at least some subset of 548 * possible operations, TRUE is written to <params>. If <internalformat> 549 * if not a valid token for any internal format usage, FALSE is returned. 550 * 551 * <internalformats> that must be supported (in GL 4.2 or later) include 552 * the following: 553 * - "sized internal formats" from Table 3.12, 3.13, and 3.15, 554 * - any specific "compressed internal format" from Table 3.14, 555 * - any "image unit format" from Table 3.21. 556 * - any generic "compressed internal format" from Table 3.14, if the 557 * implementation accepts it for any texture specification commands, and 558 * - unsized or base internal format, if the implementation accepts 559 * it for texture or image specification. 560 * 561 * But also: 562 * "If the particualar <target> and <internalformat> combination do not make 563 * sense, or if a particular type of <target> is not supported by the 564 * implementation the "unsupported" answer should be given. This is not an 565 * error. 566 */ 567 GLint buffer[1]; 568 569 if (target == GL_RENDERBUFFER) { 570 if (_mesa_base_fbo_format(ctx, internalformat) == 0) { 571 return false; 572 } 573 } else if (target == GL_TEXTURE_BUFFER) { 574 if (_mesa_validate_texbuffer_format(ctx, internalformat) == 575 MESA_FORMAT_NONE) { 576 return false; 577 } 578 } else { 579 if (_mesa_base_tex_format(ctx, internalformat) < 0) { 580 return false; 581 } 582 } 583 584 /* Let the driver have the final word */ 585 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, 586 GL_INTERNALFORMAT_SUPPORTED, buffer); 587 588 return (buffer[0] == GL_TRUE); 589} 590 591static bool 592_legal_target_for_framebuffer_texture_layer(struct gl_context *ctx, 593 GLenum target) 594{ 595 switch (target) { 596 case GL_TEXTURE_3D: 597 case GL_TEXTURE_1D_ARRAY: 598 case GL_TEXTURE_2D_ARRAY: 599 case GL_TEXTURE_CUBE_MAP_ARRAY: 600 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 601 case GL_TEXTURE_CUBE_MAP: 602 return true; 603 default: 604 return false; 605 } 606} 607 608static GLenum 609_mesa_generic_type_for_internal_format(GLenum internalFormat) 610{ 611 if (_mesa_is_enum_format_unsigned_int(internalFormat)) 612 return GL_UNSIGNED_BYTE; 613 else if (_mesa_is_enum_format_signed_int(internalFormat)) 614 return GL_BYTE; 615 else 616 return GL_FLOAT; 617} 618 619/* default implementation of QueryInternalFormat driverfunc, for 620 * drivers not implementing ARB_internalformat_query2. 621 */ 622void 623_mesa_query_internal_format_default(struct gl_context *ctx, GLenum target, 624 GLenum internalFormat, GLenum pname, 625 GLint *params) 626{ 627 (void) target; 628 629 switch (pname) { 630 case GL_SAMPLES: 631 case GL_NUM_SAMPLE_COUNTS: 632 params[0] = 1; 633 break; 634 635 case GL_INTERNALFORMAT_SUPPORTED: 636 params[0] = GL_TRUE; 637 break; 638 639 case GL_INTERNALFORMAT_PREFERRED: 640 params[0] = internalFormat; 641 break; 642 643 case GL_READ_PIXELS_FORMAT: { 644 GLenum base_format = _mesa_base_tex_format(ctx, internalFormat); 645 switch (base_format) { 646 case GL_STENCIL_INDEX: 647 case GL_DEPTH_COMPONENT: 648 case GL_DEPTH_STENCIL: 649 case GL_RED: 650 case GL_RGB: 651 case GL_BGR: 652 case GL_RGBA: 653 case GL_BGRA: 654 params[0] = base_format; 655 break; 656 default: 657 params[0] = GL_NONE; 658 break; 659 } 660 break; 661 } 662 663 case GL_READ_PIXELS_TYPE: 664 case GL_TEXTURE_IMAGE_TYPE: 665 case GL_GET_TEXTURE_IMAGE_TYPE: { 666 GLenum base_format = _mesa_base_tex_format(ctx, internalFormat); 667 if (base_format > 0) 668 params[0] = _mesa_generic_type_for_internal_format(internalFormat); 669 else 670 params[0] = GL_NONE; 671 break; 672 } 673 674 case GL_TEXTURE_IMAGE_FORMAT: 675 case GL_GET_TEXTURE_IMAGE_FORMAT: { 676 GLenum format = GL_NONE; 677 GLenum base_format = _mesa_base_tex_format(ctx, internalFormat); 678 if (base_format > 0) { 679 if (_mesa_is_enum_format_integer(internalFormat)) 680 format = _mesa_base_format_to_integer_format(base_format); 681 else 682 format = base_format; 683 } 684 685 params[0] = format; 686 break; 687 } 688 689 case GL_MANUAL_GENERATE_MIPMAP: 690 case GL_AUTO_GENERATE_MIPMAP: 691 case GL_SRGB_READ: 692 case GL_SRGB_WRITE: 693 case GL_SRGB_DECODE_ARB: 694 case GL_VERTEX_TEXTURE: 695 case GL_TESS_CONTROL_TEXTURE: 696 case GL_TESS_EVALUATION_TEXTURE: 697 case GL_GEOMETRY_TEXTURE: 698 case GL_FRAGMENT_TEXTURE: 699 case GL_COMPUTE_TEXTURE: 700 case GL_SHADER_IMAGE_LOAD: 701 case GL_SHADER_IMAGE_STORE: 702 case GL_SHADER_IMAGE_ATOMIC: 703 case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST: 704 case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST: 705 case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE: 706 case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE: 707 case GL_CLEAR_BUFFER: 708 case GL_TEXTURE_VIEW: 709 case GL_TEXTURE_SHADOW: 710 case GL_TEXTURE_GATHER: 711 case GL_TEXTURE_GATHER_SHADOW: 712 case GL_FRAMEBUFFER_RENDERABLE: 713 case GL_FRAMEBUFFER_RENDERABLE_LAYERED: 714 case GL_FRAMEBUFFER_BLEND: 715 case GL_FILTER: 716 /* 717 * TODO seems a tad optimistic just saying yes to everything here. 718 * Even for combinations which make no sense... 719 * And things like TESS_CONTROL_TEXTURE should definitely default to 720 * NONE if the driver doesn't even support tessellation... 721 */ 722 params[0] = GL_FULL_SUPPORT; 723 break; 724 case GL_NUM_TILING_TYPES_EXT: 725 params[0] = 2; 726 break; 727 case GL_TILING_TYPES_EXT: 728 params[0] = GL_OPTIMAL_TILING_EXT; 729 params[1] = GL_LINEAR_TILING_EXT; 730 break; 731 732 default: 733 _set_default_response(pname, params); 734 break; 735 } 736} 737 738/* 739 * For MAX_WIDTH/MAX_HEIGHT/MAX_DEPTH it returns the equivalent GetInteger 740 * pname for a Getinternalformat pname/target combination. target/pname 741 * combinations that would return 0 due dimension number or unsupported status 742 * should be already filtered out 743 * 744 * Note that this means that the returned value would be independent of the 745 * internalformat. This possibility is already mentioned at the Issue 7 of the 746 * arb_internalformat_query2 spec. 747 */ 748static GLenum 749_equivalent_size_pname(GLenum target, 750 GLenum pname) 751{ 752 switch (target) { 753 case GL_TEXTURE_1D: 754 case GL_TEXTURE_2D: 755 case GL_TEXTURE_2D_MULTISAMPLE: 756 return GL_MAX_TEXTURE_SIZE; 757 case GL_TEXTURE_3D: 758 return GL_MAX_3D_TEXTURE_SIZE; 759 case GL_TEXTURE_CUBE_MAP: 760 return GL_MAX_CUBE_MAP_TEXTURE_SIZE; 761 case GL_TEXTURE_RECTANGLE: 762 return GL_MAX_RECTANGLE_TEXTURE_SIZE; 763 case GL_RENDERBUFFER: 764 return GL_MAX_RENDERBUFFER_SIZE; 765 case GL_TEXTURE_1D_ARRAY: 766 if (pname == GL_MAX_HEIGHT) 767 return GL_MAX_ARRAY_TEXTURE_LAYERS; 768 else 769 return GL_MAX_TEXTURE_SIZE; 770 case GL_TEXTURE_2D_ARRAY: 771 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 772 if (pname == GL_MAX_DEPTH) 773 return GL_MAX_ARRAY_TEXTURE_LAYERS; 774 else 775 return GL_MAX_TEXTURE_SIZE; 776 case GL_TEXTURE_CUBE_MAP_ARRAY: 777 if (pname == GL_MAX_DEPTH) 778 return GL_MAX_ARRAY_TEXTURE_LAYERS; 779 else 780 return GL_MAX_CUBE_MAP_TEXTURE_SIZE; 781 case GL_TEXTURE_BUFFER: 782 return GL_MAX_TEXTURE_BUFFER_SIZE; 783 default: 784 return 0; 785 } 786} 787 788/* 789 * Returns the dimensions associated to a target. GL_TEXTURE_BUFFER and 790 * GL_RENDERBUFFER have associated a dimension, but they are not textures 791 * per-se, so we can't just call _mesa_get_texture_dimension directly. 792 */ 793static GLint 794_get_target_dimensions(GLenum target) 795{ 796 switch(target) { 797 case GL_TEXTURE_BUFFER: 798 return 1; 799 case GL_RENDERBUFFER: 800 return 2; 801 default: 802 return _mesa_get_texture_dimensions(target); 803 } 804} 805 806/* 807 * Returns the minimum amount of dimensions associated to a pname. So for 808 * example, if querying GL_MAX_HEIGHT, it is assumed that your target would 809 * have as minimum 2 dimensions. 810 * 811 * Useful to handle sentences like this from query2 spec: 812 * 813 * "MAX_HEIGHT: 814 * <skip> 815 * If the resource does not have at least two dimensions 816 * <skip>." 817 */ 818static GLint 819_get_min_dimensions(GLenum pname) 820{ 821 switch(pname) { 822 case GL_MAX_WIDTH: 823 return 1; 824 case GL_MAX_HEIGHT: 825 return 2; 826 case GL_MAX_DEPTH: 827 return 3; 828 default: 829 return 0; 830 } 831} 832 833/* 834 * Similar to teximage.c:check_multisample_target, but independent of the 835 * dimensions. 836 */ 837static bool 838_is_multisample_target(GLenum target) 839{ 840 switch(target) { 841 case GL_TEXTURE_2D_MULTISAMPLE: 842 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 843 return true; 844 default: 845 return false; 846 } 847 848} 849 850void GLAPIENTRY 851_mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, 852 GLsizei bufSize, GLint *params) 853{ 854 GLint buffer[16]; 855 GET_CURRENT_CONTEXT(ctx); 856 857 ASSERT_OUTSIDE_BEGIN_END(ctx); 858 859 /* ARB_internalformat_query is also mandatory for ARB_internalformat_query2 */ 860 if (!(_mesa_has_ARB_internalformat_query(ctx) || 861 _mesa_is_gles3(ctx))) { 862 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInternalformativ"); 863 return; 864 } 865 866 assert(ctx->Driver.QueryInternalFormat != NULL); 867 868 if (!_legal_parameters(ctx, target, internalformat, pname, bufSize, params)) 869 return; 870 871 /* initialize the contents of the temporary buffer */ 872 memcpy(buffer, params, MIN2(bufSize, 16) * sizeof(GLint)); 873 874 /* Use the 'unsupported' response defined by the spec for every pname 875 * as the default answer. 876 */ 877 _set_default_response(pname, buffer); 878 879 if (!_is_target_supported(ctx, target) || 880 !_is_internalformat_supported(ctx, target, internalformat) || 881 !_is_resource_supported(ctx, target, internalformat, pname)) 882 goto end; 883 884 switch (pname) { 885 case GL_SAMPLES: 886 /* fall-through */ 887 case GL_NUM_SAMPLE_COUNTS: 888 /* The ARB_internalformat_query2 sets the response as 'unsupported' for 889 * SAMPLES and NUM_SAMPLE_COUNTS: 890 * 891 * "If <internalformat> is not color-renderable, depth-renderable, or 892 * stencil-renderable (as defined in section 4.4.4), or if <target> 893 * does not support multiple samples (ie other than 894 * TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY, 895 * or RENDERBUFFER)." 896 */ 897 if ((target != GL_RENDERBUFFER && 898 target != GL_TEXTURE_2D_MULTISAMPLE && 899 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) || 900 !_is_renderable(ctx, internalformat)) 901 goto end; 902 903 /* The GL ES 3.0 specification, section 6.1.15 page 236 says: 904 * 905 * "Since multisampling is not supported for signed and unsigned 906 * integer internal formats, the value of NUM_SAMPLE_COUNTS will be 907 * zero for such formats. 908 * 909 * Since OpenGL ES 3.1 adds support for multisampled integer formats, we 910 * have to check the version for 30 exactly. 911 */ 912 if (pname == GL_NUM_SAMPLE_COUNTS && ctx->API == API_OPENGLES2 && 913 ctx->Version == 30 && _mesa_is_enum_format_integer(internalformat)) { 914 goto end; 915 } 916 917 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 918 buffer); 919 break; 920 921 case GL_INTERNALFORMAT_SUPPORTED: 922 /* Having a supported <internalformat> is implemented as a prerequisite 923 * for all the <pnames>. Thus, if we reach this point, the internalformat is 924 * supported. 925 */ 926 buffer[0] = GL_TRUE; 927 break; 928 929 case GL_INTERNALFORMAT_PREFERRED: 930 /* The ARB_internalformat_query2 spec says: 931 * 932 * "- INTERNALFORMAT_PREFERRED: The implementation-preferred internal 933 * format for representing resources of the specified <internalformat> is 934 * returned in <params>. 935 * 936 * Therefore, we let the driver answer. Note that if we reach this 937 * point, it means that the internalformat is supported, so the driver 938 * is called just to try to get a preferred format. If not supported, 939 * GL_NONE was already returned and the driver is not called. 940 */ 941 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 942 buffer); 943 break; 944 945 case GL_INTERNALFORMAT_RED_SIZE: 946 case GL_INTERNALFORMAT_GREEN_SIZE: 947 case GL_INTERNALFORMAT_BLUE_SIZE: 948 case GL_INTERNALFORMAT_ALPHA_SIZE: 949 case GL_INTERNALFORMAT_DEPTH_SIZE: 950 case GL_INTERNALFORMAT_STENCIL_SIZE: 951 case GL_INTERNALFORMAT_SHARED_SIZE: 952 case GL_INTERNALFORMAT_RED_TYPE: 953 case GL_INTERNALFORMAT_GREEN_TYPE: 954 case GL_INTERNALFORMAT_BLUE_TYPE: 955 case GL_INTERNALFORMAT_ALPHA_TYPE: 956 case GL_INTERNALFORMAT_DEPTH_TYPE: 957 case GL_INTERNALFORMAT_STENCIL_TYPE: { 958 GLint baseformat; 959 mesa_format texformat; 960 961 if (target != GL_RENDERBUFFER) { 962 baseformat = _mesa_base_tex_format(ctx, internalformat); 963 } else { 964 baseformat = _mesa_base_fbo_format(ctx, internalformat); 965 } 966 967 /* Let the driver choose the texture format. 968 * 969 * Disclaimer: I am considering that drivers use for renderbuffers the 970 * same format-choice logic as for textures. 971 */ 972 texformat = ctx->Driver.ChooseTextureFormat(ctx, target, internalformat, 973 GL_NONE /*format */, GL_NONE /* type */); 974 975 if (texformat == MESA_FORMAT_NONE || baseformat <= 0) 976 goto end; 977 978 /* Implementation based on what Mesa does for glGetTexLevelParameteriv 979 * and glGetRenderbufferParameteriv functions. 980 */ 981 if (pname == GL_INTERNALFORMAT_SHARED_SIZE) { 982 if (texformat == MESA_FORMAT_R9G9B9E5_FLOAT) { 983 buffer[0] = 5; 984 } 985 goto end; 986 } 987 988 if (!_mesa_base_format_has_channel(baseformat, pname)) 989 goto end; 990 991 switch (pname) { 992 case GL_INTERNALFORMAT_DEPTH_SIZE: 993 if (ctx->API != API_OPENGL_CORE && 994 !_mesa_has_ARB_depth_texture(ctx) && 995 target != GL_RENDERBUFFER && 996 target != GL_TEXTURE_BUFFER) 997 goto end; 998 /* fallthrough */ 999 case GL_INTERNALFORMAT_RED_SIZE: 1000 case GL_INTERNALFORMAT_GREEN_SIZE: 1001 case GL_INTERNALFORMAT_BLUE_SIZE: 1002 case GL_INTERNALFORMAT_ALPHA_SIZE: 1003 case GL_INTERNALFORMAT_STENCIL_SIZE: 1004 buffer[0] = _mesa_get_format_bits(texformat, pname); 1005 break; 1006 1007 case GL_INTERNALFORMAT_DEPTH_TYPE: 1008 if (!_mesa_has_ARB_texture_float(ctx)) 1009 goto end; 1010 /* fallthrough */ 1011 case GL_INTERNALFORMAT_RED_TYPE: 1012 case GL_INTERNALFORMAT_GREEN_TYPE: 1013 case GL_INTERNALFORMAT_BLUE_TYPE: 1014 case GL_INTERNALFORMAT_ALPHA_TYPE: 1015 case GL_INTERNALFORMAT_STENCIL_TYPE: 1016 buffer[0] = _mesa_get_format_datatype(texformat); 1017 break; 1018 1019 default: 1020 break; 1021 1022 } 1023 break; 1024 } 1025 1026 /* For WIDTH/HEIGHT/DEPTH/LAYERS there is no reason to think that the 1027 * returned values should be different to the values returned by 1028 * GetInteger with MAX_TEXTURE_SIZE, MAX_3D_TEXTURE_SIZE, etc.*/ 1029 case GL_MAX_WIDTH: 1030 case GL_MAX_HEIGHT: 1031 case GL_MAX_DEPTH: { 1032 GLenum get_pname; 1033 GLint dimensions; 1034 GLint min_dimensions; 1035 1036 /* From query2:MAX_HEIGHT spec (as example): 1037 * 1038 * "If the resource does not have at least two dimensions, or if the 1039 * resource is unsupported, zero is returned." 1040 */ 1041 dimensions = _get_target_dimensions(target); 1042 min_dimensions = _get_min_dimensions(pname); 1043 if (dimensions < min_dimensions) 1044 goto end; 1045 1046 get_pname = _equivalent_size_pname(target, pname); 1047 if (get_pname == 0) 1048 goto end; 1049 1050 _mesa_GetIntegerv(get_pname, buffer); 1051 break; 1052 } 1053 1054 case GL_MAX_LAYERS: 1055 if (!_mesa_has_EXT_texture_array(ctx)) 1056 goto end; 1057 1058 if (!_mesa_is_array_texture(target)) 1059 goto end; 1060 1061 _mesa_GetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, buffer); 1062 break; 1063 1064 case GL_MAX_COMBINED_DIMENSIONS:{ 1065 GLint64 combined_value = 1; 1066 GLenum max_dimensions_pnames[] = { 1067 GL_MAX_WIDTH, 1068 GL_MAX_HEIGHT, 1069 GL_MAX_DEPTH, 1070 GL_SAMPLES 1071 }; 1072 unsigned i; 1073 GLint current_value; 1074 1075 /* Combining the dimensions. Note that for array targets, this would 1076 * automatically include the value of MAX_LAYERS, as that value is 1077 * returned as MAX_HEIGHT or MAX_DEPTH */ 1078 for (i = 0; i < 4; i++) { 1079 if (max_dimensions_pnames[i] == GL_SAMPLES && 1080 !_is_multisample_target(target)) 1081 continue; 1082 1083 _mesa_GetInternalformativ(target, internalformat, 1084 max_dimensions_pnames[i], 1085 1, ¤t_value); 1086 1087 if (current_value != 0) 1088 combined_value *= current_value; 1089 } 1090 1091 if (_mesa_is_cube_map_texture(target)) 1092 combined_value *= 6; 1093 1094 /* We pack the 64-bit value on two 32-bit values. Calling the 32-bit 1095 * query, this would work as far as the value can be hold on a 32-bit 1096 * signed integer. For the 64-bit query, the wrapper around the 32-bit 1097 * query will unpack the value */ 1098 memcpy(buffer, &combined_value, sizeof(GLint64)); 1099 break; 1100 } 1101 1102 case GL_COLOR_COMPONENTS: 1103 /* The ARB_internalformat_query2 spec says: 1104 * 1105 * "- COLOR_COMPONENTS: If the internal format contains any color 1106 * components (R, G, B, or A), TRUE is returned in <params>. 1107 * If the internal format is unsupported or contains no color 1108 * components, FALSE is returned." 1109 */ 1110 if (_mesa_is_color_format(internalformat)) 1111 buffer[0] = GL_TRUE; 1112 break; 1113 1114 case GL_DEPTH_COMPONENTS: 1115 /* The ARB_internalformat_query2 spec says: 1116 * 1117 * "- DEPTH_COMPONENTS: If the internal format contains a depth 1118 * component (D), TRUE is returned in <params>. If the internal format 1119 * is unsupported or contains no depth component, FALSE is returned." 1120 */ 1121 if (_mesa_is_depth_format(internalformat) || 1122 _mesa_is_depthstencil_format(internalformat)) 1123 buffer[0] = GL_TRUE; 1124 break; 1125 1126 case GL_STENCIL_COMPONENTS: 1127 /* The ARB_internalformat_query2 spec says: 1128 * 1129 * "- STENCIL_COMPONENTS: If the internal format contains a stencil 1130 * component (S), TRUE is returned in <params>. If the internal format 1131 * is unsupported or contains no stencil component, FALSE is returned. 1132 */ 1133 if (_mesa_is_stencil_format(internalformat) || 1134 _mesa_is_depthstencil_format(internalformat)) 1135 buffer[0] = GL_TRUE; 1136 break; 1137 1138 case GL_COLOR_RENDERABLE: 1139 case GL_DEPTH_RENDERABLE: 1140 case GL_STENCIL_RENDERABLE: 1141 if (!_is_renderable(ctx, internalformat)) 1142 goto end; 1143 1144 if (pname == GL_COLOR_RENDERABLE) { 1145 if (!_mesa_is_color_format(internalformat)) 1146 goto end; 1147 } else { 1148 GLenum baseFormat = _mesa_base_fbo_format(ctx, internalformat); 1149 if (baseFormat != GL_DEPTH_STENCIL && 1150 ((pname == GL_DEPTH_RENDERABLE && baseFormat != GL_DEPTH_COMPONENT) || 1151 (pname == GL_STENCIL_RENDERABLE && baseFormat != GL_STENCIL_INDEX))) 1152 goto end; 1153 } 1154 1155 buffer[0] = GL_TRUE; 1156 break; 1157 1158 case GL_FRAMEBUFFER_RENDERABLE_LAYERED: 1159 if (!_mesa_has_EXT_texture_array(ctx) || 1160 _legal_target_for_framebuffer_texture_layer(ctx, target)) 1161 goto end; 1162 /* fallthrough */ 1163 case GL_FRAMEBUFFER_RENDERABLE: 1164 case GL_FRAMEBUFFER_BLEND: 1165 if (!_mesa_has_ARB_framebuffer_object(ctx)) 1166 goto end; 1167 1168 if (target == GL_TEXTURE_BUFFER || 1169 !_is_renderable(ctx, internalformat)) 1170 goto end; 1171 1172 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1173 buffer); 1174 break; 1175 1176 case GL_READ_PIXELS: 1177 case GL_READ_PIXELS_FORMAT: 1178 case GL_READ_PIXELS_TYPE: 1179 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1180 buffer); 1181 break; 1182 1183 case GL_TEXTURE_IMAGE_FORMAT: 1184 case GL_GET_TEXTURE_IMAGE_FORMAT: 1185 case GL_TEXTURE_IMAGE_TYPE: 1186 case GL_GET_TEXTURE_IMAGE_TYPE: 1187 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1188 buffer); 1189 break; 1190 1191 case GL_MIPMAP: 1192 case GL_MANUAL_GENERATE_MIPMAP: 1193 case GL_AUTO_GENERATE_MIPMAP: 1194 if (!_mesa_is_valid_generate_texture_mipmap_target(ctx, target) || 1195 !_mesa_is_valid_generate_texture_mipmap_internalformat(ctx, 1196 internalformat)) { 1197 goto end; 1198 } 1199 1200 if (pname == GL_MIPMAP) { 1201 buffer[0] = GL_TRUE; 1202 goto end; 1203 } 1204 else if (pname == GL_MANUAL_GENERATE_MIPMAP) { 1205 if (!_mesa_has_ARB_framebuffer_object(ctx)) 1206 goto end; 1207 } 1208 else { 1209 /* From ARB_internalformat_query2: 1210 * "Dependencies on OpenGL 3.2 (Core Profile) 1211 * In core profiles for OpenGL 3.2 and later versions, queries 1212 * for the AUTO_GENERATE_MIPMAP <pname> return the appropriate 1213 * unsupported response." 1214 */ 1215 if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 32) 1216 goto end; 1217 } 1218 1219 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1220 buffer); 1221 break; 1222 1223 case GL_COLOR_ENCODING: 1224 if (!_mesa_is_color_format(internalformat)) 1225 goto end; 1226 1227 if (_mesa_is_srgb_format(internalformat)) 1228 buffer[0] = GL_SRGB; 1229 else 1230 buffer[0] = GL_LINEAR; 1231 break; 1232 1233 case GL_SRGB_READ: 1234 if (!_mesa_has_EXT_texture_sRGB(ctx) || 1235 !_mesa_is_srgb_format(internalformat)) { 1236 goto end; 1237 } 1238 1239 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1240 buffer); 1241 break; 1242 1243 case GL_SRGB_WRITE: 1244 if (!ctx->Extensions.EXT_sRGB || 1245 !_mesa_is_color_format(internalformat)) { 1246 goto end; 1247 } 1248 1249 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1250 buffer); 1251 break; 1252 1253 case GL_SRGB_DECODE_ARB: 1254 /* Presence of EXT_texture_sRGB_decode was already verified */ 1255 if (!_mesa_has_EXT_texture_sRGB(ctx) || 1256 target == GL_RENDERBUFFER || 1257 !_mesa_is_srgb_format(internalformat)) { 1258 goto end; 1259 } 1260 1261 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1262 buffer); 1263 break; 1264 1265 case GL_FILTER: 1266 /* If it doesn't allow to set sampler parameters then it would not allow 1267 * to set a filter different to GL_NEAREST. In practice, this method 1268 * only filters out MULTISAMPLE/MULTISAMPLE_ARRAY */ 1269 if (!_mesa_target_allows_setting_sampler_parameters(target)) 1270 goto end; 1271 1272 if (_mesa_is_enum_format_integer(internalformat)) 1273 goto end; 1274 1275 if (target == GL_TEXTURE_BUFFER) 1276 goto end; 1277 1278 /* At this point we know that multi-texel filtering is supported. We 1279 * need to call the driver to know if it is CAVEAT_SUPPORT or 1280 * FULL_SUPPORT. 1281 */ 1282 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1283 buffer); 1284 break; 1285 1286 case GL_VERTEX_TEXTURE: 1287 case GL_TESS_CONTROL_TEXTURE: 1288 case GL_TESS_EVALUATION_TEXTURE: 1289 case GL_GEOMETRY_TEXTURE: 1290 case GL_FRAGMENT_TEXTURE: 1291 case GL_COMPUTE_TEXTURE: 1292 if (target == GL_RENDERBUFFER) 1293 goto end; 1294 1295 if ((pname == GL_TESS_CONTROL_TEXTURE || 1296 pname == GL_TESS_EVALUATION_TEXTURE) && 1297 !_mesa_has_tessellation(ctx)) 1298 goto end; 1299 1300 if (pname == GL_GEOMETRY_TEXTURE && !_mesa_has_geometry_shaders(ctx)) 1301 goto end; 1302 1303 if (pname == GL_COMPUTE_TEXTURE && !_mesa_has_compute_shaders(ctx)) 1304 goto end; 1305 1306 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1307 buffer); 1308 break; 1309 1310 case GL_TEXTURE_GATHER: 1311 case GL_TEXTURE_GATHER_SHADOW: 1312 if (!_mesa_has_ARB_texture_gather(ctx)) 1313 goto end; 1314 1315 /* fallthrough */ 1316 case GL_TEXTURE_SHADOW: 1317 /* Only depth or depth-stencil image formats make sense in shadow 1318 samplers */ 1319 if (pname != GL_TEXTURE_GATHER && 1320 !_mesa_is_depth_format(internalformat) && 1321 !_mesa_is_depthstencil_format(internalformat)) 1322 goto end; 1323 1324 /* Validate the target for shadow and gather operations */ 1325 switch (target) { 1326 case GL_TEXTURE_2D: 1327 case GL_TEXTURE_2D_ARRAY: 1328 case GL_TEXTURE_CUBE_MAP: 1329 case GL_TEXTURE_CUBE_MAP_ARRAY: 1330 case GL_TEXTURE_RECTANGLE: 1331 break; 1332 1333 case GL_TEXTURE_1D: 1334 case GL_TEXTURE_1D_ARRAY: 1335 /* 1D and 1DArray textures are not admitted in gather operations */ 1336 if (pname != GL_TEXTURE_SHADOW) 1337 goto end; 1338 break; 1339 1340 default: 1341 goto end; 1342 } 1343 1344 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1345 buffer); 1346 break; 1347 1348 case GL_SHADER_IMAGE_LOAD: 1349 case GL_SHADER_IMAGE_STORE: 1350 if (!_mesa_has_ARB_shader_image_load_store(ctx)) 1351 goto end; 1352 1353 /* We call to _mesa_is_shader_image_format_supported 1354 * using "internalformat" as parameter, because the 1355 * the ARB_internalformat_query2 spec says: 1356 * "In this case the <internalformat> is the value of the <format> 1357 * parameter that is passed to BindImageTexture." 1358 */ 1359 if (target == GL_RENDERBUFFER || 1360 !_mesa_is_shader_image_format_supported(ctx, internalformat)) 1361 goto end; 1362 1363 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1364 buffer); 1365 break; 1366 1367 case GL_SHADER_IMAGE_ATOMIC: 1368 if (!_mesa_has_ARB_shader_image_load_store(ctx)) 1369 goto end; 1370 1371 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1372 buffer); 1373 break; 1374 1375 case GL_IMAGE_TEXEL_SIZE: { 1376 mesa_format image_format; 1377 1378 if (!_mesa_has_ARB_shader_image_load_store(ctx) || 1379 target == GL_RENDERBUFFER) 1380 goto end; 1381 1382 image_format = _mesa_get_shader_image_format(internalformat); 1383 if (image_format == MESA_FORMAT_NONE) 1384 goto end; 1385 1386 /* We return bits */ 1387 buffer[0] = (_mesa_get_format_bytes(image_format) * 8); 1388 break; 1389 } 1390 1391 case GL_IMAGE_COMPATIBILITY_CLASS: 1392 if (!_mesa_has_ARB_shader_image_load_store(ctx) || 1393 target == GL_RENDERBUFFER) 1394 goto end; 1395 1396 buffer[0] = _mesa_get_image_format_class(internalformat); 1397 break; 1398 1399 case GL_IMAGE_PIXEL_FORMAT: { 1400 GLint base_format; 1401 1402 if (!_mesa_has_ARB_shader_image_load_store(ctx) || 1403 target == GL_RENDERBUFFER || 1404 !_mesa_is_shader_image_format_supported(ctx, internalformat)) 1405 goto end; 1406 1407 base_format = _mesa_base_tex_format(ctx, internalformat); 1408 if (base_format == -1) 1409 goto end; 1410 1411 if (_mesa_is_enum_format_integer(internalformat)) 1412 buffer[0] = _mesa_base_format_to_integer_format(base_format); 1413 else 1414 buffer[0] = base_format; 1415 break; 1416 } 1417 1418 case GL_IMAGE_PIXEL_TYPE: { 1419 mesa_format image_format; 1420 GLenum datatype; 1421 GLuint comps; 1422 1423 if (!_mesa_has_ARB_shader_image_load_store(ctx) || 1424 target == GL_RENDERBUFFER) 1425 goto end; 1426 1427 image_format = _mesa_get_shader_image_format(internalformat); 1428 if (image_format == MESA_FORMAT_NONE) 1429 goto end; 1430 1431 _mesa_uncompressed_format_to_type_and_comps(image_format, &datatype, 1432 &comps); 1433 if (!datatype) 1434 goto end; 1435 1436 buffer[0] = datatype; 1437 break; 1438 } 1439 1440 case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: { 1441 if (!_mesa_has_ARB_shader_image_load_store(ctx)) 1442 goto end; 1443 1444 /* As pointed by the spec quote below, this pname query should return 1445 * the same value that GetTexParameter. So if the target is not valid 1446 * for GetTexParameter we return the unsupported value. The check below 1447 * is the same target check used by GetTexParameter. 1448 */ 1449 int targetIndex = _mesa_tex_target_to_index(ctx, target); 1450 if (targetIndex < 0 || targetIndex == TEXTURE_BUFFER_INDEX) 1451 goto end; 1452 1453 /* From spec: "Equivalent to calling GetTexParameter with <value> set 1454 * to IMAGE_FORMAT_COMPATIBILITY_TYPE." 1455 * 1456 * GetTexParameter just returns 1457 * tex_obj->ImageFormatCompatibilityType. We create a fake tex_obj 1458 * just with the purpose of getting the value. 1459 */ 1460 struct gl_texture_object *tex_obj = _mesa_new_texture_object(ctx, 0, target); 1461 buffer[0] = tex_obj->ImageFormatCompatibilityType; 1462 _mesa_delete_texture_object(ctx, tex_obj); 1463 1464 break; 1465 } 1466 1467 case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST: 1468 case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST: 1469 case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE: 1470 case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE: 1471 if (target == GL_RENDERBUFFER) 1472 goto end; 1473 1474 if (!_mesa_is_depthstencil_format(internalformat)) { 1475 if (((pname == GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST || 1476 pname == GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE) && 1477 !_mesa_is_depth_format(internalformat)) || 1478 ((pname == GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST || 1479 pname == GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE) && 1480 !_mesa_is_stencil_format(internalformat))) 1481 goto end; 1482 } 1483 1484 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1485 buffer); 1486 break; 1487 1488 case GL_TEXTURE_COMPRESSED: 1489 buffer[0] = _mesa_is_compressed_format(ctx, internalformat); 1490 break; 1491 1492 case GL_TEXTURE_COMPRESSED_BLOCK_WIDTH: 1493 case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT: 1494 case GL_TEXTURE_COMPRESSED_BLOCK_SIZE: { 1495 mesa_format mesaformat; 1496 GLint block_size; 1497 1498 mesaformat = _mesa_glenum_to_compressed_format(internalformat); 1499 if (mesaformat == MESA_FORMAT_NONE) 1500 goto end; 1501 1502 block_size = _mesa_get_format_bytes(mesaformat); 1503 assert(block_size > 0); 1504 1505 if (pname == GL_TEXTURE_COMPRESSED_BLOCK_SIZE) { 1506 buffer[0] = block_size; 1507 } else { 1508 GLuint bwidth, bheight; 1509 1510 /* Returns the width and height in pixels. We return bytes */ 1511 _mesa_get_format_block_size(mesaformat, &bwidth, &bheight); 1512 assert(bwidth > 0 && bheight > 0); 1513 1514 if (pname == GL_TEXTURE_COMPRESSED_BLOCK_WIDTH) 1515 buffer[0] = block_size / bheight; 1516 else 1517 buffer[0] = block_size / bwidth; 1518 } 1519 break; 1520 } 1521 1522 case GL_CLEAR_BUFFER: 1523 if (target != GL_TEXTURE_BUFFER) 1524 goto end; 1525 1526 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1527 buffer); 1528 break; 1529 1530 case GL_TEXTURE_VIEW: 1531 case GL_VIEW_COMPATIBILITY_CLASS: 1532 if (!_mesa_has_ARB_texture_view(ctx) || 1533 target == GL_TEXTURE_BUFFER || 1534 target == GL_RENDERBUFFER) 1535 goto end; 1536 1537 if (pname == GL_TEXTURE_VIEW) { 1538 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1539 buffer); 1540 } else { 1541 GLenum view_class = _mesa_texture_view_lookup_view_class(ctx, 1542 internalformat); 1543 if (view_class == GL_FALSE) 1544 goto end; 1545 1546 buffer[0] = view_class; 1547 } 1548 break; 1549 1550 case GL_NUM_TILING_TYPES_EXT: 1551 case GL_TILING_TYPES_EXT: 1552 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, 1553 buffer); 1554 break; 1555 1556 default: 1557 unreachable("bad param"); 1558 } 1559 1560 end: 1561 if (bufSize != 0 && params == NULL) { 1562 /* Emit a warning to aid application debugging, but go ahead and do the 1563 * memcpy (and probably crash) anyway. 1564 */ 1565 _mesa_warning(ctx, 1566 "glGetInternalformativ(bufSize = %d, but params = NULL)", 1567 bufSize); 1568 } 1569 1570 /* Copy the data from the temporary buffer to the buffer supplied by the 1571 * application. Clamp the size of the copy to the size supplied by the 1572 * application. 1573 */ 1574 memcpy(params, buffer, MIN2(bufSize, 16) * sizeof(GLint)); 1575 1576 return; 1577} 1578 1579void GLAPIENTRY 1580_mesa_GetInternalformati64v(GLenum target, GLenum internalformat, 1581 GLenum pname, GLsizei bufSize, GLint64 *params) 1582{ 1583 GLint params32[16]; 1584 unsigned i; 1585 GLsizei realSize = MIN2(bufSize, 16); 1586 GLsizei callSize; 1587 1588 GET_CURRENT_CONTEXT(ctx); 1589 1590 ASSERT_OUTSIDE_BEGIN_END(ctx); 1591 1592 if (!_mesa_has_ARB_internalformat_query2(ctx)) { 1593 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInternalformati64v"); 1594 return; 1595 } 1596 1597 /* For SAMPLES there are cases where params needs to remain unmodified. As 1598 * no pname can return a negative value, we fill params32 with negative 1599 * values as reference values, that can be used to know what copy-back to 1600 * params */ 1601 for (i = 0; i < realSize; i++) 1602 params32[i] = -1; 1603 1604 /* For GL_MAX_COMBINED_DIMENSIONS we need to get back 2 32-bit integers, 1605 * and at the same time we only need 2. So for that pname, we call the 1606 * 32-bit query with bufSize 2, except on the case of bufSize 0, that is 1607 * basically like asking to not get the value, but that is a caller 1608 * problem. */ 1609 if (pname == GL_MAX_COMBINED_DIMENSIONS && bufSize > 0) 1610 callSize = 2; 1611 else 1612 callSize = bufSize; 1613 1614 _mesa_GetInternalformativ(target, internalformat, pname, callSize, params32); 1615 1616 if (pname == GL_MAX_COMBINED_DIMENSIONS) { 1617 memcpy(params, params32, sizeof(GLint64)); 1618 } else { 1619 for (i = 0; i < realSize; i++) { 1620 /* We only copy back the values that changed */ 1621 if (params32[i] < 0) 1622 break; 1623 params[i] = (GLint64) params32[i]; 1624 } 1625 } 1626} 1627