static bool run_test(const struct image_qualifier_info *qual, const struct image_stage_info *stage_w, const struct image_stage_info *stage_r, unsigned l) { const struct grid_info grid = { stage_w->bit | stage_r->bit, get_image_format(GL_RGBA32UI), { l, l, 1, 1 } }; const struct image_info img = image_info_for_grid(grid); GLuint prog = generate_program( grid, /* * Write (11, 22, 33, 44) to some location on the * image from the write stage. */ stage_w->stage, concat(qualifier_hunk(qual), image_hunk(img, ""), hunk("IMAGE_Q uniform IMAGE_T img;\n" "\n" "GRID_T op(ivec2 idx, GRID_T x) {\n" " imageStore(img, idx, DATA_T(11, 22, 33, 44));" " return x;" "}\n"), NULL), /* * The same location will read back the expected value * if image access is coherent, as the shader inputs * of the read stage are dependent on the outputs of * the write stage and consequently they are * guaranteed to be executed sequentially. */ stage_r->stage, concat(qualifier_hunk(qual), image_hunk(img, ""), hunk("IMAGE_Q uniform IMAGE_T img;\n" "\n" "GRID_T op(ivec2 idx, GRID_T x) {\n" " DATA_T v = imageLoad(img, idx);" " if (v == DATA_T(11, 22, 33, 44))" " return GRID_T(33, 33, 33, 33);" " else" " return GRID_T(77, 77, 77, 77);" "}\n"), NULL)); bool ret = prog && init_fb(grid) && init_image(img) && set_uniform_int(prog, "img", 0) && draw_grid(grid, prog) && (check(grid, img) || qual->control_test); glDeleteProgram(prog); return ret; }
static bool run_test(const struct image_qualifier_info *qual) { const struct grid_info grid = grid_info(GL_FRAGMENT_SHADER, GL_R32UI, W, H); const struct image_info img = image_info(GL_TEXTURE_1D, GL_R32UI, W, H); GLuint prog = generate_program( grid, /** * Write to consecutive locations of an image using a * the value read from a fixed location of a different * image uniform which aliases the first image. If * the implementation incorrectly coalesces repeated * loads from the fixed location the results of the * test will be altered. */ GL_FRAGMENT_SHADER, concat(qualifier_hunk(qual), image_hunk(img, ""), hunk("IMAGE_Q IMAGE_UNIFORM_T src_img;\n" "IMAGE_Q IMAGE_UNIFORM_T dst_img;\n" "\n" "GRID_T op(ivec2 idx, GRID_T x) {\n" " int i;\n" "\n" " for (i = 0; i < N / 2; ++i) {\n" " imageStore(dst_img, 2 * i," " imageLoad(src_img, W) + 1u);\n" " imageStore(dst_img, 2 * i + 1," " imageLoad(src_img, W) - 1u);\n" " }\n" "\n" " return x;\n" "}\n"), NULL)); bool ret = prog && init_fb(grid) && init_image(img) && set_uniform_int(prog, "src_img", 0) && set_uniform_int(prog, "dst_img", 0) && draw_grid(set_grid_size(grid, 1, 1), prog) && (check(img) || qual->control_test); glDeleteProgram(prog); return ret; }