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

_______________________________________________
Piglit mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/piglit

Reply via email to