[Piglit] [PATCH] Test transform feedback of built-in varyings.

Paul Berry stereotype441 at gmail.com
Thu Dec 29 09:15:38 PST 2011


This test verifies that transform feedback can be applied to the
following built-in vertex shader outputs:

- gl_FrontColor
- gl_BackColor
- gl_FrontSecondaryColor
- gl_BackSecondaryColor
- gl_TexCoord
- gl_FogFragCoord
- gl_Position
- gl_PointSize
- gl_ClipVertex
- gl_ClipDistance

I've verified that all of these tests pass on the nVidia proprietary
Linux driver except for gl_ClipVertex (which is unsurprising, as
gl_ClipVertex has several known bugs on this driver).
---
 tests/all.tests                                    |    6 +
 .../spec/ext_transform_feedback/CMakeLists.gl.txt  |    1 +
 .../spec/ext_transform_feedback/builtin-varyings.c |  354 ++++++++++++++++++++
 3 files changed, 361 insertions(+), 0 deletions(-)
 create mode 100644 tests/spec/ext_transform_feedback/builtin-varyings.c

diff --git a/tests/all.tests b/tests/all.tests
index ba7899f..b45e94a 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -1392,6 +1392,12 @@ ext_timer_query['time-elapsed'] = concurrent_test('ext_timer_query-time-elapsed'
 
 ext_transform_feedback = Group()
 spec['EXT_transform_feedback'] = ext_transform_feedback
+for varying in ['gl_Color', 'gl_SecondaryColor', 'gl_TexCoord',
+                'gl_FogFragCoord', 'gl_Position', 'gl_PointSize',
+                'gl_ClipVertex', 'gl_ClipDistance']:
+        test_name = 'builtin-varyings {0}'.format(varying)
+        ext_transform_feedback[test_name] = PlainExecTest(
+                'ext_transform_feedback-{0} -auto'.format(test_name))
 ext_transform_feedback['discard-api'] = concurrent_test('ext_transform_feedback-discard-api')
 ext_transform_feedback['discard-bitmap'] = concurrent_test('ext_transform_feedback-discard-bitmap')
 ext_transform_feedback['discard-clear'] = concurrent_test('ext_transform_feedback-discard-clear')
diff --git a/tests/spec/ext_transform_feedback/CMakeLists.gl.txt b/tests/spec/ext_transform_feedback/CMakeLists.gl.txt
index 8334274..d518dec 100644
--- a/tests/spec/ext_transform_feedback/CMakeLists.gl.txt
+++ b/tests/spec/ext_transform_feedback/CMakeLists.gl.txt
@@ -13,6 +13,7 @@ link_libraries (
 )
 
 add_executable (ext_transform_feedback-alignment alignment.c)
+add_executable (ext_transform_feedback-builtin-varyings builtin-varyings.c)
 add_executable (ext_transform_feedback-discard-api discard-api.c)
 add_executable (ext_transform_feedback-discard-bitmap discard-bitmap.c)
 add_executable (ext_transform_feedback-discard-clear discard-clear.c)
diff --git a/tests/spec/ext_transform_feedback/builtin-varyings.c b/tests/spec/ext_transform_feedback/builtin-varyings.c
new file mode 100644
index 0000000..9ec1a34
--- /dev/null
+++ b/tests/spec/ext_transform_feedback/builtin-varyings.c
@@ -0,0 +1,354 @@
+/*
+ * 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 builtin-varyings.c
+ *
+ * Verify that transform feedback can be used with built-in varying
+ * variables, such as gl_FrontColor, gl_BackColor, etc.
+ *
+ * Note: gl_FrontColor and gl_BackColor are tested at the same time,
+ * in order to verify that the implementation is able to distinguish
+ * them.  Same for gl_FrontSecondaryColor and gl_BackSecondaryColor.
+ */
+
+#include "piglit-util.h"
+
+int piglit_width = 32;
+int piglit_height = 32;
+int piglit_window_mode = GLUT_DOUBLE | GLUT_RGB;
+
+#define MAX_EXPECTED_OUTPUT_COMPONENTS 8
+
+/**
+ * All possible tests to run.  Note that in each test, the input will
+ * consist of 6 vertices, with attribute vertex_num running from 0
+ * through 5, and attribute vertex_pos tracing out one front-facing
+ * triangle and one back-facing triangle.
+ *
+ * The expected output of each test is the sequence of floating point
+ * values (0.0, 1.0/256.0, 2.0/256.0, 3.0/256.0, ...).
+ */
+struct test_desc {
+	const char *name;
+	int version;
+	const char *vs;
+	unsigned num_varyings;
+	const char *varyings[16];
+	unsigned expected_num_output_components;
+} tests[] = {
+	{
+		"gl_Color", /* name */
+		110, /* version */
+
+		"#version 110\n" /* vs */
+		"attribute vec4 vertex_pos;\n"
+		"attribute float vertex_num;\n"
+		"void main() {\n"
+		"  gl_Position = vertex_pos;\n"
+		"  vec4 offset = vec4(0.0, 1.0, 2.0, 3.0);\n"
+		"  float scale = 1.0/256.0;\n"
+		"  gl_FrontColor = (offset + 8.0 * vertex_num) * scale;\n"
+		"  gl_BackColor = (offset + 4.0 + 8.0 * vertex_num) * scale;\n"
+		"}\n",
+
+		2, /* num_varyings */
+		{"gl_FrontColor", "gl_BackColor"}, /* varyings */
+
+		8 /* expected_num_output_components */
+	},
+	{
+		"gl_SecondaryColor", /* name */
+		110, /* version */
+
+		"#version 110\n" /* vs */
+		"attribute vec4 vertex_pos;\n"
+		"attribute float vertex_num;\n"
+		"void main() {\n"
+		"  gl_Position = vertex_pos;\n"
+		"  vec4 offset = vec4(0.0, 1.0, 2.0, 3.0);\n"
+		"  float scale = 1.0/256.0;\n"
+		"  gl_FrontSecondaryColor = (offset + 8.0 * vertex_num) * scale;\n"
+		"  gl_BackSecondaryColor = (offset + 4.0 + 8.0 * vertex_num) * scale;\n"
+		"}\n",
+
+		2, /* num_varyings */
+		{"gl_FrontSecondaryColor", "gl_BackSecondaryColor"}, /* varyings */
+
+		8 /* expected_num_output_components */
+	},
+	{
+		"gl_TexCoord", /* name */
+		110, /* version */
+
+		"#version 110\n" /* vs */
+		"attribute vec4 vertex_pos;\n"
+		"attribute float vertex_num;\n"
+		"void main() {\n"
+		"  gl_Position = vertex_pos;\n"
+		"  vec4 offset = vec4(0.0, 1.0, 2.0, 3.0);\n"
+		"  float scale = 1.0/256.0;\n"
+		"  gl_TexCoord[0] = (offset + 8.0 * vertex_num) * scale;\n"
+		"  gl_TexCoord[1] = (offset + 4.0 + 8.0 * vertex_num) * scale;\n"
+		"}\n",
+
+		2, /* num_varyings */
+		{"gl_TexCoord[0]", "gl_TexCoord[1]"}, /* varyings */
+
+		8 /* expected_num_output_components */
+	},
+	{
+		"gl_FogFragCoord", /* name */
+		110, /* version */
+
+		"#version 110\n" /* vs */
+		"attribute vec4 vertex_pos;\n"
+		"attribute float vertex_num;\n"
+		"void main() {\n"
+		"  gl_Position = vertex_pos;\n"
+		"  gl_FogFragCoord = vertex_num / 256.0;\n"
+		"}\n",
+
+		1, /* num_varyings */
+		{"gl_FogFragCoord"}, /* varyings */
+
+		1 /* expected_num_output_components */
+	},
+	{
+		"gl_Position", /* name */
+		110, /* version */
+
+		"#version 110\n" /* vs */
+		"attribute vec4 vertex_pos;\n"
+		"attribute float vertex_num;\n"
+		"void main() {\n"
+		"  vec4 offset = vec4(0.0, 1.0, 2.0, 3.0);\n"
+		"  float scale = 1.0/256.0;\n"
+		"  gl_Position = (offset + 4.0 * vertex_num) * scale;\n"
+		"}\n",
+
+		1, /* num_varyings */
+		{"gl_Position"}, /* varyings */
+
+		4 /* expected_num_output_components */
+	},
+	{
+		"gl_PointSize", /* name */
+		110, /* version */
+
+		"#version 110\n" /* vs */
+		"attribute vec4 vertex_pos;\n"
+		"attribute float vertex_num;\n"
+		"void main() {\n"
+		"  gl_Position = vertex_pos;\n"
+		"  gl_PointSize = vertex_num / 256.0;\n"
+		"}\n",
+
+		1, /* num_varyings */
+		{"gl_PointSize"}, /* varyings */
+
+		1 /* expected_num_output_components */
+	},
+	{
+		"gl_ClipVertex", /* name */
+		110, /* version */
+
+		"#version 110\n" /* vs */
+		"attribute vec4 vertex_pos;\n"
+		"attribute float vertex_num;\n"
+		"void main() {\n"
+		"  gl_Position = vertex_pos;\n"
+		"  vec4 offset = vec4(0.0, 1.0, 2.0, 3.0);\n"
+		"  float scale = 1.0/256.0;\n"
+		"  gl_ClipVertex = (offset + 4.0 * vertex_num) * scale;\n"
+		"}\n",
+
+		1, /* num_varyings */
+		{"gl_ClipVertex"}, /* varyings */
+
+		4 /* expected_num_output_components */
+	},
+	{
+		"gl_ClipDistance", /* name */
+		130, /* version */
+
+		"#version 130\n" /* vs */
+		"in vec4 vertex_pos;\n"
+		"in float vertex_num;\n"
+		"out float gl_ClipDistance[8];\n"
+		"void main() {\n"
+		"  gl_Position = vertex_pos;\n"
+		"  float scale = 1.0/256.0;\n"
+		"  for(int i = 0; i < 8; ++i)\n"
+		"    gl_ClipDistance[i] = (float(i) + 8.0 * vertex_num) * scale;\n"
+		"}\n",
+
+		8, /* num_varyings */
+		{"gl_ClipDistance[0]", "gl_ClipDistance[1]", /* varyings */
+		 "gl_ClipDistance[2]", "gl_ClipDistance[3]",
+		 "gl_ClipDistance[4]", "gl_ClipDistance[5]",
+		 "gl_ClipDistance[6]", "gl_ClipDistance[7]"},
+
+		8 /* expected_num_output_components */
+	},
+};
+
+const struct test_desc *test_to_run;
+
+static GLuint xfb_buf;
+static GLuint prog;
+static GLuint query;
+
+void
+print_usage_and_exit(const char *prog_name)
+{
+	int i;
+
+	printf("Usage: %s <test_name>\n"
+	       "  where <test_name> is one of:\n", prog_name);
+	for (i = 0; i < ARRAY_SIZE(tests); ++i)
+		printf("    %s\n", tests[i].name);
+	exit(0);
+}
+
+const struct test_desc *
+find_matching_test(const char *prog_name, const char *test_name)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(tests); ++i) {
+		if (strcmp(tests[i].name, test_name) == 0)
+			return &tests[i];
+	}
+	print_usage_and_exit(prog_name);
+	return NULL; /* won't actually be reached */
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	GLuint vs;
+
+	/* Parse params. */
+	if (argc != 2)
+		print_usage_and_exit(argv[0]);
+	test_to_run = find_matching_test(argv[0], argv[1]);
+
+	/* Set up test */
+	piglit_require_GLSL_version(test_to_run->version);
+	piglit_require_transform_feedback();
+	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, test_to_run->vs);
+	prog = piglit_CreateProgram();
+	piglit_AttachShader(prog, vs);
+	piglit_BindAttribLocation(prog, 0, "vertex_pos");
+	piglit_BindAttribLocation(prog, 1, "vertex_num");
+	piglit_TransformFeedbackVaryings(prog, test_to_run->num_varyings,
+					 (const char **) test_to_run->varyings,
+					 GL_INTERLEAVED_ATTRIBS_EXT);
+	piglit_LinkProgram(prog);
+	if (!piglit_link_check_status(prog)) {
+		piglit_DeleteProgram(prog);
+		piglit_report_result(PIGLIT_FAIL);
+	}
+	glGenBuffers(1, &xfb_buf);
+	glGenQueries(1, &query);
+	glEnable(GL_VERTEX_PROGRAM_TWO_SIDE);
+}
+
+struct vertex_data {
+	float vertex_pos[4];
+	float vertex_num;
+};
+
+enum piglit_result
+piglit_display(void)
+{
+	static const struct vertex_data vertex_input[6] = {
+		/*  vertex_pos XYZW         vertex_num */
+		{ { -1.0, -1.0, 0.0, 1.0 }, 0.0 },
+		{ { -1.0,  1.0, 0.0, 1.0 }, 1.0 },
+		{ {  1.0, -1.0, 0.0, 1.0 }, 2.0 },
+		{ { -1.0,  1.0, 0.0, 1.0 }, 3.0 },
+		{ {  1.0, -1.0, 0.0, 1.0 }, 4.0 },
+		{ {  1.0,  1.0, 0.0, 1.0 }, 5.0 }
+	};
+	static float initial_xfb_data[MAX_EXPECTED_OUTPUT_COMPONENTS * 6];
+	GLboolean pass = GL_TRUE;
+	int i;
+	float *readback;
+	GLuint query_result;
+
+	glUseProgram(prog);
+
+	/* Setup inputs */
+	glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE,
+			      sizeof(struct vertex_data),
+			      &vertex_input[0].vertex_pos);
+	glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE,
+			      sizeof(struct vertex_data),
+			      &vertex_input[0].vertex_num);
+	glEnableVertexAttribArray(0);
+	glEnableVertexAttribArray(1);
+
+	/* Setup transform feedback */
+	for (i = 0; i < ARRAY_SIZE(initial_xfb_data); ++i)
+		initial_xfb_data[i] = 12345.0;
+	glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf);
+	glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(initial_xfb_data),
+		     initial_xfb_data, GL_STREAM_READ);
+	piglit_BindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf);
+	piglit_BeginTransformFeedback(GL_TRIANGLES);
+	glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, query);
+
+	/* Draw */
+	glDrawArrays(GL_TRIANGLES, 0, 6);
+
+	/* Check that there was room in the buffer to write all
+	 * transform feedback outputs.
+	 */
+	glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
+	glGetQueryObjectuiv(query, GL_QUERY_RESULT, &query_result);
+	if (query_result != 2) {
+		printf("Expected 2 primitives written, got %u\n",
+		       query_result);
+		pass = GL_FALSE;
+	}
+
+	/* Check transform feedback output */
+	piglit_EndTransformFeedback();
+	readback = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
+	for (i = 0; i < ARRAY_SIZE(initial_xfb_data); ++i) {
+		float expected =
+			i < 6 * test_to_run->expected_num_output_components
+			? i/256.0 : 12345.0;
+		if (readback[i] != expected) {
+			printf("Buffer[%i]=%f, expected=%f\n", i, readback[i],
+			       expected);
+			pass = GL_FALSE;
+		}
+	}
+	glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
+
+	piglit_present_results();
+
+	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
-- 
1.7.6.4



More information about the Piglit mailing list