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 the binding of individual mipmap levels to an image unit by
27 * dumping the whole accessible contents of an image to the
28 * framebuffer and then checking that the observed values match the
29 * bound mipmap level. The same mipmap level is then overwritten by
30 * the shader program after its contents have been read.
41 /** Total number of pixels in the window and image. */
44 /** Maximum number of mipmap levels. */
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
59 init_image(const struct image_info img
, unsigned l
)
61 const unsigned num_levels
= image_num_levels(img
);
62 uint32_t pixels
[4 * N
* M
];
65 for (i
= 0; i
< 4 * N
* num_levels
; ++i
)
66 pixels
[i
] = encode(img
.format
, i
);
68 return upload_image_levels(img
, num_levels
, l
, 0, pixels
);
72 check_fb(const struct grid_info grid
, const struct image_info img
, unsigned l
)
74 const unsigned offset
= 4 * image_level_offset(img
, l
);
75 const unsigned n
= 4 * product(grid
.size
);
76 uint32_t pixels_fb
[4 * N
], expect_fb
[4 * N
];
79 if (!download_result(grid
, pixels_fb
))
82 for (i
= 0; i
< n
; ++i
) {
84 * The framebuffer contents should reflect level l of
85 * the image which is read by the shader program.
87 expect_fb
[i
] = encode(grid
.format
, offset
+ i
);
90 if (!check_pixels_v(image_info_for_grid(grid
), pixels_fb
, expect_fb
)) {
91 printf(" Source: framebuffer\n");
99 check_img(const struct image_info img
, unsigned l
)
101 const unsigned num_levels
= image_num_levels(img
);
102 uint32_t pixels_img
[4 * N
* M
], expect_img
[4 * N
];
105 if (!download_image_levels(img
, num_levels
, 0, pixels_img
))
108 for (j
= 0; j
< num_levels
; ++j
) {
109 const struct image_info level_img
= image_info_for_level(img
, j
);
110 const unsigned offset
= 4 * image_level_offset(img
, j
);
111 const unsigned n
= 4 * product(level_img
.size
);
113 for (i
= 0; i
< n
; ++i
) {
116 * Level l should have been modified
119 expect_img
[i
] = encode(img
.format
, 33);
122 * Other levels should have remained
125 expect_img
[i
] = encode(img
.format
, offset
+ i
);
129 if (!check_pixels_v(level_img
, &pixels_img
[offset
],
131 printf(" Source: image level %d\n", j
);
140 * Bind an individual level of a texture mipmap to an image unit, read
141 * its contents and write back a different value to the same location.
144 run_test(const struct image_target_info
*target
)
146 const unsigned level
= 3;
147 const struct image_info img
= image_info(
148 target
->target
, GL_RGBA32F
, W
, H
);
149 const struct image_info level_img
= image_info_for_level(img
, level
);
150 const struct grid_info grid
= {
151 GL_FRAGMENT_SHADER_BIT
, img
.format
,
152 image_optimal_extent(level_img
.size
)
154 GLuint prog
= generate_program(
155 grid
, GL_FRAGMENT_SHADER
,
156 concat(image_hunk(level_img
, ""),
157 hunk("IMAGE_UNIFORM_T img;\n"
159 "GRID_T op(ivec2 idx, GRID_T x) {\n"
160 " GRID_T v = imageLoad(img, IMAGE_ADDR(idx));\n"
161 " imageStore(img, IMAGE_ADDR(idx), DATA_T(33));\n"
164 bool ret
= prog
&& init_fb(grid
) &&
165 init_image(img
, level
) &&
166 set_uniform_int(prog
, "img", 0) &&
167 draw_grid(grid
, prog
) &&
168 check_fb(grid
, img
, level
) &&
169 check_img(img
, level
);
171 glDeleteProgram(prog
);
176 piglit_init(int argc
, char **argv
)
178 enum piglit_result status
= PIGLIT_PASS
;
179 const struct image_target_info
*target
;
181 piglit_require_extension("GL_ARB_shader_image_load_store");
183 for (target
= image_targets(); target
->name
; ++target
) {
184 if (image_target_mipmapping_dimensions(target
))
185 subtest(&status
, true, run_test(target
),
186 "%s level binding test", target
->name
);
189 piglit_report_result(status
);