[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