[Piglit] [PATCH 05/14] arb_direct_state_access: Add a test for glVertexArrayAttrib[I|L]Format

Fredrik Höglund fredrik at kde.org
Tue Mar 31 10:26:37 PDT 2015


This test verifies that glVertexArrayAttribFormat,
glVertexArrayAttribIFormat and glVertexArrayAttribLFormat work
as expected.
---
 tests/all.py                                       |   1 +
 .../spec/arb_direct_state_access/CMakeLists.gl.txt |   1 +
 .../arb_direct_state_access/vao-attrib-format.c    | 791 +++++++++++++++++++++
 3 files changed, 793 insertions(+)
 create mode 100644 tests/spec/arb_direct_state_access/vao-attrib-format.c

diff --git a/tests/all.py b/tests/all.py
index cfa2a96..9f2f3ef 100755
--- a/tests/all.py
+++ b/tests/all.py
@@ -4282,6 +4282,7 @@ with profile.group_manager(
     g(['arb_direct_state_access-create-queries'], 'create-queries')
     g(['arb_direct_state_access-vao-create'], 'vao-create')
     g(['arb_direct_state_access-vao-attrib-enabledisable'], 'vao-attrib-enabledisable')
+    g(['arb_direct_state_access-vao-attrib-format'], 'vao-attrib-format')
 
 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 4ee9c0c..e5596be 100644
--- a/tests/spec/arb_direct_state_access/CMakeLists.gl.txt
+++ b/tests/spec/arb_direct_state_access/CMakeLists.gl.txt
@@ -38,4 +38,5 @@ piglit_add_executable (arb_direct_state_access-create-programpipelines create-pr
 piglit_add_executable (arb_direct_state_access-create-queries create-queries.c)
 piglit_add_executable (arb_direct_state_access-vao-create vao-create.c)
 piglit_add_executable (arb_direct_state_access-vao-attrib-enabledisable vao-attrib-enabledisable.c dsa-utils.c)
+piglit_add_executable (arb_direct_state_access-vao-attrib-format vao-attrib-format.c dsa-utils.c)
 # vim: ft=cmake:
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 0000000..807176f
--- /dev/null
+++ b/tests/spec/arb_direct_state_access/vao-attrib-format.c
@@ -0,0 +1,791 @@
+/*
+ * 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_array_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_array_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_array_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 334 of the PDF of the OpenGL 4.5 (Core Profile) spec 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 334 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 334 of the PDF of the OpenGL 4.5 (Core Profile) spec 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 334 of the PDF of the OpenGL 4.5 (Core Profile) spec 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 334 of the PDF of the OpenGL 4.5 (Core Profile) spec 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 335 of the PDF of the OpenGL 4.5 (Core Profile) spec 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 334 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 334 of the PDF of the OpenGL 4.5 (Core Profile) spec 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 334 of the PDF of the OpenGL 4.5 (Core Profile) spec 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 334 of the PDF of the OpenGL 4.5 (Core Profile) spec 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 335 of the PDF of the OpenGL 4.5 (Core Profile) spec 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, i);
+
+		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 334 of the PDF of the OpenGL 4.5 (Core Profile) spec 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 334 of the PDF of the OpenGL 4.5 (Core Profile) spec 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 334 of the PDF of the OpenGL 4.5 (Core Profile) spec 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 334 of the PDF of the OpenGL 4.5 (Core Profile) spec 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 335 of the PDF of the OpenGL 4.5 (Core Profile) spec 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_array_64bit =
+	    piglit_is_extension_supported("GL_ARB_vertex_array_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_array_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);
+}
+
-- 
2.1.4



More information about the Piglit mailing list