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