[Piglit] [PATCH] Add a test of alignment of transform feedback outputs.

Ian Romanick idr at freedesktop.org
Fri Dec 16 17:06:31 PST 2011


On 12/16/2011 03:35 PM, Paul Berry wrote:
> 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.

This tests passes on AMD's closed source driver.

Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

> ---
>   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;
> +}


More information about the Piglit mailing list