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