[Piglit] [PATCH 1/2] arb_texture_compression: Check internal formats when generic formats are used

Ian Romanick idr at freedesktop.org
Sat Jul 23 02:00:22 PDT 2011


From: Ian Romanick <ian.d.romanick at intel.com>

Typically the GL_TEXTURE_INTERNAL_FORMAT query returns the internal
format specified by the application at glTexImage2D time.  This
behavior is modified for the generic compressed texture internal
formats.  If a generic compressed format is specified by the
application, GL_TEXTURE_INTERNAL_FORMAT is supposed to return either
the specific compression format used or the generic base format (e.g.,
GL_RGBA).

This test fails on NVIDIA (driver version 260.19.36) because it
returns sized formats (e.g., GL_ALPHA8) instead of the unsized base
formats for non-compressed textures.

This test fails on AMD (driver version 11.6) because it always returns
the generic compressed format (e.g., GL_COMPRESSED_SRGB) for
non-compressed textures.  It also reports *nothing* for
GL_COMPRESSED_TEXTURE_FORMATS, so the S3TC checks also fail.

This test fails on Mesa (driver version 7.10.3) because it always returns
the generic compressed format (e.g., GL_COMPRESSED_SRGB) for
non-compressed textures.

I have not tested on Apple or Intel's Windows driver.

This is related to the ancient Mesa bug #3165.
---
 tests/all.tests                                    |    2 +
 tests/spec/CMakeLists.txt                          |    1 +
 .../spec/arb_texture_compression/CMakeLists.gl.txt |   17 +
 tests/spec/arb_texture_compression/CMakeLists.txt  |    1 +
 .../internal-format-query.c                        |  396 ++++++++++++++++++++
 5 files changed, 417 insertions(+), 0 deletions(-)
 create mode 100644 tests/spec/arb_texture_compression/CMakeLists.gl.txt
 create mode 100644 tests/spec/arb_texture_compression/CMakeLists.txt
 create mode 100644 tests/spec/arb_texture_compression/internal-format-query.c

