2 * Copyright © 2011 Intel Corporation
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:
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
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 DEALINGS
25 * \file internal-format-query.c
26 * Verify behavior of TEXTURE_INTERNAL_FORMAT for generic compression formats
28 * Typically the \c GL_TEXTURE_INTERNAL_FORMAT query returns the internal
29 * format specified by the application at \c glTexImage2D time. This behavior
30 * is modified for the generic compressed texture internal formats.
31 * Specifically, the issues section of the GL_ARB_texture_compression spec
34 * "(10) Should functionality be provided to allow applications to save
35 * compressed images to disk and reuse them in subsequent runs without
36 * programming to specific formats? If so, how?
38 * RESOLVED: Yes. This can be done without knowledge of specific
39 * compression formats in the following manner:
41 * * Call TexImage with an uncompressed image and a generic compressed
42 * internal format. The texture image will be compressed by the GL, if
45 * * Call GetTexLevelParameteriv with a <value> of TEXTURE_COMPRESSED_ARB
46 * to determine if the GL was able to store the image in compressed
49 * * Call GetTexLevelParameteriv with a <value> of
50 * TEXTURE_INTERNAL_FORMAT to determine the specific compressed image
51 * format in which the image is stored.
55 * The body of the spec (section 3.8.1, Texture Image Specification) also say:
57 * "Generic compressed internal formats are never used directly as the
58 * internal formats of texture images. If <internalformat> is one of the
59 * six generic compressed internal formats, its value is replaced by the
60 * symbolic constant for a specific compressed internal format of the GL's
61 * choosing with the same base internal format. If no specific compressed
62 * format is available, <internalformat> is instead replaced by the
63 * corresponding base internal format. If <internalformat> is given as or
64 * mapped to a specific compressed internal format, but the GL can not
65 * support images compressed in the chosen internal format for any reason
66 * (e.g., the compression format might not support 3D textures or borders),
67 * <internalformat> is replaced by the corresponding base internal format
68 * and the texture image will not be compressed by the GL."
71 #include "piglit-util-gl.h"
73 PIGLIT_GL_TEST_CONFIG_BEGIN
75 config
.supports_gl_compat_version
= 10;
77 config
.window_width
= 10;
78 config
.window_height
= 10;
79 config
.window_visual
= PIGLIT_GL_VISUAL_RGB
;
81 PIGLIT_GL_TEST_CONFIG_END
84 GLenum generic_compressed_format
;
89 * Generic texture formats in OpenGL 1.3 and GL_ARB_texture_compression.
91 static const struct test_vector arb_texture_compression_formats
[] = {
92 {GL_COMPRESSED_ALPHA
, GL_ALPHA
},
93 {GL_COMPRESSED_LUMINANCE
, GL_LUMINANCE
},
94 {GL_COMPRESSED_LUMINANCE_ALPHA
, GL_LUMINANCE_ALPHA
},
95 {GL_COMPRESSED_INTENSITY
, GL_INTENSITY
},
96 {GL_COMPRESSED_RGB
, GL_RGB
},
97 {GL_COMPRESSED_RGBA
, GL_RGBA
},
101 * Generic texture formats in OpenGL 3.0 and GL_ARB_texture_rg.
103 static const struct test_vector arb_texture_rg_formats
[] = {
104 { GL_COMPRESSED_RED
, GL_RED
},
105 { GL_COMPRESSED_RG
, GL_RG
},
109 * Generic texture formats in OpenGL 2.1 and GL_EXT_texture_sRGB.
111 static const struct test_vector ext_texture_srgb_formats
[] = {
112 { GL_COMPRESSED_SRGB_EXT
, GL_RGB
},
113 { GL_COMPRESSED_SRGB_ALPHA_EXT
, GL_RGBA
},
114 { GL_COMPRESSED_SLUMINANCE_EXT
, GL_LUMINANCE
},
115 { GL_COMPRESSED_SLUMINANCE_ALPHA_EXT
, GL_LUMINANCE_ALPHA
},
118 static GLubyte dummy_data
[16 * 16 * 4];
127 add_formats(GLenum
*formats
, GLint
*total
, unsigned add
, ...)
132 formats
= realloc(formats
, sizeof(GLenum
) * (*total
+ add
));
136 for (i
= 0; i
< add
; i
++) {
137 formats
[*total
] = va_arg(ap
, GLenum
);
146 try_formats(const struct test_vector
*t
, unsigned num_tests
,
147 const GLenum
*compressed_formats
, GLint num_compressed_formats
)
152 for (i
= 0; i
< num_tests
; i
++) {
156 const char *generic_compressed_format_string
=
157 piglit_get_gl_enum_name(
158 t
[i
].generic_compressed_format
);
160 if (!piglit_automatic
)
162 printf("Trying %s/0x%04x (base format = 0x%04x)...\n",
163 generic_compressed_format_string
,
164 t
[i
].generic_compressed_format
,
168 glGenTextures(1, &tex
);
169 glBindTexture(GL_TEXTURE_2D
, tex
);
170 glTexImage2D(GL_TEXTURE_2D
, 0,
171 t
[i
].generic_compressed_format
,
173 /* Remember that GL_INTESITY is not a valid format
176 (t
[i
].base_format
== GL_INTENSITY
)
177 ? GL_RGBA
: t
[i
].base_format
,
181 glGetTexLevelParameteriv(GL_TEXTURE_2D
,
183 GL_TEXTURE_COMPRESSED
,
186 glGetTexLevelParameteriv(GL_TEXTURE_2D
,
188 GL_TEXTURE_INTERNAL_FORMAT
,
191 if (!piglit_automatic
) {
192 printf(" is %scompressed, internal format = 0x%04x\n",
193 is_compressed
? "" : "not ",
200 for (j
= 0; j
< num_compressed_formats
; j
++) {
201 if (format
== compressed_formats
[j
])
205 if (format
== t
[i
].generic_compressed_format
) {
207 "%s did compress, but it got the "
209 "format as the specific internal "
211 generic_compressed_format_string
);
213 } else if (format
<= 4 || format
== t
[i
].base_format
) {
215 "%s did compress, but it got an "
217 "format 0x%04x that is "
219 generic_compressed_format_string
,
222 } else if (j
== num_compressed_formats
) {
224 "%s did compress, but it got an "
227 "one of the supported compressed "
228 "formats was expected.\n"
229 "This may just mean the test does not "
230 "know about the compessed format that\n"
231 "was selected by the driver.\n",
232 generic_compressed_format_string
,
233 piglit_get_gl_enum_name(format
));
235 } else if (format
!= t
[i
].base_format
) {
236 if (format
== t
[i
].generic_compressed_format
) {
238 "%s did not compress, but it got the "
240 "format as the specific internal "
242 generic_compressed_format_string
);
245 "%s did not compress, but it got an "
246 "internal format of %s when "
247 "%s was expected.\n",
248 generic_compressed_format_string
,
249 piglit_get_gl_enum_name(format
),
250 piglit_get_gl_enum_name(t
[i
].base_format
));
256 glBindTexture(GL_TEXTURE_2D
, 0);
257 glDeleteTextures(1, &tex
);
259 if (!piglit_automatic
) {
268 piglit_init(int argc
, char **argv
)
270 GLint num_compressed_formats
;
271 GLenum
*compressed_formats
= NULL
;
275 piglit_require_extension("GL_ARB_texture_compression");
277 glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS
,
278 &num_compressed_formats
);
279 if (num_compressed_formats
== 0) {
280 printf("No compressed formats supported.\n");
281 } else if (num_compressed_formats
< 0) {
283 "Invalid number of compressed formats (%d) reported\n",
284 num_compressed_formats
);
285 piglit_report_result(PIGLIT_FAIL
);
287 compressed_formats
= calloc(num_compressed_formats
,
289 glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS
,
290 (GLint
*) compressed_formats
);
292 printf("Driver reported the following compressed formats:\n");
293 for (i
= 0; i
< num_compressed_formats
; i
++) {
294 printf(" 0x%04x %s\n",
295 compressed_formats
[i
],
296 piglit_get_gl_enum_name(compressed_formats
[i
]));
302 /* There are some specific formats that are valid for certain generic
303 * formats that are not returned by the GL_COMRPESSED_TEXTURE_FORMATS
304 * query. That query only returns formats that have no restrictions or
305 * caveats for RGB or RGBA base formats. We have to add these formats
306 * to the list of possible formats by hand.
308 if (piglit_is_extension_supported("GL_EXT_texture_compression_latc")) {
310 add_formats(compressed_formats
,
311 &num_compressed_formats
,
313 GL_COMPRESSED_LUMINANCE_LATC1_EXT
,
314 GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT
,
315 GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT
,
316 GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT
);
319 if (piglit_is_extension_supported("GL_ATI_texture_compression_3dc")) {
321 add_formats(compressed_formats
,
322 &num_compressed_formats
,
327 pass
= try_formats(arb_texture_compression_formats
,
328 ARRAY_SIZE(arb_texture_compression_formats
),
330 num_compressed_formats
);
332 /* Remove the various luminance and luminance-alpha formats from the
333 * list since they cannot be used for the later tests.
335 if (piglit_is_extension_supported("GL_ATI_texture_compression_3dc")) {
336 num_compressed_formats
--;
339 if (piglit_is_extension_supported("GL_EXT_texture_compression_latc")) {
340 num_compressed_formats
-= 4;
343 /* Add the RGTC formats, then check them.
345 if (piglit_is_extension_supported("GL_ARB_texture_rg")) {
346 if (piglit_is_extension_supported("GL_ARB_texture_compression_rgtc")
347 || piglit_is_extension_supported("GL_EXT_texture_compression_rgtc")) {
349 add_formats(compressed_formats
,
350 &num_compressed_formats
,
352 GL_COMPRESSED_RED_RGTC1
,
353 GL_COMPRESSED_SIGNED_RED_RGTC1
,
354 GL_COMPRESSED_RG_RGTC2
,
355 GL_COMPRESSED_SIGNED_RG_RGTC2
);
358 pass
= try_formats(arb_texture_rg_formats
,
359 ARRAY_SIZE(arb_texture_rg_formats
),
361 num_compressed_formats
)
364 /* Remove the RGTC formats from the list since they cannot be
365 * used for the later tests.
367 if (piglit_is_extension_supported("GL_ARB_texture_compression_rgtc")
368 || piglit_is_extension_supported("GL_EXT_texture_compression_rgtc")) {
369 num_compressed_formats
-= 4;
374 /* Add the sRGB formats, then check them.
376 if (piglit_is_extension_supported("GL_EXT_texture_sRGB")) {
378 add_formats(compressed_formats
,
379 &num_compressed_formats
,
382 GL_COMPRESSED_SRGB_ALPHA
,
383 GL_COMPRESSED_SLUMINANCE
,
384 GL_COMPRESSED_SLUMINANCE_ALPHA
);
386 if (piglit_is_extension_supported("GL_EXT_texture_compression_s3tc")) {
388 add_formats(compressed_formats
,
389 &num_compressed_formats
,
391 GL_COMPRESSED_SRGB_S3TC_DXT1_EXT
,
392 GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
,
393 GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
,
394 GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
);
397 pass
= try_formats(ext_texture_srgb_formats
,
398 ARRAY_SIZE(ext_texture_srgb_formats
),
400 num_compressed_formats
)
403 /* Remove the sRGB formats from the list since they cannot be
404 * used for the later tests.
406 num_compressed_formats
-= 4;
407 if (piglit_is_extension_supported("GL_EXT_texture_compression_s3tc")) {
408 num_compressed_formats
-= 4;
412 piglit_report_result(pass
? PIGLIT_PASS
: PIGLIT_FAIL
);