ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / arb_shader_image_load_store / restrict.c
blob0017dac879b5dd95227bb34ad744141f36793767
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 restrict.c
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
38 * meaningful.
41 #include "common.h"
43 /** Window width. */
44 #define W 16
46 /** Window height. */
47 #define H 96
49 /** Total number of pixels in the window and image. */
50 #define N (W * H)
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 {
64 /** Test name. */
65 const char *name;
67 /** Image qualifier keyword. */
68 const char *qualifier;
70 /** Informative "control" test whose result is ignored. */
71 bool control_test;
74 const struct image_qualifier_info image_qualifiers[] = {
75 { "no qualifier", "", false },
76 { "restrict qualifier", "restrict", true },
77 { 0 }
80 char *
81 qualifier_hunk(const struct image_qualifier_info *qual)
83 char *s = NULL;
85 (void)!asprintf(&s, "#define IMAGE_Q %s\n", qual->qualifier);
86 return s;
89 static bool
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);
98 static bool
99 check(const struct image_info img)
101 uint32_t pixels[N];
102 uint32_t expect[N];
103 int i;
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);
112 static bool
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(
120 grid,
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.
129 GL_FRAGMENT_SHADER,
130 concat(qualifier_hunk(qual),
131 image_hunk(img, ""),
132 hunk("IMAGE_Q IMAGE_UNIFORM_T src_img;\n"
133 "IMAGE_Q IMAGE_UNIFORM_T dst_img;\n"
134 "\n"
135 "GRID_T op(ivec2 idx, GRID_T x) {\n"
136 " int i;\n"
137 "\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"
143 " }\n"
144 "\n"
145 " return x;\n"
146 "}\n"), NULL));
147 bool ret = prog &&
148 init_fb(grid) &&
149 init_image(img) &&
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);
156 return ret;
159 void
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);
176 enum piglit_result
177 piglit_display(void)
179 return PIGLIT_FAIL;