Commit 8646f41f authored by Paul Berry's avatar Paul Berry
Browse files

Test transform feedback of built-in varyings.

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).
parent 5a4ae0e4
......@@ -1394,6 +1394,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')
......
......@@ -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)
......
/*
* 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;
}
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