[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