From 9cc0d729c37e1700c4152dcdc711132407891b7f Mon Sep 17 00:00:00 2001 From: Fredrik Höglund Date: Sun, 22 Mar 2015 13:39:12 +0100 Subject: arb_direct_state_access: Add a test for glVertexArrayVertexBuffers This test verifies that glVertexArrayVertexBuffers works as expected. v2: Don't query GL_MAX_VERTEX_ATTRIB_STRIDE when GL < 4.4. Add a spec citation explaining per-binding. Update the page numbers to the current version of the GL 4.5 spec. Remove a redundant call to glGetIntegerv. Delete all the buffers at the end of the test. --- tests/all.py | 1 + .../spec/arb_direct_state_access/CMakeLists.gl.txt | 1 + .../arb_direct_state_access/vao-vertex-buffers.c | 368 +++++++++++++++++++++ 3 files changed, 370 insertions(+) create mode 100644 tests/spec/arb_direct_state_access/vao-vertex-buffers.c diff --git a/tests/all.py b/tests/all.py index b97261078..d0730d487 100755 --- a/tests/all.py +++ b/tests/all.py @@ -4287,6 +4287,7 @@ with profile.group_manager( g(['arb_direct_state_access-vao-binding-divisor'], 'vao-binding-divisor') g(['arb_direct_state_access-vao-element-array-buffer'], 'vao-element-array-buffer') g(['arb_direct_state_access-vao-vertex-buffer'], 'vao-vertex-buffer') + g(['arb_direct_state_access-vao-vertex-buffers'], 'vao-vertex-buffers') with profile.group_manager( PiglitGLTest, diff --git a/tests/spec/arb_direct_state_access/CMakeLists.gl.txt b/tests/spec/arb_direct_state_access/CMakeLists.gl.txt index 820971f4e..41e5c464e 100644 --- a/tests/spec/arb_direct_state_access/CMakeLists.gl.txt +++ b/tests/spec/arb_direct_state_access/CMakeLists.gl.txt @@ -43,4 +43,5 @@ piglit_add_executable (arb_direct_state_access-vao-attrib-binding vao-attrib-bin piglit_add_executable (arb_direct_state_access-vao-binding-divisor vao-binding-divisor.c dsa-utils.c) piglit_add_executable (arb_direct_state_access-vao-element-array-buffer vao-element-array-buffer.c) piglit_add_executable (arb_direct_state_access-vao-vertex-buffer vao-vertex-buffer.c dsa-utils.c) +piglit_add_executable (arb_direct_state_access-vao-vertex-buffers vao-vertex-buffers.c dsa-utils.c) # vim: ft=cmake: diff --git a/tests/spec/arb_direct_state_access/vao-vertex-buffers.c b/tests/spec/arb_direct_state_access/vao-vertex-buffers.c new file mode 100644 index 000000000..cca3db5c4 --- /dev/null +++ b/tests/spec/arb_direct_state_access/vao-vertex-buffers.c @@ -0,0 +1,368 @@ +/* + * Copyright (C) 2015 Fredrik Höglund + * + * 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 + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS AND/OR THEIR SUPPLIERS 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 vao-vertex-buffers.c + * + * Verifies that glVertexArrayVertexBuffers works as expected. + */ + +#include "piglit-util-gl.h" +#include "dsa-utils.h" + +#include + + +PIGLIT_GL_TEST_CONFIG_BEGIN + + config.supports_gl_core_version = 31; + config.supports_gl_compat_version = 20; + + config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE; + +PIGLIT_GL_TEST_CONFIG_END + + +enum piglit_result +piglit_display(void) +{ + /* unreached */ + return PIGLIT_FAIL; +} + + +/** + * Returns vertex buffer bindings first through first+count + * in the buffers, offsets and strides parameters. + */ +static void +get_vbo_bindings(GLuint vao, GLuint first, GLuint count, + GLuint *buffers, GLintptr *offsets, GLsizei *strides) +{ + GLuint i; + + for (i = 0; i < count; i++) { + GLuint buffer, offset, stride; + glGetVertexArrayIndexediv(vao, first + i, + GL_VERTEX_BINDING_BUFFER, + (GLint *) &buffer); + glGetVertexArrayIndexediv(vao, first + i, + GL_VERTEX_BINDING_OFFSET, + (GLint *) &offset); + glGetVertexArrayIndexediv(vao, first + i, + GL_VERTEX_BINDING_STRIDE, + (GLint *) &stride); + + buffers[i] = buffer; + offsets[i] = offset; + strides[i] = stride; + } +} + + +/** + * Returns true if vertex buffer bindings first through first+count match + * the values in buffers, offsets and strides, and false otherwise. + */ +static bool +check_vbo_bindings_(GLuint vao, GLuint first, GLsizei count, + const GLuint *buffers, const GLintptr *offsets, + const GLsizei *strides, int line) +{ + bool pass = true; + int i; + + for (i = 0; i < count; i++) + pass = check_vbo_binding_(vao, first + i, + buffers[i], offsets[i], strides[i], + __FILE__, line) && pass; + + return pass; +} + + +#define check_vbo_bindings(vao, first, count, buffers, offsets, strides) \ + check_vbo_bindings_(vao, first, count, buffers, offsets, strides, \ + __LINE__) + + +/** + * Returns true if vertex buffer bindings first through first+count are + * set to their default values, and false otherwise. + */ +static bool +check_vbo_bindings_default_(GLuint vao, GLuint first, GLsizei count, int line) +{ + bool pass = true; + int i; + + for (i = first; i < first + count; i++) + pass = check_vbo_binding_(vao, i, 0, 0, 16, + __FILE__, line) && pass; + + return pass; +} + + +#define check_vbo_bindings_default(vao, first, count) \ + check_vbo_bindings_default_(vao, first, count, __LINE__) + + +static GLuint validBuffers[10]; +static GLuint maxStride; + + +/** + * Generates count number of random buffer, offset and strides values, + * storing the results in buffers, offsets and strides respectively. + * + * All generated values are valid. + */ +static void +generate_random_values(int count, GLuint *buffers, + GLintptr *offsets, GLsizei *strides) +{ + int i; + + for (i = 0; i < count; i++) { + buffers[i] = validBuffers[rand() % ARRAY_SIZE(validBuffers)]; + offsets[i] = rand() % INT_MAX; + strides[i] = rand() % maxStride; + } +} + + +void +piglit_init(int argc, char *argv[]) +{ + GLuint vao, maxBindings, invalidBuffer; + + GLuint prevBuffers[4]; + GLintptr prevOffsets[4]; + GLsizei prevStrides[4]; + + GLuint buffers[4]; + GLintptr offsets[4]; + GLsizei strides[4]; + + bool pass = true; + + piglit_require_extension("GL_ARB_direct_state_access"); + piglit_require_extension("GL_ARB_vertex_array_object"); + piglit_require_extension("GL_ARB_vertex_attrib_binding"); + + glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, (GLint *) &maxBindings); + + if (piglit_get_gl_version() >= 44) { + glGetIntegerv(GL_MAX_VERTEX_ATTRIB_STRIDE, (GLint *) &maxStride); + } else { + /* See table 23.55 in the OpenGL 4.5 (Core Profile) spec */ + maxStride = 2048; + } + + /* Create a VAO */ + glCreateVertexArrays(1, &vao); + + /* Create a set of buffers */ + glCreateBuffers(ARRAY_SIZE(validBuffers), validBuffers); + + /* Generate one more buffer ID, but don't create the buffer */ + glGenBuffers(1, &invalidBuffer); + + /* Verify that no buffers are bound by default */ + pass = check_vbo_bindings_default(vao, 0, maxBindings) && pass; + + /* Try binding four buffers */ + generate_random_values(4, buffers, offsets, strides); + glVertexArrayVertexBuffers(vao, 0, 4, buffers, offsets, strides); + + /* Verify that the buffers were succesfully bound */ + pass = piglit_check_gl_error(GL_NO_ERROR); + pass = check_vbo_bindings(vao, 0, 4, buffers, offsets, strides) && pass; + + /* Page 338 (page 360 of the PDF) of the OpenGL 4.5 (Core Profile) + * specification says: + * + * "The values specified in buffers, offsets, and strides will be + * checked separately for each vertex buffer binding point. When a + * value for a specific vertex buffer binding point is invalid, the + * state for that binding point will be unchanged and an error will + * be generated. However, state for other vertex buffer binding points + * will still be changed if their corresponding values are valid." + * + * "An INVALID_OPERATION error is generated if any value in buffers + * is not zero or the name of an existing buffer object (per binding)." + */ + { + int first = rand() % (maxBindings - 4); + generate_random_values(4, buffers, offsets, strides); + buffers[1] = invalidBuffer; + + /* Get the current bindings */ + get_vbo_bindings(vao, first, 4, + prevBuffers, prevOffsets, prevStrides); + + /* Set the new ones */ + glVertexArrayVertexBuffers(vao, first, 4, + buffers, offsets, strides); + + /* Verify that a GL_INVALID_OPERATION error was generated */ + pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; + + /* The first binding should have been changed */ + pass = check_vbo_binding(vao, first, buffers[0], + offsets[0], strides[0]) && pass; + + /* The second binding should be unchanged */ + pass = check_vbo_binding(vao, first + 1, + prevBuffers[1], + prevOffsets[1], + prevStrides[1]) && pass; + + /* The next two bindings should have been changed */ + pass = check_vbo_bindings(vao, first + 2, 2, buffers + 2, + offsets + 2, strides + 2) && pass; + } + + /* Page 338 (page 360 of the PDF) of the OpenGL 4.5 (Core Profile) + * specification says: + * + * "An INVALID_VALUE error is generated if any value in offsets or + * strides is negative, or if any value in strides is greater than + * the value of MAX_VERTEX_ATTRIB_STRIDE (per binding)." + */ + { + int first = rand() % (maxBindings - 4); + generate_random_values(4, buffers, offsets, strides); + + offsets[0] = -1; + strides[1] = -1; + + /* Get the current bindings */ + get_vbo_bindings(vao, first + 0, 4, prevBuffers, + prevOffsets, prevStrides); + + /* Set the new ones */ + glVertexArrayVertexBuffers(vao, first, 4, buffers, + offsets, strides); + + /* Verify that a GL_INVALID_VALUE error was generated */ + pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; + + /* The first two bindings should be unchanged */ + pass = check_vbo_bindings(vao, first, 2, prevBuffers, + prevOffsets, prevStrides) && pass; + + /* The next two bindings should have been changed */ + pass = check_vbo_bindings(vao, first + 2, 2, buffers + 2, + offsets + 2, strides + 2) && pass; + } + + /* stride >= MAX_VERTEX_ATTRIB_STRIDE */ + if (piglit_get_gl_version() >= 44) { + int first = rand() % (maxBindings - 4); + generate_random_values(4, buffers, offsets, strides); + + /* Make strides[1] invalid */ + strides[1] = maxStride; + + /* Get the current bindings */ + get_vbo_bindings(vao, first, 4, prevBuffers, + prevOffsets, prevStrides); + + /* Set the new ones */ + glVertexArrayVertexBuffers(vao, first, 4, buffers, + offsets, strides); + + /* Verify that a GL_INVALID_VALUE error was generated */ + pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass; + + /* The first binding should have been changed */ + pass = check_vbo_binding(vao, first, buffers[0], + offsets[0], strides[0]) && pass; + + /* The second binding should be unchanged */ + pass = check_vbo_binding(vao, first + 1, + prevBuffers[1], + prevOffsets[1], + prevStrides[1]) && pass; + + /* The next two bindings should have been changed */ + pass = check_vbo_bindings(vao, first + 2, 2, + buffers + 2, + offsets + 2, + strides + 2) && pass; + } + + /* Page 338 (page 360 of the PDF) of the OpenGL 4.5 (Core Profile) + * specification says: + * + * "An INVALID_OPERATION error is generated if first + count is greater + * than the value of MAX_VERTEX_ATTRIB_BINDINGS." + */ + glVertexArrayVertexBuffers(vao, maxBindings - 1, 2, + buffers, offsets, strides); + pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; + + /* Page 337 (page 359 of the PDF) of the OpenGL 4.5 (Core Profile) + * specification says: + * + * "If buffers is NULL, each affected vertex buffer binding point + * from first through first + count − 1 will be reset to have no + * bound buffer object. In this case, the offsets and strides + * associated with the binding points are set to default values, + * ignoring offsets and strides." + */ + + /* Bind a set of buffers first */ + generate_random_values(4, buffers, offsets, strides); + glVertexArrayVertexBuffers(vao, 0, 4, buffers, offsets, strides); + + /* Now unbind them */ + glVertexArrayVertexBuffers(vao, 0, 4, NULL, offsets, strides); + pass = piglit_check_gl_error(GL_NO_ERROR) && pass; + + /* Verify that the buffers were unbound and that + * the offsets and strides were not used. + */ + pass = check_vbo_bindings_default(vao, 0, 4) && pass; + + glDeleteVertexArrays(1, &vao); + + /* Page 337 (page 359 of the PDF) of the OpenGL 4.5 (Core Profile) + * specification says: + * + * "An INVALID_OPERATION error is generated by VertexArrayVertexBuffer + * if vaobj is not the name of an existing vertex array object." + */ + glGenVertexArrays(1, &vao); + glVertexArrayVertexBuffers(vao, 0, 1, NULL, NULL, NULL); + pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass; + glDeleteVertexArrays(1, &vao); + + glDeleteBuffers(ARRAY_SIZE(validBuffers), validBuffers); + glDeleteBuffers(1, &invalidBuffer); + + piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); +} + -- cgit v1.2.3