[Piglit] [PATCH 17/18] !UPSTREAM util-gl: Probe with GS / TRAFO_FDBK
Fabian Bieler
fabianbieler at fastmail.fm
Sun Jan 7 22:14:12 UTC 2018
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
More information about the Piglit
mailing list