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