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(+) 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); } -- 2.19.1 _______________________________________________ Piglit mailing list Piglit@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/piglit