mesa/formatquery: support for MAX_COMBINED_DIMENSIONS
[mesa.git] / src / mesa / main / formatquery.c
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
36 static bool
37 _is_renderable(struct gl_context *ctx, GLenum internalformat)
38 {
39 /* Section 4.4.4 on page 212 of the GLES 3.0.4 spec says:
40 *
41 * "An internal format is color-renderable if it is one of the
42 * formats from table 3.13 noted as color-renderable or if it
43 * is unsized format RGBA or RGB."
44 *
45 * Therefore, we must accept GL_RGB and GL_RGBA here.
46 */
47 if (internalformat != GL_RGB && internalformat != GL_RGBA &&
48 _mesa_base_fbo_format(ctx, internalformat) == 0)
49 return false;
50
51 return true;
52 }
53
54 /* Handles the cases where either ARB_internalformat_query or
55 * ARB_internalformat_query2 have to return an error.
56 */
57 static bool
58 _legal_parameters(struct gl_context *ctx, GLenum target, GLenum internalformat,
59 GLenum pname, GLsizei bufSize, GLint *params)
60
61 {
62 bool query2 = _mesa_has_ARB_internalformat_query2(ctx);
63
64 /* The ARB_internalformat_query2 spec says:
65 *
66 * "The INVALID_ENUM error is generated if the <target> parameter to
67 * GetInternalformati*v is not one of the targets listed in Table 6.xx.
68 */
69 switch(target){
70 case GL_TEXTURE_1D:
71 case GL_TEXTURE_1D_ARRAY:
72 case GL_TEXTURE_2D:
73 case GL_TEXTURE_2D_ARRAY:
74 case GL_TEXTURE_3D:
75 case GL_TEXTURE_CUBE_MAP:
76 case GL_TEXTURE_CUBE_MAP_ARRAY:
77 case GL_TEXTURE_RECTANGLE:
78 case GL_TEXTURE_BUFFER:
79 if (!query2) {
80 /* The ARB_internalformat_query spec says:
81 *
82 * "If the <target> parameter to GetInternalformativ is not one of
83 * TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY
84 * or RENDERBUFFER then an INVALID_ENUM error is generated.
85 */
86 _mesa_error(ctx, GL_INVALID_ENUM,
87 "glGetInternalformativ(target=%s)",
88 _mesa_enum_to_string(target));
89
90 return false;
91 }
92 break;
93
94 case GL_RENDERBUFFER:
95 break;
96
97 case GL_TEXTURE_2D_MULTISAMPLE:
98 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
99 /* The non-existence of ARB_texture_multisample is treated in
100 * ARB_internalformat_query implementation like an error.
101 */
102 if (!query2 &&
103 !(_mesa_has_ARB_texture_multisample(ctx) || _mesa_is_gles31(ctx))) {
104 _mesa_error(ctx, GL_INVALID_ENUM,
105 "glGetInternalformativ(target=%s)",
106 _mesa_enum_to_string(target));
107
108 return false;
109 }
110 break;
111
112 default:
113 _mesa_error(ctx, GL_INVALID_ENUM,
114 "glGetInternalformativ(target=%s)",
115 _mesa_enum_to_string(target));
116 return false;
117 }
118
119
120 /* The ARB_internalformat_query2 spec says:
121 *
122 * "The INVALID_ENUM error is generated if the <pname> parameter is
123 * not one of the listed possibilities.
124 */
125 switch(pname){
126 case GL_SAMPLES:
127 case GL_NUM_SAMPLE_COUNTS:
128 break;
129
130 case GL_SRGB_DECODE_ARB:
131 /* The ARB_internalformat_query2 spec says:
132 *
133 * "If ARB_texture_sRGB_decode or EXT_texture_sRGB_decode or
134 * equivalent functionality is not supported, queries for the
135 * SRGB_DECODE_ARB <pname> set the INVALID_ENUM error.
136 */
137 if (!_mesa_has_EXT_texture_sRGB_decode(ctx)) {
138 _mesa_error(ctx, GL_INVALID_ENUM,
139 "glGetInternalformativ(pname=%s)",
140 _mesa_enum_to_string(pname));
141 return false;
142 }
143 /* fallthrough */
144 case GL_INTERNALFORMAT_SUPPORTED:
145 case GL_INTERNALFORMAT_PREFERRED:
146 case GL_INTERNALFORMAT_RED_SIZE:
147 case GL_INTERNALFORMAT_GREEN_SIZE:
148 case GL_INTERNALFORMAT_BLUE_SIZE:
149 case GL_INTERNALFORMAT_ALPHA_SIZE:
150 case GL_INTERNALFORMAT_DEPTH_SIZE:
151 case GL_INTERNALFORMAT_STENCIL_SIZE:
152 case GL_INTERNALFORMAT_SHARED_SIZE:
153 case GL_INTERNALFORMAT_RED_TYPE:
154 case GL_INTERNALFORMAT_GREEN_TYPE:
155 case GL_INTERNALFORMAT_BLUE_TYPE:
156 case GL_INTERNALFORMAT_ALPHA_TYPE:
157 case GL_INTERNALFORMAT_DEPTH_TYPE:
158 case GL_INTERNALFORMAT_STENCIL_TYPE:
159 case GL_MAX_WIDTH:
160 case GL_MAX_HEIGHT:
161 case GL_MAX_DEPTH:
162 case GL_MAX_LAYERS:
163 case GL_MAX_COMBINED_DIMENSIONS:
164 case GL_COLOR_COMPONENTS:
165 case GL_DEPTH_COMPONENTS:
166 case GL_STENCIL_COMPONENTS:
167 case GL_COLOR_RENDERABLE:
168 case GL_DEPTH_RENDERABLE:
169 case GL_STENCIL_RENDERABLE:
170 case GL_FRAMEBUFFER_RENDERABLE:
171 case GL_FRAMEBUFFER_RENDERABLE_LAYERED:
172 case GL_FRAMEBUFFER_BLEND:
173 case GL_READ_PIXELS:
174 case GL_READ_PIXELS_FORMAT:
175 case GL_READ_PIXELS_TYPE:
176 case GL_TEXTURE_IMAGE_FORMAT:
177 case GL_TEXTURE_IMAGE_TYPE:
178 case GL_GET_TEXTURE_IMAGE_FORMAT:
179 case GL_GET_TEXTURE_IMAGE_TYPE:
180 case GL_MIPMAP:
181 case GL_MANUAL_GENERATE_MIPMAP:
182 case GL_AUTO_GENERATE_MIPMAP:
183 case GL_COLOR_ENCODING:
184 case GL_SRGB_READ:
185 case GL_SRGB_WRITE:
186 case GL_FILTER:
187 case GL_VERTEX_TEXTURE:
188 case GL_TESS_CONTROL_TEXTURE:
189 case GL_TESS_EVALUATION_TEXTURE:
190 case GL_GEOMETRY_TEXTURE:
191 case GL_FRAGMENT_TEXTURE:
192 case GL_COMPUTE_TEXTURE:
193 case GL_TEXTURE_SHADOW:
194 case GL_TEXTURE_GATHER:
195 case GL_TEXTURE_GATHER_SHADOW:
196 case GL_SHADER_IMAGE_LOAD:
197 case GL_SHADER_IMAGE_STORE:
198 case GL_SHADER_IMAGE_ATOMIC:
199 case GL_IMAGE_TEXEL_SIZE:
200 case GL_IMAGE_COMPATIBILITY_CLASS:
201 case GL_IMAGE_PIXEL_FORMAT:
202 case GL_IMAGE_PIXEL_TYPE:
203 case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
204 case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST:
205 case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST:
206 case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE:
207 case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE:
208 case GL_TEXTURE_COMPRESSED:
209 case GL_TEXTURE_COMPRESSED_BLOCK_WIDTH:
210 case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT:
211 case GL_TEXTURE_COMPRESSED_BLOCK_SIZE:
212 case GL_CLEAR_BUFFER:
213 case GL_TEXTURE_VIEW:
214 case GL_VIEW_COMPATIBILITY_CLASS:
215 /* The ARB_internalformat_query spec says:
216 *
217 * "If the <pname> parameter to GetInternalformativ is not SAMPLES
218 * or NUM_SAMPLE_COUNTS, then an INVALID_ENUM error is generated."
219 */
220 if (!query2) {
221 _mesa_error(ctx, GL_INVALID_ENUM,
222 "glGetInternalformativ(pname=%s)",
223 _mesa_enum_to_string(pname));
224
225 return false;
226 }
227 break;
228
229 default:
230 _mesa_error(ctx, GL_INVALID_ENUM,
231 "glGetInternalformativ(pname=%s)",
232 _mesa_enum_to_string(pname));
233 return false;
234 }
235
236 /* The ARB_internalformat_query spec says:
237 *
238 * "If the <bufSize> parameter to GetInternalformativ is negative, then
239 * an INVALID_VALUE error is generated."
240 *
241 * Nothing is said in ARB_internalformat_query2 but we assume the same.
242 */
243 if (bufSize < 0) {
244 _mesa_error(ctx, GL_INVALID_VALUE,
245 "glGetInternalformativ(target=%s)",
246 _mesa_enum_to_string(target));
247 return false;
248 }
249
250 /* The ARB_internalformat_query spec says:
251 *
252 * "If the <internalformat> parameter to GetInternalformativ is not
253 * color-, depth- or stencil-renderable, then an INVALID_ENUM error is
254 * generated."
255 */
256 if (!query2 && !_is_renderable(ctx, internalformat)) {
257 _mesa_error(ctx, GL_INVALID_ENUM,
258 "glGetInternalformativ(internalformat=%s)",
259 _mesa_enum_to_string(internalformat));
260 return false;
261 }
262
263 return true;
264 }
265
266 /* Sets the appropriate "unsupported" response as defined by the
267 * ARB_internalformat_query2 spec for each each <pname>.
268 */
269 static void
270 _set_default_response(GLenum pname, GLint buffer[16])
271 {
272 /* The ARB_internalformat_query2 defines which is the reponse best
273 * representing "not supported" or "not applicable" for each <pname>.
274 *
275 * " In general:
276 * - size- or count-based queries will return zero,
277 * - support-, format- or type-based queries will return NONE,
278 * - boolean-based queries will return FALSE, and
279 * - list-based queries return no entries."
280 */
281 switch(pname) {
282 case GL_SAMPLES:
283 break;
284
285 case GL_MAX_COMBINED_DIMENSIONS:
286 /* This value can be a 64-bit value. As the default is the 32-bit query,
287 * we pack 2 32-bit integers. So we need to clean both */
288 buffer[0] = 0;
289 buffer[1] = 0;
290 break;
291
292 case GL_NUM_SAMPLE_COUNTS:
293 case GL_INTERNALFORMAT_RED_SIZE:
294 case GL_INTERNALFORMAT_GREEN_SIZE:
295 case GL_INTERNALFORMAT_BLUE_SIZE:
296 case GL_INTERNALFORMAT_ALPHA_SIZE:
297 case GL_INTERNALFORMAT_DEPTH_SIZE:
298 case GL_INTERNALFORMAT_STENCIL_SIZE:
299 case GL_INTERNALFORMAT_SHARED_SIZE:
300 case GL_MAX_WIDTH:
301 case GL_MAX_HEIGHT:
302 case GL_MAX_DEPTH:
303 case GL_MAX_LAYERS:
304 case GL_IMAGE_TEXEL_SIZE:
305 case GL_TEXTURE_COMPRESSED_BLOCK_WIDTH:
306 case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT:
307 case GL_TEXTURE_COMPRESSED_BLOCK_SIZE:
308 buffer[0] = 0;
309 break;
310
311 case GL_INTERNALFORMAT_PREFERRED:
312 case GL_INTERNALFORMAT_RED_TYPE:
313 case GL_INTERNALFORMAT_GREEN_TYPE:
314 case GL_INTERNALFORMAT_BLUE_TYPE:
315 case GL_INTERNALFORMAT_ALPHA_TYPE:
316 case GL_INTERNALFORMAT_DEPTH_TYPE:
317 case GL_INTERNALFORMAT_STENCIL_TYPE:
318 case GL_FRAMEBUFFER_RENDERABLE:
319 case GL_FRAMEBUFFER_RENDERABLE_LAYERED:
320 case GL_FRAMEBUFFER_BLEND:
321 case GL_READ_PIXELS:
322 case GL_READ_PIXELS_FORMAT:
323 case GL_READ_PIXELS_TYPE:
324 case GL_TEXTURE_IMAGE_FORMAT:
325 case GL_TEXTURE_IMAGE_TYPE:
326 case GL_GET_TEXTURE_IMAGE_FORMAT:
327 case GL_GET_TEXTURE_IMAGE_TYPE:
328 case GL_MANUAL_GENERATE_MIPMAP:
329 case GL_AUTO_GENERATE_MIPMAP:
330 case GL_COLOR_ENCODING:
331 case GL_SRGB_READ:
332 case GL_SRGB_WRITE:
333 case GL_SRGB_DECODE_ARB:
334 case GL_FILTER:
335 case GL_VERTEX_TEXTURE:
336 case GL_TESS_CONTROL_TEXTURE:
337 case GL_TESS_EVALUATION_TEXTURE:
338 case GL_GEOMETRY_TEXTURE:
339 case GL_FRAGMENT_TEXTURE:
340 case GL_COMPUTE_TEXTURE:
341 case GL_TEXTURE_SHADOW:
342 case GL_TEXTURE_GATHER:
343 case GL_TEXTURE_GATHER_SHADOW:
344 case GL_SHADER_IMAGE_LOAD:
345 case GL_SHADER_IMAGE_STORE:
346 case GL_SHADER_IMAGE_ATOMIC:
347 case GL_IMAGE_COMPATIBILITY_CLASS:
348 case GL_IMAGE_PIXEL_FORMAT:
349 case GL_IMAGE_PIXEL_TYPE:
350 case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
351 case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST:
352 case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST:
353 case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE:
354 case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE:
355 case GL_CLEAR_BUFFER:
356 case GL_TEXTURE_VIEW:
357 case GL_VIEW_COMPATIBILITY_CLASS:
358 buffer[0] = GL_NONE;
359 break;
360
361 case GL_INTERNALFORMAT_SUPPORTED:
362 case GL_COLOR_COMPONENTS:
363 case GL_DEPTH_COMPONENTS:
364 case GL_STENCIL_COMPONENTS:
365 case GL_COLOR_RENDERABLE:
366 case GL_DEPTH_RENDERABLE:
367 case GL_STENCIL_RENDERABLE:
368 case GL_MIPMAP:
369 case GL_TEXTURE_COMPRESSED:
370 buffer[0] = GL_FALSE;
371 break;
372
373 default:
374 unreachable("invalid 'pname'");
375 }
376 }
377
378 static bool
379 _is_target_supported(struct gl_context *ctx, GLenum target)
380 {
381 /* The ARB_internalformat_query2 spec says:
382 *
383 * "if a particular type of <target> is not supported by the
384 * implementation the "unsupported" answer should be given.
385 * This is not an error."
386 */
387 switch(target){
388 case GL_TEXTURE_2D:
389 case GL_TEXTURE_3D:
390 break;
391
392 case GL_TEXTURE_1D:
393 if (!_mesa_is_desktop_gl(ctx))
394 return false;
395 break;
396
397 case GL_TEXTURE_1D_ARRAY:
398 if (!_mesa_has_EXT_texture_array(ctx))
399 return false;
400 break;
401
402 case GL_TEXTURE_2D_ARRAY:
403 if (!(_mesa_has_EXT_texture_array(ctx) || _mesa_is_gles3(ctx)))
404 return false;
405 break;
406
407 case GL_TEXTURE_CUBE_MAP:
408 if (!_mesa_has_ARB_texture_cube_map(ctx))
409 return false;
410 break;
411
412 case GL_TEXTURE_CUBE_MAP_ARRAY:
413 if (!_mesa_has_ARB_texture_cube_map_array(ctx))
414 return false;
415 break;
416
417 case GL_TEXTURE_RECTANGLE:
418 if (!_mesa_has_NV_texture_rectangle(ctx))
419 return false;
420 break;
421
422 case GL_TEXTURE_BUFFER:
423 if (!_mesa_has_ARB_texture_buffer_object(ctx))
424 return false;
425 break;
426
427 case GL_RENDERBUFFER:
428 if (!(_mesa_has_ARB_framebuffer_object(ctx) ||
429 _mesa_is_gles3(ctx)))
430 return false;
431 break;
432
433 case GL_TEXTURE_2D_MULTISAMPLE:
434 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
435 if (!(_mesa_has_ARB_texture_multisample(ctx) ||
436 _mesa_is_gles31(ctx)))
437 return false;
438 break;
439
440 default:
441 unreachable("invalid target");
442 }
443
444 return true;
445 }
446
447 static bool
448 _is_resource_supported(struct gl_context *ctx, GLenum target,
449 GLenum internalformat, GLenum pname)
450 {
451 /* From the ARB_internalformat_query2 spec:
452 *
453 * In the following descriptions, the term /resource/ is used to generically
454 * refer to an object of the appropriate type that has been created with
455 * <internalformat> and <target>. If the particular <target> and
456 * <internalformat> combination do not make sense, ... the "unsupported"
457 * answer should be given. This is not an error.
458 */
459
460 /* In the ARB_internalformat_query2 spec wording, some <pnames> do not care
461 * about the /resource/ being supported or not, we return 'true' for those.
462 */
463 switch (pname) {
464 case GL_INTERNALFORMAT_SUPPORTED:
465 case GL_INTERNALFORMAT_PREFERRED:
466 case GL_COLOR_COMPONENTS:
467 case GL_DEPTH_COMPONENTS:
468 case GL_STENCIL_COMPONENTS:
469 case GL_COLOR_RENDERABLE:
470 case GL_DEPTH_RENDERABLE:
471 case GL_STENCIL_RENDERABLE:
472 return true;
473 default:
474 break;
475 }
476
477 switch(target){
478 case GL_TEXTURE_1D:
479 case GL_TEXTURE_1D_ARRAY:
480 case GL_TEXTURE_2D:
481 case GL_TEXTURE_2D_ARRAY:
482 case GL_TEXTURE_3D:
483 case GL_TEXTURE_CUBE_MAP:
484 case GL_TEXTURE_CUBE_MAP_ARRAY:
485 case GL_TEXTURE_RECTANGLE:
486 /* Based on what Mesa does for glTexImage1D/2D/3D and
487 * glCompressedTexImage1D/2D/3D functions.
488 */
489 if (_mesa_base_tex_format(ctx, internalformat) < 0)
490 return false;
491
492 /* additional checks for depth textures */
493 if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat))
494 return false;
495
496 /* additional checks for compressed textures */
497 if (_mesa_is_compressed_format(ctx, internalformat) &&
498 (!_mesa_target_can_be_compressed(ctx, target, internalformat, NULL) ||
499 _mesa_format_no_online_compression(ctx, internalformat)))
500 return false;
501
502 break;
503 case GL_TEXTURE_2D_MULTISAMPLE:
504 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
505 /* Based on what Mesa does for glTexImage2D/3DMultisample,
506 * glTexStorage2D/3DMultisample and
507 * glTextureStorage2D/3DMultisample functions.
508 */
509 if (!_mesa_is_renderable_texture_format(ctx, internalformat))
510 return false;
511
512 break;
513 case GL_TEXTURE_BUFFER:
514 /* Based on what Mesa does for the glTexBuffer function. */
515 if (_mesa_validate_texbuffer_format(ctx, internalformat) ==
516 MESA_FORMAT_NONE)
517 return false;
518
519 break;
520 case GL_RENDERBUFFER:
521 /* Based on what Mesa does for glRenderbufferStorage(Multisample) and
522 * glNamedRenderbufferStorage functions.
523 */
524 if (!_mesa_base_fbo_format(ctx, internalformat))
525 return false;
526
527 break;
528 default:
529 unreachable("bad target");
530 }
531
532 return true;
533 }
534
535 static bool
536 _is_internalformat_supported(struct gl_context *ctx, GLenum target,
537 GLenum internalformat)
538 {
539 /* From the ARB_internalformat_query2 specification:
540 *
541 * "- INTERNALFORMAT_SUPPORTED: If <internalformat> is an internal format
542 * that is supported by the implementation in at least some subset of
543 * possible operations, TRUE is written to <params>. If <internalformat>
544 * if not a valid token for any internal format usage, FALSE is returned.
545 *
546 * <internalformats> that must be supported (in GL 4.2 or later) include
547 * the following:
548 * - "sized internal formats" from Table 3.12, 3.13, and 3.15,
549 * - any specific "compressed internal format" from Table 3.14,
550 * - any "image unit format" from Table 3.21.
551 * - any generic "compressed internal format" from Table 3.14, if the
552 * implementation accepts it for any texture specification commands, and
553 * - unsized or base internal format, if the implementation accepts
554 * it for texture or image specification.
555 */
556 GLint buffer[1];
557
558 /* At this point a internalformat is valid if it is valid as a texture or
559 * as a renderbuffer format. The checks are different because those methods
560 * return different values when passing non supported internalformats */
561 if (_mesa_base_tex_format(ctx, internalformat) < 0 &&
562 _mesa_base_fbo_format(ctx, internalformat) == 0)
563 return false;
564
565 /* Let the driver have the final word */
566 ctx->Driver.QueryInternalFormat(ctx, target, internalformat,
567 GL_INTERNALFORMAT_SUPPORTED, buffer);
568
569 return (buffer[0] == GL_TRUE);
570 }
571
572 /* default implementation of QueryInternalFormat driverfunc, for
573 * drivers not implementing ARB_internalformat_query2.
574 */
575 void
576 _mesa_query_internal_format_default(struct gl_context *ctx, GLenum target,
577 GLenum internalFormat, GLenum pname,
578 GLint *params)
579 {
580 (void) ctx;
581 (void) target;
582 (void) internalFormat;
583
584 switch (pname) {
585 case GL_SAMPLES:
586 case GL_NUM_SAMPLE_COUNTS:
587 params[0] = 1;
588 break;
589
590 case GL_INTERNALFORMAT_SUPPORTED:
591 params[0] = GL_TRUE;
592 break;
593
594 case GL_INTERNALFORMAT_PREFERRED:
595 params[0] = internalFormat;
596 break;
597
598 default:
599 _set_default_response(pname, params);
600 break;
601 }
602 }
603
604 /*
605 * For MAX_WIDTH/MAX_HEIGHT/MAX_DEPTH it returns the equivalent GetInteger
606 * pname for a Getinternalformat pname/target combination. target/pname
607 * combinations that would return 0 due dimension number or unsupported status
608 * should be already filtered out
609 *
610 * Note that this means that the returned value would be independent of the
611 * internalformat. This possibility is already mentioned at the Issue 7 of the
612 * arb_internalformat_query2 spec.
613 */
614 static GLenum
615 equivalentSizePname(GLenum target,
616 GLenum pname)
617 {
618 switch (target) {
619 case GL_TEXTURE_1D:
620 case GL_TEXTURE_2D:
621 case GL_TEXTURE_2D_MULTISAMPLE:
622 return GL_MAX_TEXTURE_SIZE;
623 case GL_TEXTURE_3D:
624 return GL_MAX_3D_TEXTURE_SIZE;
625 case GL_TEXTURE_CUBE_MAP:
626 return GL_MAX_CUBE_MAP_TEXTURE_SIZE;
627 case GL_TEXTURE_RECTANGLE:
628 return GL_MAX_RECTANGLE_TEXTURE_SIZE;
629 case GL_RENDERBUFFER:
630 return GL_MAX_RENDERBUFFER_SIZE;
631 case GL_TEXTURE_1D_ARRAY:
632 if (pname == GL_MAX_HEIGHT)
633 return GL_MAX_ARRAY_TEXTURE_LAYERS;
634 else
635 return GL_MAX_TEXTURE_SIZE;
636 case GL_TEXTURE_2D_ARRAY:
637 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
638 if (pname == GL_MAX_DEPTH)
639 return GL_MAX_ARRAY_TEXTURE_LAYERS;
640 else
641 return GL_MAX_TEXTURE_SIZE;
642 case GL_TEXTURE_CUBE_MAP_ARRAY:
643 if (pname == GL_MAX_DEPTH)
644 return GL_MAX_ARRAY_TEXTURE_LAYERS;
645 else
646 return GL_MAX_CUBE_MAP_TEXTURE_SIZE;
647 case GL_TEXTURE_BUFFER:
648 return GL_MAX_TEXTURE_BUFFER_SIZE;
649 default:
650 return 0;
651 }
652 }
653
654 /*
655 * Returns the dimensions associated to a target. GL_TEXTURE_BUFFER and
656 * GL_RENDERBUFFER have associated a dimension, but they are not textures
657 * per-se, so we can't just call _mesa_get_texture_dimension directly.
658 */
659 static GLint
660 get_target_dimensions(GLenum target)
661 {
662 switch(target) {
663 case GL_TEXTURE_BUFFER:
664 return 1;
665 case GL_RENDERBUFFER:
666 return 2;
667 default:
668 return _mesa_get_texture_dimensions(target);
669 }
670 }
671
672 /*
673 * Returns the minimum amount of dimensions associated to a pname. So for
674 * example, if querying GL_MAX_HEIGHT, it is assumed that your target would
675 * have as minimum 2 dimensions.
676 *
677 * Useful to handle sentences like this from query2 spec:
678 *
679 * "MAX_HEIGHT:
680 * <skip>
681 * If the resource does not have at least two dimensions
682 * <skip>."
683 */
684 static GLint
685 get_min_dimensions(GLenum pname)
686 {
687 switch(pname) {
688 case GL_MAX_WIDTH:
689 return 1;
690 case GL_MAX_HEIGHT:
691 return 2;
692 case GL_MAX_DEPTH:
693 return 3;
694 default:
695 return 0;
696 }
697 }
698
699 /*
700 * Similar to teximage.c:check_multisample_target, but independent of the
701 * dimensions.
702 */
703 static bool
704 is_multisample_target(GLenum target)
705 {
706 switch(target) {
707 case GL_TEXTURE_2D_MULTISAMPLE:
708 case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
709 return true;
710 default:
711 return false;
712 }
713
714 }
715
716 void GLAPIENTRY
717 _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
718 GLsizei bufSize, GLint *params)
719 {
720 GLint buffer[16];
721 GET_CURRENT_CONTEXT(ctx);
722
723 ASSERT_OUTSIDE_BEGIN_END(ctx);
724
725 /* ARB_internalformat_query is also mandatory for ARB_internalformat_query2 */
726 if (!(_mesa_has_ARB_internalformat_query(ctx) ||
727 _mesa_is_gles3(ctx))) {
728 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInternalformativ");
729 return;
730 }
731
732 assert(ctx->Driver.QueryInternalFormat != NULL);
733
734 if (!_legal_parameters(ctx, target, internalformat, pname, bufSize, params))
735 return;
736
737 /* initialize the contents of the temporary buffer */
738 memcpy(buffer, params, MIN2(bufSize, 16) * sizeof(GLint));
739
740 /* Use the 'unsupported' response defined by the spec for every pname
741 * as the default answer.
742 */
743 _set_default_response(pname, buffer);
744
745 if (!_is_target_supported(ctx, target) ||
746 !_is_internalformat_supported(ctx, target, internalformat) ||
747 !_is_resource_supported(ctx, target, internalformat, pname))
748 goto end;
749
750 switch (pname) {
751 case GL_SAMPLES:
752 /* fall-through */
753 case GL_NUM_SAMPLE_COUNTS:
754 /* The ARB_internalformat_query2 sets the response as 'unsupported' for
755 * SAMPLES and NUM_SAMPLE_COUNTS:
756 *
757 * "If <internalformat> is not color-renderable, depth-renderable, or
758 * stencil-renderable (as defined in section 4.4.4), or if <target>
759 * does not support multiple samples (ie other than
760 * TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY,
761 * or RENDERBUFFER)."
762 */
763 if ((target != GL_RENDERBUFFER &&
764 target != GL_TEXTURE_2D_MULTISAMPLE &&
765 target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) ||
766 !_is_renderable(ctx, internalformat))
767 goto end;
768
769 /* The GL ES 3.0 specification, section 6.1.15 page 236 says:
770 *
771 * "Since multisampling is not supported for signed and unsigned
772 * integer internal formats, the value of NUM_SAMPLE_COUNTS will be
773 * zero for such formats.
774 */
775 if (pname == GL_NUM_SAMPLE_COUNTS && ctx->API == API_OPENGLES2 &&
776 ctx->Version == 30 && _mesa_is_enum_format_integer(internalformat)) {
777 goto end;
778 }
779
780 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
781 buffer);
782 break;
783
784 case GL_INTERNALFORMAT_SUPPORTED:
785 /* Having a supported <internalformat> is implemented as a prerequisite
786 * for all the <pnames>. Thus, if we reach this point, the internalformat is
787 * supported.
788 */
789 buffer[0] = GL_TRUE;
790 break;
791
792 case GL_INTERNALFORMAT_PREFERRED:
793 /* The ARB_internalformat_query2 spec says:
794 *
795 * "- INTERNALFORMAT_PREFERRED: The implementation-preferred internal
796 * format for representing resources of the specified <internalformat> is
797 * returned in <params>.
798 *
799 * Therefore, we let the driver answer.
800 */
801 ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
802 buffer);
803 break;
804
805 case GL_INTERNALFORMAT_RED_SIZE:
806 case GL_INTERNALFORMAT_GREEN_SIZE:
807 case GL_INTERNALFORMAT_BLUE_SIZE:
808 case GL_INTERNALFORMAT_ALPHA_SIZE:
809 case GL_INTERNALFORMAT_DEPTH_SIZE:
810 case GL_INTERNALFORMAT_STENCIL_SIZE:
811 case GL_INTERNALFORMAT_SHARED_SIZE:
812 case GL_INTERNALFORMAT_RED_TYPE:
813 case GL_INTERNALFORMAT_GREEN_TYPE:
814 case GL_INTERNALFORMAT_BLUE_TYPE:
815 case GL_INTERNALFORMAT_ALPHA_TYPE:
816 case GL_INTERNALFORMAT_DEPTH_TYPE:
817 case GL_INTERNALFORMAT_STENCIL_TYPE: {
818 GLint baseformat;
819 mesa_format texformat;
820
821 if (target != GL_RENDERBUFFER) {
822 if (!_mesa_legal_get_tex_level_parameter_target(ctx, target, true))
823 goto end;
824
825 baseformat = _mesa_base_tex_format(ctx, internalformat);
826 } else {
827 baseformat = _mesa_base_fbo_format(ctx, internalformat);
828 }
829
830 /* Let the driver choose the texture format.
831 *
832 * Disclaimer: I am considering that drivers use for renderbuffers the
833 * same format-choice logic as for textures.
834 */
835 texformat = ctx->Driver.ChooseTextureFormat(ctx, target, internalformat,
836 GL_NONE /*format */, GL_NONE /* type */);
837
838 if (texformat == MESA_FORMAT_NONE || baseformat <= 0)
839 goto end;
840
841 /* Implementation based on what Mesa does for glGetTexLevelParameteriv
842 * and glGetRenderbufferParameteriv functions.
843 */
844 if (pname == GL_INTERNALFORMAT_SHARED_SIZE) {
845 if (_mesa_has_EXT_texture_shared_exponent(ctx) &&
846 target != GL_TEXTURE_BUFFER &&
847 target != GL_RENDERBUFFER &&
848 texformat == MESA_FORMAT_R9G9B9E5_FLOAT) {
849 buffer[0] = 5;
850 }
851 goto end;
852 }
853
854 if (!_mesa_base_format_has_channel(baseformat, pname))
855 goto end;
856
857 switch (pname) {
858 case GL_INTERNALFORMAT_DEPTH_SIZE:
859 if (!_mesa_has_ARB_depth_texture(ctx) &&
860 target != GL_RENDERBUFFER &&
861 target != GL_TEXTURE_BUFFER)
862 goto end;
863 /* fallthrough */
864 case GL_INTERNALFORMAT_RED_SIZE:
865 case GL_INTERNALFORMAT_GREEN_SIZE:
866 case GL_INTERNALFORMAT_BLUE_SIZE:
867 case GL_INTERNALFORMAT_ALPHA_SIZE:
868 case GL_INTERNALFORMAT_STENCIL_SIZE:
869 buffer[0] = _mesa_get_format_bits(texformat, pname);
870 break;
871
872 case GL_INTERNALFORMAT_DEPTH_TYPE:
873 if (!_mesa_has_ARB_texture_float(ctx))
874 goto end;
875 /* fallthrough */
876 case GL_INTERNALFORMAT_RED_TYPE:
877 case GL_INTERNALFORMAT_GREEN_TYPE:
878 case GL_INTERNALFORMAT_BLUE_TYPE:
879 case GL_INTERNALFORMAT_ALPHA_TYPE:
880 case GL_INTERNALFORMAT_STENCIL_TYPE:
881 buffer[0] = _mesa_get_format_datatype(texformat);
882 break;
883
884 default:
885 break;
886
887 }
888 break;
889 }
890
891 /* For WIDTH/HEIGHT/DEPTH/LAYERS there is no reason to think that the
892 * returned values should be different to the values returned by
893 * GetInteger with MAX_TEXTURE_SIZE, MAX_3D_TEXTURE_SIZE, etc.*/
894 case GL_MAX_WIDTH:
895 case GL_MAX_HEIGHT:
896 case GL_MAX_DEPTH: {
897 GLenum get_pname;
898 GLint dimensions;
899 GLint min_dimensions;
900
901 /* From query2:MAX_HEIGHT spec (as example):
902 *
903 * "If the resource does not have at least two dimensions, or if the
904 * resource is unsupported, zero is returned."
905 */
906 dimensions = get_target_dimensions(target);
907 min_dimensions = get_min_dimensions(pname);
908 if (dimensions < min_dimensions)
909 goto end;
910
911 get_pname = equivalentSizePname(target, pname);
912 if (get_pname == 0)
913 goto end;
914
915 _mesa_GetIntegerv(get_pname, buffer);
916 break;
917 }
918
919 case GL_MAX_LAYERS:
920 if (!_mesa_has_EXT_texture_array(ctx))
921 goto end;
922
923 if (!_mesa_is_array_texture(target))
924 goto end;
925
926 _mesa_GetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, buffer);
927 break;
928
929 case GL_MAX_COMBINED_DIMENSIONS:{
930 GLint64 combined_value = 1;
931 GLenum max_dimensions_pnames[] = {
932 GL_MAX_WIDTH,
933 GL_MAX_HEIGHT,
934 GL_MAX_DEPTH,
935 GL_SAMPLES
936 };
937 unsigned i;
938 GLint current_value;
939
940 /* Combining the dimensions. Note that for array targets, this would
941 * automatically include the value of MAX_LAYERS, as that value is
942 * returned as MAX_HEIGHT or MAX_DEPTH */
943 for (i = 0; i < 4; i++) {
944 if (max_dimensions_pnames[i] == GL_SAMPLES &&
945 !is_multisample_target(target))
946 continue;
947
948 _mesa_GetInternalformativ(target, internalformat,
949 max_dimensions_pnames[i],
950 1, &current_value);
951
952 if (current_value != 0)
953 combined_value *= current_value;
954 }
955
956 if (_mesa_is_cube_map_texture(target))
957 combined_value *= 6;
958
959 /* We pack the 64-bit value on two 32-bit values. Calling the 32-bit
960 * query, this would work as far as the value can be hold on a 32-bit
961 * signed integer. For the 64-bit query, the wrapper around the 32-bit
962 * query will unpack the value */
963 memcpy(buffer, &combined_value, sizeof(GLint64));
964 break;
965 }
966
967 case GL_COLOR_COMPONENTS:
968 /* @TODO */
969 break;
970
971 case GL_DEPTH_COMPONENTS:
972 /* @TODO */
973 break;
974
975 case GL_STENCIL_COMPONENTS:
976 /* @TODO */
977 break;
978
979 case GL_COLOR_RENDERABLE:
980 /* @TODO */
981 break;
982
983 case GL_DEPTH_RENDERABLE:
984 /* @TODO */
985 break;
986
987 case GL_STENCIL_RENDERABLE:
988 /* @TODO */
989 break;
990
991 case GL_FRAMEBUFFER_RENDERABLE:
992 /* @TODO */
993 break;
994
995 case GL_FRAMEBUFFER_RENDERABLE_LAYERED:
996 /* @TODO */
997 break;
998
999 case GL_FRAMEBUFFER_BLEND:
1000 /* @TODO */
1001 break;
1002
1003 case GL_READ_PIXELS:
1004 /* @TODO */
1005 break;
1006
1007 case GL_READ_PIXELS_FORMAT:
1008 /* @TODO */
1009 break;
1010
1011 case GL_READ_PIXELS_TYPE:
1012 /* @TODO */
1013 break;
1014
1015 case GL_TEXTURE_IMAGE_FORMAT:
1016 /* @TODO */
1017 break;
1018
1019 case GL_TEXTURE_IMAGE_TYPE:
1020 /* @TODO */
1021 break;
1022
1023 case GL_GET_TEXTURE_IMAGE_FORMAT:
1024 /* @TODO */
1025 break;
1026
1027 case GL_GET_TEXTURE_IMAGE_TYPE:
1028 /* @TODO */
1029 break;
1030
1031 case GL_MIPMAP:
1032 /* @TODO */
1033 break;
1034
1035 case GL_MANUAL_GENERATE_MIPMAP:
1036 /* @TODO */
1037 break;
1038
1039 case GL_AUTO_GENERATE_MIPMAP:
1040 /* @TODO */
1041 break;
1042
1043 case GL_COLOR_ENCODING:
1044 /* @TODO */
1045 break;
1046
1047 case GL_SRGB_READ:
1048 /* @TODO */
1049 break;
1050
1051 case GL_SRGB_WRITE:
1052 /* @TODO */
1053 break;
1054
1055 case GL_SRGB_DECODE_ARB:
1056 /* @TODO */
1057 break;
1058
1059 case GL_FILTER:
1060 /* @TODO */
1061 break;
1062
1063 case GL_VERTEX_TEXTURE:
1064 /* @TODO */
1065 break;
1066
1067 case GL_TESS_CONTROL_TEXTURE:
1068 /* @TODO */
1069 break;
1070
1071 case GL_TESS_EVALUATION_TEXTURE:
1072 /* @TODO */
1073 break;
1074
1075 case GL_GEOMETRY_TEXTURE:
1076 /* @TODO */
1077 break;
1078
1079 case GL_FRAGMENT_TEXTURE:
1080 /* @TODO */
1081 break;
1082
1083 case GL_COMPUTE_TEXTURE:
1084 /* @TODO */
1085 break;
1086
1087 case GL_TEXTURE_SHADOW:
1088 /* @TODO */
1089 break;
1090
1091 case GL_TEXTURE_GATHER:
1092 /* @TODO */
1093 break;
1094
1095 case GL_TEXTURE_GATHER_SHADOW:
1096 /* @TODO */
1097 break;
1098
1099 case GL_SHADER_IMAGE_LOAD:
1100 /* @TODO */
1101 break;
1102
1103 case GL_SHADER_IMAGE_STORE:
1104 /* @TODO */
1105 break;
1106
1107 case GL_SHADER_IMAGE_ATOMIC:
1108 /* @TODO */
1109 break;
1110
1111 case GL_IMAGE_TEXEL_SIZE:
1112 /* @TODO */
1113 break;
1114
1115 case GL_IMAGE_COMPATIBILITY_CLASS:
1116 /* @TODO */
1117 break;
1118
1119 case GL_IMAGE_PIXEL_FORMAT:
1120 /* @TODO */
1121 break;
1122
1123 case GL_IMAGE_PIXEL_TYPE:
1124 /* @TODO */
1125 break;
1126
1127 case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: {
1128 if (!_mesa_has_ARB_shader_image_load_store(ctx))
1129 goto end;
1130
1131 if (!_mesa_legal_get_tex_level_parameter_target(ctx, target, true))
1132 goto end;
1133
1134 /* From spec: "Equivalent to calling GetTexParameter with <value> set
1135 * to IMAGE_FORMAT_COMPATIBILITY_TYPE."
1136 *
1137 * GetTexParameter just returns
1138 * tex_obj->ImageFormatCompatibilityType. We create a fake tex_obj
1139 * just with the purpose of getting the value.
1140 */
1141 struct gl_texture_object *tex_obj = _mesa_new_texture_object(ctx, 0, target);
1142 buffer[0] = tex_obj->ImageFormatCompatibilityType;
1143 _mesa_delete_texture_object(ctx, tex_obj);
1144
1145 break;
1146 }
1147
1148 case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST:
1149 /* @TODO */
1150 break;
1151
1152 case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST:
1153 /* @TODO */
1154 break;
1155
1156 case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE:
1157 /* @TODO */
1158 break;
1159
1160 case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE:
1161 /* @TODO */
1162 break;
1163
1164 case GL_TEXTURE_COMPRESSED:
1165 /* @TODO */
1166 break;
1167
1168 case GL_TEXTURE_COMPRESSED_BLOCK_WIDTH:
1169 /* @TODO */
1170 break;
1171
1172 case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT:
1173 /* @TODO */
1174 break;
1175
1176 case GL_TEXTURE_COMPRESSED_BLOCK_SIZE:
1177 /* @TODO */
1178 break;
1179
1180 case GL_CLEAR_BUFFER:
1181 /* @TODO */
1182 break;
1183
1184 case GL_TEXTURE_VIEW:
1185 /* @TODO */
1186 break;
1187
1188 case GL_VIEW_COMPATIBILITY_CLASS:
1189 /* @TODO */
1190 break;
1191
1192 default:
1193 unreachable("bad param");
1194 }
1195
1196 end:
1197 if (bufSize != 0 && params == NULL) {
1198 /* Emit a warning to aid application debugging, but go ahead and do the
1199 * memcpy (and probably crash) anyway.
1200 */
1201 _mesa_warning(ctx,
1202 "glGetInternalformativ(bufSize = %d, but params = NULL)",
1203 bufSize);
1204 }
1205
1206 /* Copy the data from the temporary buffer to the buffer supplied by the
1207 * application. Clamp the size of the copy to the size supplied by the
1208 * application.
1209 */
1210 memcpy(params, buffer, MIN2(bufSize, 16) * sizeof(GLint));
1211
1212 return;
1213 }
1214
1215 void GLAPIENTRY
1216 _mesa_GetInternalformati64v(GLenum target, GLenum internalformat,
1217 GLenum pname, GLsizei bufSize, GLint64 *params)
1218 {
1219 GLint params32[16];
1220 unsigned i;
1221 GLsizei realSize = MIN2(bufSize, 16);
1222 GLsizei callSize;
1223
1224 GET_CURRENT_CONTEXT(ctx);
1225
1226 ASSERT_OUTSIDE_BEGIN_END(ctx);
1227
1228 if (!_mesa_has_ARB_internalformat_query2(ctx)) {
1229 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInternalformati64v");
1230 return;
1231 }
1232
1233 /* For SAMPLES there are cases where params needs to remain unmodified. As
1234 * no pname can return a negative value, we fill params32 with negative
1235 * values as reference values, that can be used to know what copy-back to
1236 * params */
1237 memset(params32, -1, 16);
1238
1239 /* For GL_MAX_COMBINED_DIMENSIONS we need to get back 2 32-bit integers,
1240 * and at the same time we only need 2. So for that pname, we call the
1241 * 32-bit query with bufSize 2, except on the case of bufSize 0, that is
1242 * basically like asking to not get the value, but that is a caller
1243 * problem. */
1244 if (pname == GL_MAX_COMBINED_DIMENSIONS && bufSize > 0)
1245 callSize = 2;
1246 else
1247 callSize = bufSize;
1248
1249 _mesa_GetInternalformativ(target, internalformat, pname, callSize, params32);
1250
1251 if (pname == GL_MAX_COMBINED_DIMENSIONS) {
1252 memcpy(params, params32, sizeof(GLint64));
1253 } else {
1254 for (i = 0; i < realSize; i++) {
1255 /* We only copy back the values that changed */
1256 if (params32[i] < 0)
1257 break;
1258 params[i] = (GLint64) params32[i];
1259 }
1260 }
1261 }