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
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
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
;
55 int width
, height
, depth
;
64 image_init(struct image
*image
, GLenum target
, int width
, int height
, int depth
)
67 case GL_TEXTURE_CUBE_MAP
:
70 case GL_TEXTURE_CUBE_MAP_ARRAY_ARB
:
71 assert(width
== height
);
72 assert(depth
% 6 == 0);
78 case GL_TEXTURE_RECTANGLE
:
81 case GL_TEXTURE_1D_ARRAY
:
86 /* Cube maps are always 6 deep */
87 if (target
== GL_TEXTURE_CUBE_MAP
)
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
;
96 image
->height
= height
;
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
);
106 image_fill(struct image
*img
, const float *bg_color
, const float *fg_color
,
107 const struct volume
*vol
)
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
*
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
) {
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
) {
148 glTexImage1D(img
->target
, 0,
149 GL_RGB
, img
->width
, 0,
150 GL_RGB
, GL_FLOAT
, img_data
);
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,
158 img_data
+ k
* img
->height
* img
->width
* 3);
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
);
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
);
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
);
183 assert(!"Invalid target");
190 image_bind_layer(struct image
*img
, GLenum target
, int layer
)
192 switch(img
->target
) {
194 glFramebufferTexture1D(target
,
195 GL_COLOR_ATTACHMENT0_EXT
,
196 img
->target
, img
->texture
, 0);
199 case GL_TEXTURE_RECTANGLE
:
200 glFramebufferTexture2D(target
,
201 GL_COLOR_ATTACHMENT0_EXT
,
202 img
->target
, img
->texture
, 0);
204 case GL_TEXTURE_CUBE_MAP
:
205 glFramebufferTexture2D(target
,
206 GL_COLOR_ATTACHMENT0_EXT
,
207 GL_TEXTURE_CUBE_MAP_POSITIVE_X
+ layer
,
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
);
222 image_verify(struct image
*img
, const float *bg_color
, const float *fg_color
,
223 const struct volume
*vol
)
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
,
240 pass
&= piglit_probe_rect_rgb(vol
->x
,
245 pass
&= piglit_probe_rect_rgb(0, 0,
249 pass
&= piglit_probe_rect_rgb(0, vol
->y
+ vol
->h
,
251 img
->height
- vol
->y
- vol
->h
,
253 pass
&= piglit_probe_rect_rgb(0, 0,
257 pass
&= piglit_probe_rect_rgb(vol
->x
+ vol
->w
, 0,
258 img
->width
- vol
->x
- vol
->w
,
268 image_display(struct image
*img
, int parent_x
, int parent_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
,
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
;
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");
305 struct texture_target
{
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
),
326 parse_target(const char *target_str
)
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
;
338 if (target
== GL_NONE
)
342 case GL_TEXTURE_CUBE_MAP
:
343 piglit_require_extension("GL_ARB_texture_cube_map");
345 case GL_TEXTURE_1D_ARRAY
:
346 case GL_TEXTURE_2D_ARRAY
:
347 piglit_require_extension("GL_EXT_texture_array");
349 case GL_TEXTURE_CUBE_MAP_ARRAY
:
350 piglit_require_extension("GL_ARB_texture_cube_map_array");
358 piglit_init(int argc
, char **argv
)
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]);
390 image_fill(&src
, red
, green
, &src_vol
);
391 pass
&= image_verify(&src
, red
, green
, &src_vol
);
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
);
408 if (!piglit_automatic
) {
409 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT
,
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
;