[Piglit] [PATCH] ARB_draw_indirect: add initial tests
Christoph Bumiller
christoph.bumiller at speed.at
Thu Apr 4 11:10:42 PDT 2013
From: Christoph Bumiller <e0425955 at student.tuwien.ac.at>
Is that sufficient to get anyone looking at my mesa patches
(I've rebased them already) or do I need to make more/nicer
tests ? How many ?
If I'd get paid anything for this I'd gladly spend my time writing
loads of tests, it's rather relaxing, compared to reverse engineering.
---
tests/spec/CMakeLists.txt | 1 +
tests/spec/arb_draw_indirect/CMakeLists.gl.txt | 19 +
tests/spec/arb_draw_indirect/CMakeLists.txt | 1 +
tests/spec/arb_draw_indirect/draw-arrays-multi.c | 66 ++++
.../arb_draw_indirect/draw-arrays-prim-restart.c | 141 +++++++
tests/spec/arb_draw_indirect/draw-arrays.c | 67 ++++
tests/spec/arb_draw_indirect/draw-common.c | 408 ++++++++++++++++++++
tests/spec/arb_draw_indirect/draw-elements-multi.c | 66 ++++
tests/spec/arb_draw_indirect/draw-elements.c | 67 ++++
tests/spec/arb_draw_indirect/errors-multi.c | 140 +++++++
tests/spec/arb_draw_indirect/errors.c | 159 ++++++++
11 files changed, 1135 insertions(+), 0 deletions(-)
create mode 100644 tests/spec/arb_draw_indirect/CMakeLists.gl.txt
create mode 100644 tests/spec/arb_draw_indirect/CMakeLists.txt
create mode 100644 tests/spec/arb_draw_indirect/draw-arrays-multi.c
create mode 100644 tests/spec/arb_draw_indirect/draw-arrays-prim-restart.c
create mode 100644 tests/spec/arb_draw_indirect/draw-arrays.c
create mode 100644 tests/spec/arb_draw_indirect/draw-common.c
create mode 100644 tests/spec/arb_draw_indirect/draw-elements-multi.c
create mode 100644 tests/spec/arb_draw_indirect/draw-elements.c
create mode 100644 tests/spec/arb_draw_indirect/errors-multi.c
create mode 100644 tests/spec/arb_draw_indirect/errors.c
diff --git a/tests/spec/CMakeLists.txt b/tests/spec/CMakeLists.txt
index a1492cc..a07a814 100644
--- a/tests/spec/CMakeLists.txt
+++ b/tests/spec/CMakeLists.txt
@@ -2,6 +2,7 @@ add_subdirectory (amd_performance_monitor)
add_subdirectory (arb_color_buffer_float)
add_subdirectory (arb_debug_output)
add_subdirectory (arb_draw_instanced)
+add_subdirectory (arb_draw_indirect)
add_subdirectory (arb_es2_compatibility)
add_subdirectory (arb_framebuffer_object)
add_subdirectory (arb_framebuffer_srgb)
diff --git a/tests/spec/arb_draw_indirect/CMakeLists.gl.txt b/tests/spec/arb_draw_indirect/CMakeLists.gl.txt
new file mode 100644
index 0000000..3b3d823
--- /dev/null
+++ b/tests/spec/arb_draw_indirect/CMakeLists.gl.txt
@@ -0,0 +1,19 @@
+include_directories(
+ ${GLEXT_INCLUDE_DIR}
+ ${OPENGL_INCLUDE_PATH}
+ ${piglit_SOURCE_DIR}/tests/util
+)
+
+link_libraries (
+ piglitutil_${piglit_target_api}
+ ${OPENGL_gl_LIBRARY}
+ ${OPENGL_glu_LIBRARY}
+)
+
+piglit_add_executable (arb_draw_indirect-draw-arrays-prim-restart draw-arrays-prim-restart.c)
+piglit_add_executable (arb_draw_indirect-draw-elements draw-elements.c draw-common.c)
+piglit_add_executable (arb_draw_indirect-draw-elements-multi draw-elements-multi.c draw-common.c)
+piglit_add_executable (arb_draw_indirect-draw-arrays draw-arrays.c draw-common.c)
+piglit_add_executable (arb_draw_indirect-draw-arrays-multi draw-arrays-multi.c draw-common.c)
+piglit_add_executable (arb_draw_indirect-errors errors.c)
+piglit_add_executable (arb_draw_indirect-errors-multi errors-multi.c)
diff --git a/tests/spec/arb_draw_indirect/CMakeLists.txt b/tests/spec/arb_draw_indirect/CMakeLists.txt
new file mode 100644
index 0000000..144a306
--- /dev/null
+++ b/tests/spec/arb_draw_indirect/CMakeLists.txt
@@ -0,0 +1 @@
+piglit_include_target_api()
diff --git a/tests/spec/arb_draw_indirect/draw-arrays-multi.c b/tests/spec/arb_draw_indirect/draw-arrays-multi.c
new file mode 100644
index 0000000..b8dd1da
--- /dev/null
+++ b/tests/spec/arb_draw_indirect/draw-arrays-multi.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright © The Piglit project 2012
+ *
+ * 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.
+ *
+ * Authors: Christoph Bumiller
+ */
+
+/**
+ * @file draw-elements.c
+ *
+ * Tests that glDrawElementsIndirect works correctly with various combinations
+ * of draw command data generated via transform feedback.
+ */
+
+#include "piglit-util-gl-common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_compat_version = 10;
+ config.supports_gl_core_version = 31;
+
+ config.window_width = 1;
+ config.window_height = 1;
+ config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+unsigned num_indirect_draws;
+
+void write_commands_tfb(int indexed, int dump);
+void setup_indirect_draw();
+int compare_results(int indexed);
+
+enum piglit_result
+piglit_display(void)
+{
+ write_commands_tfb(0, 0);
+ setup_indirect_draw();
+
+ glBeginTransformFeedback(GL_POINTS);
+ /* If <stride> is zero, the array elements are treated as
+ * tightly packed. */
+ glMultiDrawArraysIndirect(GL_POINTS, NULL,
+ num_indirect_draws, 0);
+ glEndTransformFeedback();
+
+ return compare_results(0) ? PIGLIT_FAIL : PIGLIT_PASS;
+}
diff --git a/tests/spec/arb_draw_indirect/draw-arrays-prim-restart.c b/tests/spec/arb_draw_indirect/draw-arrays-prim-restart.c
new file mode 100644
index 0000000..005419f
--- /dev/null
+++ b/tests/spec/arb_draw_indirect/draw-arrays-prim-restart.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright © The Piglit Project 2012
+ *
+ * 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.
+ *
+ * Authors: Christoph Bumiller
+ */
+
+/**
+ * @file errors.c
+ *
+ * Tests that primitive restart is applied to glDrawArraysIndirect.
+ *
+ * The following vertices are drawn as a triangle strip:
+ * 1,5***3,6
+ * ****
+ * 0,4****2
+ * If the primitive is not restarted on index 3, the first 2 triangles
+ * will cover the whole window (0,1,2),(2,1,3).
+ */
+
+#include "piglit-util-gl-common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_compat_version = 10;
+ config.supports_gl_core_version = 31;
+
+ config.window_width = 32;
+ config.window_height = 32;
+ config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const char *vs_source = "#version 130\n"
+ "in vec2 vertex;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(vertex.x, vertex.y, 0.0, 1.0);\n"
+ "}\n";
+
+static const char *fs_source = "#version 130\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0);\n"
+ "}\n";
+
+enum piglit_result
+piglit_display(void)
+{
+ const float green[] = { 0, 1, 0, 0 };
+ const float clear[] = { 0, 0, 0, 0 };
+
+ glClearColor(clear[0], clear[1], clear[2], clear[3]);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glEnable(GL_PRIMITIVE_RESTART);
+ glPrimitiveRestartIndex(3);
+ glDrawArraysIndirect(GL_TRIANGLE_STRIP, NULL);
+
+ piglit_present_results();
+
+ if (!piglit_probe_pixel_rgb(20, 16, clear) ||
+ !piglit_probe_pixel_rgb( 1, 16, green))
+ return PIGLIT_FAIL;
+ return PIGLIT_PASS;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+ const float vboData[7][2] = {
+ { -1.0f, -1.0f },
+ { -1.0f, +1.0f },
+ { +1.0f, -1.0f },
+ { +1.0f, +1.0f }, /* restart */
+ { -1.0f, -1.0f },
+ { -1.0f, +1.0f },
+ { +1.0f, +1.0f }
+ };
+ const uint32_t cmdData[4] = {
+ 7, /* count */
+ 1, /* primCount */
+ 0, /* first */
+ 0 /* reservedMustBeZero */
+ };
+ GLuint vs, fs, prog;
+ GLuint vbo, cmd;
+ GLint vertex_location;
+
+ piglit_require_extension("GL_ARB_draw_indirect");
+ piglit_require_GLSL_version(130);
+
+ vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source);
+ fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source);
+
+ prog = piglit_link_simple_program(vs, fs);
+
+ if (!vs || !fs || !prog)
+ piglit_report_result(PIGLIT_FAIL);
+
+ glDeleteShader(vs);
+ glDeleteShader(fs);
+
+ vertex_location = glGetAttribLocation(prog, "vertex");
+
+ if (piglit_get_gl_version() >= 31) {
+ GLuint vao;
+ glGenVertexArrays(1, &vao);
+ glBindVertexArray(vao);
+ }
+ glGenBuffers(1, &vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vboData), vboData, GL_STATIC_DRAW);
+ glEnableVertexAttribArray(vertex_location);
+ glVertexAttribPointer(vertex_location, 2, GL_FLOAT, GL_FALSE, 0, NULL);
+
+ glGenBuffers(1, &cmd);
+ glBindBuffer(GL_DRAW_INDIRECT_BUFFER, cmd);
+ glBufferData(GL_DRAW_INDIRECT_BUFFER,
+ sizeof(cmdData), cmdData, GL_STATIC_DRAW);
+
+ glUseProgram(prog);
+}
diff --git a/tests/spec/arb_draw_indirect/draw-arrays.c b/tests/spec/arb_draw_indirect/draw-arrays.c
new file mode 100644
index 0000000..c6c4521
--- /dev/null
+++ b/tests/spec/arb_draw_indirect/draw-arrays.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright © The Piglit project 2012
+ *
+ * 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.
+ *
+ * Authors: Christoph Bumiller
+ */
+
+/**
+ * @file draw-elements.c
+ *
+ * Tests that glDrawElementsIndirect works correctly with various combinations
+ * of draw command data generated via transform feedback.
+ */
+
+#include "piglit-util-gl-common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_compat_version = 10;
+ config.supports_gl_core_version = 31;
+
+ config.window_width = 1;
+ config.window_height = 1;
+ config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+unsigned num_indirect_draws;
+
+void write_commands_tfb(int indexed, int dump);
+void setup_indirect_draw();
+int compare_results(int indexed);
+
+enum piglit_result
+piglit_display(void)
+{
+ unsigned int i;
+
+ write_commands_tfb(0, 0);
+ setup_indirect_draw();
+
+ glBeginTransformFeedback(GL_POINTS);
+ for (i = 0; i < num_indirect_draws; ++i)
+ glDrawArraysIndirect(GL_POINTS,
+ (void *)(4 * sizeof(GLuint) * i));
+ glEndTransformFeedback();
+
+ return compare_results(0) ? PIGLIT_FAIL : PIGLIT_PASS;
+}
diff --git a/tests/spec/arb_draw_indirect/draw-common.c b/tests/spec/arb_draw_indirect/draw-common.c
new file mode 100644
index 0000000..290dcb5
--- /dev/null
+++ b/tests/spec/arb_draw_indirect/draw-common.c
@@ -0,0 +1,408 @@
+/*
+ * Copyright © The Piglit project 2012
+ *
+ * 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.
+ *
+ * Authors: Christoph Bumiller
+ */
+
+/**
+ * @file draw-common.c
+ *
+ * Common initialization and generation of draw commands for testing the 4
+ * gl[Multi]DrawIndirect{Elements,Arrays} functions.
+ *
+ * The draw commands:
+ *
+ * typedef struct {
+ * GLuint count;
+ * GLuint primCount;
+ * GLuint firstIndex;
+ * GLint baseVertex;
+ * GLuint reservedMustBeZero;
+ * } DrawElementsIndirectCommand;
+ *
+ * typedef struct {
+ * GLuint count;
+ * GLuint primCount;
+ * GLuint first;
+ * GLuint reservedMustBeZero;
+ * } DrawArraysIndirectCommand;
+ *
+ * are generated by a vertex shader and written to the DRAW_INDIRECT_BUFFER via
+ * transform feedback.
+ * The vertex shader uses gl_VertexID as source to derive the various paramters.
+ *
+ * Then, the DrawIndirect commands stream vertices into a result buffer, also
+ * via transform feedback.
+ * Each vertex consists of a single uint that has the value of the vertex index.
+ * The sequence in which these values are written to the result buffer is used
+ * to check that the intended draw command has been executed.
+ */
+
+#include "piglit-util-gl-common.h"
+
+unsigned num_indirect_draws = 0;
+
+static GLuint tfb[2];
+static GLuint prog[2];
+static GLuint vao[2];
+
+static GLuint vtxbuf;
+static GLuint idxbuf;
+static GLuint cmdbuf;
+static GLuint resbuf;
+
+static const GLsizei vertices_size = 32 * sizeof(uint32_t);
+
+static GLsizei results_size;
+static GLsizei commands_size;
+
+static uint32_t *results;
+
+static void
+clear_buffer(GLenum target)
+{
+ void *map;
+ GLint size;
+
+ glGetBufferParameteriv(target, GL_BUFFER_SIZE, &size);
+
+ map = glMapBufferRange(target, 0, size,
+ GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
+ assert(map);
+ memset(map, 0, size);
+
+ glUnmapBuffer(target);
+}
+
+static int
+generate_data(int indexed)
+{
+ static const GLushort indices[16] = {
+ 5, 1, 3, 7, 6, 0, 4, 2,
+ 15, 11, 10, 9, 13, 14, 8, 12
+ };
+
+ unsigned int ni, nv;
+ unsigned int i, b, r, v;
+ unsigned int p;
+
+ uint32_t *vertices;
+
+ num_indirect_draws = 3 * 8 * 2 * 2;
+
+ commands_size = num_indirect_draws * (5 * 4);
+
+ /* calculate size of the result buffer */
+ results_size = 0;
+ for (ni = 1; ni <= 3; ++ni) /* 1 to 3 instances */
+ for (nv = 1; nv <= 8; ++nv) /* 1 to 8 vertices */
+ for (r = 0; r < 2; ++r) /* 2 index ranges */
+ for (b = 0; b < 2; ++b) /* 2 index biases */
+ for (i = 0; i < ni; ++i) /* instance */
+ for (v = 0; v < nv; ++v) /* vertex */
+ results_size += sizeof(uint32_t);
+
+ vertices = malloc(vertices_size);
+ results = malloc(results_size);
+ if (!vertices || !results) {
+ fprintf(stderr, "memory allocation failed\n");
+ return -1;
+ }
+
+ /* generate vertices */
+ for (v = 0; v < 32; ++v)
+ vertices[v] = v;
+
+ /* generate result data for memcmp */
+ p = 0;
+ for (ni = 1; ni <= 3; ++ni) { /* 1 to 3 instances */
+ for (nv = 1; nv <= 8; ++nv) { /* 1 to 8 vertices */
+ for (r = 0; r < 2; ++r) { /* 2 index ranges */
+ for (b = 0; b < 2; ++b) { /* 2 index biases */
+ for (i = 0; i < ni; ++i) { /* instance */
+ for (v = 0; v < nv; ++v) { /* vertex */
+ GLushort index = indexed ?
+ indices[v + (r * 8)] + (b * 16) :
+ v + (r * 16) + (b * 8);
+ results[p++] = (i << 28) | vertices[index];
+ }}}}}}
+
+ /* setup vertex and index buffer */
+ if (indexed) {
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idxbuf);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER,
+ sizeof(indices), indices, GL_STATIC_DRAW);
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, vtxbuf);
+ glBufferData(GL_ARRAY_BUFFER, vertices_size, vertices, GL_STATIC_DRAW);
+ free(vertices);
+
+ /* setup command and result buffer and hook them up to TFB objects */
+ glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, resbuf);
+ glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER,
+ results_size, NULL, GL_STREAM_DRAW);
+ clear_buffer(GL_TRANSFORM_FEEDBACK_BUFFER);
+
+ glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, cmdbuf);
+ glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER,
+ commands_size, NULL, GL_STATIC_DRAW);
+ clear_buffer(GL_TRANSFORM_FEEDBACK_BUFFER);
+
+ glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfb[1]);
+ glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, resbuf);
+
+ glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfb[0]);
+ glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, cmdbuf);
+
+ return 0;
+}
+
+static void
+dump_draw_commands(int indexed)
+{
+ const uint32_t *cmd;
+ unsigned int i;
+
+ fprintf(stderr, "number of draw commands: %u\n", num_indirect_draws);
+ fprintf(stderr, "command buffer size: 0x%x bytes\n", commands_size);
+
+ glBindBuffer(GL_DRAW_INDIRECT_BUFFER, cmdbuf);
+ cmd = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, commands_size,
+ GL_MAP_READ_BIT);
+ assert(cmd);
+ for (i = 0; i < num_indirect_draws; ++i) {
+ if (indexed) {
+ fprintf(stderr, "=== %u ===:\n"
+ " count = %u\n"
+ " primCount = %u\n"
+ " firstIndex = %u\n"
+ " baseVertex = %u\n"
+ " reservedMustBeZero = %u\n", i,
+ cmd[0], cmd[1], cmd[2], cmd[3], cmd[4]);
+ cmd += 5;
+ } else {
+ fprintf(stderr, "=== %u ===:\n"
+ " count = %u\n"
+ " primCount = %u\n"
+ " first = %u\n"
+ " reservedMustBeZero = %u\n", i,
+ cmd[0], cmd[1], cmd[2], cmd[3]);
+ cmd += 4;
+ }
+ }
+ glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER);
+}
+
+int
+compare_results(int indexed)
+{
+ const uint32_t *map;
+ int ret;
+ unsigned int ni, nv;
+ unsigned int i, b, r, v;
+ unsigned int p;
+
+ int silent = 0;
+
+ glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, resbuf);
+ map = (uint32_t *)glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER,
+ 0, results_size, GL_MAP_READ_BIT);
+ if (!map)
+ return -1;
+ ret = 0;
+ p = 0;
+ for (ni = 1; ni <= 3; ++ni) {
+ for (nv = 1; nv <= 8; ++nv) {
+ for (r = 0; r < 2; ++r) {
+ for (b = 0; b < 2; ++b) {
+ for (i = 0; i < ni; ++i) {
+ for (v = 0; v < nv; ++v, ++p) {
+ if (map[p] == results[p])
+ continue;
+ ret = -1;
+
+ if (!map[p]) {
+ if (!silent) {
+ fprintf(stderr, "incorrect at [%u]: 0\n", p);
+ silent = 1;
+ } else {
+ if (silent == 1)
+ fprintf(stderr, "...\n");
+ silent = 2;
+ }
+ break;
+ } else {
+ silent = 0;
+ }
+ fprintf(stderr,
+ "incorrect at "
+ "[%u](ni=%u,nv=%u,i=%u,r=%u,b=%u,v=%u): %08x / %08x\n",
+ p,ni,nv,i,r,b,v,map[p],results[p]);
+ }}}}}}
+
+ glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
+ return ret;
+}
+
+void
+write_commands_tfb(int indexed, int dump)
+{
+ static const char *varyingsIndexed[2] = { "commandIndexed", "zero" };
+ static const char *varyingsArrays[2] = { "commandArrays", "zero" };
+
+ if (generate_data(indexed))
+ piglit_report_result(PIGLIT_FAIL);
+
+ glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfb[0]);
+ glTransformFeedbackVaryings(prog[0], 2,
+ indexed ? varyingsIndexed : varyingsArrays,
+ GL_INTERLEAVED_ATTRIBS);
+ glLinkProgram(prog[0]);
+
+ glUseProgram(prog[0]);
+ glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfb[0]);
+ glBeginTransformFeedback(GL_POINTS);
+ glBindVertexArray(vao[0]);
+ glDrawArrays(GL_POINTS, 0, num_indirect_draws);
+ glEndTransformFeedback();
+
+ if (dump)
+ dump_draw_commands(indexed);
+}
+
+void
+setup_indirect_draw()
+{
+ glUseProgram(prog[1]);
+
+ glBindVertexArray(vao[1]);
+ /* GL_[ELEMENT]_ARRAY_BUFFER already bound */
+
+ glBindBuffer(GL_DRAW_INDIRECT_BUFFER, cmdbuf);
+
+ glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfb[1]);
+}
+
+/* Vertex program the writes the DrawIndirect command to output variables
+ * to be captured by transform feedback.
+ */
+static const char *vs_source_gen = "#version 140\n"
+ "flat out uvec4 commandIndexed;\n"
+ "flat out uvec3 commandArrays;\n"
+ "flat out uint zero;\n"
+ "void main() {\n"
+ " uint id = uint(gl_VertexID);\n"
+
+ " commandIndexed.x = ((id >> 2u) & 0x7u) + 1u;\n" /* vertex count */
+ " commandIndexed.y = ((id >> 5u) & 0x3u) + 1u;\n" /* instance count */
+ " commandIndexed.z = ((id >> 1u) & 0x1u) * 8u;\n" /* first index */
+ " commandIndexed.w = ((id >> 0u) & 0x1u) * 16u;\n" /* base vertex */
+
+ " commandArrays.x = ((id >> 2u) & 0x7u) + 1u;\n" /* vertex count */
+ " commandArrays.y = ((id >> 5u) & 0x3u) + 1u;\n" /* instance count */
+ " commandArrays.z = ((id >> 0u) & 0x3u) * 8u;\n" /* first vertex */
+
+ " zero = 0u;\n"
+ "}\n";
+
+/* Vertex program that writes the vertex input combined with gl_InstanceID
+ * (to check instanced drawing) to an output variable to be capture in the
+ * result buffer via transform feedback.
+ */
+static const char *vs_source_use = "#version 140\n"
+ "in uint vertex;\n"
+ "flat out uint result;\n"
+ "void main() {\n"
+ " result = vertex | (uint(gl_InstanceID) << 28u);\n"
+ "}\n";
+
+/* No-op fragment program.
+ */
+static const char *fs_source = "#version 140\n"
+ "void main() {\n"
+ " gl_FragColor = vec4(0.0);\n"
+ "}\n";
+
+void
+piglit_init(int argc, char **argv)
+{
+ static const char *resvar[1] = { "result" };
+ GLuint vs, fs;
+ GLint loc;
+
+ piglit_require_extension("GL_ARB_draw_indirect");
+ piglit_require_extension("GL_ARB_transform_feedback2");
+ piglit_require_extension("GL_ARB_map_buffer_range");
+ piglit_require_extension("GL_ARB_vertex_array_object");
+ piglit_require_GLSL_version(140);
+
+ vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source_gen);
+ fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source);
+
+ prog[0] = piglit_link_simple_program(vs, fs);
+
+ if (!vs || !fs || !prog[0])
+ piglit_report_result(PIGLIT_FAIL);
+
+ glDeleteShader(vs);
+ glDeleteShader(fs);
+
+ vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source_use);
+ fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source);
+
+ prog[1] = piglit_link_simple_program(vs, fs);
+
+ if (!vs || !fs || !prog[1])
+ piglit_report_result(PIGLIT_FAIL);
+
+ glDeleteShader(vs);
+ glDeleteShader(fs);
+
+
+ glGenTransformFeedbacks(2, tfb);
+
+ /* TFB for prog[0] is generated in generate_data, it depends on whether
+ * we want to test DrawElements or DrawArrays.
+ */
+
+ glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfb[1]);
+ glTransformFeedbackVaryings(prog[1], 1, resvar, GL_INTERLEAVED_ATTRIBS);
+ glLinkProgram(prog[1]);
+
+
+ glGenBuffers(1, &cmdbuf);
+ glGenBuffers(1, &resbuf);
+ glGenBuffers(1, &vtxbuf);
+ glGenBuffers(1, &idxbuf);
+
+
+ glGenVertexArrays(2, vao);
+
+ loc = glGetAttribLocation(prog[1], "vertex");
+ assert(loc >= 0);
+
+ glBindVertexArray(vao[1]);
+ glBindBuffer(GL_ARRAY_BUFFER, vtxbuf);
+ glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, 0, NULL);
+ glEnableVertexAttribArray(loc);
+}
diff --git a/tests/spec/arb_draw_indirect/draw-elements-multi.c b/tests/spec/arb_draw_indirect/draw-elements-multi.c
new file mode 100644
index 0000000..36d2067
--- /dev/null
+++ b/tests/spec/arb_draw_indirect/draw-elements-multi.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright © The Piglit project 2012
+ *
+ * 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.
+ *
+ * Authors: Christoph Bumiller
+ */
+
+/**
+ * @file draw-elements.c
+ *
+ * Tests that glDrawElementsIndirect works correctly with various combinations
+ * of draw command data generated via transform feedback.
+ */
+
+#include "piglit-util-gl-common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_compat_version = 10;
+ config.supports_gl_core_version = 31;
+
+ config.window_width = 1;
+ config.window_height = 1;
+ config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+unsigned num_indirect_draws;
+
+void write_commands_tfb(int indexed, int dump);
+void setup_indirect_draw();
+int compare_results(int indexed);
+
+enum piglit_result
+piglit_display(void)
+{
+ write_commands_tfb(1, 0);
+ setup_indirect_draw();
+
+ glBeginTransformFeedback(GL_POINTS);
+ /* If <stride> is zero, the array elements are treated as
+ * tightly packed. */
+ glMultiDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_SHORT, NULL,
+ num_indirect_draws, 0);
+ glEndTransformFeedback();
+
+ return compare_results(1) ? PIGLIT_FAIL : PIGLIT_PASS;
+}
diff --git a/tests/spec/arb_draw_indirect/draw-elements.c b/tests/spec/arb_draw_indirect/draw-elements.c
new file mode 100644
index 0000000..6e50931
--- /dev/null
+++ b/tests/spec/arb_draw_indirect/draw-elements.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright © The Piglit project 2012
+ *
+ * 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.
+ *
+ * Authors: Christoph Bumiller
+ */
+
+/**
+ * @file draw-elements.c
+ *
+ * Tests that glDrawElementsIndirect works correctly with various combinations
+ * of draw command data generated via transform feedback.
+ */
+
+#include "piglit-util-gl-common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_compat_version = 10;
+ config.supports_gl_core_version = 31;
+
+ config.window_width = 1;
+ config.window_height = 1;
+ config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+unsigned num_indirect_draws;
+
+void write_commands_tfb(int indexed, int dump);
+void setup_indirect_draw();
+int compare_results(int indexed);
+
+enum piglit_result
+piglit_display(void)
+{
+ unsigned int i;
+
+ write_commands_tfb(1, 0);
+ setup_indirect_draw();
+
+ glBeginTransformFeedback(GL_POINTS);
+ for (i = 0; i < num_indirect_draws; ++i)
+ glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_SHORT,
+ (void *)(5 * sizeof(GLuint) * i));
+ glEndTransformFeedback();
+
+ return compare_results(1) ? PIGLIT_FAIL : PIGLIT_PASS;
+}
diff --git a/tests/spec/arb_draw_indirect/errors-multi.c b/tests/spec/arb_draw_indirect/errors-multi.c
new file mode 100644
index 0000000..399b209
--- /dev/null
+++ b/tests/spec/arb_draw_indirect/errors-multi.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright © 2012 The Piglit project 2013.
+ *
+ * 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.
+ *
+ * Authors: Christoph Bumiller
+ */
+
+/**
+ * @file errors.c
+ *
+ * Tests error conditions for for glMultiDraw*Indirect:
+ */
+
+#include "piglit-util-gl-common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_compat_version = 10;
+ config.supports_gl_core_version = 31;
+
+ config.window_width = 1;
+ config.window_height = 1;
+ config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const char *vs_source = "#version 130\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(0.0);\n"
+ "}\n";
+
+static const char *fs_source = "#version 130\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = vec4(0.0);\n"
+ "}\n";
+
+enum piglit_result
+piglit_display(void)
+{
+ GLuint zeroData[128];
+ GLuint cmdBuf;
+ GLuint idxBuf;
+
+ memset(zeroData, 0, sizeof(zeroData));
+
+ if (piglit_get_gl_version() >= 31) {
+ GLuint vao;
+ glGenVertexArrays(1, &vao);
+ glBindVertexArray(vao);
+ }
+
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glGenBuffers(1, &cmdBuf);
+ glBindBuffer(GL_DRAW_INDIRECT_BUFFER, cmdBuf);
+ glBufferData(GL_DRAW_INDIRECT_BUFFER,
+ sizeof(zeroData), zeroData, GL_STATIC_DRAW);
+ glGenBuffers(1, &idxBuf);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idxBuf);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER,
+ sizeof(zeroData), zeroData, GL_STATIC_DRAW);
+
+ /* <stride> must be a multiple of four, otherwise an INVALID_VALUE
+ * error is generated.
+ *
+ * Test both functions with strides 3,4,5 and 8.
+ */
+ glMultiDrawArraysIndirect(GL_POINTS, NULL, 1, 3);
+ if (!piglit_check_gl_error(GL_INVALID_VALUE))
+ return PIGLIT_FAIL;
+ glMultiDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_BYTE, NULL, 1, 3);
+ if (!piglit_check_gl_error(GL_INVALID_VALUE))
+ return PIGLIT_FAIL;
+
+ glMultiDrawArraysIndirect(GL_POINTS, NULL, 1, 4);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+ glMultiDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_BYTE, NULL, 1, 4);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glMultiDrawArraysIndirect(GL_POINTS, NULL, 1, 5);
+ if (!piglit_check_gl_error(GL_INVALID_VALUE))
+ return PIGLIT_FAIL;
+ glMultiDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_BYTE, NULL, 1, 5);
+ if (!piglit_check_gl_error(GL_INVALID_VALUE))
+ return PIGLIT_FAIL;
+
+ glMultiDrawArraysIndirect(GL_POINTS, NULL, 1, 8);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+ glMultiDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_BYTE, NULL, 1, 8);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ glFinish(); /* force hardware driver execute */
+ return PIGLIT_PASS;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+ GLuint vs, fs, prog;
+
+ piglit_require_extension("GL_ARB_multi_draw_indirect");
+
+ vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source);
+ fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source);
+
+ prog = piglit_link_simple_program(vs, fs);
+
+ if (!vs || !fs || !prog)
+ piglit_report_result(PIGLIT_FAIL);
+
+ glDeleteShader(vs);
+ glDeleteShader(fs);
+
+ glUseProgram(prog);
+}
diff --git a/tests/spec/arb_draw_indirect/errors.c b/tests/spec/arb_draw_indirect/errors.c
new file mode 100644
index 0000000..c9ca75b
--- /dev/null
+++ b/tests/spec/arb_draw_indirect/errors.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright © The Piglit Project 2012
+ *
+ * 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.
+ *
+ * Authors: Christoph Bumiller
+ */
+
+/**
+ * @file errors.c
+ *
+ * Tests various error conditions for glDraw*Indirect:
+ */
+
+#include "piglit-util-gl-common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_compat_version = 10;
+ config.supports_gl_core_version = 31;
+
+ config.window_width = 1;
+ config.window_height = 1;
+ config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const char *vs_source = "#version 130\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = vec4(0.0);\n"
+ "}\n";
+
+static const char *fs_source = "#version 130\n"
+ "void main()\n"
+ "{\n"
+ " gl_FragColor = vec4(0.0);\n"
+ "}\n";
+
+enum piglit_result
+piglit_display(void)
+{
+ GLuint zeroData[32];
+ GLuint cmdBuf;
+ GLuint idxBuf;
+
+ memset(zeroData, 0, sizeof(zeroData));
+
+ if (piglit_get_gl_version() >= 31) {
+ GLuint vao;
+ glGenVertexArrays(1, &vao);
+ glBindVertexArray(vao);
+ }
+
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glGenBuffers(1, &cmdBuf);
+ glBindBuffer(GL_DRAW_INDIRECT_BUFFER, cmdBuf);
+ glBufferData(GL_DRAW_INDIRECT_BUFFER, 8, zeroData, GL_STATIC_DRAW);
+
+ /* Check that buffer handling worked normally. */
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* An INVALID_OPERATION error is generated if the commands source
+ * data beyond the end of the buffer object or if <indirect> is not
+ * word aligned.
+ */
+
+ /* The buffer object is too small. */
+ glDrawArraysIndirect(GL_POINTS, NULL);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ /* Create a large enough buffer object. */
+ glBufferData(GL_DRAW_INDIRECT_BUFFER,
+ sizeof(zeroData), zeroData, GL_STATIC_DRAW);
+
+ /* But read from END - 4. */
+ glDrawArraysIndirect(GL_POINTS, (void *)(sizeof(zeroData) - 4));
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ /* Use an unaligned offset. */
+ if (sizeof(GLuint) / 2) {
+ glDrawArraysIndirect(GL_POINTS, (void *)(sizeof(GLuint) / 2));
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+ }
+
+ /* Make sure we can draw without producing an error. */
+ glDrawArraysIndirect(GL_POINTS, NULL);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* Unlike regular DrawElementsInstancedBaseVertex commands,
+ * the indices may not come from a client array and must come from
+ * an index buffer.
+ * If no element array buffer is bound, an INVALID_OPERATION
+ * error is generated.
+ */
+ glGenBuffers(1, &idxBuf);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idxBuf);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER,
+ sizeof(zeroData), zeroData, GL_STATIC_DRAW);
+
+ /* Check that drawing with an index buffer worked. */
+ glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT, NULL);
+ if (!piglit_check_gl_error(GL_NO_ERROR))
+ return PIGLIT_FAIL;
+
+ /* Unbind the index buffer and check that a client array does not. */
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT, NULL);
+ if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+ return PIGLIT_FAIL;
+
+ glFinish(); /* force hardware driver execute */
+ return PIGLIT_PASS;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+ GLuint vs, fs, prog;
+
+ piglit_require_extension("GL_ARB_draw_indirect");
+
+ vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source);
+ fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source);
+
+ prog = piglit_link_simple_program(vs, fs);
+
+ if (!vs || !fs || !prog)
+ piglit_report_result(PIGLIT_FAIL);
+
+ glDeleteShader(vs);
+ glDeleteShader(fs);
+
+ glUseProgram(prog);
+}
--
1.7.3.4
More information about the Piglit
mailing list