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