fbo-mrt-alphatest: Actually require MRTs to be available.
[piglit.git] / tests / spec / arb_shader_image_load_store / layer.c
blobc587ce6894d6479af707325e85bf31794af1ae95
1 /*
2 * Copyright (C) 2014 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
24 /** @file layer.c
26 * The spec defines two different image unit binding modes for
27 * textures with multiple layers, depending on the "layered" parameter
28 * of glBindImageTexture():
30 * "If <layered> is TRUE, the entire level is bound. If <layered> is
31 * FALSE, only the single layer identified by <layer> will be bound.
32 * When <layered> is FALSE, the single bound layer is treated as a
33 * different texture target for image accesses:
35 * * one-dimensional array texture layers are treated as one-dimensional
36 * textures;
38 * * two-dimensional array, three-dimensional, cube map, cube map array
39 * texture layers are treated as two-dimensional textures; and
41 * * two-dimensional multisample array textures are treated as
42 * two-dimensional multisample textures."
44 * We check that this is the case by binding a texture of each target
45 * in layered or unlayered mode and then dumping all the accessible
46 * contents of the texture to the framebuffer from a fragment shader.
47 * After each individual texel is read its old contents are
48 * overwritten by the shader.
50 * For textures that don't have multiple layers we check that the
51 * described process reads and subsequently overwrites the full
52 * texture contents regardless of the values of the layered and layer
53 * parameters, since according to the spec:
55 * "If the texture identified by <texture> does not have multiple
56 * layers or faces, the entire texture level is bound, regardless of
57 * the values specified by <layered> and <layer>."
60 #include "common.h"
62 /** Window width. */
63 #define W 16
65 /** Window height. */
66 #define H 96
68 /** Total number of pixels in the window and image. */
69 #define N (W * H)
71 PIGLIT_GL_TEST_CONFIG_BEGIN
73 config.supports_gl_core_version = 32;
75 config.window_width = W;
76 config.window_height = H;
77 config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA;
78 config.khr_no_error_support = PIGLIT_NO_ERRORS;
80 PIGLIT_GL_TEST_CONFIG_END
82 static bool
83 init_image(const struct image_info img, bool layered, unsigned l)
85 uint32_t pixels[4 * N];
86 unsigned i;
87 bool ret;
89 for (i = 0; i < 4 * N; ++i)
90 pixels[i] = encode(img.format, i);
92 ret = upload_image(img, 0, pixels);
94 glBindImageTexture(0, get_texture(0), 0, layered, l,
95 GL_READ_WRITE, img.format->format);
97 return ret && piglit_check_gl_error(GL_NO_ERROR);
100 static bool
101 check(const struct grid_info grid, const struct image_info img, unsigned l)
103 const unsigned layer_sz = 4 * product(grid.size);
104 uint32_t pixels_fb[4 * N], expect_fb[4 * N];
105 uint32_t pixels_img[4 * N], expect_img[4 * N];
106 unsigned i;
108 if (!download_result(grid, pixels_fb) ||
109 !download_image(img, 0, pixels_img))
110 return false;
112 for (i = 0; i < layer_sz; ++i) {
114 * The framebuffer contents should reflect layer l of
115 * the image which is bound to the image unit.
117 expect_fb[i] = encode(grid.format, layer_sz * l + i);
120 for (i = 0; i < 4 * N; ++i) {
121 if (i / layer_sz == l) {
123 * Layer l should have been modified by the
124 * shader.
126 expect_img[i] = encode(img.format, 33);
127 } else {
129 * Other layers should have remained
130 * unchanged.
132 expect_img[i] = encode(img.format, i);
136 if (!check_pixels_v(image_info_for_grid(grid), pixels_fb, expect_fb)) {
137 printf(" Source: framebuffer\n");
138 return false;
141 if (!check_pixels_v(img, pixels_img, expect_img)) {
142 printf(" Source: image\n");
143 return false;
146 return true;
150 * If \a layered is false, bind an individual layer of a texture to an
151 * image unit, read its contents and write back a different value to
152 * the same location. If \a layered is true or the texture has a
153 * single layer, the whole texture will be read and written back.
155 * For textures with a single layer, the arguments \a layered and \a
156 * layer which are passed to the same arguments of
157 * glBindImageTexture() should have no effect as required by the spec.
159 static bool
160 run_test(const struct image_target_info *target,
161 bool layered, unsigned layer)
163 const struct image_info real_img = image_info(
164 target->target, GL_RGBA32F, W, H);
165 const unsigned slices = (layered ? 1 : image_num_layers(real_img));
167 * "Slice" of the image that will be bound to the pipeline.
169 const struct image_info slice_img = image_info(
170 (layered ? target->target : image_layer_target(target)),
171 GL_RGBA32F, W, H / slices);
173 * Grid with as many elements as the slice.
175 const struct grid_info grid = grid_info(
176 GL_FRAGMENT_SHADER, GL_RGBA32F, W, H / slices);
177 GLuint prog = generate_program(
178 grid, GL_FRAGMENT_SHADER,
179 concat(image_hunk(slice_img, ""),
180 hunk("IMAGE_UNIFORM_T img;\n"
181 "\n"
182 "GRID_T op(ivec2 idx, GRID_T x) {\n"
183 " GRID_T v = imageLoad(img, IMAGE_ADDR(idx));\n"
184 " imageStore(img, IMAGE_ADDR(idx), DATA_T(33));\n"
185 " return v;\n"
186 "}\n"), NULL));
187 bool ret = prog && init_fb(grid) &&
188 init_image(real_img, layered, layer) &&
189 set_uniform_int(prog, "img", 0) &&
190 draw_grid(grid, prog) &&
191 check(grid, real_img, (slices == 1 ? 0 : layer));
193 glDeleteProgram(prog);
194 return ret;
197 void
198 piglit_init(int argc, char **argv)
200 enum piglit_result status = PIGLIT_PASS;
201 const struct image_target_info *target;
203 piglit_require_extension("GL_ARB_shader_image_load_store");
205 for (target = image_targets(); target->name; ++target) {
206 subtest(&status, true,
207 run_test(target, false, 5),
208 "image%s/non-layered binding test", target->name);
210 subtest(&status, true,
211 run_test(target, true, 5),
212 "image%s/layered binding test", target->name);
215 piglit_report_result(status);
218 enum piglit_result
219 piglit_display(void)
221 return PIGLIT_FAIL;