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(-) 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; } -- 1.9.3 _______________________________________________ Piglit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/piglit
