[Piglit] [PATCH] fbo-clear-format: test stencil glClear
Marek Olšák
maraeo at gmail.com
Mon Oct 15 10:10:15 PDT 2012
The test visualizes the stencil buffer (unlike some other tests),
which is very useful for debugging.
Unfortunately, it doesn't work with Mesa. There seems to be a bogus GL error.
The problem can be reproduced by running:
./fbo-clear-formats GL_EXT_packed_depth_stencil stencil -auto
It would be useful to know if the proprietary drivers have the same issue.
---
tests/all.tests | 2 +
tests/fbo/fbo-clear-formats.c | 160 +++++++++++++++++++++++++++++++++++------
2 files changed, 142 insertions(+), 20 deletions(-)
diff --git a/tests/all.tests b/tests/all.tests
index fbc4d22..9be38b9 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -1297,6 +1297,7 @@ add_fbo_stencil_tests(arb_depth_buffer_float, 'GL_DEPTH32F_STENCIL8')
add_fbo_depthstencil_tests(arb_depth_buffer_float, 'GL_DEPTH32F_STENCIL8')
add_fbo_formats_tests('spec/ARB_depth_buffer_float', 'GL_ARB_depth_buffer_float')
add_texwrap_format_tests(arb_depth_buffer_float, 'GL_ARB_depth_buffer_float')
+arb_depth_buffer_float['fbo-clear-formats stencil'] = PlainExecTest(['fbo-clear-formats', 'GL_ARB_depth_buffer_float', 'stencil', '-auto'])
arb_texture_env_crossbar = Group()
spec['ARB_texture_env_crossbar'] = arb_texture_env_crossbar
@@ -1566,6 +1567,7 @@ add_fbo_depthstencil_tests(ext_packed_depth_stencil, 'GL_DEPTH24_STENCIL8')
add_fbo_formats_tests('spec/EXT_packed_depth_stencil', 'GL_EXT_packed_depth_stencil')
add_texwrap_format_tests(ext_packed_depth_stencil, 'GL_EXT_packed_depth_stencil')
ext_packed_depth_stencil['readpixels-24_8'] = PlainExecTest(['ext_packed_depth_stencil-readpixels-24_8', '-auto'])
+ext_packed_depth_stencil['fbo-clear-formats stencil'] = PlainExecTest(['fbo-clear-formats', 'GL_EXT_packed_depth_stencil', 'stencil', '-auto'])
ext_texture_array = Group()
spec['EXT_texture_array'] = ext_texture_array
diff --git a/tests/fbo/fbo-clear-formats.c b/tests/fbo/fbo-clear-formats.c
index ad085d7..3abb877 100644
--- a/tests/fbo/fbo-clear-formats.c
+++ b/tests/fbo/fbo-clear-formats.c
@@ -43,10 +43,13 @@ PIGLIT_GL_TEST_CONFIG_BEGIN
config.window_width = 700;
config.window_height = 300;
- config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_ALPHA;
+ config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_STENCIL |
+ PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_ALPHA;
PIGLIT_GL_TEST_CONFIG_END
+static bool clear_stencil = false;
+
/* Do piglit_rgbw_texture() image but using glClear */
static bool
do_rgba_clear(GLenum format, GLuint tex, int level, int size)
@@ -71,12 +74,8 @@ do_rgba_clear(GLenum format, GLuint tex, int level, int size)
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- if (!level)
- printf(" - FBO incomplete\n");
+ glDeleteFramebuffersEXT(1, &fb);
return false;
- } else {
- if (!level)
- printf("\n");
}
/* Handle the small sizes of compressed mipmap blocks */
@@ -152,13 +151,8 @@ do_depth_clear(GLenum format, GLuint tex, int level, int size)
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- if (!level)
- printf(" - FBO incomplete\n");
glDeleteFramebuffersEXT(1, &fb);
return false;
- } else {
- if (!level)
- printf("\n");
}
glEnable(GL_SCISSOR_TEST);
@@ -181,6 +175,55 @@ do_depth_clear(GLenum format, GLuint tex, int level, int size)
}
static bool
+do_stencil_clear(GLenum format, GLuint tex, int level, int size)
+{
+ GLuint fb;
+ GLenum status;
+ GLint draw_buffer, read_buffer;
+ int x;
+
+ glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer);
+ glGetIntegerv(GL_READ_BUFFER, &read_buffer);
+
+ glGenFramebuffersEXT(1, &fb);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
+
+ glDrawBuffer(GL_NONE);
+ glReadBuffer(GL_NONE);
+
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
+ GL_STENCIL_ATTACHMENT_EXT,
+ GL_TEXTURE_2D,
+ tex,
+ level);
+
+ status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ glDeleteFramebuffersEXT(1, &fb);
+ return false;
+ }
+
+ glEnable(GL_SCISSOR_TEST);
+
+ for (x = 0; x < size; x++) {
+ unsigned val = ((x + 0.5) / (size)) * 0xff;
+ glScissor(x, 0, 1, size);
+ glClearStencil(val);
+ glClear(GL_STENCIL_BUFFER_BIT);
+ }
+
+ glDisable(GL_SCISSOR_TEST);
+
+ glDeleteFramebuffersEXT(1, &fb);
+
+ glDrawBuffer(draw_buffer);
+ glReadBuffer(read_buffer);
+ assert(glGetError() == 0);
+
+ return true;
+}
+
+static bool
create_tex(GLenum internalformat, GLenum baseformat)
{
GLuint tex;
@@ -220,8 +263,13 @@ create_tex(GLenum internalformat, GLenum baseformat)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
- if (baseformat == GL_DEPTH_COMPONENT ||
- baseformat == GL_DEPTH_STENCIL) {
+ if (clear_stencil) {
+ if (!do_stencil_clear(format, tex, level, dim)) {
+ glDeleteTextures(1, &tex);
+ return 0;
+ }
+ } else if (baseformat == GL_DEPTH_COMPONENT ||
+ baseformat == GL_DEPTH_STENCIL) {
if (!do_depth_clear(format, tex, level, dim)) {
glDeleteTextures(1, &tex);
return 0;
@@ -244,9 +292,6 @@ create_tex(GLenum internalformat, GLenum baseformat)
static void
draw_mipmap(int x, int y, int dim)
{
- glViewport(0, 0, piglit_width, piglit_height);
- piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
-
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
@@ -258,6 +303,51 @@ draw_mipmap(int x, int y, int dim)
glDisable(GL_TEXTURE_2D);
}
+static void
+draw_stencil_mipmap(int x, int y, int dim, GLuint tex, GLuint level)
+{
+ GLuint fbo;
+ GLint draw_buffer, read_buffer;
+
+ glGetIntegerv(GL_DRAW_BUFFER, &draw_buffer);
+ glGetIntegerv(GL_READ_BUFFER, &read_buffer);
+
+ glGenFramebuffers(1, &fbo);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
+
+ glDrawBuffer(GL_NONE);
+ glReadBuffer(GL_NONE);
+
+ glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+ GL_TEXTURE_2D, tex, level);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+ glBlitFramebuffer(0, 0, dim, dim, x, y, x+dim, y+dim,
+ GL_STENCIL_BUFFER_BIT, GL_NEAREST);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glDeleteFramebuffers(1, &fbo);
+
+ glDrawBuffer(draw_buffer);
+ glReadBuffer(read_buffer);
+
+ assert(glGetError() == 0);
+}
+
+static void
+visualize_stencil()
+{
+ unsigned i;
+
+ glEnable(GL_STENCIL_TEST);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ for (i = 0; i <= 0xff; i++) {
+ glStencilFunc(GL_EQUAL, i, ~0);
+ glColor4ub(i, i, i, 255);
+ piglit_draw_rect(0, 0, piglit_width, piglit_height);
+ }
+ glDisable(GL_STENCIL_TEST);
+ glColor4ub(255, 255, 255, 255);
+}
+
static GLboolean
test_mipmap_drawing(int x, int y, int dim, int level, GLuint internalformat)
{
@@ -414,17 +504,41 @@ test_format(const struct format_desc *format)
GLboolean pass = GL_TRUE;
printf("Testing %s", format->name);
- tex = create_tex(format->internalformat, format->base_internal_format);
- if (tex == 0)
+ if (clear_stencil && format->base_internal_format != GL_DEPTH_STENCIL) {
+ printf(" - no stencil.\n");
return PIGLIT_SKIP;
+ }
+
+ tex = create_tex(format->internalformat, format->base_internal_format);
+ if (tex == 0) {
+ printf(" - FBO incomplete\n");
+ return PIGLIT_SKIP;
+ }
+ printf("\n");
+
+ if (clear_stencil) {
+ glClearStencil(0x0);
+ glClear(GL_STENCIL_BUFFER_BIT);
+ }
+
+ glViewport(0, 0, piglit_width, piglit_height);
+ piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
x = 1;
+ level = 0;
for (dim = TEX_WIDTH; dim > 1; dim /= 2) {
- draw_mipmap(x, 1, dim);
+ if (clear_stencil)
+ draw_stencil_mipmap(x, 1, dim, tex, level);
+ else
+ draw_mipmap(x, 1, dim);
x += dim + 1;
+ level++;
}
+ if (clear_stencil)
+ visualize_stencil();
+
x = 1;
level = 0;
for (dim = TEX_WIDTH; dim > 1; dim /= 2) {
@@ -446,5 +560,11 @@ enum piglit_result piglit_display(void)
void piglit_init(int argc, char **argv)
{
- fbo_formats_init(argc, argv, GL_TRUE);
+ if (argc == 3 && strcmp(argv[2], "stencil") == 0)
+ clear_stencil = true;
+
+ if (clear_stencil)
+ piglit_require_extension("GL_ARB_framebuffer_object");
+
+ fbo_formats_init(clear_stencil ? 2 : argc, argv, GL_TRUE);
}
--
1.7.9.5
More information about the Piglit
mailing list