ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / ext_framebuffer_multisample / alpha-blending-after-rendering.c
blob816b634967959416106a53bff1dca43ecc2f5c95
1 /*
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
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
21 * DEALINGS IN THE SOFTWARE.
24 /** \file
26 * Verify that alpha blending works properly in multisample
27 * framebuffers even if it is preceded by normal (non-blended)
28 * rendering.
30 * In the fix for https://bugs.freedesktop.org/show_bug.cgi?id=53077,
31 * Mesa's i965 driver must convert a compressed multisampled buffer to
32 * an uncompressed buffer the first time it notices that alpha
33 * blending is being performed on the buffer. This test verifies that
34 * the conversion happens correctly. It specifically exercises pixels
35 * that are in the following states at the time of conversion:
37 * - Clear
38 * - Fully covered
39 * - Partially covered, partially clear
40 * - Partially covered by one color, partially by another color
43 #include "piglit-util-gl.h"
45 PIGLIT_GL_TEST_CONFIG_BEGIN
47 config.supports_gl_compat_version = 30;
48 config.supports_gl_core_version = 31;
49 config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
50 config.khr_no_error_support = PIGLIT_NO_ERRORS;
52 PIGLIT_GL_TEST_CONFIG_END
54 const char *vs_text =
55 "#version 130\n"
56 "in vec4 piglit_vertex;\n"
57 "void main()\n"
58 "{\n"
59 " gl_Position = piglit_vertex;\n"
60 "}\n";
62 const char *fs_text =
63 "#version 130\n"
64 "uniform vec4 color;\n"
65 "void main()\n"
66 "{\n"
67 " gl_FragColor = color;\n"
68 "}\n";
70 static GLuint prog, singlesampled_fbo;
71 static GLint color_loc;
72 static int num_samples;
75 static void
76 print_usage_and_exit(const char *prog_name)
78 printf("Usage: %s <num_samples>\n", prog_name);
79 piglit_report_result(PIGLIT_FAIL);
83 void
84 piglit_init(int argc, char **argv)
86 GLuint rb;
87 char *endptr;
88 GLint max_samples;
90 if (argc != 2)
91 print_usage_and_exit(argv[0]);
92 endptr = NULL;
93 num_samples = strtol(argv[1], &endptr, 0);
94 if (endptr != argv[1] + strlen(argv[1]))
95 print_usage_and_exit(argv[0]);
97 /* Test assumes that glSampleCoverage(0.5) will yield exactly
98 * 50% blending; this only works if num_samples is even and
99 * greater than zero.
101 if (num_samples <= 0 || num_samples % 2 != 0) {
102 printf("num_samples must be even and greater than zero.\n");
103 piglit_report_result(PIGLIT_FAIL);
106 /* Skip the test if num_samples > GL_MAX_SAMPLES */
107 glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
108 if (num_samples > max_samples) {
109 printf("num_samples = %d requested, but only %d supported.\n",
110 num_samples, max_samples);
111 piglit_report_result(PIGLIT_SKIP);
114 prog = piglit_build_simple_program(vs_text, fs_text);
115 color_loc = glGetUniformLocation(prog, "color");
117 /* Create the single-sampled fbo. We only need to create this
118 * once, since it isn't subject to the bugfix.
120 glGenFramebuffers(1, &singlesampled_fbo);
121 glGenRenderbuffers(1, &rb);
122 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, singlesampled_fbo);
123 glBindRenderbuffer(GL_RENDERBUFFER, rb);
124 glRenderbufferStorageMultisample(GL_RENDERBUFFER,
125 0 /* samples */,
126 GL_RGBA8 /* internalformat */,
127 piglit_width, piglit_height);
128 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
129 GL_RENDERBUFFER, rb);
130 if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)
131 != GL_FRAMEBUFFER_COMPLETE) {
132 printf("Single-sampled framebuffer incomplete\n");
133 piglit_report_result(PIGLIT_FAIL);
138 enum piglit_result
139 piglit_display(void)
141 GLuint msaa_fbo, rb;
142 bool pass = true;
143 GLfloat expected_ul[] = { 0.25, 0.0, 0.25, 0.75 };
144 GLfloat expected_ur[] = { 0.0, 0.25, 0.25, 0.75 };
145 GLfloat expected_ll[] = { 0.5, 0.0, 0.0, 0.75 };
146 GLfloat expected_lr[] = { 0.0, 0.5, 0.0, 0.75 };
148 /* Create a multisampled framebuffer. We need to do this here
149 * (rather than in piglit_init()) because the bugfix we are
150 * verifying only converts any given buffer once; we want to
151 * make sure we trigger the bugfix for every call to
152 * piglit_display().
154 glGenFramebuffers(1, &msaa_fbo);
155 glGenRenderbuffers(1, &rb);
156 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, msaa_fbo);
157 glBindRenderbuffer(GL_RENDERBUFFER, rb);
158 glRenderbufferStorageMultisample(GL_RENDERBUFFER,
159 num_samples,
160 GL_RGBA8 /* internalformat */,
161 piglit_width, piglit_height);
162 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
163 GL_RENDERBUFFER, rb);
164 if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)
165 != GL_FRAMEBUFFER_COMPLETE) {
166 printf("MSAA framebuffer incomplete\n");
167 pass = false;
170 /* Clear the framebuffer to red. */
171 glClearColor(1, 0, 0, 1);
172 glClear(GL_COLOR_BUFFER_BIT);
174 /* Paint the right half of the framebuffer green. */
175 glUseProgram(prog);
176 glDisable(GL_SAMPLE_COVERAGE);
177 glDisable(GL_BLEND);
178 glUniform4f(color_loc, 0, 1, 0, 1);
179 piglit_draw_rect(0, -1, 1, 2);
181 /* Paint the top half of the framebuffer blue, using 50%
182 * sample coverage.
184 glEnable(GL_SAMPLE_COVERAGE);
185 glSampleCoverage(0.5, GL_FALSE);
186 glUniform4f(color_loc, 0, 0, 1, 1);
187 piglit_draw_rect(-1, 0, 2, 1);
189 /* Paint black over the entire framebuffer, using 50% alpha
190 * blending.
192 glDisable(GL_SAMPLE_COVERAGE);
193 glEnable(GL_BLEND);
194 glBlendEquation(GL_FUNC_ADD);
195 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
196 glUniform4f(color_loc, 0, 0, 0, 0.5);
197 piglit_draw_rect(-1, -1, 2, 2);
199 /* Blit to the single-sampled fbo to force a multisample
200 * resolve. Note that we don't blit directly to the screen
201 * because the screen may be using SRGB, which might trigger
202 * the driver to do something other than linear averaging when
203 * resolving the samples.
205 glBindFramebuffer(GL_READ_FRAMEBUFFER, msaa_fbo);
206 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, singlesampled_fbo);
207 glBlitFramebuffer(0, 0, piglit_width, piglit_height,
208 0, 0, piglit_width, piglit_height,
209 GL_COLOR_BUFFER_BIT, GL_NEAREST);
211 /* Blit to the screen for ease in diagnosing failures. */
212 glBindFramebuffer(GL_READ_FRAMEBUFFER, singlesampled_fbo);
213 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, piglit_winsys_fbo);
214 glBlitFramebuffer(0, 0, piglit_width, piglit_height,
215 0, 0, piglit_width, piglit_height,
216 GL_COLOR_BUFFER_BIT, GL_NEAREST);
218 /* Check that the color is correct in each quadrant. */
219 pass = piglit_probe_rect_rgba(0, 0, piglit_width / 2,
220 piglit_height / 2, expected_ll) && pass;
221 pass = piglit_probe_rect_rgba(piglit_width - piglit_width / 2, 0,
222 piglit_width / 2, piglit_height / 2,
223 expected_lr) && pass;
224 pass = piglit_probe_rect_rgba(0, piglit_height - piglit_height / 2,
225 piglit_width / 2, piglit_height / 2,
226 expected_ul) && pass;
227 pass = piglit_probe_rect_rgba(piglit_width - piglit_width / 2,
228 piglit_height - piglit_height / 2,
229 piglit_width / 2, piglit_height / 2,
230 expected_ur) && pass;
232 piglit_present_results();
234 /* Clean up */
235 glDeleteRenderbuffers(1, &rb);
236 glDeleteFramebuffers(1, &msaa_fbo);
238 return pass ? PIGLIT_PASS : PIGLIT_FAIL;