2 * Copyright © 2013 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 * \file fbo-incomplete.c
26 * Collection of negative framebuffer completeness tests.
29 #include "piglit-util-gl.h"
31 PIGLIT_GL_TEST_CONFIG_BEGIN
33 config
.supports_gl_compat_version
= 10;
35 config
.window_visual
= PIGLIT_GL_VISUAL_RGB
| PIGLIT_GL_VISUAL_DOUBLE
;
36 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
38 PIGLIT_GL_TEST_CONFIG_END
40 static const float green
[] = { 0.f
, 1.f
, 0.f
, 1.f
};
42 class incomplete_fbo_test
{
45 incomplete_fbo_test(const char *_name
, GLenum _target
)
46 : name(_name
), target(_target
), tex(0), rb(0), fbo(0),
49 if (target
== GL_RENDERBUFFER
) {
50 glGenRenderbuffers(1, &rb
);
51 glBindRenderbuffer(target
, rb
);
53 glGenTextures(1, &tex
);
54 glBindTexture(target
, tex
);
55 glTexParameteri(target
,
56 GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
59 glGenFramebuffers(1, &fbo
);
60 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, fbo
);
64 ~incomplete_fbo_test()
66 if (target
== GL_RENDERBUFFER
)
67 glBindRenderbuffer(target
, 0);
69 glBindTexture(target
, 0);
71 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, piglit_winsys_fbo
);
72 glBindFramebuffer(GL_READ_FRAMEBUFFER
, piglit_winsys_fbo
);
74 glDeleteTextures(1, &tex
);
75 glDeleteRenderbuffers(1, &rb
);
76 glDeleteFramebuffers(1, &fbo
);
79 bool check_fbo_status(GLenum expect
)
81 GLenum status
= glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER
);
82 if (status
!= expect
) {
84 "status was %s (0x%04x), "
85 "expected %s (0x%04x).\n",
86 piglit_get_gl_enum_name(status
),
88 piglit_get_gl_enum_name(expect
),
96 enum piglit_result
pass()
102 enum piglit_result
fail()
119 * Verify that attaching a 0x0 texture results in incompleteness.
121 extern "C" enum piglit_result
122 incomplete_0_by_0_texture(void *data
)
124 incomplete_fbo_test
t("0x0 texture", GL_TEXTURE_2D
);
126 /* Attach a 0x0 texture to the framebuffer. That should make it
129 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, 0, 0, 0, GL_RGBA
,
130 GL_UNSIGNED_BYTE
, NULL
);
131 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
,
132 GL_TEXTURE_2D
, t
.tex
, 0);
134 if (!piglit_check_gl_error(GL_NO_ERROR
))
137 if (!t
.check_fbo_status(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
))
140 /* Allocate some storage for the texture and verify that the FBO is
143 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, 4, 4, 0, GL_RGBA
,
144 GL_UNSIGNED_BYTE
, NULL
);
146 if (!t
.check_fbo_status(GL_FRAMEBUFFER_COMPLETE
))
149 /* Verify that simple rendering can occur to the FBO.
151 glClearColor(0.f
, 1.f
, 0.f
, 1.f
);
152 glClear(GL_COLOR_BUFFER_BIT
);
154 glBindFramebuffer(GL_READ_FRAMEBUFFER
, t
.fbo
);
155 if (!piglit_probe_rect_rgba(0, 0, 4, 4, green
))
162 * Verify that attaching a 0x0 renderbuffer results in incompleteness.
164 extern "C" enum piglit_result
165 incomplete_0_by_0_renderbuffer(void *data
)
167 incomplete_fbo_test
t("0x0 renderbuffer", GL_RENDERBUFFER
);
169 /* Attach a 0x0 renderbuffer to the framebuffer. That should make it
172 glRenderbufferStorage(GL_RENDERBUFFER
, GL_RGBA8
, 0, 0);
173 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
,
174 GL_RENDERBUFFER
, t
.rb
);
175 if (!piglit_check_gl_error(GL_NO_ERROR
))
178 if (!t
.check_fbo_status(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
))
181 /* Allocate some storage for the renderbuffer and verify that
182 * the FBO is now complete.
184 glRenderbufferStorage(GL_RENDERBUFFER
, GL_RGBA8
, 4, 4);
186 if (!t
.check_fbo_status(GL_FRAMEBUFFER_COMPLETE
))
189 /* Verify that simple rendering can occur to the FBO.
191 glClearColor(0.f
, 1.f
, 0.f
, 1.f
);
192 glClear(GL_COLOR_BUFFER_BIT
);
194 glBindFramebuffer(GL_READ_FRAMEBUFFER
, t
.fbo
);
195 if (!piglit_probe_rect_rgba(0, 0, 4, 4, green
))
202 * Verify that attaching an invalid slice of a 3D texture results in
205 extern "C" enum piglit_result
206 invalid_3d_slice(void *data
)
208 incomplete_fbo_test
t("invalid slice of 3D texture", GL_TEXTURE_3D
);
210 /* Create a texture with only 8 slices (0 through 7), but try to
211 * attach slice 8 and slice 9 to the FBO.
213 glTexImage3D(GL_TEXTURE_3D
, 0, GL_RGBA
, 8, 8, 8, 0, GL_RGBA
,
214 GL_UNSIGNED_BYTE
, NULL
);
215 glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
,
216 GL_TEXTURE_3D
, t
.tex
, 0, 8);
218 if (!piglit_check_gl_error(GL_NO_ERROR
))
221 if (!t
.check_fbo_status(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
))
224 glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
,
225 GL_TEXTURE_3D
, t
.tex
, 0, 9);
227 if (!piglit_check_gl_error(GL_NO_ERROR
))
230 if (!t
.check_fbo_status(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
))
233 /* Now try slice 7. This should work.
235 glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
,
236 GL_TEXTURE_3D
, t
.tex
, 0, 7);
238 if (!piglit_check_gl_error(GL_NO_ERROR
))
241 if (!t
.check_fbo_status(GL_FRAMEBUFFER_COMPLETE
))
248 * Common code the verify attaching an invalid layer of an array texture
249 * results in incompleteness.
252 invalid_array_layer_common(incomplete_fbo_test
&t
)
254 const unsigned scale
= (t
.target
== GL_TEXTURE_CUBE_MAP_ARRAY
) ? 6 : 1;
256 /* The texture has only 8 layers (0 through 7), but try to attach
257 * layer 8 and layer 9 to the FBO.
259 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
,
260 t
.tex
, 0, 8 * scale
);
262 if (!piglit_check_gl_error(GL_NO_ERROR
))
265 if (!t
.check_fbo_status(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
))
268 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
,
269 t
.tex
, 0, 9 * scale
);
271 if (!piglit_check_gl_error(GL_NO_ERROR
))
274 if (!t
.check_fbo_status(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
))
277 /* Now try layer 7. This should work.
279 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
,
280 t
.tex
, 0, 7 * scale
);
282 if (!piglit_check_gl_error(GL_NO_ERROR
))
285 if (!t
.check_fbo_status(GL_FRAMEBUFFER_COMPLETE
))
291 * Verify that attaching an invalid layer of a 1D array texture results in
294 extern "C" enum piglit_result
295 invalid_1d_array_layer(void *data
)
297 static const char subtest_name
[] =
298 "invalid layer of a 1D-array texture";
300 if (!piglit_is_extension_supported("GL_EXT_texture_array")
301 && piglit_get_gl_version() < 30) {
305 incomplete_fbo_test
t(subtest_name
, GL_TEXTURE_1D_ARRAY
);
307 /* Create a texture with only 8 layers (0 through 7), but try to
308 * attach layer 8 and layer 9 to the FBO.
310 glTexImage2D(GL_TEXTURE_1D_ARRAY
, 0, GL_RGBA
, 8, 8, 0, GL_RGBA
,
311 GL_UNSIGNED_BYTE
, NULL
);
313 return invalid_array_layer_common(t
);
317 * Verify that attaching an invalid layer of a 2D array texture results in
320 extern "C" enum piglit_result
321 invalid_2d_array_layer(void *data
)
323 static const char subtest_name
[] =
324 "invalid layer of a 2D-array texture";
326 if (!piglit_is_extension_supported("GL_EXT_texture_array")
327 && piglit_get_gl_version() < 30) {
331 incomplete_fbo_test
t(subtest_name
, GL_TEXTURE_2D_ARRAY
);
333 /* Create a texture with only 8 layers (0 through 7), but try to
334 * attach layer 8 and layer 9 to the FBO.
336 glTexImage3D(GL_TEXTURE_2D_ARRAY
, 0, GL_RGBA
, 8, 8, 8, 0, GL_RGBA
,
337 GL_UNSIGNED_BYTE
, NULL
);
339 return invalid_array_layer_common(t
);
343 * Verify that attaching an invalid layer of a cube array texture results in
346 extern "C" enum piglit_result
347 invalid_cube_array_layer(void *data
)
349 static const char subtest_name
[] =
350 "invalid layer of a cube-array texture";
352 if (!piglit_is_extension_supported("GL_ARB_texture_cube_map_array")
353 && piglit_get_gl_version() < 40) {
357 incomplete_fbo_test
t(subtest_name
, GL_TEXTURE_CUBE_MAP_ARRAY
);
359 /* Create a texture with only 8 layers (0 through 7), but try to
360 * attach layer 8 and layer 9 to the FBO.
362 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY
, 0, GL_RGBA
, 8, 8, 8 * 6, 0,
363 GL_RGBA
, GL_UNSIGNED_BYTE
, NULL
);
365 return invalid_array_layer_common(t
);
369 * Verify that deleting the texture attached the currently bound FBO
370 * results in incompleteness.
372 extern "C" enum piglit_result
373 delete_texture_of_current_fbo(void *data
)
375 incomplete_fbo_test
t("delete texture of bound FBO",
378 /* Create a small color texture and attach it. Everything should
379 * be fine at this point.
381 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
, 4, 4, 0, GL_RGBA
,
382 GL_UNSIGNED_BYTE
, NULL
);
383 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
,
384 GL_TEXTURE_2D
, t
.tex
, 0);
386 if (!piglit_check_gl_error(GL_NO_ERROR
))
389 if (!t
.check_fbo_status(GL_FRAMEBUFFER_COMPLETE
))
392 /* Now unbind the texture and delete it. t.rb is set to zero so
393 * that the destructor won't try to delete it again.
395 glBindTexture(GL_TEXTURE_2D
, 0);
396 glDeleteTextures(1, &t
.tex
);
399 /* Now the deleted attachment is "missing."
401 if (!t
.check_fbo_status(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
))
408 * Verify that deleting the renderbuffer attached the currently bound FBO
409 * results in incompleteness.
411 extern "C" enum piglit_result
412 delete_renderbuffer_of_current_fbo(void *data
)
414 incomplete_fbo_test
t("delete renderbuffer of bound FBO",
417 /* Create a small color renderbuffer and attach it. Everything should
418 * be fine at this point.
420 glRenderbufferStorage(GL_RENDERBUFFER
, GL_RGBA8
, 4, 4);
421 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
,
422 GL_RENDERBUFFER
, t
.rb
);
424 if (!piglit_check_gl_error(GL_NO_ERROR
))
427 if (!t
.check_fbo_status(GL_FRAMEBUFFER_COMPLETE
))
430 /* Now unbind the renderbuffer and delete it. t.rb is set to zero so
431 * that the destructor won't try to delete it again.
433 glBindRenderbuffer(GL_RENDERBUFFER
, 0);
434 glDeleteRenderbuffers(1, &t
.rb
);
437 /* Now the deleted attachment is "missing."
439 if (!t
.check_fbo_status(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
))
452 piglit_init(int argc
, char **argv
)
454 enum piglit_result result
= PIGLIT_SKIP
;
456 piglit_require_extension("GL_ARB_framebuffer_object");
458 piglit_subtest tests
[] = {
459 { "0x0 texture", "", incomplete_0_by_0_texture
, NULL
},
460 { "0x0 renderbuffer", "", incomplete_0_by_0_renderbuffer
, NULL
},
461 { "invalid slice of 3D texture", "", invalid_3d_slice
, NULL
},
462 { "invalid layer of a 1D-array texture", "", invalid_1d_array_layer
, NULL
},
463 { "invalid layer of a 2D-array texture", "", invalid_2d_array_layer
, NULL
},
464 { "invalid layer of a cube-array texture", "", invalid_cube_array_layer
, NULL
},
465 { "delete texture of bound FBO", "", delete_texture_of_current_fbo
, NULL
},
466 { "delete renderbuffer of bound FBO", "", delete_renderbuffer_of_current_fbo
, NULL
},
467 { NULL
, NULL
, NULL
, NULL
}
470 result
= piglit_run_selected_subtests(tests
, NULL
, 0, result
);
472 piglit_report_result(result
);