ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / arb_shader_image_load_store / semantics.c
blob4b2eaf6c1a579612d36b60e45db67336bda3dc64
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 semantics.c
26 * Test all allowed combinations of image targets, formats, built-in
27 * functions and shader stages. The test initializes an image to some
28 * arbitrary pattern and runs N invocations of a shader that calls the
29 * built-in function once on the corresponding location of the image.
30 * Then the same operation is simulated on the CPU and the results are
31 * compared with each other.
34 #include "common.h"
36 /** Window width. The actual width of the image varies with the image
37 * dimensionality, but the total number of pixels \a N remains
38 * invariant. */
39 #define W 16
41 /** Window height. */
42 #define H 96
44 /** Total number of pixels in the window and image. */
45 #define N (W * H)
47 PIGLIT_GL_TEST_CONFIG_BEGIN
49 config.supports_gl_core_version = 32;
51 config.window_width = W;
52 config.window_height = H;
53 config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA;
54 config.khr_no_error_support = PIGLIT_NO_ERRORS;
56 PIGLIT_GL_TEST_CONFIG_END
58 struct image_op_info {
59 /** Image built-in name. */
60 const char *name;
62 /** Allowed image formats. */
63 const struct image_format_info *formats;
65 /** Execute this image built-in on the CPU. */
66 void (*exec)(const struct image_format_info *format,
67 const uint32_t *arg, uint32_t *img, uint32_t *ret);
69 /** GLSL statement that invokes this image built-in. */
70 const char *hunk;
73 static void
74 image_exec_load(const struct image_format_info *format,
75 const uint32_t *arg, uint32_t *img, uint32_t *ret)
77 int i;
79 for (i = 0; i < image_num_components(format); ++i)
80 ret[i] = img[i];
83 static void
84 image_exec_store(const struct image_format_info *format,
85 const uint32_t *arg, uint32_t *img, uint32_t *ret)
87 int i;
89 for (i = 0; i < image_num_components(format); ++i)
90 img[i] = arg[i];
92 for (i = 0; i < 4; ++i)
93 ret[i] = 0;
96 static void
97 image_exec_add(const struct image_format_info *format,
98 const uint32_t *arg, uint32_t *img, uint32_t *ret)
100 ret[0] = img[0];
101 img[0] = encode(format, (decode(format, img[0]) +
102 decode(format, arg[0])));
105 static void
106 image_exec_min(const struct image_format_info *format,
107 const uint32_t *arg, uint32_t *img, uint32_t *ret)
109 ret[0] = img[0];
110 img[0] = encode(format, MIN2(decode(format, img[0]),
111 decode(format, arg[0])));
114 static void
115 image_exec_max(const struct image_format_info *format,
116 const uint32_t *arg, uint32_t *img, uint32_t *ret)
118 ret[0] = img[0];
119 img[0] = encode(format, MAX2(decode(format, img[0]),
120 decode(format, arg[0])));
123 static void
124 image_exec_and(const struct image_format_info *format,
125 const uint32_t *arg, uint32_t *img, uint32_t *ret)
127 ret[0] = img[0];
128 img[0] = img[0] & arg[0];
131 static void
132 image_exec_or(const struct image_format_info *format,
133 const uint32_t *arg, uint32_t *img, uint32_t *ret)
135 ret[0] = img[0];
136 img[0] = img[0] | arg[0];
139 static void
140 image_exec_xor(const struct image_format_info *format,
141 const uint32_t *arg, uint32_t *img, uint32_t *ret)
143 ret[0] = img[0];
144 img[0] = img[0] ^ arg[0];
147 static void
148 image_exec_exchange(const struct image_format_info *format,
149 const uint32_t *arg, uint32_t *img, uint32_t *ret)
151 ret[0] = img[0];
152 img[0] = arg[0];
155 static void
156 image_exec_comp_swap(const struct image_format_info *format,
157 const uint32_t *arg, uint32_t *img, uint32_t *ret)
159 ret[0] = img[0];
160 img[0] = (img[0] == encode(format, image_format_scale(format).x / N) ?
161 arg[0] : img[0]);
164 static const struct image_op_info image_ops[] = {
166 "imageLoad", image_formats_load_store, image_exec_load,
167 "GRID_T op(ivec2 idx, GRID_T x) {\n"
168 " return imageLoad(img, IMAGE_ADDR(idx));\n"
169 "}\n"
172 "imageStore", image_formats_load_store, image_exec_store,
173 "GRID_T op(ivec2 idx, GRID_T x) {\n"
174 " imageStore(img, IMAGE_ADDR(idx), arg(idx));\n"
175 " return GRID_T(0);"
176 "}\n"
179 "imageAtomicAdd", image_formats_atomic, image_exec_add,
180 "GRID_T op(ivec2 idx, GRID_T x) {\n"
181 " return GRID_T(imageAtomicAdd(img, IMAGE_ADDR(idx),"
182 " arg(idx).x),"
183 " 0, 0, 1);\n"
184 "}\n"
187 "imageAtomicMin", image_formats_atomic, image_exec_min,
188 "GRID_T op(ivec2 idx, GRID_T x) {\n"
189 " return GRID_T(imageAtomicMin(img, IMAGE_ADDR(idx),"
190 " arg(idx).x),"
191 " 0, 0, 1);\n"
192 "}\n"
195 "imageAtomicMax", image_formats_atomic, image_exec_max,
196 "GRID_T op(ivec2 idx, GRID_T x) {\n"
197 " return GRID_T(imageAtomicMax(img, IMAGE_ADDR(idx),"
198 " arg(idx).x),"
199 " 0, 0, 1);\n"
200 "}\n"
203 "imageAtomicAnd", image_formats_atomic, image_exec_and,
204 "GRID_T op(ivec2 idx, GRID_T x) {\n"
205 " return GRID_T(imageAtomicAnd(img, IMAGE_ADDR(idx),"
206 " arg(idx).x),"
207 " 0, 0, 1);\n"
208 "}\n"
211 "imageAtomicOr", image_formats_atomic, image_exec_or,
212 "GRID_T op(ivec2 idx, GRID_T x) {\n"
213 " return GRID_T(imageAtomicOr(img, IMAGE_ADDR(idx),"
214 " arg(idx).x),"
215 " 0, 0, 1);\n"
216 "}\n"
219 "imageAtomicXor", image_formats_atomic, image_exec_xor,
220 "GRID_T op(ivec2 idx, GRID_T x) {\n"
221 " return GRID_T(imageAtomicXor(img, IMAGE_ADDR(idx),"
222 " arg(idx).x),"
223 " 0, 0, 1);\n"
224 "}\n"
227 "imageAtomicExchange", image_formats_atomic, image_exec_exchange,
228 "GRID_T op(ivec2 idx, GRID_T x) {\n"
229 " return GRID_T(imageAtomicExchange(img, IMAGE_ADDR(idx),"
230 " arg(idx).x),"
231 " 0, 0, 1);\n"
232 "}\n"
235 "imageAtomicCompSwap", image_formats_atomic, image_exec_comp_swap,
236 "GRID_T op(ivec2 idx, GRID_T x) {\n"
237 " return GRID_T(imageAtomicCompSwap(img, IMAGE_ADDR(idx),"
238 " BASE_T(SCALE.x / N),"
239 " arg(idx).x),"
240 " 0, 0, 1);\n"
241 "}\n"
243 { 0 }
246 static bool
247 init_image_pixels(const struct image_info img, unsigned unit,
248 uint32_t *r_pixels)
250 const unsigned m = image_num_components(img.format);
251 unsigned i;
253 for (i = 0; i < m * N; ++i)
254 r_pixels[i] = encode(img.format,
255 get_idx(image_format_scale(img.format), i % m)
256 * (unit == 0 ? i : m * N - i) / (m * N));
258 return true;
261 static bool
262 init_image(const struct image_info img, unsigned unit)
264 uint32_t pixels[4 * N];
266 return init_image_pixels(img, unit, pixels) &&
267 upload_image(img, unit, pixels);
270 static bool
271 check(const struct image_op_info *op,
272 const struct grid_info grid,
273 const struct image_info img)
275 const struct image_info grid_img = {
276 get_image_target(GL_TEXTURE_2D),
277 grid.format, grid.size, img.epsilon
279 const unsigned m = image_num_components(img.format);
280 uint32_t pixels_fb[4 * N], expect_fb[4 * N];
281 uint32_t pixels_img[4 * N], expect_img[4 * N];
282 uint32_t arg[4 * N];
283 int i;
285 if (!download_result(grid, pixels_fb) ||
286 !download_image(img, 0, pixels_img))
287 return false;
289 /* Initialize the image and argument to the known state. */
290 init_image_pixels(img, 0, expect_img);
291 init_image_pixels(img, 1, arg);
292 init_pixels(grid_img, expect_fb, 0, 0, 0, 1);
294 /* Calculate the result of the image built-in. */
295 for (i = 0; i < N; ++i)
296 op->exec(img.format, &arg[m * i], &expect_img[m * i],
297 &expect_fb[4 * i]);
299 /* Check that the shader gave the same result. */
300 if (!check_pixels_v(grid_img, pixels_fb, expect_fb)) {
301 printf(" Source: framebuffer\n");
302 return false;
305 if (!check_pixels_v(img, pixels_img, expect_img)) {
306 printf(" Source: image\n");
307 return false;
310 return true;
313 static bool
314 run_test(const struct image_op_info *op,
315 const struct image_stage_info *stage,
316 const struct image_format_info *format,
317 const struct image_target_info *target)
319 const struct grid_info grid = grid_info(
320 stage->stage, image_base_internal_format(format), W, H);
321 const struct image_info img = image_info(
322 target->target, format->format, W, H);
323 GLuint prog = generate_program(
324 grid, stage->stage,
325 concat(image_hunk(img, ""),
326 hunk("IMAGE_UNIFORM_T img;\n"
327 "IMAGE_UNIFORM_T arg_img;\n"
328 "\n"
329 "GRID_T arg(ivec2 idx) {\n"
330 " return imageLoad(arg_img, IMAGE_ADDR(idx));\n"
331 "}\n"),
332 hunk(op->hunk), NULL));
333 bool ret = prog && init_fb(grid) &&
334 init_image(img, 0) &&
335 init_image(img, 1) &&
336 set_uniform_int(prog, "img", 0) &&
337 set_uniform_int(prog, "arg_img", 1) &&
338 draw_grid(grid, prog) &&
339 check(op, grid, img);
341 glDeleteProgram(prog);
342 return ret;
345 void
346 piglit_init(int argc, char **argv)
349 * If quick is enabled traverse each variable (stage, op,
350 * format and target) in sequence leaving the other ones fixed
351 * instead of going through the cartesian product of the four
352 * variables.
354 const bool quick = (argc >= 2 && !strcmp(argv[1], "--quick"));
355 enum piglit_result status = PIGLIT_PASS;
356 const struct image_stage_info *stage;
357 const struct image_op_info *op;
358 const struct image_format_info *format;
359 const struct image_target_info *target;
360 unsigned m = 0;
362 piglit_require_extension("GL_ARB_shader_image_load_store");
363 piglit_require_extension("GL_ARB_texture_cube_map_array");
365 for (op = image_ops; op->name; ++op) {
366 for (stage = image_stages(); stage->name; ++stage) {
367 for (format = op->formats; format->name; ++format) {
368 for (target = image_targets(); target->name; ++target) {
369 subtest(&status, true,
370 run_test(op, stage, format, target),
371 "%s/%s shader/%s/image%s test",
372 op->name, stage->name,
373 format->name, target->name);
375 if (quick && (m & 1))
376 break;
379 if (quick && ((m |= 1) & 2))
380 break;
383 if (quick && ((m |= 2) & 4))
384 break;
387 if (quick)
388 m |= 4;
391 piglit_report_result(status);
394 enum piglit_result
395 piglit_display(void)
397 return PIGLIT_FAIL;