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
21 * DEALINGS IN THE SOFTWARE.
26 * Verify that alpha blending works properly in multisample
27 * framebuffers even if it is preceded by normal (non-blended)
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:
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
56 "in vec4 piglit_vertex;\n"
59 " gl_Position = piglit_vertex;\n"
64 "uniform vec4 color;\n"
67 " gl_FragColor = color;\n"
70 static GLuint prog
, singlesampled_fbo
;
71 static GLint color_loc
;
72 static int num_samples
;
76 print_usage_and_exit(const char *prog_name
)
78 printf("Usage: %s <num_samples>\n", prog_name
);
79 piglit_report_result(PIGLIT_FAIL
);
84 piglit_init(int argc
, char **argv
)
91 print_usage_and_exit(argv
[0]);
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
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
,
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
);
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
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
,
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");
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. */
176 glDisable(GL_SAMPLE_COVERAGE
);
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%
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
192 glDisable(GL_SAMPLE_COVERAGE
);
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();
235 glDeleteRenderbuffers(1, &rb
);
236 glDeleteFramebuffers(1, &msaa_fbo
);
238 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;