fbo-blit-stretch: Try rendering to a texture as well

Submitted by Neil Roberts on June 23, 2014, 1:36 p.m.

Details

Message ID 1403530617-18498-1-git-send-email-neil@linux.intel.com
State New
Headers show

Not browsing as part of any series.

Commit Message

Neil Roberts June 23, 2014, 1:36 p.m.
With the i965 driver in Mesa since commit 61e264f4fcdba3623 the winsys
buffers are created as BGRA whereas the textures are created as RGBA.
If the two buffers in a blit have a different format then the driver
will avoid using the blorp blit path and instead fall back to the meta
path. The blorp blit path makes the test fail on Sandybridge but the
commit mentioned above hides the bug because the blorp path is no
longer used.

In order to make the test more likely to hit the bug, it now tries
rendering to a texture via an FBO in addition to rendering to the
winsys buffer. The texture is created in the same way so it should
always have the same format.

https://bugs.freedesktop.org/show_bug.cgi?id=68365
---
 tests/fbo/fbo-blit-stretch.cpp | 187 +++++++++++++++++++++++++----------------
 1 file changed, 114 insertions(+), 73 deletions(-)

Patch hide | download patch | download mbox

diff --git a/tests/fbo/fbo-blit-stretch.cpp b/tests/fbo/fbo-blit-stretch.cpp
index 1109783..4c3ebb2 100644
--- a/tests/fbo/fbo-blit-stretch.cpp
+++ b/tests/fbo/fbo-blit-stretch.cpp
@@ -63,22 +63,21 @@  PIGLIT_GL_TEST_CONFIG_END
 
 struct TestCase
 {
-	GLint srcW, srcH;
 	GLint srcX0; GLint srcY0; GLint srcX1; GLint srcY1;
 	GLint dstX0; GLint dstY0; GLint dstX1; GLint dstY1;
+	GLint srcW, srcH;
+	GLint dstW, dstH;
 	GLenum filter;
+	GLboolean to_texture;
 };
 
 static void
 describe(const TestCase &test)
 {
-	GLint dstW = piglit_width;
-	GLint dstH = piglit_height;
-
 	printf("%ix%i (%i, %i)-(%i, %i) => %ix%i (%i, %i)-(%i, %i)",
 	       test.srcW, test.srcH,
 	       test.srcX0, test.srcY0, test.srcX1, test.srcY1,
-	       dstW, dstH,
+	       test.dstW, test.dstH,
 	       test.dstX0, test.dstY0, test.dstX1, test.dstY1);
 
 	GLint srcDX = test.srcX1 - test.srcX0;
@@ -120,11 +119,11 @@  describe(const TestCase &test)
 	    test.srcY1 < 0 || test.srcY1 > test.srcH)
 		printf(" clamp_src_y");
 
-	if (test.dstX0 < 0 || test.dstX0 > dstW ||
-	    test.dstX1 < 0 || test.dstX1 > dstW)
+	if (test.dstX0 < 0 || test.dstX0 > test.dstW ||
+	    test.dstX1 < 0 || test.dstX1 > test.dstW)
 		printf(" clamp_dst_x");
-	if (test.dstY0 < 0 || test.dstY0 > dstH ||
-	    test.dstY1 < 0 || test.dstY1 > dstH)
+	if (test.dstY0 < 0 || test.dstY0 > test.dstH ||
+	    test.dstY1 < 0 || test.dstY1 > test.dstH)
 		printf(" clamp_dst_y");
 
 	switch (test.filter) {
@@ -332,54 +331,95 @@  run_test(const TestCase &test)
 
 	GLboolean pass;
 
-	GLuint tex;
-	GLuint fbo;
+	GLuint read_tex, draw_tex;
+	GLuint read_fbo, draw_fbo;
 	GLenum status;
 
-	glGenFramebuffers(1, &fbo);
-	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+	glGenFramebuffers(1, &read_fbo);
+	glBindFramebuffer(GL_FRAMEBUFFER, read_fbo);
 
 #if CHECKERBOARD
 	const float color1[4] = {1.0f, 0.0f, 0.0f, 1.0f};
 	const float color2[4] = {0.0f, 1.0f, 0.0f, 1.0f};
-	tex = piglit_checkerboard_texture(0, 0, test.srcW, test.srcH, 1, 1,  color1, color2);
+	read_tex = piglit_checkerboard_texture(0, 0,
+					       test.srcW, test.srcH,
+					       1, 1,
+					       color1, color2);
 #else
-	tex = piglit_rgbw_texture(GL_RGBA, test.srcW, test.srcH, GL_FALSE, GL_TRUE, GL_UNSIGNED_NORMALIZED);
+	read_tex = piglit_rgbw_texture(GL_RGBA,
+				       test.srcW, test.srcH,
+				       GL_FALSE, GL_TRUE,
+				       GL_UNSIGNED_NORMALIZED);
 #endif
-	glBindTexture(GL_TEXTURE_2D, tex);
+	glBindTexture(GL_TEXTURE_2D, read_tex);
 
 	glFramebufferTexture2D(GL_FRAMEBUFFER,
 			       GL_COLOR_ATTACHMENT0,
 			       GL_TEXTURE_2D,
-			       tex,
+			       read_tex,
 			       0);
 	assert(glGetError() == 0);
 
 	status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
 	if (status != GL_FRAMEBUFFER_COMPLETE) {
 		pass = GL_TRUE;
+                goto out_read_fbo;
+	}
+
+	if (test.to_texture) {
+		glGenTextures(1, &draw_tex);
+		glBindTexture(GL_TEXTURE_2D, draw_tex);
+		glTexImage2D(GL_TEXTURE_2D,
+			     0, /* level */
+			     GL_RGBA,
+			     test.dstW, test.dstH,
+			     0, /* border */
+			     GL_RGBA, /* format */
+			     GL_FLOAT, /* type */
+			     NULL);
+		glGenFramebuffers(1, &draw_fbo);
+		glBindFramebuffer(GL_FRAMEBUFFER, draw_fbo);
+		glFramebufferTexture2D(GL_FRAMEBUFFER,
+				       GL_COLOR_ATTACHMENT0,
+				       GL_TEXTURE_2D,
+				       draw_tex,
+				       0 /* level */);
+		status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+		if (status != GL_FRAMEBUFFER_COMPLETE) {
+			pass = GL_TRUE;
+			goto out_draw_fbo;
+		}
 	} else {
-		glViewport(0, 0, piglit_width, piglit_height);
-		piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
+		draw_fbo = piglit_winsys_fbo;
+	}
+
+	glViewport(0, 0, piglit_width, piglit_height);
+	piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
 
-		glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
-		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, piglit_winsys_fbo);
+	glBindFramebuffer(GL_READ_FRAMEBUFFER, read_fbo);
+	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, draw_fbo);
 
