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 * Check that images work as expected up to the maximum texture size
27 * reported for each target.
32 PIGLIT_GL_TEST_CONFIG_BEGIN
34 config
.supports_gl_core_version
= 32;
36 config
.window_width
= 1;
37 config
.window_height
= 1;
38 config
.window_visual
= PIGLIT_GL_VISUAL_DOUBLE
| PIGLIT_GL_VISUAL_RGBA
;
39 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
41 PIGLIT_GL_TEST_CONFIG_END
44 init_image(const struct image_info img
, unsigned unit
)
46 const unsigned n
= image_num_components(img
.format
) * product(img
.size
);
47 uint32_t *pixels
= malloc(sizeof(uint32_t) * n
);
51 for (i
= 0; i
< n
; ++i
)
52 pixels
[i
] = (unit
== 0 ? encode(img
.format
, i
) : 0);
54 ret
= upload_image(img
, unit
, pixels
);
61 check(const struct image_info img
)
63 const unsigned n
= image_num_components(img
.format
) * product(img
.size
);
64 uint32_t *pixels
= malloc(sizeof(uint32_t) * n
);
65 uint32_t *expect
= malloc(sizeof(uint32_t) * n
);
69 for (i
= 0; i
< n
; ++i
)
70 expect
[i
] = encode(img
.format
, i
);
72 ret
= download_image(img
, 1, pixels
) &&
73 check_pixels_v(img
, pixels
, expect
);
81 run_test(const struct image_target_info
*target
,
82 const struct image_extent size
)
84 const struct grid_info grid
= {
85 GL_FRAGMENT_SHADER_BIT
,
86 get_image_format(GL_RGBA32F
),
87 image_optimal_extent(size
)
89 const struct image_info img
= {
90 target
, grid
.format
, size
,
91 image_format_epsilon(grid
.format
)
93 GLuint prog
= generate_program(
94 grid
, GL_FRAGMENT_SHADER
,
95 concat(image_hunk(img
, ""),
96 hunk("readonly IMAGE_UNIFORM_T src_img;\n"
97 "writeonly IMAGE_UNIFORM_T dst_img;\n"
99 "GRID_T op(ivec2 idx, GRID_T x) {\n"
100 " imageStore(dst_img, IMAGE_ADDR(idx),"
101 " imageLoad(src_img, IMAGE_ADDR(idx)));\n"
104 bool ret
= prog
&& init_fb(grid
) &&
105 init_image(img
, 0) &&
106 init_image(img
, 1) &&
107 set_uniform_int(prog
, "src_img", 0) &&
108 set_uniform_int(prog
, "dst_img", 1) &&
109 draw_grid(grid
, prog
) &&
112 glDeleteProgram(prog
);
116 static struct image_extent
117 get_test_extent(const struct image_target_info
*target
, unsigned d
)
119 const struct image_extent ls
= image_target_limits(target
);
120 const unsigned high
= ~0, low
= 8;
121 struct image_extent ext
;
124 for (i
= 0; i
< 4; ++i
)
125 set_idx(ext
, i
, MIN2(get_idx(ls
, i
), (i
== d
? high
: low
)));
127 if (target
->target
== GL_TEXTURE_CUBE_MAP
||
128 target
->target
== GL_TEXTURE_CUBE_MAP_ARRAY
) {
129 /* Cube maps have to be square and the number of faces
130 * should be a multiple of six. */
132 ext
.z
= 6 * MAX2(ext
.z
/ 6, 1);
134 } else if (image_target_samples(target
) > 1) {
135 /* Use the maximum number of samples to keep things
137 ext
.x
= image_target_samples(target
);
144 should_test_dimension(const struct image_target_info
*target
, int d
)
146 const struct image_extent ls
= image_target_limits(target
);
148 return get_idx(ls
, d
) > 1 &&
149 /* Skip second cube map dimension as faces have to be
151 !(target
->target
== GL_TEXTURE_CUBE_MAP
&& d
>= 1) &&
152 !(target
->target
== GL_TEXTURE_CUBE_MAP_ARRAY
&& d
== 1) &&
153 /* Skip sample dimension. */
154 !(image_target_samples(target
) > 1 && d
== 0);
158 is_test_reasonable(bool quick
, const struct image_extent size
)
160 /* Set an arbitrary limit on the number of texels so the test
161 * doesn't take forever. */
162 return product(size
) < (quick
? 4 : 64) * 1024 * 1024;
166 piglit_init(int argc
, char **argv
)
168 const bool quick
= (argc
>= 2 && !strcmp(argv
[1], "--quick"));
169 enum piglit_result status
= PIGLIT_PASS
;
170 const struct image_target_info
*target
;
173 piglit_require_extension("GL_ARB_shader_image_load_store");
175 for (target
= image_targets(); target
->name
; ++target
) {
176 for (d
= 0; d
< 4; ++d
) {
177 if (should_test_dimension(target
, d
)) {
178 const struct image_extent size
=
179 get_test_extent(target
, d
);
182 is_test_reasonable(quick
, size
),
183 run_test(target
, size
),
184 "image%s max size test/%dx%dx%dx%d",
186 size
.x
, size
.y
, size
.z
, size
.w
);
191 piglit_report_result(status
);