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