[23/63] shader_runner: add xfb testing support

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

Details

Message ID 20190223234551.21111-24-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.
Limited to capture doubles and floats, for simplicity. This patch
introduces the following [test] commands:

   * "expected buffer <size>": it allocates a expected buffer of the
     given <size> in bytes. It frees any previous one if already
     allocated.

   * "expected buffer float <index> <float_value>": sets <float_value>
     at the expected buffer <index> position, it assumes that the
     expected buffer will be used to store floats.

   * "expected buffer double <index> <double_value>": sets
     <double_value> at the expected buffer <index> position, it
     assumes that the expected buffer will be used to store doubles.

   * "xfb buffer object <n_buffer> <size>": generates and allocates
     one TRANSFORM_FEEDBACK_BUFFER buffer object, with declared buffer
     <n_buffer> (so xfb_buffer = <n_buffer> on the shader) and a given
     <size> in bytes.

   * "xfb draw arrays <mode> <first> <count>": equivalent to the
     already existing command "draw arrays", but under a transform
     feedback operation, and enabling GL_RASTERIZER_DISCARD.

   * "probe xfb buffer <element_type> <n_buffer> <n_components>":
     compares <n_components> of the expected value buffer with the xfb
     buffer <n_buffer>. It does a comparison using <element_type>,
     being the allowed values "float" or "double". Both expected
     buffer and the xfb buffer are expected to be already allocated,
     and of the proper size.
---
 tests/shaders/shader_runner.c | 106 ++++++++++++++++++++++++++++++++++
 1 file changed, 106 insertions(+)

Patch hide | download patch | download mbox

diff --git a/tests/shaders/shader_runner.c b/tests/shaders/shader_runner.c
index d786963bd..795f30682 100644
--- a/tests/shaders/shader_runner.c
+++ b/tests/shaders/shader_runner.c
@@ -149,6 +149,11 @@  static GLenum geometry_layout_output_type = GL_TRIANGLE_STRIP;
 static GLint geometry_layout_vertices_out = 0;
 static GLuint atomics_bos[8];
 static GLuint ssbo[32];
+#define MAX_XFB_BUFFERS 4 /* Same value used at nir_xfb_info */
+static GLuint xfb[MAX_XFB_BUFFERS];
+
+/* Store expected xfb values. Used for floats and doubles values */
+static void *expected_buffer = NULL;
 
 #define SHADER_TYPES 6
 static GLuint *subuniform_locations[SHADER_TYPES];
@@ -4337,6 +4342,16 @@  teardown_atomics(void)
 	}
 }
 
