summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2014-12-04 12:51:46 +0200
committerFrancisco Jerez <currojerez@riseup.net>2015-02-03 19:10:57 +0200
commit4db5cbf03832dedeb1f7cbf70f3c3745cf9d3a66 (patch)
treea5a34f39e33bb02b499acc797b013a291ab8342f
parenta6ffc0ef5945cb6499dde4c814efc96b5583f09e (diff)
arb_shader_image_load_store: Import tests for layered and unlayered binding.
Test binding of individual layers from a layered texture and the simultaneous binding of all layers (layered binding). For textures targets that don't have multiple layers we just test that the layered and unlayered binding modes have no effect as required by the spec.
-rw-r--r--tests/all.py1
-rw-r--r--tests/spec/arb_shader_image_load_store/CMakeLists.gl.txt1
-rw-r--r--tests/spec/arb_shader_image_load_store/layer.c221
3 files changed, 223 insertions, 0 deletions
diff --git a/tests/all.py b/tests/all.py
index f233fe67b..85f58e9d7 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -4439,6 +4439,7 @@ arb_shader_image_load_store['early-z'] = PiglitGLTest(['arb_shader_image_load_st
arb_shader_image_load_store['host-mem-barrier'] = PiglitGLTest(['arb_shader_image_load_store-host-mem-barrier'], run_concurrent=True)
arb_shader_image_load_store['indexing'] = PiglitGLTest(['arb_shader_image_load_store-indexing'], run_concurrent=True)
arb_shader_image_load_store['invalid'] = PiglitGLTest(['arb_shader_image_load_store-invalid'], run_concurrent=True)
+arb_shader_image_load_store['layer'] = PiglitGLTest(['arb_shader_image_load_store-layer'], run_concurrent=True)
profile.tests['hiz'] = hiz
profile.tests['fast_color_clear'] = fast_color_clear
diff --git a/tests/spec/arb_shader_image_load_store/CMakeLists.gl.txt b/tests/spec/arb_shader_image_load_store/CMakeLists.gl.txt
index 6139e58d8..2dfdccff8 100644
--- a/tests/spec/arb_shader_image_load_store/CMakeLists.gl.txt
+++ b/tests/spec/arb_shader_image_load_store/CMakeLists.gl.txt
@@ -20,5 +20,6 @@ piglit_add_executable(arb_shader_image_load_store-early-z early-z.c ${depends})
piglit_add_executable(arb_shader_image_load_store-host-mem-barrier host-mem-barrier.c ${depends})
piglit_add_executable(arb_shader_image_load_store-indexing indexing.c ${depends})
piglit_add_executable(arb_shader_image_load_store-invalid invalid.c ${depends})
+piglit_add_executable(arb_shader_image_load_store-layer layer.c ${depends})
# vim: ft=cmake:
diff --git a/tests/spec/arb_shader_image_load_store/layer.c b/tests/spec/arb_shader_image_load_store/layer.c
new file mode 100644
index 000000000..8cf26736d
--- /dev/null
+++ b/tests/spec/arb_shader_image_load_store/layer.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2014 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 layer.c
+ *
+ * The spec defines two different image unit binding modes for
+ * textures with multiple layers, depending on the "layered" parameter
+ * of glBindImageTexture():
+ *
+ * "If <layered> is TRUE, the entire level is bound. If <layered> is
+ * FALSE, only the single layer identified by <layer> will be bound.
+ * When <layered> is FALSE, the single bound layer is treated as a
+ * different texture target for image accesses:
+ *
+ * * one-dimensional array texture layers are treated as one-dimensional
+ * textures;
+ *
+ * * two-dimensional array, three-dimensional, cube map, cube map array
+ * texture layers are treated as two-dimensional textures; and
+ *
+ * * two-dimensional multisample array textures are treated as
+ * two-dimensional multisample textures."
+ *
+ * We check that this is the case by binding a texture of each target
+ * in layered or unlayered mode and then dumping all the accessible
+ * contents of the texture to the framebuffer from a fragment shader.
+ * After each individual texel is read its old contents are
+ * overwritten by the shader.
+ *
+ * For textures that don't have multiple layers we check that the
+ * described process reads and subsequently overwrites the full
+ * texture contents regardless of the values of the layered and layer
+ * parameters, since according to the spec:
+ *
+ * "If the texture identified by <texture> does not have multiple
+ * layers or faces, the entire texture level is bound, regardless of
+ * the values specified by <layered> and <layer>."
+ */
+
+#include "common.h"
+
+/** Window width. */
+#define W 16
+
+/** Window height. */
+#define H 96
+
+/** Total number of pixels in the window and image. */
+#define N (W * H)
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+config.supports_gl_core_version = 32;
+
+config.window_width = W;
+config.window_height = H;
+config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static bool
+init_image(const struct image_info img, bool layered, unsigned l)
+{
+ uint32_t pixels[4 * N];
+ unsigned i;
+ bool ret;
+
+ for (i = 0; i < 4 * N; ++i)
+ pixels[i] = encode(img.format, i);
+
+ ret = upload_image(img, 0, pixels);
+
+ glBindImageTexture(0, get_texture(0), 0, layered, l,
+ GL_READ_WRITE, img.format->format);
+
+ return ret && piglit_check_gl_error(GL_NO_ERROR);
+}
+
+static bool
+check(const struct grid_info grid, const struct image_info img, unsigned l)
+{
+ const unsigned layer_sz = 4 * product(grid.size);
+ uint32_t pixels_fb[4 * N], expect_fb[4 * N];
+ uint32_t pixels_img[4 * N], expect_img[4 * N];
+ unsigned i;
+
+ if (!download_result(grid, pixels_fb) ||
+ !download_image(img, 0, pixels_img))
+ return false;
+
+ for (i = 0; i < layer_sz; ++i) {
+ /*
+ * The framebuffer contents should reflect layer l of
+ * the image which is bound to the image unit.
+ */
+ expect_fb[i] = encode(grid.format, layer_sz * l + i);
+ }
+
+ for (i = 0; i < 4 * N; ++i) {
+ if (i / layer_sz == l) {
+ /*
+ * Layer l should have been modified by the
+ * shader.
+ */
+ expect_img[i] = encode(img.format, 33);
+ } else {
+ /*
+ * Other layers should have remained
+ * unchanged.
+ */
+ expect_img[i] = encode(img.format, i);
+ }
+ }
+
+ if (!check_pixels_v(image_info_for_grid(grid), pixels_fb, expect_fb)) {
+ printf(" Source: framebuffer\n");
+ return false;
+ }
+
+ if (!check_pixels_v(img, pixels_img, expect_img)) {
+ printf(" Source: image\n");
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * If \a layered is false, bind an individual layer of a texture to an
+ * image unit, read its contents and write back a different value to
+ * the same location. If \a layered is true or the texture has a
+ * single layer, the whole texture will be read and written back.
+ *
+ * For textures with a single layer, the arguments \a layered and \a
+ * layer which are passed to the same arguments of
+ * glBindImageTexture() should have no effect as required by the spec.
+ */
+static bool
+run_test(const struct image_target_info *target,
+ bool layered, unsigned layer)
+{
+ const struct image_info real_img = image_info(
+ target->target, GL_RGBA32F, W, H);
+ const unsigned slices = (layered ? 1 : image_num_layers(real_img));
+ /*
+ * "Slice" of the image that will be bound to the pipeline.
+ */
+ const struct image_info slice_img = image_info(
+ (layered ? target->target : image_layer_target(target)),
+ GL_RGBA32F, W, H / slices);
+ /*
+ * Grid with as many elements as the slice.
+ */
+ const struct grid_info grid = grid_info(
+ GL_FRAGMENT_SHADER, GL_RGBA32F, W, H / slices);
+ GLuint prog = generate_program(
+ grid, GL_FRAGMENT_SHADER,
+ concat(image_hunk(slice_img, ""),
+ hunk("uniform IMAGE_T img;\n"
+ "\n"
+ "GRID_T op(ivec2 idx, GRID_T x) {\n"
+ " GRID_T v = imageLoad(img, IMAGE_ADDR(idx));\n"
+ " imageStore(img, IMAGE_ADDR(idx), DATA_T(33));\n"
+ " return v;\n"
+ "}\n"), NULL));
+ bool ret = prog && init_fb(grid) &&
+ init_image(real_img, layered, layer) &&
+ set_uniform_int(prog, "img", 0) &&
+ draw_grid(grid, prog) &&
+ check(grid, real_img, (slices == 1 ? 0 : layer));
+
+ glDeleteProgram(prog);
+ return ret;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+ enum piglit_result status = PIGLIT_PASS;
+ const struct image_target_info *target;
+
+ piglit_require_extension("GL_ARB_shader_image_load_store");
+
+ for (target = image_targets(); target->name; ++target) {
+ subtest(&status, true,
+ run_test(target, false, 5),
+ "image%s/non-layered binding test", target->name);
+
+ subtest(&status, true,
+ run_test(target, true, 5),
+ "image%s/layered binding test", target->name);
+ }
+
+ piglit_report_result(status);
+}
+
+enum piglit_result
+piglit_display(void)
+{
+ return PIGLIT_FAIL;
+}