framework/replay: disable AA accounting when comparing with no tolerance
[piglit.git] / tests / spec / arb_fragment_shader_interlock / image-load-store.c
blob597bcf7d528127515451a6a0953a957a7b3ce8d1
1 /*
2 * Copyright (c) 2015 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 #include "piglit-util-gl.h"
27 * A test to check whether GL_ARB_fragment_shader_interlock operates as
28 * expected. This test simulates blending behaviour by using image loads/stores
29 * to a 3D texture. The blending formula used is:
30 * result = current_alpha * current_color + (1 - current_alpha) * previous_color
31 * Multisampling is also enabled and tested at 2, 4, 8 and 16.
34 PIGLIT_GL_TEST_CONFIG_BEGIN
35 config.supports_gl_compat_version = 42;
36 config.supports_gl_core_version = 42;
37 config.window_width = 100;
38 config.window_height = 100;
39 config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DEPTH |
40 PIGLIT_GL_VISUAL_DOUBLE;
41 PIGLIT_GL_TEST_CONFIG_END
43 static GLuint prog, vao, tex_frame, tex_blend, fbo;
45 static GLuint
46 make_fbo(void)
48 GLuint fbo;
49 glGenFramebuffers(1, &fbo);
50 glBindFramebuffer(GL_FRAMEBUFFER, fbo );
51 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex_frame);
52 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
53 GL_TEXTURE_2D_MULTISAMPLE, tex_frame, 0);
55 return fbo;
58 static GLuint
59 make_shader_program(void)
61 static const char *vs_text =
62 "#version 430\n"
63 "layout(location = 0) in vec4 pos_in;\n"
64 "layout(location = 1) in vec4 col_in;\n"
65 "smooth out vec4 col_vary;\n"
66 "void main()\n"
67 "{\n"
68 " gl_Position = pos_in;\n"
69 " col_vary = col_in;\n"
70 "}\n";
72 static const char *fs_text =
73 "#version 430\n"
74 "#extension GL_ARB_fragment_shader_interlock: require\n"
75 "layout(pixel_interlock_ordered) in;\n"
76 "layout(rgba32f, binding = 0) uniform image3D img_output;\n"
77 "layout(location = 1) uniform int sample_rate;\n"
78 "smooth in vec4 col_vary;\n"
79 "out vec4 col_out;\n"
80 "void main()\n"
81 "{\n"
82 " vec4 result = vec4(0.0, 0.0, 0.0, 1.0);\n"
83 " ivec3 current_sample_coord = ivec3(gl_FragCoord.x, gl_FragCoord.y, gl_SampleID);\n"
84 " ivec3 result_coord = ivec3(gl_FragCoord.x, gl_FragCoord.y, sample_rate);\n"
85 " int i;\n"
86 " beginInvocationInterlockARB();\n"
87 " vec4 current_sample_color = imageLoad(img_output, current_sample_coord);\n"
88 " result.rgb += col_vary.a * col_vary.rgb + (1 - col_vary.a) * current_sample_color.rgb;\n"
89 " imageStore(img_output, current_sample_coord, result);\n"
90 "\n"
91 " for (i = 0; i < sample_rate; i++) {\n"
92 " if (i != gl_SampleID) {\n"
93 " ivec3 sample_coord = ivec3(gl_FragCoord.x, gl_FragCoord.y, i);\n"
94 " vec4 sample_color = imageLoad(img_output, sample_coord);\n"
95 " result.rgb += sample_color.rgb;\n"
96 " }\n"
97 " }\n"
98 " result.rgb /= sample_rate;\n"
99 " imageStore(img_output, result_coord, result);\n"
100 " endInvocationInterlockARB();\n"
101 " col_out = result;\n"
102 "}\n";
104 GLuint prog;
106 prog = piglit_build_simple_program(vs_text, fs_text);
107 glUseProgram(prog);
109 glBindAttribLocation(prog, 0, "pos_in");
110 glBindAttribLocation(prog, 1, "col_in");
112 glLinkProgram(prog);
114 if (!piglit_check_gl_error(GL_NO_ERROR)) {
115 piglit_report_result(PIGLIT_FAIL);
118 return prog;
121 static GLuint
122 make_texture_buffer(void)
124 GLuint tex;
126 glGenTextures(1, &tex);
127 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
128 glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2,
129 GL_RGBA32F, piglit_width, piglit_height, false);
130 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
132 return tex;
135 static GLuint
136 make_texture_blend(void)
138 GLuint tex;
140 glGenTextures(1, &tex);
141 glActiveTexture(GL_TEXTURE0);
142 glBindTexture(GL_TEXTURE_3D, tex);
143 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
144 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
145 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
146 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
147 glBindImageTexture(0, tex, 0, GL_TRUE, 0, GL_READ_WRITE, GL_RGBA32F);
149 return tex;
152 static GLuint
153 make_vao(void)
155 static const float pos_col[18][6] = {
156 { -1.0, -1.0, 0.0, 1.0, 0.0, 0.25 },
157 { 0.0, -1.0, 0.0, 1.0, 0.0, 0.25 },
158 { 0.0, 1.0, 0.0, 1.0, 0.0, 0.25 },
159 { 0.0, 1.0, 0.0, 1.0, 0.0, 0.25 },
160 { -1.0, 1.0, 0.0, 1.0, 0.0, 0.25 },
161 { -1.0, -1.0, 0.0, 1.0, 0.0, 0.25 },
162 { -1.0, -1.0, 1.0, 0.0, 0.0, 0.25 },
163 { 1.0, -1.0, 1.0, 0.0, 0.0, 0.25 },
164 { 1.0, 1.0, 1.0, 0.0, 0.0, 0.25 },
165 { 1.0, 1.0, 1.0, 0.0, 0.0, 0.25 },
166 { -1.0, 1.0, 1.0, 0.0, 0.0, 0.25 },
167 { -1.0, -1.0, 1.0, 0.0, 0.0, 0.25 },
168 { -1.0, -1.0, 0.0, 0.0, 1.0, 0.25 },
169 { 1.0, -1.0, 0.0, 0.0, 1.0, 0.25 },
170 { 1.0, 1.0, 0.0, 0.0, 1.0, 0.25 },
171 { 1.0, 1.0, 0.0, 0.0, 1.0, 0.25 },
172 { -1.0, 1.0, 0.0, 0.0, 1.0, 0.25 },
173 { -1.0, -1.0, 0.0, 0.0, 1.0, 0.25 }
176 const int stride = sizeof(pos_col[0]);
177 GLuint vbo, vao;
179 glGenVertexArrays(1, &vao);
180 glBindVertexArray(vao);
182 glGenBuffers(1, &vbo);
183 glBindBuffer(GL_ARRAY_BUFFER, vbo);
184 glBufferData(GL_ARRAY_BUFFER, sizeof(pos_col), pos_col, GL_STATIC_DRAW);
186 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, stride, (void *) 0);
187 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, stride,
188 (void *)(sizeof(float) * 2));
190 glEnableVertexAttribArray(0);
191 glEnableVertexAttribArray(1);
193 if (!piglit_check_gl_error(GL_NO_ERROR)) {
194 piglit_report_result(PIGLIT_FAIL);
197 return vao;
200 void
201 piglit_init(int argc, char **argv)
203 piglit_require_extension("GL_ARB_fragment_shader_interlock");
205 glEnable(GL_MULTISAMPLE);
206 glDisable(GL_CULL_FACE);
207 glClearColor(0.0, 0.0, 0.0, 1.0);
209 prog = make_shader_program();
210 vao = make_vao();
211 tex_frame = make_texture_buffer();
212 fbo = make_fbo();
213 tex_blend = make_texture_blend();
216 enum piglit_result
217 piglit_display(void)
219 int samples[4] = { 2, 4, 8, 16 };
220 bool pass = true;
221 unsigned i, j, k;
222 const unsigned result1[4] = { 47, 35, 63, 255 };
223 const unsigned result2[4] = { 47, 0, 63, 255 };
224 int max_samples;
226 glViewport(0, 0, piglit_width, piglit_height);
227 glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
229 for (i = 0; i < 4 && samples[i] <= max_samples; i++) {
230 GLfloat *tex_data = calloc(piglit_width * piglit_height *
231 (samples[i] + 1) * 4, sizeof(GLfloat));
233 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA32F, piglit_width, piglit_height,
234 samples[i] + 1, 0, GL_RGBA, GL_FLOAT, tex_data);
236 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
237 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex_frame);
238 glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, samples[i],
239 GL_RGBA8, piglit_width, piglit_height, false);
240 glUniform1i(1, samples[i]);
242 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
243 GL_STENCIL_BUFFER_BIT);
245 glUseProgram(prog);
246 glDrawArrays(GL_TRIANGLES, 0, 18);
248 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
249 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
250 glDrawBuffer(GL_BACK);
251 glBlitFramebuffer(0, 0, piglit_width, piglit_height, 0, 0, piglit_width,
252 piglit_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
253 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
254 piglit_present_results();
256 glGetTexImage(GL_TEXTURE_3D, 0, GL_RGBA, GL_FLOAT, tex_data);
257 for (j = 0; j < piglit_height; j++) {
258 for (k = 0; k < piglit_width; k++) {
259 unsigned l = ((piglit_width * piglit_height * samples[i]) +
260 (j * piglit_width) + k) * 4;
261 unsigned r = fabs(tex_data[l]) * 255;
262 unsigned g = fabs(tex_data[l + 1]) * 255;
263 unsigned b = fabs(tex_data[l + 2]) * 255;
264 unsigned a = fabs(tex_data[l + 3]) * 255;
266 if ((k < piglit_width / 2) && (r != result1[0] ||
267 g != result1[1] || b != result1[2] || a != result1[3])) {
268 printf("observed %u %u %u %u %u %u\n", j, k, r,
269 g, b, a);
270 printf("expected %u %u %u %u %u %u\n", j, k,
271 result1[0], result1[1], result1[2], result1[3]);
272 pass = false;
273 break;
276 if ((k > piglit_width / 2) && (r != result2[0] ||
277 g != result2[1] || b != result2[2] || a != result2[3])) {
278 printf("observed %u %u %u %u %u %u\n", j, k, r,
279 g, b, a);
280 printf("expected %u %u %u %u %u %u\n", j, k,
281 result1[0], result1[1], result1[2], result1[3]);
282 pass = false;
283 break;
286 if (!pass)
287 break;
290 free(tex_data);
291 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
292 if (!pass)
293 break;
296 return pass ? PIGLIT_PASS : PIGLIT_FAIL;