WIP

not faster -> drop it
---
 tests/util/piglit-util-gl.c | 180 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 180 insertions(+)

diff --git a/tests/util/piglit-util-gl.c b/tests/util/piglit-util-gl.c
index e9c20385e..39125e3a4 100644
--- a/tests/util/piglit-util-gl.c
+++ b/tests/util/piglit-util-gl.c
@@ -1067,6 +1067,27 @@ can_probe_ubyte()
        return r <= 8 && g <= 8 && b <= 8 && a <= 8;
 }
 
+static bool
+can_and_should_probe_gpu(int x, int y, int w, int h)
+{
+       //TODO: check environment variable to enable feature
+       if (piglit_get_gl_version() < 32)
+               return false;
+       if (!piglit_is_extension_supported("GL_ARB_explicit_uniform_location"))
+               return false;
+       if (!piglit_use_fbo)
+               return false;
+       int query;
+       glGetQueryiv(GL_PRIMITIVES_GENERATED, GL_CURRENT_QUERY, &query);
+       if (query)
+               return false;
+
+       if (w * h <= 0x100) //TODO: benchmark this
+               return false;
+
+       return true;
+}
+
 static void
 print_components_ubyte(const GLubyte *pixel, unsigned components)
 {
@@ -1261,6 +1282,156 @@ probe_rect_ubyte(int x, int y, int w, int h, int 
num_components,
        return true;
 }
 
+static bool
+probe_rect_gpu(int x, int y, int w, int h, int num_components,
+              const float *expected, bool silent)
+{
+       assert (num_components == 3 || num_components == 4);
+
+       //TODO: check if moving logic to vs and passing bool is faster
+       static const char *vs_src =
+               "#version 150\n"
+               "#extension GL_ARB_explicit_uniform_location : enable\n"
+               "layout(location = 0) uniform sampler2D color_buffer;\n"
+               "layout(location = 1) uniform ivec4 rect;\n"
+               "out vec4 color;\n"
+               "out ivec2 xy;\n"
+               "void main()\n"
+               "{\n"
+               "       xy = ivec2(rect.x, rect.y);\n"
+               "       xy += ivec2(gl_VertexID % rect.z, gl_VertexID / 
rect.z);\n"
+               "       color = texelFetch(color_buffer, xy, 0);\n"
+               "}\n";
+#define GS_SRC_HEADER \
+       "#version 150\n" \
+       "#extension GL_ARB_explicit_uniform_location : enable\n" \
+       "layout(points) in;\n" \
+       "layout(points, max_vertices=1) out;\n" \
+       "layout(location = 11) uniform vec4 expected;\n" \
+       "layout(location = 12) uniform vec4 tolerance;\n" \
+       "in vec4 color[];\n" \
+       "in ivec2 xy[];\n" \
+       "out ivec2 xy_err;\n" \
+       "out vec4 color_err;\n" \
+       "void main()\n" \
+       "{\n"
+#define GS_SRC_FOOTER \
+       "               xy_err = xy[0];\n" \
+       "               color_err = color[0];\n" \
+       "               EmitVertex();\n" \
+       "       }\n" \
+       "}\n"
+       static const char *gs_src3 =
+               GS_SRC_HEADER
+               "       if (any(greaterThan(abs(expected.xyz - color[0].xyz), 
tolerance.xyz))) {\n"
+               GS_SRC_FOOTER;
+       static const char *gs_src4 =
+               GS_SRC_HEADER
+               "       if (any(greaterThan(abs(expected - color[0]), 
tolerance))) {\n"
+               GS_SRC_FOOTER;
+#undef GS_SRC_HEADER
+#undef GS_SRC_FOOTER
+
+       static int prog3, prog4;
+       int *prog = num_components == 3 ? &prog3 : &prog4;
+       const char *gs_src = num_components == 3 ? gs_src3 : gs_src4;
+
+       if (!*prog) {
+               *prog = piglit_build_simple_program_unlinked_multiple_shaders(
+                       GL_VERTEX_SHADER, vs_src, GL_GEOMETRY_SHADER, gs_src, 
0);
+               const char *names[] = {"xy_err", "color_err"};
+               glTransformFeedbackVaryings(*prog, 2, names, 
GL_INTERLEAVED_ATTRIBS);
+               glLinkProgram(*prog);
+       }
+
+       /* Set up the transform feedback buffer. */
+       unsigned buf;
+       int old_buf;
+       glGenBuffers(1, &buf);
+       glGetIntegerv(GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, &old_buf);
+       glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
+       glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER,
+                    (2*sizeof(int) + 4*sizeof(float)), NULL, GL_STREAM_READ);
+
+       //FIXME: how to get previous buffer binding?
+       glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
+
+       /* bind program */
+       int old_prog;
+       glGetIntegerv(GL_CURRENT_PROGRAM, &old_prog);
+       glUseProgram(*prog);
+
+       /* set up uniforms */
+       glUniform1i(0, 0);
+       glUniform4i(1, x, y, w, h);
+       if (num_components == 3) {
+               glUniform3fv(11, 1, expected);
+       } else {
+               glUniform4fv(11, 1, expected);
+       }
+       glUniform4fv(12, 1, piglit_tolerance);
+
+       /* bind texture */
+       int tex;
+       glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, 
GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &tex);
+       int old_texture_unit;
+       glGetIntegerv(GL_ACTIVE_TEXTURE, &old_texture_unit);
+       glActiveTexture(GL_TEXTURE0);
+       int old_tex;
+       glGetIntegerv(GL_TEXTURE_BINDING_2D, &old_tex);
+       glBindTexture(GL_TEXTURE_2D, tex);
+
+       bool old_raster_discard = glIsEnabled(GL_RASTERIZER_DISCARD);
+       glEnable(GL_RASTERIZER_DISCARD);
+
+       //XXX: Disable arrays?
+
+       unsigned query;
+       glGenQueries(1, &query);
+       glBeginQuery(GL_PRIMITIVES_GENERATED, query);
+       glBeginTransformFeedback(GL_POINTS);
+
+       glDrawArrays(GL_POINTS, 0, w * h);
+
+       glEndTransformFeedback();
+       glEndQuery(GL_PRIMITIVES_GENERATED);
+
+       /* restore state */
+       if (!old_raster_discard)
+               glDisable(GL_RASTERIZER_DISCARD);
+       glBindTexture(GL_TEXTURE_2D, old_tex);
+       glActiveTexture(old_texture_unit);
+       glUseProgram(old_prog);
+       //glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, ???);
+       glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, old_buf);
+
+       int result;
+       glGetQueryObjectiv(query, GL_QUERY_RESULT, &result);
+
+       if (result != 0) {
+               glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
+               struct {
+                       int xy[2];
+                       float color[4];
+               } data;
+               glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0,
+                                  sizeof(data), &data);
+               glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, old_buf);
+
+               if (!silent) {
+                       print_bad_pixel_float(data.xy[0], data.xy[1],
+                                             num_components, expected,
+                                             data.color);
+               }
+       }
+
+       /* delete objects */
+       glDeleteQueries(1, &query);
+       glDeleteBuffers(1, &buf);
+
+       return result == 0;
+}
+
 int
 piglit_probe_rect_rgb_silent(int x, int y, int w, int h, const float *expected)
 {
@@ -1268,6 +1439,9 @@ piglit_probe_rect_rgb_silent(int x, int y, int w, int h, 
const float *expected)
        GLfloat *probe;
        GLfloat *pixels;
 
+       if (can_and_should_probe_gpu(x, y, w, h))
+               return probe_rect_gpu(x, y, w, h, 3, expected, true);
+
        if (can_probe_ubyte())
                return probe_rect_ubyte(x, y, w, h, 3, expected, true);
 
@@ -1328,6 +1502,9 @@ piglit_probe_rect_rgb(int x, int y, int w, int h, const 
float *expected)
        GLfloat *probe;
        GLfloat *pixels;
 
+       if (can_and_should_probe_gpu(x, y, w, h))
+               return probe_rect_gpu(x, y, w, h, 3, expected, false);
+
        if (can_probe_ubyte())
                return probe_rect_ubyte(x, y, w, h, 3, expected, false);
 
@@ -1436,6 +1613,9 @@ piglit_probe_rect_rgba(int x, int y, int w, int h, const 
float *expected)
        GLfloat *probe;
        GLfloat *pixels;
 
+       if (can_and_should_probe_gpu(x, y, w, h))
+               return probe_rect_gpu(x, y, w, h, 4, expected, false);
+
        if (can_probe_ubyte())
                return probe_rect_ubyte(x, y, w, h, 4, expected, false);
 
-- 
2.15.1

_______________________________________________
Piglit mailing list
Piglit@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/piglit

Reply via email to