-		blit(test);
+	blit(test);
 
-		pass = verify(test, fbo, 0, 3);
+	pass = verify(test, read_fbo, draw_fbo, 3);
 
-		if (!piglit_automatic) {
-			piglit_present_results();
-			if (!pass) {
-				//getchar();
-			}
+	if (!piglit_automatic) {
+		piglit_present_results();
+		if (!pass) {
+			//getchar();
 		}
 	}
 
+out_draw_fbo:
+	if (test.to_texture) {
+		glDeleteFramebuffers(1, &draw_fbo);
+		glDeleteTextures(1, &draw_tex);
+	}
+
+out_read_fbo:
 	glBindFramebuffer(GL_FRAMEBUFFER, piglit_winsys_fbo);
-	glDeleteFramebuffers(1, &fbo);
-	glDeleteTextures(1, &tex);
+	glDeleteFramebuffers(1, &read_fbo);
+	glDeleteTextures(1, &read_tex);
 
 	return pass;
 }
@@ -409,10 +449,8 @@  tests[] = {
 	 */
 
 	{
-		SRCW, SRCH,
 		SRCXMIN, SRCYMIN, SRCXMAX, SRCYMAX,
 		DSTXMIN, DSTYMIN, DSTXMAX, DSTYMAX,
-		GL_NEAREST,
 	},
 
 	/*
@@ -420,22 +458,16 @@  tests[] = {
 	 */
 
 	{
-		SRCW, SRCH,
 		SRCXMAX, SRCYMAX, SRCXMIN, SRCYMIN, // flip xy
 		DSTXMAX, DSTYMAX, DSTXMIN, DSTYMIN, // flip xy
-		GL_NEAREST,
 	},
 	{
-		SRCW, SRCH,
 		SRCXMAX, SRCYMIN, SRCXMIN, SRCYMAX, // fliped x
 		DSTXMIN, DSTYMAX, DSTXMAX, DSTYMIN, // fliped y
-		GL_NEAREST,
 	},
 	{
-		SRCW, SRCH,
 		SRCXMIN, SRCYMAX, SRCXMAX, SRCYMIN, // fliped y
 		DSTXMAX, DSTYMIN, DSTXMIN, DSTYMAX, // fliped x
-		GL_NEAREST,
 	},
 
 	/*
@@ -443,16 +475,12 @@  tests[] = {
 	 */
 
 	{
-		SRCW, SRCH,
 		SRCXMIN, SRCYMIN, SRCXMAX, SRCYMAX,
 		DSTXMIN, DSTYMIN, DSTXMAX + 3*DX, DSTYMAX + 3*DY, // stretch x y
-		GL_NEAREST,
 	},
 	{
-		SRCW, SRCH,
 		SRCXMIN, SRCYMIN, SRCXMAX, SRCYMAX,
 		DSTXMIN, DSTYMIN, DSTXMAX + 3*DX, DSTYMAX + 3*DY, // stretch x y
-		GL_NEAREST,
 	},
 
 	/*
@@ -460,10 +488,8 @@  tests[] = {
 	 */
 
 	{
-		SRCW, SRCH,
 		SRCXMIN, SRCYMIN, SRCXMIN + 1, SRCYMIN + 1,
 		DSTXMIN, DSTYMIN, DSTXMIN + 7, DSTYMIN + 7, // stretch x y
-		GL_NEAREST,
 	},
 
 
@@ -472,28 +498,20 @@  tests[] = {
 	 */
 
 	{
-		SRCW, SRCH,
 		SRCXMIN, SRCYMIN, SRCXMAX, SRCYMAX,
 		-DX/2, -DY/2, -DX/2 + DX, -DY/2 + DY, // clip dst left bottom
-		GL_NEAREST,
 	},
 	{
-		SRCW, SRCH,
 		SRCXMIN, SRCYMIN, SRCXMAX, SRCYMAX,
 		DSTW - DX/2, DSTH - DY/2, DSTW - DX/2 + DX, DSTH - DY/2 + DY, // clip dst top right
-		GL_NEAREST,
 	},
 	{
-		SRCW, SRCH,
 		-DX/2, -DY/2, -DX/2 + DX, -DY/2 + DY, // clip src left bottom
 		DSTXMIN, DSTYMIN, DSTXMAX, DSTYMAX,
-		GL_NEAREST,
 	},
 	{
-		SRCW, SRCH,
 		SRCW - DX/2, SRCH - DY/2, SRCW - DX/2 + DX, SRCH - DY/2 + DY, // clip src top right
 		DSTXMIN, DSTYMIN, DSTXMAX, DSTYMAX,
-		GL_NEAREST,
 	},
 
 	/*
@@ -505,34 +523,24 @@  tests[] = {
 	 */
 #if 0
 	{
-		SRCW, SRCH,
 		SRCXMIN, SRCYMIN, SRCXMAX, SRCYMAX,
 		-DSTXMIN, -DSTYMIN, DSTXMAX, DSTYMAX, // clip dst left bottom
-		GL_NEAREST,
 	},
 	{
-		SRCW, SRCH,
 		SRCXMIN, SRCYMIN, SRCXMAX, SRCYMAX,
 		DSTXMIN, DSTYMIN, DSTW + DSTXMIN, DSTH + DSTYMIN, // clip dst top right
-		GL_NEAREST,
 	},
 	{
-		SRCW, SRCH,
 		-SRCXMIN, -SRCYMIN, SRCXMAX, SRCYMAX, // clip src left bottom
 		DSTXMIN, DSTYMIN, DSTXMAX, DSTYMAX,
-		GL_NEAREST,
 	},
 	{
-		SRCW, SRCH,
 		SRCXMIN, SRCYMIN, SRCW + SRCXMIN, SRCH + SRCYMIN, // clip src top right
 		DSTXMIN, DSTYMIN, DSTXMAX, DSTYMAX,
-		GL_NEAREST,
 	},
 	{
-		SRCW, SRCH,
 		SRCXMAX, SRCYMIN, SRCXMIN, SRCYMAX, // fliped x
 		-DSTXMIN, DSTH + DSTYMIN, DSTW + DSTXMIN, -DSTYMIN, // fliped y, cliped x y
-		GL_NEAREST,
 	},
 #endif
 
@@ -541,32 +549,65 @@  tests[] = {
 	 */
 
 	{
-		SRCW, SRCH,
 		0, 0, SRCW, SRCH,
 		0, 0, DSTW, DSTH,
-		GL_NEAREST,
 	},
 };
 
 static int test_index = -1;
 
+static GLint
+next_pot(GLint value)
+{
+	GLint result = 1;
+
+	while (result < value)
+		result <<= 1;
+
+	return result;
+}
+
 enum piglit_result
 piglit_display(void)
 {
+	static const GLenum filters[] = { GL_NEAREST, GL_LINEAR };
 	GLboolean pass = GL_TRUE;
-	for (unsigned i = 0; i < ARRAY_SIZE(tests); i++) {
-		if (test_index != -1 &&
-		    test_index != (int) i)
-			continue;
 
-		TestCase test = tests[i];
+	for (GLboolean to_texture = GL_FALSE;
+	     to_texture <= GL_TRUE;
+	     to_texture++) {
+
+		if (to_texture)
+			printf("Rendering to texture:\n");
+		else
+			printf("Rendering to window system buffer:\n");
+
+		for (unsigned i = 0; i < ARRAY_SIZE(tests); i++) {
+			if (test_index != -1 &&
+			    test_index != (int) i)
+				continue;
+
+			TestCase test = tests[i];
 
-		test.filter = GL_NEAREST;
-		pass = run_test(test) && pass;
+			test.to_texture = to_texture;
+
+			if (to_texture) {
+				test.dstW = next_pot(piglit_width);
+				test.dstH = next_pot(piglit_height);
+			} else {
+				test.dstW = piglit_width;
+				test.dstH = piglit_height;
+			}
+			test.srcW = SRCW;
+			test.srcH = SRCH;
 
-		test.filter = GL_LINEAR;
-		pass = run_test(test) && pass;
+			for (unsigned j = 0; j < ARRAY_SIZE(filters); j++) {
+				test.filter = filters[j];
+				pass &= run_test(test);
+			}
+		}
 	}
+
 	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
 }