2 * Copyright © 2019 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 DEALINGS
24 * \file builtin-gl-sample-mask-mrt-alpha-to-coverage-combinations.cpp
26 * Test verifies correct work of alpha-to-coverage with every variation of
27 * sample mask, all levels of MSAA and different number of render targets.
29 * \author Andrii Kryvytskyi <andrii.o.kryvytskyi@globallogic.com>
32 #include "piglit-fbo.h"
33 using namespace piglit_util_fbo
;
34 PIGLIT_GL_TEST_CONFIG_BEGIN
36 config
.supports_gl_core_version
= 40;
38 config
.window_visual
= PIGLIT_GL_VISUAL_DOUBLE
| PIGLIT_GL_VISUAL_RGBA
;
39 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
41 /* 4 possible alphas and 2^16 possible sample masks */
42 config
.window_height
= 512;
43 config
.window_width
= 512;
45 PIGLIT_GL_TEST_CONFIG_END
48 make_fbo(int tex_attachments_num
, int samples_num
)
50 FboConfig
config(samples_num
, piglit_width
, piglit_height
);
51 config
.num_rb_attachments
= 0;
53 config
.num_tex_attachments
= tex_attachments_num
;
55 for (int i
= 0; i
< tex_attachments_num
; i
++)
56 config
.tex_attachment
[i
] = GL_COLOR_ATTACHMENT0
+ i
;
61 if (!piglit_check_gl_error(GL_NO_ERROR
))
62 piglit_report_result(PIGLIT_FAIL
);
67 static GLuint test_prog
;
68 static GLuint check_prog
;
69 static GLint max_samples_num
;
70 static GLint max_attachments_num
;
72 static bool should_all_be_checked
;
73 static int num_samples_to_check
;
74 static int num_render_targets_to_check
;
76 static const char *test_vs
=
78 "in vec4 piglit_vertex;\n"
82 " gl_Position = piglit_vertex;\n"
85 static const char *test_fs
=
87 "#extension GL_ARB_sample_shading : enable\n"
89 "layout(pixel_center_integer) in vec4 gl_FragCoord;\n"
90 "uniform int render_targets;\n"
91 "uniform int samples_num;\n"
92 "uniform int screen_width;\n"
93 "out vec4 out_color[gl_MaxDrawBuffers];\n"
98 " float fragment_index = gl_FragCoord.x +"
99 " gl_FragCoord.y * screen_width;\n"
100 " int sample_permutations = int(exp2(samples_num));\n"
102 " vec4 color = vec4(\n"
103 " mod(gl_FragCoord.x, 2),\n"
104 " mod(gl_FragCoord.y, 2),\n"
105 " mod(fragment_index, 2),\n"
106 " mod(gl_FragCoord.x, 4) - 1\n"
109 " gl_SampleMask[0] = int(mod("
110 " fragment_index / 4,"
111 " sample_permutations)"
114 " out_color[0] = color;\n"
115 " for (int i = 1; i < render_targets; i++) {\n"
117 " mod(gl_FragCoord.y, 2),\n"
118 " mod(fragment_index, 2),\n"
119 " mod(gl_FragCoord.x, 2),\n"
123 " out_color[i] = color;\n"
127 static const char *check_vs
=
129 "in vec4 piglit_vertex;\n"
133 " gl_Position = piglit_vertex;\n"
136 static const char *check_fs
=
138 "#extension GL_ARB_texture_multisample : require\n"
140 "layout(pixel_center_integer) in vec4 gl_FragCoord;\n"
141 "uniform int screen_width;\n"
142 "uniform int screen_height;\n"
143 "uniform int samples_num;\n"
144 "uniform int render_target;\n"
145 "uniform sampler2DMS tex;\n"
147 "out vec4 out_color;\n"
149 "vec4 get_expected_color()\n"
151 " float fragment_index = gl_FragCoord.x +"
152 " gl_FragCoord.y * screen_width;\n"
153 " vec4 expected = vec4(0.0);\n"
154 " float alpha = clamp(mod(gl_FragCoord.x, 4) - 1, 0, 1);\n"
156 " if (alpha == 0.0f) {\n"
157 " expected = vec4(0.0);\n"
158 " } else if (render_target == 0) {\n"
159 " expected = vec4(\n"
160 " mod(gl_FragCoord.x, 2),\n"
161 " mod(gl_FragCoord.y, 2),\n"
162 " mod(fragment_index, 2),\n"
166 " expected = vec4(\n"
167 " mod(gl_FragCoord.y, 2),\n"
168 " mod(fragment_index, 2),\n"
169 " mod(gl_FragCoord.x, 2),\n"
174 " return expected;\n"
179 " vec4 expected = get_expected_color();\n"
180 " bool pass = true;\n"
182 " int fragment_index = int(gl_FragCoord.x +"
183 " gl_FragCoord.y * screen_width);\n"
184 " int sample_permutations = int(exp2(samples_num));\n"
185 " int sample_mask = int(mod("
186 " fragment_index / 4,"
187 " sample_permutations)"
190 " for (int i = 0; i < samples_num; i++) {\n"
191 " ivec2 texelToFetch = ivec2(gl_FragCoord.x, gl_FragCoord.y);\n"
192 " vec4 currentColor = texelFetch(tex, texelToFetch, i);\n"
194 " if ((sample_mask & (1 << i)) != 0)\n"
195 " pass = pass && (expected == currentColor);\n"
197 " pass = pass && (vec4(0.0) == currentColor);"
201 " out_color = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n"
203 " out_color = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n"
207 * Render to all specified texture attachments of the multisample fbo
208 * enabling alpha-to-coverage to make the implementation pass the additional
209 * alpha component from the first attachment when rendering into the
210 * second. Alpha value is being counted using current fragment coordinates
211 * to cover more possible variations of sample mask and alpha.
212 * The resulting sample mask will still be such as specified in
213 * the fragment shader because an alpha value of 1.0 maps to the
217 run_test(Fbo
&fbo
, int render_targets
, int samples_num
)
219 glUseProgram(test_prog
);
220 glUniform1i(glGetUniformLocation(test_prog
, "render_targets"),
222 glUniform1i(glGetUniformLocation(test_prog
, "samples_num"),
224 glUniform1i(glGetUniformLocation(test_prog
, "screen_width"),
227 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, fbo
.handle
);
228 glDrawBuffers(fbo
.config
.num_tex_attachments
,
229 fbo
.config
.tex_attachment
);
231 glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE
);
234 glClear(GL_COLOR_BUFFER_BIT
);
235 piglit_draw_rect(-1, -1, 2, 2);
237 glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE
);
239 return piglit_check_gl_error(GL_NO_ERROR
);
243 * Resolve the green component of each sample in case all checks are
244 * done and equal to expected values.
247 check(const Fbo
&fbo
, unsigned render_target
,
248 int render_targets_num
, int samples_num
)
251 const float expected
[] = { 0.0f
, 1.0f
, 0.0f
, 1.0f
};
253 glUseProgram(check_prog
);
254 glUniform1i(glGetUniformLocation(check_prog
, "tex"), 0);
255 glUniform1i(glGetUniformLocation(check_prog
, "samples_num"),
257 glUniform1i(glGetUniformLocation(check_prog
, "screen_width"),
259 glUniform1i(glGetUniformLocation(check_prog
, "screen_height"),
261 glUniform1i(glGetUniformLocation(check_prog
, "render_target"),
264 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, piglit_winsys_fbo
);
265 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE
, fbo
.color_tex
[render_target
]);
266 glViewport(0, 0, piglit_width
, piglit_height
);
268 glClear(GL_COLOR_BUFFER_BIT
);
269 piglit_draw_rect(-1, -1, 2, 2);
271 pass
&= piglit_check_gl_error(GL_NO_ERROR
);
272 pass
&= piglit_probe_rect_rgba(0, 0, piglit_width
, piglit_height
,
276 printf("Test failed with %d samples, %d render targets, "
277 "%d render target.\n",
278 samples_num
, render_targets_num
, render_target
);
280 piglit_present_results();
286 run_check(int samples_num
, int render_targets_num
)
290 Fbo fbo
= make_fbo(render_targets_num
, samples_num
);
292 pass
&= run_test(fbo
, render_targets_num
, samples_num
);
294 for (int render_target_to_check
= render_targets_num
- 1;
295 render_target_to_check
>= 0; render_target_to_check
--) {
296 pass
&= check(fbo
, render_target_to_check
, render_targets_num
,
304 print_usage_and_exit(char *prog_name
)
306 printf("%s Should be used without arguments or with: <samples_num>"
307 " <render_targets_num>\n",
310 piglit_report_result(PIGLIT_FAIL
);
313 void delete_programs()
315 glDeleteProgram(test_prog
);
316 glDeleteProgram(check_prog
);
320 piglit_init(int argc
, char **argv
)
322 piglit_require_extension("GL_ARB_texture_multisample");
323 piglit_require_extension("GL_ARB_sample_shading");
325 glGetIntegerv(GL_MAX_SAMPLES
, &max_samples_num
);
326 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS
, &max_attachments_num
);
328 /* 32 will have too many permutations */
329 max_samples_num
= max_samples_num
> 16 ? 16 : max_samples_num
;
332 should_all_be_checked
= true;
333 } else if (argc
== 3) {
334 should_all_be_checked
= false;
336 /* arg1 - samples_num */
337 char *end_ptr
= NULL
;
338 num_samples_to_check
= strtol(argv
[1], &end_ptr
, 0);
339 if (end_ptr
!= argv
[1] + strlen(argv
[1]))
340 print_usage_and_exit(argv
[0]);
342 /* arg2 - render_targets_num */
344 num_render_targets_to_check
= strtol(argv
[2], &end_ptr
, 0);
345 if (end_ptr
!= argv
[2] + strlen(argv
[2]))
346 print_usage_and_exit(argv
[0]);
348 if (num_samples_to_check
> max_samples_num
||
349 num_render_targets_to_check
> max_attachments_num
) {
350 printf("Error max supported samples = %d, max supported "
351 "color attachments = %d \n",
352 max_samples_num
, max_attachments_num
);
353 piglit_report_result(PIGLIT_FAIL
);
356 print_usage_and_exit(argv
[0]);
359 test_prog
= piglit_build_simple_program(test_vs
, test_fs
);
360 check_prog
= piglit_build_simple_program(check_vs
, check_fs
);
362 atexit(delete_programs
);
370 if (should_all_be_checked
) {
371 for (int samples_num
= 1; samples_num
<= max_samples_num
;
373 pass
&= run_check(samples_num
, 1) &&
374 run_check(samples_num
, 2) &&
375 run_check(samples_num
, max_attachments_num
);
378 pass
&= run_check(num_samples_to_check
, num_render_targets_to_check
);
381 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;