[Mesa-dev] [PATCH] arb_indirect_parameters: add basic rendering tests
Ilia Mirkin
imirkin at alum.mit.edu
Sat Jan 2 12:02:10 PST 2016
Creates an array with 3 draws, the last of which is "bad", and makes
sure that the "bad" one is never drawn. Parameter count is supplied from
an earlier XFB draw to ensure that proper fencing occurs.
Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
---
tests/spec/CMakeLists.txt | 1 +
.../spec/arb_indirect_parameters/CMakeLists.gl.txt | 13 ++
tests/spec/arb_indirect_parameters/CMakeLists.txt | 1 +
.../spec/arb_indirect_parameters/tf-count-arrays.c | 220 ++++++++++++++++++++
.../arb_indirect_parameters/tf-count-elements.c | 229 +++++++++++++++++++++
5 files changed, 464 insertions(+)
create mode 100644 tests/spec/arb_indirect_parameters/CMakeLists.gl.txt
create mode 100644 tests/spec/arb_indirect_parameters/CMakeLists.txt
create mode 100644 tests/spec/arb_indirect_parameters/tf-count-arrays.c
create mode 100644 tests/spec/arb_indirect_parameters/tf-count-elements.c
diff --git a/tests/spec/CMakeLists.txt b/tests/spec/CMakeLists.txt
index 3c4bcfb..a984734 100644
--- a/tests/spec/CMakeLists.txt
+++ b/tests/spec/CMakeLists.txt
@@ -142,3 +142,4 @@ add_subdirectory (mesa_pack_invert)
add_subdirectory (ext_texture_format_bgra8888)
add_subdirectory (oes_draw_elements_base_vertex)
add_subdirectory (arb_shader_draw_parameters)
+add_subdirectory (arb_indirect_parameters)
diff --git a/tests/spec/arb_indirect_parameters/CMakeLists.gl.txt b/tests/spec/arb_indirect_parameters/CMakeLists.gl.txt
new file mode 100644
index 0000000..88f533d
--- /dev/null
+++ b/tests/spec/arb_indirect_parameters/CMakeLists.gl.txt
@@ -0,0 +1,13 @@
+include_directories(
+ ${GLEXT_INCLUDE_DIR}
+ ${OPENGL_INCLUDE_PATH}
+ ${piglit_SOURCE_DIR}/tests/mesa/util
+)
+
+link_libraries (
+ piglitutil_${piglit_target_api}
+ ${OPENGL_gl_LIBRARY}
+)
+
+piglit_add_executable (arb_indirect_parameters-tf-count-elements tf-count-elements.c)
+piglit_add_executable (arb_indirect_parameters-tf-count-arrays tf-count-arrays.c)
diff --git a/tests/spec/arb_indirect_parameters/CMakeLists.txt b/tests/spec/arb_indirect_parameters/CMakeLists.txt
new file mode 100644
index 0000000..144a306
--- /dev/null
+++ b/tests/spec/arb_indirect_parameters/CMakeLists.txt
@@ -0,0 +1 @@
+piglit_include_target_api()
diff --git a/tests/spec/arb_indirect_parameters/tf-count-arrays.c b/tests/spec/arb_indirect_parameters/tf-count-arrays.c
new file mode 100644
index 0000000..e88a7ba
--- /dev/null
+++ b/tests/spec/arb_indirect_parameters/tf-count-arrays.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2016 Ilia Mirkin
+ *
+ * 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.
+ */
+
+#include "piglit-util-gl.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_core_version = 31;
+ config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const char *vs_tf =
+ "#version 140\n"
+ "out int tf;\n"
+ "uniform int tf_val;\n"
+ "void main() { gl_Position = vec4(0); tf = tf_val; }\n";
+
+static const char *vs_draw =
+ "#version 140\n"
+ "out vec4 color;\n"
+ "in vec4 vtx, in_color;\n"
+ "void main() { gl_Position = vtx; color = in_color; }\n";
+
+static const char *fs_draw =
+ "#version 140\n"
+ "out vec4 c;\n"
+ "in vec4 color;\n"
+ "void main() { c = color; }\n";
+
+static GLint tf_prog, draw_prog;
+static GLint tf_val;
+static GLuint tf_vao, draw_vao;
+
+void
+piglit_init(int argc, char **argv)
+{
+ static const char *varying = "tf";
+ static const unsigned cmds[] = {
+ 4, 1, 0, 0,
+ 4, 1, 4, 0,
+ 4, 1, 8, 0,
+ };
+ static const struct {
+ float vertex_array[12 * 2];
+ float colors[12 * 4];
+ } geometry = {
+ {
+ -1, -1,
+ 0, -1,
+ 0, 1,
+ -1, 1,
+
+ 0, -1,
+ 1, -1,
+ 1, 1,
+ 0, 1,
+
+ -1, -1,
+ 1, -1,
+ 1, 1,
+ -1, 1,
+ },
+ {
+ 0, 1, 0, 1,
+ 0, 1, 0, 1,
+ 0, 1, 0, 1,
+ 0, 1, 0, 1,
+
+ 0, 1, 1, 1,
+ 0, 1, 1, 1,
+ 0, 1, 1, 1,
+ 0, 1, 1, 1,
+
+ 1, 0, 0, 0,
+ 1, 0, 0, 0,
+ 1, 0, 0, 0,
+ 1, 0, 0, 0,
+ },
+ };
+
+ GLuint vbo, dbo;
+
+ piglit_require_extension("GL_ARB_indirect_parameters");
+
+ tf_prog = piglit_build_simple_program_unlinked(vs_tf, NULL);
+ draw_prog = piglit_build_simple_program(vs_draw, fs_draw);
+
+ glTransformFeedbackVaryings(tf_prog, 1, &varying,
+ GL_INTERLEAVED_ATTRIBS);
+ glLinkProgram(tf_prog);
+ if (!piglit_link_check_status(tf_prog))
+ piglit_report_result(PIGLIT_FAIL);
+ tf_val = glGetUniformLocation(tf_prog, "tf_val");
+
+ glGenVertexArrays(1, &tf_vao);
+
+ glGenVertexArrays(1, &draw_vao);
+ glBindVertexArray(draw_vao);
+
+ glGenBuffers(1, &vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(geometry), &geometry, GL_STATIC_DRAW);
+
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE,
+ 2 * sizeof(GLfloat), NULL);
+
+ glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE,
+ 4 * sizeof(GLfloat), (void *)(12 * 2 * 4));
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+
+ glGenBuffers(1, &dbo);
+ glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dbo);
+ glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(cmds), cmds, GL_STATIC_DRAW);
+}
+
+enum piglit_result
+piglit_display(void)
+{
+ GLuint xfb_buf;
+ bool pass = true;
+ unsigned *map;
+
+ static const float g[] = {0, 1, 0, 1};
+ static const float gb[] = {0, 1, 1, 1};
+
+ glClearColor(0.2, 0.2, 0.2, 0.2);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glGenBuffers(1, &xfb_buf);
+ glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf);
+ glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 8, NULL, GL_STATIC_READ);
+
+ glEnable(GL_RASTERIZER_DISCARD);
+ glBindVertexArray(tf_vao);
+ glUseProgram(tf_prog);
+
+ /* write a 2 into xfb_buf[0] */
+ glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf, 0, 4);
+ glUniform1i(tf_val, 2);
+ glBeginTransformFeedback(GL_POINTS);
+ glDrawArrays(GL_POINTS, 0, 1);
+ glEndTransformFeedback();
+
+ /* write a 0 into xfb_buf[1] */
+ glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf, 4, 4);
+ glUniform1i(tf_val, 0);
+ glBeginTransformFeedback(GL_POINTS);
+ glDrawArrays(GL_POINTS, 0, 1);
+ glEndTransformFeedback();
+
+ glDisable(GL_RASTERIZER_DISCARD);
+ glBindVertexArray(draw_vao);
+ glUseProgram(draw_prog);
+
+ /* Draw the g/gb halves */
+ glBindBuffer(GL_PARAMETER_BUFFER_ARB, xfb_buf);
+ glMultiDrawArraysIndirectCountARB(
+ GL_TRIANGLE_FAN,
+ 0, 0, 2, 0);
+
+ pass &= piglit_probe_rect_rgba(0, 0, piglit_width / 2, piglit_height,
+ g);
+ pass &= piglit_probe_rect_rgba(piglit_width / 2, 0,
+ piglit_width / 2, piglit_height,
+ gb);
+ if (!pass) {
+ printf("first draw failed\n");
+ goto end;
+ }
+
+ /* Overdraw with the red quad, except count = 0 */
+ glMultiDrawArraysIndirectCountARB(
+ GL_TRIANGLE_FAN,
+ (2 * 4 * 4), 4, 1, 0);
+
+ pass &= piglit_probe_rect_rgba(0, 0, piglit_width / 2, piglit_height,
+ g);
+ pass &= piglit_probe_rect_rgba(piglit_width / 2, 0,
+ piglit_width / 2, piglit_height,
+ gb);
+ if (!pass)
+ printf("second draw did something when it shouldn't have.\n");
+
+end:
+ piglit_present_results();
+ map = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
+ if (map[0] != 2) {
+ printf("map[0] != 2\n");
+ pass = false;
+ }
+ if (map[1] != 0) {
+ printf("map[1] != 0\n");
+ pass = false;
+ }
+ glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
+ glDeleteBuffers(1, &xfb_buf);
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
diff --git a/tests/spec/arb_indirect_parameters/tf-count-elements.c b/tests/spec/arb_indirect_parameters/tf-count-elements.c
new file mode 100644
index 0000000..6ba646f
--- /dev/null
+++ b/tests/spec/arb_indirect_parameters/tf-count-elements.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2016 Ilia Mirkin
+ *
+ * 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.
+ */
+
+#include "piglit-util-gl.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_core_version = 31;
+ config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const char *vs_tf =
+ "#version 140\n"
+ "out int tf;\n"
+ "uniform int tf_val;\n"
+ "void main() { gl_Position = vec4(0); tf = tf_val; }\n";
+
+static const char *vs_draw =
+ "#version 140\n"
+ "out vec4 color;\n"
+ "in vec4 vtx, in_color;\n"
+ "void main() { gl_Position = vtx; color = in_color; }\n";
+
+static const char *fs_draw =
+ "#version 140\n"
+ "out vec4 c;\n"
+ "in vec4 color;\n"
+ "void main() { c = color; }\n";
+
+static GLint tf_prog, draw_prog;
+static GLint tf_val;
+static GLuint tf_vao, draw_vao;
+
+void
+piglit_init(int argc, char **argv)
+{
+ static const char *varying = "tf";
+ static const unsigned cmds[] = {
+ 6, 1, 0, 0, 0,
+ 6, 1, 0, 4, 0,
+ 6, 1, 0, 8, 0,
+ };
+ static const struct {
+ float vertex_array[12 * 2];
+ float colors[12 * 4];
+ } geometry = {
+ {
+ -1, -1,
+ 0, -1,
+ 0, 1,
+ -1, 1,
+
+ 0, -1,
+ 1, -1,
+ 1, 1,
+ 0, 1,
+
+ -1, -1,
+ 1, -1,
+ 1, 1,
+ -1, 1,
+ },
+ {
+ 0, 1, 0, 1,
+ 0, 1, 0, 1,
+ 0, 1, 0, 1,
+ 0, 1, 0, 1,
+
+ 0, 1, 1, 1,
+ 0, 1, 1, 1,
+ 0, 1, 1, 1,
+ 0, 1, 1, 1,
+
+ 1, 0, 0, 0,
+ 1, 0, 0, 0,
+ 1, 0, 0, 0,
+ 1, 0, 0, 0,
+ },
+ };
+
+ static const int indices[12] = {
+ 0, 1, 2,
+ 0, 2, 3,
+ };
+
+ GLuint vbo, ibo, dbo;
+
+ piglit_require_extension("GL_ARB_indirect_parameters");
+
+ tf_prog = piglit_build_simple_program_unlinked(vs_tf, NULL);
+ draw_prog = piglit_build_simple_program(vs_draw, fs_draw);
+
+ glTransformFeedbackVaryings(tf_prog, 1, &varying,
+ GL_INTERLEAVED_ATTRIBS);
+ glLinkProgram(tf_prog);
+ if (!piglit_link_check_status(tf_prog))
+ piglit_report_result(PIGLIT_FAIL);
+ tf_val = glGetUniformLocation(tf_prog, "tf_val");
+
+ glGenVertexArrays(1, &tf_vao);
+
+ glGenVertexArrays(1, &draw_vao);
+ glBindVertexArray(draw_vao);
+
+ glGenBuffers(1, &vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(geometry), &geometry, GL_STATIC_DRAW);
+
+ glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE,
+ 2 * sizeof(GLfloat), NULL);
+
+ glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE,
+ 4 * sizeof(GLfloat), (void *)(12 * 2 * 4));
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+
+ glGenBuffers(1, &ibo);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
+
+ glGenBuffers(1, &dbo);
+ glBindBuffer(GL_DRAW_INDIRECT_BUFFER, dbo);
+ glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(cmds), cmds, GL_STATIC_DRAW);
+}
+
+enum piglit_result
+piglit_display(void)
+{
+ GLuint xfb_buf;
+ bool pass = true;
+ unsigned *map;
+
+ static const float g[] = {0, 1, 0, 1};
+ static const float gb[] = {0, 1, 1, 1};
+
+ glClearColor(0.2, 0.2, 0.2, 0.2);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glGenBuffers(1, &xfb_buf);
+ glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf);
+ glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 8, NULL, GL_STATIC_READ);
+
+ glEnable(GL_RASTERIZER_DISCARD);
+ glBindVertexArray(tf_vao);
+ glUseProgram(tf_prog);
+
+ /* write a 2 into xfb_buf[0] */
+ glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf, 0, 4);
+ glUniform1i(tf_val, 2);
+ glBeginTransformFeedback(GL_POINTS);
+ glDrawArrays(GL_POINTS, 0, 1);
+ glEndTransformFeedback();
+
+ /* write a 0 into xfb_buf[1] */
+ glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf, 4, 4);
+ glUniform1i(tf_val, 0);
+ glBeginTransformFeedback(GL_POINTS);
+ glDrawArrays(GL_POINTS, 0, 1);
+ glEndTransformFeedback();
+
+ glDisable(GL_RASTERIZER_DISCARD);
+ glBindVertexArray(draw_vao);
+ glUseProgram(draw_prog);
+
+ /* Draw the g/gb halves */
+ glBindBuffer(GL_PARAMETER_BUFFER_ARB, xfb_buf);
+ glMultiDrawElementsIndirectCountARB(
+ GL_TRIANGLES, GL_UNSIGNED_INT,
+ 0, 0, 2, 0);
+
+ pass &= piglit_probe_rect_rgba(0, 0, piglit_width / 2, piglit_height,
+ g);
+ pass &= piglit_probe_rect_rgba(piglit_width / 2, 0,
+ piglit_width / 2, piglit_height,
+ gb);
+ if (!pass) {
+ printf("first draw failed\n");
+ goto end;
+ }
+
+ /* Overdraw with the red quad, except count = 0 */
+ glMultiDrawElementsIndirectCountARB(
+ GL_TRIANGLES, GL_UNSIGNED_INT,
+ (2 * 5 * 4), 4, 1, 0);
+
+ pass &= piglit_probe_rect_rgba(0, 0, piglit_width / 2, piglit_height,
+ g);
+ pass &= piglit_probe_rect_rgba(piglit_width / 2, 0,
+ piglit_width / 2, piglit_height,
+ gb);
+ if (!pass)
+ printf("second draw did something when it shouldn't have.\n");
+
+end:
+ piglit_present_results();
+ map = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
+ if (map[0] != 2) {
+ printf("map[0] != 2\n");
+ pass = false;
+ }
+ if (map[1] != 0) {
+ printf("map[1] != 0\n");
+ pass = false;
+ }
+ glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
+ glDeleteBuffers(1, &xfb_buf);
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
--
2.4.10
More information about the mesa-dev
mailing list