[Piglit] [PATCH] Add a test of alignment of transform feedback outputs.
Paul Berry
stereotype441 at gmail.com
Fri Dec 16 15:35:29 PST 2011
Certain graphics hardware (notably Intel i965) has restrictions on
unaligned memory accesses. However, transform feedback can be
configured in such a way that data is not aligned on a natural
boundary (e.g. a vec4 is 16 bytes wide, but is only required to be
aligned to a multiple of 4 bytes). This test verifies that transform
feedback data is written to memory correctly regardless of how the
data is aligned.
---
tests/all.tests | 4 +
.../spec/ext_transform_feedback/CMakeLists.gl.txt | 1 +
tests/spec/ext_transform_feedback/alignment.c | 193 ++++++++++++++++++++
3 files changed, 198 insertions(+), 0 deletions(-)
create mode 100644 tests/spec/ext_transform_feedback/alignment.c
diff --git a/tests/all.tests b/tests/all.tests
index 4b1ba49..bc581f4 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -1425,6 +1425,10 @@ for draw_mode in ['points', 'lines', 'line_loop', 'line_strip',
draw_mode, shade_mode)
ext_transform_feedback[test_name] = PlainExecTest(
'ext_transform_feedback-{0} -auto'.format(test_name))
+for alignment in [0, 4, 8, 12]:
+ test_name = 'alignment {0}'.format(alignment)
+ ext_transform_feedback[test_name] = PlainExecTest(
+ 'ext_transform_feedback-{0} -auto'.format(test_name))
ext_transform_feedback['output-type float'] = PlainExecTest(['ext_transform_feedback-output-type', '-auto', 'float'])
ext_transform_feedback['output-type float[2]'] = PlainExecTest(['ext_transform_feedback-output-type', '-auto', 'float[2]'])
diff --git a/tests/spec/ext_transform_feedback/CMakeLists.gl.txt b/tests/spec/ext_transform_feedback/CMakeLists.gl.txt
index 06dd099..2e337ec 100644
--- a/tests/spec/ext_transform_feedback/CMakeLists.gl.txt
+++ b/tests/spec/ext_transform_feedback/CMakeLists.gl.txt
@@ -12,6 +12,7 @@ link_libraries (
${GLUT_glut_LIBRARY}
)
+add_executable (ext_transform_feedback-alignment alignment.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/alignment.c b/tests/spec/ext_transform_feedback/alignment.c
new file mode 100644
index 0000000..66b1d56
--- /dev/null
+++ b/tests/spec/ext_transform_feedback/alignment.c
@@ -0,0 +1,193 @@
+/*
+ * 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 alignment.c
+ *
+ * Verify that transform feedback outputs are generated correctly
+ * regardless of how the buffers (and the data) are aligned in memory.
+ *
+ * The test requires a single integer argument, which specifies the
+ * number of bytes of offset that should be specified when calling
+ * glBindBufferRange(). This value may be 0, 4, 8, or 12.
+ */
+
+#include "piglit-util.h"
+
+#define BUFFER_SIZE 0x40
+
+int piglit_width = 10;
+int piglit_height = 10;
+int piglit_window_mode = GLUT_DOUBLE | GLUT_RGB | GLUT_ALPHA;
+
+/* Test parameters */
+static unsigned long additional_offset;
+
+/* Other globals */
+static GLuint prog;
+static GLuint xfb_buf;
+
+/**
+ * Input data for the vertex shader.
+ */
+static GLuint verts[4] = { 0, 1, 2, 3 };
+
+/**
+ * Vertex shader. This is designed so that its transform feedback
+ * outputs appear at all possible alignments, and so that the correct
+ * output will consist of the following pattern of uints:
+ *
+ * 0x00010203
+ * 0x04050607
+ * 0x08090a0b
+ * ...
+ * 0xacadaeaf
+ *
+ * (a total of 44 uints)
+ */
+static const char *vstext =
+ "#version 130\n"
+ "in uint input_uint;\n"
+ "flat out uint out_a;\n"
+ "flat out uvec2 out_b;\n"
+ "flat out uvec3 out_c;\n"
+ "flat out uvec4 out_d;\n"
+ "flat out uint out_e;\n"
+ "\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(0.0);\n"
+ " uint offset = input_uint * 0x2c2c2c2cu;\n"
+ " out_a = 0x00010203u + offset;\n"
+ " out_b = uvec2(0x04050607, 0x08090a0b) + offset;\n"
+ " out_c = uvec3(0x0c0d0e0f, 0x10111213, 0x14151617) + offset;\n"
+ " out_d = uvec4(0x18191a1b, 0x1c1d1e1f, 0x20212223, 0x24252627) + offset;\n"
+ " out_e = 0x28292a2bu + offset;\n"
+ "}\n";
+
+#define EXPECTED_NUM_OUTPUTS 44
+
+static const char *varyings[] = {
+ "out_a", "out_b", "out_c", "out_d", "out_e"
+};
+
+static const char *fstext =
+ "#version 130\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = vec4(0.0);\n"
+ "}\n";
+
+static void
+print_usage_and_exit(char *prog_name)
+{
+ printf("Usage: %s <additional_offset>\n"
+ " where <additional_offset> is one of the values\n"
+ " 0, 4, 8, or 12.\n", prog_name);
+ exit(1);
+}
+
+void piglit_init(int argc, char **argv)
+{
+ char *endptr;
+ GLuint vs, fs;
+
+ /* Interpret command line args */
+ if (argc != 2)
+ print_usage_and_exit(argv[0]);
+ endptr = argv[1];
+ additional_offset = strtoul(argv[1], &endptr, 0);
+ if (*endptr != '\0')
+ print_usage_and_exit(argv[0]);
+ if (additional_offset > 12 || additional_offset % 4 != 0)
+ print_usage_and_exit(argv[0]);
+
+ piglit_require_GLSL_version(130);
+ piglit_require_gl_version(30);
+ piglit_require_transform_feedback();
+ vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext);
+ fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fstext);
+ prog = piglit_CreateProgram();
+ piglit_AttachShader(prog, vs);
+ piglit_AttachShader(prog, fs);
+ piglit_TransformFeedbackVaryings(prog, 5, varyings,
+ GL_INTERLEAVED_ATTRIBS);
+ piglit_LinkProgram(prog);
+ if (!piglit_link_check_status(prog))
+ piglit_report_result(PIGLIT_FAIL);
+ glGenBuffers(1, &xfb_buf);
+ piglit_check_gl_error(0, PIGLIT_FAIL);
+}
+
+enum piglit_result piglit_display(void)
+{
+ GLint input_index = glGetAttribLocation(prog, "input_uint");
+ GLuint *readback;
+ GLuint buffer[BUFFER_SIZE];
+ GLuint expected[BUFFER_SIZE];
+ int i;
+ GLboolean pass = GL_TRUE;
+
+ piglit_UseProgram(prog);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glVertexAttribIPointer(input_index, 1, GL_UNSIGNED_INT,
+ sizeof(GLuint), &verts);
+ glEnableVertexAttribArray(input_index);
+ piglit_check_gl_error(0, PIGLIT_FAIL);
+
+ glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf);
+ memset(buffer, 0xffffffff, sizeof(buffer));
+ glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(buffer), buffer,
+ GL_STREAM_READ);
+ piglit_BindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf,
+ additional_offset,
+ sizeof(buffer) - additional_offset);
+ piglit_BeginTransformFeedback(GL_POINTS);
+ glDrawArrays(GL_POINTS, 0, 4);
+ piglit_EndTransformFeedback();
+ piglit_check_gl_error(0, PIGLIT_FAIL);
+
+ readback = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
+ piglit_check_gl_error(0, PIGLIT_FAIL);
+
+ /* Figure out expected output */
+ memset(expected, 0xffffffff, sizeof(expected));
+ for (i = 0; i < EXPECTED_NUM_OUTPUTS; ++i) {
+ expected[i + additional_offset / 4] =
+ 0x00010203 + 0x04040404 * i;
+ }
+
+ /* Check output */
+ for (i = 0; i < BUFFER_SIZE; ++i) {
+ if (expected[i] != readback[i]) {
+ printf("readback[%u]: %u, expected: %u\n", i,
+ readback[i], expected[i]);
+ pass = GL_FALSE;
+ }
+ }
+
+ piglit_present_results();
+
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
--
1.7.6.4
More information about the Piglit
mailing list