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