On 18 December 2012 11:54, Ian Romanick <i...@freedesktop.org> wrote:
> On 12/17/2012 10:17 AM, Paul Berry wrote: > > This test looks good. You should add the note about NVIDIA's driver to > the commit message when you push. > Ok, will do. Thanks. > > Reviewed-by: Ian Romanick <ian.d.roman...@intel.com> > > > --- >> tests/all.tests | 6 + >> .../spec/ext_transform_**feedback/CMakeLists.gl.txt | 1 + >> tests/spec/ext_transform_**feedback/change-size.c | 320 >> +++++++++++++++++++++ >> 3 files changed, 327 insertions(+) >> create mode 100644 tests/spec/ext_transform_**feedback/change-size.c >> >> diff --git a/tests/all.tests b/tests/all.tests >> index c823bcf..1cbbe98 100644 >> --- a/tests/all.tests >> +++ b/tests/all.tests >> @@ -1925,6 +1925,12 @@ for mode in ['discard', 'buffer', >> 'prims_generated', 'prims_written']: >> ext_transform_feedback[test_**name] = concurrent_test( >> 'ext_transform_feedback-{0}'.**format(test_name)) >> >> +for test_case in ['base-shrink', 'base-grow', 'offset-shrink', >> 'offset-grow', >> + 'range-shrink', 'range-grow']: >> + test_name = 'change-size {0}'.format(test_case) >> + ext_transform_feedback[test_**name] = concurrent_test( >> + 'ext_transform_feedback-{0}'.**format(test_name)) >> + >> arb_transform_feedback2 = Group() >> spec['ARB_transform_feedback2'**] = arb_transform_feedback2 >> arb_transform_feedback2['draw-**auto'] = PlainExecTest(['arb_transform_ >> **feedback2-draw-auto', '-auto']) >> diff --git a/tests/spec/ext_transform_**feedback/CMakeLists.gl.txt >> b/tests/spec/ext_transform_**feedback/CMakeLists.gl.txt >> index 9325091..63c3f4b 100644 >> --- a/tests/spec/ext_transform_**feedback/CMakeLists.gl.txt >> +++ b/tests/spec/ext_transform_**feedback/CMakeLists.gl.txt >> @@ -13,6 +13,7 @@ piglit_add_executable (ext_transform_feedback-**alignment >> alignment.c) >> piglit_add_executable (ext_transform_feedback-api-**errors >> api-errors.c) >> piglit_add_executable (ext_transform_feedback-**buffer-usage >> buffer-usage.c) >> piglit_add_executable (ext_transform_feedback-**builtin-varyings >> builtin-varyings.c) >> +piglit_add_executable (ext_transform_feedback-**change-size >> change-size.c) >> piglit_add_executable (ext_transform_feedback-**discard-api >> discard-api.c) >> piglit_add_executable (ext_transform_feedback-**discard-bitmap >> discard-bitmap.c) >> piglit_add_executable (ext_transform_feedback-**discard-clear >> discard-clear.c) >> diff --git a/tests/spec/ext_transform_**feedback/change-size.c >> b/tests/spec/ext_transform_**feedback/change-size.c >> new file mode 100644 >> index 0000000..ea6fe46 >> --- /dev/null >> +++ b/tests/spec/ext_transform_**feedback/change-size.c >> @@ -0,0 +1,320 @@ >> +/* >> + * Copyright © 2012 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 change-size.c >> + * >> + * Confirm that transform feedback properly handles a change in the >> + * size of a transform feedback buffer after it is bound but before it >> + * is used. >> + * >> + * In particular, this test verifies the following behaviours, from >> + * the GL 4.3 spec, section 6.1.1 ("Binding Buffer Objects to Indexed >> + * Targets"): >> + * >> + * BindBufferBase binds the entire buffer, even when the size of the >> buffer >> + * is changed after the binding is established. It is equivalent to >> calling >> + * BindBufferRange with offset zero, while size is determined by the >> size of >> + * the bound buffer at the time the binding is used. >> + * >> + * Regardless of the size specified with BindBufferRange, or >> indirectly with >> + * BindBufferBase, the GL will never read or write beyond the end of a >> bound >> + * buffer. In some cases this constraint may result in visibly >> different >> + * behavior when a buffer overflow would otherwise result, such as >> described >> + * for transform feedback operations in section 13.2.2. >> + * >> + * This test verifies that the expected number of primitives are >> + * written after a change to the size of the transform feedback >> + * buffer, using both a GL_TRANSFORM_FEEDBACK_**PRIMITIVES_WRITTEN query >> + * and by looking at the contents of the buffer itself. We run >> + * transform feedback in GL_TRIANGLES mode and use a buffer size that >> + * is not a multiple of 3, so that we can look at the last element in >> + * the transform feedback buffer and verify that transform feedback >> + * didn't overwrite it. >> + * >> + * The test performs the following operations: >> + * >> + * 1. Create a transform feedback buffer using glBufferData(). >> + * >> + * 2. Bind the buffer for transform feedback using either >> + * glBindBufferBase, glBindBufferRange, or glBindBufferOffsetEXT >> + * (if supported). >> + * >> + * 3. Change the size of the bound buffer using glBufferData(). A >> + * non-null data pointer is passed to glBufferData() to store a >> + * known pattern in the buffer, so that in step 6 we'll be able to >> + * determine which parts of the buffer were overwritten. >> + * >> + * 4. Draw some triangles, feeding back a single float from each >> + * vertex. >> + * >> + * 5. Verify, using a GL_TRANSFORM_FEEDBACK_**PRIMITIVES_WRITTEN query, >> + * that the expected number of primitives were written to the >> + * buffer. >> + * >> + * 6. Verify, using glMapBuffer, that the expected data was written to >> + * the buffer. >> + */ >> + >> +#include "piglit-util-gl-common.h" >> + >> +PIGLIT_GL_TEST_CONFIG_BEGIN >> + >> + config.supports_gl_compat_**version = 10; >> + >> + config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | >> PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_ALPHA; >> + >> +PIGLIT_GL_TEST_CONFIG_END >> + >> +/** >> + * Maximum buffer size--used for declaraing static arrays. Measured >> + * in multiples of sizeof(GLfloat). >> + */ >> +#define MAX_BUFFER_SIZE_FLOATS 10 >> + >> +static GLuint prog; >> +static GLuint xfb_buf; >> +static GLuint query; >> + >> +const struct test_case >> +{ >> + /** >> + * Name of the test case. NULL is used as a sentinel to mark >> + * the end of the list of test cases. >> + */ >> + const char *name; >> + >> + /** >> + * Size that the buffer should have before binding. Measured >> + * in multiples of sizeof(GLfloat). >> + */ >> + unsigned initial_size; >> + >> + /** >> + * Offset to pass to glBindBufferRange/**glBindBufferOffsetEXT, >> + * or zero if glBindBufferBase should be used. Measured in >> + * multiples of sizeof(GLfloat). >> + */ >> + unsigned bind_offset; >> + >> + /** >> + * Size to pass to glBindBufferRange, or zero if >> + * glBindBufferOffsetEXT/**glBindBufferBase should be used. >> + * Measured in multiples of sizeof(GLfloat). >> + */ >> + unsigned bind_size; >> + >> + /** >> + * Size of the buffer that should be passed to >> + * glBindBufferData after the buffer is bound. Measured in >> + * multiples of sizeof(GLfloat). >> + */ >> + unsigned new_size; >> + >> + /** >> + * Number of triangles to draw. >> + */ >> + unsigned num_draw_triangles; >> + >> + /** >> + * Number of primitives that are expected to be written to the >> + * buffer. >> + */ >> + unsigned num_feedback_triangles; >> +} test_cases[] = { >> + /* name initial bind bind new num tris: >> + * size offset size size draw feedback */ >> + { "base-shrink", 7, 0, 0, 4, 2, 1 }, >> + { "base-grow", 4, 0, 0, 7, 2, 2 }, >> + { "offset-shrink", 10, 3, 0, 7, 2, 1 }, >> + { "offset-grow", 7, 3, 0, 10, 2, 2 }, >> + { "range-shrink", 10, 3, 7, 7, 2, 1 }, >> + { "range-grow", 7, 3, 4, 10, 2, 1 }, >> + { NULL, 0, 0, 0, 0, 0, 0 } >> +}; >> + >> +const struct test_case *selected_test; >> + >> +/** >> + * Vertex shader, which simply copies its input attribute to its >> + * output varying, adding 100 in the process. >> + */ >> +static const char *vstext = >> + "#version 120\n" >> + "attribute float input_value;\n" >> + "varying float output_value;\n" >> + "\n" >> + "void main()\n" >> + "{\n" >> + " gl_Position = vec4(0.0);\n" >> + " output_value = 100.0 + input_value;\n" >> + "}\n"; >> + >> +static void >> +print_usage_and_exit(const char *prog_name) >> +{ >> + unsigned i; >> + printf("Usage: %s <test_case>\n" >> + " where <test_case> is one of the following:\n", >> prog_name); >> + for (i = 0; test_cases[i].name != NULL; i++) >> + printf(" %s\n", test_cases[i].name); >> + exit(1); >> +} >> + >> +static const struct test_case * >> +interpret_test_case_arg(const char *arg) >> +{ >> + unsigned i; >> + for (i = 0; test_cases[i].name != NULL; i++) { >> + if (strcmp(test_cases[i].name, arg) == 0) >> + return &test_cases[i]; >> + } >> + return NULL; >> +} >> + >> +void >> +piglit_init(int argc, char **argv) >> +{ >> + GLuint vs; >> + const char *varying_name = "output_value"; >> + >> + /* Parse args */ >> + if (argc != 2) >> + print_usage_and_exit(argv[0]); >> + selected_test = interpret_test_case_arg(argv[**1]); >> + if (selected_test == NULL) >> + print_usage_and_exit(argv[0]); >> + >> + /* Make sure required GL features are present */ >> + piglit_require_GLSL_version(**120); >> + piglit_require_transform_**feedback(); >> + if (selected_test->bind_offset != 0 && selected_test->bind_size >> == 0) { >> + /* Test requires glBindBufferOffsetEXT, which is in >> + * EXT_transform_feedback, but was never adopted into >> + * OpenGL. >> + */ >> + piglit_require_extension("GL_**EXT_transform_feedback"); >> + } >> + >> + /* Create program and buffer */ >> + vs = piglit_compile_shader_text(GL_**VERTEX_SHADER, vstext); >> + prog = glCreateProgram(); >> + glAttachShader(prog, vs); >> + glTransformFeedbackVaryings(**prog, 1, &varying_name, >> + GL_INTERLEAVED_ATTRIBS); >> + glLinkProgram(prog); >> + if (!piglit_link_check_status(**prog)) >> + piglit_report_result(PIGLIT_**FAIL); >> + glGenBuffers(1, &xfb_buf); >> + glGenQueries(1, &query); >> + if (!piglit_check_gl_error(GL_NO_**ERROR)) >> + piglit_report_result(PIGLIT_**FAIL); >> +} >> + >> +enum piglit_result >> +piglit_display(void) >> +{ >> + GLint input_index = glGetAttribLocation(prog, "input_value"); >> + GLfloat canary_data[MAX_BUFFER_SIZE_**FLOATS]; >> + GLfloat input_data[MAX_BUFFER_SIZE_**FLOATS]; >> + GLfloat expected_data[MAX_BUFFER_SIZE_**FLOATS]; >> + GLfloat *output_data; >> + GLuint query_result; >> + GLboolean pass = GL_TRUE; >> + unsigned i; >> + >> + glUseProgram(prog); >> + >> + /* Create a transform feedback buffer. */ >> + glBindBuffer(GL_TRANSFORM_**FEEDBACK_BUFFER, xfb_buf); >> + glBufferData(GL_TRANSFORM_**FEEDBACK_BUFFER, >> + selected_test->initial_size * sizeof(GLfloat), NULL, >> + GL_STREAM_READ); >> + >> + /* Bind the buffer for transform feedback. */ >> + if (selected_test->bind_size != 0) { >> + glBindBufferRange(GL_**TRANSFORM_FEEDBACK_BUFFER, 0, >> xfb_buf, >> + selected_test->bind_offset * >> sizeof(GLfloat), >> + selected_test->bind_size * >> sizeof(GLfloat)); >> + } else if (selected_test->bind_offset != 0) { >> + glBindBufferOffsetEXT(GL_**TRANSFORM_FEEDBACK_BUFFER, 0, >> + xfb_buf, >> + selected_test->bind_offset >> + * sizeof(GLfloat)); >> + } else { >> + glBindBufferBase(GL_TRANSFORM_**FEEDBACK_BUFFER, 0, >> xfb_buf); >> + } >> + >> + /* Change the size of the bound buffer. */ >> + for (i = 0; i < MAX_BUFFER_SIZE_FLOATS; i++) >> + canary_data[i] = -1; >> + glBufferData(GL_TRANSFORM_**FEEDBACK_BUFFER, >> + selected_test->new_size * sizeof(GLfloat), >> canary_data, >> + GL_STREAM_READ); >> + >> + /* Draw some triangles. */ >> + for (i = 0; i < MAX_BUFFER_SIZE_FLOATS; i++) >> + input_data[i] = i + 1; >> + glBindBuffer(GL_ARRAY_BUFFER, 0); >> + glVertexAttribPointer(input_**index, 1, GL_FLOAT, GL_FALSE, >> + sizeof(GLfloat), input_data); >> + glEnableVertexAttribArray(**input_index); >> + glBeginTransformFeedback(GL_**TRIANGLES); >> + glBeginQuery(GL_TRANSFORM_**FEEDBACK_PRIMITIVES_WRITTEN, query); >> + glDrawArrays(GL_TRIANGLES, 0, selected_test->num_draw_**triangles >> * 3); >> + glEndQuery(GL_TRANSFORM_**FEEDBACK_PRIMITIVES_WRITTEN); >> + glEndTransformFeedback(); >> + >> + /* Verify that the expected number of primitives were >> + * written. >> + */ >> + glGetQueryObjectuiv(query, GL_QUERY_RESULT, &query_result); >> + printf("PRIMITIVES_WRITTEN: expected=%u, actual=%u\n", >> + selected_test->num_feedback_**triangles, query_result); >> + if (query_result != selected_test->num_feedback_**triangles) >> + pass = GL_FALSE; >> + >> + /* Verify that the expected data was written. */ >> + for (i = 0; i < selected_test->new_size; i++) { >> + if (i >= selected_test->bind_offset && >> + i < (3 * selected_test->num_feedback_**triangles >> + + selected_test->bind_offset)) { >> + expected_data[i] = 100.0 >> + + input_data[i - >> selected_test->bind_offset]; >> + } else { >> + expected_data[i] = canary_data[i]; >> + } >> + } >> + output_data = glMapBuffer(GL_TRANSFORM_**FEEDBACK_BUFFER, >> GL_READ_ONLY); >> + for (i = 0; i < selected_test->new_size; ++i) { >> + printf("data[%u]: expected=%f, actual=%f\n", i, >> + expected_data[i], output_data[i]); >> + if (expected_data[i] != output_data[i]) >> + pass = GL_FALSE; >> + } >> + glUnmapBuffer(GL_TRANSFORM_**FEEDBACK_BUFFER); >> + >> + piglit_present_results(); >> + >> + return pass ? PIGLIT_PASS : PIGLIT_FAIL; >> +} >> >> >
_______________________________________________ Piglit mailing list Piglit@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/piglit