[Piglit] [PATCH] Test layered color clears with all layered texture types.

Paul Berry stereotype441 at gmail.com
Wed Nov 20 13:04:57 PST 2013


This test is similar to the existing clear-color test, except that it
tests all possible layered attachment types, and it's capable of
testing both mipmapped and non-mipmapped textures.

Verified using the Nvidia proprietary driver for Linux, version
313.18.
---
 tests/all.tests                                    |   9 +
 .../gl-3.2/layered-rendering/CMakeLists.gl.txt     |   1 +
 .../layered-rendering/clear-color-all-types.c      | 403 +++++++++++++++++++++
 3 files changed, 413 insertions(+)
 create mode 100644 tests/spec/gl-3.2/layered-rendering/clear-color-all-types.c

diff --git a/tests/all.tests b/tests/all.tests
index e9a579c..132c2f4 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -754,6 +754,15 @@ spec['!OpenGL 3.2/get-integer-64iv'] = concurrent_test('gl-3.2-get-integer-64iv'
 spec['!OpenGL 3.2/get-integer-64v'] = concurrent_test('gl-3.2-get-integer-64v')
 spec['!OpenGL 3.2/layered-rendering/blit'] = concurrent_test('gl-3.2-layered-rendering-blit')
 spec['!OpenGL 3.2/layered-rendering/clear-color'] = concurrent_test('gl-3.2-layered-rendering-clear-color')
+for texture_type in ['3d', '2d_array', '2d_multisample_array', '1d_array',
+                     'cube_map', 'cube_map_array']:
+    for test_type in ['single_level', 'mipmapped']:
+        if texture_type == '2d_multisample_array' and test_type == 'mipmapped':
+            continue
+        cmdline = 'clear-color-all-types {0} {1}'.format(
+            texture_type, test_type)
+        spec['!OpenGL 3.2/layered-rendering/' + cmdline] = \
+            concurrent_test('gl-3.2-layered-rendering-' + cmdline)
 spec['!OpenGL 3.2/layered-rendering/clear-depth'] = concurrent_test('gl-3.2-layered-rendering-clear-depth')
 spec['!OpenGL 3.2/layered-rendering/framebuffertexture'] = concurrent_test('gl-3.2-layered-rendering-framebuffertexture')
 spec['!OpenGL 3.2/layered-rendering/framebuffertexture-buffer-textures'] = concurrent_test('gl-3.2-layered-rendering-framebuffertexture-buffer-textures')
diff --git a/tests/spec/gl-3.2/layered-rendering/CMakeLists.gl.txt b/tests/spec/gl-3.2/layered-rendering/CMakeLists.gl.txt
index 9ce5552..c769b15 100644
--- a/tests/spec/gl-3.2/layered-rendering/CMakeLists.gl.txt
+++ b/tests/spec/gl-3.2/layered-rendering/CMakeLists.gl.txt
@@ -11,6 +11,7 @@ link_libraries (
 
 piglit_add_executable (gl-3.2-layered-rendering-blit blit.c)
 piglit_add_executable (gl-3.2-layered-rendering-clear-color clear-color.c)
+piglit_add_executable (gl-3.2-layered-rendering-clear-color-all-types clear-color-all-types.c)
 piglit_add_executable (gl-3.2-layered-rendering-clear-depth clear-depth.c)
 piglit_add_executable (gl-3.2-layered-rendering-framebuffer-layered-attachments framebuffer-layered-attachments.c)
 piglit_add_executable (gl-3.2-layered-rendering-framebuffer-layer-complete framebuffer-layer-complete.c)
diff --git a/tests/spec/gl-3.2/layered-rendering/clear-color-all-types.c b/tests/spec/gl-3.2/layered-rendering/clear-color-all-types.c
new file mode 100644
index 0000000..facb1d5
--- /dev/null
+++ b/tests/spec/gl-3.2/layered-rendering/clear-color-all-types.c
@@ -0,0 +1,403 @@
+/*
+ * Copyright © 2013 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
+ *
+ * Test that layered color clear works properly with all of the
+ * following texture types:
+ *
+ * - GL_TEXTURE_3D
+ * - GL_TEXTURE_2D_ARRAY
+ * - GL_TEXTURE_2D_MULTISAMPLE_ARRAY
+ * - GL_TEXTURE_1D_ARRAY
+ * - GL_TEXTURE_CUBE_MAP
+ * - GL_TEXTURE_CUBE_MAP_ARRAY (requires GL_ARB_texture_cube_map_array)
+ *
+ * The test can be run in two modes:
+ *
+ * - single_level, which tests layered clears on a texture with just a
+ *   single miplevel.
+ *
+ * - mipmapped, which tests layered clears on a mipmapped texture.
+ *
+ * The test operates as follows:
+ *
+ * - A texture is created with the requested type and the appropriate
+ *   number of miplevels for the test.
+ *
+ * - Every level and layer of the texture is individually cleared to
+ *   red.
+ *
+ * - Every level and layer of the texture is checked to verify that it
+ *   has been properly cleared to red.
+ *
+ * - The texture is cleared in layered fashion, with each level being
+ *   bound to a layered framebuffer and then cleared all at once.
+ *   Each level is cleared to a different color.
+ *
+ * - Every level and layer of the texture is checked to verify that it
+ *   has been cleared to the expected color.
+ */
+
+#include "piglit-util-gl-common.h"
+#include "piglit-util.h"
+
+#define TEX_LEVELS 6
+#define TEX_SIZE (1 << (TEX_LEVELS - 1))
+#define TEX_DEPTH 4
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_compat_version = 32;
+	config.supports_gl_core_version = 32;
+	config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+
+static GLenum texture_type;
+static int num_layers;
+static int layer_height;
+static GLuint probe_fbo = 0;
+static bool mipmapped;
+static int num_miplevels;
+static GLfloat level_colors[TEX_LEVELS][4] = {
+	{ 0,   1,   0,   1 },
+	{ 0,   1,   0.5, 1 },
+	{ 0,   1,   1,   1 },
+	{ 0,   0.5, 1,   1 },
+	{ 0,   0,   1,   1 },
+	{ 0.5, 0,   1,   1 }
+};
+
+
+
+static void
+print_usage_and_exit(const char *prog_name)
+{
+	printf("Usage: %s <texture_type> <test_type>\n"
+	       "  Where <texture_type> is one of:\n"
+	       "    3d\n"
+	       "    2d_array\n"
+	       "    2d_multisample_array\n"
+	       "    1d_array\n"
+	       "    cube_map\n"
+	       "    cube_map_array\n"
+	       "  And <test_type> is one of:\n"
+	       "    single_level\n"
+	       "    mipmapped\n",
+	       prog_name);
+	piglit_report_result(PIGLIT_FAIL);
+}
+
+
+GLenum cube_map_faces[6] = {
+	GL_TEXTURE_CUBE_MAP_POSITIVE_X,
+	GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
+	GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
+	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
+	GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
+	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
+};
+
+
+static int
+level_width(int level)
+{
+	return MAX2(TEX_SIZE >> level, 1);
+}
+
+
+static int
+level_height(int level)
+{
+	return MAX2(layer_height >> level, 1);
+}
+
+
+static int
+level_layers(int level)
+{
+	if (texture_type == GL_TEXTURE_3D)
+		return MAX2(num_layers >> level, 1);
+	else
+		return num_layers;
+}
+
+
+static void
+init_texture(void)
+{
+	int i, level;
+
+	for (level = 0; level < num_miplevels; level++) {
+		switch (texture_type) {
+		case GL_TEXTURE_3D:
+		case GL_TEXTURE_2D_ARRAY:
+		case GL_TEXTURE_CUBE_MAP_ARRAY:
+			glTexImage3D(texture_type, level, GL_RGBA,
+				     level_width(level), level_height(level),
+				     level_layers(level), 0 /* border */,
+				     GL_RGBA, GL_FLOAT, NULL);
+			break;
+		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+			glTexImage3DMultisample(texture_type, 4, GL_RGBA,
+						level_width(level),
+						level_height(level), TEX_DEPTH,
+						GL_FALSE);
+			break;
+		case GL_TEXTURE_CUBE_MAP:
+			for (i = 0; i < 6; i++) {
+				glTexImage2D(cube_map_faces[i], level, GL_RGBA,
+					     level_width(level),
+					     level_height(level),
+					     0 /* border */, GL_RGBA, GL_FLOAT,
+					     NULL);
+			}
+			break;
+		case GL_TEXTURE_1D_ARRAY:
+			for (level = 0; level < num_miplevels; level++) {
+				glTexImage2D(texture_type, level, GL_RGBA,
+					     level_width(level),
+					     level_layers(level),
+					     0 /* border */, GL_RGBA, GL_FLOAT,
+					     NULL);
+			}
+			break;
+		default:
+			printf("Don't know how to create texture type %s\n",
+			       piglit_get_gl_enum_name(texture_type));
+			piglit_report_result(PIGLIT_FAIL);
+		}
+	}
+}
+
+
+static void
+bind_layer(GLenum target, GLuint texture, int level, int layer)
+{
+	switch (texture_type) {
+	case GL_TEXTURE_3D:
+	case GL_TEXTURE_2D_ARRAY:
+	case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+	case GL_TEXTURE_1D_ARRAY:
+	case GL_TEXTURE_CUBE_MAP_ARRAY:
+		glFramebufferTextureLayer(target, GL_COLOR_ATTACHMENT0,
+					  texture, level, layer);
+		break;
+	case GL_TEXTURE_CUBE_MAP:
+		glFramebufferTexture2D(target, GL_COLOR_ATTACHMENT0,
+				       cube_map_faces[layer], texture, level);
+		break;
+	default:
+		printf("Don't know how to bind texture type %s\n",
+		       piglit_get_gl_enum_name(texture_type));
+		piglit_report_result(PIGLIT_FAIL);
+	}
+}
+
+
+static void
+check_completeness(const char *when, GLenum target)
+{
+	GLenum fbstatus = glCheckFramebufferStatus(target);
+	if (fbstatus != GL_FRAMEBUFFER_COMPLETE) {
+		printf("Framebuffer incomplete when %s: %s\n", when,
+		       piglit_get_gl_enum_name(fbstatus));
+		piglit_report_result(PIGLIT_FAIL);
+	}
+}
+
+
+static bool
+check_layers(GLuint fbo, GLuint tex, bool expect_red)
+{
+	const GLfloat red[] = { 1, 0, 0, 1 };
+	bool pass = true;
+	int level, layer;
+
+	for (level = 0; level < num_miplevels; level++) {
+		const GLfloat *expected_color;
+		if (expect_red)
+			expected_color = red;
+		else
+			expected_color = level_colors[level];
+
+		for (layer = 0; layer < level_layers(level); layer++) {
+			glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
+			bind_layer(GL_READ_FRAMEBUFFER, tex, level, layer);
+			check_completeness("reading layers",
+					   GL_READ_FRAMEBUFFER);
+			printf("Probing level %d, layer %d\n", level, layer);
+
+			if (probe_fbo != 0) {
+				/* We can't probe a multisampled texture
+				 * directly, so first blit it to a temporary
+				 * framebuffer.
+				 */
+				glBindFramebuffer(GL_DRAW_FRAMEBUFFER,
+						  probe_fbo);
+				glBlitFramebuffer(0, 0, level_width(level),
+						  level_height(level),
+						  0, 0, level_width(level),
+						  level_height(level),
+						  GL_COLOR_BUFFER_BIT,
+						  GL_NEAREST);
+				glBindFramebuffer(GL_READ_FRAMEBUFFER,
+						  probe_fbo);
+			}
+
+			pass = piglit_probe_rect_rgba(0, 0, level_width(level),
+						      level_height(level),
+						      expected_color) && pass;
+		}
+	}
+	return pass;
+}
+
+
+void
+piglit_init(int argc, char **argv)
+{
+	int level, layer;
+	bool pass = true;
+	GLuint tex, fbo;
+
+	layer_height = TEX_SIZE;
+	num_layers = TEX_DEPTH;
+
+	if (argc != 3)
+		print_usage_and_exit(argv[0]);
+	if (strcmp(argv[1], "3d") == 0) {
+		texture_type = GL_TEXTURE_3D;
+	} else if (strcmp(argv[1], "2d_array") == 0) {
+		texture_type = GL_TEXTURE_2D_ARRAY;
+	} else if (strcmp(argv[1], "2d_multisample_array") == 0) {
+		texture_type = GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
+	} else if (strcmp(argv[1], "1d_array") == 0) {
+		texture_type = GL_TEXTURE_1D_ARRAY;
+		layer_height = 1;
+	} else if (strcmp(argv[1], "cube_map") == 0) {
+		texture_type = GL_TEXTURE_CUBE_MAP;
+		num_layers = 6;
+	} else if (strcmp(argv[1], "cube_map_array") == 0) {
+		piglit_require_extension("GL_ARB_texture_cube_map_array");
+		texture_type = GL_TEXTURE_CUBE_MAP_ARRAY;
+		num_layers = 6 * TEX_DEPTH;
+	} else {
+		print_usage_and_exit(argv[0]);
+	}
+	if (strcmp(argv[2], "single_level") == 0) {
+		mipmapped = false;
+		num_miplevels = 1;
+	} else if (strcmp(argv[2], "mipmapped") == 0) {
+		if (texture_type == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
+			printf("2d_multisample_array is incompatible with "
+			       "mipmapped\n");
+			piglit_report_result(PIGLIT_FAIL);
+		}
+		mipmapped = true;
+		num_miplevels = TEX_LEVELS;
+	} else {
+		print_usage_and_exit(argv[0]);
+	}
+
+	glGenTextures(1, &tex);
+	glBindTexture(texture_type, tex);
+	if (texture_type != GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
+		if (mipmapped) {
+			glTexParameteri(texture_type, GL_TEXTURE_MIN_FILTER,
+					GL_LINEAR_MIPMAP_NEAREST);
+		} else {
+			glTexParameteri(texture_type, GL_TEXTURE_MIN_FILTER,
+					GL_LINEAR);
+		}
+		glTexParameteri(texture_type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+	}
+	init_texture();
+	glGenFramebuffers(1, &fbo);
+
+	if (texture_type == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) {
+		/* We'll need a framebuffer we can blit to (in order
+		 * to resolve the multisamples) before probing.
+		 */
+		GLuint rb;
+		glGenRenderbuffers(1, &rb);
+		glBindRenderbuffer(GL_RENDERBUFFER, rb);
+		glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, TEX_SIZE,
+				      layer_height);
+		glGenFramebuffers(1, &probe_fbo);
+		glBindFramebuffer(GL_FRAMEBUFFER, probe_fbo);
+		glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+					  GL_RENDERBUFFER, rb);
+	}
+
+	/* Bind each layer of the texture individually and clear it to red. */
+	printf("Clearing each layer individually\n");
+	glViewport(0, 0, TEX_SIZE, layer_height);
+	glClearColor(1, 0, 0, 1);
+	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
+	for (level = 0; level < num_miplevels; level++) {
+		for (layer = 0; layer < level_layers(level); layer++) {
+			bind_layer(GL_DRAW_FRAMEBUFFER, tex, level, layer);
+			check_completeness("clearing individual layers",
+					   GL_DRAW_FRAMEBUFFER);
+			glClear(GL_COLOR_BUFFER_BIT);
+		}
+	}
+
+	/* Check that each level/layer is cleared to red. */
+	pass = check_layers(fbo, tex, true) && pass;
+
+	/* Bind the entire texture in layered fashion and clear each
+	 * miplevel to level_colors[level].
+	 */
+	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
+	for (level = 0; level < num_miplevels; level++) {
+		printf("Clearing all layers in miplevel %d at once\n", level);
+		glClearColor(level_colors[level][0], level_colors[level][1],
+			     level_colors[level][2], level_colors[level][3]);
+		glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+				     tex, level);
+		check_completeness("clearing whole texture",
+				   GL_DRAW_FRAMEBUFFER);
+		glClear(GL_COLOR_BUFFER_BIT);
+	}
+
+	/* Check that each level/layer is cleared to the proper
+	 * color.
+	 */
+	pass = check_layers(fbo, tex, false) && pass;
+
+	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
+
+	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
+}
+
+
+enum piglit_result
+piglit_display(void)
+{
+	/* Should never be reached */
+	return PIGLIT_FAIL;
+}
-- 
1.8.4.2



More information about the Piglit mailing list