README: recommend Ninja by default and switch to cmake --build
[piglit.git] / tests / fbo / fbo-scissor-blit.c
blob574454518ceb6cfa931bb296ba4536a3605603c4
1 /*
2 * Copyright © 2012 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
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.
24 /**
25 * \file fbo-scissor-blit.c
27 * Since window system framebuffers use a different coordinate system
28 * than fbo's, it is important to check that glBlitFramebuffer()
29 * interprets scissor coordinates correctly depending whether the
30 * destination framebuffer is an fbo or a window. This test verifies
31 * proper scissor operation in both cases.
33 * The test takes a single command-line argument: "window" to test
34 * scissoring in a window, and "fbo" to test scissoring in an fbo. In
35 * the fbo case, the final image is blitted to the window afterwards
36 * (without scissoring it) so that failures can be easily diagnosed.
39 #include "piglit-util-gl.h"
41 static const int width = 128, height = 128;
43 PIGLIT_GL_TEST_CONFIG_BEGIN
45 config.supports_gl_compat_version = 10;
47 config.window_width = width;
48 config.window_height = height;
49 config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA;
50 config.khr_no_error_support = PIGLIT_NO_ERRORS;
52 PIGLIT_GL_TEST_CONFIG_END
53 static GLuint src_fbo;
54 static GLuint ref_fbo;
55 static GLuint dst_fbo;
58 static GLuint
59 setup_framebuffer()
61 GLuint fbo, rb;
62 glGenFramebuffers(1, &fbo);
63 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
64 glGenRenderbuffers(1, &rb);
65 glBindRenderbuffer(GL_RENDERBUFFER, rb);
66 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, width, height);
67 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
68 GL_RENDERBUFFER, rb);
69 if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)
70 != GL_FRAMEBUFFER_COMPLETE) {
71 printf("Framebuffer incomplete\n");
72 piglit_report_result(PIGLIT_FAIL);
75 return fbo;
79 static void
80 print_usage_and_exit(char *prog_name)
82 printf("Usage: %s <dst_fb_type>\n"
83 " where <dst_fb_type> is one of:\n"
84 " fbo\n"
85 " window\n",
86 prog_name);
87 piglit_report_result(PIGLIT_FAIL);
91 void
92 piglit_init(int argc, char **argv)
94 bool blit_to_fbo;
96 if (argc != 2)
97 print_usage_and_exit(argv[0]);
99 if (strcmp(argv[1], "window") == 0) {
100 blit_to_fbo = false;
101 if (piglit_winsys_fbo != 0) {
102 fprintf(stderr, "window case is for using a winsys surface, must be run without -fbo\n");
103 piglit_report_result(PIGLIT_FAIL);
105 } else if (strcmp(argv[1], "fbo") == 0)
106 blit_to_fbo = true;
107 else {
108 blit_to_fbo = false;
109 print_usage_and_exit(argv[0]);
112 piglit_require_extension("GL_ARB_framebuffer_object");
114 src_fbo = setup_framebuffer();
115 ref_fbo = setup_framebuffer();
116 if (blit_to_fbo)
117 dst_fbo = setup_framebuffer();
118 else
119 dst_fbo = 0;
123 enum piglit_result
124 piglit_display(void)
126 float red[4] = {1.0, 0.0, 0.0, 0.0};
127 float green[4] = {0.0, 1.0, 0.0, 0.25};
128 float blue[4] = {0.0, 0.0, 1.0, 0.5};
129 float white[4] = {1.0, 1.0, 1.0, 1.0};
130 float grey[4] = {0.5, 0.5, 0.5, 0.5};
131 bool pass;
132 float *ref_image;
134 /* Draw the source image to src_fbo */
135 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, src_fbo);
136 glEnable(GL_SCISSOR_TEST);
138 glScissor(0, 0, width / 2, height / 2);
139 glClearColor(red[0], red[1], red[2], red[3]);
140 glClear(GL_COLOR_BUFFER_BIT);
142 glScissor(width / 2, 0, width / 2, height / 2);
143 glClearColor(green[0], green[1], green[2], green[3]);
144 glClear(GL_COLOR_BUFFER_BIT);
146 glScissor(0, height / 2, width / 2, height / 2);
147 glClearColor(blue[0], blue[1], blue[2], blue[3]);
148 glClear(GL_COLOR_BUFFER_BIT);
150 glScissor(width / 2, height / 2, width / 2, height / 2);
151 glClearColor(white[0], white[1], white[2], white[3]);
152 glClear(GL_COLOR_BUFFER_BIT);
154 glDisable(GL_SCISSOR_TEST);
156 glClearColor(grey[0], grey[1], grey[2], grey[3]);
158 /* Blit to dst_fbo, scissoring the image in an asymmetrical way. */
159 glBindFramebuffer(GL_READ_FRAMEBUFFER, src_fbo);
160 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst_fbo);
161 glClear(GL_COLOR_BUFFER_BIT);
162 glEnable(GL_SCISSOR_TEST);
163 glScissor(10, 20, width - 40, height - 60);
164 glBlitFramebuffer(0, 0, width, height,
165 0, 0, width, height,
166 GL_COLOR_BUFFER_BIT, GL_NEAREST);
167 glDisable(GL_SCISSOR_TEST);
169 /* Blit to ref_fbo, simulating the correct scissoring effect
170 * by manually adjusting the coordinates.
172 glBindFramebuffer(GL_READ_FRAMEBUFFER, src_fbo);
173 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, ref_fbo);
174 glClear(GL_COLOR_BUFFER_BIT);
175 glBlitFramebuffer(10, 20, width - 30, height - 40,
176 10, 20, width - 30, height - 40,
177 GL_COLOR_BUFFER_BIT, GL_NEAREST);
179 /* Read the reference image from ref_fbo */
180 ref_image = malloc(sizeof(float) * 4 * width * height);
181 glBindFramebuffer(GL_READ_FRAMEBUFFER, ref_fbo);
182 glReadPixels(0, 0, width, height, GL_RGBA, GL_FLOAT, ref_image);
184 /* Compare the image in dst_fbo with the reference image */
185 glBindFramebuffer(GL_READ_FRAMEBUFFER, dst_fbo);
186 pass = piglit_probe_image_rgba(0, 0, width, height, ref_image);
188 if (dst_fbo != 0) {
189 /* Show the contents of dst_fbo in the window */
190 glBindFramebuffer(GL_READ_FRAMEBUFFER, dst_fbo);
191 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, piglit_winsys_fbo);
192 glBlitFramebuffer(0, 0, width, height,
193 0, 0, width, height,
194 GL_COLOR_BUFFER_BIT, GL_NEAREST);
197 free(ref_image);
198 piglit_present_results();
200 return pass ? PIGLIT_PASS : PIGLIT_FAIL;