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

Reply via email to