arb_copy_image: test copying of different mipmap levels of a texture
[piglit.git] / tests / fbo / fbo-depth.c
blob1294ef6e2d15bba43b54a2044946c1003fe2b309
1 /*
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
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 /** @file fbo-depth.c
27 * Tests glClear, glReadPixels, glDrawPixels, glCopyPixels, glBlitFramebuffer
28 * with depth buffers.
31 #include "piglit-util-gl.h"
33 #define BUF_SIZE 123
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
46 enum {
47 CLEAR,
48 READPIXELS,
49 DRAWPIXELS,
50 COPYPIXELS,
51 BLIT
53 int test = CLEAR;
55 struct format {
56 GLenum iformat;
57 const char *extension;
58 } formats[] = {
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"}
67 struct format f;
69 static enum piglit_result test_clear(void)
71 GLuint cb;
72 GLenum status;
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. */
93 glClearDepth(0.75);
94 glClear(GL_DEPTH_BUFFER_BIT);
96 glEnable(GL_DEPTH_TEST);
98 glColor3fv(green);
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);
103 glColor3f(1, 1, 1);
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);
118 return res;
121 static enum piglit_result compare()
123 int x, y, failures = 0;
124 GLfloat depth[BUF_SIZE*BUF_SIZE];
125 GLfloat expected_depth;
127 /* Read buffers. */
128 glReadPixels(0, 0, BUF_SIZE, BUF_SIZE, GL_DEPTH_COMPONENT,
129 GL_FLOAT, depth);
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
139 * differences.
141 if (x == BUF_SIZE / 2 || y == BUF_SIZE / 2)
142 continue;
144 if (y < BUF_SIZE/2) {
145 expected_depth = x < BUF_SIZE/2 ? 0.25 : 0.375;
146 } else {
147 expected_depth = x < BUF_SIZE/2 ? 0.625 : 0.75;
150 if (fabs(depth[y*BUF_SIZE+x] - expected_depth) > 0.001) {
151 failures++;
152 if (failures < 20) {
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) {
156 printf("...\n");
161 if (failures)
162 printf("Total failures: %i\n", failures);
164 return failures == 0 ? PIGLIT_PASS : PIGLIT_FAIL;
167 static enum piglit_result test_readpixels()
169 /* Clear. */
170 glClearDepth(0);
171 glClear(GL_DEPTH_BUFFER_BIT);
173 /* Initialize. */
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);
184 return compare();
187 static enum piglit_result test_drawpixels()
189 int x, y;
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;
196 } else {
197 depth[y*BUF_SIZE+x] = x < BUF_SIZE/2 ? 0.625 : 0.75;
202 /* Clear. */
203 glClearDepth(0);
204 glClear(GL_DEPTH_BUFFER_BIT);
206 /* Draw pixels. */
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);
212 return compare();
215 static enum piglit_result test_copy(void)
217 /* Clear. */
218 glClearDepth(0);
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);
227 if (test == BLIT)
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);
231 else
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);
241 return compare();
244 enum piglit_result piglit_display(void)
246 enum piglit_result res;
247 GLuint fb, rb;
248 GLenum status;
250 glMatrixMode(GL_PROJECTION);
251 glLoadIdentity();
252 glMatrixMode(GL_MODELVIEW);
253 glLoadIdentity();
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);
280 switch (test) {
281 case CLEAR:
282 puts("Testing glClear(depth).");
283 res = test_clear();
284 break;
285 case READPIXELS:
286 puts("Testing glReadPixels(depth).");
287 res = test_readpixels();
288 break;
289 case DRAWPIXELS:
290 puts("Testing glDrawPixels(depth).");
291 res = test_drawpixels();
292 break;
293 case COPYPIXELS:
294 case BLIT:
295 puts(test == BLIT ?
296 "Testing glBlitFramebuffer(depth)." :
297 "Testing glCopyPixels(depth).");
298 res = test_copy();
299 break;
300 default:
301 assert(0);
302 res = PIGLIT_SKIP;
305 /* Cleanup. */
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);
314 return res;
317 void piglit_init(int argc, char **argv)
319 unsigned i, p;
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")) {
326 test = CLEAR;
327 continue;
329 if (!strcmp(argv[p], "readpixels")) {
330 test = READPIXELS;
331 continue;
333 if (!strcmp(argv[p], "drawpixels")) {
334 test = DRAWPIXELS;
335 continue;
337 if (!strcmp(argv[p], "copypixels")) {
338 test = COPYPIXELS;
339 continue;
341 if (!strcmp(argv[p], "blit")) {
342 test = BLIT;
343 continue;
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);
350 f = formats[i];
351 printf("Testing %s.\n",
352 piglit_get_gl_enum_name(f.iformat));
353 break;
358 if (!f.iformat) {
359 printf("Not enough parameters.\n");
360 piglit_report_result(PIGLIT_SKIP);