conversion-explicit: use a different value for normalized +/- min
[piglit.git] / tests / spec / arb_copy_image / targets.c
blob3bd6630edf257de315dd4c70e921400ee1ab68ce
1 /*
2 * Copyright 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.
25 * This tests copySubImageData on 3D targets. The maximum testable
26 * textures size is 32x32x32 due to the way the textures are
27 * displayed/verified. One texture is filled with a red background and a
28 * green solid in the foreground. Then the green solid is copied to a blue
29 * texture. The results are then verified. This can test all possible
30 * combinations of texture targets.
33 #include "piglit-util-gl.h"
35 PIGLIT_GL_TEST_CONFIG_BEGIN
37 config.supports_gl_compat_version = 13;
39 config.window_width = 34 * 8;
40 config.window_height = 34 * 8;
41 config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
42 config.khr_no_error_support = PIGLIT_NO_ERRORS;
44 PIGLIT_GL_TEST_CONFIG_END
46 static const float green[3] = {0.0, 1.0, 0.0};
47 static const float red[3] = {1.0, 0.0, 0.0};
48 static const float blue[3] = {0.0, 0.0, 1.0};
50 GLuint prog_1d_array, prog_1D_array;
52 struct image {
53 GLuint texture;
54 GLenum target;
55 int width, height, depth;
58 struct volume {
59 int x, y, z;
60 int w, h, d;
63 static void
64 image_init(struct image *image, GLenum target, int width, int height, int depth)
66 switch (target) {
67 case GL_TEXTURE_CUBE_MAP:
68 assert(depth == 6);
69 /* Fall through. */
70 case GL_TEXTURE_CUBE_MAP_ARRAY_ARB:
71 assert(width == height);
72 assert(depth % 6 == 0);
73 break;
74 case GL_TEXTURE_1D:
75 assert(height == 1);
76 /* Fall through. */
77 case GL_TEXTURE_2D:
78 case GL_TEXTURE_RECTANGLE:
79 assert(depth == 1);
80 break;
81 case GL_TEXTURE_1D_ARRAY:
82 assert(height == 1);
83 break;
86 /* Cube maps are always 6 deep */
87 if (target == GL_TEXTURE_CUBE_MAP)
88 assert(depth == 6);
90 /* Cube map arrays always must be a multiple of 6 */
91 if (target == GL_TEXTURE_CUBE_MAP_ARRAY_ARB)
92 assert(depth % 6 == 0);
94 image->target = target;
95 image->width = width;
96 image->height = height;
97 image->depth = depth;
99 glGenTextures(1, &image->texture);
100 glBindTexture(image->target, image->texture);
101 glTexParameteri(image->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
102 glTexParameteri(image->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
105 static void
106 image_fill(struct image *img, const float *bg_color, const float *fg_color,
107 const struct volume *vol)
109 float *img_data;
110 int i, j, k;
111 const float *color;
113 assert(vol->x >= 0);
114 assert(vol->y >= 0);
115 assert(vol->z >= 0);
116 assert(vol->w >= 0);
117 assert(vol->h >= 0);
118 assert(vol->d >= 0);
119 assert(vol->x + vol->w <= img->width);
120 assert(vol->y + vol->h <= img->height);
121 assert(vol->z + vol->d <= img->depth);
123 img_data = malloc(img->width * img->height * img->depth *
124 3 * sizeof(float));
126 /* Construct the image */
127 for (k = 0; k < img->depth; ++k) {
128 for (j = 0; j < img->height; ++j) {
129 for (i = 0; i < img->width; ++i) {
130 if (i >= vol->x && i < vol->x + vol->w &&
131 j >= vol->y && j < vol->y + vol->h &&
132 k >= vol->z && k < vol->z + vol->d) {
133 color = fg_color;
134 } else {
135 color = bg_color;
138 memcpy(img_data + ((k * img->height + j) * img->width + i) * 3,
139 color, 3 * sizeof(float));
144 glBindTexture(img->target, img->texture);
146 switch (img->target) {
147 case GL_TEXTURE_1D:
148 glTexImage1D(img->target, 0,
149 GL_RGB, img->width, 0,
150 GL_RGB, GL_FLOAT, img_data);
151 break;
153 case GL_TEXTURE_CUBE_MAP:
154 for (k = 0; k < 6; ++k) {
155 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + k, 0,
156 GL_RGB, img->width, img->height, 0,
157 GL_RGB, GL_FLOAT,
158 img_data + k * img->height * img->width * 3);
160 break;
162 case GL_TEXTURE_2D:
163 case GL_TEXTURE_RECTANGLE:
164 glTexImage2D(img->target, 0,
165 GL_RGB, img->width, img->height, 0,
166 GL_RGB, GL_FLOAT, img_data);
167 break;
169 case GL_TEXTURE_1D_ARRAY:
170 glTexImage2D(img->target, 0,
171 GL_RGB, img->width, img->depth, 0,
172 GL_RGB, GL_FLOAT, img_data);
173 break;
175 case GL_TEXTURE_3D:
176 case GL_TEXTURE_2D_ARRAY:
177 case GL_TEXTURE_CUBE_MAP_ARRAY_ARB:
178 glTexImage3D(img->target, 0,
179 GL_RGB, img->width, img->height, img->depth, 0,
180 GL_RGB, GL_FLOAT, img_data);
181 break;
182 default:
183 assert(!"Invalid target");
186 free(img_data);
189 static void
190 image_bind_layer(struct image *img, GLenum target, int layer)
192 switch(img->target) {
193 case GL_TEXTURE_1D:
194 glFramebufferTexture1D(target,
195 GL_COLOR_ATTACHMENT0_EXT,
196 img->target, img->texture, 0);
197 break;
198 case GL_TEXTURE_2D:
199 case GL_TEXTURE_RECTANGLE:
200 glFramebufferTexture2D(target,
201 GL_COLOR_ATTACHMENT0_EXT,
202 img->target, img->texture, 0);
203 break;
204 case GL_TEXTURE_CUBE_MAP:
205 glFramebufferTexture2D(target,
206 GL_COLOR_ATTACHMENT0_EXT,
207 GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer,
208 img->texture, 0);
209 break;
210 case GL_TEXTURE_3D:
211 case GL_TEXTURE_1D_ARRAY:
212 case GL_TEXTURE_2D_ARRAY:
213 case GL_TEXTURE_CUBE_MAP_ARRAY_ARB:
214 glFramebufferTextureLayer(target,
215 GL_COLOR_ATTACHMENT0_EXT,
216 img->texture, 0, layer);
217 break;
221 static bool
222 image_verify(struct image *img, const float *bg_color, const float *fg_color,
223 const struct volume *vol)
225 GLuint fbo;
226 int k;
227 bool pass = true;
229 glGenFramebuffersEXT(1, &fbo);
230 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, fbo);
232 for (k = 0; k < img->depth; ++k) {
233 image_bind_layer(img, GL_READ_FRAMEBUFFER_EXT, k);
235 if (k < vol->z || k >= vol->z + vol->d) {
236 pass &= piglit_probe_rect_rgb(0, 0,
237 img->width, img->height,
238 bg_color);
239 } else {
240 pass &= piglit_probe_rect_rgb(vol->x,
241 vol->y,
242 vol->w,
243 vol->h,
244 fg_color);
245 pass &= piglit_probe_rect_rgb(0, 0,
246 img->width,
247 vol->y,
248 bg_color);
249 pass &= piglit_probe_rect_rgb(0, vol->y + vol->h,
250 img->width,
251 img->height - vol->y - vol->h,
252 bg_color);
253 pass &= piglit_probe_rect_rgb(0, 0,
254 vol->x,
255 img->height,
256 bg_color);
257 pass &= piglit_probe_rect_rgb(vol->x + vol->w, 0,
258 img->width - vol->x - vol->w,
259 img->height,
260 bg_color);
264 return pass;
267 static void
268 image_display(struct image *img, int parent_x, int parent_y)
270 GLuint fbo;
271 int k, off_x, off_y;
273 glGenFramebuffersEXT(1, &fbo);
274 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, fbo);
276 for (k = 0; k < img->depth; ++k) {
277 off_x = parent_x + (k % 8) * (img->width + 2) + 1;
278 off_y = parent_y + (k / 8) * (img->height + 2) + 1;
280 image_bind_layer(img, GL_READ_FRAMEBUFFER_EXT, k);
282 glBlitFramebufferEXT(0, 0, img->width, img->height,
283 off_x, off_y,
284 off_x + img->width, off_y + img->height,
285 GL_COLOR_BUFFER_BIT, GL_NEAREST);
288 glDeleteFramebuffersEXT(1, &fbo);
291 struct image src, dst;
292 struct volume src_vol, dst_vol;
293 int dst_x, dst_y, dst_z;
295 static void
296 quit_with_usage()
298 printf("usage: arb_copy_image-targets srcTarget srcTexWidth srcTexHeight srcTexDepth\n"
299 " dstTarget dstTexWidth dstTexHeight dstTexDepth\n"
300 " srcVolX srcVolY srcVolZ dstVolX dstVolY dstVolZ\n"
301 " volWidth volHeight volDepth\n");
302 exit(1);
305 struct texture_target {
306 GLenum val;
307 const char *str;
310 #define TARGET(x) { x, #x }
311 struct texture_target targets[] = {
312 TARGET(GL_TEXTURE_1D),
313 TARGET(GL_TEXTURE_1D_ARRAY),
314 TARGET(GL_TEXTURE_2D),
315 /* TARGET(GL_TEXTURE_2D_MULTISAMPLE), */
316 TARGET(GL_TEXTURE_RECTANGLE),
317 TARGET(GL_TEXTURE_2D_ARRAY),
318 /* TARGET(GL_TEXTURE_2D_MULTISAMPLE_ARRAY), */
319 TARGET(GL_TEXTURE_CUBE_MAP),
320 TARGET(GL_TEXTURE_CUBE_MAP_ARRAY),
321 TARGET(GL_TEXTURE_3D),
323 #undef TARGET
325 static GLenum
326 parse_target(const char *target_str)
328 int i;
329 GLenum target = GL_NONE;
331 for (i = 0; i < sizeof(targets) / sizeof(*targets); ++i) {
332 if (strcmp(target_str, targets[i].str) == 0) {
333 target = targets[i].val;
334 break;
338 if (target == GL_NONE)
339 quit_with_usage();
341 switch (target) {
342 case GL_TEXTURE_CUBE_MAP:
343 piglit_require_extension("GL_ARB_texture_cube_map");
344 break;
345 case GL_TEXTURE_1D_ARRAY:
346 case GL_TEXTURE_2D_ARRAY:
347 piglit_require_extension("GL_EXT_texture_array");
348 break;
349 case GL_TEXTURE_CUBE_MAP_ARRAY:
350 piglit_require_extension("GL_ARB_texture_cube_map_array");
351 break;
354 return target;
357 void
358 piglit_init(int argc, char **argv)
360 if (argc < 18)
361 quit_with_usage();
363 piglit_require_extension("GL_ARB_copy_image");
364 piglit_require_extension("GL_EXT_framebuffer_object");
366 image_init(&src, parse_target(argv[1]),
367 atoi(argv[2]), atoi(argv[3]), atoi(argv[4]));
369 image_init(&dst, parse_target(argv[5]),
370 atoi(argv[6]), atoi(argv[7]), atoi(argv[8]));
372 src_vol.x = atoi(argv[9]);
373 src_vol.y = atoi(argv[10]);
374 src_vol.z = atoi(argv[11]);
376 dst_vol.x = atoi(argv[12]);
377 dst_vol.y = atoi(argv[13]);
378 dst_vol.z = atoi(argv[14]);
380 dst_vol.w = src_vol.w = atoi(argv[15]);
381 dst_vol.h = src_vol.h = atoi(argv[16]);
382 dst_vol.d = src_vol.d = atoi(argv[17]);
385 enum piglit_result
386 piglit_display(void)
388 bool pass = true;
390 image_fill(&src, red, green, &src_vol);
391 pass &= image_verify(&src, red, green, &src_vol);
393 if (!pass) goto out;
395 image_fill(&dst, blue, blue, &dst_vol);
396 pass &= image_verify(&dst, blue, blue, &dst_vol);
398 glCopyImageSubData(src.texture, src.target, 0,
399 src_vol.x, src_vol.y, src_vol.z,
400 dst.texture, dst.target, 0,
401 dst_vol.x, dst_vol.y, dst_vol.z,
402 src_vol.w, src_vol.h, src_vol.d);
403 pass &= piglit_check_gl_error(GL_NO_ERROR);
405 pass &= image_verify(&dst, blue, green, &dst_vol);
407 out:
408 if (!piglit_automatic) {
409 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT,
410 piglit_winsys_fbo);
411 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
412 glClear(GL_COLOR_BUFFER_BIT);
414 image_display(&dst, 0, 0);
415 image_display(&src, 0, 34 * 4);
417 piglit_present_results();
420 return pass ? PIGLIT_PASS : PIGLIT_FAIL;