diff options
author | Francisco Jerez <currojerez@riseup.net> | 2015-01-31 18:11:35 +0200 |
---|---|---|
committer | Francisco Jerez <currojerez@riseup.net> | 2015-01-31 18:29:16 +0200 |
commit | d8827bf612d18b80f64577e495c429753f9f4f56 (patch) | |
tree | 2449071b8dcd2ccbb573c2e3efdd9302146a76a4 | |
parent | a91f318f05f3ab1f63cf930bd56342c1ed7faddf (diff) |
arb_shader_image_load_store: Import test for mipmap level binding.
Test that image loads and stores land in the correct mipmap level of
the texture when a level other than the first is bound to an image
unit.
-rw-r--r-- | tests/all.py | 1 | ||||
-rw-r--r-- | tests/spec/arb_shader_image_load_store/CMakeLists.gl.txt | 1 | ||||
-rw-r--r-- | tests/spec/arb_shader_image_load_store/level.c | 195 |
3 files changed, 197 insertions, 0 deletions
diff --git a/tests/all.py b/tests/all.py index 1550e8a51..ab5f02584 100644 --- a/tests/all.py +++ b/tests/all.py @@ -4435,6 +4435,7 @@ arb_shader_image_load_store['host-mem-barrier'] = PiglitGLTest(['arb_shader_imag 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) +arb_shader_image_load_store['level'] = PiglitGLTest(['arb_shader_image_load_store-level'], 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 2dfdccff8..990c3e03a 100644 --- a/tests/spec/arb_shader_image_load_store/CMakeLists.gl.txt +++ b/tests/spec/arb_shader_image_load_store/CMakeLists.gl.txt @@ -21,5 +21,6 @@ piglit_add_executable(arb_shader_image_load_store-host-mem-barrier host-mem-barr 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}) +piglit_add_executable(arb_shader_image_load_store-level level.c ${depends}) # vim: ft=cmake: diff --git a/tests/spec/arb_shader_image_load_store/level.c b/tests/spec/arb_shader_image_load_store/level.c new file mode 100644 index 000000000..5fbdbaf5c --- /dev/null +++ b/tests/spec/arb_shader_image_load_store/level.c @@ -0,0 +1,195 @@ +/* + * 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 level.c + * + * Test the binding of individual mipmap levels to an image unit by + * dumping the whole accessible contents of an image to the + * framebuffer and then checking that the observed values match the + * bound mipmap level. The same mipmap level is then overwritten by + * the shader program after its contents have been read. + */ + +#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) + +/** Maximum number of mipmap levels. */ +#define M 11 + +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, unsigned l) +{ + const unsigned num_levels = image_num_levels(img); + uint32_t pixels[4 * N * M]; + unsigned i; + + for (i = 0; i < 4 * N * num_levels; ++i) + pixels[i] = encode(img.format, i); + + return upload_image_levels(img, num_levels, l, 0, pixels); +} + +static bool +check_fb(const struct grid_info grid, const struct image_info img, unsigned l) +{ + const unsigned offset = 4 * image_level_offset(img, l); + const unsigned n = 4 * product(grid.size); + uint32_t pixels_fb[4 * N], expect_fb[4 * N]; + unsigned i; + + if (!download_result(grid, pixels_fb)) + return false; + + for (i = 0; i < n; ++i) { + /* + * The framebuffer contents should reflect level l of + * the image which is read by the shader program. + */ + expect_fb[i] = encode(grid.format, offset + i); + } + + if (!check_pixels_v(image_info_for_grid(grid), pixels_fb, expect_fb)) { + printf(" Source: framebuffer\n"); + return false; + } + + return true; +} + +static bool +check_img(const struct image_info img, unsigned l) +{ + const unsigned num_levels = image_num_levels(img); + uint32_t pixels_img[4 * N * M], expect_img[4 * N]; + unsigned i, j; + + if (!download_image_levels(img, num_levels, 0, pixels_img)) + return false; + + for (j = 0; j < num_levels; ++j) { + const struct image_info level_img = image_info_for_level(img, j); + const unsigned offset = 4 * image_level_offset(img, j); + const unsigned n = 4 * product(level_img.size); + + for (i = 0; i < n; ++i) { + if (j == l) { + /* + * Level l should have been modified + * by the shader. + */ + expect_img[i] = encode(img.format, 33); + } else { + /* + * Other levels should have remained + * unchanged. + */ + expect_img[i] = encode(img.format, offset + i); + } + } + + if (!check_pixels_v(level_img, &pixels_img[offset], + expect_img)) { + printf(" Source: image level %d\n", j); + return false; + } + } + + return true; +} + +/** + * Bind an individual level of a texture mipmap to an image unit, read + * its contents and write back a different value to the same location. + */ +static bool +run_test(const struct image_target_info *target) +{ + const unsigned level = 3; + const struct image_info img = image_info( + target->target, GL_RGBA32F, W, H); + const struct image_info level_img = image_info_for_level(img, level); + const struct grid_info grid = { + GL_FRAGMENT_SHADER_BIT, img.format, + image_optimal_extent(level_img.size) + }; + GLuint prog = generate_program( + grid, GL_FRAGMENT_SHADER, + concat(image_hunk(level_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(img, level) && + set_uniform_int(prog, "img", 0) && + draw_grid(grid, prog) && + check_fb(grid, img, level) && + check_img(img, level); + + 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) { + if (image_target_mipmapping_dimensions(target)) + subtest(&status, true, run_test(target), + "%s level binding test", target->name); + } + + piglit_report_result(status); +} + +enum piglit_result +piglit_display(void) +{ + return PIGLIT_FAIL; +} |