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
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
26 * Test if the implementation is incorrectly assuming that different
27 * image uniforms point to disjoint locations in memory, which could lead
28 * to code reordering and access coalescing that could break valid GLSL
29 * programs. This is done by repeatedly reading and writing to an image
30 * through two different uniforms that alias the same image in a way that
31 * is likely to misrender if the implementation is coalescing loads.
33 * The same test is repeated with the "restrict" keyword which
34 * explicitly allows the implementation to make such assumptions. The
35 * rendering results from this test are ignored as it's only useful to
36 * test the "restrict" keyword and to find out if the implementation
37 * is making such transformations since otherwise the main test is not
49 /** Total number of pixels in the window and image. */
52 PIGLIT_GL_TEST_CONFIG_BEGIN
54 config
.supports_gl_core_version
= 32;
56 config
.window_width
= W
;
57 config
.window_height
= H
;
58 config
.window_visual
= PIGLIT_GL_VISUAL_DOUBLE
| PIGLIT_GL_VISUAL_RGBA
;
59 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
61 PIGLIT_GL_TEST_CONFIG_END
63 struct image_qualifier_info
{
67 /** Image qualifier keyword. */
68 const char *qualifier
;
70 /** Informative "control" test whose result is ignored. */
74 const struct image_qualifier_info image_qualifiers
[] = {
75 { "no qualifier", "", false },
76 { "restrict qualifier", "restrict", true },
81 qualifier_hunk(const struct image_qualifier_info
*qual
)
85 (void)!asprintf(&s
, "#define IMAGE_Q %s\n", qual
->qualifier
);
90 init_image(const struct image_info img
)
92 uint32_t pixels
[4 * N
];
94 return init_pixels(img
, pixels
, 1, 0, 0, 0) &&
95 upload_image(img
, 0, pixels
);
99 check(const struct image_info img
)
105 for (i
= 0; i
< N
; ++i
)
106 expect
[i
] = (i
> W
? 2 : 1) + (i
% 2 ? -1 : 1);
108 return download_image(img
, 0, pixels
) &&
109 check_pixels_v(img
, pixels
, expect
);
113 run_test(const struct image_qualifier_info
*qual
)
115 const struct grid_info grid
=
116 grid_info(GL_FRAGMENT_SHADER
, GL_R32UI
, W
, H
);
117 const struct image_info img
=
118 image_info(GL_TEXTURE_1D
, GL_R32UI
, W
, H
);
119 GLuint prog
= generate_program(
122 * Write to consecutive locations of an image using a
123 * the value read from a fixed location of a different
124 * image uniform which aliases the first image. If
125 * the implementation incorrectly coalesces repeated
126 * loads from the fixed location the results of the
127 * test will be altered.
130 concat(qualifier_hunk(qual
),
132 hunk("IMAGE_Q IMAGE_UNIFORM_T src_img;\n"
133 "IMAGE_Q IMAGE_UNIFORM_T dst_img;\n"
135 "GRID_T op(ivec2 idx, GRID_T x) {\n"
138 " for (i = 0; i < N / 2; ++i) {\n"
139 " imageStore(dst_img, 2 * i,"
140 " imageLoad(src_img, W) + 1u);\n"
141 " imageStore(dst_img, 2 * i + 1,"
142 " imageLoad(src_img, W) - 1u);\n"
150 set_uniform_int(prog
, "src_img", 0) &&
151 set_uniform_int(prog
, "dst_img", 0) &&
152 draw_grid(set_grid_size(grid
, 1, 1), prog
) &&
153 (check(img
) || qual
->control_test
);
155 glDeleteProgram(prog
);
160 piglit_init(int argc
, char **argv
)
162 const struct image_qualifier_info
*qual
;
163 enum piglit_result status
= PIGLIT_PASS
;
165 piglit_require_extension("GL_ARB_shader_image_load_store");
167 for (qual
= image_qualifiers
; qual
->name
; ++qual
) {
168 subtest(&status
, true, run_test(qual
),
169 "%s image aliasing test", qual
->name
);
173 piglit_report_result(status
);