summaryrefslogtreecommitdiff
path: root/tests/spec/arb_direct_state_access/vao-attrib-format.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/spec/arb_direct_state_access/vao-attrib-format.c')
-rw-r--r--tests/spec/arb_direct_state_access/vao-attrib-format.c805
1 files changed, 805 insertions, 0 deletions
diff --git a/tests/spec/arb_direct_state_access/vao-attrib-format.c b/tests/spec/arb_direct_state_access/vao-attrib-format.c
new file mode 100644
index 000000000..5eb0240ff
--- /dev/null
+++ b/tests/spec/arb_direct_state_access/vao-attrib-format.c
@@ -0,0 +1,805 @@
+/*
+ * 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-attrib-format.c
+ *
+ * Verifies that glVertexArrayAttribFormat, glVertexArrayAttribIFormat and
+ * glVertexArrayAttribLFormat work as expected.
+ */
+
+#include "piglit-util-gl.h"
+#include "dsa-utils.h"
+
+
+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
+
+
+static bool ARB_ES2_compatibility;
+static bool ARB_half_float_vertex;
+static bool ARB_vertex_type_2_10_10_10_rev;
+static bool ARB_vertex_type_10f_11f_11f_rev;
+static bool ARB_vertex_attrib_64bit;
+static bool ARB_vertex_array_bgra;
+
+
+enum piglit_result
+piglit_display(void)
+{
+ /* unreached */
+ return PIGLIT_FAIL;
+}
+
+
+/**
+ * Returns true if the format of attribindex matches the expected
+ * format, and false otherwise.
+ */
+bool
+check_attrib_format_(GLuint vao, GLuint attribindex, GLuint size, GLenum type,
+ GLboolean normalized, GLboolean integer, GLboolean _long,
+ GLuint relativeOffset, int line)
+{
+ bool ret = true;
+
+ ret = check_indexed_vao_param_(vao, attribindex,
+ GL_VERTEX_ATTRIB_ARRAY_SIZE,
+ size, __FILE__, line) && ret;
+ ret = check_indexed_vao_param_(vao, attribindex,
+ GL_VERTEX_ATTRIB_ARRAY_TYPE,
+ type, __FILE__, line) && ret;
+ ret = check_indexed_vao_param_(vao, attribindex,
+ GL_VERTEX_ATTRIB_ARRAY_NORMALIZED,
+ normalized, __FILE__, line) && ret;
+
+ if (piglit_get_gl_version() >= 30) {
+ ret = check_indexed_vao_param_(vao, attribindex,
+ GL_VERTEX_ATTRIB_ARRAY_INTEGER,
+ integer, __FILE__, line) && ret;
+ } else if (integer) {
+ fprintf(stderr, "GL_VERTEX_ATTRIB_ARRAY_INTEGER[%u] expected "
+ "to be GL_TRUE, but OpenGL 3.0 "
+ "is not supported (%s:%d).",
+ attribindex, __FILE__, line);
+ ret = false;
+ }
+
+ if (ARB_vertex_attrib_64bit) {
+ ret = check_indexed_vao_param_(vao, attribindex,
+ GL_VERTEX_ATTRIB_ARRAY_LONG,
+ _long, __FILE__, line) && ret;
+ } else if (_long) {
+ fprintf(stderr, "GL_VERTEX_ATTRIB_ARRAY_LONG[%u] expected "
+ "to be GL_TRUE, but GL_ARB_vertex_attrib_64bit "
+ "is not supported (%s:%d).",
+ attribindex, __FILE__, line);
+ ret = false;
+ }
+
+ ret = check_indexed_vao_param_(vao, attribindex,
+ GL_VERTEX_ATTRIB_RELATIVE_OFFSET,
+ relativeOffset, __FILE__, line) && ret;
+
+ return ret;
+}
+
+#define check_attrib_format(vao, attribindex, size, type, normalized, \
+ integer, _long, relativeOffset) \
+ check_attrib_format_(vao, attribindex, size, type, normalized, \
+ integer, _long, relativeOffset, __LINE__)
+
+#define check_attrib_format_default(vao, attribindex) \
+ check_attrib_format_(vao, attribindex, 4, GL_FLOAT, GL_FALSE, \
+ GL_FALSE, GL_FALSE, 0, __LINE__)
+
+#define reset_attrib_format(vao, attribindex) \
+ glVertexArrayAttribFormat(vao, attribindex, 4, GL_FLOAT, GL_FALSE, 0)
+
+
+/**
+ * Returns true if the 0 terminated array contains value, and false otherwise.
+ */
+static bool
+find(const GLuint *array, GLuint value)
+{
+ int i;
+ for (i = 0; array[i]; i++) {
+ if (array[i] == value)
+ return true;
+ }
+
+ return false;
+}
+
+
+/**
+ * Returns true if the given type is a packed type, and false otherwise.
+ */
+static bool
+is_packed_type(GLenum type)
+{
+ switch (type) {
+ case GL_INT_2_10_10_10_REV:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ case GL_UNSIGNED_INT_10F_11F_11F_REV:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+
+/**
+ * Prints the parameter values and calls glVertexArrayAttribFormat.
+ */
+static void
+vertex_attrib_format(GLuint vao, GLuint attribindex, GLuint size, GLenum type,
+ GLboolean normalized, GLuint relativeoffset)
+{
+ if (size == GL_BGRA)
+ fprintf(stdout, "glVertexArrayAttribFormat"
+ "(%u, GL_BGRA, %s, %s, %u)\n",
+ attribindex, piglit_get_gl_enum_name(type),
+ normalized ? "GL_TRUE" : "GL_FALSE", relativeoffset);
+ else
+ fprintf(stdout, "glVertexArrayAttribFormat"
+ "(%u, %d, %s, %s, %u)\n",
+ attribindex, size, piglit_get_gl_enum_name(type),
+ normalized ? "GL_TRUE" : "GL_FALSE", relativeoffset);
+
+ glVertexArrayAttribFormat(vao, attribindex, size, type, normalized,
+ relativeoffset);
+}
+
+
+/**
+ * Prints the parameter values and calls glVertexArrayAttribIFormat.
+ */
+static void
+vertex_attrib_iformat(GLuint vao, GLuint attribindex, GLuint size, GLenum type,
+ GLuint relativeoffset)
+{
+ if (size == GL_BGRA)
+ fprintf(stdout, "glVertexArrayAttribIFormat"
+ "(%u, GL_BGRA, %s, %u)\n",
+ attribindex, piglit_get_gl_enum_name(type),
+ relativeoffset);
+ else
+ fprintf(stdout, "glVertexArrayAttribIFormat"
+ "(%u, %d, %s, %u)\n",
+ attribindex, size, piglit_get_gl_enum_name(type),
+ relativeoffset);
+
+ glVertexArrayAttribIFormat(vao, attribindex, size, type,
+ relativeoffset);
+}
+
+
+/**
+ * Prints the parameter values and calls glVertexArrayAttribLFormat.
+ */
+static void
+vertex_attrib_lformat(GLuint vao, GLuint attribindex, GLuint size, GLenum type,
+ GLuint relativeoffset)
+{
+ if (size == GL_BGRA)
+ fprintf(stdout, "glVertexArrayAttribLFormat"
+ "(%u, GL_BGRA, %s, %u)\n",
+ attribindex, piglit_get_gl_enum_name(type),
+ relativeoffset);
+ else
+ fprintf(stdout, "glVertexArrayAttribLFormat"
+ "(%u, %d, %s, %u)\n",
+ attribindex, size, piglit_get_gl_enum_name(type),
+ relativeoffset);
+
+ glVertexArrayAttribLFormat(vao, attribindex, size, type,
+ relativeoffset);
+}
+
+
+/**
+ * Calls glVertexArrayAttribFormat with the given parameters, and checks that
+ * the format is set when the size/normalized parameters are valid, and that
+ * the correct error is generated otherwise.
+ *
+ * This function expects that the given vao, type, and relativeoffset are
+ * always valid.
+ */
+static bool
+test_attribformat(GLuint vao, GLuint attribindex,
+ GLenum type, GLuint size,
+ GLboolean normalized,
+ GLuint relativeoffset,
+ bool sizeValid)
+{
+ bool pass = true;
+
+ /* Page 336 (page 358 of the PDF) of the OpenGL 4.5 (Core Profile)
+ * specification says:
+ *
+ * "An INVALID_VALUE error is generated if size is not
+ * one of the values shown in table 10.2 for the
+ * corresponding command.
+ * [...]
+ * An INVALID_OPERATION error is generated under any
+ * of the following conditions:
+ *
+ * • size is BGRA and type is not
+ * UNSIGNED_BYTE, INT_2_10_10_10_REV
+ * or UNSIGNED_INT_2_10_10_10_REV;
+ *
+ * • type is INT_2_10_10_10_REV or
+ * UNSIGNED_INT_2_10_10_10_REV, and
+ * size is neither 4 nor BGRA;
+ *
+ * • type is UNSIGNED_INT_10F_11F_11F_REV and
+ * size is not 3;
+ *
+ * • size is BGRA and normalized is FALSE."
+ */
+ GLenum err = GL_NO_ERROR;
+
+ if (!sizeValid) {
+ if (is_packed_type(type))
+ err = GL_INVALID_OPERATION;
+ else if (size == GL_BGRA && ARB_vertex_array_bgra)
+ err = GL_INVALID_OPERATION;
+ else
+ err = GL_INVALID_VALUE;
+ }
+
+ if (ARB_vertex_array_bgra && size == GL_BGRA && !normalized)
+ err = GL_INVALID_OPERATION;
+
+ reset_attrib_format(vao, attribindex);
+ vertex_attrib_format(vao, attribindex, size, type, normalized,
+ relativeoffset);
+
+ pass = piglit_check_gl_error(err);
+
+ if (err == GL_NO_ERROR) {
+ /* Verify that the format was changed */
+ pass = check_attrib_format(vao, attribindex, size, type,
+ normalized, GL_FALSE,
+ GL_FALSE, relativeoffset) && pass;
+ } else {
+ /* Verify that the format was not changed */
+ pass = check_attrib_format_default(vao, attribindex) && pass;
+ }
+
+ return pass;
+}
+
+
+/**
+ * Tests glVertexArrayAttribFormat
+ */
+static bool
+test_vertexarrayattribformat(GLuint vao, GLuint invalidvao, GLuint maxAttribs,
+ GLuint maxRelativeOffset)
+{
+ const GLuint bgra = ARB_vertex_array_bgra ? GL_BGRA : 0;
+ bool pass = true;
+ int i;
+
+ /* See table 10.2 on page 335 (page 357 of the PDF)
+ * of the OpenGL 4.5 (Core Profile) specification
+ */
+ struct {
+ GLenum type;
+ GLuint sizes[6];
+ bool supported;
+ } formats[] = {
+ {
+ GL_BYTE, /* type */
+ { 1, 2, 3, 4 }, /* sizes */
+ true /* supported */
+ },
+ {
+ GL_UNSIGNED_BYTE, /* type */
+ { 1, 2, 3, 4, bgra }, /* sizes */
+ true, /* supported */
+ },
+ {
+ GL_SHORT, /* type */
+ { 1, 2, 3, 4 }, /* sizes */
+ true, /* supported */
+ },
+ {
+ GL_UNSIGNED_SHORT, /* type */
+ { 1, 2, 3, 4 }, /* sizes */
+ true, /* supported */
+ },
+ {
+ GL_INT, /* type */
+ { 1, 2, 3, 4 }, /* sizes */
+ true, /* supported */
+ },
+ {
+ GL_UNSIGNED_INT, /* type */
+ { 1, 2, 3, 4 }, /* sizes */
+ true, /* supported */
+ },
+ {
+ GL_FIXED, /* type */
+ { 1, 2, 3, 4 }, /* sizes */
+ ARB_ES2_compatibility, /* supported */
+ },
+ {
+ GL_FLOAT, /* type */
+ { 1, 2, 3, 4 }, /* sizes */
+ true, /* supported */
+ },
+ {
+ GL_HALF_FLOAT, /* type */
+ { 1, 2, 3, 4 }, /* sizes */
+ ARB_half_float_vertex, /* supported */
+ },
+ {
+ GL_DOUBLE, /* type */
+ { 1, 2, 3, 4 }, /* sizes */
+ true, /* supported */
+ },
+ {
+ GL_INT_2_10_10_10_REV, /* type */
+ { 4, bgra }, /* sizes */
+ ARB_vertex_type_2_10_10_10_rev, /* supported */
+ },
+ {
+ GL_UNSIGNED_INT_2_10_10_10_REV, /* type */
+ { 4, bgra }, /* sizes */
+ ARB_vertex_type_2_10_10_10_rev, /* supported */
+ },
+ {
+ GL_UNSIGNED_INT_10F_11F_11F_REV, /* type */
+ { 3 }, /* sizes */
+ ARB_vertex_type_10f_11f_11f_rev, /* supported */
+ },
+ };
+
+ /* Test each supported type */
+ for (i = 0; i < ARRAY_SIZE(formats); i++) {
+ const GLuint sizes[] = { 0, 1, 2, 3, 4, GL_BGRA, 5 };
+ const GLenum type = formats[i].type;
+ const GLuint *validSizes = formats[i].sizes;
+ int j;
+
+ if (!formats[i].supported)
+ continue;
+
+ /* Test all sizes */
+ for (j = 0; j < ARRAY_SIZE(sizes); j++) {
+ const GLuint size = sizes[j];
+ const bool sizeValid = find(validSizes, size);
+ const int maxOffset = maxRelativeOffset + 1;
+
+ /* Normalized = GL_TRUE */
+ pass = test_attribformat(vao, rand() % maxAttribs,
+ type, size, GL_TRUE,
+ rand() % maxOffset,
+ sizeValid) && pass;
+
+ /* Normalized = GL_FALSE */
+ pass = test_attribformat(vao, rand() % maxAttribs,
+ type, size, GL_FALSE,
+ rand() % maxOffset,
+ sizeValid) && pass;
+ }
+ }
+
+ /* Page 335 (page 357 of the PDF) of the OpenGL 4.5 (Core Profile)
+ * specification says:
+ *
+ * "An INVALID_OPERATION error is generated by VertexArrayAttrib*Format
+ * if vaobj is not the name of an existing vertex array object.
+ */
+ vertex_attrib_format(invalidvao, 0, 4, GL_FLOAT, GL_FALSE, 0);
+ pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
+
+ /* Page 335 (page 357 of the PDF) of the OpenGL 4.5 (Core Profile)
+ * specification says:
+ *
+ * "An INVALID_VALUE error is generated if attribindex is
+ * greater than or equal to the value of MAX_VERTEX_ATTRIBS."
+ */
+ vertex_attrib_format(vao, maxAttribs, 4, GL_FLOAT, GL_FALSE, 0);
+ pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
+
+ /* Page 335 (page 357 of the PDF) of the OpenGL 4.5 (Core Profile)
+ * specification says:
+ *
+ * "An INVALID_ENUM error is generated if type is not one
+ * of the parameter token names from table 8.2 corresponding
+ * to one of the allowed GL data types for that command as
+ * shown in table 10.2."
+ */
+ reset_attrib_format(vao, 0);
+ vertex_attrib_format(vao, 0, 4, GL_4_BYTES, GL_FALSE, 0);
+ pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass;
+ pass = check_attrib_format_default(vao, 0) && pass;
+
+ /* Test all invalid types */
+ for (i = 0; i < ARRAY_SIZE(formats); i++) {
+ if (formats[i].supported)
+ continue;
+
+ reset_attrib_format(vao, 0);
+ vertex_attrib_format(vao, 0, formats[i].sizes[0],
+ formats[i].type, GL_TRUE, 0);
+
+ pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass;
+ pass = check_attrib_format_default(vao, 0) && pass;
+ }
+
+ /* Page 336 (page 358 of the PDF) of the OpenGL 4.5 (Core Profile)
+ * specification says:
+ *
+ * "An INVALID_VALUE error is generated if relativeoffset
+ * is larger than the value of
+ * MAX_VERTEX_ATTRIB_RELATIVE_OFFSET."
+ */
+ reset_attrib_format(vao, 0);
+ vertex_attrib_format(vao, 0, 4, GL_FLOAT, GL_FALSE,
+ maxRelativeOffset + 1);
+ pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
+ pass = check_attrib_format_default(vao, 0) && pass;
+
+ piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL,
+ "glVertexArrayAttribFormat");
+
+ return pass;
+}
+
+
+/**
+ * Tests glVertexArrayAttribIFormat
+ */
+static bool
+test_vertexarrayattribiformat(GLuint vao, GLuint invalidvao,
+ GLuint maxAttribs, GLuint maxRelativeOffset)
+{
+ bool pass = true;
+ int i;
+
+ const GLenum validTypes[] = {
+ GL_BYTE, GL_UNSIGNED_BYTE,
+ GL_SHORT, GL_UNSIGNED_SHORT,
+ GL_INT, GL_UNSIGNED_INT
+ };
+
+ const GLenum invalidTypes[] = {
+ GL_FIXED, GL_FLOAT, GL_HALF_FLOAT, GL_DOUBLE,
+ GL_INT_2_10_10_10_REV, GL_UNSIGNED_INT_2_10_10_10_REV,
+ GL_UNSIGNED_INT_10F_11F_11F_REV
+ };
+
+ for (i = 0; i < ARRAY_SIZE(validTypes); i++) {
+ const GLuint validSizes[] = { 1, 2, 3, 4 };
+ const GLuint invalidSizes[] = { 0, GL_BGRA, 5 };
+ int j;
+
+ /* Test all valid sizes */
+ for (j = 0; j < ARRAY_SIZE(validSizes); j++) {
+ const GLuint attribindex = rand() % maxAttribs;
+ const GLuint relativeoffset =
+ rand() % (maxRelativeOffset + 1);
+
+ reset_attrib_format(vao, attribindex);
+
+ vertex_attrib_iformat(vao, attribindex,
+ validSizes[j],
+ validTypes[i],
+ relativeoffset);
+
+ pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
+ pass = check_attrib_format(vao, attribindex,
+ validSizes[j],
+ validTypes[i],
+ GL_FALSE, GL_TRUE,
+ GL_FALSE,
+ relativeoffset) && pass;
+ }
+
+ /* Page 335 (page 357 of the PDF) of the OpenGL 4.5
+ * (Core Profile) specification says:
+ *
+ * "An INVALID_VALUE error is generated if size is
+ * not one of the values shown in table 10.2 for
+ * the corresponding command."
+ */
+ for (j = 0; j < ARRAY_SIZE(invalidSizes); j++) {
+ reset_attrib_format(vao, 0);
+ vertex_attrib_iformat(vao, 0,
+ invalidSizes[j],
+ validTypes[i], 0);
+
+ /* Check that GL_INVALID_VALUE was generated
+ * and that the format was not changed.
+ */
+ pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
+ pass = check_attrib_format_default(vao, 0) && pass;
+ }
+ }
+
+ /* Page 335 (page 357 of the PDF) of the OpenGL 4.5 (Core Profile)
+ * specification says:
+ *
+ * "An INVALID_ENUM error is generated if type is not one of
+ * the parameter token names from table 8.2 corresponding to
+ * one of the allowed GL data types for that command as
+ * shown in table 10.2."
+ */
+ for (i = 0; i < ARRAY_SIZE(invalidTypes); i++) {
+ /* Make sure the size is valid */
+ const GLuint size = invalidTypes[i] ==
+ GL_UNSIGNED_INT_10F_11F_11F_REV ? 3 : 4;
+
+ reset_attrib_format(vao, 0);
+ vertex_attrib_iformat(vao, 0, size,
+ invalidTypes[i], 0);
+ pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass;
+ pass = check_attrib_format_default(vao, 0) && pass;
+ }
+
+ /* Page 335 (page 357 of the PDF) of the OpenGL 4.5 (Core Profile)
+ * specification says:
+ *
+ * "An INVALID_OPERATION error is generated by VertexArrayAttrib*Format
+ * if vaobj is not the name of an existing vertex array object.
+ */
+ vertex_attrib_iformat(invalidvao, 0, 4, GL_INT, 0);
+ pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
+
+ /* Page 335 (page 357 of the PDF) of the OpenGL 4.5 (Core Profile)
+ * specification says:
+ *
+ * "An INVALID_VALUE error is generated if attribindex is
+ * greater than or equal to the value of MAX_VERTEX_ATTRIBS."
+ */
+ vertex_attrib_iformat(vao, maxAttribs, 4, GL_INT, 0);
+ pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
+
+ /* Page 336 (page 358 of the PDF) of the OpenGL 4.5 (Core Profile)
+ * specification says:
+ *
+ * "An INVALID_VALUE error is generated if relativeoffset is
+ * larger than the value of MAX_VERTEX_ATTRIB_RELATIVE_OFFSET."
+ */
+ vertex_attrib_iformat(vao, 0, 4, GL_INT,
+ maxRelativeOffset + 1);
+ pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
+
+ piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL,
+ "glVertexArrayAttribIFormat");
+
+ return pass;
+}
+
+
+/**
+ * Tests glVertexArrayAttribLFormat
+ */
+static bool
+test_vertexarrayattriblformat(GLuint vao, GLuint invalidvao,
+ GLuint maxAttribs, GLuint maxRelativeOffset)
+{
+ bool pass = true;
+ int i;
+
+ const GLuint validSizes[] = { 1, 2, 3, 4 };
+ const GLuint invalidSizes[] = { 0, GL_BGRA, 5 };
+
+ const GLenum invalidTypes[] = {
+ GL_BYTE, GL_UNSIGNED_BYTE,
+ GL_SHORT, GL_UNSIGNED_SHORT,
+ GL_INT, GL_UNSIGNED_INT,
+ GL_FIXED, GL_FLOAT, GL_HALF_FLOAT,
+ GL_INT_2_10_10_10_REV,
+ GL_UNSIGNED_INT_2_10_10_10_REV,
+ GL_UNSIGNED_INT_10F_11F_11F_REV
+ };
+
+ /* Test all valid sizes */
+ for (i = 0; i < ARRAY_SIZE(validSizes); i++) {
+ const GLuint attribindex = rand() % maxAttribs;
+ const GLuint relativeoffset = rand() % (maxRelativeOffset + 1);
+
+ reset_attrib_format(vao, attribindex);
+
+ vertex_attrib_lformat(vao, attribindex, validSizes[i],
+ GL_DOUBLE, relativeoffset);
+
+ pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
+ pass = check_attrib_format(vao, attribindex, validSizes[i],
+ GL_DOUBLE, GL_FALSE, GL_FALSE,
+ GL_TRUE, relativeoffset) && pass;
+ }
+
+ /* Page 335 (page 357 of the PDF) of the OpenGL 4.5 (Core Profile)
+ * specification says:
+ *
+ * "An INVALID_VALUE error is generated if size is not one of
+ * the values shown in table 10.2 for the corresponding
+ * command."
+ */
+ for (i = 0; i < ARRAY_SIZE(invalidSizes); i++) {
+ reset_attrib_format(vao, 0);
+ vertex_attrib_lformat(vao, 0, invalidSizes[i],
+ GL_DOUBLE, 0);
+ pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
+ pass = check_attrib_format_default(vao, 0) && pass;
+ }
+
+ /* Page 335 (page 357 of the PDF) of the OpenGL 4.5 (Core Profile)
+ * specification says:
+ *
+ * "An INVALID_ENUM error is generated if type is not one of
+ * the parameter token names from table 8.2 corresponding to
+ * one of the allowed GL data types for that command as
+ * shown in table 10.2."
+ */
+ for (i = 0; i < ARRAY_SIZE(invalidTypes); i++) {
+ /* Make sure the size is valid */
+ const GLuint size = invalidTypes[i] ==
+ GL_UNSIGNED_INT_10F_11F_11F_REV ? 3 : 4;
+
+ reset_attrib_format(vao, 0);
+ vertex_attrib_lformat(vao, 0, size,
+ invalidTypes[i], 0);
+ pass = piglit_check_gl_error(GL_INVALID_ENUM) && pass;
+ pass = check_attrib_format_default(vao, 0) && pass;
+ }
+
+ /* Page 335 (page 357 of the PDF) of the OpenGL 4.5 (Core Profile)
+ * specification says:
+ *
+ * "An INVALID_OPERATION error is generated by VertexArrayAttrib*Format
+ * if vaobj is not the name of an existing vertex array object.
+ */
+ vertex_attrib_lformat(invalidvao, 0, 4, GL_DOUBLE, 0);
+ pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
+
+
+ /* Page 335 (page 357 of the PDF) of the OpenGL 4.5 (Core Profile)
+ * specification says:
+ *
+ * "An INVALID_VALUE error is generated if attribindex is
+ * greater than or equal to the value of MAX_VERTEX_ATTRIBS."
+ */
+ vertex_attrib_lformat(vao, maxAttribs, 4, GL_DOUBLE, 0);
+ pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
+
+ /* Page 336 (page 358 of the PDF) of the OpenGL 4.5 (Core Profile)
+ * specification says:
+ *
+ * "An INVALID_VALUE error is generated if relativeoffset is
+ * larger than the value of MAX_VERTEX_ATTRIB_RELATIVE_OFFSET."
+ */
+ reset_attrib_format(vao, 0);
+ vertex_attrib_lformat(vao, 0, 4, GL_DOUBLE,
+ maxRelativeOffset + 1);
+ pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
+ pass = check_attrib_format_default(vao, 0) && pass;
+
+ piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL,
+ "glVertexArrayAttribLFormat");
+
+ return pass;
+}
+
+
+/**
+ * Checks the default formats in a newly created VAO
+ */
+static bool
+test_defaults(GLuint vao, GLint maxAttribs)
+{
+ bool pass = true;
+ int i;
+
+ for (i = 0; i < maxAttribs; i++) {
+ pass = check_attrib_format_default(vao, i) && pass;
+ }
+
+ piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL,
+ "Defaults");
+
+ return pass;
+}
+
+
+void
+piglit_init(int argc, char *argv[])
+{
+ GLint maxAttribs;
+ GLint maxRelativeOffset;
+ GLuint vao, invalidvao;
+ 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");
+
+ ARB_ES2_compatibility =
+ piglit_is_extension_supported("GL_ARB_ES2_compatibility");
+ ARB_half_float_vertex =
+ piglit_is_extension_supported("GL_ARB_half_float_vertex");
+ ARB_vertex_type_2_10_10_10_rev =
+ piglit_is_extension_supported( "GL_ARB_vertex_type_2_10_10_10_rev");
+ ARB_vertex_type_10f_11f_11f_rev =
+ piglit_is_extension_supported("GL_ARB_vertex_type_10f_11f_11f_rev");
+ ARB_vertex_attrib_64bit =
+ piglit_is_extension_supported("GL_ARB_vertex_attrib_64bit");
+ ARB_vertex_array_bgra =
+ piglit_is_extension_supported("GL_ARB_vertex_array_bgra");
+
+ glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttribs);
+ glGetIntegerv(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, &maxRelativeOffset);
+
+ /* Create a VAO */
+ glCreateVertexArrays(1, &vao);
+
+ /* Generate a VAO name, but don't create the object */
+ glGenVertexArrays(1, &invalidvao);
+
+ pass = test_defaults(vao, maxAttribs) && pass;
+
+ /* Test glVertexArrayAttribFormat */
+ pass = test_vertexarrayattribformat(vao, invalidvao, maxAttribs,
+ maxRelativeOffset) && pass;
+
+ /* Test glVertexAttribIFormat */
+ if (piglit_get_gl_version() >= 30) {
+ pass = test_vertexarrayattribiformat(vao, invalidvao,
+ maxAttribs,
+ maxRelativeOffset) && pass;
+ } else {
+ piglit_report_subtest_result(PIGLIT_SKIP,
+ "glVertexArrayAttribIFormat");
+ }
+
+ /* Test glVertexAttribLFormat */
+ if (ARB_vertex_attrib_64bit) {
+ pass = test_vertexarrayattriblformat(vao, invalidvao,
+ maxAttribs,
+ maxRelativeOffset) && pass;
+ } else {
+ piglit_report_subtest_result(PIGLIT_SKIP,
+ "glVertexArrayAttribLFormat");
+ }
+
+ glDeleteVertexArrays(1, &vao);
+ glDeleteVertexArrays(1, &invalidvao);
+
+ piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
+}
+