[Piglit] [PATCH] Test that glBlitFramebuffer works properly with nonzero miplevels.
Paul Berry
stereotype441 at gmail.com
Tue Aug 14 13:23:07 PDT 2012
This patch adds a test to verify the proper operation of
glBlitFramebuffer when blitting to and from miplevels other than zero.
---
tests/all.tests | 3 +
.../spec/arb_framebuffer_object/CMakeLists.gl.txt | 1 +
.../framebuffer-blit-levels.c | 250 ++++++++++++++++++++
3 files changed, 254 insertions(+), 0 deletions(-)
create mode 100644 tests/spec/arb_framebuffer_object/framebuffer-blit-levels.c
diff --git a/tests/all.tests b/tests/all.tests
index 9419e73..a03b904 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -1163,6 +1163,9 @@ 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 test_mode in ('draw', 'read'):
+ test_name = ' '.join(['framebuffer-blit-levels', test_mode])
+ arb_framebuffer_object[test_name] = PlainExecTest(test_name + ' -auto')
# Group ARB_sampler_objects
diff --git a/tests/spec/arb_framebuffer_object/CMakeLists.gl.txt b/tests/spec/arb_framebuffer_object/CMakeLists.gl.txt
index 9764bf3..33b09c1 100644
--- a/tests/spec/arb_framebuffer_object/CMakeLists.gl.txt
+++ b/tests/spec/arb_framebuffer_object/CMakeLists.gl.txt
@@ -10,6 +10,7 @@ link_libraries (
${OPENGL_glu_LIBRARY}
)
+piglit_add_executable(framebuffer-blit-levels framebuffer-blit-levels.c)
piglit_add_executable(get-renderbuffer-internalformat get-renderbuffer-internalformat.c)
piglit_add_executable(same-attachment-glFramebufferTexture2D-GL_DEPTH_STENCIL_ATTACHMENT same-attachment-glFramebufferTexture2D-GL_DEPTH_STENCIL_ATTACHMENT.c)
piglit_add_executable(same-attachment-glFramebufferRenderbuffer-GL_DEPTH_STENCIL_ATTACHMENT same-attachment-glFramebufferRenderbuffer-GL_DEPTH_STENCIL_ATTACHMENT.c)
diff --git a/tests/spec/arb_framebuffer_object/framebuffer-blit-levels.c b/tests/spec/arb_framebuffer_object/framebuffer-blit-levels.c
new file mode 100644
index 0000000..31e0cf2
--- /dev/null
+++ b/tests/spec/arb_framebuffer_object/framebuffer-blit-levels.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/** \file framebuffer-blit-levels.c
+ *
+ * This test verifies that glBlitFramebuffer operates correctly when
+ * the read or draw framebuffer is bound to a nonzero miplevel of a
+ * texture.
+ *
+ * The test can be run in two modes: "read" and "draw". In "read"
+ * mode, the layered/mipmapped texture is attached to
+ * GL_READ_FRAMEBUFFER, and in "draw" mode, the layered/mipmapped
+ * texture is attached to GL_DRAW_FRAMEBUFFER.
+ *
+ * The test operates as follows:
+ *
+ * - A 2D test texture is created with all miplevels present. An
+ * auxiliary 2D texture is also created which has a single miplevel.
+ *
+ * - The test texture is populated with a deterministic pattern of
+ * data. In "read" mode, this is done by simply uploading the data
+ * pattern using glTexImage2D. In "draw" mode, this is done by
+ * first uploading the data pattern to the auxiliary texture, and
+ * then blitting it to the test texture (this checks that blits work
+ * properly when GL_DRAW_FRAMEBUFFER is the test texture).
+ *
+ * - The data in the test texture is then verified. In "draw" mode,
+ * this is done by a direct call to glReadPixels(). In "read" mode,
+ * this is done by first blitting the data to the auxiliary texture,
+ * and then using glReadPixels() on the auxiliary texture (this
+ * checks that blits work properly when GL_READ_FRAMEBUFFER is the
+ * test texture).
+ */
+
+#include "piglit-util-gl-common.h"
+
+PIGLIT_GL_TEST_MAIN(
+ 32,
+ 32,
+ GLUT_RGBA);
+
+enum {
+ TEST_MODE_DRAW,
+ TEST_MODE_READ,
+} test_mode;
+
+GLuint test_framebuffer;
+GLuint aux_framebuffer;
+
+GLuint test_texture;
+GLuint aux_texture;
+
+#define LOG2_SIZE 7
+#define SIZE (1 << LOG2_SIZE)
+
+/**
+ * Generate a block of test data in which each pixel has a unique RGBA
+ * color. Different values of the \c level parameter produce
+ * different unique sets of pixels.
+ *
+ * This takes advantage of the Chinese Remainder Theorem to produce a
+ * unique color for each pixel--we produce the R, G, B, and A values
+ * by taking an integer mod four different primes.
+ */
+static void
+create_test_data(GLfloat *data, unsigned level,
+ unsigned width, unsigned height)
+{
+ unsigned pixel;
+ unsigned num_pixels = width * height;
+ for (pixel = 0; pixel < num_pixels; ++pixel) {
+ unsigned unique_value = level * (SIZE * SIZE) + pixel;
+ data[4*pixel + 0] = (unique_value % 233) / 233.0;
+ data[4*pixel + 1] = (unique_value % 239) / 239.0;
+ data[4*pixel + 2] = (unique_value % 241) / 241.0;
+ data[4*pixel + 3] = (unique_value % 251) / 251.0;
+ }
+}
+
+static void
+print_usage_and_exit(char *prog_name)
+{
+ printf("Usage: %s <test_mode>\n"
+ " where <test_mode> is one of:\n"
+ " draw: test blitting *to* the given texture type\n"
+ " read: test blitting *from* the given texture type\n",
+ prog_name);
+ piglit_report_result(PIGLIT_FAIL);
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+ unsigned level;
+
+ if (argc != 2) {
+ print_usage_and_exit(argv[0]);
+ }
+
+ if (strcmp(argv[1], "draw") == 0) {
+ test_mode = TEST_MODE_DRAW;
+ } else if (strcmp(argv[1], "read") == 0) {
+ test_mode = TEST_MODE_READ;
+ } else {
+ print_usage_and_exit(argv[0]);
+ }
+
+ piglit_require_extension("GL_ARB_framebuffer_object");
+
+ /* Set up test framebuffer and test texture, but don't
+ * populate with data yet.
+ */
+ glGenFramebuffers(1, &test_framebuffer);
+ glGenTextures(1, &test_texture);
+ glBindTexture(GL_TEXTURE_2D, test_texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
+ GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
+ GL_NEAREST);
+ for (level = 0; level < LOG2_SIZE; ++level) {
+ glTexImage2D(GL_TEXTURE_2D, level,
+ GL_RGBA, SIZE >> level, SIZE >> level,
+ 0 /* border */, GL_RGBA,
+ GL_BYTE /* type */, NULL /* data */);
+ }
+
+ /* Set up aux framebuffer */
+ glGenFramebuffers(1, &aux_framebuffer);
+ glGenTextures(1, &aux_texture);
+ glBindTexture(GL_TEXTURE_2D, aux_texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexImage2D(GL_TEXTURE_2D, 0 /* level */,
+ GL_RGBA, SIZE, SIZE,
+ 0 /* border */, GL_RGBA,
+ GL_BYTE /* type */, NULL /* data */);
+ glBindFramebuffer(GL_FRAMEBUFFER, aux_framebuffer);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, aux_texture, 0 /* level */);
+}
+
+enum piglit_result
+piglit_display()
+{
+ bool pass = true;
+ GLfloat *data = malloc(SIZE * SIZE * 4 * sizeof(GLfloat));
+ unsigned level;
+
+ /* Populate the test texture */
+ for (level = 0; level < LOG2_SIZE; ++level) {
+ unsigned width = SIZE >> level;
+ unsigned height = SIZE >> level;
+ create_test_data(data, level, width, height);
+ if (test_mode == TEST_MODE_READ) {
+ /* Populate directly */
+ glBindTexture(GL_TEXTURE_2D, test_texture);
+ glTexImage2D(GL_TEXTURE_2D, level,
+ GL_RGBA, width, height,
+ 0 /* border */, GL_RGBA,
+ GL_FLOAT /* type */, data);
+ } else {
+ /* Populate via aux texture */
+ glBindFramebuffer(GL_READ_FRAMEBUFFER,
+ aux_framebuffer);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER,
+ test_framebuffer);
+ glBindTexture(GL_TEXTURE_2D, aux_texture);
+ glTexImage2D(GL_TEXTURE_2D, 0 /* level */,
+ GL_RGBA, width, height,
+ 0 /* border */, GL_RGBA,
+ GL_FLOAT /* type */, data);
+ glBindTexture(GL_TEXTURE_2D, test_texture);
+ glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D,
+ test_texture,
+ level);
+ glBlitFramebuffer(0, 0, width, height,
+ 0, 0, width, height,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ }
+ }
+
+ /* Verify the test texture */
+ for (level = 0; level < LOG2_SIZE; ++level) {
+ unsigned width = SIZE >> level;
+ unsigned height = SIZE >> level;
+ printf("Testing level %d\n", level);
+ create_test_data(data, level, width, height);
+ if (test_mode == TEST_MODE_DRAW) {
+ /* Read texture data directly using glReadPixels() */
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, test_texture);
+ glFramebufferTexture2D(GL_READ_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D,
+ test_texture,
+ level);
+ pass = piglit_probe_image_rgba(0, 0, width, height,
+ data) && pass;
+ } else {
+ /* Read via aux texture */
+ glBindFramebuffer(GL_READ_FRAMEBUFFER,
+ test_framebuffer);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER,
+ aux_framebuffer);
+ glBindTexture(GL_TEXTURE_2D, test_texture);
+ glFramebufferTexture2D(GL_READ_FRAMEBUFFER,
+ GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D,
+ test_texture,
+ level);
+ glBindTexture(GL_TEXTURE_2D, aux_texture);
+ glTexImage2D(GL_TEXTURE_2D, 0 /* level */,
+ GL_RGBA, width, height,
+ 0 /* border */, GL_RGBA,
+ GL_BYTE /* type */, NULL);
+ glBlitFramebuffer(0, 0, width, height,
+ 0, 0, width, height,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER,
+ aux_framebuffer);
+ pass = piglit_probe_image_rgba(0, 0, width, height,
+ data) && pass;
+ }
+ }
+
+ free(data);
+
+ return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
--
1.7.7.6
More information about the Piglit
mailing list