[24/63] shader_runner: add xfb query object support

Submitted by apinheiro on Feb. 23, 2019, 11:45 p.m.

Details

Message ID 20190223234551.21111-25-apinheiro@igalia.com
State New
Headers show
Series "ARB_gl_spirv full series" ( rev: 1 ) in Piglit

Not browsing as part of any series.

Commit Message

apinheiro Feb. 23, 2019, 11:45 p.m.
This commit adds query objects for GL_PRIMITIVES_GENERATED and
GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, and only for xfb
drawing. Those query objects are created implicitly during xfb
drawing.

We don't add general query object support for two reasons:
  * Right now only xfb tests would be using it.

  * Adding general support would make the test section more
    complicated, as we would need to add beginquery/endquery like
    commands, making [test] section too much of a GL pseudocode.

If in the future we need general query object support, we can just
expand this.

It also add them always for any xfb drawing, instead of
conditionally. Again, to make things easier.

So it introduces just one [test] command, that can be used as:

  * "verify query_object GL_PRIMITIVES_GENERATED <integer value>"

  * "verify query_object GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN <integer_value>"
---
 tests/shaders/shader_runner.c | 76 +++++++++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

Patch hide | download patch | download mbox

diff --git a/tests/shaders/shader_runner.c b/tests/shaders/shader_runner.c
index 795f30682..851d66b04 100644
--- a/tests/shaders/shader_runner.c
+++ b/tests/shaders/shader_runner.c
@@ -154,6 +154,7 @@  static GLuint xfb[MAX_XFB_BUFFERS];
 
 /* Store expected xfb values. Used for floats and doubles values */
 static void *expected_buffer = NULL;
+static GLuint queries[2];
 
 #define SHADER_TYPES 6
 static GLuint *subuniform_locations[SHADER_TYPES];
@@ -3563,6 +3564,68 @@  enum program_interface_queries {
 	QUERY_RESOURCE_NAME,
 };
 
+/**
+ * Checks if the GL_QUERY_RESULT of a given query object has the
+ * expected value.
+ *
+ * Note that right now it only supports the following two queries:
+ *    * GL_PRIMITIVES_GENERATED
+ *    * GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
+ *
+ * As right now we are only creating those query objects with xfb
+ * rendering.
+ *
+ * Format of the command:
+ *
+ *  verify query_object GL_PRIMITIVES_GENERATED integer
+ *
+ * or
+ *
+ *  verify query_object GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN integer
+ */
+static void
+verify_query_object_result(const char *line)
+{
+	static const struct string_to_enum all_targets[] = {
+		ENUM_STRING(GL_PRIMITIVES_GENERATED),
+		ENUM_STRING(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN),
+		{ NULL, 0 }
+	};
+
+	unsigned target;
+	unsigned expected;
+	unsigned value = 0;
+	unsigned index = 0;
+
+	REQUIRE(parse_enum_tab(all_targets, line,
+			       &target, &line),
+		"Bad query object target at: %s\n", line);
+
+	REQUIRE(parse_uint(line, &expected, &line),
+		"Bad expected value at: %s\n", line);
+
+        /* Previous require already checks if the target is one of the
+         * supported ones.
+         */
+        index = target == GL_PRIMITIVES_GENERATED ? 0 : 1;
+
+	if (queries[index]) {
+		glGetQueryObjectuiv(queries[index], GL_QUERY_RESULT, &value);
+	} else {
+		fprintf(stderr, "query object for target %s is not initialized. "
+			"Did you forget to call \"xfb draw arrays\"?\n",
+			piglit_get_gl_enum_name(target));
+		piglit_report_result(PIGLIT_FAIL);
+	}
+
+	if (expected != value) {
+		fprintf(stderr, "glGetQueryObjectuiv(GL_QUERY_RESULT) for a %s "
+                        "query object: expected %d, got %d\n",
+			piglit_get_gl_enum_name(target), expected, value);
+		piglit_report_result(PIGLIT_FAIL);
+	}
+}
+
 /**
  * Query properties of interfaces and resources used by a program
  * using ARB_program_interface_query queries.
@@ -4350,6 +4413,10 @@  teardown_xfb(void)
 	}
 	if (expected_buffer != NULL)
 		free(expected_buffer);
+	for (unsigned i = 0; i < 2 ; ++i) {
+		if (queries[0])
+			glDeleteQueries(1, &queries[i]);
+	}
 }
 
 static enum piglit_result
@@ -4508,6 +4575,10 @@  piglit_xfb_draw_arrays(GLenum mode, int first, size_t count)
 {
 	GLenum primitive_mode = piglit_xfb_primitive_mode(mode);
 
+	glGenQueries(2, queries);
+	glBeginQuery(GL_PRIMITIVES_GENERATED, queries[0]);
+	glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, queries[1]);
+
 	glEnable(GL_RASTERIZER_DISCARD);
 
 	/* We don't need to call glBindBufferBase here, it is done on
@@ -4521,6 +4592,9 @@  piglit_xfb_draw_arrays(GLenum mode, int first, size_t count)
 	glDisable(GL_RASTERIZER_DISCARD);
 
 	glFlush();
+
+	glEndQuery(GL_PRIMITIVES_GENERATED);
+	glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
 }
 
 enum piglit_result
@@ -5518,6 +5592,8 @@  piglit_display(void)
                         verify_program_query(rest);
 		} else if (parse_str(line, "verify program_interface_query ", &rest)) {
 			verify_program_interface_query(rest, block_data);
+		} else if (parse_str(line, "verify query_object", &rest)) {
+			verify_query_object_result(rest);
 		} else if (parse_str(line, "vertex attrib ", &rest)) {
 			set_vertex_attrib(rest);
 		} else if (parse_str(line, "newlist ", &rest)) {