• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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