This test covers following cases: - Blit multisample-to-multisample with matching sample count - Blit multisample-to-multisample with non-matching sample count - Blit multisample-to-multisample with non-matching format - Blit multisample-to-multisample nonmatching buffer size - Blit singlesample-to-multisample
Signed-off-by: Anuj Phogat <[email protected]> --- tests/all.tests | 1 + .../ext_framebuffer_multisample/CMakeLists.gl.txt | 1 + tests/spec/ext_framebuffer_multisample/blit.c | 454 ++++++++++++++++++++ 3 files changed, 456 insertions(+), 0 deletions(-) create mode 100644 tests/spec/ext_framebuffer_multisample/blit.c diff --git a/tests/all.tests b/tests/all.tests index 7d3d239..49288fb 100644 --- a/tests/all.tests +++ b/tests/all.tests @@ -1277,6 +1277,7 @@ arb_vertex_program['minmax'] = concurrent_test('arb_vertex_program-minmax') ext_framebuffer_multisample = Group() spec['EXT_framebuffer_multisample'] = ext_framebuffer_multisample +ext_framebuffer_multisample['blit'] = concurrent_test('ext_framebuffer_multisample-blit') ext_framebuffer_multisample['dlist'] = concurrent_test('ext_framebuffer_multisample-dlist') ext_framebuffer_multisample['minmax'] = concurrent_test('ext_framebuffer_multisample-minmax') ext_framebuffer_multisample['negative-copypixels'] = concurrent_test('ext_framebuffer_multisample-negative-copypixels') diff --git a/tests/spec/ext_framebuffer_multisample/CMakeLists.gl.txt b/tests/spec/ext_framebuffer_multisample/CMakeLists.gl.txt index c451f9f..be3c013 100644 --- a/tests/spec/ext_framebuffer_multisample/CMakeLists.gl.txt +++ b/tests/spec/ext_framebuffer_multisample/CMakeLists.gl.txt @@ -12,6 +12,7 @@ link_libraries ( ) piglit_add_executable (ext_framebuffer_multisample-accuracy accuracy.cpp) +piglit_add_executable (ext_framebuffer_multisample-blit blit.c) piglit_add_executable (ext_framebuffer_multisample-dlist dlist.c) piglit_add_executable (ext_framebuffer_multisample-minmax minmax.c) piglit_add_executable (ext_framebuffer_multisample-negative-copypixels negative-copypixels.c) diff --git a/tests/spec/ext_framebuffer_multisample/blit.c b/tests/spec/ext_framebuffer_multisample/blit.c new file mode 100644 index 0000000..3da16fc --- /dev/null +++ b/tests/spec/ext_framebuffer_multisample/blit.c @@ -0,0 +1,454 @@ +/* + * Copyright © 2012 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "piglit-util.h" +/** + * @file blit.c + * + * This test verifies glBlitFramebuffer() with multisample framebuffer objects. + * We generate FBOs with specified sample count, clear them to unique colors, + * do blitting operation and then probe their color buffers to verify against + * expected values. + * + * Tests following cases: + * - Blit multisample-to-multisample with matching sample count + * - Blit multisample-to-multisample with non-matching sample count + * - Blit multisample-to-multisample with non-matching format + * - Blit multisample-to-multisample nonmatching buffer size + * - Blit singlesample-to-multisample + * + * Bottom half of framebuffer draws contents of fbo_ms0 before blit operation. + * Top half of framebuffer draws contents of fbo_ms0 after blit operatrion. + * + */ + +int piglit_width = 500; +int piglit_height = 200; + +int piglit_window_mode = GLUT_DOUBLE | GLUT_RGBA | GLUT_ALPHA; +int max_samples; +static GLenum fbo_formats[] = { + GL_RED, + GL_RG, + GL_RGB, + GL_ALPHA, + /* TODO: Add testing for depth and stencil buffers */ + //GL_DEPTH_COMPONENT, + //GL_STENCIL_INDEX, + }; + +struct fbo_data { + GLuint fb_handle; + GLuint rb_handle; + GLuint tex_handle; + GLuint width; + GLuint height; + GLint samples; + GLenum format; }; + +/* Function to switch ON/OFF MSAA in a FBO */ +static void +setup_fbo(struct fbo_data *fbo) +{ + GLint samples, sample_buffers; + GLenum status; + + glGenRenderbuffersEXT(1, &fbo->rb_handle); + glBindRenderbufferEXT(GL_RENDERBUFFER, fbo->rb_handle); + + if (fbo->samples) + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, + fbo->samples, + fbo->format, + fbo->width, + fbo->height); + else + glRenderbufferStorage(GL_RENDERBUFFER, + fbo->format, + fbo->width, + fbo->height); + + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + GL_RENDERBUFFER, fbo->rb_handle); + + status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { + fprintf(stderr, "FBO incomplete, format = %s\n", + piglit_get_gl_enum_name(fbo->format)); + piglit_report_result(PIGLIT_FAIL); + } + + if(!piglit_automatic) { + glGetIntegerv(GL_SAMPLES, &samples); + glGetIntegerv(GL_SAMPLE_BUFFERS, &sample_buffers); + printf("FBO handle = %d, GL_SAMPLES = %d, MSAA = %s\n", + fbo->fb_handle, samples, sample_buffers ? "ON" : "OFF"); + } +} + +static void +init_fbo_data(struct fbo_data *fbo) +{ + fbo->width = piglit_width / 5; + fbo->height = piglit_height / 2; + fbo->format = GL_RGBA; +} + +static void +generate_fbo(struct fbo_data *fbo) +{ + glGenFramebuffersEXT(1, &fbo->fb_handle); + glBindFramebufferEXT(GL_FRAMEBUFFER, fbo->fb_handle); + setup_fbo(fbo); +} + +static void +destroy_fbo(struct fbo_data *fbo) +{ + glDeleteRenderbuffersEXT(1, &fbo->rb_handle); + glDeleteFramebuffersEXT(1, &fbo->fb_handle); + fbo->rb_handle = fbo->fb_handle = 0; +} + +static void +blit_fbo(int src_x1, int src_y1, int src_x2, int src_y2, + int dst_x1, int dst_y1, int dst_x2, int dst_y2, + struct fbo_data *src_fbo, struct fbo_data *dst_fbo, + bool blit_to_default) +{ + if (blit_to_default) + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); + else + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, + dst_fbo->fb_handle); + + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src_fbo->fb_handle); + + /* In case of multisample FBO, glBlitFramebufferEXT invokes the + * multisample to single sample resolution for each pixel */ + + glBlitFramebufferEXT(src_x1, src_y1, src_x2, src_y2, + dst_x1, dst_y1, dst_x2, dst_y2, + GL_COLOR_BUFFER_BIT, GL_NEAREST); +} + + +static bool +test_blit_ms_ms_matching_samples(void) +{ + bool result = true; + struct fbo_data fbo_ms0, fbo_ms1; + GLint i; + GLuint w, h; + GLfloat green[4] = {0.0, 1.0, 0.0, 1.0}; + + init_fbo_data(&fbo_ms0); init_fbo_data(&fbo_ms1); + w = fbo_ms0.width; h = fbo_ms0.height; + + for(i = 2; i <= max_samples; i += 2) { + fbo_ms0.samples = fbo_ms1.samples = i; + /* Create a fbo with multisample render buffer */ + generate_fbo(&fbo_ms0); + glClearColor(1.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* Blit the multisampled fbo in to default framebuffer */ + blit_fbo(0, 0, w, h, 0, 0, w, h, &fbo_ms0, NULL, true); + + /* Create another fbo with multisample render buffer */ + generate_fbo(&fbo_ms1); + glClearColor(0.0, 1.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* Blit fbo_ms1 to fbo_ms0 */ + blit_fbo(0, 0, w, h, 0, 0, w, h, &fbo_ms1, &fbo_ms0, false); + + result = piglit_check_gl_error(GL_NO_ERROR) + && result; + + /* Blit fbo_ms0 to default fb */ + blit_fbo(0, 0, w, h, 0, h, w, 2 * h, &fbo_ms0, NULL, true); + + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); + + /* Probe fbo_ms0 and compare to expected color. + */ + result = piglit_probe_rect_rgba(0, h, w, h, green) + && result; + + destroy_fbo(&fbo_ms0); + destroy_fbo(&fbo_ms1); + } + return result; +} + +static bool +test_blit_ms_ms_non_matching_samples(void) +{ + bool result = true; + struct fbo_data fbo_ms0, fbo_ms1; + GLint i; + GLuint w, h; + GLfloat yellow[4] = {1.0, 1.0, 0.0, 1.0}; + + init_fbo_data(&fbo_ms0); init_fbo_data(&fbo_ms1); + w = fbo_ms0.width; h = fbo_ms0.height; + + for(i = 4; i <= max_samples; i += 2) { + fbo_ms0.samples = i; fbo_ms1.samples = i - 2; + /* Create a fbo with multisample render buffer */ + generate_fbo(&fbo_ms0); + glClearColor(1.0, 1.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* Blit the multisampled fbo in to default framebuffer */ + blit_fbo(0, 0, w, h, w, 0, 2 * w, h, &fbo_ms0, NULL, true); + + /* Create another fbo with multisample render buffer */ + generate_fbo(&fbo_ms1); + glClearColor(0.0, 1.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* Blit fbo_ms1 to fbo_ms0 */ + blit_fbo(0, 0, w, h, 0, 0, w, h, &fbo_ms1, &fbo_ms0, false); + + result = piglit_check_gl_error(GL_INVALID_OPERATION) + && result; + + /* Verify that no blitting is done. Blit fbo_ms0 to default fb. + */ + blit_fbo(0, 0, w, h, w, h, 2 * w, 2 * h, &fbo_ms0, NULL, true); + + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); + + /* Probe fbo_ms0 and compare to expected color. + */ + result = piglit_probe_rect_rgba(w, h, w, h, yellow) + && result; + + destroy_fbo(&fbo_ms0); + destroy_fbo(&fbo_ms1); + } + return result; +} + +static bool +test_blit_ms_ms_non_matching_formats(void) +{ + bool result = true; + struct fbo_data fbo_ms0, fbo_ms1; + GLint i, j; + GLuint w, h; + GLfloat blue[4] = {0.0, 0.0, 1.0, 1.0}; + + init_fbo_data(&fbo_ms0); init_fbo_data(&fbo_ms1); + w = fbo_ms0.width; h = fbo_ms0.height; + + for(j = 0; j < ARRAY_SIZE(fbo_formats); j++) { + for(i = 2; i <= max_samples; i += 2) { + fbo_ms0.samples = fbo_ms1.samples = i; + fbo_ms1.format = fbo_formats[j]; + + /* Create a fbo with multisample render buffer */ + generate_fbo(&fbo_ms0); + glClearColor(0.0, 0.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* Blit the multisampled fbo in to default + * framebuffer */ + blit_fbo(0, 0, w, h, 2 * w, 0, 3 * w, h, &fbo_ms0, NULL, true); + + /* Create another fbo with multisample render buffer */ + generate_fbo(&fbo_ms1); + glClearColor(0.4, 0.6, 0.8, 0.5); + glClear(GL_COLOR_BUFFER_BIT); + + /* Blit fbo_ms1 to fbo_ms0 */ + blit_fbo(0, 0, w, h, 0, 0, w, h, &fbo_ms1, &fbo_ms0, false); + + result = piglit_check_gl_error(GL_INVALID_OPERATION) + && result; + + /* Blit fbo_ms0 to default fb */ + blit_fbo(0, 0, w, h, 2 * w, h, 3 * w, 2 * h, &fbo_ms0, NULL, true); + + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); + + /* Probe fbo_ms0 and compare to expected color */ + result = piglit_probe_rect_rgba(2 * w, h, w, h, blue) + && result; + + destroy_fbo(&fbo_ms0); + destroy_fbo(&fbo_ms1); + } + } + return result; +} + +static bool test_blit_ms_ms_non_matching_buffer_size(void) +{ + bool result = true; + struct fbo_data fbo_ms0, fbo_ms1; + GLfloat cyan[4] = {0.0, 1.0, 1.0, 1.0}; + GLint i; + GLuint w, h; + + init_fbo_data(&fbo_ms0); init_fbo_data(&fbo_ms1); + w = fbo_ms0.width; h = fbo_ms0.height; + + fbo_ms1.width = piglit_width / 8; + fbo_ms1.height = piglit_height/2; + + for(i = 2; i <= max_samples; i += 2) { + + fbo_ms0.samples = fbo_ms1.samples = i; + + /* Create a fbo with multisample render buffer */ + generate_fbo(&fbo_ms0); + glClearColor(0.0, 1.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* Blit the multisampled fbo in to default framebuffer */ + blit_fbo(0, 0, w, h, 3 * w, 0, 4 * w, h, &fbo_ms0, NULL, true); + + /* Create another fbo with multisample render buffer */ + generate_fbo(&fbo_ms1); + glClearColor(0.0, 1.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* Blit fbo_ms1 to fbo_ms0 */ + blit_fbo(0, 0, fbo_ms1.width, fbo_ms1.height, + 0, 0, w, h, &fbo_ms1, &fbo_ms0, false); + + result = piglit_check_gl_error(GL_INVALID_OPERATION) + && result; + + /* Blit fbo_ms0 to default fb */ + blit_fbo(0, 0, w, h, 3 * w, h, 4 * w, 2 * h, &fbo_ms0, NULL, true); + + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); + + /* Probe fbo_ms0 and compare to expected color. + */ + result = piglit_probe_rect_rgba(3 * w, h, w, h, cyan) + && result; + + destroy_fbo(&fbo_ms0); + destroy_fbo(&fbo_ms1); + } + return result; +} + +static bool +test_blit_ss_ms(void) +{ + bool result = true; + struct fbo_data fbo_ms0, fbo_ss1; + GLfloat green[4] = {0.0, 1.0, 0.0, 1.0}; + GLint i; + GLuint w, h; + + init_fbo_data(&fbo_ms0); init_fbo_data(&fbo_ss1); + w = fbo_ms0.width; h = fbo_ms0.height; + + for(i = 2; i <= max_samples; i += 2) { + fbo_ms0.samples = i; fbo_ss1.samples = 0; + + /* Create a fbo with multisample render buffer */ + generate_fbo(&fbo_ms0); + glClearColor(1.0, 0.0, 1.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* Blit the multisampled fbo in to default framebuffer */ + blit_fbo(0, 0, w, h, 4 * w, 0, 5 * w, h, &fbo_ms0, NULL, true); + + /* Create another fbo with single sample render buffer */ + generate_fbo(&fbo_ss1); + glClearColor(0.0, 1.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + /* Blit fbo_ss1 to fbo_ms0 */ + blit_fbo(0, 0, w, h, 0, 0, w, h, &fbo_ss1, &fbo_ms0, false); + + result = piglit_check_gl_error(GL_NO_ERROR) + && result; + + /* Blit fbo_ms0 to default fb */ + blit_fbo(0, 0, w, h, 4 * w, h, 5 * w, 2 * h, &fbo_ms0, NULL, true); + + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); + + /* Probe fbo_ms0 and compare to expected color */ + result = piglit_probe_rect_rgba(4 * w, h, w, h, green) + && result; + + destroy_fbo(&fbo_ms0); + destroy_fbo(&fbo_ss1); + } + return result; +} + +enum piglit_result +piglit_display(void) +{ + bool pass = true; + + glClearColor(0.4, 0.4, 0.4, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + glGetIntegerv(GL_MAX_SAMPLES, &max_samples); + + /* Blit multisample-to-multisample with matching sample count */ + pass = test_blit_ms_ms_matching_samples() + && pass; + + /* Blit multisample-to-multisample with non-matching sample count */ + pass = test_blit_ms_ms_non_matching_samples() + && pass; + + /* Blit multisample-to-multisample with non-matching format */ + pass = test_blit_ms_ms_non_matching_formats() + && pass; + + /* Blit multisample-to-multisample with non-matching buffer size */ + pass = test_blit_ms_ms_non_matching_buffer_size() + && pass; + + /* Blit singlesample-to-multisample */ + pass = test_blit_ss_ms() + && pass; + + if (!piglit_automatic) + piglit_present_results(); + + return (pass ? PIGLIT_PASS : PIGLIT_FAIL); +} + +void +piglit_init(int argc, char **argv) +{ + piglit_ortho_projection(piglit_width, piglit_height, GL_TRUE); + piglit_require_extension("GL_EXT_framebuffer_multisample"); + piglit_require_extension("GL_EXT_framebuffer_blit"); +} -- 1.7.7.6 _______________________________________________ Piglit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/piglit
