1af69d88dSmrg/*
2af69d88dSmrg * Copyright © 2012 Intel Corporation
3af69d88dSmrg *
4af69d88dSmrg * Permission is hereby granted, free of charge, to any person obtaining a
5af69d88dSmrg * copy of this software and associated documentation files (the "Software"),
6af69d88dSmrg * to deal in the Software without restriction, including without limitation
7af69d88dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8af69d88dSmrg * and/or sell copies of the Software, and to permit persons to whom the
9af69d88dSmrg * Software is furnished to do so, subject to the following conditions:
10af69d88dSmrg *
11af69d88dSmrg * The above copyright notice and this permission notice (including the next
12af69d88dSmrg * paragraph) shall be included in all copies or substantial portions of the
13af69d88dSmrg * Software.
14af69d88dSmrg *
15af69d88dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16af69d88dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17af69d88dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19af69d88dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20af69d88dSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21af69d88dSmrg * DEALINGS IN THE SOFTWARE.
22af69d88dSmrg */
23af69d88dSmrg
24af69d88dSmrg#include "mtypes.h"
25af69d88dSmrg#include "context.h"
26af69d88dSmrg#include "glformats.h"
27af69d88dSmrg#include "macros.h"
28af69d88dSmrg#include "enums.h"
29af69d88dSmrg#include "fbobject.h"
30af69d88dSmrg#include "formatquery.h"
3101e04c3fSmrg#include "teximage.h"
3201e04c3fSmrg#include "texparam.h"
3301e04c3fSmrg#include "texobj.h"
3401e04c3fSmrg#include "get.h"
3501e04c3fSmrg#include "genmipmap.h"
3601e04c3fSmrg#include "shaderimage.h"
3701e04c3fSmrg#include "texcompress.h"
3801e04c3fSmrg#include "textureview.h"
39af69d88dSmrg
4001e04c3fSmrgstatic bool
4101e04c3fSmrg_is_renderable(struct gl_context *ctx, GLenum internalformat)
42af69d88dSmrg{
4301e04c3fSmrg   /*  Section 4.4.4 on page 212 of the  GLES 3.0.4 spec says:
4401e04c3fSmrg    *
4501e04c3fSmrg    *     "An internal format is color-renderable if it is one of the
4601e04c3fSmrg    *     formats from table 3.13 noted as color-renderable or if it
4701e04c3fSmrg    *     is unsized format RGBA or RGB."
4801e04c3fSmrg    *
4901e04c3fSmrg    * Therefore, we must accept GL_RGB and GL_RGBA here.
5001e04c3fSmrg    */
5101e04c3fSmrg   if (internalformat != GL_RGB && internalformat != GL_RGBA &&
5201e04c3fSmrg       _mesa_base_fbo_format(ctx, internalformat) == 0)
5301e04c3fSmrg      return false;
54af69d88dSmrg
5501e04c3fSmrg   return true;
56af69d88dSmrg}
57af69d88dSmrg
5801e04c3fSmrg/* Handles the cases where either ARB_internalformat_query or
5901e04c3fSmrg * ARB_internalformat_query2 have to return an error.
6001e04c3fSmrg */
6101e04c3fSmrgstatic bool
6201e04c3fSmrg_legal_parameters(struct gl_context *ctx, GLenum target, GLenum internalformat,
6301e04c3fSmrg                  GLenum pname, GLsizei bufSize, GLint *params)
64af69d88dSmrg
65af69d88dSmrg{
6601e04c3fSmrg   bool query2 = _mesa_has_ARB_internalformat_query2(ctx);
67af69d88dSmrg
6801e04c3fSmrg   /* The ARB_internalformat_query2 spec says:
69af69d88dSmrg    *
7001e04c3fSmrg    *    "The INVALID_ENUM error is generated if the <target> parameter to
7101e04c3fSmrg    *    GetInternalformati*v is not one of the targets listed in Table 6.xx.
72af69d88dSmrg    */
7301e04c3fSmrg   switch(target){
7401e04c3fSmrg   case GL_TEXTURE_1D:
7501e04c3fSmrg   case GL_TEXTURE_1D_ARRAY:
7601e04c3fSmrg   case GL_TEXTURE_2D:
7701e04c3fSmrg   case GL_TEXTURE_2D_ARRAY:
7801e04c3fSmrg   case GL_TEXTURE_3D:
7901e04c3fSmrg   case GL_TEXTURE_CUBE_MAP:
8001e04c3fSmrg   case GL_TEXTURE_CUBE_MAP_ARRAY:
8101e04c3fSmrg   case GL_TEXTURE_RECTANGLE:
8201e04c3fSmrg   case GL_TEXTURE_BUFFER:
8301e04c3fSmrg      if (!query2) {
8401e04c3fSmrg         /* The ARB_internalformat_query spec says:
8501e04c3fSmrg          *
8601e04c3fSmrg          *     "If the <target> parameter to GetInternalformativ is not one of
8701e04c3fSmrg          *      TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY
8801e04c3fSmrg          *      or RENDERBUFFER then an INVALID_ENUM error is generated.
8901e04c3fSmrg          */
9001e04c3fSmrg         _mesa_error(ctx, GL_INVALID_ENUM,
9101e04c3fSmrg                     "glGetInternalformativ(target=%s)",
9201e04c3fSmrg                     _mesa_enum_to_string(target));
9301e04c3fSmrg
9401e04c3fSmrg         return false;
9501e04c3fSmrg      }
9601e04c3fSmrg      break;
9701e04c3fSmrg
98af69d88dSmrg   case GL_RENDERBUFFER:
99af69d88dSmrg      break;
100af69d88dSmrg
101af69d88dSmrg   case GL_TEXTURE_2D_MULTISAMPLE:
102af69d88dSmrg   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
10301e04c3fSmrg      /* The non-existence of ARB_texture_multisample is treated in
10401e04c3fSmrg       * ARB_internalformat_query implementation like an error.
10501e04c3fSmrg       */
10601e04c3fSmrg      if (!query2 &&
10701e04c3fSmrg          !(_mesa_has_ARB_texture_multisample(ctx) || _mesa_is_gles31(ctx))) {
10801e04c3fSmrg         _mesa_error(ctx, GL_INVALID_ENUM,
10901e04c3fSmrg                     "glGetInternalformativ(target=%s)",
11001e04c3fSmrg                     _mesa_enum_to_string(target));
11101e04c3fSmrg
11201e04c3fSmrg         return false;
11301e04c3fSmrg      }
11401e04c3fSmrg      break;
115af69d88dSmrg
116af69d88dSmrg   default:
117af69d88dSmrg      _mesa_error(ctx, GL_INVALID_ENUM,
118af69d88dSmrg                  "glGetInternalformativ(target=%s)",
11901e04c3fSmrg                  _mesa_enum_to_string(target));
12001e04c3fSmrg      return false;
121af69d88dSmrg   }
122af69d88dSmrg
12301e04c3fSmrg
12401e04c3fSmrg   /* The ARB_internalformat_query2 spec says:
125af69d88dSmrg    *
12601e04c3fSmrg    *     "The INVALID_ENUM error is generated if the <pname> parameter is
12701e04c3fSmrg    *     not one of the listed possibilities.
128af69d88dSmrg    */
12901e04c3fSmrg   switch(pname){
13001e04c3fSmrg   case GL_SAMPLES:
13101e04c3fSmrg   case GL_NUM_SAMPLE_COUNTS:
13201e04c3fSmrg      break;
13301e04c3fSmrg
1347ec681f3Smrg   case GL_TEXTURE_REDUCTION_MODE_ARB:
1357ec681f3Smrg      if (!_mesa_has_ARB_texture_filter_minmax(ctx)) {
1367ec681f3Smrg         _mesa_error(ctx, GL_INVALID_ENUM,
1377ec681f3Smrg                     "glGetInternalformativ(pname=%s)",
1387ec681f3Smrg                     _mesa_enum_to_string(pname));
1397ec681f3Smrg         return false;
1407ec681f3Smrg      }
1417ec681f3Smrg      break;
1427ec681f3Smrg
14301e04c3fSmrg   case GL_SRGB_DECODE_ARB:
14401e04c3fSmrg      /* The ARB_internalformat_query2 spec says:
14501e04c3fSmrg       *
14601e04c3fSmrg       *     "If ARB_texture_sRGB_decode or EXT_texture_sRGB_decode or
14701e04c3fSmrg       *     equivalent functionality is not supported, queries for the
14801e04c3fSmrg       *     SRGB_DECODE_ARB <pname> set the INVALID_ENUM error.
14901e04c3fSmrg       */
15001e04c3fSmrg      if (!_mesa_has_EXT_texture_sRGB_decode(ctx)) {
15101e04c3fSmrg         _mesa_error(ctx, GL_INVALID_ENUM,
15201e04c3fSmrg                     "glGetInternalformativ(pname=%s)",
15301e04c3fSmrg                     _mesa_enum_to_string(pname));
15401e04c3fSmrg         return false;
15501e04c3fSmrg      }
1567ec681f3Smrg      FALLTHROUGH;
15701e04c3fSmrg   case GL_INTERNALFORMAT_SUPPORTED:
15801e04c3fSmrg   case GL_INTERNALFORMAT_PREFERRED:
15901e04c3fSmrg   case GL_INTERNALFORMAT_RED_SIZE:
16001e04c3fSmrg   case GL_INTERNALFORMAT_GREEN_SIZE:
16101e04c3fSmrg   case GL_INTERNALFORMAT_BLUE_SIZE:
16201e04c3fSmrg   case GL_INTERNALFORMAT_ALPHA_SIZE:
16301e04c3fSmrg   case GL_INTERNALFORMAT_DEPTH_SIZE:
16401e04c3fSmrg   case GL_INTERNALFORMAT_STENCIL_SIZE:
16501e04c3fSmrg   case GL_INTERNALFORMAT_SHARED_SIZE:
16601e04c3fSmrg   case GL_INTERNALFORMAT_RED_TYPE:
16701e04c3fSmrg   case GL_INTERNALFORMAT_GREEN_TYPE:
16801e04c3fSmrg   case GL_INTERNALFORMAT_BLUE_TYPE:
16901e04c3fSmrg   case GL_INTERNALFORMAT_ALPHA_TYPE:
17001e04c3fSmrg   case GL_INTERNALFORMAT_DEPTH_TYPE:
17101e04c3fSmrg   case GL_INTERNALFORMAT_STENCIL_TYPE:
17201e04c3fSmrg   case GL_MAX_WIDTH:
17301e04c3fSmrg   case GL_MAX_HEIGHT:
17401e04c3fSmrg   case GL_MAX_DEPTH:
17501e04c3fSmrg   case GL_MAX_LAYERS:
17601e04c3fSmrg   case GL_MAX_COMBINED_DIMENSIONS:
17701e04c3fSmrg   case GL_COLOR_COMPONENTS:
17801e04c3fSmrg   case GL_DEPTH_COMPONENTS:
17901e04c3fSmrg   case GL_STENCIL_COMPONENTS:
18001e04c3fSmrg   case GL_COLOR_RENDERABLE:
18101e04c3fSmrg   case GL_DEPTH_RENDERABLE:
18201e04c3fSmrg   case GL_STENCIL_RENDERABLE:
18301e04c3fSmrg   case GL_FRAMEBUFFER_RENDERABLE:
18401e04c3fSmrg   case GL_FRAMEBUFFER_RENDERABLE_LAYERED:
18501e04c3fSmrg   case GL_FRAMEBUFFER_BLEND:
18601e04c3fSmrg   case GL_READ_PIXELS:
18701e04c3fSmrg   case GL_READ_PIXELS_FORMAT:
18801e04c3fSmrg   case GL_READ_PIXELS_TYPE:
18901e04c3fSmrg   case GL_TEXTURE_IMAGE_FORMAT:
19001e04c3fSmrg   case GL_TEXTURE_IMAGE_TYPE:
19101e04c3fSmrg   case GL_GET_TEXTURE_IMAGE_FORMAT:
19201e04c3fSmrg   case GL_GET_TEXTURE_IMAGE_TYPE:
19301e04c3fSmrg   case GL_MIPMAP:
19401e04c3fSmrg   case GL_MANUAL_GENERATE_MIPMAP:
19501e04c3fSmrg   case GL_AUTO_GENERATE_MIPMAP:
19601e04c3fSmrg   case GL_COLOR_ENCODING:
19701e04c3fSmrg   case GL_SRGB_READ:
19801e04c3fSmrg   case GL_SRGB_WRITE:
19901e04c3fSmrg   case GL_FILTER:
20001e04c3fSmrg   case GL_VERTEX_TEXTURE:
20101e04c3fSmrg   case GL_TESS_CONTROL_TEXTURE:
20201e04c3fSmrg   case GL_TESS_EVALUATION_TEXTURE:
20301e04c3fSmrg   case GL_GEOMETRY_TEXTURE:
20401e04c3fSmrg   case GL_FRAGMENT_TEXTURE:
20501e04c3fSmrg   case GL_COMPUTE_TEXTURE:
20601e04c3fSmrg   case GL_TEXTURE_SHADOW:
20701e04c3fSmrg   case GL_TEXTURE_GATHER:
20801e04c3fSmrg   case GL_TEXTURE_GATHER_SHADOW:
20901e04c3fSmrg   case GL_SHADER_IMAGE_LOAD:
21001e04c3fSmrg   case GL_SHADER_IMAGE_STORE:
21101e04c3fSmrg   case GL_SHADER_IMAGE_ATOMIC:
21201e04c3fSmrg   case GL_IMAGE_TEXEL_SIZE:
21301e04c3fSmrg   case GL_IMAGE_COMPATIBILITY_CLASS:
21401e04c3fSmrg   case GL_IMAGE_PIXEL_FORMAT:
21501e04c3fSmrg   case GL_IMAGE_PIXEL_TYPE:
21601e04c3fSmrg   case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
21701e04c3fSmrg   case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST:
21801e04c3fSmrg   case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST:
21901e04c3fSmrg   case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE:
22001e04c3fSmrg   case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE:
22101e04c3fSmrg   case GL_TEXTURE_COMPRESSED:
22201e04c3fSmrg   case GL_TEXTURE_COMPRESSED_BLOCK_WIDTH:
22301e04c3fSmrg   case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT:
22401e04c3fSmrg   case GL_TEXTURE_COMPRESSED_BLOCK_SIZE:
22501e04c3fSmrg   case GL_CLEAR_BUFFER:
22601e04c3fSmrg   case GL_TEXTURE_VIEW:
22701e04c3fSmrg   case GL_VIEW_COMPATIBILITY_CLASS:
22801e04c3fSmrg   case GL_NUM_TILING_TYPES_EXT:
22901e04c3fSmrg   case GL_TILING_TYPES_EXT:
23001e04c3fSmrg      /* The ARB_internalformat_query spec says:
23101e04c3fSmrg       *
23201e04c3fSmrg       *     "If the <pname> parameter to GetInternalformativ is not SAMPLES
23301e04c3fSmrg       *     or NUM_SAMPLE_COUNTS, then an INVALID_ENUM error is generated."
23401e04c3fSmrg       */
23501e04c3fSmrg      if (!query2) {
23601e04c3fSmrg         _mesa_error(ctx, GL_INVALID_ENUM,
23701e04c3fSmrg                     "glGetInternalformativ(pname=%s)",
23801e04c3fSmrg                     _mesa_enum_to_string(pname));
23901e04c3fSmrg
24001e04c3fSmrg         return false;
24101e04c3fSmrg      }
24201e04c3fSmrg      break;
24301e04c3fSmrg
24401e04c3fSmrg   default:
245af69d88dSmrg      _mesa_error(ctx, GL_INVALID_ENUM,
24601e04c3fSmrg                  "glGetInternalformativ(pname=%s)",
24701e04c3fSmrg                  _mesa_enum_to_string(pname));
24801e04c3fSmrg      return false;
249af69d88dSmrg   }
250af69d88dSmrg
251af69d88dSmrg   /* The ARB_internalformat_query spec says:
252af69d88dSmrg    *
253af69d88dSmrg    *     "If the <bufSize> parameter to GetInternalformativ is negative, then
254af69d88dSmrg    *     an INVALID_VALUE error is generated."
25501e04c3fSmrg    *
25601e04c3fSmrg    * Nothing is said in ARB_internalformat_query2 but we assume the same.
257af69d88dSmrg    */
258af69d88dSmrg   if (bufSize < 0) {
259af69d88dSmrg      _mesa_error(ctx, GL_INVALID_VALUE,
260af69d88dSmrg                  "glGetInternalformativ(target=%s)",
26101e04c3fSmrg                  _mesa_enum_to_string(target));
26201e04c3fSmrg      return false;
26301e04c3fSmrg   }
26401e04c3fSmrg
26501e04c3fSmrg   /* The ARB_internalformat_query spec says:
26601e04c3fSmrg    *
26701e04c3fSmrg    *     "If the <internalformat> parameter to GetInternalformativ is not
26801e04c3fSmrg    *     color-, depth- or stencil-renderable, then an INVALID_ENUM error is
26901e04c3fSmrg    *     generated."
27001e04c3fSmrg    */
27101e04c3fSmrg   if (!query2 && !_is_renderable(ctx, internalformat)) {
27201e04c3fSmrg      _mesa_error(ctx, GL_INVALID_ENUM,
27301e04c3fSmrg                  "glGetInternalformativ(internalformat=%s)",
27401e04c3fSmrg                  _mesa_enum_to_string(internalformat));
27501e04c3fSmrg      return false;
27601e04c3fSmrg   }
27701e04c3fSmrg
27801e04c3fSmrg   return true;
27901e04c3fSmrg}
28001e04c3fSmrg
28101e04c3fSmrg/* Sets the appropriate "unsupported" response as defined by the
28201e04c3fSmrg * ARB_internalformat_query2 spec for each each <pname>.
28301e04c3fSmrg */
28401e04c3fSmrgstatic void
28501e04c3fSmrg_set_default_response(GLenum pname, GLint buffer[16])
28601e04c3fSmrg{
28701e04c3fSmrg   /* The ARB_internalformat_query2 defines which is the reponse best
28801e04c3fSmrg    * representing "not supported" or "not applicable" for each <pname>.
28901e04c3fSmrg    *
29001e04c3fSmrg    *     " In general:
29101e04c3fSmrg    *          - size- or count-based queries will return zero,
29201e04c3fSmrg    *          - support-, format- or type-based queries will return NONE,
29301e04c3fSmrg    *          - boolean-based queries will return FALSE, and
29401e04c3fSmrg    *          - list-based queries return no entries."
29501e04c3fSmrg    */
29601e04c3fSmrg   switch(pname) {
29701e04c3fSmrg   case GL_SAMPLES:
29801e04c3fSmrg   case GL_TILING_TYPES_EXT:
29901e04c3fSmrg      break;
30001e04c3fSmrg
30101e04c3fSmrg   case GL_MAX_COMBINED_DIMENSIONS:
30201e04c3fSmrg      /* This value can be a 64-bit value. As the default is the 32-bit query,
30301e04c3fSmrg       * we pack 2 32-bit integers. So we need to clean both */
30401e04c3fSmrg      buffer[0] = 0;
30501e04c3fSmrg      buffer[1] = 0;
30601e04c3fSmrg      break;
30701e04c3fSmrg
30801e04c3fSmrg   case GL_NUM_SAMPLE_COUNTS:
30901e04c3fSmrg   case GL_INTERNALFORMAT_RED_SIZE:
31001e04c3fSmrg   case GL_INTERNALFORMAT_GREEN_SIZE:
31101e04c3fSmrg   case GL_INTERNALFORMAT_BLUE_SIZE:
31201e04c3fSmrg   case GL_INTERNALFORMAT_ALPHA_SIZE:
31301e04c3fSmrg   case GL_INTERNALFORMAT_DEPTH_SIZE:
31401e04c3fSmrg   case GL_INTERNALFORMAT_STENCIL_SIZE:
31501e04c3fSmrg   case GL_INTERNALFORMAT_SHARED_SIZE:
31601e04c3fSmrg   case GL_MAX_WIDTH:
31701e04c3fSmrg   case GL_MAX_HEIGHT:
31801e04c3fSmrg   case GL_MAX_DEPTH:
31901e04c3fSmrg   case GL_MAX_LAYERS:
32001e04c3fSmrg   case GL_IMAGE_TEXEL_SIZE:
32101e04c3fSmrg   case GL_TEXTURE_COMPRESSED_BLOCK_WIDTH:
32201e04c3fSmrg   case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT:
32301e04c3fSmrg   case GL_TEXTURE_COMPRESSED_BLOCK_SIZE:
32401e04c3fSmrg   case GL_NUM_TILING_TYPES_EXT:
32501e04c3fSmrg      buffer[0] = 0;
32601e04c3fSmrg      break;
32701e04c3fSmrg
32801e04c3fSmrg   case GL_INTERNALFORMAT_PREFERRED:
32901e04c3fSmrg   case GL_INTERNALFORMAT_RED_TYPE:
33001e04c3fSmrg   case GL_INTERNALFORMAT_GREEN_TYPE:
33101e04c3fSmrg   case GL_INTERNALFORMAT_BLUE_TYPE:
33201e04c3fSmrg   case GL_INTERNALFORMAT_ALPHA_TYPE:
33301e04c3fSmrg   case GL_INTERNALFORMAT_DEPTH_TYPE:
33401e04c3fSmrg   case GL_INTERNALFORMAT_STENCIL_TYPE:
33501e04c3fSmrg   case GL_FRAMEBUFFER_RENDERABLE:
33601e04c3fSmrg   case GL_FRAMEBUFFER_RENDERABLE_LAYERED:
33701e04c3fSmrg   case GL_FRAMEBUFFER_BLEND:
33801e04c3fSmrg   case GL_READ_PIXELS:
33901e04c3fSmrg   case GL_READ_PIXELS_FORMAT:
34001e04c3fSmrg   case GL_READ_PIXELS_TYPE:
34101e04c3fSmrg   case GL_TEXTURE_IMAGE_FORMAT:
34201e04c3fSmrg   case GL_TEXTURE_IMAGE_TYPE:
34301e04c3fSmrg   case GL_GET_TEXTURE_IMAGE_FORMAT:
34401e04c3fSmrg   case GL_GET_TEXTURE_IMAGE_TYPE:
34501e04c3fSmrg   case GL_MANUAL_GENERATE_MIPMAP:
34601e04c3fSmrg   case GL_AUTO_GENERATE_MIPMAP:
34701e04c3fSmrg   case GL_COLOR_ENCODING:
34801e04c3fSmrg   case GL_SRGB_READ:
34901e04c3fSmrg   case GL_SRGB_WRITE:
35001e04c3fSmrg   case GL_SRGB_DECODE_ARB:
35101e04c3fSmrg   case GL_FILTER:
35201e04c3fSmrg   case GL_VERTEX_TEXTURE:
35301e04c3fSmrg   case GL_TESS_CONTROL_TEXTURE:
35401e04c3fSmrg   case GL_TESS_EVALUATION_TEXTURE:
35501e04c3fSmrg   case GL_GEOMETRY_TEXTURE:
35601e04c3fSmrg   case GL_FRAGMENT_TEXTURE:
35701e04c3fSmrg   case GL_COMPUTE_TEXTURE:
35801e04c3fSmrg   case GL_TEXTURE_SHADOW:
35901e04c3fSmrg   case GL_TEXTURE_GATHER:
36001e04c3fSmrg   case GL_TEXTURE_GATHER_SHADOW:
36101e04c3fSmrg   case GL_SHADER_IMAGE_LOAD:
36201e04c3fSmrg   case GL_SHADER_IMAGE_STORE:
36301e04c3fSmrg   case GL_SHADER_IMAGE_ATOMIC:
36401e04c3fSmrg   case GL_IMAGE_COMPATIBILITY_CLASS:
36501e04c3fSmrg   case GL_IMAGE_PIXEL_FORMAT:
36601e04c3fSmrg   case GL_IMAGE_PIXEL_TYPE:
36701e04c3fSmrg   case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
36801e04c3fSmrg   case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST:
36901e04c3fSmrg   case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST:
37001e04c3fSmrg   case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE:
37101e04c3fSmrg   case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE:
37201e04c3fSmrg   case GL_CLEAR_BUFFER:
37301e04c3fSmrg   case GL_TEXTURE_VIEW:
37401e04c3fSmrg   case GL_VIEW_COMPATIBILITY_CLASS:
37501e04c3fSmrg      buffer[0] = GL_NONE;
37601e04c3fSmrg      break;
37701e04c3fSmrg
37801e04c3fSmrg   case GL_INTERNALFORMAT_SUPPORTED:
37901e04c3fSmrg   case GL_COLOR_COMPONENTS:
38001e04c3fSmrg   case GL_DEPTH_COMPONENTS:
38101e04c3fSmrg   case GL_STENCIL_COMPONENTS:
38201e04c3fSmrg   case GL_COLOR_RENDERABLE:
38301e04c3fSmrg   case GL_DEPTH_RENDERABLE:
38401e04c3fSmrg   case GL_STENCIL_RENDERABLE:
38501e04c3fSmrg   case GL_MIPMAP:
38601e04c3fSmrg   case GL_TEXTURE_COMPRESSED:
3877ec681f3Smrg   case GL_TEXTURE_REDUCTION_MODE_ARB:
38801e04c3fSmrg      buffer[0] = GL_FALSE;
38901e04c3fSmrg      break;
39001e04c3fSmrg
39101e04c3fSmrg   default:
39201e04c3fSmrg      unreachable("invalid 'pname'");
39301e04c3fSmrg   }
39401e04c3fSmrg}
39501e04c3fSmrg
39601e04c3fSmrgstatic bool
39701e04c3fSmrg_is_target_supported(struct gl_context *ctx, GLenum target)
39801e04c3fSmrg{
39901e04c3fSmrg   /* The ARB_internalformat_query2 spec says:
40001e04c3fSmrg    *
40101e04c3fSmrg    *     "if a particular type of <target> is not supported by the
40201e04c3fSmrg    *     implementation the "unsupported" answer should be given.
40301e04c3fSmrg    *     This is not an error."
40401e04c3fSmrg    *
40501e04c3fSmrg    * Note that legality of targets has already been verified.
40601e04c3fSmrg    */
40701e04c3fSmrg   switch(target){
40801e04c3fSmrg   case GL_TEXTURE_1D:
40901e04c3fSmrg   case GL_TEXTURE_2D:
41001e04c3fSmrg   case GL_TEXTURE_3D:
41101e04c3fSmrg      break;
41201e04c3fSmrg
41301e04c3fSmrg   case GL_TEXTURE_1D_ARRAY:
41401e04c3fSmrg      if (!_mesa_has_EXT_texture_array(ctx))
41501e04c3fSmrg         return false;
41601e04c3fSmrg      break;
41701e04c3fSmrg
41801e04c3fSmrg   case GL_TEXTURE_2D_ARRAY:
41901e04c3fSmrg      if (!_mesa_has_EXT_texture_array(ctx))
42001e04c3fSmrg         return false;
42101e04c3fSmrg      break;
42201e04c3fSmrg
42301e04c3fSmrg   case GL_TEXTURE_CUBE_MAP:
42401e04c3fSmrg      if (ctx->API != API_OPENGL_CORE && !_mesa_has_ARB_texture_cube_map(ctx))
42501e04c3fSmrg         return false;
42601e04c3fSmrg      break;
42701e04c3fSmrg
42801e04c3fSmrg   case GL_TEXTURE_CUBE_MAP_ARRAY:
42901e04c3fSmrg      if (!_mesa_has_ARB_texture_cube_map_array(ctx))
43001e04c3fSmrg         return false;
43101e04c3fSmrg      break;
43201e04c3fSmrg
43301e04c3fSmrg   case GL_TEXTURE_RECTANGLE:
43401e04c3fSmrg      if (!_mesa_has_ARB_texture_rectangle(ctx))
43501e04c3fSmrg          return false;
43601e04c3fSmrg      break;
43701e04c3fSmrg
43801e04c3fSmrg   case GL_TEXTURE_BUFFER:
43901e04c3fSmrg      if (!_mesa_has_ARB_texture_buffer_object(ctx))
44001e04c3fSmrg         return false;
44101e04c3fSmrg      break;
44201e04c3fSmrg
44301e04c3fSmrg   case GL_RENDERBUFFER:
44401e04c3fSmrg      if (!(_mesa_has_ARB_framebuffer_object(ctx) ||
44501e04c3fSmrg            _mesa_is_gles3(ctx)))
44601e04c3fSmrg         return false;
44701e04c3fSmrg      break;
44801e04c3fSmrg
44901e04c3fSmrg   case GL_TEXTURE_2D_MULTISAMPLE:
45001e04c3fSmrg   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
45101e04c3fSmrg      if (!(_mesa_has_ARB_texture_multisample(ctx) ||
45201e04c3fSmrg            _mesa_is_gles31(ctx)))
45301e04c3fSmrg         return false;
45401e04c3fSmrg      break;
45501e04c3fSmrg
45601e04c3fSmrg   default:
45701e04c3fSmrg      unreachable("invalid target");
45801e04c3fSmrg   }
45901e04c3fSmrg
46001e04c3fSmrg   return true;
46101e04c3fSmrg}
46201e04c3fSmrg
46301e04c3fSmrgstatic bool
46401e04c3fSmrg_is_resource_supported(struct gl_context *ctx, GLenum target,
46501e04c3fSmrg                       GLenum internalformat, GLenum pname)
46601e04c3fSmrg{
46701e04c3fSmrg   /* From the ARB_internalformat_query2 spec:
46801e04c3fSmrg    *
46901e04c3fSmrg    * In the following descriptions, the term /resource/ is used to generically
47001e04c3fSmrg    * refer to an object of the appropriate type that has been created with
47101e04c3fSmrg    * <internalformat> and <target>.  If the particular <target> and
47201e04c3fSmrg    * <internalformat> combination do not make sense, ... the "unsupported"
47301e04c3fSmrg    * answer should be given. This is not an error.
47401e04c3fSmrg    */
47501e04c3fSmrg
47601e04c3fSmrg   /* In the ARB_internalformat_query2 spec wording, some <pnames> do not care
47701e04c3fSmrg    * about the /resource/ being supported or not, we return 'true' for those.
47801e04c3fSmrg    */
47901e04c3fSmrg   switch (pname) {
48001e04c3fSmrg   case GL_INTERNALFORMAT_SUPPORTED:
48101e04c3fSmrg   case GL_INTERNALFORMAT_PREFERRED:
48201e04c3fSmrg   case GL_COLOR_COMPONENTS:
48301e04c3fSmrg   case GL_DEPTH_COMPONENTS:
48401e04c3fSmrg   case GL_STENCIL_COMPONENTS:
48501e04c3fSmrg   case GL_COLOR_RENDERABLE:
48601e04c3fSmrg   case GL_DEPTH_RENDERABLE:
48701e04c3fSmrg   case GL_STENCIL_RENDERABLE:
48801e04c3fSmrg      return true;
48901e04c3fSmrg   default:
49001e04c3fSmrg      break;
49101e04c3fSmrg   }
49201e04c3fSmrg
49301e04c3fSmrg   switch(target){
49401e04c3fSmrg   case GL_TEXTURE_1D:
49501e04c3fSmrg   case GL_TEXTURE_1D_ARRAY:
49601e04c3fSmrg   case GL_TEXTURE_2D:
49701e04c3fSmrg   case GL_TEXTURE_2D_ARRAY:
49801e04c3fSmrg   case GL_TEXTURE_3D:
49901e04c3fSmrg   case GL_TEXTURE_CUBE_MAP:
50001e04c3fSmrg   case GL_TEXTURE_CUBE_MAP_ARRAY:
50101e04c3fSmrg   case GL_TEXTURE_RECTANGLE:
50201e04c3fSmrg      /* Based on what Mesa does for glTexImage1D/2D/3D and
50301e04c3fSmrg       * glCompressedTexImage1D/2D/3D functions.
50401e04c3fSmrg       */
50501e04c3fSmrg      if (_mesa_base_tex_format(ctx, internalformat) < 0)
50601e04c3fSmrg         return false;
50701e04c3fSmrg
50801e04c3fSmrg      /* additional checks for depth textures */
50901e04c3fSmrg      if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat))
51001e04c3fSmrg         return false;
51101e04c3fSmrg
51201e04c3fSmrg      /* additional checks for compressed textures */
51301e04c3fSmrg      if (_mesa_is_compressed_format(ctx, internalformat) &&
51401e04c3fSmrg          !_mesa_target_can_be_compressed(ctx, target, internalformat, NULL))
51501e04c3fSmrg         return false;
51601e04c3fSmrg
51701e04c3fSmrg      break;
51801e04c3fSmrg   case GL_TEXTURE_2D_MULTISAMPLE:
51901e04c3fSmrg   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
52001e04c3fSmrg      /* Based on what Mesa does for glTexImage2D/3DMultisample,
52101e04c3fSmrg       * glTexStorage2D/3DMultisample and
52201e04c3fSmrg       * glTextureStorage2D/3DMultisample functions.
52301e04c3fSmrg       */
52401e04c3fSmrg      if (!_mesa_is_renderable_texture_format(ctx, internalformat))
52501e04c3fSmrg         return false;
52601e04c3fSmrg
52701e04c3fSmrg      break;
52801e04c3fSmrg   case GL_TEXTURE_BUFFER:
52901e04c3fSmrg      /* Based on what Mesa does for the glTexBuffer function. */
53001e04c3fSmrg      if (_mesa_validate_texbuffer_format(ctx, internalformat) ==
53101e04c3fSmrg          MESA_FORMAT_NONE)
53201e04c3fSmrg         return false;
53301e04c3fSmrg
53401e04c3fSmrg      break;
53501e04c3fSmrg   case GL_RENDERBUFFER:
53601e04c3fSmrg      /* Based on what Mesa does for glRenderbufferStorage(Multisample) and
53701e04c3fSmrg       * glNamedRenderbufferStorage functions.
53801e04c3fSmrg       */
53901e04c3fSmrg      if (!_mesa_base_fbo_format(ctx, internalformat))
54001e04c3fSmrg         return false;
54101e04c3fSmrg
54201e04c3fSmrg      break;
54301e04c3fSmrg   default:
54401e04c3fSmrg      unreachable("bad target");
54501e04c3fSmrg   }
54601e04c3fSmrg
54701e04c3fSmrg   return true;
54801e04c3fSmrg}
54901e04c3fSmrg
55001e04c3fSmrgstatic bool
55101e04c3fSmrg_is_internalformat_supported(struct gl_context *ctx, GLenum target,
55201e04c3fSmrg                             GLenum internalformat)
55301e04c3fSmrg{
55401e04c3fSmrg   /* From the ARB_internalformat_query2 specification:
55501e04c3fSmrg    *
55601e04c3fSmrg    *     "- INTERNALFORMAT_SUPPORTED: If <internalformat> is an internal format
55701e04c3fSmrg    *     that is supported by the implementation in at least some subset of
55801e04c3fSmrg    *     possible operations, TRUE is written to <params>.  If <internalformat>
55901e04c3fSmrg    *     if not a valid token for any internal format usage, FALSE is returned.
56001e04c3fSmrg    *
56101e04c3fSmrg    *     <internalformats> that must be supported (in GL 4.2 or later) include
56201e04c3fSmrg    *      the following:
56301e04c3fSmrg    *         - "sized internal formats" from Table 3.12, 3.13, and 3.15,
56401e04c3fSmrg    *         - any specific "compressed internal format" from Table 3.14,
56501e04c3fSmrg    *         - any "image unit format" from Table 3.21.
56601e04c3fSmrg    *         - any generic "compressed internal format" from Table 3.14, if the
56701e04c3fSmrg    *         implementation accepts it for any texture specification commands, and
56801e04c3fSmrg    *         - unsized or base internal format, if the implementation accepts
56901e04c3fSmrg    *         it for texture or image specification.
57001e04c3fSmrg    *
57101e04c3fSmrg    * But also:
57201e04c3fSmrg    * "If the particualar <target> and <internalformat> combination do not make
57301e04c3fSmrg    * sense, or if a particular type of <target> is not supported by the
57401e04c3fSmrg    * implementation the "unsupported" answer should be given. This is not an
57501e04c3fSmrg    * error.
57601e04c3fSmrg    */
57701e04c3fSmrg   GLint buffer[1];
57801e04c3fSmrg
57901e04c3fSmrg   if (target == GL_RENDERBUFFER) {
58001e04c3fSmrg      if (_mesa_base_fbo_format(ctx, internalformat) == 0) {
58101e04c3fSmrg         return false;
58201e04c3fSmrg      }
58301e04c3fSmrg   } else if (target == GL_TEXTURE_BUFFER) {
58401e04c3fSmrg      if (_mesa_validate_texbuffer_format(ctx, internalformat) ==
58501e04c3fSmrg          MESA_FORMAT_NONE) {
58601e04c3fSmrg         return false;
58701e04c3fSmrg      }
58801e04c3fSmrg   } else {
58901e04c3fSmrg      if (_mesa_base_tex_format(ctx, internalformat) < 0) {
59001e04c3fSmrg         return false;
59101e04c3fSmrg      }
59201e04c3fSmrg   }
59301e04c3fSmrg
59401e04c3fSmrg   /* Let the driver have the final word */
59501e04c3fSmrg   ctx->Driver.QueryInternalFormat(ctx, target, internalformat,
59601e04c3fSmrg                                   GL_INTERNALFORMAT_SUPPORTED, buffer);
59701e04c3fSmrg
59801e04c3fSmrg   return (buffer[0] == GL_TRUE);
59901e04c3fSmrg}
60001e04c3fSmrg
60101e04c3fSmrgstatic bool
60201e04c3fSmrg_legal_target_for_framebuffer_texture_layer(struct gl_context *ctx,
60301e04c3fSmrg                                            GLenum target)
60401e04c3fSmrg{
60501e04c3fSmrg   switch (target) {
60601e04c3fSmrg   case GL_TEXTURE_3D:
60701e04c3fSmrg   case GL_TEXTURE_1D_ARRAY:
60801e04c3fSmrg   case GL_TEXTURE_2D_ARRAY:
60901e04c3fSmrg   case GL_TEXTURE_CUBE_MAP_ARRAY:
61001e04c3fSmrg   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
61101e04c3fSmrg   case GL_TEXTURE_CUBE_MAP:
61201e04c3fSmrg      return true;
61301e04c3fSmrg   default:
61401e04c3fSmrg      return false;
61501e04c3fSmrg   }
61601e04c3fSmrg}
61701e04c3fSmrg
61801e04c3fSmrgstatic GLenum
61901e04c3fSmrg_mesa_generic_type_for_internal_format(GLenum internalFormat)
62001e04c3fSmrg{
62101e04c3fSmrg   if (_mesa_is_enum_format_unsigned_int(internalFormat))
62201e04c3fSmrg      return GL_UNSIGNED_BYTE;
62301e04c3fSmrg   else if (_mesa_is_enum_format_signed_int(internalFormat))
62401e04c3fSmrg      return GL_BYTE;
62501e04c3fSmrg   else
62601e04c3fSmrg      return GL_FLOAT;
62701e04c3fSmrg}
62801e04c3fSmrg
62901e04c3fSmrg/* default implementation of QueryInternalFormat driverfunc, for
63001e04c3fSmrg * drivers not implementing ARB_internalformat_query2.
63101e04c3fSmrg */
63201e04c3fSmrgvoid
63301e04c3fSmrg_mesa_query_internal_format_default(struct gl_context *ctx, GLenum target,
63401e04c3fSmrg                                    GLenum internalFormat, GLenum pname,
63501e04c3fSmrg                                    GLint *params)
63601e04c3fSmrg{
63701e04c3fSmrg   (void) target;
63801e04c3fSmrg
63901e04c3fSmrg   switch (pname) {
64001e04c3fSmrg   case GL_SAMPLES:
64101e04c3fSmrg   case GL_NUM_SAMPLE_COUNTS:
64201e04c3fSmrg      params[0] = 1;
64301e04c3fSmrg      break;
64401e04c3fSmrg
64501e04c3fSmrg   case GL_INTERNALFORMAT_SUPPORTED:
64601e04c3fSmrg      params[0] = GL_TRUE;
64701e04c3fSmrg      break;
64801e04c3fSmrg
64901e04c3fSmrg   case GL_INTERNALFORMAT_PREFERRED:
65001e04c3fSmrg      params[0] = internalFormat;
65101e04c3fSmrg      break;
65201e04c3fSmrg
65301e04c3fSmrg   case GL_READ_PIXELS_FORMAT: {
65401e04c3fSmrg      GLenum base_format = _mesa_base_tex_format(ctx, internalFormat);
65501e04c3fSmrg      switch (base_format) {
65601e04c3fSmrg      case GL_STENCIL_INDEX:
65701e04c3fSmrg      case GL_DEPTH_COMPONENT:
65801e04c3fSmrg      case GL_DEPTH_STENCIL:
65901e04c3fSmrg      case GL_RED:
66001e04c3fSmrg      case GL_RGB:
66101e04c3fSmrg      case GL_BGR:
66201e04c3fSmrg      case GL_RGBA:
66301e04c3fSmrg      case GL_BGRA:
66401e04c3fSmrg         params[0] = base_format;
66501e04c3fSmrg         break;
66601e04c3fSmrg      default:
66701e04c3fSmrg         params[0] = GL_NONE;
66801e04c3fSmrg         break;
66901e04c3fSmrg      }
67001e04c3fSmrg      break;
67101e04c3fSmrg   }
67201e04c3fSmrg
67301e04c3fSmrg   case GL_READ_PIXELS_TYPE:
67401e04c3fSmrg   case GL_TEXTURE_IMAGE_TYPE:
67501e04c3fSmrg   case GL_GET_TEXTURE_IMAGE_TYPE: {
67601e04c3fSmrg      GLenum base_format = _mesa_base_tex_format(ctx, internalFormat);
67701e04c3fSmrg      if (base_format > 0)
67801e04c3fSmrg         params[0] = _mesa_generic_type_for_internal_format(internalFormat);
67901e04c3fSmrg      else
68001e04c3fSmrg         params[0] = GL_NONE;
68101e04c3fSmrg      break;
68201e04c3fSmrg   }
68301e04c3fSmrg
68401e04c3fSmrg   case GL_TEXTURE_IMAGE_FORMAT:
68501e04c3fSmrg   case GL_GET_TEXTURE_IMAGE_FORMAT: {
68601e04c3fSmrg      GLenum format = GL_NONE;
68701e04c3fSmrg      GLenum base_format = _mesa_base_tex_format(ctx, internalFormat);
68801e04c3fSmrg      if (base_format > 0) {
68901e04c3fSmrg         if (_mesa_is_enum_format_integer(internalFormat))
69001e04c3fSmrg           format = _mesa_base_format_to_integer_format(base_format);
69101e04c3fSmrg         else
69201e04c3fSmrg           format = base_format;
69301e04c3fSmrg      }
69401e04c3fSmrg
69501e04c3fSmrg      params[0] = format;
69601e04c3fSmrg      break;
69701e04c3fSmrg   }
69801e04c3fSmrg
69901e04c3fSmrg   case GL_MANUAL_GENERATE_MIPMAP:
70001e04c3fSmrg   case GL_AUTO_GENERATE_MIPMAP:
70101e04c3fSmrg   case GL_SRGB_READ:
70201e04c3fSmrg   case GL_SRGB_WRITE:
70301e04c3fSmrg   case GL_SRGB_DECODE_ARB:
70401e04c3fSmrg   case GL_VERTEX_TEXTURE:
70501e04c3fSmrg   case GL_TESS_CONTROL_TEXTURE:
70601e04c3fSmrg   case GL_TESS_EVALUATION_TEXTURE:
70701e04c3fSmrg   case GL_GEOMETRY_TEXTURE:
70801e04c3fSmrg   case GL_FRAGMENT_TEXTURE:
70901e04c3fSmrg   case GL_COMPUTE_TEXTURE:
71001e04c3fSmrg   case GL_SHADER_IMAGE_LOAD:
71101e04c3fSmrg   case GL_SHADER_IMAGE_STORE:
71201e04c3fSmrg   case GL_SHADER_IMAGE_ATOMIC:
71301e04c3fSmrg   case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST:
71401e04c3fSmrg   case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST:
71501e04c3fSmrg   case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE:
71601e04c3fSmrg   case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE:
71701e04c3fSmrg   case GL_CLEAR_BUFFER:
71801e04c3fSmrg   case GL_TEXTURE_VIEW:
71901e04c3fSmrg   case GL_TEXTURE_SHADOW:
72001e04c3fSmrg   case GL_TEXTURE_GATHER:
72101e04c3fSmrg   case GL_TEXTURE_GATHER_SHADOW:
72201e04c3fSmrg   case GL_FRAMEBUFFER_RENDERABLE:
72301e04c3fSmrg   case GL_FRAMEBUFFER_RENDERABLE_LAYERED:
72401e04c3fSmrg   case GL_FRAMEBUFFER_BLEND:
72501e04c3fSmrg   case GL_FILTER:
72601e04c3fSmrg      /*
72701e04c3fSmrg       * TODO seems a tad optimistic just saying yes to everything here.
72801e04c3fSmrg       * Even for combinations which make no sense...
72901e04c3fSmrg       * And things like TESS_CONTROL_TEXTURE should definitely default to
73001e04c3fSmrg       * NONE if the driver doesn't even support tessellation...
73101e04c3fSmrg       */
73201e04c3fSmrg      params[0] = GL_FULL_SUPPORT;
73301e04c3fSmrg      break;
73401e04c3fSmrg   case GL_NUM_TILING_TYPES_EXT:
73501e04c3fSmrg      params[0] = 2;
73601e04c3fSmrg      break;
73701e04c3fSmrg   case GL_TILING_TYPES_EXT:
73801e04c3fSmrg      params[0] = GL_OPTIMAL_TILING_EXT;
73901e04c3fSmrg      params[1] = GL_LINEAR_TILING_EXT;
74001e04c3fSmrg      break;
74101e04c3fSmrg
74201e04c3fSmrg   default:
74301e04c3fSmrg      _set_default_response(pname, params);
74401e04c3fSmrg      break;
74501e04c3fSmrg   }
74601e04c3fSmrg}
74701e04c3fSmrg
74801e04c3fSmrg/*
74901e04c3fSmrg * For MAX_WIDTH/MAX_HEIGHT/MAX_DEPTH it returns the equivalent GetInteger
75001e04c3fSmrg * pname for a Getinternalformat pname/target combination. target/pname
75101e04c3fSmrg * combinations that would return 0 due dimension number or unsupported status
75201e04c3fSmrg * should be already filtered out
75301e04c3fSmrg *
75401e04c3fSmrg * Note that this means that the returned value would be independent of the
75501e04c3fSmrg * internalformat. This possibility is already mentioned at the Issue 7 of the
75601e04c3fSmrg * arb_internalformat_query2 spec.
75701e04c3fSmrg */
75801e04c3fSmrgstatic GLenum
75901e04c3fSmrg_equivalent_size_pname(GLenum target,
76001e04c3fSmrg                       GLenum pname)
76101e04c3fSmrg{
76201e04c3fSmrg   switch (target) {
76301e04c3fSmrg   case GL_TEXTURE_1D:
76401e04c3fSmrg   case GL_TEXTURE_2D:
76501e04c3fSmrg   case GL_TEXTURE_2D_MULTISAMPLE:
76601e04c3fSmrg      return GL_MAX_TEXTURE_SIZE;
76701e04c3fSmrg   case GL_TEXTURE_3D:
76801e04c3fSmrg      return GL_MAX_3D_TEXTURE_SIZE;
76901e04c3fSmrg   case GL_TEXTURE_CUBE_MAP:
77001e04c3fSmrg      return GL_MAX_CUBE_MAP_TEXTURE_SIZE;
77101e04c3fSmrg   case GL_TEXTURE_RECTANGLE:
77201e04c3fSmrg      return GL_MAX_RECTANGLE_TEXTURE_SIZE;
77301e04c3fSmrg   case GL_RENDERBUFFER:
77401e04c3fSmrg      return GL_MAX_RENDERBUFFER_SIZE;
77501e04c3fSmrg   case GL_TEXTURE_1D_ARRAY:
77601e04c3fSmrg      if (pname == GL_MAX_HEIGHT)
77701e04c3fSmrg         return GL_MAX_ARRAY_TEXTURE_LAYERS;
77801e04c3fSmrg      else
77901e04c3fSmrg         return GL_MAX_TEXTURE_SIZE;
78001e04c3fSmrg   case GL_TEXTURE_2D_ARRAY:
78101e04c3fSmrg   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
78201e04c3fSmrg      if (pname == GL_MAX_DEPTH)
78301e04c3fSmrg         return GL_MAX_ARRAY_TEXTURE_LAYERS;
78401e04c3fSmrg      else
78501e04c3fSmrg         return GL_MAX_TEXTURE_SIZE;
78601e04c3fSmrg   case GL_TEXTURE_CUBE_MAP_ARRAY:
78701e04c3fSmrg      if (pname == GL_MAX_DEPTH)
78801e04c3fSmrg         return GL_MAX_ARRAY_TEXTURE_LAYERS;
78901e04c3fSmrg      else
79001e04c3fSmrg         return GL_MAX_CUBE_MAP_TEXTURE_SIZE;
79101e04c3fSmrg   case GL_TEXTURE_BUFFER:
79201e04c3fSmrg      return GL_MAX_TEXTURE_BUFFER_SIZE;
79301e04c3fSmrg   default:
79401e04c3fSmrg      return 0;
79501e04c3fSmrg   }
79601e04c3fSmrg}
79701e04c3fSmrg
79801e04c3fSmrg/*
79901e04c3fSmrg * Returns the dimensions associated to a target. GL_TEXTURE_BUFFER and
80001e04c3fSmrg * GL_RENDERBUFFER have associated a dimension, but they are not textures
80101e04c3fSmrg * per-se, so we can't just call _mesa_get_texture_dimension directly.
80201e04c3fSmrg */
80301e04c3fSmrgstatic GLint
80401e04c3fSmrg_get_target_dimensions(GLenum target)
80501e04c3fSmrg{
80601e04c3fSmrg   switch(target) {
80701e04c3fSmrg   case GL_TEXTURE_BUFFER:
80801e04c3fSmrg      return 1;
80901e04c3fSmrg   case GL_RENDERBUFFER:
81001e04c3fSmrg      return 2;
81101e04c3fSmrg   default:
81201e04c3fSmrg      return _mesa_get_texture_dimensions(target);
81301e04c3fSmrg   }
81401e04c3fSmrg}
81501e04c3fSmrg
81601e04c3fSmrg/*
81701e04c3fSmrg * Returns the minimum amount of dimensions associated to a pname. So for
81801e04c3fSmrg * example, if querying GL_MAX_HEIGHT, it is assumed that your target would
81901e04c3fSmrg * have as minimum 2 dimensions.
82001e04c3fSmrg *
82101e04c3fSmrg * Useful to handle sentences like this from query2 spec:
82201e04c3fSmrg *
82301e04c3fSmrg * "MAX_HEIGHT:
82401e04c3fSmrg *  <skip>
82501e04c3fSmrg *  If the resource does not have at least two dimensions
82601e04c3fSmrg *  <skip>."
82701e04c3fSmrg */
82801e04c3fSmrgstatic GLint
82901e04c3fSmrg_get_min_dimensions(GLenum pname)
83001e04c3fSmrg{
83101e04c3fSmrg   switch(pname) {
83201e04c3fSmrg   case GL_MAX_WIDTH:
83301e04c3fSmrg      return 1;
83401e04c3fSmrg   case GL_MAX_HEIGHT:
83501e04c3fSmrg      return 2;
83601e04c3fSmrg   case GL_MAX_DEPTH:
83701e04c3fSmrg      return 3;
83801e04c3fSmrg   default:
83901e04c3fSmrg      return 0;
84001e04c3fSmrg   }
84101e04c3fSmrg}
84201e04c3fSmrg
84301e04c3fSmrg/*
84401e04c3fSmrg * Similar to teximage.c:check_multisample_target, but independent of the
84501e04c3fSmrg * dimensions.
84601e04c3fSmrg */
84701e04c3fSmrgstatic bool
84801e04c3fSmrg_is_multisample_target(GLenum target)
84901e04c3fSmrg{
85001e04c3fSmrg   switch(target) {
85101e04c3fSmrg   case GL_TEXTURE_2D_MULTISAMPLE:
85201e04c3fSmrg   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
85301e04c3fSmrg      return true;
85401e04c3fSmrg   default:
85501e04c3fSmrg      return false;
85601e04c3fSmrg   }
85701e04c3fSmrg
85801e04c3fSmrg}
85901e04c3fSmrg
86001e04c3fSmrgvoid GLAPIENTRY
86101e04c3fSmrg_mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
86201e04c3fSmrg                          GLsizei bufSize, GLint *params)
86301e04c3fSmrg{
86401e04c3fSmrg   GLint buffer[16];
86501e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
86601e04c3fSmrg
86701e04c3fSmrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
86801e04c3fSmrg
86901e04c3fSmrg   /* ARB_internalformat_query is also mandatory for ARB_internalformat_query2 */
87001e04c3fSmrg   if (!(_mesa_has_ARB_internalformat_query(ctx) ||
87101e04c3fSmrg         _mesa_is_gles3(ctx))) {
87201e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInternalformativ");
873af69d88dSmrg      return;
874af69d88dSmrg   }
875af69d88dSmrg
87601e04c3fSmrg   assert(ctx->Driver.QueryInternalFormat != NULL);
87701e04c3fSmrg
87801e04c3fSmrg   if (!_legal_parameters(ctx, target, internalformat, pname, bufSize, params))
87901e04c3fSmrg      return;
88001e04c3fSmrg
88101e04c3fSmrg   /* initialize the contents of the temporary buffer */
88201e04c3fSmrg   memcpy(buffer, params, MIN2(bufSize, 16) * sizeof(GLint));
88301e04c3fSmrg
88401e04c3fSmrg   /* Use the 'unsupported' response defined by the spec for every pname
88501e04c3fSmrg    * as the default answer.
88601e04c3fSmrg    */
88701e04c3fSmrg   _set_default_response(pname, buffer);
88801e04c3fSmrg
88901e04c3fSmrg   if (!_is_target_supported(ctx, target) ||
89001e04c3fSmrg       !_is_internalformat_supported(ctx, target, internalformat) ||
89101e04c3fSmrg       !_is_resource_supported(ctx, target, internalformat, pname))
89201e04c3fSmrg      goto end;
89301e04c3fSmrg
894af69d88dSmrg   switch (pname) {
895af69d88dSmrg   case GL_SAMPLES:
8967ec681f3Smrg      FALLTHROUGH;
89701e04c3fSmrg   case GL_NUM_SAMPLE_COUNTS:
89801e04c3fSmrg      /* The ARB_internalformat_query2 sets the response as 'unsupported' for
89901e04c3fSmrg       * SAMPLES and NUM_SAMPLE_COUNTS:
90001e04c3fSmrg       *
90101e04c3fSmrg       *     "If <internalformat> is not color-renderable, depth-renderable, or
90201e04c3fSmrg       *     stencil-renderable (as defined in section 4.4.4), or if <target>
90301e04c3fSmrg       *     does not support multiple samples (ie other than
90401e04c3fSmrg       *     TEXTURE_2D_MULTISAMPLE,  TEXTURE_2D_MULTISAMPLE_ARRAY,
90501e04c3fSmrg       *     or RENDERBUFFER)."
90601e04c3fSmrg       */
90701e04c3fSmrg      if ((target != GL_RENDERBUFFER &&
90801e04c3fSmrg           target != GL_TEXTURE_2D_MULTISAMPLE &&
90901e04c3fSmrg           target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) ||
91001e04c3fSmrg          !_is_renderable(ctx, internalformat))
91101e04c3fSmrg         goto end;
91201e04c3fSmrg
91301e04c3fSmrg      /* The GL ES 3.0 specification, section 6.1.15 page 236 says:
91401e04c3fSmrg       *
91501e04c3fSmrg       *     "Since multisampling is not supported for signed and unsigned
91601e04c3fSmrg       *     integer internal formats, the value of NUM_SAMPLE_COUNTS will be
91701e04c3fSmrg       *     zero for such formats.
91801e04c3fSmrg       *
91901e04c3fSmrg       * Since OpenGL ES 3.1 adds support for multisampled integer formats, we
92001e04c3fSmrg       * have to check the version for 30 exactly.
92101e04c3fSmrg       */
92201e04c3fSmrg      if (pname == GL_NUM_SAMPLE_COUNTS && ctx->API == API_OPENGLES2 &&
92301e04c3fSmrg          ctx->Version == 30 && _mesa_is_enum_format_integer(internalformat)) {
92401e04c3fSmrg         goto end;
92501e04c3fSmrg      }
92601e04c3fSmrg
92701e04c3fSmrg      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
92801e04c3fSmrg                                      buffer);
92901e04c3fSmrg      break;
93001e04c3fSmrg
93101e04c3fSmrg   case GL_INTERNALFORMAT_SUPPORTED:
93201e04c3fSmrg      /* Having a supported <internalformat> is implemented as a prerequisite
93301e04c3fSmrg       * for all the <pnames>. Thus,  if we reach this point, the internalformat is
93401e04c3fSmrg       * supported.
93501e04c3fSmrg       */
93601e04c3fSmrg      buffer[0] = GL_TRUE;
93701e04c3fSmrg      break;
93801e04c3fSmrg
93901e04c3fSmrg   case GL_INTERNALFORMAT_PREFERRED:
94001e04c3fSmrg      /* The ARB_internalformat_query2 spec says:
94101e04c3fSmrg       *
94201e04c3fSmrg       *     "- INTERNALFORMAT_PREFERRED: The implementation-preferred internal
94301e04c3fSmrg       *     format for representing resources of the specified <internalformat> is
94401e04c3fSmrg       *     returned in <params>.
94501e04c3fSmrg       *
94601e04c3fSmrg       * Therefore, we let the driver answer. Note that if we reach this
94701e04c3fSmrg       * point, it means that the internalformat is supported, so the driver
94801e04c3fSmrg       * is called just to try to get a preferred format. If not supported,
94901e04c3fSmrg       * GL_NONE was already returned and the driver is not called.
95001e04c3fSmrg       */
95101e04c3fSmrg      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
95201e04c3fSmrg                                      buffer);
95301e04c3fSmrg      break;
95401e04c3fSmrg
95501e04c3fSmrg   case GL_INTERNALFORMAT_RED_SIZE:
95601e04c3fSmrg   case GL_INTERNALFORMAT_GREEN_SIZE:
95701e04c3fSmrg   case GL_INTERNALFORMAT_BLUE_SIZE:
95801e04c3fSmrg   case GL_INTERNALFORMAT_ALPHA_SIZE:
95901e04c3fSmrg   case GL_INTERNALFORMAT_DEPTH_SIZE:
96001e04c3fSmrg   case GL_INTERNALFORMAT_STENCIL_SIZE:
96101e04c3fSmrg   case GL_INTERNALFORMAT_SHARED_SIZE:
96201e04c3fSmrg   case GL_INTERNALFORMAT_RED_TYPE:
96301e04c3fSmrg   case GL_INTERNALFORMAT_GREEN_TYPE:
96401e04c3fSmrg   case GL_INTERNALFORMAT_BLUE_TYPE:
96501e04c3fSmrg   case GL_INTERNALFORMAT_ALPHA_TYPE:
96601e04c3fSmrg   case GL_INTERNALFORMAT_DEPTH_TYPE:
96701e04c3fSmrg   case GL_INTERNALFORMAT_STENCIL_TYPE: {
96801e04c3fSmrg      GLint baseformat;
96901e04c3fSmrg      mesa_format texformat;
97001e04c3fSmrg
97101e04c3fSmrg      if (target != GL_RENDERBUFFER) {
97201e04c3fSmrg         baseformat = _mesa_base_tex_format(ctx, internalformat);
97301e04c3fSmrg      } else {
97401e04c3fSmrg         baseformat = _mesa_base_fbo_format(ctx, internalformat);
97501e04c3fSmrg      }
97601e04c3fSmrg
97701e04c3fSmrg      /* Let the driver choose the texture format.
97801e04c3fSmrg       *
97901e04c3fSmrg       * Disclaimer: I am considering that drivers use for renderbuffers the
98001e04c3fSmrg       * same format-choice logic as for textures.
98101e04c3fSmrg       */
98201e04c3fSmrg      texformat = ctx->Driver.ChooseTextureFormat(ctx, target, internalformat,
98301e04c3fSmrg                                                  GL_NONE /*format */, GL_NONE /* type */);
98401e04c3fSmrg
98501e04c3fSmrg      if (texformat == MESA_FORMAT_NONE || baseformat <= 0)
98601e04c3fSmrg         goto end;
98701e04c3fSmrg
98801e04c3fSmrg      /* Implementation based on what Mesa does for glGetTexLevelParameteriv
98901e04c3fSmrg       * and glGetRenderbufferParameteriv functions.
99001e04c3fSmrg       */
99101e04c3fSmrg      if (pname == GL_INTERNALFORMAT_SHARED_SIZE) {
99201e04c3fSmrg         if (texformat == MESA_FORMAT_R9G9B9E5_FLOAT) {
99301e04c3fSmrg            buffer[0] = 5;
99401e04c3fSmrg         }
99501e04c3fSmrg         goto end;
99601e04c3fSmrg      }
99701e04c3fSmrg
99801e04c3fSmrg      if (!_mesa_base_format_has_channel(baseformat, pname))
99901e04c3fSmrg         goto end;
100001e04c3fSmrg
100101e04c3fSmrg      switch (pname) {
100201e04c3fSmrg      case GL_INTERNALFORMAT_DEPTH_SIZE:
100301e04c3fSmrg         if (ctx->API != API_OPENGL_CORE &&
100401e04c3fSmrg             !_mesa_has_ARB_depth_texture(ctx) &&
100501e04c3fSmrg             target != GL_RENDERBUFFER &&
100601e04c3fSmrg             target != GL_TEXTURE_BUFFER)
100701e04c3fSmrg            goto end;
10087ec681f3Smrg         FALLTHROUGH;
100901e04c3fSmrg      case GL_INTERNALFORMAT_RED_SIZE:
101001e04c3fSmrg      case GL_INTERNALFORMAT_GREEN_SIZE:
101101e04c3fSmrg      case GL_INTERNALFORMAT_BLUE_SIZE:
101201e04c3fSmrg      case GL_INTERNALFORMAT_ALPHA_SIZE:
101301e04c3fSmrg      case GL_INTERNALFORMAT_STENCIL_SIZE:
101401e04c3fSmrg         buffer[0] = _mesa_get_format_bits(texformat, pname);
101501e04c3fSmrg         break;
101601e04c3fSmrg
101701e04c3fSmrg      case GL_INTERNALFORMAT_DEPTH_TYPE:
101801e04c3fSmrg         if (!_mesa_has_ARB_texture_float(ctx))
101901e04c3fSmrg            goto end;
10207ec681f3Smrg         FALLTHROUGH;
102101e04c3fSmrg      case GL_INTERNALFORMAT_RED_TYPE:
102201e04c3fSmrg      case GL_INTERNALFORMAT_GREEN_TYPE:
102301e04c3fSmrg      case GL_INTERNALFORMAT_BLUE_TYPE:
102401e04c3fSmrg      case GL_INTERNALFORMAT_ALPHA_TYPE:
102501e04c3fSmrg      case GL_INTERNALFORMAT_STENCIL_TYPE:
102601e04c3fSmrg         buffer[0]  = _mesa_get_format_datatype(texformat);
102701e04c3fSmrg         break;
102801e04c3fSmrg
102901e04c3fSmrg      default:
103001e04c3fSmrg         break;
103101e04c3fSmrg
103201e04c3fSmrg      }
1033af69d88dSmrg      break;
103401e04c3fSmrg   }
103501e04c3fSmrg
103601e04c3fSmrg      /* For WIDTH/HEIGHT/DEPTH/LAYERS there is no reason to think that the
103701e04c3fSmrg       * returned values should be different to the values returned by
103801e04c3fSmrg       * GetInteger with MAX_TEXTURE_SIZE, MAX_3D_TEXTURE_SIZE, etc.*/
103901e04c3fSmrg   case GL_MAX_WIDTH:
104001e04c3fSmrg   case GL_MAX_HEIGHT:
104101e04c3fSmrg   case GL_MAX_DEPTH: {
104201e04c3fSmrg      GLenum get_pname;
104301e04c3fSmrg      GLint dimensions;
104401e04c3fSmrg      GLint min_dimensions;
104501e04c3fSmrg
104601e04c3fSmrg      /* From query2:MAX_HEIGHT spec (as example):
1047af69d88dSmrg       *
104801e04c3fSmrg       * "If the resource does not have at least two dimensions, or if the
104901e04c3fSmrg       * resource is unsupported, zero is returned."
105001e04c3fSmrg       */
105101e04c3fSmrg      dimensions = _get_target_dimensions(target);
105201e04c3fSmrg      min_dimensions = _get_min_dimensions(pname);
105301e04c3fSmrg      if (dimensions < min_dimensions)
105401e04c3fSmrg         goto end;
105501e04c3fSmrg
105601e04c3fSmrg      get_pname = _equivalent_size_pname(target, pname);
105701e04c3fSmrg      if (get_pname == 0)
105801e04c3fSmrg         goto end;
105901e04c3fSmrg
106001e04c3fSmrg      _mesa_GetIntegerv(get_pname, buffer);
106101e04c3fSmrg      break;
106201e04c3fSmrg   }
106301e04c3fSmrg
106401e04c3fSmrg   case GL_MAX_LAYERS:
106501e04c3fSmrg      if (!_mesa_has_EXT_texture_array(ctx))
106601e04c3fSmrg         goto end;
106701e04c3fSmrg
106801e04c3fSmrg      if (!_mesa_is_array_texture(target))
106901e04c3fSmrg         goto end;
107001e04c3fSmrg
107101e04c3fSmrg      _mesa_GetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, buffer);
107201e04c3fSmrg      break;
107301e04c3fSmrg
107401e04c3fSmrg   case GL_MAX_COMBINED_DIMENSIONS:{
107501e04c3fSmrg      GLint64 combined_value = 1;
107601e04c3fSmrg      GLenum max_dimensions_pnames[] = {
107701e04c3fSmrg         GL_MAX_WIDTH,
107801e04c3fSmrg         GL_MAX_HEIGHT,
107901e04c3fSmrg         GL_MAX_DEPTH,
108001e04c3fSmrg         GL_SAMPLES
108101e04c3fSmrg      };
108201e04c3fSmrg      unsigned i;
108301e04c3fSmrg      GLint current_value;
108401e04c3fSmrg
108501e04c3fSmrg      /* Combining the dimensions. Note that for array targets, this would
108601e04c3fSmrg       * automatically include the value of MAX_LAYERS, as that value is
108701e04c3fSmrg       * returned as MAX_HEIGHT or MAX_DEPTH */
108801e04c3fSmrg      for (i = 0; i < 4; i++) {
108901e04c3fSmrg         if (max_dimensions_pnames[i] == GL_SAMPLES &&
109001e04c3fSmrg             !_is_multisample_target(target))
109101e04c3fSmrg            continue;
109201e04c3fSmrg
109301e04c3fSmrg         _mesa_GetInternalformativ(target, internalformat,
109401e04c3fSmrg                                   max_dimensions_pnames[i],
109501e04c3fSmrg                                   1, &current_value);
109601e04c3fSmrg
109701e04c3fSmrg         if (current_value != 0)
109801e04c3fSmrg            combined_value *= current_value;
109901e04c3fSmrg      }
110001e04c3fSmrg
110101e04c3fSmrg      if (_mesa_is_cube_map_texture(target))
110201e04c3fSmrg         combined_value *= 6;
110301e04c3fSmrg
110401e04c3fSmrg      /* We pack the 64-bit value on two 32-bit values. Calling the 32-bit
110501e04c3fSmrg       * query, this would work as far as the value can be hold on a 32-bit
110601e04c3fSmrg       * signed integer. For the 64-bit query, the wrapper around the 32-bit
110701e04c3fSmrg       * query will unpack the value */
110801e04c3fSmrg      memcpy(buffer, &combined_value, sizeof(GLint64));
110901e04c3fSmrg      break;
111001e04c3fSmrg   }
111101e04c3fSmrg
111201e04c3fSmrg   case GL_COLOR_COMPONENTS:
111301e04c3fSmrg      /* The ARB_internalformat_query2 spec says:
111401e04c3fSmrg       *
111501e04c3fSmrg       *     "- COLOR_COMPONENTS: If the internal format contains any color
111601e04c3fSmrg       *     components (R, G, B, or A), TRUE is returned in <params>.
111701e04c3fSmrg       *     If the internal format is unsupported or contains no color
111801e04c3fSmrg       *     components, FALSE is returned."
111901e04c3fSmrg       */
112001e04c3fSmrg      if (_mesa_is_color_format(internalformat))
112101e04c3fSmrg         buffer[0] = GL_TRUE;
112201e04c3fSmrg      break;
112301e04c3fSmrg
112401e04c3fSmrg   case GL_DEPTH_COMPONENTS:
112501e04c3fSmrg      /* The ARB_internalformat_query2 spec says:
112601e04c3fSmrg       *
112701e04c3fSmrg       *     "- DEPTH_COMPONENTS: If the internal format contains a depth
112801e04c3fSmrg       *     component (D), TRUE is returned in <params>. If the internal format
112901e04c3fSmrg       *     is unsupported or contains no depth component, FALSE is returned."
113001e04c3fSmrg       */
113101e04c3fSmrg      if (_mesa_is_depth_format(internalformat) ||
113201e04c3fSmrg          _mesa_is_depthstencil_format(internalformat))
113301e04c3fSmrg         buffer[0] = GL_TRUE;
113401e04c3fSmrg      break;
113501e04c3fSmrg
113601e04c3fSmrg   case GL_STENCIL_COMPONENTS:
113701e04c3fSmrg      /* The ARB_internalformat_query2 spec says:
1138af69d88dSmrg       *
113901e04c3fSmrg       *     "- STENCIL_COMPONENTS: If the internal format contains a stencil
114001e04c3fSmrg       *     component (S), TRUE is returned in <params>. If the internal format
114101e04c3fSmrg       *     is unsupported or contains no stencil component, FALSE is returned.
114201e04c3fSmrg       */
114301e04c3fSmrg      if (_mesa_is_stencil_format(internalformat) ||
114401e04c3fSmrg          _mesa_is_depthstencil_format(internalformat))
114501e04c3fSmrg         buffer[0] = GL_TRUE;
114601e04c3fSmrg      break;
114701e04c3fSmrg
114801e04c3fSmrg   case GL_COLOR_RENDERABLE:
114901e04c3fSmrg   case GL_DEPTH_RENDERABLE:
115001e04c3fSmrg   case GL_STENCIL_RENDERABLE:
115101e04c3fSmrg      if (!_is_renderable(ctx, internalformat))
115201e04c3fSmrg         goto end;
115301e04c3fSmrg
115401e04c3fSmrg      if (pname == GL_COLOR_RENDERABLE) {
115501e04c3fSmrg         if (!_mesa_is_color_format(internalformat))
115601e04c3fSmrg            goto end;
115701e04c3fSmrg      } else {
115801e04c3fSmrg         GLenum baseFormat = _mesa_base_fbo_format(ctx, internalformat);
115901e04c3fSmrg         if (baseFormat != GL_DEPTH_STENCIL &&
116001e04c3fSmrg             ((pname == GL_DEPTH_RENDERABLE && baseFormat != GL_DEPTH_COMPONENT) ||
116101e04c3fSmrg              (pname == GL_STENCIL_RENDERABLE && baseFormat != GL_STENCIL_INDEX)))
116201e04c3fSmrg            goto end;
116301e04c3fSmrg      }
116401e04c3fSmrg
116501e04c3fSmrg      buffer[0] = GL_TRUE;
116601e04c3fSmrg      break;
116701e04c3fSmrg
116801e04c3fSmrg   case GL_FRAMEBUFFER_RENDERABLE_LAYERED:
116901e04c3fSmrg      if (!_mesa_has_EXT_texture_array(ctx) ||
117001e04c3fSmrg          _legal_target_for_framebuffer_texture_layer(ctx, target))
117101e04c3fSmrg         goto end;
11727ec681f3Smrg      FALLTHROUGH;
117301e04c3fSmrg   case GL_FRAMEBUFFER_RENDERABLE:
117401e04c3fSmrg   case GL_FRAMEBUFFER_BLEND:
117501e04c3fSmrg      if (!_mesa_has_ARB_framebuffer_object(ctx))
117601e04c3fSmrg         goto end;
117701e04c3fSmrg
117801e04c3fSmrg      if (target == GL_TEXTURE_BUFFER ||
117901e04c3fSmrg          !_is_renderable(ctx, internalformat))
118001e04c3fSmrg         goto end;
118101e04c3fSmrg
118201e04c3fSmrg      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
118301e04c3fSmrg                                      buffer);
118401e04c3fSmrg      break;
118501e04c3fSmrg
118601e04c3fSmrg   case GL_READ_PIXELS:
118701e04c3fSmrg   case GL_READ_PIXELS_FORMAT:
118801e04c3fSmrg   case GL_READ_PIXELS_TYPE:
118901e04c3fSmrg      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
119001e04c3fSmrg                                      buffer);
119101e04c3fSmrg      break;
119201e04c3fSmrg
119301e04c3fSmrg   case GL_TEXTURE_IMAGE_FORMAT:
119401e04c3fSmrg   case GL_GET_TEXTURE_IMAGE_FORMAT:
119501e04c3fSmrg   case GL_TEXTURE_IMAGE_TYPE:
119601e04c3fSmrg   case GL_GET_TEXTURE_IMAGE_TYPE:
119701e04c3fSmrg      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
119801e04c3fSmrg                                      buffer);
119901e04c3fSmrg      break;
120001e04c3fSmrg
120101e04c3fSmrg   case GL_MIPMAP:
120201e04c3fSmrg   case GL_MANUAL_GENERATE_MIPMAP:
120301e04c3fSmrg   case GL_AUTO_GENERATE_MIPMAP:
120401e04c3fSmrg      if (!_mesa_is_valid_generate_texture_mipmap_target(ctx, target) ||
120501e04c3fSmrg          !_mesa_is_valid_generate_texture_mipmap_internalformat(ctx,
120601e04c3fSmrg                                                              internalformat)) {
120701e04c3fSmrg         goto end;
120801e04c3fSmrg      }
120901e04c3fSmrg
121001e04c3fSmrg      if (pname == GL_MIPMAP) {
121101e04c3fSmrg         buffer[0] = GL_TRUE;
121201e04c3fSmrg         goto end;
121301e04c3fSmrg      }
121401e04c3fSmrg      else if (pname == GL_MANUAL_GENERATE_MIPMAP) {
121501e04c3fSmrg         if (!_mesa_has_ARB_framebuffer_object(ctx))
121601e04c3fSmrg            goto end;
121701e04c3fSmrg      }
121801e04c3fSmrg      else {
121901e04c3fSmrg         /* From ARB_internalformat_query2:
122001e04c3fSmrg          *    "Dependencies on OpenGL 3.2 (Core Profile)
122101e04c3fSmrg          *     In core profiles for OpenGL 3.2 and later versions, queries
122201e04c3fSmrg          *     for the AUTO_GENERATE_MIPMAP <pname> return the appropriate
122301e04c3fSmrg          *     unsupported response."
122401e04c3fSmrg          */
122501e04c3fSmrg         if (_mesa_is_desktop_gl(ctx) && ctx->Version >= 32)
122601e04c3fSmrg            goto end;
122701e04c3fSmrg      }
122801e04c3fSmrg
122901e04c3fSmrg      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
123001e04c3fSmrg                                      buffer);
123101e04c3fSmrg      break;
123201e04c3fSmrg
123301e04c3fSmrg   case GL_COLOR_ENCODING:
123401e04c3fSmrg      if (!_mesa_is_color_format(internalformat))
123501e04c3fSmrg         goto end;
123601e04c3fSmrg
123701e04c3fSmrg      if (_mesa_is_srgb_format(internalformat))
123801e04c3fSmrg         buffer[0] = GL_SRGB;
123901e04c3fSmrg      else
124001e04c3fSmrg         buffer[0] = GL_LINEAR;
124101e04c3fSmrg      break;
124201e04c3fSmrg
124301e04c3fSmrg   case GL_SRGB_READ:
124401e04c3fSmrg      if (!_mesa_has_EXT_texture_sRGB(ctx) ||
124501e04c3fSmrg          !_mesa_is_srgb_format(internalformat)) {
124601e04c3fSmrg         goto end;
124701e04c3fSmrg      }
124801e04c3fSmrg
124901e04c3fSmrg      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
125001e04c3fSmrg                                      buffer);
125101e04c3fSmrg      break;
125201e04c3fSmrg
125301e04c3fSmrg   case GL_SRGB_WRITE:
1254b9abf16eSmaya      if (!ctx->Extensions.EXT_sRGB ||
125501e04c3fSmrg          !_mesa_is_color_format(internalformat)) {
125601e04c3fSmrg         goto end;
125701e04c3fSmrg      }
125801e04c3fSmrg
125901e04c3fSmrg      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
126001e04c3fSmrg                                      buffer);
126101e04c3fSmrg      break;
126201e04c3fSmrg
126301e04c3fSmrg   case GL_SRGB_DECODE_ARB:
126401e04c3fSmrg      /* Presence of EXT_texture_sRGB_decode was already verified */
126501e04c3fSmrg      if (!_mesa_has_EXT_texture_sRGB(ctx) ||
126601e04c3fSmrg          target == GL_RENDERBUFFER ||
126701e04c3fSmrg          !_mesa_is_srgb_format(internalformat)) {
126801e04c3fSmrg         goto end;
126901e04c3fSmrg      }
127001e04c3fSmrg
127101e04c3fSmrg      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
127201e04c3fSmrg                                      buffer);
127301e04c3fSmrg      break;
127401e04c3fSmrg
127501e04c3fSmrg   case GL_FILTER:
127601e04c3fSmrg      /* If it doesn't allow to set sampler parameters then it would not allow
127701e04c3fSmrg       * to set a filter different to GL_NEAREST. In practice, this method
127801e04c3fSmrg       * only filters out MULTISAMPLE/MULTISAMPLE_ARRAY */
127901e04c3fSmrg      if (!_mesa_target_allows_setting_sampler_parameters(target))
128001e04c3fSmrg         goto end;
128101e04c3fSmrg
128201e04c3fSmrg      if (_mesa_is_enum_format_integer(internalformat))
128301e04c3fSmrg         goto end;
128401e04c3fSmrg
128501e04c3fSmrg      if (target == GL_TEXTURE_BUFFER)
128601e04c3fSmrg         goto end;
128701e04c3fSmrg
128801e04c3fSmrg      /* At this point we know that multi-texel filtering is supported. We
128901e04c3fSmrg       * need to call the driver to know if it is CAVEAT_SUPPORT or
129001e04c3fSmrg       * FULL_SUPPORT.
129101e04c3fSmrg       */
129201e04c3fSmrg      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
129301e04c3fSmrg                                      buffer);
129401e04c3fSmrg      break;
129501e04c3fSmrg
129601e04c3fSmrg   case GL_VERTEX_TEXTURE:
129701e04c3fSmrg   case GL_TESS_CONTROL_TEXTURE:
129801e04c3fSmrg   case GL_TESS_EVALUATION_TEXTURE:
129901e04c3fSmrg   case GL_GEOMETRY_TEXTURE:
130001e04c3fSmrg   case GL_FRAGMENT_TEXTURE:
130101e04c3fSmrg   case GL_COMPUTE_TEXTURE:
130201e04c3fSmrg      if (target == GL_RENDERBUFFER)
130301e04c3fSmrg         goto end;
130401e04c3fSmrg
130501e04c3fSmrg      if ((pname == GL_TESS_CONTROL_TEXTURE ||
130601e04c3fSmrg           pname == GL_TESS_EVALUATION_TEXTURE) &&
130701e04c3fSmrg          !_mesa_has_tessellation(ctx))
130801e04c3fSmrg         goto end;
130901e04c3fSmrg
131001e04c3fSmrg      if (pname == GL_GEOMETRY_TEXTURE && !_mesa_has_geometry_shaders(ctx))
131101e04c3fSmrg         goto end;
131201e04c3fSmrg
131301e04c3fSmrg      if (pname == GL_COMPUTE_TEXTURE && !_mesa_has_compute_shaders(ctx))
131401e04c3fSmrg         goto end;
131501e04c3fSmrg
131601e04c3fSmrg      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
131701e04c3fSmrg                                      buffer);
131801e04c3fSmrg      break;
131901e04c3fSmrg
132001e04c3fSmrg   case GL_TEXTURE_GATHER:
132101e04c3fSmrg   case GL_TEXTURE_GATHER_SHADOW:
132201e04c3fSmrg      if (!_mesa_has_ARB_texture_gather(ctx))
132301e04c3fSmrg         goto end;
132401e04c3fSmrg
13257ec681f3Smrg      FALLTHROUGH;
132601e04c3fSmrg   case GL_TEXTURE_SHADOW:
132701e04c3fSmrg      /* Only depth or depth-stencil image formats make sense in shadow
132801e04c3fSmrg         samplers */
132901e04c3fSmrg      if (pname != GL_TEXTURE_GATHER &&
133001e04c3fSmrg          !_mesa_is_depth_format(internalformat) &&
133101e04c3fSmrg          !_mesa_is_depthstencil_format(internalformat))
133201e04c3fSmrg         goto end;
133301e04c3fSmrg
133401e04c3fSmrg      /* Validate the target for shadow and gather operations */
133501e04c3fSmrg      switch (target) {
133601e04c3fSmrg      case GL_TEXTURE_2D:
133701e04c3fSmrg      case GL_TEXTURE_2D_ARRAY:
133801e04c3fSmrg      case GL_TEXTURE_CUBE_MAP:
133901e04c3fSmrg      case GL_TEXTURE_CUBE_MAP_ARRAY:
134001e04c3fSmrg      case GL_TEXTURE_RECTANGLE:
134101e04c3fSmrg         break;
134201e04c3fSmrg
134301e04c3fSmrg      case GL_TEXTURE_1D:
134401e04c3fSmrg      case GL_TEXTURE_1D_ARRAY:
134501e04c3fSmrg         /* 1D and 1DArray textures are not admitted in gather operations */
134601e04c3fSmrg         if (pname != GL_TEXTURE_SHADOW)
134701e04c3fSmrg            goto end;
134801e04c3fSmrg         break;
134901e04c3fSmrg
135001e04c3fSmrg      default:
135101e04c3fSmrg         goto end;
135201e04c3fSmrg      }
135301e04c3fSmrg
135401e04c3fSmrg      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
135501e04c3fSmrg                                      buffer);
135601e04c3fSmrg      break;
135701e04c3fSmrg
135801e04c3fSmrg   case GL_SHADER_IMAGE_LOAD:
135901e04c3fSmrg   case GL_SHADER_IMAGE_STORE:
136001e04c3fSmrg      if (!_mesa_has_ARB_shader_image_load_store(ctx))
136101e04c3fSmrg         goto end;
136201e04c3fSmrg
136301e04c3fSmrg      /* We call to _mesa_is_shader_image_format_supported
136401e04c3fSmrg       * using "internalformat" as parameter, because the
136501e04c3fSmrg       * the ARB_internalformat_query2 spec says:
136601e04c3fSmrg       * "In this case the <internalformat> is the value of the <format>
136701e04c3fSmrg       * parameter that is passed to BindImageTexture."
136801e04c3fSmrg       */
136901e04c3fSmrg      if (target == GL_RENDERBUFFER ||
137001e04c3fSmrg          !_mesa_is_shader_image_format_supported(ctx, internalformat))
137101e04c3fSmrg         goto end;
137201e04c3fSmrg
137301e04c3fSmrg      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
137401e04c3fSmrg                                      buffer);
137501e04c3fSmrg      break;
137601e04c3fSmrg
137701e04c3fSmrg   case GL_SHADER_IMAGE_ATOMIC:
137801e04c3fSmrg      if (!_mesa_has_ARB_shader_image_load_store(ctx))
137901e04c3fSmrg         goto end;
138001e04c3fSmrg
138101e04c3fSmrg      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
138201e04c3fSmrg                                      buffer);
138301e04c3fSmrg      break;
138401e04c3fSmrg
138501e04c3fSmrg   case GL_IMAGE_TEXEL_SIZE: {
138601e04c3fSmrg      mesa_format image_format;
138701e04c3fSmrg
138801e04c3fSmrg      if (!_mesa_has_ARB_shader_image_load_store(ctx) ||
138901e04c3fSmrg          target == GL_RENDERBUFFER)
139001e04c3fSmrg         goto end;
139101e04c3fSmrg
139201e04c3fSmrg      image_format = _mesa_get_shader_image_format(internalformat);
139301e04c3fSmrg      if (image_format == MESA_FORMAT_NONE)
139401e04c3fSmrg         goto end;
139501e04c3fSmrg
139601e04c3fSmrg      /* We return bits */
139701e04c3fSmrg      buffer[0] = (_mesa_get_format_bytes(image_format) * 8);
139801e04c3fSmrg      break;
139901e04c3fSmrg   }
140001e04c3fSmrg
140101e04c3fSmrg   case GL_IMAGE_COMPATIBILITY_CLASS:
140201e04c3fSmrg      if (!_mesa_has_ARB_shader_image_load_store(ctx) ||
140301e04c3fSmrg          target == GL_RENDERBUFFER)
140401e04c3fSmrg         goto end;
140501e04c3fSmrg
140601e04c3fSmrg      buffer[0] = _mesa_get_image_format_class(internalformat);
140701e04c3fSmrg      break;
140801e04c3fSmrg
140901e04c3fSmrg   case GL_IMAGE_PIXEL_FORMAT: {
141001e04c3fSmrg      GLint base_format;
141101e04c3fSmrg
141201e04c3fSmrg      if (!_mesa_has_ARB_shader_image_load_store(ctx) ||
141301e04c3fSmrg          target == GL_RENDERBUFFER ||
141401e04c3fSmrg          !_mesa_is_shader_image_format_supported(ctx, internalformat))
141501e04c3fSmrg         goto end;
141601e04c3fSmrg
141701e04c3fSmrg      base_format = _mesa_base_tex_format(ctx, internalformat);
141801e04c3fSmrg      if (base_format == -1)
141901e04c3fSmrg         goto end;
142001e04c3fSmrg
142101e04c3fSmrg      if (_mesa_is_enum_format_integer(internalformat))
142201e04c3fSmrg         buffer[0] = _mesa_base_format_to_integer_format(base_format);
142301e04c3fSmrg      else
142401e04c3fSmrg         buffer[0] = base_format;
142501e04c3fSmrg      break;
142601e04c3fSmrg   }
142701e04c3fSmrg
142801e04c3fSmrg   case GL_IMAGE_PIXEL_TYPE: {
142901e04c3fSmrg      mesa_format image_format;
143001e04c3fSmrg      GLenum datatype;
143101e04c3fSmrg      GLuint comps;
143201e04c3fSmrg
143301e04c3fSmrg      if (!_mesa_has_ARB_shader_image_load_store(ctx) ||
143401e04c3fSmrg          target == GL_RENDERBUFFER)
143501e04c3fSmrg         goto end;
143601e04c3fSmrg
143701e04c3fSmrg      image_format = _mesa_get_shader_image_format(internalformat);
143801e04c3fSmrg      if (image_format == MESA_FORMAT_NONE)
143901e04c3fSmrg         goto end;
144001e04c3fSmrg
144101e04c3fSmrg      _mesa_uncompressed_format_to_type_and_comps(image_format, &datatype,
144201e04c3fSmrg                                                  &comps);
144301e04c3fSmrg      if (!datatype)
144401e04c3fSmrg         goto end;
144501e04c3fSmrg
144601e04c3fSmrg      buffer[0] = datatype;
144701e04c3fSmrg      break;
144801e04c3fSmrg   }
144901e04c3fSmrg
145001e04c3fSmrg   case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: {
145101e04c3fSmrg      if (!_mesa_has_ARB_shader_image_load_store(ctx))
145201e04c3fSmrg         goto end;
145301e04c3fSmrg
145401e04c3fSmrg      /* As pointed by the spec quote below, this pname query should return
145501e04c3fSmrg       * the same value that GetTexParameter. So if the target is not valid
145601e04c3fSmrg       * for GetTexParameter we return the unsupported value. The check below
145701e04c3fSmrg       * is the same target check used by GetTexParameter.
1458af69d88dSmrg       */
145901e04c3fSmrg      int targetIndex = _mesa_tex_target_to_index(ctx, target);
146001e04c3fSmrg      if (targetIndex < 0 || targetIndex == TEXTURE_BUFFER_INDEX)
146101e04c3fSmrg         goto end;
1462af69d88dSmrg
146301e04c3fSmrg      /* From spec: "Equivalent to calling GetTexParameter with <value> set
146401e04c3fSmrg       * to IMAGE_FORMAT_COMPATIBILITY_TYPE."
146501e04c3fSmrg       *
146601e04c3fSmrg       * GetTexParameter just returns
146701e04c3fSmrg       * tex_obj->ImageFormatCompatibilityType. We create a fake tex_obj
146801e04c3fSmrg       * just with the purpose of getting the value.
1469af69d88dSmrg       */
147001e04c3fSmrg      struct gl_texture_object *tex_obj = _mesa_new_texture_object(ctx, 0, target);
14717ec681f3Smrg      buffer[0] = tex_obj->Attrib.ImageFormatCompatibilityType;
147201e04c3fSmrg      _mesa_delete_texture_object(ctx, tex_obj);
147301e04c3fSmrg
147401e04c3fSmrg      break;
147501e04c3fSmrg   }
147601e04c3fSmrg
147701e04c3fSmrg   case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST:
147801e04c3fSmrg   case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST:
147901e04c3fSmrg   case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE:
148001e04c3fSmrg   case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE:
148101e04c3fSmrg      if (target == GL_RENDERBUFFER)
148201e04c3fSmrg         goto end;
148301e04c3fSmrg
148401e04c3fSmrg      if (!_mesa_is_depthstencil_format(internalformat)) {
148501e04c3fSmrg         if (((pname == GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST ||
148601e04c3fSmrg               pname == GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE) &&
148701e04c3fSmrg              !_mesa_is_depth_format(internalformat)) ||
148801e04c3fSmrg             ((pname == GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST ||
148901e04c3fSmrg               pname == GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE) &&
149001e04c3fSmrg              !_mesa_is_stencil_format(internalformat)))
149101e04c3fSmrg            goto end;
149201e04c3fSmrg      }
149301e04c3fSmrg
149401e04c3fSmrg      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
149501e04c3fSmrg                                      buffer);
149601e04c3fSmrg      break;
149701e04c3fSmrg
149801e04c3fSmrg   case GL_TEXTURE_COMPRESSED:
149901e04c3fSmrg      buffer[0] = _mesa_is_compressed_format(ctx, internalformat);
150001e04c3fSmrg      break;
150101e04c3fSmrg
150201e04c3fSmrg   case GL_TEXTURE_COMPRESSED_BLOCK_WIDTH:
150301e04c3fSmrg   case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT:
150401e04c3fSmrg   case GL_TEXTURE_COMPRESSED_BLOCK_SIZE: {
150501e04c3fSmrg      mesa_format mesaformat;
150601e04c3fSmrg      GLint block_size;
150701e04c3fSmrg
150801e04c3fSmrg      mesaformat = _mesa_glenum_to_compressed_format(internalformat);
150901e04c3fSmrg      if (mesaformat == MESA_FORMAT_NONE)
151001e04c3fSmrg         goto end;
151101e04c3fSmrg
151201e04c3fSmrg      block_size = _mesa_get_format_bytes(mesaformat);
151301e04c3fSmrg      assert(block_size > 0);
151401e04c3fSmrg
151501e04c3fSmrg      if (pname == GL_TEXTURE_COMPRESSED_BLOCK_SIZE) {
151601e04c3fSmrg         buffer[0] = block_size;
151701e04c3fSmrg      } else {
151801e04c3fSmrg         GLuint bwidth, bheight;
151901e04c3fSmrg
152001e04c3fSmrg         /* Returns the width and height in pixels. We return bytes */
152101e04c3fSmrg         _mesa_get_format_block_size(mesaformat, &bwidth, &bheight);
152201e04c3fSmrg         assert(bwidth > 0 && bheight > 0);
152301e04c3fSmrg
152401e04c3fSmrg         if (pname == GL_TEXTURE_COMPRESSED_BLOCK_WIDTH)
152501e04c3fSmrg            buffer[0] = block_size / bheight;
152601e04c3fSmrg         else
152701e04c3fSmrg            buffer[0] = block_size / bwidth;
152801e04c3fSmrg      }
1529af69d88dSmrg      break;
1530af69d88dSmrg   }
153101e04c3fSmrg
153201e04c3fSmrg   case GL_CLEAR_BUFFER:
153301e04c3fSmrg      if (target != GL_TEXTURE_BUFFER)
153401e04c3fSmrg         goto end;
153501e04c3fSmrg
153601e04c3fSmrg      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
153701e04c3fSmrg                                      buffer);
153801e04c3fSmrg      break;
153901e04c3fSmrg
154001e04c3fSmrg   case GL_TEXTURE_VIEW:
154101e04c3fSmrg   case GL_VIEW_COMPATIBILITY_CLASS:
154201e04c3fSmrg      if (!_mesa_has_ARB_texture_view(ctx) ||
154301e04c3fSmrg          target == GL_TEXTURE_BUFFER ||
154401e04c3fSmrg          target == GL_RENDERBUFFER)
154501e04c3fSmrg         goto end;
154601e04c3fSmrg
154701e04c3fSmrg      if (pname == GL_TEXTURE_VIEW) {
154801e04c3fSmrg         ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
154901e04c3fSmrg                                         buffer);
155001e04c3fSmrg      } else {
155101e04c3fSmrg         GLenum view_class = _mesa_texture_view_lookup_view_class(ctx,
155201e04c3fSmrg                                                                  internalformat);
155301e04c3fSmrg         if (view_class == GL_FALSE)
155401e04c3fSmrg            goto end;
155501e04c3fSmrg
155601e04c3fSmrg         buffer[0] = view_class;
155701e04c3fSmrg      }
155801e04c3fSmrg      break;
155901e04c3fSmrg
156001e04c3fSmrg   case GL_NUM_TILING_TYPES_EXT:
156101e04c3fSmrg   case GL_TILING_TYPES_EXT:
156201e04c3fSmrg      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
156301e04c3fSmrg                                      buffer);
156401e04c3fSmrg      break;
156501e04c3fSmrg
15667ec681f3Smrg   case GL_TEXTURE_REDUCTION_MODE_ARB:
15677ec681f3Smrg      if (ctx->Extensions.EXT_texture_filter_minmax)
15687ec681f3Smrg         buffer[0] = (GLint)1;
15697ec681f3Smrg      else if (ctx->Extensions.ARB_texture_filter_minmax)
15707ec681f3Smrg         ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
15717ec681f3Smrg                                         buffer);
15727ec681f3Smrg      else
15737ec681f3Smrg         buffer[0] = (GLint)0;
15747ec681f3Smrg      break;
15757ec681f3Smrg
1576af69d88dSmrg   default:
157701e04c3fSmrg      unreachable("bad param");
1578af69d88dSmrg   }
1579af69d88dSmrg
158001e04c3fSmrg end:
1581af69d88dSmrg   if (bufSize != 0 && params == NULL) {
1582af69d88dSmrg      /* Emit a warning to aid application debugging, but go ahead and do the
1583af69d88dSmrg       * memcpy (and probably crash) anyway.
1584af69d88dSmrg       */
1585af69d88dSmrg      _mesa_warning(ctx,
1586af69d88dSmrg                    "glGetInternalformativ(bufSize = %d, but params = NULL)",
1587af69d88dSmrg                    bufSize);
1588af69d88dSmrg   }
1589af69d88dSmrg
1590af69d88dSmrg   /* Copy the data from the temporary buffer to the buffer supplied by the
1591af69d88dSmrg    * application.  Clamp the size of the copy to the size supplied by the
1592af69d88dSmrg    * application.
1593af69d88dSmrg    */
159401e04c3fSmrg   memcpy(params, buffer, MIN2(bufSize, 16) * sizeof(GLint));
1595af69d88dSmrg
1596af69d88dSmrg   return;
1597af69d88dSmrg}
159801e04c3fSmrg
159901e04c3fSmrgvoid GLAPIENTRY
160001e04c3fSmrg_mesa_GetInternalformati64v(GLenum target, GLenum internalformat,
160101e04c3fSmrg                            GLenum pname, GLsizei bufSize, GLint64 *params)
160201e04c3fSmrg{
160301e04c3fSmrg   GLint params32[16];
160401e04c3fSmrg   unsigned i;
160501e04c3fSmrg   GLsizei realSize = MIN2(bufSize, 16);
160601e04c3fSmrg   GLsizei callSize;
160701e04c3fSmrg
160801e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
160901e04c3fSmrg
161001e04c3fSmrg   ASSERT_OUTSIDE_BEGIN_END(ctx);
161101e04c3fSmrg
161201e04c3fSmrg   if (!_mesa_has_ARB_internalformat_query2(ctx)) {
161301e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInternalformati64v");
161401e04c3fSmrg      return;
161501e04c3fSmrg   }
161601e04c3fSmrg
161701e04c3fSmrg   /* For SAMPLES there are cases where params needs to remain unmodified. As
161801e04c3fSmrg    * no pname can return a negative value, we fill params32 with negative
161901e04c3fSmrg    * values as reference values, that can be used to know what copy-back to
162001e04c3fSmrg    * params */
162101e04c3fSmrg   for (i = 0; i < realSize; i++)
162201e04c3fSmrg      params32[i] = -1;
162301e04c3fSmrg
162401e04c3fSmrg   /* For GL_MAX_COMBINED_DIMENSIONS we need to get back 2 32-bit integers,
162501e04c3fSmrg    * and at the same time we only need 2. So for that pname, we call the
162601e04c3fSmrg    * 32-bit query with bufSize 2, except on the case of bufSize 0, that is
162701e04c3fSmrg    * basically like asking to not get the value, but that is a caller
162801e04c3fSmrg    * problem. */
162901e04c3fSmrg   if (pname == GL_MAX_COMBINED_DIMENSIONS && bufSize > 0)
163001e04c3fSmrg      callSize = 2;
163101e04c3fSmrg   else
163201e04c3fSmrg      callSize = bufSize;
163301e04c3fSmrg
163401e04c3fSmrg   _mesa_GetInternalformativ(target, internalformat, pname, callSize, params32);
163501e04c3fSmrg
163601e04c3fSmrg   if (pname == GL_MAX_COMBINED_DIMENSIONS) {
163701e04c3fSmrg      memcpy(params, params32, sizeof(GLint64));
163801e04c3fSmrg   } else {
163901e04c3fSmrg      for (i = 0; i < realSize; i++) {
164001e04c3fSmrg         /* We only copy back the values that changed */
164101e04c3fSmrg         if (params32[i] < 0)
164201e04c3fSmrg            break;
164301e04c3fSmrg         params[i] = (GLint64) params32[i];
164401e04c3fSmrg      }
164501e04c3fSmrg   }
164601e04c3fSmrg}
1647