+static void
+teardown_xfb(void)
+{
+	for (unsigned i = 0; i < MAX_XFB_BUFFERS; ++i) {
+		glDeleteBuffers(MAX_XFB_BUFFERS, &xfb[i]);
+	}
+	if (expected_buffer != NULL)
+		free(expected_buffer);
+}
+
 static enum piglit_result
 program_must_be_in_use(void)
 {
@@ -4464,6 +4479,50 @@  probe_ssbo_uint(GLint ssbo_index, GLint ssbo_offset, const char *op, uint32_t va
 	return true;
 }
 
+GLenum piglit_xfb_primitive_mode(GLenum draw_arrays_mode)
+{
+	switch (draw_arrays_mode) {
+	case GL_POINTS:
+		return GL_POINTS;
+	case GL_LINES:
+	case GL_LINE_LOOP:
+	case GL_LINE_STRIP:
+	case GL_LINES_ADJACENCY:
+	case GL_LINE_STRIP_ADJACENCY:
+		return GL_LINES;
+	case GL_TRIANGLES:
+	case GL_TRIANGLE_STRIP:
+	case GL_TRIANGLE_FAN:
+	case GL_TRIANGLES_ADJACENCY:
+	case GL_TRIANGLE_STRIP_ADJACENCY:
+		return GL_TRIANGLES;
+	}
+
+	printf("glDrawArrays mode %s not supported for a transform feedback operation\n",
+	       piglit_get_gl_enum_name(draw_arrays_mode));
+	piglit_report_result(PIGLIT_FAIL);
+}
+
+static void
+piglit_xfb_draw_arrays(GLenum mode, int first, size_t count)
+{
+	GLenum primitive_mode = piglit_xfb_primitive_mode(mode);
+
+	glEnable(GL_RASTERIZER_DISCARD);
+
+	/* We don't need to call glBindBufferBase here, it is done on
+	 * the "xfb buffer object" command
+	 */
+
+	glBeginTransformFeedback(primitive_mode);
+	glDrawArrays(mode, first, count);
+	glEndTransformFeedback();
+
+	glDisable(GL_RASTERIZER_DISCARD);
+
+	glFlush();
+}
+
 enum piglit_result
 piglit_display(void)
 {
@@ -5082,6 +5141,52 @@  piglit_display(void)
 			glBufferData(GL_SHADER_STORAGE_BUFFER, y,
 				     ssbo_init, GL_DYNAMIC_DRAW);
 			free(ssbo_init);
+		} else if (sscanf(line, "expected buffer %d", &x) == 1) {
+			if (expected_buffer)
+				free(expected_buffer);
+			expected_buffer = calloc(x, 1);
+		} else if (sscanf(line, "expected buffer float %u %f", &ux, &c[0]) == 2) {
+			float *float_buffer = (float *) expected_buffer;
+			if (!expected_buffer) {
+				fprintf(stderr, "No expected buffer allocated\n");
+				piglit_report_result(PIGLIT_FAIL);
+			}
+			float_buffer[ux] = c[0];
+		} else if (sscanf(line, "expected buffer double %u %lf", &ux, &d[0])) {
+			double *double_buffer = (double *) expected_buffer;
+			if (!expected_buffer) {
+				fprintf(stderr, "No expected buffer allocated\n");
+				piglit_report_result(PIGLIT_FAIL);
+			}
+			double_buffer[ux] = d[0];
+		}
+		else if (sscanf(line, "xfb buffer object %u %u", &ux, &uy) == 2) {
+			GLuint *xfb_init = calloc(uy, 1);
+			glGenBuffers(1, &xfb[ux]);
+			glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, ux, xfb[ux]);
+			glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, uy,
+				     xfb_init, GL_STREAM_READ);
+			free(xfb_init);
+		} else if (sscanf(line, "xfb draw arrays %31s %d %d", s, &x, &y) == 3) {
+			GLenum mode = decode_drawing_mode(s);
+			int first = x;
+			size_t count = (size_t) y;
+			result = draw_arrays_common(first, count);
+			piglit_xfb_draw_arrays(mode, first, count);
+		} else if (sscanf(line, "probe xfb buffer %s %u %u", s, &ux, &uy) == 3) {
+			char label[255];
+			snprintf(label, sizeof(s) - 1, "xfb buffer %i", ux);
+			if (strcmp("float", s) == 0) {
+				if (!piglit_probe_buffer(xfb[ux], GL_TRANSFORM_FEEDBACK_BUFFER,
+							 label, 1, uy, expected_buffer)) {
+					result = PIGLIT_FAIL;
+				}
+			} else if (strcmp("double", s) == 0) {
+				if (!piglit_probe_buffer_doubles(xfb[ux], GL_TRANSFORM_FEEDBACK_BUFFER,
+								 label, 1, uy, expected_buffer)) {
+					result = PIGLIT_FAIL;
+				}
+			} else fprintf(stderr, "not supported xfb probing %s\n", s);
 		} else if (sscanf(line, "ssbo %d subdata float %d %f", &x, &y, &c[0]) == 3) {
 			glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo[x]);
 			glBufferSubData(GL_SHADER_STORAGE_BUFFER, y, 4, &c[0]);
@@ -5845,6 +5950,7 @@  piglit_init(int argc, char **argv)
 			teardown_ubos();
 			teardown_atomics();
 			teardown_fbos();
+			teardown_xfb();
 		}
 		exit(0);
 	}