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
26 * A simple test of glCopyImageSubData that copies a square from one
27 * 2D texture to another and back. This test exercises texture to texture,
28 * texture to renderbuffer, renderbuffer to texture, and renderbuffer to
29 * renderbuffer copies. This test also exercises copying from one texture
30 * or renderbuffer to the same texture or renderbuffer
32 #include "piglit-util-gl.h"
34 PIGLIT_GL_TEST_CONFIG_BEGIN
36 config
.supports_gl_compat_version
= 13;
38 config
.window_visual
= PIGLIT_GL_VISUAL_RGB
| PIGLIT_GL_VISUAL_DOUBLE
;
39 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
41 PIGLIT_GL_TEST_CONFIG_END
43 static const float green
[3] = {0.0, 1.0, 0.0};
44 static const float red
[3] = {1.0, 0.0, 0.0};
45 static const float blue
[3] = {0.0, 0.0, 1.0};
47 int renderbuffers
= 0;
50 piglit_init(int argc
, char **argv
)
54 piglit_require_extension("GL_ARB_copy_image");
55 piglit_require_extension("GL_EXT_framebuffer_object");
57 for (i
= 0; i
< argc
; ++i
) {
58 if (strcmp(argv
[i
], "--tex-to-tex") == 0)
60 else if (strcmp(argv
[i
], "--tex-to-rb") == 0)
62 else if (strcmp(argv
[i
], "--rb-to-rb") == 0)
73 image_init(struct image
*image
, GLenum target
, GLenum internalformat
)
75 image
->target
= target
;
77 glGenFramebuffersEXT(1, &image
->fbo
);
78 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, image
->fbo
);
80 if (image
->target
== GL_RENDERBUFFER_EXT
) {
81 glGenRenderbuffersEXT(1, &image
->name
);
82 glBindRenderbufferEXT(GL_RENDERBUFFER
, image
->name
);
83 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT
,
84 internalformat
, 64, 64);
85 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT
,
86 GL_COLOR_ATTACHMENT0_EXT
,
87 image
->target
, image
->name
);
89 glGenTextures(1, &image
->name
);
90 glBindTexture(image
->target
, image
->name
);
91 glTexImage2D(image
->target
, 0, internalformat
,
92 64, 64, 0, internalformat
, GL_BYTE
, NULL
);
93 glTexParameteri(target
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
94 glTexParameteri(target
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
95 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT
,
96 GL_COLOR_ATTACHMENT0_EXT
,
97 image
->target
, image
->name
, 0);
102 image_destroy(struct image
*image
)
104 if (image
->target
== GL_RENDERBUFFER_EXT
)
105 glDeleteRenderbuffersEXT(1, &image
->name
);
107 glDeleteTextures(1, &image
->name
);
109 glDeleteFramebuffers(1, &image
->fbo
);
113 image_fill(struct image
*image
, const float *color
)
115 glClearColor(color
[0], color
[1], color
[2], 1.0f
);
116 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, image
->fbo
);
117 glClear(GL_COLOR_BUFFER_BIT
);
121 image_draw(struct image
*image
, int x
, int y
)
123 if (image
->target
== GL_RENDERBUFFER_EXT
) {
124 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT
, image
->fbo
);
125 glBlitFramebufferEXT(0, 0, 64, 64, x
, y
, x
+ 64, y
+ 64,
126 GL_COLOR_BUFFER_BIT
, GL_NEAREST
);
128 /* Set up or GL environment for rendering */
129 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
130 glEnable(GL_TEXTURE_2D
);
131 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
133 glBindTexture(image
->target
, image
->name
);
134 piglit_draw_rect_tex(x
, y
, 64, 64, 0, 0, 1, 1);
136 glDisable(GL_TEXTURE_2D
);
144 struct image images
[2];
146 if (renderbuffers
>= 1)
147 images
[0].target
= GL_RENDERBUFFER_EXT
;
149 images
[0].target
= GL_TEXTURE_2D
;
151 if (renderbuffers
== 2)
152 images
[1].target
= GL_RENDERBUFFER_EXT
;
154 images
[1].target
= GL_TEXTURE_2D
;
156 image_init(&images
[0], images
[0].target
, GL_RGB
);
157 image_init(&images
[1], images
[1].target
, GL_RGB
);
159 image_fill(&images
[0], green
);
160 image_fill(&images
[1], red
);
162 glCopyImageSubData(images
[0].name
, images
[0].target
, 0, 0, 0, 0,
163 images
[1].name
, images
[1].target
, 0, 17, 11, 0,
165 pass
&= piglit_check_gl_error(GL_NO_ERROR
);
167 /* We should now have a green square on red */
168 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT
, images
[1].fbo
);
169 pass
&= piglit_probe_rect_rgb(17, 11, 32, 32, green
);
170 pass
&= piglit_probe_rect_rgb(0, 0, 64, 11, red
);
171 pass
&= piglit_probe_rect_rgb(0, 11, 17, 32, red
);
172 pass
&= piglit_probe_rect_rgb(49, 11, 15, 32, red
);
173 pass
&= piglit_probe_rect_rgb(0, 43, 64, 21, red
);
175 image_fill(&images
[0], blue
);
176 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT
, images
[0].fbo
);
177 pass
&= piglit_probe_rect_rgb(0, 0, 64, 64, blue
);
179 glCopyImageSubData(images
[1].name
, images
[1].target
, 0, 17, 11, 0,
180 images
[0].name
, images
[0].target
, 0, 0, 32, 0,
182 pass
&= piglit_check_gl_error(GL_NO_ERROR
);
184 /* This should be a green square on blue (no red!) */
185 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT
, images
[0].fbo
);
186 pass
&= piglit_probe_rect_rgb(0, 32, 32, 32, green
);
187 pass
&= piglit_probe_rect_rgb(0, 0, 64, 32, blue
);
188 pass
&= piglit_probe_rect_rgb(32, 32, 32, 32, blue
);
190 glCopyImageSubData(images
[0].name
, images
[0].target
, 0, 0, 32, 0,
191 images
[0].name
, images
[0].target
, 0, 32, 0, 0,
193 pass
&= piglit_check_gl_error(GL_NO_ERROR
);
195 /* This should be a blue/green checkerboard */
196 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT
, images
[0].fbo
);
197 pass
&= piglit_probe_rect_rgb(0, 0, 32, 32, blue
);
198 pass
&= piglit_probe_rect_rgb(0, 32, 32, 32, green
);
199 pass
&= piglit_probe_rect_rgb(32, 0, 32, 32, green
);
200 pass
&= piglit_probe_rect_rgb(32, 32, 32, 32, blue
);
202 if (!piglit_automatic
) {
203 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT
,
206 image_draw(&images
[1], 0, 0);
207 image_draw(&images
[0], 64, 0);
209 piglit_present_results();
212 image_destroy(&images
[0]);
213 image_destroy(&images
[1]);
215 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;