/* * Copyright 2014 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. */ /** @file simple.c * * A simple test of glCopyImageSubData that copies a square from one * 2D texture to another and back. This test exercises texture to texture, * texture to renderbuffer, renderbuffer to texture, and renderbuffer to * renderbuffer copies. This test also exercises copying from one texture * or renderbuffer to the same texture or renderbuffer */ #include "piglit-util-gl.h" PIGLIT_GL_TEST_CONFIG_BEGIN config.supports_gl_compat_version = 13; config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE; config.khr_no_error_support = PIGLIT_NO_ERRORS; PIGLIT_GL_TEST_CONFIG_END static const float green[3] = {0.0, 1.0, 0.0}; static const float red[3] = {1.0, 0.0, 0.0}; static const float blue[3] = {0.0, 0.0, 1.0}; int renderbuffers = 0; void piglit_init(int argc, char **argv) { int i; piglit_require_extension("GL_ARB_copy_image"); piglit_require_extension("GL_EXT_framebuffer_object"); for (i = 0; i < argc; ++i) { if (strcmp(argv[i], "--tex-to-tex") == 0) renderbuffers = 0; else if (strcmp(argv[i], "--tex-to-rb") == 0) renderbuffers = 1; else if (strcmp(argv[i], "--rb-to-rb") == 0) renderbuffers = 2; } } struct image { GLuint name, fbo; GLenum target; }; static void image_init(struct image *image, GLenum target, GLenum internalformat) { image->target = target; glGenFramebuffersEXT(1, &image->fbo); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, image->fbo); if (image->target == GL_RENDERBUFFER_EXT) { glGenRenderbuffersEXT(1, &image->name); glBindRenderbufferEXT(GL_RENDERBUFFER, image->name); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalformat, 64, 64); glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, image->target, image->name); } else { glGenTextures(1, &image->name); glBindTexture(image->target, image->name); glTexImage2D(image->target, 0, internalformat, 64, 64, 0, internalformat, GL_BYTE, NULL); glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, image->target, image->name, 0); } } static void image_destroy(struct image *image) { if (image->target == GL_RENDERBUFFER_EXT) glDeleteRenderbuffersEXT(1, &image->name); else glDeleteTextures(1, &image->name); glDeleteFramebuffers(1, &image->fbo); } static void image_fill(struct image *image, const float *color) { glClearColor(color[0], color[1], color[2], 1.0f); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, image->fbo); glClear(GL_COLOR_BUFFER_BIT); } static void image_draw(struct image *image, int x, int y) { if (image->target == GL_RENDERBUFFER_EXT) { glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, image->fbo); glBlitFramebufferEXT(0, 0, 64, 64, x, y, x + 64, y + 64, GL_COLOR_BUFFER_BIT, GL_NEAREST); } else { /* Set up or GL environment for rendering */ piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glBindTexture(image->target, image->name); piglit_draw_rect_tex(x, y, 64, 64, 0, 0, 1, 1); glDisable(GL_TEXTURE_2D); } } enum piglit_result piglit_display(void) { bool pass = true; struct image images[2]; if (renderbuffers >= 1) images[0].target = GL_RENDERBUFFER_EXT; else images[0].target = GL_TEXTURE_2D; if (renderbuffers == 2) images[1].target = GL_RENDERBUFFER_EXT; else images[1].target = GL_TEXTURE_2D; image_init(&images[0], images[0].target, GL_RGB); image_init(&images[1], images[1].target, GL_RGB); image_fill(&images[0], green); image_fill(&images[1], red); glCopyImageSubData(images[0].name, images[0].target, 0, 0, 0, 0, images[1].name, images[1].target, 0, 17, 11, 0, 32, 32, 1); pass &= piglit_check_gl_error(GL_NO_ERROR); /* We should now have a green square on red */ glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, images[1].fbo); pass &= piglit_probe_rect_rgb(17, 11, 32, 32, green); pass &= piglit_probe_rect_rgb(0, 0, 64, 11, red); pass &= piglit_probe_rect_rgb(0, 11, 17, 32, red); pass &= piglit_probe_rect_rgb(49, 11, 15, 32, red); pass &= piglit_probe_rect_rgb(0, 43, 64, 21, red); image_fill(&images[0], blue); glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, images[0].fbo); pass &= piglit_probe_rect_rgb(0, 0, 64, 64, blue); glCopyImageSubData(images[1].name, images[1].target, 0, 17, 11, 0, images[0].name, images[0].target, 0, 0, 32, 0, 32, 32, 1); pass &= piglit_check_gl_error(GL_NO_ERROR); /* This should be a green square on blue (no red!) */ glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, images[0].fbo); pass &= piglit_probe_rect_rgb(0, 32, 32, 32, green); pass &= piglit_probe_rect_rgb(0, 0, 64, 32, blue); pass &= piglit_probe_rect_rgb(32, 32, 32, 32, blue); glCopyImageSubData(images[0].name, images[0].target, 0, 0, 32, 0, images[0].name, images[0].target, 0, 32, 0, 0, 32, 32, 1); pass &= piglit_check_gl_error(GL_NO_ERROR); /* This should be a blue/green checkerboard */ glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, images[0].fbo); pass &= piglit_probe_rect_rgb(0, 0, 32, 32, blue); pass &= piglit_probe_rect_rgb(0, 32, 32, 32, green); pass &= piglit_probe_rect_rgb(32, 0, 32, 32, green); pass &= piglit_probe_rect_rgb(32, 32, 32, 32, blue); if (!piglit_automatic) { glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, piglit_winsys_fbo); image_draw(&images[1], 0, 0); image_draw(&images[0], 64, 0); piglit_present_results(); } image_destroy(&images[0]); image_destroy(&images[1]); return pass ? PIGLIT_PASS : PIGLIT_FAIL; }