2 * Copyright © 2010 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
24 * Eric Anholt <eric@anholt.net>
30 * Tests EXT_framebuffer_blit with various combinations of window system and
31 * FBO objects. Because FBOs are generally stored inverted relative to
32 * window system frambuffers, this could catch flipping failures in blit paths.
34 * See also fbo-readdrawpix.c and fbo-copypix.c
37 #include "piglit-util-gl.h"
39 PIGLIT_GL_TEST_CONFIG_BEGIN
41 config
.supports_gl_compat_version
= 10;
43 config
.window_visual
= PIGLIT_GL_VISUAL_RGB
| PIGLIT_GL_VISUAL_DOUBLE
;
44 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
46 PIGLIT_GL_TEST_CONFIG_END
51 /* size of texture/renderbuffer (power of two) */
54 static GLuint target
= GL_TEXTURE_2D
;
58 make_fbo(int w
, int h
)
64 glGenFramebuffersEXT(1, &fb
);
65 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, fb
);
67 glGenTextures(1, &tex
);
68 glBindTexture(target
, tex
);
69 glTexImage2D(target
, 0, GL_RGBA
,
71 GL_RGBA
, GL_UNSIGNED_BYTE
, NULL
);
73 glTexParameteri(target
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
74 glTexParameteri(target
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
76 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT
,
77 GL_COLOR_ATTACHMENT0_EXT
,
81 if (!piglit_check_gl_error(GL_NO_ERROR
))
82 piglit_report_result(PIGLIT_FAIL
);
84 status
= glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT
);
85 if (status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
86 fprintf(stderr
, "fbo incomplete (status = 0x%04x)\n", status
);
87 piglit_report_result(PIGLIT_SKIP
);
94 draw_color_rect(int x
, int y
, int w
, int h
)
101 glColor4f(1.0, 0.0, 0.0, 0.0);
102 piglit_draw_rect(x1
, y1
, w
/ 2, h
/ 2);
103 glColor4f(0.0, 1.0, 0.0, 0.0);
104 piglit_draw_rect(x2
, y1
, w
/ 2, h
/ 2);
105 glColor4f(0.0, 0.0, 1.0, 0.0);
106 piglit_draw_rect(x1
, y2
, w
/ 2, h
/ 2);
107 glColor4f(1.0, 1.0, 1.0, 0.0);
108 piglit_draw_rect(x2
, y2
, w
/ 2, h
/ 2);
112 verify_color_rect(int start_x
, int start_y
, int w
, int h
)
114 float red
[] = {1, 0, 0, 0};
115 float green
[] = {0, 1, 0, 0};
116 float blue
[] = {0, 0, 1, 0};
117 float white
[] = {1, 1, 1, 0};
119 if (!piglit_probe_rect_rgb(start_x
, start_y
, w
/ 2, h
/ 2, red
))
121 if (!piglit_probe_rect_rgb(start_x
+ w
/2, start_y
, w
/2, h
/2, green
))
123 if (!piglit_probe_rect_rgb(start_x
, start_y
+ h
/2, w
/2, h
/2, blue
))
125 if (!piglit_probe_rect_rgb(start_x
+ w
/2, start_y
+ h
/2, w
/2, h
/2, white
))
133 copy(GLint srcX0
, GLint srcY0
, GLint srcX1
, GLint srcY1
,
134 GLint dstX0
, GLint dstY0
, GLint dstX1
, GLint dstY1
)
136 glBlitFramebufferEXT(srcX0
, srcY0
, srcX1
, srcY1
,
137 dstX0
, dstY0
, dstX1
, dstY1
,
138 GL_COLOR_BUFFER_BIT
, GL_NEAREST
);
145 GLboolean pass
= GL_TRUE
;
147 int fbo_width
= FBO_SIZE
;
148 int fbo_height
= FBO_SIZE
;
151 int y1
= PAD
* 2 + SIZE
;
152 int y2
= PAD
* 3 + SIZE
* 2;
154 glViewport(0, 0, piglit_width
, piglit_height
);
155 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
157 glClearColor(0.5, 0.5, 0.5, 0.5);
158 glClear(GL_COLOR_BUFFER_BIT
);
160 /* Draw the color rect in the window system window */
161 draw_color_rect(x0
, y0
, SIZE
, SIZE
);
163 fbo
= make_fbo(fbo_width
, fbo_height
);
165 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT
, fbo
);
166 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT
, piglit_winsys_fbo
);
167 glViewport(0, 0, fbo_width
, fbo_height
);
168 piglit_ortho_projection(fbo_width
, fbo_height
, GL_FALSE
);
169 glClearColor(1.0, 0.0, 1.0, 0.0);
170 glClear(GL_COLOR_BUFFER_BIT
);
172 /* Draw the color rect in the FBO */
173 draw_color_rect(x0
, y0
, SIZE
, SIZE
);
175 /* Now that we have correct samples, blit things around.
176 * FBO(bottom) -> WIN(middle)
178 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT
, piglit_winsys_fbo
);
179 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT
, fbo
);
180 copy(x0
, y0
, x0
+ SIZE
, y0
+ SIZE
,
181 x0
, y1
, x0
+ SIZE
, y1
+ SIZE
);
183 /* WIN(bottom) -> FBO(middle) */
184 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT
, fbo
);
185 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT
, piglit_winsys_fbo
);
186 copy(x0
, y0
, x0
+ SIZE
, y0
+ SIZE
,
187 x0
, y1
, x0
+ SIZE
, y1
+ SIZE
);
189 /* FBO(middle) -> WIN(top) back to verify WIN -> FBO */
190 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT
, piglit_winsys_fbo
);
191 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT
, fbo
);
192 copy(x0
, y1
, x0
+ SIZE
, y1
+ SIZE
,
193 x0
, y2
, x0
+ SIZE
, y2
+ SIZE
);
195 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT
, piglit_winsys_fbo
);
196 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, piglit_winsys_fbo
);
198 pass
= verify_color_rect(PAD
, y0
, SIZE
, SIZE
) && pass
;
199 pass
= verify_color_rect(PAD
, y1
, SIZE
, SIZE
) && pass
;
200 pass
= verify_color_rect(PAD
, y2
, SIZE
, SIZE
) && pass
;
201 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, fbo
);
202 pass
= verify_color_rect(PAD
, y0
, SIZE
, SIZE
) && pass
;
203 pass
= verify_color_rect(PAD
, y1
, SIZE
, SIZE
) && pass
;
204 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, piglit_winsys_fbo
);
206 piglit_present_results();
215 GLboolean pass
= run_test();
217 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;
222 piglit_init(int argc
, char **argv
)
226 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
228 piglit_require_extension("GL_EXT_framebuffer_object");
229 piglit_require_extension("GL_EXT_framebuffer_blit");
231 for (i
= 1; i
< argc
; i
++) {
232 if (strcmp(argv
[i
], "rect") == 0) {
233 piglit_require_extension("GL_ARB_texture_rectangle");
234 target
= GL_TEXTURE_RECTANGLE
;
235 puts("Testing ARB_texture_rectangle");