v2: review from Tapani - add the copyright for Intel - add some documentation - set the minimum GL version to 2.0 - use piglit_build_simple_program_unlinked
Reviewed-by: Tapani Pälli <[email protected]> Acked-by: Laura Ekstrand <[email protected]> v3: - rewrite the test for GL 3.1 core (Ilia) - do not hardcode the tolerance (Laura) - delete the copyright from vmware as none of the code is left - improve the cleanup at the end of the test Signed-off-by: Martin Peres <[email protected]> --- tests/all.py | 1 + .../spec/arb_direct_state_access/CMakeLists.gl.txt | 1 + .../transformfeedback-bufferrange.c | 248 +++++++++++++++++++++ 3 files changed, 250 insertions(+) create mode 100644 tests/spec/arb_direct_state_access/transformfeedback-bufferrange.c diff --git a/tests/all.py b/tests/all.py index 3f6be98..31c65e4 100644 --- a/tests/all.py +++ b/tests/all.py @@ -3998,6 +3998,7 @@ arb_shader_atomic_counters['respecify-buffer'] = PiglitGLTest(['arb_shader_atomi spec['ARB_direct_state_access']['create-transformfeedbacks'] = PiglitGLTest(['arb_direct_state_access-create-transformfeedbacks'], run_concurrent=True) spec['ARB_direct_state_access']['transformfeedback-bufferbase'] = PiglitGLTest(['arb_direct_state_access-transformfeedback-bufferbase'], run_concurrent=True) +spec['ARB_direct_state_access']['transformfeedback-bufferrange'] = PiglitGLTest(['arb_direct_state_access-transformfeedback-bufferrange'], run_concurrent=True) spec['ARB_direct_state_access']['dsa-textures'] = PiglitGLTest(['arb_direct_state_access-dsa-textures'], run_concurrent=True) spec['ARB_direct_state_access']['texturesubimage'] = PiglitGLTest(['arb_direct_state_access-texturesubimage'], run_concurrent=True) spec['ARB_direct_state_access']['bind-texture-unit'] = PiglitGLTest(['arb_direct_state_access-bind-texture-unit'], run_concurrent=True) diff --git a/tests/spec/arb_direct_state_access/CMakeLists.gl.txt b/tests/spec/arb_direct_state_access/CMakeLists.gl.txt index e01894f..8ae8275 100644 --- a/tests/spec/arb_direct_state_access/CMakeLists.gl.txt +++ b/tests/spec/arb_direct_state_access/CMakeLists.gl.txt @@ -11,6 +11,7 @@ link_libraries ( piglit_add_executable (arb_direct_state_access-create-transformfeedbacks create-transformfeedbacks.c) piglit_add_executable (arb_direct_state_access-transformfeedback-bufferbase transformfeedback-bufferbase.c) +piglit_add_executable (arb_direct_state_access-transformfeedback-bufferrange transformfeedback-bufferrange.c) piglit_add_executable (arb_direct_state_access-dsa-textures dsa-textures.c dsa-utils.c) piglit_add_executable (arb_direct_state_access-texturesubimage texturesubimage.c) piglit_add_executable (arb_direct_state_access-bind-texture-unit bind-texture-unit.c) diff --git a/tests/spec/arb_direct_state_access/transformfeedback-bufferrange.c b/tests/spec/arb_direct_state_access/transformfeedback-bufferrange.c new file mode 100644 index 0000000..2e5fc6a --- /dev/null +++ b/tests/spec/arb_direct_state_access/transformfeedback-bufferrange.c @@ -0,0 +1,248 @@ +/* + * Copyright © 2015 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 transformfeedback-bufferrange.c + * Simple transform feedback test drawing GL_POINTS and making use of the + * transform-feedback-related direct state access entry points. + * + * Greatly inspired from ext_transform_feedback/points.c. + * + * From OpenGL 4.5, section 13.2.2 "Transform Feedback Primitive Capture", + * page 422: + * + * "void TransformFeedbackBufferRange(uint xfb, uint index, uint buffer, + * intptr offset, sizeiptr size); + * + * xfb must be zero, indicating the default transform feedback object, or the + * name of an existing transform feedback object. buffer must be zero or the + * name of an existing buffer object. + * + * TransformFeedbackBufferRange and TransformFeedbackBufferBase behave + * similarly to BindBufferRange and BindBufferBase, respectively, except + * that the target of the operation is xfb, and they do not affect any binding + * to the generic TRANSFORM_FEEDBACK_BUFFER target. + * + * Errors + * An INVALID_OPERATION error is generated if xfb is not zero or the name + * of an existing transform feedback object. + * An INVALID_VALUE error is generated if buffer is not zero or the name of + * an existing buffer object. + * An INVALID_VALUE error is generated if index is greater than or equal + * to the number of binding points for transform feedback, as described in + * section 6.7.1. + * An INVALID_VALUE error is generated by TransformFeedbackBufferRange + * if offset is negative. + * An INVALID_VALUE error is generated by TransformFeedbackBufferRange + * if size is less than or equal to zero. + * An INVALID_VALUE error is generated by TransformFeedbackBufferRange + * if offset or size do not satisfy the constraints described for those + * parameters for transform feedback array bindings, as described in + * section 6.7.1." + */ + +#include "piglit-util-gl.h" +#include "dsa-utils.h" + +PIGLIT_GL_TEST_CONFIG_BEGIN + config.supports_gl_core_version = 31; + config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA; +PIGLIT_GL_TEST_CONFIG_END + + +static GLuint prog; +static GLuint xfb_buf[3], input_buf, vao; +static const int xfb_buf_size = 500; +static const int offset = 16; + +static const char *vstext = { + "#version 140\n" + "in float valIn;" + "out float valOut1;" + "out float valOut2;" + "void main() {" + " valOut1 = valIn + 1;" + " valOut2 = valIn * 2;" + "}" +}; + +#define NUM_INPUTS 4 +static const GLfloat inputs[NUM_INPUTS] = {-1.0, 0.0, 1.0, 3.0}; +static const GLfloat out1_ret[NUM_INPUTS] = { 0.0, 1.0, 2.0, 4.0}; +static const GLfloat out2_ret[NUM_INPUTS] = {-2.0, 0.0, 2.0, 6.0}; + +void +piglit_init(int argc, char **argv) +{ + static const char *varyings[] = { "valOut1", "valOut2" }; + GLint inAttrib; + + /* Check the driver. */ + piglit_require_extension("GL_ARB_transform_feedback3"); + piglit_require_extension("GL_ARB_direct_state_access"); + + /* Create shaders. */ + prog = piglit_build_simple_program_unlinked(vstext, NULL); + glTransformFeedbackVaryings(prog, 2, varyings, + GL_SEPARATE_ATTRIBS); + glLinkProgram(prog); + if (!piglit_link_check_status(prog)) { + glDeleteProgram(prog); + piglit_report_result(PIGLIT_FAIL); + } + glUseProgram(prog); + + /* Set up the Vertex Array Buffer */ + glEnable(GL_VERTEX_ARRAY); + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + + /* Set up the input data buffer */ + glGenBuffers(1, &input_buf); + glBindBuffer(GL_ARRAY_BUFFER, input_buf); + glBufferData(GL_ARRAY_BUFFER, sizeof(inputs), inputs, GL_STATIC_DRAW); + inAttrib = glGetAttribLocation(prog, "valIn"); + piglit_check_gl_error(GL_NO_ERROR); + glVertexAttribPointer(inAttrib, 1, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(inAttrib); +} + +static bool +equal(float a, float b) +{ + float tolerance[4]; + piglit_compute_probe_tolerance(GL_RGBA, tolerance); + return fabsf(a - b) < tolerance[0]; +} + +enum piglit_result +piglit_display(void) +{ + GLint max_bind_points = 0; + GLuint q, num_prims; + bool pass = true, test = true; + GLfloat *v, *w; + int i; + + /* init the transform feedback buffers */ + glGenBuffers(3, xfb_buf); + glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf[2]); + piglit_check_gl_error(GL_NO_ERROR); + + /* Fetch the number of bind points */ + glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_bind_points); + SUBTEST(GL_NO_ERROR, pass, "fetch maximum number of bind points"); + + /* bind a non-existing transform feedback BO */ + glTransformFeedbackBufferRange(1337, 0, 0, 0, 4096); + SUBTEST(GL_INVALID_OPERATION, pass, "bind non-existing transform " + "feedback BO"); + + /* bind a non-existing output BO */ + glTransformFeedbackBufferRange(0, 0, 1337, 0, 4096); + SUBTEST(GL_INVALID_VALUE, pass, "bind a non-existing output BO"); + + /* bind to a negative index */ + glTransformFeedbackBufferRange(0, -1, xfb_buf[2], 0, 4096); + SUBTEST(GL_INVALID_VALUE, pass, "bind negative index"); + + /* bind to an index == max */ + glTransformFeedbackBufferRange(0, max_bind_points, xfb_buf[2], 0, + 4096); + SUBTEST(GL_INVALID_VALUE, pass, "bind to index == max_bind_points " + "(%i)", max_bind_points); + + /* bind at a non-aligned offset */ + glTransformFeedbackBufferRange(0, 0, xfb_buf[2], 3, 4096); + SUBTEST(GL_INVALID_VALUE, pass, "bind at a non-aligned offset"); + + /* bind with a non-aligned size */ + glTransformFeedbackBufferRange(0, 0, xfb_buf[2], 0, 4095); + SUBTEST(GL_INVALID_VALUE, pass, "bind with a non-aligned size"); + + /* Set up the transform feedback buffer */ + for (i = 0; i < 2; i++) { + glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf[i]); + glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, + xfb_buf_size, NULL, GL_STREAM_READ); + glTransformFeedbackBufferRange(0, i, xfb_buf[i], offset, + xfb_buf_size); + piglit_check_gl_error(GL_NO_ERROR); + } + + /* Set up the query that checks the # of primitives handled */ + glGenQueries(1, &q); + glBeginQuery(GL_PRIMITIVES_GENERATED, q); + piglit_check_gl_error(GL_NO_ERROR); + + /* do the transform feedback */ + glBeginTransformFeedback(GL_POINTS); + glBindBuffer(GL_ARRAY_BUFFER, input_buf); + glDrawArrays(GL_POINTS, 0, NUM_INPUTS); + glEndTransformFeedback(); + + glEndQuery(GL_PRIMITIVES_GENERATED); + + /* check the number of primitives */ + glGetQueryObjectuiv(q, GL_QUERY_RESULT, &num_prims); + glDeleteQueries(1, &q); + printf("%u primitives generated:\n", num_prims); + if (num_prims != NUM_INPUTS) { + printf("Incorrect number of prims generated.\n"); + printf("Found %u, expected %u\n", num_prims, NUM_INPUTS); + pass = false; + test = false; + } + + /* check the result */ + glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf[0]); + v = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY) + offset; + piglit_check_gl_error(GL_NO_ERROR); + glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf[1]); + w = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY) + offset; + piglit_check_gl_error(GL_NO_ERROR); + + for (i = 0; i < num_prims; i++) { + printf("%2d: (%2.0g, %2.0g) : ", i, v[i], w[i]); + if (!equal(v[i], out1_ret[i]) || !equal(w[i], out2_ret[i])) { + printf("NOK, expected (%2.0g, %2.0g)\n", + out1_ret[i], out2_ret[i]); + test = false; + } else + printf("OK\n"); + } + SUBTESTCONDITION(test, pass, "general test"); + + piglit_present_results(); + + /* clean-up everything */ + glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf[0]); + glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); + glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf[1]); + glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER); + glDeleteBuffers(3, xfb_buf); + glDeleteBuffers(1, &input_buf); + glDeleteVertexArrays(1, &vao); + glDeleteProgram(prog); + + return pass ? PIGLIT_PASS : PIGLIT_FAIL; +} -- 2.3.1 _______________________________________________ Piglit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/piglit
