Commit bc73fbe6 authored by Paul Berry's avatar Paul Berry
Browse files

Add a test of alignment of transform feedback outputs.



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.
Reviewed-by: default avatarIan Romanick <ian.d.romanick@intel.com>
parent dc02bdd9
......@@ -1426,6 +1426,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]'])
......
......@@ -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)
......
/*
* 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;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment