1 //
2 // Copyright 2021 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // FramebufferFetchTest:
7 // Tests the correctness of the EXT_shader_framebuffer_fetch and the
8 // EXT_shader_framebuffer_fetch_non_coherent extensions.
9 //
10
11 #include "common/debug.h"
12 #include "test_utils/ANGLETest.h"
13 #include "test_utils/gl_raii.h"
14 #include "util/EGLWindow.h"
15
16 namespace angle
17 {
18 //
19 // Shared Vertex Shaders for the tests below
20 //
21 // A 1.0 GLSL vertex shader
22 static constexpr char k100VS[] = R"(#version 100
23 attribute vec4 a_position;
24
25 void main (void)
26 {
27 gl_Position = a_position;
28 })";
29
30 // A 3.1 GLSL vertex shader
31 static constexpr char k310VS[] = R"(#version 310 es
32 in highp vec4 a_position;
33
34 void main (void)
35 {
36 gl_Position = a_position;
37 })";
38
39 // Shared simple (i.e. no framebuffer fetch) Fragment Shaders for the tests below
40 //
41 // Simple (i.e. no framebuffer fetch) 3.1 GLSL fragment shader that writes to 1 attachment
42 static constexpr char k310NoFetch1AttachmentFS[] = R"(#version 310 es
43 layout(location = 0) out highp vec4 o_color;
44
45 uniform highp vec4 u_color;
46 void main (void)
47 {
48 o_color = u_color;
49 })";
50
51 // Shared Coherent Fragment Shaders for the tests below
52 //
53 // Coherent version of a 1.0 GLSL fragment shader that uses gl_LastFragData
54 static constexpr char k100CoherentFS[] = R"(#version 100
55 #extension GL_EXT_shader_framebuffer_fetch : require
56 mediump vec4 gl_LastFragData[gl_MaxDrawBuffers];
57 uniform highp vec4 u_color;
58
59 void main (void)
60 {
61 gl_FragColor = u_color + gl_LastFragData[0];
62 })";
63
64 // Coherent version of a 3.1 GLSL fragment shader that writes to 1 attachment
65 static constexpr char k310Coherent1AttachmentFS[] = R"(#version 310 es
66 #extension GL_EXT_shader_framebuffer_fetch : require
67 layout(location = 0) inout highp vec4 o_color;
68
69 uniform highp vec4 u_color;
70 void main (void)
71 {
72 o_color += u_color;
73 })";
74
75 // Coherent version of a 3.1 GLSL fragment shader that writes the output to a storage buffer.
76 static constexpr char k310CoherentStorageBuffer[] = R"(#version 310 es
77 #extension GL_EXT_shader_framebuffer_fetch : require
78 layout(location = 0) inout highp vec4 o_color;
79
80 layout(std140, binding = 0) buffer outBlock {
81 highp vec4 data[256];
82 };
83
84 uniform highp vec4 u_color;
85 void main (void)
86 {
87 uint index = uint(gl_FragCoord.y) * 16u + uint(gl_FragCoord.x);
88 data[index] = o_color;
89 o_color += u_color;
90 })";
91
92 // Coherent version of a 1.0 GLSL fragment shader that writes to 4 attachments with constant indices
93 static constexpr char k100Coherent4AttachmentFS[] = R"(#version 100
94 #extension GL_EXT_shader_framebuffer_fetch : require
95 #extension GL_EXT_draw_buffers : require
96 uniform highp vec4 u_color;
97
98 void main (void)
99 {
100 gl_FragData[0] = gl_LastFragData[0] + u_color;
101 gl_FragData[1] = gl_LastFragData[1] + u_color;
102 gl_FragData[2] = gl_LastFragData[2] + u_color;
103 gl_FragData[3] = gl_LastFragData[3] + u_color;
104 })";
105
106 // Coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments
107 static constexpr char k310Coherent4AttachmentFS[] = R"(#version 310 es
108 #extension GL_EXT_shader_framebuffer_fetch : require
109 layout(location = 0) inout highp vec4 o_color0;
110 layout(location = 1) inout highp vec4 o_color1;
111 layout(location = 2) inout highp vec4 o_color2;
112 layout(location = 3) inout highp vec4 o_color3;
113 uniform highp vec4 u_color;
114
115 void main (void)
116 {
117 o_color0 += u_color;
118 o_color1 += u_color;
119 o_color2 += u_color;
120 o_color3 += u_color;
121 })";
122
123 // Coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments via an inout
124 // array
125 static constexpr char k310Coherent4AttachmentArrayFS[] = R"(#version 310 es
126 #extension GL_EXT_shader_framebuffer_fetch : require
127 inout highp vec4 o_color[4];
128 uniform highp vec4 u_color;
129
130 void main (void)
131 {
132 o_color[0] += u_color;
133 o_color[1] += u_color;
134 o_color[2] += u_color;
135 o_color[3] += u_color;
136 })";
137
138 // Coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments with the order of
139 // non-fetch program and fetch program with different attachments (version 1)
140 static constexpr char k310CoherentDifferent4AttachmentFS1[] = R"(#version 310 es
141 #extension GL_EXT_shader_framebuffer_fetch : require
142 layout(location = 0) inout highp vec4 o_color0;
143 layout(location = 1) out highp vec4 o_color1;
144 layout(location = 2) inout highp vec4 o_color2;
145 layout(location = 3) out highp vec4 o_color3;
146 uniform highp vec4 u_color;
147
148 void main (void)
149 {
150 o_color0 += u_color;
151 o_color1 = u_color;
152 o_color2 += u_color;
153 o_color3 = u_color;
154 })";
155
156 // Coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments with the order
157 // of non-fetch program and fetch program with different attachments (version 2)
158 static constexpr char k310CoherentDifferent4AttachmentFS2[] = R"(#version 310 es
159 #extension GL_EXT_shader_framebuffer_fetch : require
160 layout(location = 0) inout highp vec4 o_color0;
161 layout(location = 1) out highp vec4 o_color1;
162 layout(location = 2) out highp vec4 o_color2;
163 layout(location = 3) inout highp vec4 o_color3;
164 uniform highp vec4 u_color;
165
166 void main (void)
167 {
168 o_color0 += u_color;
169 o_color1 = u_color;
170 o_color2 = u_color;
171 o_color3 += u_color;
172 })";
173
174 // Coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments, fetching from
175 // different indices (version 3)
176 static constexpr char k310CoherentDifferent4AttachmentFS3[] = R"(#version 310 es
177 #extension GL_EXT_shader_framebuffer_fetch : require
178 layout(location = 0) out highp vec4 o_color0;
179 layout(location = 1) inout highp vec4 o_color1;
180 layout(location = 2) inout highp vec4 o_color2;
181 layout(location = 3) out highp vec4 o_color3;
182 uniform highp vec4 u_color;
183
184 void main (void)
185 {
186 o_color0 = u_color;
187 o_color1 += u_color;
188 o_color2 += u_color;
189 o_color3 = u_color;
190 })";
191
192 // Coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments, fetching from
193 // different indices (version 4)
194 static constexpr char k310CoherentDifferent4AttachmentFS4[] = R"(#version 310 es
195 #extension GL_EXT_shader_framebuffer_fetch : require
196 layout(location = 0) out highp vec4 o_color0;
197 layout(location = 1) out highp vec4 o_color1;
198 layout(location = 2) inout highp vec4 o_color2;
199 layout(location = 3) inout highp vec4 o_color3;
200 uniform highp vec4 u_color;
201
202 void main (void)
203 {
204 o_color0 = u_color;
205 o_color1 = u_color;
206 o_color2 += u_color;
207 o_color3 += u_color;
208 })";
209
210 // Coherent version of a 1.0 GLSL fragment shader with complex interactions
211 static constexpr char k100CoherentComplexFS[] = R"(#version 100
212 #extension GL_EXT_shader_framebuffer_fetch : require
213 #extension GL_EXT_draw_buffers : require
214 precision highp float;
215 uniform vec4 u_color;
216
217 vec4 addColor(vec4 lastFragData, vec4 color)
218 {
219 return lastFragData + color;
220 }
221
222 void addLastFragData(inout vec4 outVar, vec4 lastFragData)
223 {
224 outVar += lastFragData;
225 }
226
227 void main (void)
228 {
229 // Leave gl_LastFragData[0] unused, as well as gl_LastFragData[2]
230 gl_FragData[0] = u_color;
231 gl_FragData[1] = addColor(gl_LastFragData[1], u_color);
232 gl_FragData[2] = u_color;
233 gl_FragData[3] = addColor(gl_LastFragData[3], u_color);
234
235 // Make sure gl_LastFragData is not clobbered by a write to gl_FragData.
236 gl_FragData[1] -= gl_LastFragData[1];
237 gl_FragData[3] -= gl_LastFragData[3];
238 // Test passing to inout variables.
239 addLastFragData(gl_FragData[1], gl_LastFragData[1]);
240 addLastFragData(gl_FragData[3], gl_LastFragData[3]);
241 })";
242
243 // Coherent version of a 3.1 GLSL fragment shader with complex interactions
244 static constexpr char k310CoherentComplexFS[] = R"(#version 310 es
245 #extension GL_EXT_shader_framebuffer_fetch : require
246 precision highp float;
247 layout(location = 0) inout highp vec4 o_color0;
248 layout(location = 1) inout highp vec4 o_color1;
249 layout(location = 2) inout highp vec4 o_color2[2];
250 uniform vec4 u_color;
251
252 vec4 addColor(vec4 lastValue, vec4 color)
253 {
254 return lastValue + color;
255 }
256
257 vec4 getColor2_1()
258 {
259 return o_color2[1];
260 }
261
262 void addUniform(inout vec4 outVar)
263 {
264 outVar += u_color;
265 }
266
267 void main (void)
268 {
269 // o_color0 and o_color2[0] don't use the input value.
270 o_color0 = u_color;
271 o_color2[0] = u_color;
272
273 addUniform(o_color1);
274 addUniform(o_color2[1]);
275
276 // Make sure reading back from the output variables returns the latest value and not the
277 // original input value.
278 vec4 temp1 = o_color1;
279 vec4 temp3 = getColor2_1();
280
281 o_color1 = temp1;
282 o_color2[1] = temp3;
283 })";
284
285 // Shared Non-Coherent Fragment Shaders for the tests below
286 //
287 // Non-coherent version of a 1.0 GLSL fragment shader that uses gl_LastFragData
288 static constexpr char k100NonCoherentFS[] = R"(#version 100
289 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
290 layout(noncoherent) mediump vec4 gl_LastFragData[gl_MaxDrawBuffers];
291 uniform highp vec4 u_color;
292
293 void main (void)
294 {
295 gl_FragColor = u_color + gl_LastFragData[0];
296 })";
297
298 // Non-coherent version of a 3.1 GLSL fragment shader that writes to 1 attachment
299 static constexpr char k310NonCoherent1AttachmentFS[] = R"(#version 310 es
300 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
301 layout(noncoherent, location = 0) inout highp vec4 o_color;
302
303 uniform highp vec4 u_color;
304 void main (void)
305 {
306 o_color += u_color;
307 })";
308
309 // Non-coherent version of a 3.1 GLSL fragment shader that writes the output to a storage buffer.
310 static constexpr char k310NonCoherentStorageBuffer[] = R"(#version 310 es
311 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
312 layout(noncoherent) inout highp vec4 o_color;
313
314 layout(std140, binding = 0) buffer outBlock {
315 highp vec4 data[256];
316 };
317
318 uniform highp vec4 u_color;
319 void main (void)
320 {
321 uint index = uint(gl_FragCoord.y) * 16u + uint(gl_FragCoord.x);
322 data[index] = o_color;
323 o_color += u_color;
324 })";
325
326 // Non-coherent version of a 1.0 GLSL fragment shader that writes to 4 attachments with constant
327 // indices
328 static constexpr char k100NonCoherent4AttachmentFS[] = R"(#version 100
329 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
330 #extension GL_EXT_draw_buffers : require
331 layout(noncoherent) mediump vec4 gl_LastFragData[gl_MaxDrawBuffers];
332 uniform highp vec4 u_color;
333
334 void main (void)
335 {
336 gl_FragData[0] = gl_LastFragData[0] + u_color;
337 gl_FragData[1] = gl_LastFragData[1] + u_color;
338 gl_FragData[2] = gl_LastFragData[2] + u_color;
339 gl_FragData[3] = gl_LastFragData[3] + u_color;
340 })";
341
342 // Non-coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments
343 static constexpr char k310NonCoherent4AttachmentFS[] = R"(#version 310 es
344 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
345 layout(noncoherent, location = 0) inout highp vec4 o_color0;
346 layout(noncoherent, location = 1) inout highp vec4 o_color1;
347 layout(noncoherent, location = 2) inout highp vec4 o_color2;
348 layout(noncoherent, location = 3) inout highp vec4 o_color3;
349 uniform highp vec4 u_color;
350
351 void main (void)
352 {
353 o_color0 += u_color;
354 o_color1 += u_color;
355 o_color2 += u_color;
356 o_color3 += u_color;
357 })";
358
359 // Non-coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments via an inout
360 // array
361 static constexpr char k310NonCoherent4AttachmentArrayFS[] = R"(#version 310 es
362 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
363 layout(noncoherent, location = 0) inout highp vec4 o_color[4];
364 uniform highp vec4 u_color;
365
366 void main (void)
367 {
368 o_color[0] += u_color;
369 o_color[1] += u_color;
370 o_color[2] += u_color;
371 o_color[3] += u_color;
372 })";
373
374 // Non-coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments with the order
375 // of non-fetch program and fetch program with different attachments (version 1)
376 static constexpr char k310NonCoherentDifferent4AttachmentFS1[] = R"(#version 310 es
377 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
378 layout(noncoherent, location = 0) inout highp vec4 o_color0;
379 layout(location = 1) out highp vec4 o_color1;
380 layout(noncoherent, location = 2) inout highp vec4 o_color2;
381 layout(location = 3) out highp vec4 o_color3;
382 uniform highp vec4 u_color;
383
384 void main (void)
385 {
386 o_color0 += u_color;
387 o_color1 = u_color;
388 o_color2 += u_color;
389 o_color3 = u_color;
390 })";
391
392 // Non-coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments with the order
393 // of non-fetch program and fetch program with different attachments (version 2)
394 static constexpr char k310NonCoherentDifferent4AttachmentFS2[] = R"(#version 310 es
395 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
396 layout(noncoherent, location = 0) inout highp vec4 o_color0;
397 layout(location = 1) out highp vec4 o_color1;
398 layout(location = 2) out highp vec4 o_color2;
399 layout(noncoherent, location = 3) inout highp vec4 o_color3;
400 uniform highp vec4 u_color;
401
402 void main (void)
403 {
404 o_color0 += u_color;
405 o_color1 = u_color;
406 o_color2 = u_color;
407 o_color3 += u_color;
408 })";
409
410 // Non-coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments, fetching from
411 // different indices (version 3)
412 static constexpr char k310NonCoherentDifferent4AttachmentFS3[] = R"(#version 310 es
413 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
414 layout(location = 0) out highp vec4 o_color0;
415 layout(noncoherent, location = 1) inout highp vec4 o_color1;
416 layout(noncoherent, location = 2) inout highp vec4 o_color2;
417 layout(location = 3) out highp vec4 o_color3;
418 uniform highp vec4 u_color;
419
420 void main (void)
421 {
422 o_color0 = u_color;
423 o_color1 += u_color;
424 o_color2 += u_color;
425 o_color3 = u_color;
426 })";
427
428 // Non-coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments, fetching from
429 // different indices (version 4)
430 static constexpr char k310NonCoherentDifferent4AttachmentFS4[] = R"(#version 310 es
431 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
432 layout(location = 0) out highp vec4 o_color0;
433 layout(location = 1) out highp vec4 o_color1;
434 layout(noncoherent, location = 2) inout highp vec4 o_color2;
435 layout(noncoherent, location = 3) inout highp vec4 o_color3;
436 uniform highp vec4 u_color;
437
438 void main (void)
439 {
440 o_color0 = u_color;
441 o_color1 = u_color;
442 o_color2 += u_color;
443 o_color3 += u_color;
444 })";
445
446 // Non-coherent version of a 1.0 GLSL fragment shader with complex interactions
447 static constexpr char k100NonCoherentComplexFS[] = R"(#version 100
448 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
449 #extension GL_EXT_draw_buffers : require
450 precision highp float;
451 layout(noncoherent) mediump vec4 gl_LastFragData[gl_MaxDrawBuffers];
452 uniform vec4 u_color;
453
454 vec4 addColor(vec4 lastFragData, vec4 color)
455 {
456 return lastFragData + color;
457 }
458
459 void addLastFragData(inout vec4 outVar, vec4 lastFragData)
460 {
461 outVar += lastFragData;
462 }
463
464 void main (void)
465 {
466 // Leave gl_LastFragData[0] unused, as well as gl_LastFragData[2]
467 gl_FragData[0] = u_color;
468 gl_FragData[1] = addColor(gl_LastFragData[1], u_color);
469 gl_FragData[2] = u_color;
470 gl_FragData[3] = addColor(gl_LastFragData[3], u_color);
471
472 // Make sure gl_LastFragData is not clobbered by a write to gl_FragData.
473 gl_FragData[1] -= gl_LastFragData[1];
474 gl_FragData[3] -= gl_LastFragData[3];
475 // Test passing to inout variables.
476 addLastFragData(gl_FragData[1], gl_LastFragData[1]);
477 addLastFragData(gl_FragData[3], gl_LastFragData[3]);
478 })";
479
480 // Non-coherent version of a 3.1 GLSL fragment shader with complex interactions
481 static constexpr char k310NonCoherentComplexFS[] = R"(#version 310 es
482 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
483 precision highp float;
484 layout(location = 0) out highp vec4 o_color0;
485 layout(noncoherent, location = 1) inout highp vec4 o_color1;
486 layout(noncoherent, location = 2) inout highp vec4 o_color2[2];
487 uniform vec4 u_color;
488
489 vec4 addColor(vec4 lastValue, vec4 color)
490 {
491 return lastValue + color;
492 }
493
494 vec4 getColor2_1()
495 {
496 return o_color2[1];
497 }
498
499 void addUniform(inout vec4 outVar)
500 {
501 outVar += u_color;
502 }
503
504 void main (void)
505 {
506 // o_color0 and o_color2[0] don't use the input value.
507 o_color0 = u_color;
508 o_color2[0] = u_color;
509
510 addUniform(o_color1);
511 addUniform(o_color2[1]);
512
513 // Make sure reading back from the output variables returns the latest value and not the
514 // original input value.
515 vec4 temp1 = o_color1;
516 vec4 temp3 = getColor2_1();
517
518 o_color1 = temp1;
519 o_color2[1] = temp3;
520 })";
521
522 // Shared Coherent Fragment Shaders for the tests below
523 //
524 // Coherent version of a 1.0 GLSL fragment shader that uses gl_LastFragColorARM
525 static constexpr char k100ARMFS[] = R"(#version 100
526 #extension GL_ARM_shader_framebuffer_fetch : require
527 mediump vec4 gl_LastFragColorARM;
528 uniform highp vec4 u_color;
529
530 void main (void)
531 {
532 gl_FragColor = u_color + gl_LastFragColorARM;
533 })";
534
535 // ARM version of a 3.1 GLSL fragment shader that writes to 1 attachment
536 static constexpr char k310ARM1AttachmentFS[] = R"(#version 310 es
537 #extension GL_ARM_shader_framebuffer_fetch : require
538 layout(location = 0) out highp vec4 o_color;
539
540 uniform highp vec4 u_color;
541 void main (void)
542 {
543 o_color = u_color + gl_LastFragColorARM;
544 })";
545
546 // ARM version of a 3.1 GLSL fragment shader that writes the output to a storage buffer.
547 static constexpr char k310ARMStorageBuffer[] = R"(#version 310 es
548 #extension GL_ARM_shader_framebuffer_fetch : require
549 layout(location = 0) out highp vec4 o_color;
550
551 layout(std140, binding = 0) buffer outBlock {
552 highp vec4 data[256];
553 };
554
555 uniform highp vec4 u_color;
556 void main (void)
557 {
558 uint index = uint(gl_FragCoord.y) * 16u + uint(gl_FragCoord.x);
559 data[index] = gl_LastFragColorARM;
560 o_color = u_color + gl_LastFragColorARM;
561 })";
562
563 // Variants that use both EXT and ARM simultaneously. At least one app has been observed to do
564 // this.
565 static constexpr char k100BothFS[] = R"(#version 100
566 #extension GL_EXT_shader_framebuffer_fetch : require
567 #extension GL_ARM_shader_framebuffer_fetch : require
568 uniform highp vec4 u_color;
569
570 void main (void)
571 {
572 gl_FragColor = u_color + (gl_LastFragColorARM + gl_LastFragData[0]) / 2.;
573 })";
574
575 static constexpr char k310Both1AttachmentFS[] = R"(#version 310 es
576 #extension GL_EXT_shader_framebuffer_fetch : require
577 #extension GL_ARM_shader_framebuffer_fetch : require
578 inout highp vec4 o_color;
579
580 uniform highp vec4 u_color;
581 void main (void)
582 {
583 o_color = u_color + (o_color + gl_LastFragColorARM) / 2.;
584 })";
585
586 static constexpr char k100Both4AttachmentFS[] = R"(#version 100
587 #extension GL_EXT_shader_framebuffer_fetch : require
588 #extension GL_ARM_shader_framebuffer_fetch : require
589 #extension GL_EXT_draw_buffers : require
590 uniform highp vec4 u_color;
591
592 void main (void)
593 {
594 gl_FragData[0] = (gl_LastFragData[0] + gl_LastFragColorARM) / 2. + u_color;
595 gl_FragData[1] = gl_LastFragData[1] + u_color;
596 gl_FragData[2] = gl_LastFragData[2] + u_color;
597 gl_FragData[3] = gl_LastFragData[3] + u_color;
598 })";
599
600 static constexpr char k100BothComplexFS[] = R"(#version 100
601 #extension GL_EXT_shader_framebuffer_fetch : require
602 #extension GL_ARM_shader_framebuffer_fetch : require
603 #extension GL_EXT_draw_buffers : require
604 precision highp float;
605 uniform vec4 u_color;
606
607 vec4 addColor(vec4 lastFragData, vec4 color)
608 {
609 return lastFragData + color;
610 }
611
612 void addLastFragData(inout vec4 outVar, vec4 lastFragData)
613 {
614 outVar += lastFragData;
615 }
616
617 void main (void)
618 {
619 // Leave gl_LastFragData[1] unused, as well as gl_LastFragData[3]
620 gl_FragData[0] = addColor((gl_LastFragData[0] + gl_LastFragColorARM) / 2., u_color);
621 gl_FragData[1] = u_color;
622 gl_FragData[2] = addColor(gl_LastFragData[2], u_color);
623 gl_FragData[3] = u_color;
624
625 // Make sure gl_LastFragData is not clobbered by a write to gl_FragData.
626 gl_FragData[0] -= gl_LastFragColorARM;
627 gl_FragData[2] -= gl_LastFragData[2];
628 // Test passing to inout variables.
629 addLastFragData(gl_FragData[0], gl_LastFragData[0]);
630 addLastFragData(gl_FragData[2], gl_LastFragData[2]);
631 })";
632
633 static constexpr char k310BothComplexFS[] = R"(#version 310 es
634 #extension GL_EXT_shader_framebuffer_fetch : require
635 #extension GL_ARM_shader_framebuffer_fetch : require
636 precision highp float;
637 layout(location = 0) inout highp vec4 o_color0;
638 layout(location = 1) inout highp vec4 o_color1;
639 layout(location = 2) inout highp vec4 o_color2[2];
640 uniform vec4 u_color;
641
642 vec4 addColor(vec4 lastValue, vec4 color)
643 {
644 return lastValue + color;
645 }
646
647 vec4 getColor2_0()
648 {
649 return o_color2[0];
650 }
651
652 void addUniform(inout vec4 outVar)
653 {
654 outVar += u_color;
655 }
656
657 void main (void)
658 {
659 // o_color1 and o_color2[1] don't use the input value.
660 o_color1 = u_color;
661 o_color2[1] = u_color;
662
663 o_color0 = gl_LastFragColorARM + u_color;
664 addUniform(o_color2[0]);
665
666 // Make sure reading back from the output variables returns the latest value and not the
667 // original input value.
668 vec4 temp0 = o_color0;
669 vec4 temp2 = getColor2_0();
670
671 o_color0 = temp0;
672 o_color2[0] = temp2;
673
674 // Make sure gl_LastFragColorARM is not clobberred by the write to o_color0
675 if (gl_LastFragColorARM == o_color0)
676 o_color0 = vec4(0);
677 })";
678
679 class FramebufferFetchES31 : public ANGLETest<>
680 {
681 protected:
682 static constexpr GLuint kMaxColorBuffer = 4u;
683 static constexpr GLuint kViewportWidth = 16u;
684 static constexpr GLuint kViewportHeight = 16u;
685
FramebufferFetchES31()686 FramebufferFetchES31()
687 {
688 setWindowWidth(16);
689 setWindowHeight(16);
690 setConfigRedBits(8);
691 setConfigGreenBits(8);
692 setConfigBlueBits(8);
693 setConfigAlphaBits(8);
694 setConfigDepthBits(24);
695
696 mCoherentExtension = false;
697 mARMExtension = false;
698 mBothExtensions = false;
699 }
700
701 enum WhichExtension
702 {
703 COHERENT,
704 NON_COHERENT,
705 ARM,
706 BOTH,
707 };
setWhichExtension(WhichExtension whichExtension)708 void setWhichExtension(WhichExtension whichExtension)
709 {
710 mCoherentExtension = whichExtension != NON_COHERENT;
711 mARMExtension = whichExtension == ARM;
712 mBothExtensions = whichExtension == BOTH;
713 }
714
715 enum WhichFragmentShader
716 {
717 GLSL100,
718 GLSL310_NO_FETCH_1ATTACHMENT,
719 GLSL310_1ATTACHMENT,
720 GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER,
721 GLSL100_4ATTACHMENT,
722 GLSL100_COMPLEX,
723 GLSL310_4ATTACHMENT,
724 GLSL310_4ATTACHMENT_ARRAY,
725 GLSL310_4ATTACHMENT_DIFFERENT1,
726 GLSL310_4ATTACHMENT_DIFFERENT2,
727 GLSL310_4ATTACHMENT_DIFFERENT3,
728 GLSL310_4ATTACHMENT_DIFFERENT4,
729 GLSL310_COMPLEX,
730 };
getFragmentShader(WhichFragmentShader whichFragmentShader)731 const char *getFragmentShader(WhichFragmentShader whichFragmentShader)
732 {
733 if (mBothExtensions)
734 {
735 switch (whichFragmentShader)
736 {
737 case GLSL100:
738 return k100BothFS;
739 case GLSL310_NO_FETCH_1ATTACHMENT:
740 return k310NoFetch1AttachmentFS;
741 case GLSL310_1ATTACHMENT:
742 return k310Both1AttachmentFS;
743 case GLSL100_4ATTACHMENT:
744 return k100Both4AttachmentFS;
745 case GLSL100_COMPLEX:
746 return k100BothComplexFS;
747 case GLSL310_COMPLEX:
748 return k310BothComplexFS;
749 default:
750 UNREACHABLE();
751 return nullptr;
752 }
753 }
754 else if (mARMExtension)
755 {
756 // gl_LastFragColorARM cannot support multiple attachments
757 switch (whichFragmentShader)
758 {
759 case GLSL100:
760 return k100ARMFS;
761 case GLSL310_NO_FETCH_1ATTACHMENT:
762 return k310NoFetch1AttachmentFS;
763 case GLSL310_1ATTACHMENT:
764 return k310ARM1AttachmentFS;
765 case GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER:
766 return k310ARMStorageBuffer;
767 default:
768 UNREACHABLE();
769 return nullptr;
770 }
771 }
772 else if (mCoherentExtension)
773 {
774 switch (whichFragmentShader)
775 {
776 case GLSL100:
777 return k100CoherentFS;
778 case GLSL310_NO_FETCH_1ATTACHMENT:
779 return k310NoFetch1AttachmentFS;
780 case GLSL310_1ATTACHMENT:
781 return k310Coherent1AttachmentFS;
782 case GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER:
783 return k310CoherentStorageBuffer;
784 case GLSL100_4ATTACHMENT:
785 return k100Coherent4AttachmentFS;
786 case GLSL310_4ATTACHMENT:
787 return k310Coherent4AttachmentFS;
788 case GLSL310_4ATTACHMENT_ARRAY:
789 return k310Coherent4AttachmentArrayFS;
790 case GLSL310_4ATTACHMENT_DIFFERENT1:
791 return k310CoherentDifferent4AttachmentFS1;
792 case GLSL310_4ATTACHMENT_DIFFERENT2:
793 return k310CoherentDifferent4AttachmentFS2;
794 case GLSL310_4ATTACHMENT_DIFFERENT3:
795 return k310CoherentDifferent4AttachmentFS3;
796 case GLSL310_4ATTACHMENT_DIFFERENT4:
797 return k310CoherentDifferent4AttachmentFS4;
798 case GLSL100_COMPLEX:
799 return k100CoherentComplexFS;
800 case GLSL310_COMPLEX:
801 return k310CoherentComplexFS;
802 default:
803 UNREACHABLE();
804 return nullptr;
805 }
806 }
807 else
808 {
809 switch (whichFragmentShader)
810 {
811 case GLSL100:
812 return k100NonCoherentFS;
813 case GLSL310_NO_FETCH_1ATTACHMENT:
814 return k310NoFetch1AttachmentFS;
815 case GLSL310_1ATTACHMENT:
816 return k310NonCoherent1AttachmentFS;
817 case GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER:
818 return k310NonCoherentStorageBuffer;
819 case GLSL100_4ATTACHMENT:
820 return k100NonCoherent4AttachmentFS;
821 case GLSL310_4ATTACHMENT:
822 return k310NonCoherent4AttachmentFS;
823 case GLSL310_4ATTACHMENT_ARRAY:
824 return k310NonCoherent4AttachmentArrayFS;
825 case GLSL310_4ATTACHMENT_DIFFERENT1:
826 return k310NonCoherentDifferent4AttachmentFS1;
827 case GLSL310_4ATTACHMENT_DIFFERENT2:
828 return k310NonCoherentDifferent4AttachmentFS2;
829 case GLSL310_4ATTACHMENT_DIFFERENT3:
830 return k310NonCoherentDifferent4AttachmentFS3;
831 case GLSL310_4ATTACHMENT_DIFFERENT4:
832 return k310NonCoherentDifferent4AttachmentFS4;
833 case GLSL100_COMPLEX:
834 return k100NonCoherentComplexFS;
835 case GLSL310_COMPLEX:
836 return k310NonCoherentComplexFS;
837 default:
838 UNREACHABLE();
839 return nullptr;
840 }
841 }
842 }
843
render(GLuint coordLoc,GLboolean needsFramebufferFetchBarrier)844 void render(GLuint coordLoc, GLboolean needsFramebufferFetchBarrier)
845 {
846 const GLfloat coords[] = {
847 -1.0f, -1.0f, +1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f,
848 };
849
850 const GLushort indices[] = {
851 0, 1, 2, 2, 3, 0,
852 };
853
854 glViewport(0, 0, kViewportWidth, kViewportHeight);
855
856 GLBuffer coordinatesBuffer;
857 GLBuffer elementsBuffer;
858
859 glBindBuffer(GL_ARRAY_BUFFER, coordinatesBuffer);
860 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW);
861 glEnableVertexAttribArray(coordLoc);
862 glVertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
863
864 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementsBuffer);
865 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)sizeof(indices), &indices[0],
866 GL_STATIC_DRAW);
867
868 if (needsFramebufferFetchBarrier)
869 {
870 glFramebufferFetchBarrierEXT();
871 }
872
873 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
874
875 ASSERT_GL_NO_ERROR();
876 }
877
BasicTest(GLProgram & program)878 void BasicTest(GLProgram &program)
879 {
880 GLFramebuffer framebuffer;
881 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
882 std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
883 GLTexture colorBufferTex;
884 glBindTexture(GL_TEXTURE_2D, colorBufferTex);
885 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
886 GL_UNSIGNED_BYTE, greenColor.data());
887 glBindTexture(GL_TEXTURE_2D, 0);
888 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
889 0);
890
891 ASSERT_GL_NO_ERROR();
892
893 float color[4] = {1.0f, 0.0f, 0.0f, 1.0f};
894 GLint colorLocation = glGetUniformLocation(program, "u_color");
895 glUniform4fv(colorLocation, 1, color);
896
897 GLint positionLocation = glGetAttribLocation(program, "a_position");
898 render(positionLocation, !mCoherentExtension);
899
900 ASSERT_GL_NO_ERROR();
901
902 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
903
904 glBindFramebuffer(GL_FRAMEBUFFER, 0);
905 }
906
MultipleRenderTargetTest(GLProgram & program,WhichFragmentShader whichFragmentShader)907 void MultipleRenderTargetTest(GLProgram &program, WhichFragmentShader whichFragmentShader)
908 {
909 GLFramebuffer framebuffer;
910 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
911 std::vector<GLColor> color0(kViewportWidth * kViewportHeight, GLColor::cyan);
912 std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
913 std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
914 std::vector<GLColor> color3(kViewportWidth * kViewportHeight, GLColor::black);
915 GLTexture colorBufferTex[kMaxColorBuffer];
916 GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
917 GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
918 glBindTexture(GL_TEXTURE_2D, colorBufferTex[0]);
919 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
920 GL_UNSIGNED_BYTE, color0.data());
921 glBindTexture(GL_TEXTURE_2D, colorBufferTex[1]);
922 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
923 GL_UNSIGNED_BYTE, color1.data());
924 glBindTexture(GL_TEXTURE_2D, colorBufferTex[2]);
925 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
926 GL_UNSIGNED_BYTE, color2.data());
927 glBindTexture(GL_TEXTURE_2D, colorBufferTex[3]);
928 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
929 GL_UNSIGNED_BYTE, color3.data());
930 glBindTexture(GL_TEXTURE_2D, 0);
931 for (unsigned int i = 0; i < kMaxColorBuffer; i++)
932 {
933 glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
934 colorBufferTex[i], 0);
935 }
936 glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
937
938 ASSERT_GL_NO_ERROR();
939
940 float color[4] = {1.0f, 0.0f, 0.0f, 1.0f};
941 GLint colorLocation = glGetUniformLocation(program, "u_color");
942 glUniform4fv(colorLocation, 1, color);
943
944 GLint positionLocation = glGetAttribLocation(program, "a_position");
945 render(positionLocation, !mCoherentExtension);
946
947 ASSERT_GL_NO_ERROR();
948
949 // All fragment shaders add the input color with the uniform. Except the COMPLEX shaders
950 // which initialize attachments 0 and 2, or 1 and 3 with the uniform only (and don't use
951 // input attachments for these indices).
952 GLColor expect0 = GLColor::white;
953 GLColor expect1 = GLColor::yellow;
954 GLColor expect2 = GLColor::magenta;
955 GLColor expect3 = GLColor::red;
956 switch (whichFragmentShader)
957 {
958 case GLSL100_COMPLEX:
959 case GLSL310_COMPLEX:
960 if (mBothExtensions)
961 {
962 expect1 = GLColor::red;
963 expect3 = GLColor::red;
964 }
965 else
966 {
967 expect0 = GLColor::red;
968 expect2 = GLColor::red;
969 }
970 break;
971 default:
972 break;
973 }
974
975 glReadBuffer(colorAttachments[0]);
976 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, expect0);
977 glReadBuffer(colorAttachments[1]);
978 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, expect1);
979 glReadBuffer(colorAttachments[2]);
980 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, expect2);
981 glReadBuffer(colorAttachments[3]);
982 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, expect3);
983
984 glBindFramebuffer(GL_FRAMEBUFFER, 0);
985 }
986
MultipleRenderTargetArrayTest(GLProgram & program)987 void MultipleRenderTargetArrayTest(GLProgram &program)
988 {
989 GLFramebuffer framebuffer;
990 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
991 std::vector<GLColor> color0(kViewportWidth * kViewportHeight, GLColor::black);
992 std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
993 std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
994 std::vector<GLColor> color3(kViewportWidth * kViewportHeight, GLColor::cyan);
995 GLTexture colorBufferTex[kMaxColorBuffer];
996 GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
997 GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
998 glBindTexture(GL_TEXTURE_2D, colorBufferTex[0]);
999 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1000 GL_UNSIGNED_BYTE, color0.data());
1001 glBindTexture(GL_TEXTURE_2D, colorBufferTex[1]);
1002 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1003 GL_UNSIGNED_BYTE, color1.data());
1004 glBindTexture(GL_TEXTURE_2D, colorBufferTex[2]);
1005 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1006 GL_UNSIGNED_BYTE, color2.data());
1007 glBindTexture(GL_TEXTURE_2D, colorBufferTex[3]);
1008 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1009 GL_UNSIGNED_BYTE, color3.data());
1010 glBindTexture(GL_TEXTURE_2D, 0);
1011 for (unsigned int i = 0; i < kMaxColorBuffer; i++)
1012 {
1013 glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
1014 colorBufferTex[i], 0);
1015 }
1016 glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
1017
1018 ASSERT_GL_NO_ERROR();
1019
1020 float color[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1021 GLint colorLocation = glGetUniformLocation(program, "u_color");
1022 glUniform4fv(colorLocation, 1, color);
1023
1024 GLint positionLocation = glGetAttribLocation(program, "a_position");
1025 render(positionLocation, !mCoherentExtension);
1026
1027 ASSERT_GL_NO_ERROR();
1028
1029 glReadBuffer(colorAttachments[0]);
1030 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1031 glReadBuffer(colorAttachments[1]);
1032 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1033 glReadBuffer(colorAttachments[2]);
1034 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
1035 glReadBuffer(colorAttachments[3]);
1036 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::white);
1037
1038 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1039 }
1040
MultipleDrawTest(GLProgram & program)1041 void MultipleDrawTest(GLProgram &program)
1042 {
1043 GLFramebuffer framebuffer;
1044 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1045 std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
1046 GLTexture colorBufferTex;
1047 glBindTexture(GL_TEXTURE_2D, colorBufferTex);
1048 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1049 GL_UNSIGNED_BYTE, greenColor.data());
1050 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
1051 0);
1052
1053 ASSERT_GL_NO_ERROR();
1054
1055 float color1[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1056 GLint colorLocation = glGetUniformLocation(program, "u_color");
1057 glUniform4fv(colorLocation, 1, color1);
1058
1059 GLint positionLocation = glGetAttribLocation(program, "a_position");
1060 render(positionLocation, !mCoherentExtension);
1061
1062 float color2[4] = {0.0f, 0.0f, 1.0f, 1.0f};
1063 glUniform4fv(colorLocation, 1, color2);
1064
1065 render(positionLocation, !mCoherentExtension);
1066
1067 ASSERT_GL_NO_ERROR();
1068
1069 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::white);
1070
1071 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1072 }
1073
DrawNonFetchDrawFetchTest(GLProgram & programNonFetch,GLProgram & programFetch)1074 void DrawNonFetchDrawFetchTest(GLProgram &programNonFetch, GLProgram &programFetch)
1075 {
1076 glUseProgram(programNonFetch);
1077 ASSERT_GL_NO_ERROR();
1078
1079 GLFramebuffer framebuffer;
1080 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1081 std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
1082 GLTexture colorBufferTex;
1083 glBindTexture(GL_TEXTURE_2D, colorBufferTex);
1084 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1085 GL_UNSIGNED_BYTE, greenColor.data());
1086 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
1087 0);
1088
1089 ASSERT_GL_NO_ERROR();
1090
1091 float colorRed[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1092 GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
1093 glUniform4fv(colorLocationNonFetch, 1, colorRed);
1094
1095 GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
1096 // Render without regard to glFramebufferFetchBarrierEXT()
1097 render(positionLocationNonFetch, GL_FALSE);
1098
1099 ASSERT_GL_NO_ERROR();
1100
1101 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1102
1103 glUseProgram(programFetch);
1104
1105 float colorGreen[4] = {0.0f, 1.0f, 0.0f, 1.0f};
1106 GLint colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
1107 glUniform4fv(colorLocationFetch, 1, colorGreen);
1108
1109 GLint positionLocationFetch = glGetAttribLocation(programFetch, "a_position");
1110 // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1111 // extension being used
1112 render(positionLocationFetch, !mCoherentExtension);
1113
1114 ASSERT_GL_NO_ERROR();
1115
1116 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1117
1118 glUseProgram(programNonFetch);
1119 glUniform4fv(colorLocationNonFetch, 1, colorRed);
1120 // Render without regard to glFramebufferFetchBarrierEXT()
1121 render(positionLocationNonFetch, GL_FALSE);
1122
1123 ASSERT_GL_NO_ERROR();
1124
1125 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1126
1127 glUseProgram(programFetch);
1128 glUniform4fv(colorLocationFetch, 1, colorGreen);
1129 // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1130 // extension being used
1131 render(positionLocationFetch, !mCoherentExtension);
1132
1133 ASSERT_GL_NO_ERROR();
1134
1135 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1136
1137 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1138 }
1139
DrawFetchDrawNonFetchTest(GLProgram & programNonFetch,GLProgram & programFetch)1140 void DrawFetchDrawNonFetchTest(GLProgram &programNonFetch, GLProgram &programFetch)
1141 {
1142 glUseProgram(programFetch);
1143 ASSERT_GL_NO_ERROR();
1144
1145 GLFramebuffer framebuffer;
1146 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1147 std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
1148 GLTexture colorBufferTex;
1149 glBindTexture(GL_TEXTURE_2D, colorBufferTex);
1150 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1151 GL_UNSIGNED_BYTE, greenColor.data());
1152 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
1153 0);
1154
1155 ASSERT_GL_NO_ERROR();
1156
1157 float colorRed[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1158 GLint colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
1159 glUniform4fv(colorLocationFetch, 1, colorRed);
1160
1161 GLint positionLocationFetch = glGetAttribLocation(programFetch, "a_position");
1162 // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1163 // extension being used
1164 render(positionLocationFetch, !mCoherentExtension);
1165 ASSERT_GL_NO_ERROR();
1166
1167 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1168
1169 glUseProgram(programNonFetch);
1170
1171 GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
1172 glUniform4fv(colorLocationNonFetch, 1, colorRed);
1173
1174 GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
1175 // Render without regard to glFramebufferFetchBarrierEXT()
1176 render(positionLocationNonFetch, GL_FALSE);
1177 ASSERT_GL_NO_ERROR();
1178
1179 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1180
1181 float colorGreen[4] = {0.0f, 1.0f, 0.0f, 1.0f};
1182 glUseProgram(programFetch);
1183 glUniform4fv(colorLocationFetch, 1, colorGreen);
1184 // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1185 // extension being used
1186 render(positionLocationFetch, !mCoherentExtension);
1187 ASSERT_GL_NO_ERROR();
1188
1189 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1190
1191 glUseProgram(programNonFetch);
1192 glUniform4fv(colorLocationNonFetch, 1, colorRed);
1193 // Render without regard to glFramebufferFetchBarrierEXT()
1194 render(positionLocationNonFetch, GL_FALSE);
1195
1196 ASSERT_GL_NO_ERROR();
1197
1198 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1199
1200 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1201 }
1202
1203 enum class StorageBufferTestPostFetchAction
1204 {
1205 Nothing,
1206 Clear,
1207 };
1208
DrawNonFetchDrawFetchInStorageBufferTest(GLProgram & programNonFetch,GLProgram & programFetch,StorageBufferTestPostFetchAction postFetchAction)1209 void DrawNonFetchDrawFetchInStorageBufferTest(GLProgram &programNonFetch,
1210 GLProgram &programFetch,
1211 StorageBufferTestPostFetchAction postFetchAction)
1212 {
1213 // Create output buffer
1214 constexpr GLsizei kBufferSize = kViewportWidth * kViewportHeight * sizeof(float[4]);
1215 GLBuffer buffer;
1216 glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
1217 glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
1218 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, buffer, 0, kBufferSize);
1219
1220 // Zero-initialize it
1221 void *bufferData = glMapBufferRange(
1222 GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,
1223 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
1224 memset(bufferData, 0, kBufferSize);
1225 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
1226
1227 glUseProgram(programNonFetch);
1228 ASSERT_GL_NO_ERROR();
1229
1230 GLFramebuffer framebuffer;
1231 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1232 std::vector<GLColor> initColor(kViewportWidth * kViewportHeight, GLColor{10, 20, 30, 40});
1233 GLTexture colorBufferTex;
1234 glBindTexture(GL_TEXTURE_2D, colorBufferTex);
1235 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1236 GL_UNSIGNED_BYTE, initColor.data());
1237 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
1238 0);
1239
1240 ASSERT_GL_NO_ERROR();
1241
1242 float colorRed[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1243 GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
1244 glUniform4fv(colorLocationNonFetch, 1, colorRed);
1245
1246 GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
1247
1248 // Mask color output. The no-fetch draw call should be a no-op, and the fetch draw-call
1249 // should only output to the storage buffer, but not the color attachment.
1250 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1251
1252 // Render without regard to glFramebufferFetchBarrierEXT()
1253 render(positionLocationNonFetch, GL_FALSE);
1254
1255 ASSERT_GL_NO_ERROR();
1256
1257 glUseProgram(programFetch);
1258
1259 float colorBlue[4] = {0.0f, 0.0f, 1.0f, 1.0f};
1260 GLint colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
1261 glUniform4fv(colorLocationFetch, 1, colorBlue);
1262
1263 GLint positionLocationFetch = glGetAttribLocation(programFetch, "a_position");
1264 // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1265 // extension being used
1266 render(positionLocationFetch, !mCoherentExtension);
1267
1268 ASSERT_GL_NO_ERROR();
1269
1270 // Enable the color mask and clear the alpha channel. This shouldn't be reordered with the
1271 // fetch draw.
1272 GLColor expect = initColor[0];
1273 if (postFetchAction == StorageBufferTestPostFetchAction::Clear)
1274 {
1275 expect.A = 200;
1276 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
1277 glClearColor(0.5, 0.6, 0.7, expect.A / 255.0f);
1278 glClear(GL_COLOR_BUFFER_BIT);
1279 }
1280
1281 // Since color is completely masked out, the texture should retain its original green color.
1282 EXPECT_PIXEL_COLOR_NEAR(kViewportWidth / 2, kViewportHeight / 2, expect, 1);
1283
1284 // Read back the storage buffer and make sure framebuffer fetch worked as intended despite
1285 // masked color.
1286 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
1287
1288 const float *colorData = static_cast<const float *>(
1289 glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT));
1290 for (uint32_t y = 0; y < kViewportHeight; ++y)
1291 {
1292 for (uint32_t x = 0; x < kViewportWidth; ++x)
1293 {
1294 uint32_t ssboIndex = (y * kViewportWidth + x) * 4;
1295 EXPECT_NEAR(colorData[ssboIndex + 0], initColor[0].R / 255.0, 0.05);
1296 EXPECT_NEAR(colorData[ssboIndex + 1], initColor[0].G / 255.0, 0.05);
1297 EXPECT_NEAR(colorData[ssboIndex + 2], initColor[0].B / 255.0, 0.05);
1298 EXPECT_NEAR(colorData[ssboIndex + 3], initColor[0].A / 255.0, 0.05);
1299 }
1300 }
1301 glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
1302
1303 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1304 }
1305
DrawNonFetchDrawFetchWithDifferentAttachmentsTest(GLProgram & programNonFetch,GLProgram & programFetch)1306 void DrawNonFetchDrawFetchWithDifferentAttachmentsTest(GLProgram &programNonFetch,
1307 GLProgram &programFetch)
1308 {
1309 glUseProgram(programNonFetch);
1310 ASSERT_GL_NO_ERROR();
1311
1312 GLFramebuffer framebuffer;
1313 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1314 std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
1315 GLTexture colorTex;
1316 glBindTexture(GL_TEXTURE_2D, colorTex);
1317 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1318 GL_UNSIGNED_BYTE, greenColor.data());
1319 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
1320
1321 ASSERT_GL_NO_ERROR();
1322
1323 float colorRed[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1324 GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
1325 glUniform4fv(colorLocationNonFetch, 1, colorRed);
1326
1327 GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
1328 // Render without regard to glFramebufferFetchBarrierEXT()
1329 render(positionLocationNonFetch, GL_FALSE);
1330 ASSERT_GL_NO_ERROR();
1331
1332 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1333
1334 glUseProgram(programFetch);
1335 ASSERT_GL_NO_ERROR();
1336
1337 GLFramebuffer framebufferMRT1;
1338 glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT1);
1339 std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
1340 std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
1341 GLTexture colorBufferTex1[kMaxColorBuffer];
1342 GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
1343 GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
1344 glBindTexture(GL_TEXTURE_2D, colorBufferTex1[0]);
1345 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1346 GL_UNSIGNED_BYTE, color1.data());
1347 glBindTexture(GL_TEXTURE_2D, colorBufferTex1[1]);
1348 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1349 GL_UNSIGNED_BYTE, color1.data());
1350 glBindTexture(GL_TEXTURE_2D, colorBufferTex1[2]);
1351 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1352 GL_UNSIGNED_BYTE, color2.data());
1353 glBindTexture(GL_TEXTURE_2D, colorBufferTex1[3]);
1354 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1355 GL_UNSIGNED_BYTE, color2.data());
1356 glBindTexture(GL_TEXTURE_2D, 0);
1357 for (unsigned int i = 0; i < kMaxColorBuffer; i++)
1358 {
1359 glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
1360 colorBufferTex1[i], 0);
1361 }
1362 glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
1363 ASSERT_GL_NO_ERROR();
1364
1365 GLint colorLocation = glGetUniformLocation(programFetch, "u_color");
1366 glUniform4fv(colorLocation, 1, colorRed);
1367
1368 GLint positionLocation = glGetAttribLocation(programFetch, "a_position");
1369 // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1370 // extension being used
1371 render(positionLocation, !mCoherentExtension);
1372 ASSERT_GL_NO_ERROR();
1373
1374 glReadBuffer(colorAttachments[0]);
1375 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1376 glReadBuffer(colorAttachments[1]);
1377 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1378 glReadBuffer(colorAttachments[2]);
1379 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
1380 glReadBuffer(colorAttachments[3]);
1381 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1382
1383 GLFramebuffer framebufferMRT2;
1384 glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT2);
1385 GLTexture colorBufferTex2[kMaxColorBuffer];
1386 glBindTexture(GL_TEXTURE_2D, colorBufferTex2[0]);
1387 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1388 GL_UNSIGNED_BYTE, color2.data());
1389 glBindTexture(GL_TEXTURE_2D, colorBufferTex2[1]);
1390 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1391 GL_UNSIGNED_BYTE, color2.data());
1392 glBindTexture(GL_TEXTURE_2D, colorBufferTex2[2]);
1393 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1394 GL_UNSIGNED_BYTE, color1.data());
1395 glBindTexture(GL_TEXTURE_2D, colorBufferTex2[3]);
1396 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1397 GL_UNSIGNED_BYTE, color1.data());
1398 glBindTexture(GL_TEXTURE_2D, 0);
1399 for (unsigned int i = 0; i < kMaxColorBuffer; i++)
1400 {
1401 glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
1402 colorBufferTex2[i], 0);
1403 }
1404 glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
1405 ASSERT_GL_NO_ERROR();
1406
1407 glUniform4fv(colorLocation, 1, colorRed);
1408 // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1409 // extension being used
1410 render(positionLocation, !mCoherentExtension);
1411 ASSERT_GL_NO_ERROR();
1412
1413 glReadBuffer(colorAttachments[0]);
1414 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
1415 glReadBuffer(colorAttachments[1]);
1416 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1417 glReadBuffer(colorAttachments[2]);
1418 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1419 glReadBuffer(colorAttachments[3]);
1420 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1421
1422 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1423 }
1424
DrawNonFetchDrawFetchWithDifferentProgramsTest(GLProgram & programNonFetch,GLProgram & programFetch1,GLProgram & programFetch2)1425 void DrawNonFetchDrawFetchWithDifferentProgramsTest(GLProgram &programNonFetch,
1426 GLProgram &programFetch1,
1427 GLProgram &programFetch2)
1428 {
1429 glUseProgram(programNonFetch);
1430 ASSERT_GL_NO_ERROR();
1431 GLFramebuffer framebuffer;
1432 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1433 std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
1434 GLTexture colorTex;
1435 glBindTexture(GL_TEXTURE_2D, colorTex);
1436 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1437 GL_UNSIGNED_BYTE, greenColor.data());
1438 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
1439
1440 ASSERT_GL_NO_ERROR();
1441
1442 float colorRed[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1443 GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
1444 glUniform4fv(colorLocationNonFetch, 1, colorRed);
1445
1446 GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
1447 // Render without regard to glFramebufferFetchBarrierEXT()
1448 render(positionLocationNonFetch, GL_FALSE);
1449 ASSERT_GL_NO_ERROR();
1450
1451 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1452
1453 glUseProgram(programFetch1);
1454 ASSERT_GL_NO_ERROR();
1455
1456 GLFramebuffer framebufferMRT1;
1457 glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT1);
1458 std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
1459 GLTexture colorBufferTex1[kMaxColorBuffer];
1460 GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
1461 GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
1462 for (unsigned int i = 0; i < kMaxColorBuffer; i++)
1463 {
1464 glBindTexture(GL_TEXTURE_2D, colorBufferTex1[i]);
1465 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1466 GL_UNSIGNED_BYTE, color1.data());
1467 glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
1468 colorBufferTex1[i], 0);
1469 }
1470 glBindTexture(GL_TEXTURE_2D, 0);
1471 glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
1472 ASSERT_GL_NO_ERROR();
1473
1474 GLint colorLocation = glGetUniformLocation(programFetch1, "u_color");
1475 glUniform4fv(colorLocation, 1, colorRed);
1476
1477 GLint positionLocation = glGetAttribLocation(programFetch1, "a_position");
1478 // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1479 // extension being used
1480 render(positionLocation, !mCoherentExtension);
1481 ASSERT_GL_NO_ERROR();
1482
1483 glReadBuffer(colorAttachments[0]);
1484 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1485 glReadBuffer(colorAttachments[1]);
1486 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1487 glReadBuffer(colorAttachments[2]);
1488 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1489 glReadBuffer(colorAttachments[3]);
1490 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1491
1492 glUseProgram(programFetch2);
1493 ASSERT_GL_NO_ERROR();
1494
1495 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1496 glClear(GL_COLOR_BUFFER_BIT);
1497
1498 GLint colorLocation1 = glGetUniformLocation(programFetch2, "u_color");
1499 glUniform4fv(colorLocation1, 1, colorRed);
1500
1501 GLint positionLocation1 = glGetAttribLocation(programFetch2, "a_position");
1502 // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1503 // extension being used
1504 render(positionLocation1, !mCoherentExtension);
1505 ASSERT_GL_NO_ERROR();
1506
1507 glReadBuffer(colorAttachments[0]);
1508 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1509 glReadBuffer(colorAttachments[1]);
1510 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1511 glReadBuffer(colorAttachments[2]);
1512 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1513 glReadBuffer(colorAttachments[3]);
1514 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1515
1516 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1517 }
1518
DrawFetchWithDifferentIndicesInSameRenderPassTest(GLProgram & programFetch1,GLProgram & programFetch2)1519 void DrawFetchWithDifferentIndicesInSameRenderPassTest(GLProgram &programFetch1,
1520 GLProgram &programFetch2)
1521 {
1522 GLFramebuffer framebufferMRT1;
1523 glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT1);
1524 std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
1525 GLTexture colorBufferTex1[kMaxColorBuffer];
1526 GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
1527 GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
1528 for (unsigned int i = 0; i < kMaxColorBuffer; i++)
1529 {
1530 glBindTexture(GL_TEXTURE_2D, colorBufferTex1[i]);
1531 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1532 GL_UNSIGNED_BYTE, color1.data());
1533 glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
1534 colorBufferTex1[i], 0);
1535 }
1536 glBindTexture(GL_TEXTURE_2D, 0);
1537 glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
1538 ASSERT_GL_NO_ERROR();
1539
1540 glUseProgram(programFetch1);
1541 ASSERT_GL_NO_ERROR();
1542
1543 GLint colorLocation = glGetUniformLocation(programFetch1, "u_color");
1544 const float colorRed[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1545 glUniform4fv(colorLocation, 1, colorRed);
1546
1547 GLint positionLocation = glGetAttribLocation(programFetch1, "a_position");
1548 // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1549 // extension being used
1550 //
1551 // Attachments are red, yellow, yellow, red
1552 render(positionLocation, !mCoherentExtension);
1553 ASSERT_GL_NO_ERROR();
1554
1555 glUseProgram(programFetch2);
1556 ASSERT_GL_NO_ERROR();
1557
1558 GLint colorLocation1 = glGetUniformLocation(programFetch2, "u_color");
1559 const float colorBlue[4] = {0.0f, 0.0f, 1.0f, 1.0f};
1560 glUniform4fv(colorLocation1, 1, colorBlue);
1561
1562 GLint positionLocation1 = glGetAttribLocation(programFetch2, "a_position");
1563 // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1564 // extension being used
1565 //
1566 // Attachments are blue, blue, white, magenta
1567 render(positionLocation1, !mCoherentExtension);
1568 ASSERT_GL_NO_ERROR();
1569
1570 glReadBuffer(colorAttachments[0]);
1571 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
1572 glReadBuffer(colorAttachments[1]);
1573 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
1574 glReadBuffer(colorAttachments[2]);
1575 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::white);
1576 glReadBuffer(colorAttachments[3]);
1577 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
1578
1579 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1580 }
1581
DrawFetchBlitDrawFetchTest(GLProgram & programNonFetch,GLProgram & programFetch)1582 void DrawFetchBlitDrawFetchTest(GLProgram &programNonFetch, GLProgram &programFetch)
1583 {
1584 glUseProgram(programFetch);
1585 ASSERT_GL_NO_ERROR();
1586
1587 GLFramebuffer framebufferMRT1;
1588 glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT1);
1589 std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
1590 std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
1591 GLTexture colorBufferTex1[kMaxColorBuffer];
1592 GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
1593 GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
1594 glBindTexture(GL_TEXTURE_2D, colorBufferTex1[0]);
1595 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1596 GL_UNSIGNED_BYTE, color1.data());
1597 glBindTexture(GL_TEXTURE_2D, colorBufferTex1[1]);
1598 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1599 GL_UNSIGNED_BYTE, color1.data());
1600 glBindTexture(GL_TEXTURE_2D, colorBufferTex1[2]);
1601 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1602 GL_UNSIGNED_BYTE, color2.data());
1603 glBindTexture(GL_TEXTURE_2D, colorBufferTex1[3]);
1604 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1605 GL_UNSIGNED_BYTE, color2.data());
1606 glBindTexture(GL_TEXTURE_2D, 0);
1607 for (unsigned int i = 0; i < kMaxColorBuffer; i++)
1608 {
1609 glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
1610 colorBufferTex1[i], 0);
1611 }
1612 glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
1613 ASSERT_GL_NO_ERROR();
1614
1615 float colorRed[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1616 GLint colorLocation = glGetUniformLocation(programFetch, "u_color");
1617 glUniform4fv(colorLocation, 1, colorRed);
1618
1619 GLint positionLocation = glGetAttribLocation(programFetch, "a_position");
1620 // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1621 // extension being used
1622 render(positionLocation, !mCoherentExtension);
1623 ASSERT_GL_NO_ERROR();
1624
1625 glReadBuffer(colorAttachments[0]);
1626 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1627 glReadBuffer(colorAttachments[1]);
1628 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1629 glReadBuffer(colorAttachments[2]);
1630 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
1631 glReadBuffer(colorAttachments[3]);
1632 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1633
1634 GLFramebuffer framebufferColor;
1635 glBindFramebuffer(GL_FRAMEBUFFER, framebufferColor);
1636
1637 GLTexture colorTex;
1638 glBindTexture(GL_TEXTURE_2D, colorTex);
1639 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1640 GL_UNSIGNED_BYTE, color2.data());
1641 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
1642
1643 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, framebufferColor);
1644 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, framebufferMRT1);
1645
1646 glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth,
1647 kViewportHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1648 ASSERT_GL_NO_ERROR();
1649
1650 glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT1);
1651 glReadBuffer(colorAttachments[0]);
1652 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
1653 glReadBuffer(colorAttachments[1]);
1654 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
1655 glReadBuffer(colorAttachments[2]);
1656 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
1657 glReadBuffer(colorAttachments[3]);
1658 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
1659
1660 float colorGreen[4] = {0.0f, 1.0f, 0.0f, 1.0f};
1661 glUniform4fv(colorLocation, 1, colorGreen);
1662
1663 // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1664 // extension being used
1665 render(positionLocation, !mCoherentExtension);
1666 ASSERT_GL_NO_ERROR();
1667
1668 glReadBuffer(colorAttachments[0]);
1669 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::cyan);
1670 glReadBuffer(colorAttachments[1]);
1671 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
1672 glReadBuffer(colorAttachments[2]);
1673 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::cyan);
1674 glReadBuffer(colorAttachments[3]);
1675 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
1676
1677 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1678 }
1679
ProgramPipelineTest(const char * kVS,const char * kFS1,const char * kFS2)1680 void ProgramPipelineTest(const char *kVS, const char *kFS1, const char *kFS2)
1681 {
1682 GLProgram programVert, programNonFetch, programFetch;
1683 const char *sourceArray[3] = {kVS, kFS1, kFS2};
1684
1685 GLShader vertShader(GL_VERTEX_SHADER);
1686 glShaderSource(vertShader, 1, &sourceArray[0], nullptr);
1687 glCompileShader(vertShader);
1688 glProgramParameteri(programVert, GL_PROGRAM_SEPARABLE, GL_TRUE);
1689 glAttachShader(programVert, vertShader);
1690 glLinkProgram(programVert);
1691 ASSERT_GL_NO_ERROR();
1692
1693 GLShader fragShader1(GL_FRAGMENT_SHADER);
1694 glShaderSource(fragShader1, 1, &sourceArray[1], nullptr);
1695 glCompileShader(fragShader1);
1696 glProgramParameteri(programNonFetch, GL_PROGRAM_SEPARABLE, GL_TRUE);
1697 glAttachShader(programNonFetch, fragShader1);
1698 glLinkProgram(programNonFetch);
1699 ASSERT_GL_NO_ERROR();
1700
1701 GLShader fragShader2(GL_FRAGMENT_SHADER);
1702 glShaderSource(fragShader2, 1, &sourceArray[2], nullptr);
1703 glCompileShader(fragShader2);
1704 glProgramParameteri(programFetch, GL_PROGRAM_SEPARABLE, GL_TRUE);
1705 glAttachShader(programFetch, fragShader2);
1706 glLinkProgram(programFetch);
1707 ASSERT_GL_NO_ERROR();
1708
1709 GLProgramPipeline pipeline1, pipeline2, pipeline3, pipeline4;
1710 glUseProgramStages(pipeline1, GL_VERTEX_SHADER_BIT, programVert);
1711 glUseProgramStages(pipeline1, GL_FRAGMENT_SHADER_BIT, programNonFetch);
1712 glBindProgramPipeline(pipeline1);
1713 ASSERT_GL_NO_ERROR();
1714
1715 GLFramebuffer framebuffer;
1716 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1717 std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
1718 GLTexture colorBufferTex;
1719 glBindTexture(GL_TEXTURE_2D, colorBufferTex);
1720 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1721 GL_UNSIGNED_BYTE, greenColor.data());
1722 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
1723 0);
1724 ASSERT_GL_NO_ERROR();
1725
1726 glActiveShaderProgram(pipeline1, programNonFetch);
1727 float colorRed[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1728 GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
1729 glUniform4fv(colorLocationNonFetch, 1, colorRed);
1730 ASSERT_GL_NO_ERROR();
1731
1732 glActiveShaderProgram(pipeline1, programVert);
1733 GLint positionLocation = glGetAttribLocation(programVert, "a_position");
1734 // Render without regard to glFramebufferFetchBarrierEXT()
1735 render(positionLocation, GL_FALSE);
1736 ASSERT_GL_NO_ERROR();
1737
1738 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1739
1740 glUseProgramStages(pipeline2, GL_VERTEX_SHADER_BIT, programVert);
1741 glUseProgramStages(pipeline2, GL_FRAGMENT_SHADER_BIT, programFetch);
1742 glBindProgramPipeline(pipeline2);
1743 ASSERT_GL_NO_ERROR();
1744
1745 glActiveShaderProgram(pipeline2, programFetch);
1746 float colorGreen[4] = {0.0f, 1.0f, 0.0f, 1.0f};
1747 GLint colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
1748 glUniform4fv(colorLocationFetch, 1, colorGreen);
1749
1750 // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1751 // extension being used
1752 render(positionLocation, !mCoherentExtension);
1753 ASSERT_GL_NO_ERROR();
1754
1755 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1756
1757 glUseProgramStages(pipeline3, GL_VERTEX_SHADER_BIT, programVert);
1758 glUseProgramStages(pipeline3, GL_FRAGMENT_SHADER_BIT, programNonFetch);
1759 glBindProgramPipeline(pipeline3);
1760 ASSERT_GL_NO_ERROR();
1761
1762 glActiveShaderProgram(pipeline3, programNonFetch);
1763 colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
1764 glUniform4fv(colorLocationNonFetch, 1, colorRed);
1765
1766 ASSERT_GL_NO_ERROR();
1767
1768 // Render without regard to glFramebufferFetchBarrierEXT()
1769 render(positionLocation, GL_FALSE);
1770 ASSERT_GL_NO_ERROR();
1771
1772 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1773
1774 glUseProgramStages(pipeline4, GL_VERTEX_SHADER_BIT, programVert);
1775 glUseProgramStages(pipeline4, GL_FRAGMENT_SHADER_BIT, programFetch);
1776 glBindProgramPipeline(pipeline4);
1777 ASSERT_GL_NO_ERROR();
1778
1779 glActiveShaderProgram(pipeline4, programFetch);
1780 colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
1781 glUniform4fv(colorLocationFetch, 1, colorGreen);
1782 // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1783 // extension being used
1784 render(positionLocation, !mCoherentExtension);
1785 ASSERT_GL_NO_ERROR();
1786
1787 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1788
1789 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1790 }
1791
1792 bool mCoherentExtension;
1793 bool mARMExtension;
1794 bool mBothExtensions;
1795 };
1796
1797 // Test coherent extension with inout qualifier
TEST_P(FramebufferFetchES31,BasicInout_Coherent)1798 TEST_P(FramebufferFetchES31, BasicInout_Coherent)
1799 {
1800 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1801 setWhichExtension(COHERENT);
1802
1803 GLProgram program;
1804 program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1805 glUseProgram(program);
1806 ASSERT_GL_NO_ERROR();
1807
1808 BasicTest(program);
1809 }
1810
1811 // Test non-coherent extension with inout qualifier
TEST_P(FramebufferFetchES31,BasicInout_NonCoherent)1812 TEST_P(FramebufferFetchES31, BasicInout_NonCoherent)
1813 {
1814 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1815 setWhichExtension(NON_COHERENT);
1816
1817 GLProgram program;
1818 program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1819 glUseProgram(program);
1820 ASSERT_GL_NO_ERROR();
1821
1822 BasicTest(program);
1823 }
1824
1825 // Test coherent extension with gl_LastFragData
TEST_P(FramebufferFetchES31,BasicLastFragData_Coherent)1826 TEST_P(FramebufferFetchES31, BasicLastFragData_Coherent)
1827 {
1828 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1829 setWhichExtension(COHERENT);
1830
1831 GLProgram program;
1832 program.makeRaster(k100VS, getFragmentShader(GLSL100));
1833 glUseProgram(program);
1834 ASSERT_GL_NO_ERROR();
1835
1836 BasicTest(program);
1837 }
1838
1839 // Test non-coherent extension with gl_LastFragData
TEST_P(FramebufferFetchES31,BasicLastFragData_NonCoherent)1840 TEST_P(FramebufferFetchES31, BasicLastFragData_NonCoherent)
1841 {
1842 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1843 setWhichExtension(NON_COHERENT);
1844
1845 GLProgram program;
1846 program.makeRaster(k100VS, getFragmentShader(GLSL100));
1847 glUseProgram(program);
1848 ASSERT_GL_NO_ERROR();
1849
1850 BasicTest(program);
1851 }
1852
1853 // Testing coherent extension with multiple render target, using gl_FragData with constant indices
TEST_P(FramebufferFetchES31,MultipleRenderTarget_Coherent_FragData)1854 TEST_P(FramebufferFetchES31, MultipleRenderTarget_Coherent_FragData)
1855 {
1856 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1857 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_draw_buffers"));
1858 setWhichExtension(COHERENT);
1859
1860 GLProgram program;
1861 program.makeRaster(k100VS, getFragmentShader(GLSL100_4ATTACHMENT));
1862 glUseProgram(program);
1863 ASSERT_GL_NO_ERROR();
1864
1865 MultipleRenderTargetTest(program, GLSL100_4ATTACHMENT);
1866 }
1867
1868 // Testing coherent extension with multiple render target, using gl_FragData with complex
1869 // expressions
TEST_P(FramebufferFetchES31,MultipleRenderTarget_Coherent_FragData_Complex)1870 TEST_P(FramebufferFetchES31, MultipleRenderTarget_Coherent_FragData_Complex)
1871 {
1872 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1873 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_draw_buffers"));
1874 setWhichExtension(COHERENT);
1875
1876 GLProgram program;
1877 program.makeRaster(k100VS, getFragmentShader(GLSL100_COMPLEX));
1878 glUseProgram(program);
1879 ASSERT_GL_NO_ERROR();
1880
1881 MultipleRenderTargetTest(program, GLSL100_COMPLEX);
1882 }
1883
1884 // Testing coherent extension with multiple render target, using inouts with complex expressions
TEST_P(FramebufferFetchES31,MultipleRenderTarget_Coherent_Complex)1885 TEST_P(FramebufferFetchES31, MultipleRenderTarget_Coherent_Complex)
1886 {
1887 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1888 setWhichExtension(COHERENT);
1889
1890 GLProgram program;
1891 program.makeRaster(k310VS, getFragmentShader(GLSL310_COMPLEX));
1892 glUseProgram(program);
1893 ASSERT_GL_NO_ERROR();
1894
1895 MultipleRenderTargetTest(program, GLSL310_COMPLEX);
1896 }
1897
1898 // Testing coherent extension with multiple render target
TEST_P(FramebufferFetchES31,MultipleRenderTarget_Coherent)1899 TEST_P(FramebufferFetchES31, MultipleRenderTarget_Coherent)
1900 {
1901 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1902 setWhichExtension(COHERENT);
1903
1904 GLProgram program;
1905 program.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT));
1906 glUseProgram(program);
1907 ASSERT_GL_NO_ERROR();
1908
1909 MultipleRenderTargetTest(program, GLSL310_4ATTACHMENT);
1910 }
1911
1912 // Testing non-coherent extension with multiple render target, using gl_FragData with constant
1913 // indices
TEST_P(FramebufferFetchES31,MultipleRenderTarget_NonCoherent_FragData)1914 TEST_P(FramebufferFetchES31, MultipleRenderTarget_NonCoherent_FragData)
1915 {
1916 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1917 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_draw_buffers"));
1918 setWhichExtension(NON_COHERENT);
1919
1920 GLProgram program;
1921 program.makeRaster(k100VS, getFragmentShader(GLSL100_4ATTACHMENT));
1922 glUseProgram(program);
1923 ASSERT_GL_NO_ERROR();
1924
1925 MultipleRenderTargetTest(program, GLSL100_4ATTACHMENT);
1926 }
1927
1928 // Testing non-coherent extension with multiple render target, using gl_FragData with complex
1929 // expressions
TEST_P(FramebufferFetchES31,MultipleRenderTarget_NonCoherent_FragData_Complex)1930 TEST_P(FramebufferFetchES31, MultipleRenderTarget_NonCoherent_FragData_Complex)
1931 {
1932 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1933 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_draw_buffers"));
1934 setWhichExtension(NON_COHERENT);
1935
1936 GLProgram program;
1937 program.makeRaster(k100VS, getFragmentShader(GLSL100_COMPLEX));
1938 glUseProgram(program);
1939 ASSERT_GL_NO_ERROR();
1940
1941 MultipleRenderTargetTest(program, GLSL100_COMPLEX);
1942 }
1943
1944 // Testing non-coherent extension with multiple render target, using inouts with complex expressions
TEST_P(FramebufferFetchES31,MultipleRenderTarget_NonCoherent_Complex)1945 TEST_P(FramebufferFetchES31, MultipleRenderTarget_NonCoherent_Complex)
1946 {
1947 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1948 setWhichExtension(NON_COHERENT);
1949
1950 GLProgram program;
1951 program.makeRaster(k310VS, getFragmentShader(GLSL310_COMPLEX));
1952 glUseProgram(program);
1953 ASSERT_GL_NO_ERROR();
1954
1955 MultipleRenderTargetTest(program, GLSL310_COMPLEX);
1956 }
1957
1958 // Testing non-coherent extension with multiple render target
TEST_P(FramebufferFetchES31,MultipleRenderTarget_NonCoherent)1959 TEST_P(FramebufferFetchES31, MultipleRenderTarget_NonCoherent)
1960 {
1961 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1962 setWhichExtension(NON_COHERENT);
1963
1964 GLProgram program;
1965 program.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT));
1966 glUseProgram(program);
1967 ASSERT_GL_NO_ERROR();
1968
1969 MultipleRenderTargetTest(program, GLSL310_4ATTACHMENT);
1970 }
1971
1972 // Testing non-coherent extension with multiple render target using inout array
TEST_P(FramebufferFetchES31,MultipleRenderTargetWithInoutArray_NonCoherent)1973 TEST_P(FramebufferFetchES31, MultipleRenderTargetWithInoutArray_NonCoherent)
1974 {
1975 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1976 setWhichExtension(NON_COHERENT);
1977
1978 GLProgram program;
1979 program.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT));
1980 glUseProgram(program);
1981 ASSERT_GL_NO_ERROR();
1982
1983 MultipleRenderTargetTest(program, GLSL310_4ATTACHMENT);
1984 }
1985
1986 // Testing coherent extension with multiple render target using inout array
TEST_P(FramebufferFetchES31,MultipleRenderTargetWithInoutArray_Coherent)1987 TEST_P(FramebufferFetchES31, MultipleRenderTargetWithInoutArray_Coherent)
1988 {
1989 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1990 setWhichExtension(COHERENT);
1991
1992 GLProgram program;
1993 program.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT));
1994 glUseProgram(program);
1995 ASSERT_GL_NO_ERROR();
1996
1997 MultipleRenderTargetTest(program, GLSL310_4ATTACHMENT);
1998 }
1999
2000 // Test coherent extension with multiple draw
TEST_P(FramebufferFetchES31,MultipleDraw_Coherent)2001 TEST_P(FramebufferFetchES31, MultipleDraw_Coherent)
2002 {
2003 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2004 setWhichExtension(COHERENT);
2005
2006 GLProgram program;
2007 program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
2008 glUseProgram(program);
2009 ASSERT_GL_NO_ERROR();
2010
2011 MultipleDrawTest(program);
2012 }
2013
2014 // Test non-coherent extension with multiple draw
TEST_P(FramebufferFetchES31,MultipleDraw_NonCoherent)2015 TEST_P(FramebufferFetchES31, MultipleDraw_NonCoherent)
2016 {
2017 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2018 setWhichExtension(NON_COHERENT);
2019
2020 GLProgram program;
2021 program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
2022 glUseProgram(program);
2023 ASSERT_GL_NO_ERROR();
2024
2025 MultipleDrawTest(program);
2026 }
2027
2028 // Testing coherent extension with the order of non-fetch program and fetch program
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetch_Coherent)2029 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetch_Coherent)
2030 {
2031 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2032 setWhichExtension(COHERENT);
2033
2034 GLProgram programNonFetch, programFetch;
2035 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2036 programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
2037 ASSERT_GL_NO_ERROR();
2038
2039 DrawNonFetchDrawFetchTest(programNonFetch, programFetch);
2040 }
2041
2042 // Testing non-coherent extension with the order of non-fetch program and fetch program
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetch_NonCoherent)2043 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetch_NonCoherent)
2044 {
2045 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2046 setWhichExtension(NON_COHERENT);
2047
2048 GLProgram programNonFetch, programFetch;
2049 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2050 programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
2051 ASSERT_GL_NO_ERROR();
2052
2053 DrawNonFetchDrawFetchTest(programNonFetch, programFetch);
2054 }
2055
2056 // Testing coherent extension with the order of fetch program and non-fetch program
TEST_P(FramebufferFetchES31,DrawFetchDrawNonFetch_Coherent)2057 TEST_P(FramebufferFetchES31, DrawFetchDrawNonFetch_Coherent)
2058 {
2059 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2060 setWhichExtension(COHERENT);
2061
2062 GLProgram programNonFetch, programFetch;
2063 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2064 programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
2065 ASSERT_GL_NO_ERROR();
2066
2067 DrawFetchDrawNonFetchTest(programNonFetch, programFetch);
2068 }
2069
2070 // Testing non-coherent extension with the order of fetch program and non-fetch program
TEST_P(FramebufferFetchES31,DrawFetchDrawNonFetch_NonCoherent)2071 TEST_P(FramebufferFetchES31, DrawFetchDrawNonFetch_NonCoherent)
2072 {
2073 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2074 setWhichExtension(NON_COHERENT);
2075
2076 GLProgram programNonFetch, programFetch;
2077 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2078 programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
2079 ASSERT_GL_NO_ERROR();
2080
2081 DrawFetchDrawNonFetchTest(programNonFetch, programFetch);
2082 }
2083
2084 // Testing coherent extension with framebuffer fetch read in combination with color attachment mask
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchInStorageBuffer_Coherent)2085 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchInStorageBuffer_Coherent)
2086 {
2087 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2088 setWhichExtension(COHERENT);
2089
2090 GLint maxFragmentShaderStorageBlocks = 0;
2091 glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
2092 ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks == 0);
2093
2094 GLProgram programNonFetch, programFetch;
2095 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2096 programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER));
2097 ASSERT_GL_NO_ERROR();
2098
2099 DrawNonFetchDrawFetchInStorageBufferTest(programNonFetch, programFetch,
2100 StorageBufferTestPostFetchAction::Nothing);
2101 }
2102
2103 // Testing non-coherent extension with framebuffer fetch read in combination with color attachment
2104 // mask
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchInStorageBuffer_NonCoherent)2105 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchInStorageBuffer_NonCoherent)
2106 {
2107 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2108 setWhichExtension(NON_COHERENT);
2109
2110 GLint maxFragmentShaderStorageBlocks = 0;
2111 glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
2112 ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks == 0);
2113
2114 GLProgram programNonFetch, programFetch;
2115 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2116 programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER));
2117 ASSERT_GL_NO_ERROR();
2118
2119 DrawNonFetchDrawFetchInStorageBufferTest(programNonFetch, programFetch,
2120 StorageBufferTestPostFetchAction::Nothing);
2121 }
2122
2123 // Testing coherent extension with the order of non-fetch program and fetch program with
2124 // different attachments
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchWithDifferentAttachments_Coherent)2125 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchWithDifferentAttachments_Coherent)
2126 {
2127 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2128 setWhichExtension(COHERENT);
2129
2130 GLProgram programNonFetch, programFetch;
2131 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2132 programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
2133 ASSERT_GL_NO_ERROR();
2134
2135 DrawNonFetchDrawFetchWithDifferentAttachmentsTest(programNonFetch, programFetch);
2136 }
2137
2138 // Testing coherent extension with framebuffer fetch read in combination with color attachment mask
2139 // and clear
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchInStorageBufferThenClear_Coherent)2140 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchInStorageBufferThenClear_Coherent)
2141 {
2142 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2143 setWhichExtension(COHERENT);
2144
2145 GLint maxFragmentShaderStorageBlocks = 0;
2146 glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
2147 ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks == 0);
2148
2149 GLProgram programNonFetch, programFetch;
2150 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2151 programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER));
2152 ASSERT_GL_NO_ERROR();
2153
2154 DrawNonFetchDrawFetchInStorageBufferTest(programNonFetch, programFetch,
2155 StorageBufferTestPostFetchAction::Clear);
2156 }
2157
2158 // Testing non-coherent extension with framebuffer fetch read in combination with color attachment
2159 // mask and clear
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchInStorageBufferThenClear_NonCoherent)2160 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchInStorageBufferThenClear_NonCoherent)
2161 {
2162 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2163 setWhichExtension(NON_COHERENT);
2164
2165 GLint maxFragmentShaderStorageBlocks = 0;
2166 glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
2167 ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks == 0);
2168
2169 GLProgram programNonFetch, programFetch;
2170 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2171 programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER));
2172 ASSERT_GL_NO_ERROR();
2173
2174 DrawNonFetchDrawFetchInStorageBufferTest(programNonFetch, programFetch,
2175 StorageBufferTestPostFetchAction::Clear);
2176 }
2177
2178 // Testing non-coherent extension with the order of non-fetch program and fetch program with
2179 // different attachments
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchWithDifferentAttachments_NonCoherent)2180 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchWithDifferentAttachments_NonCoherent)
2181 {
2182 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2183 setWhichExtension(NON_COHERENT);
2184
2185 GLProgram programNonFetch, programFetch;
2186 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2187 programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
2188 ASSERT_GL_NO_ERROR();
2189
2190 DrawNonFetchDrawFetchWithDifferentAttachmentsTest(programNonFetch, programFetch);
2191 }
2192
2193 // Testing coherent extension with the order of non-fetch program and fetch with different
2194 // programs
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchWithDifferentPrograms_Coherent)2195 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchWithDifferentPrograms_Coherent)
2196 {
2197 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2198 setWhichExtension(COHERENT);
2199
2200 GLProgram programNonFetch, programFetch1, programFetch2;
2201 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2202 programFetch1.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
2203 programFetch2.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT2));
2204 ASSERT_GL_NO_ERROR();
2205
2206 DrawNonFetchDrawFetchWithDifferentProgramsTest(programNonFetch, programFetch1, programFetch2);
2207 }
2208
2209 // Testing non-coherent extension with the order of non-fetch program and fetch with different
2210 // programs
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchWithDifferentPrograms_NonCoherent)2211 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchWithDifferentPrograms_NonCoherent)
2212 {
2213 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2214 setWhichExtension(NON_COHERENT);
2215
2216 GLProgram programNonFetch, programFetch1, programFetch2;
2217 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2218 programFetch1.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
2219 programFetch2.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT2));
2220 ASSERT_GL_NO_ERROR();
2221
2222 DrawNonFetchDrawFetchWithDifferentProgramsTest(programNonFetch, programFetch1, programFetch2);
2223 }
2224
2225 // Testing coherent extension with two fetch programs using different attachments. The different
2226 // sets of attachments start at different non-zero indices.
TEST_P(FramebufferFetchES31,DrawFetchWithDifferentIndicesInSameRenderPass_Coherent)2227 TEST_P(FramebufferFetchES31, DrawFetchWithDifferentIndicesInSameRenderPass_Coherent)
2228 {
2229 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2230 setWhichExtension(COHERENT);
2231
2232 GLProgram programFetch1, programFetch2;
2233 programFetch1.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT3));
2234 programFetch2.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT4));
2235 ASSERT_GL_NO_ERROR();
2236
2237 DrawFetchWithDifferentIndicesInSameRenderPassTest(programFetch1, programFetch2);
2238 }
2239
2240 // Testing non-coherent extension with two fetch programs using different attachments. The
2241 // different sets of attachments start at different non-zero indices.
TEST_P(FramebufferFetchES31,DrawFetchWithDifferentIndicesInSameRenderPass_NonCoherent)2242 TEST_P(FramebufferFetchES31, DrawFetchWithDifferentIndicesInSameRenderPass_NonCoherent)
2243 {
2244 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2245 setWhichExtension(NON_COHERENT);
2246
2247 GLProgram programFetch1, programFetch2;
2248 programFetch1.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT3));
2249 programFetch2.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT4));
2250 ASSERT_GL_NO_ERROR();
2251
2252 DrawFetchWithDifferentIndicesInSameRenderPassTest(programFetch1, programFetch2);
2253 }
2254
2255 // Testing coherent extension with the order of draw fetch, blit and draw fetch
TEST_P(FramebufferFetchES31,DrawFetchBlitDrawFetch_Coherent)2256 TEST_P(FramebufferFetchES31, DrawFetchBlitDrawFetch_Coherent)
2257 {
2258 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2259 setWhichExtension(COHERENT);
2260
2261 GLProgram programNonFetch, programFetch;
2262 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2263 programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
2264 ASSERT_GL_NO_ERROR();
2265
2266 DrawFetchBlitDrawFetchTest(programNonFetch, programFetch);
2267 }
2268
2269 // Testing non-coherent extension with the order of draw fetch, blit and draw fetch
TEST_P(FramebufferFetchES31,DrawFetchBlitDrawFetch_NonCoherent)2270 TEST_P(FramebufferFetchES31, DrawFetchBlitDrawFetch_NonCoherent)
2271 {
2272 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2273 setWhichExtension(NON_COHERENT);
2274
2275 GLProgram programNonFetch, programFetch;
2276 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2277 programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
2278 ASSERT_GL_NO_ERROR();
2279
2280 DrawFetchBlitDrawFetchTest(programNonFetch, programFetch);
2281 }
2282
2283 // Testing coherent extension with program pipeline
TEST_P(FramebufferFetchES31,ProgramPipeline_Coherent)2284 TEST_P(FramebufferFetchES31, ProgramPipeline_Coherent)
2285 {
2286 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2287 setWhichExtension(COHERENT);
2288
2289 ProgramPipelineTest(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT),
2290 getFragmentShader(GLSL310_1ATTACHMENT));
2291 }
2292
2293 // Testing non-coherent extension with program pipeline
TEST_P(FramebufferFetchES31,ProgramPipeline_NonCoherent)2294 TEST_P(FramebufferFetchES31, ProgramPipeline_NonCoherent)
2295 {
2296 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2297 setWhichExtension(NON_COHERENT);
2298
2299 ProgramPipelineTest(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT),
2300 getFragmentShader(GLSL310_1ATTACHMENT));
2301 }
2302
2303 // Test combination of inout and samplers.
TEST_P(FramebufferFetchES31,UniformUsageCombinations)2304 TEST_P(FramebufferFetchES31, UniformUsageCombinations)
2305 {
2306 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2307
2308 constexpr char kVS[] = R"(#version 310 es
2309 in highp vec4 a_position;
2310 out highp vec2 texCoord;
2311
2312 void main()
2313 {
2314 gl_Position = a_position;
2315 texCoord = (a_position.xy * 0.5) + 0.5;
2316 })";
2317
2318 constexpr char kFS[] = R"(#version 310 es
2319 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
2320
2321 layout(binding=0, offset=0) uniform atomic_uint atDiff;
2322 uniform sampler2D tex;
2323
2324 layout(noncoherent, location = 0) inout highp vec4 o_color[4];
2325 in highp vec2 texCoord;
2326
2327 void main()
2328 {
2329 highp vec4 texColor = texture(tex, texCoord);
2330
2331 if (texColor != o_color[0])
2332 {
2333 atomicCounterIncrement(atDiff);
2334 o_color[0] = texColor;
2335 }
2336 else
2337 {
2338 if (atomicCounter(atDiff) > 0u)
2339 {
2340 atomicCounterDecrement(atDiff);
2341 }
2342 }
2343
2344 if (texColor != o_color[1])
2345 {
2346 atomicCounterIncrement(atDiff);
2347 o_color[1] = texColor;
2348 }
2349 else
2350 {
2351 if (atomicCounter(atDiff) > 0u)
2352 {
2353 atomicCounterDecrement(atDiff);
2354 }
2355 }
2356
2357 if (texColor != o_color[2])
2358 {
2359 atomicCounterIncrement(atDiff);
2360 o_color[2] = texColor;
2361 }
2362 else
2363 {
2364 if (atomicCounter(atDiff) > 0u)
2365 {
2366 atomicCounterDecrement(atDiff);
2367 }
2368 }
2369
2370 if (texColor != o_color[3])
2371 {
2372 atomicCounterIncrement(atDiff);
2373 o_color[3] = texColor;
2374 }
2375 else
2376 {
2377 if (atomicCounter(atDiff) > 0u)
2378 {
2379 atomicCounterDecrement(atDiff);
2380 }
2381 }
2382 })";
2383
2384 GLProgram program;
2385 program.makeRaster(kVS, kFS);
2386 glUseProgram(program);
2387
2388 ASSERT_GL_NO_ERROR();
2389
2390 GLFramebuffer framebuffer;
2391 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
2392 std::vector<GLColor> color0(kViewportWidth * kViewportHeight, GLColor::cyan);
2393 std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
2394 std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
2395 std::vector<GLColor> color3(kViewportWidth * kViewportHeight, GLColor::black);
2396 GLTexture colorBufferTex[kMaxColorBuffer];
2397 GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
2398 GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
2399 glBindTexture(GL_TEXTURE_2D, colorBufferTex[0]);
2400 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
2401 GL_UNSIGNED_BYTE, color0.data());
2402 glBindTexture(GL_TEXTURE_2D, colorBufferTex[1]);
2403 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
2404 GL_UNSIGNED_BYTE, color1.data());
2405 glBindTexture(GL_TEXTURE_2D, colorBufferTex[2]);
2406 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
2407 GL_UNSIGNED_BYTE, color2.data());
2408 glBindTexture(GL_TEXTURE_2D, colorBufferTex[3]);
2409 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
2410 GL_UNSIGNED_BYTE, color3.data());
2411 glBindTexture(GL_TEXTURE_2D, 0);
2412 for (unsigned int i = 0; i < kMaxColorBuffer; i++)
2413 {
2414 glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
2415 colorBufferTex[i], 0);
2416 }
2417 glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
2418
2419 ASSERT_GL_NO_ERROR();
2420
2421 GLBuffer atomicBuffer;
2422 glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicBuffer);
2423 glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_DRAW);
2424
2425 // Reset atomic counter buffer
2426 GLuint *userCounters;
2427 userCounters = static_cast<GLuint *>(glMapBufferRange(
2428 GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint),
2429 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT));
2430 memset(userCounters, 0, sizeof(GLuint));
2431 glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
2432
2433 glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicBuffer);
2434 glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);
2435
2436 float color[4] = {1.0f, 0.0f, 0.0f, 1.0f};
2437 GLint colorLocation = glGetUniformLocation(program, "u_color");
2438 glUniform4fv(colorLocation, 1, color);
2439
2440 GLint positionLocation = glGetAttribLocation(program, "a_position");
2441 render(positionLocation, GL_TRUE);
2442
2443 ASSERT_GL_NO_ERROR();
2444
2445 // Because no texture is bound, the shader samples black, increments the counter for every pixel
2446 // and sets all attachments to black.
2447 for (unsigned int i = 0; i < kMaxColorBuffer; i++)
2448 {
2449 glReadBuffer(colorAttachments[i]);
2450 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::black);
2451 }
2452
2453 glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicBuffer);
2454 userCounters = static_cast<GLuint *>(
2455 glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint), GL_MAP_READ_BIT));
2456 EXPECT_EQ(*userCounters, kViewportWidth * kViewportHeight * 4);
2457 glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
2458 glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);
2459
2460 glBindFramebuffer(GL_FRAMEBUFFER, 0);
2461 }
2462
2463 // Testing that binding the location value using GLES API is conflicted to the location value of the
2464 // fragment inout.
TEST_P(FramebufferFetchES31,FixedUniformLocation)2465 TEST_P(FramebufferFetchES31, FixedUniformLocation)
2466 {
2467 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2468
2469 constexpr char kVS[] = R"(#version 310 es
2470 in highp vec4 a_position;
2471
2472 void main (void)
2473 {
2474 gl_Position = a_position;
2475 })";
2476
2477 constexpr char kFS[] = R"(#version 310 es
2478 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
2479 layout(noncoherent, location = 0) inout highp vec4 o_color;
2480
2481 layout(location = 0) uniform highp vec4 u_color;
2482 void main (void)
2483 {
2484 o_color += u_color;
2485 })";
2486
2487 GLProgram program;
2488 program.makeRaster(kVS, kFS);
2489 glUseProgram(program);
2490
2491 ASSERT_GL_NO_ERROR();
2492
2493 GLFramebuffer framebuffer;
2494 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
2495 std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
2496 GLTexture colorBufferTex;
2497 glBindTexture(GL_TEXTURE_2D, colorBufferTex);
2498 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
2499 GL_UNSIGNED_BYTE, greenColor.data());
2500 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex, 0);
2501
2502 ASSERT_GL_NO_ERROR();
2503
2504 float color[4] = {1.0f, 0.0f, 0.0f, 1.0f};
2505 GLint colorLocation = glGetUniformLocation(program, "u_color");
2506 glUniform4fv(colorLocation, 1, color);
2507
2508 GLint positionLocation = glGetAttribLocation(program, "a_position");
2509 render(positionLocation, GL_TRUE);
2510
2511 ASSERT_GL_NO_ERROR();
2512
2513 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
2514
2515 glBindFramebuffer(GL_FRAMEBUFFER, 0);
2516 }
2517
2518 // Verify we can use inout with the default framebuffer
2519 // http://anglebug.com/6893
TEST_P(FramebufferFetchES31,DefaultFramebufferTest)2520 TEST_P(FramebufferFetchES31, DefaultFramebufferTest)
2521 {
2522 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2523
2524 constexpr char kVS[] = R"(#version 300 es
2525 in highp vec4 a_position;
2526
2527 void main (void)
2528 {
2529 gl_Position = a_position;
2530 })";
2531
2532 constexpr char kFS[] = R"(#version 300 es
2533 #extension GL_EXT_shader_framebuffer_fetch : require
2534 layout(location = 0) inout highp vec4 o_color;
2535
2536 uniform highp vec4 u_color;
2537 void main (void)
2538 {
2539 o_color += u_color;
2540 })";
2541
2542 GLProgram program;
2543 program.makeRaster(kVS, kFS);
2544 glUseProgram(program);
2545
2546 ASSERT_GL_NO_ERROR();
2547
2548 // Ensure that we're rendering to the default framebuffer
2549 glBindFramebuffer(GL_FRAMEBUFFER, 0);
2550
2551 // Start with a clear buffer
2552 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
2553 glClear(GL_COLOR_BUFFER_BIT);
2554
2555 GLint positionLocation = glGetAttribLocation(program, "a_position");
2556 GLint colorLocation = glGetUniformLocation(program, "u_color");
2557
2558 // Draw once with red
2559 glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
2560 render(positionLocation, GL_FALSE);
2561 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
2562 ASSERT_GL_NO_ERROR();
2563
2564 // Draw again with blue, adding it to the existing red, ending up with magenta
2565 glUniform4fv(colorLocation, 1, GLColor::blue.toNormalizedVector().data());
2566 render(positionLocation, GL_FALSE);
2567 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
2568 ASSERT_GL_NO_ERROR();
2569 }
2570
2571 // Verify we can render to the default framebuffer without fetch, then switch to a program
2572 // that does fetch.
2573 // http://anglebug.com/6893
TEST_P(FramebufferFetchES31,DefaultFramebufferMixedProgramsTest)2574 TEST_P(FramebufferFetchES31, DefaultFramebufferMixedProgramsTest)
2575 {
2576 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2577
2578 constexpr char kVS[] = R"(#version 300 es
2579 in highp vec4 a_position;
2580
2581 void main (void)
2582 {
2583 gl_Position = a_position;
2584 })";
2585
2586 constexpr char kFS[] = R"(#version 300 es
2587 layout(location = 0) out highp vec4 o_color;
2588
2589 uniform highp vec4 u_color;
2590 void main (void)
2591 {
2592 o_color = u_color;
2593 })";
2594
2595 constexpr char kFetchFS[] = R"(#version 300 es
2596 #extension GL_EXT_shader_framebuffer_fetch : require
2597 layout(location = 0) inout highp vec4 o_color;
2598
2599 uniform highp vec4 u_color;
2600 void main (void)
2601 {
2602 o_color += u_color;
2603 })";
2604
2605 // Create a program that simply writes out a color, no fetching
2606 GLProgram program;
2607 program.makeRaster(kVS, kFS);
2608 glUseProgram(program);
2609
2610 ASSERT_GL_NO_ERROR();
2611
2612 // Ensure that we're rendering to the default framebuffer
2613 glBindFramebuffer(GL_FRAMEBUFFER, 0);
2614
2615 // Start with a clear buffer
2616 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
2617 glClear(GL_COLOR_BUFFER_BIT);
2618
2619 GLint positionLocation = glGetAttribLocation(program, "a_position");
2620 GLint colorLocation = glGetUniformLocation(program, "u_color");
2621
2622 // Draw once with red
2623 glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
2624 render(positionLocation, false);
2625 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
2626 ASSERT_GL_NO_ERROR();
2627
2628 // Create another program that DOES fetch from the framebuffer
2629 GLProgram program2;
2630 program2.makeRaster(kVS, kFetchFS);
2631 glUseProgram(program2);
2632
2633 GLint positionLocation2 = glGetAttribLocation(program2, "a_position");
2634 GLint colorLocation2 = glGetUniformLocation(program2, "u_color");
2635
2636 // Draw again with blue, fetching red from the framebuffer, adding it together
2637 glUniform4fv(colorLocation2, 1, GLColor::blue.toNormalizedVector().data());
2638 render(positionLocation2, false);
2639 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
2640 ASSERT_GL_NO_ERROR();
2641
2642 // Switch back to the non-fetched framebuffer, and render green
2643 glUseProgram(program);
2644 glUniform4fv(colorLocation, 1, GLColor::green.toNormalizedVector().data());
2645 render(positionLocation, false);
2646 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
2647 ASSERT_GL_NO_ERROR();
2648 }
2649
2650 // Verify we can render to a framebuffer with fetch, then switch to another framebuffer (without
2651 // changing programs) http://anglebug.com/6893
TEST_P(FramebufferFetchES31,FramebufferMixedFetchTest)2652 TEST_P(FramebufferFetchES31, FramebufferMixedFetchTest)
2653 {
2654 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2655
2656 constexpr char kVS[] = R"(#version 300 es
2657 in highp vec4 a_position;
2658
2659 void main (void)
2660 {
2661 gl_Position = a_position;
2662 })";
2663
2664 constexpr char kFS[] = R"(#version 300 es
2665 layout(location = 0) out highp vec4 o_color;
2666
2667 uniform highp vec4 u_color;
2668 void main (void)
2669 {
2670 o_color = u_color;
2671 })";
2672
2673 constexpr char kFetchFS[] = R"(#version 300 es
2674 #extension GL_EXT_shader_framebuffer_fetch : require
2675 layout(location = 0) inout highp vec4 o_color;
2676
2677 uniform highp vec4 u_color;
2678 void main (void)
2679 {
2680 o_color += u_color;
2681 })";
2682
2683 // Create a program that simply writes out a color, no fetching
2684 GLProgram program;
2685 program.makeRaster(kVS, kFS);
2686 GLint positionLocation = glGetAttribLocation(program, "a_position");
2687 GLint colorLocation = glGetUniformLocation(program, "u_color");
2688 ASSERT_GL_NO_ERROR();
2689
2690 // Create a program that DOES fetch from the framebuffer
2691 GLProgram fetchProgram;
2692 fetchProgram.makeRaster(kVS, kFetchFS);
2693 GLint fetchPositionLocation = glGetAttribLocation(fetchProgram, "a_position");
2694 GLint fetchColorLocation = glGetUniformLocation(fetchProgram, "u_color");
2695 ASSERT_GL_NO_ERROR();
2696
2697 // Create an empty framebuffer to use without fetch
2698 GLFramebuffer framebuffer1;
2699 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
2700 std::vector<GLColor> clearColor(kViewportWidth * kViewportHeight, GLColor::transparentBlack);
2701 GLTexture colorBufferTex1;
2702 glBindTexture(GL_TEXTURE_2D, colorBufferTex1);
2703 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
2704 GL_UNSIGNED_BYTE, clearColor.data());
2705 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex1, 0);
2706 ASSERT_GL_NO_ERROR();
2707
2708 // Draw to it with green, without using fetch, overwriting any contents
2709 glUseProgram(program);
2710 glUniform4fv(colorLocation, 1, GLColor::green.toNormalizedVector().data());
2711 render(positionLocation, false);
2712 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
2713 ASSERT_GL_NO_ERROR();
2714
2715 // Create another framebuffer to use WITH fetch, and initialize it with blue
2716 GLFramebuffer framebuffer2;
2717 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2);
2718 std::vector<GLColor> blueColor(kViewportWidth * kViewportHeight, GLColor::blue);
2719 GLTexture colorBufferTex2;
2720 glBindTexture(GL_TEXTURE_2D, colorBufferTex2);
2721 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
2722 GL_UNSIGNED_BYTE, blueColor.data());
2723 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex2, 0);
2724 ASSERT_GL_NO_ERROR();
2725
2726 // Draw once with red, fetching blue from the framebuffer, adding it together
2727 glUseProgram(fetchProgram);
2728 glUniform4fv(fetchColorLocation, 1, GLColor::red.toNormalizedVector().data());
2729 render(fetchPositionLocation, false);
2730 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
2731 ASSERT_GL_NO_ERROR();
2732
2733 // Now use the same program (WITH fetch) and render to the other framebuffer that was NOT used
2734 // with fetch. This verifies the framebuffer state is appropriately updated to match the
2735 // program.
2736 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
2737 render(fetchPositionLocation, false);
2738 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
2739 ASSERT_GL_NO_ERROR();
2740 }
2741
2742 // Verify that switching between single sampled framebuffer fetch and multi sampled framebuffer
2743 // fetch works fine
TEST_P(FramebufferFetchES31,SingleSampledMultiSampledMixedTest)2744 TEST_P(FramebufferFetchES31, SingleSampledMultiSampledMixedTest)
2745 {
2746 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2747 setWhichExtension(COHERENT);
2748
2749 // Create a program that fetches from the framebuffer
2750 GLProgram fetchProgram;
2751 fetchProgram.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
2752 GLint positionLocation = glGetAttribLocation(fetchProgram, "a_position");
2753 GLint colorLocation = glGetUniformLocation(fetchProgram, "u_color");
2754 ASSERT_GL_NO_ERROR();
2755
2756 // Create two single sampled framebuffer
2757 GLRenderbuffer singleSampledRenderbuffer1;
2758 glBindRenderbuffer(GL_RENDERBUFFER, singleSampledRenderbuffer1);
2759 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kViewportWidth, kViewportHeight);
2760 GLFramebuffer singleSampledFramebuffer1;
2761 glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer1);
2762 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
2763 singleSampledRenderbuffer1);
2764
2765 GLRenderbuffer singleSampledRenderbuffer2;
2766 glBindRenderbuffer(GL_RENDERBUFFER, singleSampledRenderbuffer2);
2767 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kViewportWidth, kViewportHeight);
2768 GLFramebuffer singleSampledFramebuffer2;
2769 glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer2);
2770 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
2771 singleSampledRenderbuffer2);
2772
2773 // Create one multi sampled framebuffer
2774 GLRenderbuffer multiSampledRenderbuffer;
2775 glBindRenderbuffer(GL_RENDERBUFFER, multiSampledRenderbuffer);
2776 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, kViewportWidth, kViewportHeight);
2777 GLFramebuffer multiSampledFramebuffer;
2778 glBindFramebuffer(GL_FRAMEBUFFER, multiSampledFramebuffer);
2779 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
2780 multiSampledRenderbuffer);
2781
2782 // Create a singlesampled render buffer for blit and read
2783 GLRenderbuffer resolvedRbo;
2784 glBindRenderbuffer(GL_RENDERBUFFER, resolvedRbo);
2785 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kViewportWidth, kViewportHeight);
2786 GLFramebuffer resolvedFbo;
2787 glBindFramebuffer(GL_FRAMEBUFFER, resolvedFbo);
2788 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, resolvedRbo);
2789
2790 // Clear three Framebuffers with different colors
2791 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
2792 glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer1);
2793 glClear(GL_COLOR_BUFFER_BIT);
2794 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::black);
2795
2796 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
2797 glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer2);
2798 glClear(GL_COLOR_BUFFER_BIT);
2799 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
2800
2801 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
2802 glBindFramebuffer(GL_FRAMEBUFFER, multiSampledFramebuffer);
2803 glClear(GL_COLOR_BUFFER_BIT);
2804 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolvedFbo);
2805 glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth, kViewportHeight,
2806 GL_COLOR_BUFFER_BIT, GL_NEAREST);
2807 glBindFramebuffer(GL_READ_FRAMEBUFFER, resolvedFbo);
2808 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
2809
2810 // Bind first single sampled framebuffer, draw once with red, fetching black from the
2811 // framebuffer
2812 glUseProgram(fetchProgram);
2813 glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
2814 glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer1);
2815 render(positionLocation, false);
2816 ASSERT_GL_NO_ERROR();
2817
2818 // Bind the multi sampled framebuffer, draw once with red, fetching green from the framebuffer
2819 glBindFramebuffer(GL_FRAMEBUFFER, multiSampledFramebuffer);
2820 render(positionLocation, false);
2821 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolvedFbo);
2822 glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth, kViewportHeight,
2823 GL_COLOR_BUFFER_BIT, GL_NEAREST);
2824 glBindFramebuffer(GL_READ_FRAMEBUFFER, resolvedFbo);
2825 ASSERT_GL_NO_ERROR();
2826
2827 // Bind the single sampled framebuffer, draw once with red, fetching blue from the framebuffer
2828 glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
2829 glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer2);
2830 render(positionLocation, false);
2831 ASSERT_GL_NO_ERROR();
2832
2833 // Verify the rendering result on all three framebuffers
2834
2835 // Verify the last framebuffer being drawn: singleSampledFramebuffer2
2836 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
2837
2838 // Verify the second last framebuffer being drawn: multisampledFramebuffer
2839 glBindFramebuffer(GL_READ_FRAMEBUFFER, multiSampledFramebuffer);
2840 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolvedFbo);
2841 glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth, kViewportHeight,
2842 GL_COLOR_BUFFER_BIT, GL_NEAREST);
2843 glBindFramebuffer(GL_READ_FRAMEBUFFER, resolvedFbo);
2844 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
2845
2846 // Verify the first framebuffer being drawn: singleSampledFramebuffer1
2847 glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer1);
2848 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
2849 }
2850
2851 // Verify that calling glFramebufferFetchBarrierEXT without an open render pass is ok.
TEST_P(FramebufferFetchES31,BarrierBeforeDraw)2852 TEST_P(FramebufferFetchES31, BarrierBeforeDraw)
2853 {
2854 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch") ||
2855 !IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2856
2857 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
2858
2859 glFramebufferFetchBarrierEXT();
2860 drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
2861
2862 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2863 }
2864
2865 // Test ARM extension with gl_LastFragColorARM
TEST_P(FramebufferFetchES31,BasicLastFragData_ARM)2866 TEST_P(FramebufferFetchES31, BasicLastFragData_ARM)
2867 {
2868 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
2869 setWhichExtension(ARM);
2870
2871 GLProgram program;
2872 program.makeRaster(k100VS, getFragmentShader(GLSL100));
2873 glUseProgram(program);
2874 ASSERT_GL_NO_ERROR();
2875
2876 BasicTest(program);
2877 }
2878
2879 // Test ARM extension with multiple draw
TEST_P(FramebufferFetchES31,MultipleDraw_ARM)2880 TEST_P(FramebufferFetchES31, MultipleDraw_ARM)
2881 {
2882 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
2883 setWhichExtension(ARM);
2884
2885 GLProgram program;
2886 program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
2887 glUseProgram(program);
2888 ASSERT_GL_NO_ERROR();
2889
2890 MultipleDrawTest(program);
2891 }
2892
2893 // Testing ARM extension with the order of non-fetch program and fetch program
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetch_ARM)2894 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetch_ARM)
2895 {
2896 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
2897 setWhichExtension(ARM);
2898
2899 GLProgram programNonFetch, programFetch;
2900 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2901 programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
2902 ASSERT_GL_NO_ERROR();
2903
2904 DrawNonFetchDrawFetchTest(programNonFetch, programFetch);
2905 }
2906
2907 // Testing ARM extension with the order of fetch program and non-fetch program
TEST_P(FramebufferFetchES31,DrawFetchDrawNonFetch_ARM)2908 TEST_P(FramebufferFetchES31, DrawFetchDrawNonFetch_ARM)
2909 {
2910 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
2911 setWhichExtension(ARM);
2912
2913 GLProgram programNonFetch, programFetch;
2914 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2915 programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
2916 ASSERT_GL_NO_ERROR();
2917
2918 DrawFetchDrawNonFetchTest(programNonFetch, programFetch);
2919 }
2920
2921 // Testing ARM extension with framebuffer fetch read in combination with color attachment mask
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchInStorageBuffer_ARM)2922 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchInStorageBuffer_ARM)
2923 {
2924 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
2925 setWhichExtension(ARM);
2926
2927 GLint maxFragmentShaderStorageBlocks = 0;
2928 glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
2929 ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks == 0);
2930
2931 GLProgram programNonFetch, programFetch;
2932 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2933 programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER));
2934 ASSERT_GL_NO_ERROR();
2935
2936 DrawNonFetchDrawFetchInStorageBufferTest(programNonFetch, programFetch,
2937 StorageBufferTestPostFetchAction::Nothing);
2938 }
2939
2940 // Testing ARM extension with framebuffer fetch read in combination with color attachment mask
2941 // and clear
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchInStorageBufferThenClear_ARM)2942 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchInStorageBufferThenClear_ARM)
2943 {
2944 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
2945 setWhichExtension(ARM);
2946
2947 GLint maxFragmentShaderStorageBlocks = 0;
2948 glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
2949 ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks == 0);
2950
2951 GLProgram programNonFetch, programFetch;
2952 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2953 programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER));
2954 ASSERT_GL_NO_ERROR();
2955
2956 DrawNonFetchDrawFetchInStorageBufferTest(programNonFetch, programFetch,
2957 StorageBufferTestPostFetchAction::Clear);
2958 }
2959
2960 // Testing ARM extension with program pipeline
TEST_P(FramebufferFetchES31,ProgramPipeline_ARM)2961 TEST_P(FramebufferFetchES31, ProgramPipeline_ARM)
2962 {
2963 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
2964 setWhichExtension(ARM);
2965
2966 ProgramPipelineTest(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT),
2967 getFragmentShader(GLSL310_1ATTACHMENT));
2968 }
2969
2970 // Verify we can use the default framebuffer
2971 // http://anglebug.com/6893
TEST_P(FramebufferFetchES31,DefaultFramebufferTest_ARM)2972 TEST_P(FramebufferFetchES31, DefaultFramebufferTest_ARM)
2973 {
2974 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
2975
2976 constexpr char kVS[] = R"(#version 300 es
2977 in highp vec4 a_position;
2978
2979 void main (void)
2980 {
2981 gl_Position = a_position;
2982 })";
2983
2984 constexpr char kFS[] = R"(#version 300 es
2985 #extension GL_ARM_shader_framebuffer_fetch : require
2986 layout(location = 0) out highp vec4 o_color;
2987
2988 uniform highp vec4 u_color;
2989 void main (void)
2990 {
2991 o_color = u_color + gl_LastFragColorARM;
2992 })";
2993
2994 GLProgram program;
2995 program.makeRaster(kVS, kFS);
2996 glUseProgram(program);
2997
2998 ASSERT_GL_NO_ERROR();
2999
3000 // Ensure that we're rendering to the default framebuffer
3001 glBindFramebuffer(GL_FRAMEBUFFER, 0);
3002
3003 // Start with a clear buffer
3004 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
3005 glClear(GL_COLOR_BUFFER_BIT);
3006
3007 GLint positionLocation = glGetAttribLocation(program, "a_position");
3008 GLint colorLocation = glGetUniformLocation(program, "u_color");
3009
3010 // Draw once with red
3011 glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
3012 render(positionLocation, GL_FALSE);
3013 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
3014 ASSERT_GL_NO_ERROR();
3015
3016 // Draw again with blue, adding it to the existing red, ending up with magenta
3017 glUniform4fv(colorLocation, 1, GLColor::blue.toNormalizedVector().data());
3018 render(positionLocation, GL_FALSE);
3019 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
3020 ASSERT_GL_NO_ERROR();
3021 }
3022
3023 // Verify we can redeclare gl_LastFragColorARM with a new precision
3024 // http://anglebug.com/6893
TEST_P(FramebufferFetchES31,NondefaultPrecisionTest_ARM)3025 TEST_P(FramebufferFetchES31, NondefaultPrecisionTest_ARM)
3026 {
3027 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3028
3029 constexpr char kVS[] = R"(#version 300 es
3030 in highp vec4 a_position;
3031
3032 void main (void)
3033 {
3034 gl_Position = a_position;
3035 })";
3036
3037 constexpr char kFS[] = R"(#version 300 es
3038 #extension GL_ARM_shader_framebuffer_fetch : require
3039 highp vec4 gl_LastFragColorARM;
3040 layout(location = 0) out highp vec4 o_color;
3041
3042 uniform highp vec4 u_color;
3043 void main (void)
3044 {
3045 o_color = u_color + gl_LastFragColorARM;
3046 })";
3047
3048 GLProgram program;
3049 program.makeRaster(kVS, kFS);
3050 glUseProgram(program);
3051
3052 ASSERT_GL_NO_ERROR();
3053
3054 // Ensure that we're rendering to the default framebuffer
3055 glBindFramebuffer(GL_FRAMEBUFFER, 0);
3056
3057 // Start with a clear buffer
3058 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
3059 glClear(GL_COLOR_BUFFER_BIT);
3060
3061 GLint positionLocation = glGetAttribLocation(program, "a_position");
3062 GLint colorLocation = glGetUniformLocation(program, "u_color");
3063
3064 // Draw once with red
3065 glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
3066 render(positionLocation, GL_FALSE);
3067 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
3068 ASSERT_GL_NO_ERROR();
3069
3070 // Draw again with blue, adding it to the existing red, ending up with magenta
3071 glUniform4fv(colorLocation, 1, GLColor::blue.toNormalizedVector().data());
3072 render(positionLocation, GL_FALSE);
3073 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
3074 ASSERT_GL_NO_ERROR();
3075 }
3076
3077 // Verify we can render to the default framebuffer without fetch, then switch to a program
3078 // that does fetch.
3079 // http://anglebug.com/6893
TEST_P(FramebufferFetchES31,DefaultFramebufferMixedProgramsTest_ARM)3080 TEST_P(FramebufferFetchES31, DefaultFramebufferMixedProgramsTest_ARM)
3081 {
3082 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3083
3084 constexpr char kVS[] = R"(#version 300 es
3085 in highp vec4 a_position;
3086
3087 void main (void)
3088 {
3089 gl_Position = a_position;
3090 })";
3091
3092 constexpr char kFS[] = R"(#version 300 es
3093 layout(location = 0) out highp vec4 o_color;
3094
3095 uniform highp vec4 u_color;
3096 void main (void)
3097 {
3098 o_color = u_color;
3099 })";
3100
3101 constexpr char kFetchFS[] = R"(#version 300 es
3102 #extension GL_ARM_shader_framebuffer_fetch : require
3103 layout(location = 0) out highp vec4 o_color;
3104
3105 uniform highp vec4 u_color;
3106 void main (void)
3107 {
3108 o_color = u_color + gl_LastFragColorARM;
3109 })";
3110
3111 // Create a program that simply writes out a color, no fetching
3112 GLProgram program;
3113 program.makeRaster(kVS, kFS);
3114 glUseProgram(program);
3115
3116 ASSERT_GL_NO_ERROR();
3117
3118 // Ensure that we're rendering to the default framebuffer
3119 glBindFramebuffer(GL_FRAMEBUFFER, 0);
3120
3121 // Start with a clear buffer
3122 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
3123 glClear(GL_COLOR_BUFFER_BIT);
3124
3125 GLint positionLocation = glGetAttribLocation(program, "a_position");
3126 GLint colorLocation = glGetUniformLocation(program, "u_color");
3127
3128 // Draw once with red
3129 glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
3130 render(positionLocation, false);
3131 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
3132 ASSERT_GL_NO_ERROR();
3133
3134 // Create another program that DOES fetch from the framebuffer
3135 GLProgram program2;
3136 program2.makeRaster(kVS, kFetchFS);
3137 glUseProgram(program2);
3138
3139 GLint positionLocation2 = glGetAttribLocation(program2, "a_position");
3140 GLint colorLocation2 = glGetUniformLocation(program2, "u_color");
3141
3142 // Draw again with blue, fetching red from the framebuffer, adding it together
3143 glUniform4fv(colorLocation2, 1, GLColor::blue.toNormalizedVector().data());
3144 render(positionLocation2, false);
3145 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
3146 ASSERT_GL_NO_ERROR();
3147
3148 // Switch back to the non-fetched framebuffer, and render green
3149 glUseProgram(program);
3150 glUniform4fv(colorLocation, 1, GLColor::green.toNormalizedVector().data());
3151 render(positionLocation, false);
3152 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
3153 ASSERT_GL_NO_ERROR();
3154 }
3155
3156 // Verify we can render to a framebuffer with fetch, then switch to another framebuffer (without
3157 // changing programs) http://anglebug.com/6893
TEST_P(FramebufferFetchES31,FramebufferMixedFetchTest_ARM)3158 TEST_P(FramebufferFetchES31, FramebufferMixedFetchTest_ARM)
3159 {
3160 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3161
3162 constexpr char kVS[] = R"(#version 300 es
3163 in highp vec4 a_position;
3164
3165 void main (void)
3166 {
3167 gl_Position = a_position;
3168 })";
3169
3170 constexpr char kFS[] = R"(#version 300 es
3171 layout(location = 0) out highp vec4 o_color;
3172
3173 uniform highp vec4 u_color;
3174 void main (void)
3175 {
3176 o_color = u_color;
3177 })";
3178
3179 constexpr char kFetchFS[] = R"(#version 300 es
3180 #extension GL_ARM_shader_framebuffer_fetch : require
3181 layout(location = 0) out highp vec4 o_color;
3182
3183 uniform highp vec4 u_color;
3184 void main (void)
3185 {
3186 o_color = u_color + gl_LastFragColorARM;
3187 })";
3188
3189 // Create a program that simply writes out a color, no fetching
3190 GLProgram program;
3191 program.makeRaster(kVS, kFS);
3192 GLint positionLocation = glGetAttribLocation(program, "a_position");
3193 GLint colorLocation = glGetUniformLocation(program, "u_color");
3194 ASSERT_GL_NO_ERROR();
3195
3196 // Create a program that DOES fetch from the framebuffer
3197 GLProgram fetchProgram;
3198 fetchProgram.makeRaster(kVS, kFetchFS);
3199 GLint fetchPositionLocation = glGetAttribLocation(fetchProgram, "a_position");
3200 GLint fetchColorLocation = glGetUniformLocation(fetchProgram, "u_color");
3201 ASSERT_GL_NO_ERROR();
3202
3203 // Create an empty framebuffer to use without fetch
3204 GLFramebuffer framebuffer1;
3205 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
3206 std::vector<GLColor> clearColor(kViewportWidth * kViewportHeight, GLColor::transparentBlack);
3207 GLTexture colorBufferTex1;
3208 glBindTexture(GL_TEXTURE_2D, colorBufferTex1);
3209 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
3210 GL_UNSIGNED_BYTE, clearColor.data());
3211 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex1, 0);
3212 ASSERT_GL_NO_ERROR();
3213
3214 // Draw to it with green, without using fetch, overwriting any contents
3215 glUseProgram(program);
3216 glUniform4fv(colorLocation, 1, GLColor::green.toNormalizedVector().data());
3217 render(positionLocation, false);
3218 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
3219 ASSERT_GL_NO_ERROR();
3220
3221 // Create another framebuffer to use WITH fetch, and initialize it with blue
3222 GLFramebuffer framebuffer2;
3223 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2);
3224 std::vector<GLColor> blueColor(kViewportWidth * kViewportHeight, GLColor::blue);
3225 GLTexture colorBufferTex2;
3226 glBindTexture(GL_TEXTURE_2D, colorBufferTex2);
3227 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
3228 GL_UNSIGNED_BYTE, blueColor.data());
3229 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex2, 0);
3230 ASSERT_GL_NO_ERROR();
3231
3232 // Draw once with red, fetching blue from the framebuffer, adding it together
3233 glUseProgram(fetchProgram);
3234 glUniform4fv(fetchColorLocation, 1, GLColor::red.toNormalizedVector().data());
3235 render(fetchPositionLocation, false);
3236 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
3237 ASSERT_GL_NO_ERROR();
3238
3239 // Now use the same program (WITH fetch) and render to the other framebuffer that was NOT used
3240 // with fetch. This verifies the framebuffer state is appropriately updated to match the
3241 // program.
3242 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
3243 render(fetchPositionLocation, false);
3244 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
3245 ASSERT_GL_NO_ERROR();
3246 }
3247
3248 // Verify that switching between single sampled framebuffer fetch and multi sampled framebuffer
3249 // fetch works fine
TEST_P(FramebufferFetchES31,SingleSampledMultiSampledMixedTest_ARM)3250 TEST_P(FramebufferFetchES31, SingleSampledMultiSampledMixedTest_ARM)
3251 {
3252 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3253 setWhichExtension(ARM);
3254
3255 // Create a program that fetches from the framebuffer
3256 GLProgram fetchProgram;
3257 fetchProgram.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
3258 GLint positionLocation = glGetAttribLocation(fetchProgram, "a_position");
3259 GLint colorLocation = glGetUniformLocation(fetchProgram, "u_color");
3260 ASSERT_GL_NO_ERROR();
3261
3262 // Create two single sampled framebuffer
3263 GLRenderbuffer singleSampledRenderbuffer1;
3264 glBindRenderbuffer(GL_RENDERBUFFER, singleSampledRenderbuffer1);
3265 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kViewportWidth, kViewportHeight);
3266 GLFramebuffer singleSampledFramebuffer1;
3267 glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer1);
3268 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
3269 singleSampledRenderbuffer1);
3270
3271 GLRenderbuffer singleSampledRenderbuffer2;
3272 glBindRenderbuffer(GL_RENDERBUFFER, singleSampledRenderbuffer2);
3273 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kViewportWidth, kViewportHeight);
3274 GLFramebuffer singleSampledFramebuffer2;
3275 glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer2);
3276 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
3277 singleSampledRenderbuffer2);
3278
3279 // Create one multi sampled framebuffer
3280 GLRenderbuffer multiSampledRenderbuffer;
3281 glBindRenderbuffer(GL_RENDERBUFFER, multiSampledRenderbuffer);
3282 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, kViewportWidth, kViewportHeight);
3283 GLFramebuffer multiSampledFramebuffer;
3284 glBindFramebuffer(GL_FRAMEBUFFER, multiSampledFramebuffer);
3285 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
3286 multiSampledRenderbuffer);
3287
3288 // Create a singlesampled render buffer for blit and read
3289 GLRenderbuffer resolvedRbo;
3290 glBindRenderbuffer(GL_RENDERBUFFER, resolvedRbo);
3291 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kViewportWidth, kViewportHeight);
3292 GLFramebuffer resolvedFbo;
3293 glBindFramebuffer(GL_FRAMEBUFFER, resolvedFbo);
3294 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, resolvedRbo);
3295
3296 // Clear three Framebuffers with different colors
3297 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
3298 glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer1);
3299 glClear(GL_COLOR_BUFFER_BIT);
3300 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::black);
3301
3302 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
3303 glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer2);
3304 glClear(GL_COLOR_BUFFER_BIT);
3305 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
3306
3307 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
3308 glBindFramebuffer(GL_FRAMEBUFFER, multiSampledFramebuffer);
3309 glClear(GL_COLOR_BUFFER_BIT);
3310 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolvedFbo);
3311 glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth, kViewportHeight,
3312 GL_COLOR_BUFFER_BIT, GL_NEAREST);
3313 glBindFramebuffer(GL_READ_FRAMEBUFFER, resolvedFbo);
3314 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
3315
3316 // Bind first single sampled framebuffer, draw once with red, fetching black from the
3317 // framebuffer
3318 glUseProgram(fetchProgram);
3319 glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
3320 glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer1);
3321 render(positionLocation, false);
3322 ASSERT_GL_NO_ERROR();
3323
3324 // Bind the multi sampled framebuffer, draw once with red, fetching green from the framebuffer
3325 glBindFramebuffer(GL_FRAMEBUFFER, multiSampledFramebuffer);
3326 render(positionLocation, false);
3327 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolvedFbo);
3328 glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth, kViewportHeight,
3329 GL_COLOR_BUFFER_BIT, GL_NEAREST);
3330 glBindFramebuffer(GL_READ_FRAMEBUFFER, resolvedFbo);
3331 ASSERT_GL_NO_ERROR();
3332
3333 // Bind the single sampled framebuffer, draw once with red, fetching blue from the framebuffer
3334 glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
3335 glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer2);
3336 render(positionLocation, false);
3337 ASSERT_GL_NO_ERROR();
3338
3339 // Verify the rendering result on all three framebuffers
3340
3341 // Verify the last framebuffer being drawn: singleSampledFramebuffer2
3342 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
3343
3344 // Verify the second last framebuffer being drawn: multisampledFramebuffer
3345 glBindFramebuffer(GL_READ_FRAMEBUFFER, multiSampledFramebuffer);
3346 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolvedFbo);
3347 glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth, kViewportHeight,
3348 GL_COLOR_BUFFER_BIT, GL_NEAREST);
3349 glBindFramebuffer(GL_READ_FRAMEBUFFER, resolvedFbo);
3350 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
3351
3352 // Verify the first framebuffer being drawn: singleSampledFramebuffer1
3353 glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer1);
3354 EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
3355 }
3356
3357 // Test ARM extension with new tokens
TEST_P(FramebufferFetchES31,BasicTokenUsage_ARM)3358 TEST_P(FramebufferFetchES31, BasicTokenUsage_ARM)
3359 {
3360 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3361
3362 // GL_FETCH_PER_SAMPLE_ARM can be set and queried
3363 GLboolean isFetchPerSampleEnabledBool = false;
3364 GLint isFetchPerSampleEnabledInt = -1;
3365 GLfloat isFetchPerSampleEnabledFloat = -1.0f;
3366
3367 // Set GL_FETCH_PER_SAMPLE_ARM true
3368 glEnable(GL_FETCH_PER_SAMPLE_ARM);
3369 EXPECT_GL_TRUE(glIsEnabled(GL_FETCH_PER_SAMPLE_ARM));
3370
3371 // Ensure it returns true
3372 glGetBooleanv(GL_FETCH_PER_SAMPLE_ARM, &isFetchPerSampleEnabledBool);
3373 EXPECT_GL_TRUE(isFetchPerSampleEnabledBool);
3374 glGetIntegerv(GL_FETCH_PER_SAMPLE_ARM, &isFetchPerSampleEnabledInt);
3375 ASSERT_EQ(isFetchPerSampleEnabledInt, 1);
3376 glGetFloatv(GL_FETCH_PER_SAMPLE_ARM, &isFetchPerSampleEnabledFloat);
3377 ASSERT_EQ(isFetchPerSampleEnabledFloat, 1.0);
3378
3379 // Set GL_FETCH_PER_SAMPLE_ARM false
3380 glDisable(GL_FETCH_PER_SAMPLE_ARM);
3381 EXPECT_GL_FALSE(glIsEnabled(GL_FETCH_PER_SAMPLE_ARM));
3382
3383 // Ensure it returns false
3384 glGetBooleanv(GL_FETCH_PER_SAMPLE_ARM, &isFetchPerSampleEnabledBool);
3385 EXPECT_GL_FALSE(isFetchPerSampleEnabledBool);
3386 glGetIntegerv(GL_FETCH_PER_SAMPLE_ARM, &isFetchPerSampleEnabledInt);
3387 ASSERT_EQ(isFetchPerSampleEnabledInt, 0);
3388 glGetFloatv(GL_FETCH_PER_SAMPLE_ARM, &isFetchPerSampleEnabledFloat);
3389 ASSERT_EQ(isFetchPerSampleEnabledFloat, 0.0);
3390
3391 ASSERT_GL_NO_ERROR();
3392
3393 // GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM can only be queried
3394 GLboolean isFragmentShaderFramebufferFetchMrtBool = false;
3395 GLint isFragmentShaderFramebufferFetchMrtInt = -1;
3396 GLfloat isFragmentShaderFramebufferFetchMrtFloat = -1.0f;
3397
3398 // Try to set it, ensure we can't
3399 glEnable(GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM);
3400 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3401 glDisable(GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM);
3402 EXPECT_GL_ERROR(GL_INVALID_ENUM);
3403
3404 // Ensure we can't query its state with isEnabled
3405 // Commented out due to http://anglebug.com/8025
3406 // glIsEnabled(GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM);
3407 // EXPECT_GL_ERROR(GL_INVALID_ENUM);
3408
3409 // Ensure GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM returns false
3410 glGetBooleanv(GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM,
3411 &isFragmentShaderFramebufferFetchMrtBool);
3412 EXPECT_GL_FALSE(isFragmentShaderFramebufferFetchMrtBool);
3413 glGetIntegerv(GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM,
3414 &isFragmentShaderFramebufferFetchMrtInt);
3415 ASSERT_EQ(isFragmentShaderFramebufferFetchMrtInt, 0);
3416 glGetFloatv(GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM,
3417 &isFragmentShaderFramebufferFetchMrtFloat);
3418 ASSERT_EQ(isFragmentShaderFramebufferFetchMrtFloat, 0.0);
3419
3420 ASSERT_GL_NO_ERROR();
3421 }
3422
3423 // Test using both extensions simultaneously with gl_LastFragData and gl_LastFragColorARM
TEST_P(FramebufferFetchES31,BasicLastFragData_Both)3424 TEST_P(FramebufferFetchES31, BasicLastFragData_Both)
3425 {
3426 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3427 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
3428 setWhichExtension(BOTH);
3429
3430 GLProgram program;
3431 program.makeRaster(k100VS, getFragmentShader(GLSL100));
3432 glUseProgram(program);
3433 ASSERT_GL_NO_ERROR();
3434
3435 BasicTest(program);
3436 }
3437
3438 // Test using both extentions simultaneously with multiple draw
TEST_P(FramebufferFetchES31,MultipleDraw_Both)3439 TEST_P(FramebufferFetchES31, MultipleDraw_Both)
3440 {
3441 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3442 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
3443 setWhichExtension(BOTH);
3444
3445 GLProgram program;
3446 program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
3447 glUseProgram(program);
3448 ASSERT_GL_NO_ERROR();
3449
3450 MultipleDrawTest(program);
3451 }
3452
3453 // Testing using both extentions simultaneously with the order of non-fetch program and fetch
3454 // program
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetch_Both)3455 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetch_Both)
3456 {
3457 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3458 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
3459 setWhichExtension(BOTH);
3460
3461 GLProgram programNonFetch, programFetch;
3462 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
3463 programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
3464 ASSERT_GL_NO_ERROR();
3465
3466 DrawNonFetchDrawFetchTest(programNonFetch, programFetch);
3467 }
3468
3469 // Testing using both extentions simultaneously with the order of fetch program and non-fetch
3470 // program
TEST_P(FramebufferFetchES31,DrawFetchDrawNonFetch_Both)3471 TEST_P(FramebufferFetchES31, DrawFetchDrawNonFetch_Both)
3472 {
3473 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3474 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
3475 setWhichExtension(BOTH);
3476
3477 GLProgram programNonFetch, programFetch;
3478 programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
3479 programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
3480 ASSERT_GL_NO_ERROR();
3481
3482 DrawFetchDrawNonFetchTest(programNonFetch, programFetch);
3483 }
3484
3485 // Testing using both extentions simultaneously with multiple render target, using gl_FragData with
3486 // constant indices
TEST_P(FramebufferFetchES31,MultipleRenderTarget_Both_FragData)3487 TEST_P(FramebufferFetchES31, MultipleRenderTarget_Both_FragData)
3488 {
3489 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3490 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
3491 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_draw_buffers"));
3492 setWhichExtension(BOTH);
3493
3494 GLProgram program;
3495 program.makeRaster(k100VS, getFragmentShader(GLSL100_4ATTACHMENT));
3496 glUseProgram(program);
3497 ASSERT_GL_NO_ERROR();
3498
3499 MultipleRenderTargetTest(program, GLSL100_4ATTACHMENT);
3500 }
3501
3502 // Testing using both extentions simultaneously with multiple render target, using gl_FragData with
3503 // complex expressions
TEST_P(FramebufferFetchES31,MultipleRenderTarget_Both_FragData_Complex)3504 TEST_P(FramebufferFetchES31, MultipleRenderTarget_Both_FragData_Complex)
3505 {
3506 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3507 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
3508 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_draw_buffers"));
3509 setWhichExtension(BOTH);
3510
3511 GLProgram program;
3512 program.makeRaster(k100VS, getFragmentShader(GLSL100_COMPLEX));
3513 glUseProgram(program);
3514 ASSERT_GL_NO_ERROR();
3515
3516 MultipleRenderTargetTest(program, GLSL100_COMPLEX);
3517 }
3518
3519 // Testing using both extentions simultaneously with multiple render target, using inouts with
3520 // complex expressions
TEST_P(FramebufferFetchES31,MultipleRenderTarget_Both_Complex)3521 TEST_P(FramebufferFetchES31, MultipleRenderTarget_Both_Complex)
3522 {
3523 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3524 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
3525 setWhichExtension(BOTH);
3526
3527 GLProgram program;
3528 program.makeRaster(k310VS, getFragmentShader(GLSL310_COMPLEX));
3529 glUseProgram(program);
3530 ASSERT_GL_NO_ERROR();
3531
3532 MultipleRenderTargetTest(program, GLSL310_COMPLEX);
3533 }
3534
3535 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FramebufferFetchES31);
3536 ANGLE_INSTANTIATE_TEST_ES31_AND(FramebufferFetchES31,
3537 ES31_VULKAN().disable(Feature::SupportsSPIRV14));
3538 } // namespace angle
3539