diff --git a/tests/all.tests b/tests/all.tests
index 1a36834..ead56d6 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -932,6 +932,8 @@ add_texwrap_test2(arb_texture_compression, '2D', 'GL_COMPRESSED_LUMINANCE_ALPHA'
 add_texwrap_test2(arb_texture_compression, '2D', 'GL_COMPRESSED_INTENSITY')
 add_texwrap_test2(arb_texture_compression, '2D', 'GL_COMPRESSED_RGB')
 add_texwrap_test2(arb_texture_compression, '2D', 'GL_COMPRESSED_RGBA')
+arb_texture_compression['GL_TEXTURE_INTERNAL_FORMAT query'] = PlainExecTest(['arb_texture_compression-internal-format-query', '-auto'])
+arb_texture_compression['GL_TEXTURE_INTERNAL_FORMAT query'].runConcurrent = True
 
 arb_vertex_buffer_object = Group()
 spec['ARB_vertex_buffer_object'] = arb_vertex_buffer_object
diff --git a/tests/spec/CMakeLists.txt b/tests/spec/CMakeLists.txt
index 5900c9f..c1af70d 100644
--- a/tests/spec/CMakeLists.txt
+++ b/tests/spec/CMakeLists.txt
@@ -7,6 +7,7 @@ add_subdirectory (arb_seamless_cube_map)
 add_subdirectory (amd_seamless_cubemap_per_texture)
 add_subdirectory (arb_shader_texture_lod/execution)
 add_subdirectory (ati_draw_buffers)
+add_subdirectory (arb_texture_compression)
 add_subdirectory (arb_texture_float)
 add_subdirectory (ati_envmap_bumpmap)
 add_subdirectory (ext_fog_coord)
diff --git a/tests/spec/arb_texture_compression/CMakeLists.gl.txt b/tests/spec/arb_texture_compression/CMakeLists.gl.txt
new file mode 100644
index 0000000..7fdf00c
--- /dev/null
+++ b/tests/spec/arb_texture_compression/CMakeLists.gl.txt
@@ -0,0 +1,17 @@
+include_directories(
+	${GLEXT_INCLUDE_DIR}
+	${OPENGL_INCLUDE_PATH}
+	${GLUT_INCLUDE_DIR}
+	${piglit_SOURCE_DIR}/tests/util
+)
+
+link_libraries (
+	piglitutil
+	${OPENGL_gl_LIBRARY}
+	${OPENGL_glu_LIBRARY}
+	${GLUT_glut_LIBRARY}
+)
+
+add_executable (arb_texture_compression-internal-format-query internal-format-query.c)
+
+# vim: ft=cmake:
diff --git a/tests/spec/arb_texture_compression/CMakeLists.txt b/tests/spec/arb_texture_compression/CMakeLists.txt
new file mode 100644
index 0000000..144a306
--- /dev/null
+++ b/tests/spec/arb_texture_compression/CMakeLists.txt
@@ -0,0 +1 @@
+piglit_include_target_api()
diff --git a/tests/spec/arb_texture_compression/internal-format-query.c b/tests/spec/arb_texture_compression/internal-format-query.c
new file mode 100644
index 0000000..6b1b065
--- /dev/null
+++ b/tests/spec/arb_texture_compression/internal-format-query.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/**
+ * \file internal-format-query.c
+ * Verify behavior of TEXTURE_INTERNAL_FORMAT for generic compression formats
+ *
+ * Typically the \c GL_TEXTURE_INTERNAL_FORMAT query returns the internal
+ * format specified by the application at \c glTexImage2D time.  This behavior
+ * is modified for the generic compressed texture internal formats.
+ * Specifically, the issues section of the GL_ARB_texture_compression spec
+ * says:
+ *
+ *    "(10) Should functionality be provided to allow applications to save
+ *    compressed images to disk and reuse them in subsequent runs without
+ *    programming to specific formats?  If so, how?
+ *
+ *      RESOLVED:  Yes.  This can be done without knowledge of specific
+ *      compression formats in the following manner:
+ *
+ *        * Call TexImage with an uncompressed image and a generic compressed
+ *          internal format.  The texture image will be compressed by the GL, if
+ *          possible.
+ *
+ *        * Call GetTexLevelParameteriv with a <value> of TEXTURE_COMPRESSED_ARB
+ *          to determine if the GL was able to store the image in compressed
+ *          form.
+ *
+ *        * Call GetTexLevelParameteriv with a <value> of
+ *          TEXTURE_INTERNAL_FORMAT to determine the specific compressed image
+ *          format in which the image is stored.
+ *
+ *        ..."
+ *
+ * The body of the spec (section 3.8.1, Texture Image Specification) also say:
+ *
+ *     "Generic compressed internal formats are never used directly as the
+ *     internal formats of texture images.  If <internalformat> is one of the
+ *     six generic compressed internal formats, its value is replaced by the
+ *     symbolic constant for a specific compressed internal format of the GL's
+ *     choosing with the same base internal format.  If no specific compressed
+ *     format is available, <internalformat> is instead replaced by the
+ *     corresponding base internal format.  If <internalformat> is given as or
+ *     mapped to a specific compressed internal format, but the GL can not
+ *     support images compressed in the chosen internal format for any reason
+ *     (e.g., the compression format might not support 3D textures or borders),
+ *     <internalformat> is replaced by the corresponding base internal format
+ *     and the texture image will not be compressed by the GL."
+ */
+#include <stdarg.h>
+#include "piglit-util.h"
+
+int piglit_width = 10, piglit_height = 10;
+int piglit_window_mode = GLUT_RGB;
+
+#define ENUM_AND_STRING(e) \
+	# e, e
+
+struct test_vector {
+	const char *generic_compressed_format_string;
+	GLenum generic_compressed_format;
+	GLenum base_format;
+};
+
+static const struct test_vector arb_texture_compression_formats[] = {
+        { ENUM_AND_STRING(GL_COMPRESSED_ALPHA), GL_ALPHA },
+        { ENUM_AND_STRING(GL_COMPRESSED_LUMINANCE), GL_LUMINANCE },
+        { ENUM_AND_STRING(GL_COMPRESSED_LUMINANCE_ALPHA), GL_LUMINANCE_ALPHA },
+        { ENUM_AND_STRING(GL_COMPRESSED_INTENSITY), GL_INTENSITY },
+        { ENUM_AND_STRING(GL_COMPRESSED_RGB), GL_RGB },
+        { ENUM_AND_STRING(GL_COMPRESSED_RGBA), GL_RGBA },
+};
+
+static const struct test_vector arb_texture_rg_formats[] = {
+        { ENUM_AND_STRING(GL_COMPRESSED_RED), GL_RGB },
+        { ENUM_AND_STRING(GL_COMPRESSED_RG), GL_RGB },
+};
+
+static const struct test_vector ext_texture_srgb_formats[] = {
+	{ ENUM_AND_STRING(GL_COMPRESSED_SRGB_EXT), GL_RGB },
+	{ ENUM_AND_STRING(GL_COMPRESSED_SRGB_ALPHA_EXT), GL_RGBA },
+	{ ENUM_AND_STRING(GL_COMPRESSED_SLUMINANCE_EXT), GL_LUMINANCE },
+	{ ENUM_AND_STRING(GL_COMPRESSED_SLUMINANCE_ALPHA_EXT), GL_LUMINANCE_ALPHA },
+};
+
+static GLubyte dummy_data[16 * 16 * 4];
+
+enum piglit_result
+piglit_display(void)
+{
+	return PIGLIT_FAIL;
+}
+
+GLenum *
+add_formats(GLenum *formats, GLint *total, unsigned add, ...)
+{
+	va_list ap;
+	unsigned i;
+
+	formats = realloc(formats, sizeof(GLenum) * (*total + add));
+
+	va_start(ap, add);
+
+	for (i = 0; i < add; i++) {
+		formats[*total] = va_arg(ap, GLenum);
+		(*total)++;
+	}
+
+	va_end(ap);
+	return formats;
+}
+
+static bool
+try_formats(const struct test_vector *t, unsigned num_tests,
+	    const GLenum *compressed_formats, GLint num_compressed_formats)
+{
+	bool pass = true;
+	unsigned i;
+
+	for (i = 0; i < num_tests; i++) {
+		GLuint tex;
+		GLint is_compressed;
+		GLenum format;
+
+		if (!piglit_automatic) {
+			printf("Trying %s/0x%04x (base format = 0x%04x)...\n",
+			       t[i].generic_compressed_format_string,
+			       t[i].generic_compressed_format,
+			       t[i].base_format);
+		}
+
+		glGenTextures(1, &tex);
+		glBindTexture(GL_TEXTURE_2D, tex);
+		glTexImage2D(GL_TEXTURE_2D, 0,
+			     t[i].generic_compressed_format,
+			     16, 16, 0,
+			     /* Remember that GL_INTESITY is not a valid format
+			      * for image data.
+			      */
+			     (t[i].base_format == GL_INTENSITY)
+			     ? GL_RGBA : t[i].base_format,
+			     GL_UNSIGNED_BYTE,
+			     dummy_data);
+
+		glGetTexLevelParameteriv(GL_TEXTURE_2D,
+					 0,
+					 GL_TEXTURE_COMPRESSED,
+					 &is_compressed);
+
+		glGetTexLevelParameteriv(GL_TEXTURE_2D,
+					 0,
+					 GL_TEXTURE_INTERNAL_FORMAT,
+					 (GLint *) &format);
+
+		if (!piglit_automatic) {
+			printf("  is %scompressed, internal format = 0x%04x\n",
+			       is_compressed ? "" : "not ",
+			       format);
+		}
+
+		if (is_compressed) {
+			unsigned j;
+
+			for (j = 0; j < num_compressed_formats; j++) {
+				if (format == compressed_formats[j])
+					break;
+			}
+
+			if (format == t[i].generic_compressed_format) {
+				fprintf(stderr,
+					"%s did compress, but it got the "
+					"generic\n"
+					"format as the specific internal "
+					"format.\n",
+					t[i].generic_compressed_format_string);
+				pass = false;
+			} else if (format <= 4 || format == t[i].base_format) {
+				fprintf(stderr,
+					"%s did compress, but it got an "
+					"internal\n"
+					"format 0x%04x that is "
+					"non-compressed\n",
+					t[i].generic_compressed_format_string,
+					format);
+				pass = false;
+			} else if (j == num_compressed_formats) {
+				fprintf(stderr,
+					"%s did compress, but it got an "
+					"internal\n"
+					"format of 0x%04x when "
+					"one of the supported compressed "
+					"formats was expected.\n"
+					"This may just mean the test does not "
+					"know about the compessed format that\n"
+					"was selected by the driver.\n",
+					t[i].generic_compressed_format_string,
+					format);
+			}
+		} else if (format != t[i].base_format) {
+			if (format == t[i].generic_compressed_format) {
+				fprintf(stderr,
+					"%s did not compress, but it got the "
+					"generic\n"
+					"format as the specific internal "
+					"format.\n",
+					t[i].generic_compressed_format_string);
+			} else {
+				fprintf(stderr,
+					"%s did not compress, but it got an "
+					"internal\n"
+					"format of 0x%04x when "
+					"0x%04x was expected.\n",
+					t[i].generic_compressed_format_string,
+					format,
+					t[i].base_format);
+			}
+
+			pass = false;
+		}
+
+		glBindTexture(GL_TEXTURE_2D, 0);
+		glDeleteTextures(1, &tex);
+
+		if (!piglit_automatic) {
+			printf("\n");
+		}
+	}
+
+	return pass;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	GLint num_compressed_formats;
+	GLenum *compressed_formats = NULL;
+	unsigned i;
+	bool pass = true;
+
+	piglit_require_extension("GL_ARB_texture_compression");
+
+	glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS,
+		      &num_compressed_formats);
+	if (num_compressed_formats == 0) {
+		printf("No compressed formats supported.\n");
+	} else if (num_compressed_formats < 0) {
+		fprintf(stderr,
+			"Invalid number of compressed formats (%d) reported\n",
+			num_compressed_formats);
+		piglit_report_result(PIGLIT_FAIL);
+	} else {
+		compressed_formats = calloc(num_compressed_formats,
+					    sizeof(GLenum));
+		glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS,
+			      (GLint *) compressed_formats);
+
+		printf("Driver reported the following compressed formats:\n");
+		for (i = 0; i < num_compressed_formats; i++) {
+			printf("    0x%04x\n", compressed_formats[i]);
+		}
+		printf("\n");
+		fflush(stdout);
+	}
+
+	/* There are some specific formats that are valid for certain generic
+	 * formats that are not returned by the GL_COMRPESSED_TEXTURE_FORMATS
+	 * query.  That query only returns formats that have no restrictions or
+	 * caveats for RGB or RGBA base formats.  We have to add these formats
+	 * to the list of possible formats by hand.
+	 */
+	if (GLEW_EXT_texture_compression_latc) {
+		compressed_formats =
+			add_formats(compressed_formats,
+				    &num_compressed_formats,
+				    4,
+				    GL_COMPRESSED_LUMINANCE_LATC1_EXT,
+				    GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT,
+				    GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT,
+				    GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT);
+	}
+
+	if (GLEW_ATI_texture_compression_3dc) {
+		compressed_formats =
+			add_formats(compressed_formats,
+				    &num_compressed_formats,
+				    1,
+				    0x8837);
+	}
+
+	pass = try_formats(arb_texture_compression_formats,
+			   ARRAY_SIZE(arb_texture_compression_formats),
+			   compressed_formats,
+			   num_compressed_formats);
+
+	/* Remove the various luminance and luminance-alpha formats from the
+	 * list since they cannot be used for the later tests.
+	 */
+	if (GLEW_ATI_texture_compression_3dc) {
+		num_compressed_formats--;
+	}
+
+	if (GLEW_EXT_texture_compression_latc) {
+		num_compressed_formats -= 4;
+	}
+
+	/* Add the RGTC formats, then check them.
+	 */
+	if (GLEW_ARB_texture_rg) {
+		if (GLEW_ARB_texture_compression_rgtc
+		    || GLEW_EXT_texture_compression_rgtc) {
+			compressed_formats =
+				add_formats(compressed_formats,
+					    &num_compressed_formats,
+					    4,
+					    GL_COMPRESSED_RED_RGTC1,
+					    GL_COMPRESSED_SIGNED_RED_RGTC1,
+					    GL_COMPRESSED_RG_RGTC2,
+					    GL_COMPRESSED_SIGNED_RG_RGTC2);
+		}
+
+		pass = try_formats(arb_texture_rg_formats,
+				   ARRAY_SIZE(arb_texture_rg_formats),
+				   compressed_formats,
+				   num_compressed_formats)
+			&& pass;
+
+		/* Remove the RGTC formats from the list since they cannot be
+		 * used for the later tests.
+		 */
+		if (GLEW_ARB_texture_compression_rgtc
+		    || GLEW_EXT_texture_compression_rgtc) {
+			num_compressed_formats -= 4;
+		}
+	}
+
+
+	/* Add the sRGB formats, then check them.
+	 */
+	if (GLEW_EXT_texture_sRGB) {
+		compressed_formats =
+			add_formats(compressed_formats,
+				    &num_compressed_formats,
+				    4,
+				    GL_COMPRESSED_SRGB,
+				    GL_COMPRESSED_SRGB_ALPHA,
+				    GL_COMPRESSED_SLUMINANCE,
+				    GL_COMPRESSED_SLUMINANCE_ALPHA);
+
+		if (GLEW_EXT_texture_compression_s3tc) {
+			compressed_formats =
+				add_formats(compressed_formats,
+					    &num_compressed_formats,
+					    4,
+					    GL_COMPRESSED_SRGB_S3TC_DXT1_EXT,
+					    GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,
+					    GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,
+					    GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT);
+		}
+
+		pass = try_formats(ext_texture_srgb_formats,
+				   ARRAY_SIZE(ext_texture_srgb_formats),
+				   compressed_formats,
+				   num_compressed_formats)
+			&& pass;
+
+		/* Remove the sRGB formats from the list since they cannot be
+		 * used for the later tests.
+		 */
+		num_compressed_formats -= 4;
+		if (GLEW_EXT_texture_compression_s3tc) {
+			num_compressed_formats -= 4;
+		}
+	}
+
+	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
+}
-- 
1.7.4.4



More information about the Piglit mailing list