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