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