aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Worth <cworth@cworth.org>2012-12-21 17:15:39 -0800
committerCarl Worth <cworth@cworth.org>2013-01-14 11:38:26 -0800
commit1c186176f4602a61bed0de81feb5ef8c05384508 (patch)
treecec2f35163aaa322a9c0166ca28dba7378870dd5
parenta7bb55b683f979ef18a5c63f770bc51e4d809e5f (diff)
Add occlusion-query tests for various meta operations.
These tests invoke occlusion queries around the several meta-operations implemented within mesa. They are designed to demonstrate various bugs in the current implementation of mesa, (where meta operations either do or do not generate fragments as specified by the OpenGL specification). Reviewed-by: Eric Anholt <eric@anholt.net>
-rw-r--r--tests/all.tests2
-rw-r--r--tests/spec/arb_occlusion_query/CMakeLists.gl.txt2
-rw-r--r--tests/spec/arb_occlusion_query/occlusion_query_meta_fragments.c165
-rw-r--r--tests/spec/arb_occlusion_query/occlusion_query_meta_no_fragments.c205
4 files changed, 374 insertions, 0 deletions
diff --git a/tests/all.tests b/tests/all.tests
index 1c75cd33..b1180b1c 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -1013,6 +1013,8 @@ arb_occlusion_query = Group()
spec['ARB_occlusion_query'] = arb_occlusion_query
add_concurrent_test(arb_occlusion_query, 'occlusion_query')
add_concurrent_test(arb_occlusion_query, 'occlusion_query_lifetime')
+add_concurrent_test(arb_occlusion_query, 'occlusion_query_meta_fragments')
+add_concurrent_test(arb_occlusion_query, 'occlusion_query_meta_no_fragments')
add_concurrent_test(arb_occlusion_query, 'occlusion_query_order')
# Group ARB_sampler_objects
diff --git a/tests/spec/arb_occlusion_query/CMakeLists.gl.txt b/tests/spec/arb_occlusion_query/CMakeLists.gl.txt
index 0878f785..30fb5194 100644
--- a/tests/spec/arb_occlusion_query/CMakeLists.gl.txt
+++ b/tests/spec/arb_occlusion_query/CMakeLists.gl.txt
@@ -11,4 +11,6 @@ link_libraries (
piglit_add_executable (occlusion_query occlusion_query.c)
piglit_add_executable (occlusion_query_lifetime occlusion_query_lifetime.c)
+piglit_add_executable (occlusion_query_meta_no_fragments occlusion_query_meta_no_fragments.c)
+piglit_add_executable (occlusion_query_meta_fragments occlusion_query_meta_fragments.c)
piglit_add_executable (occlusion_query_order occlusion_query_order.c)
diff --git a/tests/spec/arb_occlusion_query/occlusion_query_meta_fragments.c b/tests/spec/arb_occlusion_query/occlusion_query_meta_fragments.c
new file mode 100644
index 00000000..50e57933
--- /dev/null
+++ b/tests/spec/arb_occlusion_query/occlusion_query_meta_fragments.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright © 2009,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.
+ *
+ * Authors:
+ * Ian Romanick <ian.d.romanick@intel.com>
+ * Carl Worth <cworth@cworth.org>
+ */
+
+/**
+ * \file occlusion_query_meta_fragments.c
+ *
+ * Verify that various operations, (potentially implemented as
+ * meta-operations within the OpenGL implementation), generate
+ * fragments as specified.
+ */
+
+#include "piglit-util-gl-common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_compat_version = 10;
+
+ config.window_width = 16;
+ config.window_height = 16;
+ config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_DEPTH;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static bool
+verify_fragments(GLuint query, const char *operation, int expected_fragments)
+{
+ GLint result;
+
+ glGetQueryObjectiv(query, GL_QUERY_RESULT, &result);
+
+ if (result == expected_fragments)
+ return true;
+
+ printf("Occlusion query for %s resulted in %d samples, (expected %d)\n",
+ operation, result, expected_fragments);
+ return false;
+}
+
+/* Draw several things that should generate fragments, each within an
+ * occlusion query. Then verify that each query returns a non-zero
+ * value.
+ */
+enum piglit_result
+piglit_display(void)
+{
+ /* 2x2 data: Red, Green, Blue, and White. */
+ float data[16] = { 1.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0,
+ 1.0, 1.0, 1.0 };
+ GLubyte bitmap[16] = { 0x5f, 0xff, 0xff, 0xff,
+ 0xAf, 0xff, 0xff, 0xff,
+ 0x5f, 0xff, 0xff, 0xff,
+ 0xAf, 0xff, 0xff, 0xff };
+ GLuint query;
+ int test_pass = 1;
+
+ piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
+
+ glClearColor(0.0, 1.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glGenQueries(1, &query);
+
+ /* Fragments for glDrawPixels
+ *
+ * Assuming one fragment per pixel based on:
+ *
+ * Rectangles of color, depth, and certain
+ * other values may be converted to fragments
+ * using the DrawPixels command. [OpenGL 3.0 § 3.7]
+ */
+ glBeginQuery(GL_SAMPLES_PASSED, query);
+ {
+ glRasterPos2i(2, 2);
+ glDrawPixels(2, 2, GL_RGB, GL_FLOAT, data);
+ }
+ glEndQuery(GL_SAMPLES_PASSED);
+ test_pass &= verify_fragments(query, "glDrawPixels", 4);
+
+ /* Fragments for glCopyPixels
+ *
+ * And here, CopyPixels is specified to behave
+ * identically to DrawPixels:
+ *
+ * The groups of elements so obtained are then
+ * written to the framebuffer just as if
+ * DrawPixels had been given width and height,
+ * beginning with final conversion of elements.
+ * [OpenGL 3.0 § 4.3.3]
+ */
+ glBeginQuery(GL_SAMPLES_PASSED, query);
+ {
+ glRasterPos2i(6, 2);
+ glCopyPixels(2, 2, 2, 2, GL_COLOR);
+ }
+ glEndQuery(GL_SAMPLES_PASSED);
+ test_pass &= verify_fragments(query, "glCopyPixels", 4);
+
+ /* Fragments for glBitmap.
+ *
+ * The specification implies very strongly that a bitmap
+ * should generate one fragment per set bit:
+ *
+ * Bitmaps are rectangles of zeros and ones
+ * specifying a particular pattern of frag-
+ * ments to be produced. [OpenGL 3.0 § 3.8]
+ */
+ glBeginQuery(GL_SAMPLES_PASSED, query);
+ {
+ glRasterPos2i(10, 2);
+ glColor4f(0.0, 0.0, 1.0, 0.0);
+ glBitmap(4, 4, 0, 0, 0, 0, bitmap);
+ }
+ glEndQuery(GL_SAMPLES_PASSED);
+ test_pass &= verify_fragments(query, "glBitmap", 8);
+
+ glDeleteQueries(1, &query);
+
+ piglit_present_results();
+
+ return test_pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+ GLint query_bits;
+
+ piglit_require_extension("GL_ARB_occlusion_query");
+
+ /* It is legal for a driver to support the query API but not have
+ * any query bits. I wonder how many applications actually check for
+ * this case...
+ */
+ glGetQueryiv(GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS,
+ & query_bits);
+ if (query_bits == 0) {
+ piglit_report_result(PIGLIT_SKIP);
+ }
+}
diff --git a/tests/spec/arb_occlusion_query/occlusion_query_meta_no_fragments.c b/tests/spec/arb_occlusion_query/occlusion_query_meta_no_fragments.c
new file mode 100644
index 00000000..33da98d4
--- /dev/null
+++ b/tests/spec/arb_occlusion_query/occlusion_query_meta_no_fragments.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright © 2009,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.
+ *
+ * Authors:
+ * Ian Romanick <ian.d.romanick@intel.com>
+ * Carl Worth <cworth@cworth.org>
+ */
+
+/**
+ * \file occlusion_query_meta_no_fragments.c
+ *
+ * Verify that various operations, (potentially implemented as
+ * meta-operations within the OpenGL implementation), do not generate
+ * fragments as specified.
+ */
+
+#include "piglit-util-gl-common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+ config.supports_gl_compat_version = 10;
+
+ config.window_width = 64;
+ config.window_height = 64;
+ config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_DEPTH;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static bool
+verify_no_fragments(GLuint query, const char *operation)
+{
+ GLint result;
+
+ glGetQueryObjectiv(query, GL_QUERY_RESULT, &result);
+
+ if (result != 0) {
+ printf("Occlusion query for %s resulted in %d samples, (expected 0)\n", operation, result);
+ return false;
+ }
+
+ return true;
+}
+
+/* Draw several things that should not generate fragments, each within
+ * an occlusion query. Then verify that each query returns 0.
+ */
+
+enum piglit_result
+piglit_display(void)
+{
+ /* 2x2 texture data: Red, Green, Blue, and White. */
+ float data[16] = { 1.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0,
+ 0.0, 0.0, 1.0,
+ 1.0, 1.0, 1.0 };
+ GLuint texture, texture_copy, fb;
+ GLuint query;
+ int test_pass = 1;
+
+ piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
+
+ glGenQueries(1, &query);
+ glGenTextures(1, &texture);
+ glGenTextures(1, &texture_copy);
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glGenFramebuffers(1, &fb);
+
+ /* No fragments for glClear
+ *
+ * Clear is specified to bypass most of the fragment pipeline:
+ *
+ * When Clear is called, the only per-fragment
+ * operations that are applied (if enabled) are
+ * the pixel ownership test, the scissor test,
+ * and dithering. [OpenGL 3.1 § 4.2.3]
+ */
+ glBeginQuery(GL_SAMPLES_PASSED, query);
+ {
+ glClearColor(0.0, 1.0, 0.0, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ }
+ glEndQuery(GL_SAMPLES_PASSED);
+ test_pass &= verify_no_fragments(query, "glClear");
+
+ /* No fragments for glGenerateMipmap
+ *
+ * This call does not affect the framebuffer, so
+ * should not generate any fragments. */
+ glBeginQuery(GL_SAMPLES_PASSED, query);
+ {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 2, 2, 0,
+ GL_RGB, GL_FLOAT, data);
+
+ glGenerateMipmap(GL_TEXTURE_2D);
+ }
+ glEndQuery(GL_SAMPLES_PASSED);
+ test_pass &= verify_no_fragments(query, "glGenerateMipmap");
+
+ /* No fragments for glBlitFramebuffer
+ *
+ * The specification could not be more clear:
+ *
+ * Blit operations bypass the fragment
+ * pipeline. [OpenGL 3.1 § 4.3]
+ */
+ glBeginQuery(GL_SAMPLES_PASSED, query);
+ {
+ glBindFramebuffer(GL_FRAMEBUFFER, fb);
+
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_2D,
+ texture,
+ 0);
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+ glBlitFramebuffer(0, 0, 2, 2,
+ 2, 2, 20, 20,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ }
+ glEndQuery(GL_SAMPLES_PASSED);
+ test_pass &= verify_no_fragments(query, "glBlitFramebuffer");
+
+ /* No fragments for glCopyTexImage
+ *
+ * This call does not affect the framebuffer, so
+ * should not generate any fragments. */
+ glBeginQuery(GL_SAMPLES_PASSED, query);
+ {
+ glBindTexture(GL_TEXTURE_2D, texture_copy);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,
+ 0, 0, 2, 2, 0);
+ }
+ glEndQuery(GL_SAMPLES_PASSED);
+ test_pass &= verify_no_fragments(query, "glCopyTexImage2D");
+
+ /* Paint the copied texture just ensure it worked. */
+ glEnable(GL_TEXTURE_2D);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ piglit_draw_rect_tex(22, 2, 18, 18, 0, 0, 1, 1);
+
+ /* No fragments for glCopyTexSubImage */
+ glBeginQuery(GL_SAMPLES_PASSED, query);
+ {
+ glBindTexture(GL_TEXTURE_2D, texture_copy);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
+ 1, 1, 0, 0, 1, 1);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ }
+ glEndQuery(GL_SAMPLES_PASSED);
+ test_pass &= verify_no_fragments(query, "glCopyTexImage2D");
+
+ /* Paint the copied texture so a user can see that it worked. */
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ piglit_draw_rect_tex(42, 2, 18, 18, 0, 0, 1, 1);
+
+ glDeleteQueries(1, &query);
+
+ piglit_present_results();
+
+ return test_pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+ GLint query_bits;
+
+ piglit_require_extension("GL_ARB_occlusion_query");
+
+ /* It is legal for a driver to support the query API but not have
+ * any query bits. I wonder how many applications actually check for
+ * this case...
+ */
+ glGetQueryiv(GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS,
+ & query_bits);
+ if (query_bits == 0) {
+ piglit_report_result(PIGLIT_SKIP);
+ }
+}