[Piglit] [PATCH 1/3] Add a fast clear test for non-MSRT surfaces

Neil Roberts neil at linux.intel.com
Wed Nov 25 03:22:35 PST 2015


This is similar to ext_framebuffer_multisample-fast-clear except that
it tests a regular single-sampled texture. This is worth testing at
least on i965 because fast clears are handled differently when
multisampling is not used.
---
 tests/all.py                |   5 +
 tests/fbo/CMakeLists.gl.txt |   1 +
 tests/fbo/fbo-fast-clear.c  | 401 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 407 insertions(+)
 create mode 100644 tests/fbo/fbo-fast-clear.c

diff --git a/tests/all.py b/tests/all.py
index 07e3599..f5252f4 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -135,6 +135,8 @@ def add_fbo_formats_tests(adder, extension, suffix=''):
               'fbo-alphatest-formats{}'.format(suffix))
         adder(['fbo-colormask-formats', extension],
               'fbo-colormask-formats{}'.format(suffix))
+        adder(['fbo-fast-clear', extension],
+              'fbo-fast-clear{}'.format(suffix))
 
 
 def add_msaa_formats_tests(adder, extension):
@@ -2911,6 +2913,7 @@ with profile.group_manager(
     g(['fbo-drawbuffers-blend-add'])
     g(['fbo-drawbuffers-fragcolor'])
     g(['fbo-drawbuffers-maxtargets'])
+    g(['fbo-fast-clear'])
     g(['fbo-finish-deleted'])
     g(['fbo-flushing'])
     g(['fbo-flushing-2'])
@@ -3237,6 +3240,8 @@ with profile.group_manager(
     #   'fbo-blending-formats')
     g(['fbo-alphatest-formats', 'GL_EXT_texture_sRGB'],
       'fbo-alphatest-formats')
+    g(['fbo-fast-clear', 'GL_EXT_texture_sRGB'],
+      'fbo-fast-clear')
     add_msaa_formats_tests(g, 'GL_EXT_texture_sRGB')
     add_texwrap_format_tests(g, 'GL_EXT_texture_sRGB')
     add_texwrap_format_tests(g, 'GL_EXT_texture_sRGB-s3tc', '-s3tc')
diff --git a/tests/fbo/CMakeLists.gl.txt b/tests/fbo/CMakeLists.gl.txt
index 0476b10..bd0f7bc 100644
--- a/tests/fbo/CMakeLists.gl.txt
+++ b/tests/fbo/CMakeLists.gl.txt
@@ -43,6 +43,7 @@ piglit_add_executable (fbo-drawbuffers-maxtargets fbo-drawbuffers-maxtargets.c)
 piglit_add_executable (fbo-drawbuffers2-blend fbo-drawbuffers2-blend.c)
 piglit_add_executable (fbo-drawbuffers2-colormask fbo-drawbuffers2-colormask.c)
 piglit_add_executable (fbo-draw-buffers-blend fbo-draw-buffers-blend.c)
+piglit_add_executable (fbo-fast-clear fbo-fast-clear.c)
 piglit_add_executable (fbo-finish-deleted fbo-finish-deleted.c)
 piglit_add_executable (fbo-flushing fbo-flushing.c)
 piglit_add_executable (fbo-flushing-2 fbo-flushing-2.c)
diff --git a/tests/fbo/fbo-fast-clear.c b/tests/fbo/fbo-fast-clear.c
new file mode 100644
index 0000000..95c6ebe
--- /dev/null
+++ b/tests/fbo/fbo-fast-clear.c
@@ -0,0 +1,401 @@
+/*
+ * Copyright © 2015 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 fbo-fast-clear.c
+ *
+ * Clears a texture with various formats to various different colors
+ * and then samples from it in a shader to ensure that the expected
+ * color is returned. This includes verifying that when there are
+ * components missing they are overriden to the right value (such as
+ * GL_RED should report 0 for green and blue and 1 for the alpha). The
+ * main reason to do this is that the i965 driver has various
+ * different code paths to implement a fast clear optimisation and the
+ * path taken depends on the color chosen to a certain degree.
+ */
+
+#include "piglit-util-gl.h"
+#include "fbo-formats.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_compat_version = 21;
+	config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const char
+vertex_source[] =
+	"attribute vec4 piglit_vertex;\n"
+	"\n"
+	"void\n"
+	"main()\n"
+	"{\n"
+	"	 gl_Position = piglit_vertex;\n"
+	"}\n";
+
+static const char
+fragment_source_float[] =
+	"uniform sampler2D tex;\n"
+	"\n"
+	"void\n"
+	"main()\n"
+	"{\n"
+	"	 gl_FragColor = texture2D(tex, vec2(0.5));\n"
+	"}\n";
+
+static const char
+fragment_source_int[] =
+	"#version 130\n"
+	"\n"
+	"uniform isampler2D tex;\n"
+	"\n"
+	"void\n"
+	"main()\n"
+	"{\n"
+	"	 gl_FragColor = vec4(texelFetch(tex, ivec2(0), 0)) / 127.0;\n"
+	"}\n";
+
+static const char
+fragment_source_uint[] =
+	"#version 130\n"
+	"\n"
+	"uniform usampler2D tex;\n"
+	"\n"
+	"void\n"
+	"main()\n"
+	"{\n"
+	"	 gl_FragColor = vec4(texelFetch(tex, ivec2(0), 0)) / 255.0;\n"
+	"}\n";
+
+static const struct test_desc *
+test_set = &test_sets[0];
+
+static const float
+clear_colors[][4] = {
+	{ 0.0f, 0.0f, 0.0f, 0.0f },
+	{ 1.0f, 1.0f, 1.0f, 1.0f },
+	{ 0.0f, 0.0f, 1.0f, 0.0f },
+	{ 1.0f, 0.0f, 0.0f, 1.0f },
+
+	{ 0.25f, 0.5f, 0.75f, 1.0f },
+	{ 0.75f, 0.5f, 0.25f, 0.0f },
+	{ 0.5f, 0.25f, 0.75f, 0.5f },
+};
+
+static GLuint prog_float, prog_int, prog_uint;
+
+static enum piglit_result
+test_color(GLuint fbo,
+	   int offset,
+	   const struct format_desc *format,
+	   GLenum clear_type,
+	   const float *clear_color)
+{
+	float expected_color[4];
+	float alpha_override;
+	int i;
+
+	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+	switch (clear_type) {
+	case GL_INT: {
+		GLint clear_color_int[4] = {
+			clear_color[0] * 127,
+			clear_color[1] * 127,
+			clear_color[2] * 127,
+			clear_color[3] * 127
+		};
+		if (prog_int == 0)
+			return PIGLIT_SKIP;
+		glUseProgram(prog_int);
+		glClearBufferiv(GL_COLOR,
+				0, /* draw buffer */
+				clear_color_int);
+		alpha_override = 1.0f / 127.0f;
+		break;
+	}
+	case GL_UNSIGNED_INT: {
+		GLint clear_color_uint[4] = {
+			clear_color[0] * 255,
+			clear_color[1] * 255,
+			clear_color[2] * 255,
+			clear_color[3] * 255
+		};
+		if (prog_uint == 0)
+			return PIGLIT_SKIP;
+		glUseProgram(prog_uint);
+		glClearBufferiv(GL_COLOR,
+				0, /* draw buffer */
+				clear_color_uint);
+		alpha_override = 1.0f / 255.0f;
+		break;
+	}
+	default:
+		glUseProgram(prog_float);
+		glClearColor(clear_color[0],
+			     clear_color[1],
+			     clear_color[2],
+			     clear_color[3]);
+		glClear(GL_COLOR_BUFFER_BIT);
+		alpha_override = 1.0f;
+		break;
+	}
+
+	memcpy(expected_color, clear_color, sizeof expected_color);
+
+	switch (format->base_internal_format) {
+	case GL_ALPHA:
+		expected_color[0] = 0.0f;
+		expected_color[1] = 0.0f;
+		expected_color[2] = 0.0f;
+		break;
+	case GL_INTENSITY:
+		expected_color[0] = clear_color[0];
+		expected_color[1] = clear_color[0];
+		expected_color[2] = clear_color[0];
+		expected_color[3] = clear_color[0];
+		break;
+	case GL_LUMINANCE:
+		expected_color[1] = clear_color[0];
+		expected_color[2] = clear_color[0];
+		expected_color[3] = alpha_override;
+		break;
+	case GL_LUMINANCE_ALPHA:
+		expected_color[1] = clear_color[0];
+		expected_color[2] = clear_color[0];
+		break;
+	case GL_RED:
+		expected_color[1] = 0.0f;
+		expected_color[2] = 0.0f;
+		expected_color[3] = alpha_override;
+		break;
+	case GL_RG:
+		expected_color[2] = 0.0f;
+		expected_color[3] = alpha_override;
+		break;
+	case GL_RGB:
+		expected_color[3] = alpha_override;
+		break;
+	}
+
+	if (strstr(format->name, "SRGB") ||
+	    strstr(format->name, "SLUMINANCE")) {
+		for (i = 0; i < 3; i++) {
+			expected_color[i] =
+				piglit_srgb_to_linear(expected_color[i]);
+		}
+	}
+
+	glBindFramebuffer(GL_FRAMEBUFFER, piglit_winsys_fbo);
+	piglit_draw_rect(offset * 16 * 2.0f / piglit_width - 1.0f,
+			 -1.0f,
+			 16 * 2.0f / piglit_width,
+			 16 * 2.0f / piglit_height);
+	return piglit_probe_rect_rgba(offset * 16, 0, 16, 16,
+				      expected_color) ?
+		PIGLIT_PASS :
+		PIGLIT_FAIL;
+}
+
+static enum piglit_result
+test_format(const struct format_desc *format)
+{
+	enum piglit_result result = PIGLIT_PASS;
+	enum piglit_result color_result;
+	GLint l_size, i_size, r_size, g_size, b_size, a_size;
+	GLenum type_param;
+	GLint type;
+	GLuint tex;
+	GLuint fbo;
+	int i;
+
+	if (format->internalformat == 3 || format->internalformat == 4)
+		return PIGLIT_SKIP;
+
+	/* Compressed formats aren't supported for multisampling */
+	if (strstr("COMPRESSED", format->name))
+		return PIGLIT_SKIP;
+
+	printf("Testing %s\n", format->name);
+
+	glGenTextures(1, &tex);
+	glBindTexture(GL_TEXTURE_2D, tex);
+
+	glTexParameteri(GL_TEXTURE_2D,
+			GL_TEXTURE_MAG_FILTER,
+			GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D,
+			GL_TEXTURE_MIN_FILTER,
+			GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D,
+			GL_TEXTURE_MAX_LEVEL,
+			0);
+
+	glTexImage2D(GL_TEXTURE_2D,
+		     0, /* level */
+		     format->internalformat,
+		     128, 128, /* width/height */
+		     0, /* border */
+		     GL_RGBA,
+		     GL_UNSIGNED_BYTE,
+		     NULL /* data */);
+
+	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
+				 GL_TEXTURE_LUMINANCE_SIZE, &l_size);
+	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
+				 GL_TEXTURE_ALPHA_SIZE, &a_size);
+	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
+				 GL_TEXTURE_INTENSITY_SIZE, &i_size);
+	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
+				 GL_TEXTURE_RED_SIZE, &r_size);
+	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
+				 GL_TEXTURE_GREEN_SIZE, &g_size);
+	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
+				 GL_TEXTURE_BLUE_SIZE, &b_size);
+
+	if (l_size > 0)
+		type_param = GL_TEXTURE_LUMINANCE_TYPE;
+	else if (i_size > 0)
+		type_param = GL_TEXTURE_INTENSITY_TYPE;
+	else if (r_size > 0)
+		type_param = GL_TEXTURE_RED_TYPE;
+	else if (a_size > 0)
+		type_param = GL_TEXTURE_ALPHA_TYPE;
+	else {
+		assert(0);
+		type_param = GL_NONE;
+	}
+	glGetTexLevelParameteriv(GL_TEXTURE_2D,
+				 0, /* level */
+				 type_param,
+				 &type);
+
+	switch (format->base_internal_format) {
+	case GL_ALPHA:
+		r_size = g_size = b_size = 8;
+		break;
+	case GL_INTENSITY:
+		r_size = g_size = b_size = a_size = i_size;
+		break;
+	case GL_LUMINANCE:
+		r_size = g_size = b_size = l_size;
+		a_size = 8;
+		break;
+	case GL_LUMINANCE_ALPHA:
+		r_size = g_size = b_size = l_size;
+		break;
+	case GL_RED:
+		g_size = b_size = a_size = 8;
+		break;
+	case GL_RG:
+		b_size = a_size = 8;
+		break;
+	case GL_RGB:
+		a_size = 8;
+		break;
+	}
+
+	/* We can't measure more bits than what the winsys buffer has */
+	r_size = MIN2(r_size, 8);
+	g_size = MIN2(g_size, 8);
+	b_size = MIN2(b_size, 8);
+	a_size = MIN2(a_size, 8);
+
+	piglit_set_tolerance_for_bits(r_size, g_size, b_size, a_size);
+
+	glGenFramebuffers(1, &fbo);
+	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+	glFramebufferTexture2D(GL_FRAMEBUFFER,
+			       GL_COLOR_ATTACHMENT0,
+			       GL_TEXTURE_2D,
+			       tex,
+			       0);
+	if (glCheckFramebufferStatus(GL_FRAMEBUFFER) ==
+	    GL_FRAMEBUFFER_COMPLETE) {
+		for (i = 0; i < ARRAY_SIZE(clear_colors); i++) {
+			color_result = test_color(fbo, i, format, type,
+						  clear_colors[i]);
+			if (color_result == PIGLIT_SKIP) {
+				if (result == PIGLIT_PASS)
+					result = PIGLIT_SKIP;
+				break;
+			} else if (color_result == PIGLIT_FAIL) {
+				result = PIGLIT_FAIL;
+			}
+		}
+	} else {
+		printf("FBO not complete\n");
+		result = PIGLIT_SKIP;
+	}
+
+	glDeleteFramebuffers(1, &fbo);
+	glDeleteTextures(1, &tex);
+
+	return result;
+}
+
+enum piglit_result
+piglit_display()
+{
+	return fbo_formats_display(test_format);
+}
+
+static GLuint
+build_program(const char *fragment_source)
+{
+	GLint tex_location;
+	GLuint prog;
+
+	prog = piglit_build_simple_program(vertex_source, fragment_source);
+	glUseProgram(prog);
+	tex_location = glGetUniformLocation(prog, "tex");
+	glUniform1i(tex_location, 0);
+
+	return prog;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	int test_set_index = 0;
+	int glsl_major, glsl_minor;
+	bool es;
+
+	if (argc >= 2)
+		test_set_index = fbo_lookup_test_set(argv[1]);
+
+	test_set = test_set + test_set_index;
+
+	fbo_formats_init_test_set(test_set_index,
+				  GL_TRUE /* print_options */);
+
+	prog_float = build_program(fragment_source_float);
+
+	piglit_get_glsl_version(&es, &glsl_major, &glsl_minor);
+
+	if (!es && (glsl_major > 1 || (glsl_major == 1 && glsl_minor >= 3))) {
+		prog_int = build_program(fragment_source_int);
+		prog_uint = build_program(fragment_source_uint);
+	}
+}
-- 
1.9.3



More information about the Piglit mailing list