[Piglit] [PATCH v2 2/2] framebuffer-blit-levels: Test stencil buffers.
Paul Berry
stereotype441 at gmail.com
Fri Sep 14 14:48:30 PDT 2012
This patch modifies framebuffer-blit-levels to test that blitting
between miplevels of the stencil portion of a depth/stencil texture
works properly. This is an important corner case for Mesa's i965
driver.
Note that stencil data can't be uploaded to a texture directly using
glTexImage2D(). It must be converted into a combined depth/stencil
format first.
---
tests/all.tests | 2 +-
.../framebuffer-blit-levels.c | 111 ++++++++++++++++++---
2 files changed, 99 insertions(+), 14 deletions(-)
diff --git a/tests/all.tests b/tests/all.tests
index 6f9982b..5f99fb2 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -1165,7 +1165,7 @@ spec['ARB_framebuffer_object'] = arb_framebuffer_object
add_concurrent_test(arb_framebuffer_object, 'same-attachment-glFramebufferTexture2D-GL_DEPTH_STENCIL_ATTACHMENT')
add_concurrent_test(arb_framebuffer_object, 'same-attachment-glFramebufferRenderbuffer-GL_DEPTH_STENCIL_ATTACHMENT')
add_plain_test(arb_framebuffer_object, 'fdo28551')
-for format in ('rgba', 'depth'):
+for format in ('rgba', 'depth', 'stencil'):
for test_mode in ('draw', 'read'):
test_name = ' '.join(['framebuffer-blit-levels', test_mode, format])
arb_framebuffer_object[test_name] = PlainExecTest(test_name + ' -auto')
diff --git a/tests/spec/arb_framebuffer_object/framebuffer-blit-levels.c b/tests/spec/arb_framebuffer_object/framebuffer-blit-levels.c
index c605eba..4e734ff 100644
--- a/tests/spec/arb_framebuffer_object/framebuffer-blit-levels.c
+++ b/tests/spec/arb_framebuffer_object/framebuffer-blit-levels.c
@@ -125,16 +125,78 @@ create_test_data_depth(GLfloat *data, unsigned level,
}
}
+/**
+ * Generate a block of test data appropriate for testing a stencil
+ * buffer. Different values of the \c level parameter produce
+ * different unique sets of pixels.
+ *
+ * Since there are only 256 possible stencil values, we need to be
+ * clever to generate a pattern that doesn't repeat every 256 pixels.
+ * Here's how we do it: for each consecutive pair of values, we
+ * compute x = (16451 * (i + 1)) % 65521 (where i is the index of the
+ * pair, and starts at a different value for each miplevel). Since
+ * 16451 and 65521 are relatively prime, this pattern won't repeat for
+ * 65521 pairs. Then we set the first pixel in the pair to x / 256
+ * and the second pixel in the pair to x % 256.
+ */
+static void
+create_test_data_stencil(GLbyte *data, unsigned level,
+ unsigned width, unsigned height)
+{
+ unsigned pixel;
+ unsigned num_pixels = width * height;
+ for (pixel = 0; pixel < num_pixels; ++pixel) {
+ unsigned i = (level * (SIZE * SIZE) + pixel) / 2;
+ unsigned x = (16451 * (i + 1)) % 65521;
+ if (pixel % 2 == 0)
+ data[pixel] = x / 256;
+ else
+ data[pixel] = x % 256;
+ }
+}
+
+/**
+ * As with create_test_data_stencil(), but intersperse the stencil
+ * data with depth values of 0, so that the resulting data can be
+ * uploaded to a depth/stencil texture using glTexImage2D().
+ */
+static void
+create_test_data_depthstencil(GLbyte *data, unsigned level,
+ unsigned width, unsigned height)
+{
+ GLbyte *stencil_data = malloc(width * height);
+ unsigned i;
+ create_test_data_stencil(stencil_data, level, width, height);
+
+ for (i = 0; i < width * height; ++i) {
+ data[4 * i] = stencil_data[i];
+ data[4 * i + 1] = 0;
+ data[4 * i + 2] = 0;
+ data[4 * i + 3] = 0;
+ }
+
+ free(stencil_data);
+}
+
static void
create_test_data(GLfloat *data, GLenum texture_format,
unsigned level, unsigned width, unsigned height)
{
- if (texture_format == GL_RGBA)
+ switch (texture_format) {
+ case GL_RGBA:
create_test_data_rgba(data, level, width, height);
- else if (texture_format == GL_DEPTH_COMPONENT)
+ break;
+ case GL_DEPTH_COMPONENT:
create_test_data_depth(data, level, width, height);
- else
+ break;
+ case GL_DEPTH_STENCIL:
+ create_test_data_stencil((GLbyte *) data, level,
+ width, height);
+ break;
+ default:
assert(0);
+ break;
+ }
}
static void
@@ -146,7 +208,8 @@ print_usage_and_exit(char *prog_name)
" read: test blitting *from* the given texture type\n"
" where <format> is one of:\n"
" rgba\n"
- " depth\n",
+ " depth\n"
+ " stencil\n",
prog_name);
piglit_report_result(PIGLIT_FAIL);
}
@@ -180,6 +243,12 @@ piglit_init(int argc, char **argv)
texture_type = GL_FLOAT;
framebuffer_attachment = GL_DEPTH_ATTACHMENT;
blit_mask = GL_DEPTH_BUFFER_BIT;
+ } else if (strcmp(argv[2], "stencil") == 0) {
+ texture_internal_format = GL_DEPTH_STENCIL;
+ texture_format = GL_DEPTH_STENCIL;
+ texture_type = GL_UNSIGNED_INT_24_8;
+ framebuffer_attachment = GL_DEPTH_STENCIL_ATTACHMENT;
+ blit_mask = GL_STENCIL_BUFFER_BIT;
} else {
print_usage_and_exit(argv[0]);
}
@@ -239,7 +308,13 @@ upload_test_data(GLuint texture, unsigned data_level,
glBindTexture(GL_TEXTURE_2D, texture);
- create_test_data(data, texture_format, data_level, width, height);
+ if (texture_format == GL_DEPTH_STENCIL) {
+ create_test_data_depthstencil((GLbyte *) data, data_level,
+ width, height);
+ } else {
+ create_test_data(data, texture_format, data_level,
+ width, height);
+ }
glTexImage2D(GL_TEXTURE_2D, upload_level, texture_internal_format,
width, height, 0 /* border */, texture_format,
@@ -248,6 +323,18 @@ upload_test_data(GLuint texture, unsigned data_level,
free(data);
}
+static bool
+test_image(unsigned width, unsigned height, const GLfloat *expected)
+{
+ if (texture_format == GL_DEPTH_STENCIL) {
+ return piglit_probe_image_stencil(0, 0, width, height,
+ (const GLubyte *) expected);
+ } else {
+ return piglit_probe_image_color(0, 0, width, height,
+ texture_format, expected);
+ }
+}
+
enum piglit_result
piglit_display()
{
@@ -261,11 +348,13 @@ piglit_display()
unsigned height = SIZE >> level;
if (test_mode == TEST_MODE_READ) {
/* Populate directly */
- upload_test_data(test_texture, level, level,
+ upload_test_data(test_texture,
+ level, level,
width, height);
} else {
/* Populate via aux texture */
- upload_test_data(aux_texture, level, 0,
+ upload_test_data(aux_texture,
+ level, 0,
width, height);
glBindFramebuffer(GL_READ_FRAMEBUFFER,
aux_framebuffer);
@@ -297,9 +386,7 @@ piglit_display()
GL_TEXTURE_2D,
test_texture,
level);
- pass = piglit_probe_image_color(0, 0, width, height,
- texture_format,
- data) && pass;
+ pass = test_image(width, height, data) && pass;
} else {
/* Read via aux texture */
glBindFramebuffer(GL_READ_FRAMEBUFFER,
@@ -322,9 +409,7 @@ piglit_display()
blit_mask, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER,
aux_framebuffer);
- pass = piglit_probe_image_color(0, 0, width, height,
- texture_format,
- data) && pass;
+ pass = test_image(width, height, data) && pass;
}
}
--
1.7.12
More information about the Piglit
mailing list