2 * Copyright © 2011 Marek Olšák <maraeo@gmail.com>
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
27 * Tests glClear, glReadPixels, glDrawPixels, glCopyPixels, glBlitFramebuffer
31 #include "piglit-util-gl.h"
35 PIGLIT_GL_TEST_CONFIG_BEGIN
37 config
.supports_gl_compat_version
= 10;
39 config
.window_width
= BUF_SIZE
;
40 config
.window_height
= BUF_SIZE
;
41 config
.window_visual
= PIGLIT_GL_VISUAL_DOUBLE
;
42 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
44 PIGLIT_GL_TEST_CONFIG_END
57 const char *extension
;
59 {GL_DEPTH_COMPONENT16
, "GL_ARB_depth_texture"},
60 {GL_DEPTH_COMPONENT24
, "GL_ARB_depth_texture"},
61 {GL_DEPTH_COMPONENT32
, "GL_ARB_depth_texture"},
62 {GL_DEPTH24_STENCIL8
, "GL_EXT_packed_depth_stencil"},
63 {GL_DEPTH_COMPONENT32F
, "GL_ARB_depth_buffer_float"},
64 {GL_DEPTH32F_STENCIL8
, "GL_ARB_depth_buffer_float"}
69 static enum piglit_result
test_clear(void)
73 float green
[3] = {0, 1, 0};
74 enum piglit_result res
;
76 /* Add a colorbuffer. */
77 glGenRenderbuffersEXT(1, &cb
);
78 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT
, cb
);
79 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT
, GL_RGBA8
, BUF_SIZE
, BUF_SIZE
);
80 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT
, 0);
82 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT
, GL_COLOR_ATTACHMENT0
,
83 GL_RENDERBUFFER_EXT
, cb
);
85 glDrawBuffer(GL_COLOR_ATTACHMENT0
);
86 glReadBuffer(GL_COLOR_ATTACHMENT0
);
87 status
= glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT
);
88 if (status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
89 printf("FBO incomplete status 0x%X\n", status
);
90 piglit_report_result(PIGLIT_FAIL
); /* RGBA8 must succeed. */
94 glClear(GL_DEPTH_BUFFER_BIT
);
96 glEnable(GL_DEPTH_TEST
);
99 glDepthFunc(GL_LEQUAL
);
100 piglit_draw_rect_z(0.499, -1, -1, 1, 2); /* 0.75 converted to clip space is 0.5. */
101 glDepthFunc(GL_GEQUAL
);
102 piglit_draw_rect_z(0.501, 0, -1, 1, 2);
105 glDisable(GL_DEPTH_TEST
);
107 res
= piglit_probe_rect_rgb(0, 0, BUF_SIZE
, BUF_SIZE
, green
) ? PIGLIT_PASS
: PIGLIT_FAIL
;
109 /* Display the colorbuffer. */
110 if (!piglit_automatic
) {
111 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT
, piglit_winsys_fbo
);
112 glBlitFramebufferEXT(0, 0, BUF_SIZE
, BUF_SIZE
, 0, 0, BUF_SIZE
, BUF_SIZE
,
113 GL_COLOR_BUFFER_BIT
, GL_NEAREST
);
116 glDeleteRenderbuffersEXT(1, &cb
);
121 static enum piglit_result
compare()
123 int x
, y
, failures
= 0;
124 GLfloat depth
[BUF_SIZE
*BUF_SIZE
];
125 GLfloat expected_depth
;
128 glReadPixels(0, 0, BUF_SIZE
, BUF_SIZE
, GL_DEPTH_COMPONENT
,
131 /* Compare results. */
132 for (y
= 0; y
< BUF_SIZE
; y
++) {
133 for (x
= 0; x
< BUF_SIZE
; x
++) {
135 /* Skip the middle row and column of pixels because
136 * drawing polygons for the left/right and bottom/top
137 * quadrants may hit the middle pixels differently
138 * depending on minor transformation and rasterization
141 if (x
== BUF_SIZE
/ 2 || y
== BUF_SIZE
/ 2)
144 if (y
< BUF_SIZE
/2) {
145 expected_depth
= x
< BUF_SIZE
/2 ? 0.25 : 0.375;
147 expected_depth
= x
< BUF_SIZE
/2 ? 0.625 : 0.75;
150 if (fabs(depth
[y
*BUF_SIZE
+x
] - expected_depth
) > 0.001) {
153 printf("Depth at %i,%i Expected: %f Observed: %f\n",
154 x
, y
, expected_depth
, depth
[y
*BUF_SIZE
+x
]);
155 } else if (failures
== 20) {
162 printf("Total failures: %i\n", failures
);
164 return failures
== 0 ? PIGLIT_PASS
: PIGLIT_FAIL
;
167 static enum piglit_result
test_readpixels()
171 glClear(GL_DEPTH_BUFFER_BIT
);
174 glEnable(GL_DEPTH_TEST
);
175 glDepthFunc(GL_ALWAYS
);
177 piglit_draw_rect_z(-0.5, -1, -1, 1, 1);
178 piglit_draw_rect_z(-0.25, 0, -1, 1, 1);
179 piglit_draw_rect_z(0.25, -1, 0, 1, 1);
180 piglit_draw_rect_z(0.5, 0, 0, 1, 1);
182 glDisable(GL_DEPTH_TEST
);
187 static enum piglit_result
test_drawpixels()
190 GLfloat depth
[BUF_SIZE
*BUF_SIZE
];
192 for (y
= 0; y
< BUF_SIZE
; y
++) {
193 for (x
= 0; x
< BUF_SIZE
; x
++) {
194 if (y
< BUF_SIZE
/2) {
195 depth
[y
*BUF_SIZE
+x
] = x
< BUF_SIZE
/2 ? 0.25 : 0.375;
197 depth
[y
*BUF_SIZE
+x
] = x
< BUF_SIZE
/2 ? 0.625 : 0.75;
204 glClear(GL_DEPTH_BUFFER_BIT
);
207 glEnable(GL_DEPTH_TEST
);
208 glDepthFunc(GL_ALWAYS
);
209 glDrawPixels(BUF_SIZE
, BUF_SIZE
, GL_DEPTH_COMPONENT
, GL_FLOAT
, depth
);
210 glDisable(GL_DEPTH_TEST
);
215 static enum piglit_result
test_copy(void)
219 glClear(GL_DEPTH_BUFFER_BIT
);
221 /* Initialize buffers. */
222 glEnable(GL_DEPTH_TEST
);
223 glDepthFunc(GL_ALWAYS
);
225 /* Set the upper-right corner to 0x3333 and copy the content to the lower-left one. */
226 piglit_draw_rect_z(-0.5, 0, 0, 1, 1);
228 glBlitFramebufferEXT(BUF_SIZE
/2+1, BUF_SIZE
/2+1, BUF_SIZE
, BUF_SIZE
,
229 0, 0, BUF_SIZE
/2, BUF_SIZE
/2,
230 GL_DEPTH_BUFFER_BIT
, GL_NEAREST
);
232 glCopyPixels(BUF_SIZE
/2+1, BUF_SIZE
/2+1, BUF_SIZE
/2, BUF_SIZE
/2, GL_DEPTH
);
234 /* Initialize the other corners. */
235 piglit_draw_rect_z(-0.25, 0, -1, 1, 1);
236 piglit_draw_rect_z(0.25, -1, 0, 1, 1);
237 piglit_draw_rect_z(0.5, 0, 0, 1, 1);
239 glDisable(GL_DEPTH_TEST
);
244 enum piglit_result
piglit_display(void)
246 enum piglit_result res
;
250 glMatrixMode(GL_PROJECTION
);
252 glMatrixMode(GL_MODELVIEW
);
255 glClearColor(0, 0, 0, 0);
256 glClear(GL_COLOR_BUFFER_BIT
);
258 /* Create the FBO. */
259 glGenRenderbuffersEXT(1, &rb
);
260 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT
, rb
);
261 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT
, f
.iformat
, BUF_SIZE
, BUF_SIZE
);
262 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT
, 0);
264 glGenFramebuffersEXT(1, &fb
);
265 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT
, fb
);
266 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT
, GL_DEPTH_ATTACHMENT
,
267 GL_RENDERBUFFER_EXT
, rb
);
268 glViewport(0, 0, BUF_SIZE
, BUF_SIZE
);
269 glDrawBuffer(GL_NONE
);
270 glReadBuffer(GL_NONE
);
271 status
= glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT
);
272 if (status
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
273 printf("FBO incomplete status 0x%X\n", status
);
274 piglit_report_result(PIGLIT_SKIP
);
277 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
278 glPixelStorei(GL_PACK_ALIGNMENT
, 1);
282 puts("Testing glClear(depth).");
286 puts("Testing glReadPixels(depth).");
287 res
= test_readpixels();
290 puts("Testing glDrawPixels(depth).");
291 res
= test_drawpixels();
296 "Testing glBlitFramebuffer(depth)." :
297 "Testing glCopyPixels(depth).");
306 glBindFramebufferEXT(GL_FRAMEBUFFER
, piglit_winsys_fbo
);
307 glDeleteFramebuffersEXT(1, &fb
);
308 glDeleteRenderbuffersEXT(1, &rb
);
310 piglit_present_results();
312 if (!piglit_check_gl_error(GL_NO_ERROR
))
313 piglit_report_result(PIGLIT_FAIL
);
317 void piglit_init(int argc
, char **argv
)
321 piglit_require_extension("GL_EXT_framebuffer_object");
322 piglit_require_extension("GL_EXT_framebuffer_blit");
324 for (p
= 1; p
< argc
; p
++) {
325 if (!strcmp(argv
[p
], "clear")) {
329 if (!strcmp(argv
[p
], "readpixels")) {
333 if (!strcmp(argv
[p
], "drawpixels")) {
337 if (!strcmp(argv
[p
], "copypixels")) {
341 if (!strcmp(argv
[p
], "blit")) {
345 const GLenum arg
= piglit_get_gl_enum_from_name(argv
[p
]);
346 for (i
= 0; i
< sizeof(formats
)/sizeof(*formats
); i
++) {
347 if (arg
== formats
[i
].iformat
) {
348 if (formats
[i
].extension
)
349 piglit_require_extension(formats
[i
].extension
);
351 printf("Testing %s.\n",
352 piglit_get_gl_enum_name(f
.iformat
));
359 printf("Not enough parameters.\n");
360 piglit_report_result(PIGLIT_SKIP
);