xref: /aosp_15_r20/external/angle/src/tests/gl_tests/FramebufferFetchTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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         setConfigStencilBits(8);
696 
697         mCoherentExtension = false;
698         mARMExtension      = false;
699         mBothExtensions    = false;
700     }
701 
702     enum WhichExtension
703     {
704         COHERENT,
705         NON_COHERENT,
706         ARM,
707         BOTH,
708     };
setWhichExtension(WhichExtension whichExtension)709     void setWhichExtension(WhichExtension whichExtension)
710     {
711         mCoherentExtension = whichExtension != NON_COHERENT;
712         mARMExtension      = whichExtension == ARM;
713         mBothExtensions    = whichExtension == BOTH;
714     }
715 
716     enum WhichFragmentShader
717     {
718         GLSL100,
719         GLSL310_NO_FETCH_1ATTACHMENT,
720         GLSL310_1ATTACHMENT,
721         GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER,
722         GLSL100_4ATTACHMENT,
723         GLSL100_COMPLEX,
724         GLSL310_4ATTACHMENT,
725         GLSL310_4ATTACHMENT_ARRAY,
726         GLSL310_4ATTACHMENT_DIFFERENT1,
727         GLSL310_4ATTACHMENT_DIFFERENT2,
728         GLSL310_4ATTACHMENT_DIFFERENT3,
729         GLSL310_4ATTACHMENT_DIFFERENT4,
730         GLSL310_COMPLEX,
731     };
getFragmentShader(WhichFragmentShader whichFragmentShader)732     const char *getFragmentShader(WhichFragmentShader whichFragmentShader)
733     {
734         if (mBothExtensions)
735         {
736             switch (whichFragmentShader)
737             {
738                 case GLSL100:
739                     return k100BothFS;
740                 case GLSL310_NO_FETCH_1ATTACHMENT:
741                     return k310NoFetch1AttachmentFS;
742                 case GLSL310_1ATTACHMENT:
743                     return k310Both1AttachmentFS;
744                 case GLSL100_4ATTACHMENT:
745                     return k100Both4AttachmentFS;
746                 case GLSL100_COMPLEX:
747                     return k100BothComplexFS;
748                 case GLSL310_COMPLEX:
749                     return k310BothComplexFS;
750                 default:
751                     UNREACHABLE();
752                     return nullptr;
753             }
754         }
755         else if (mARMExtension)
756         {
757             // gl_LastFragColorARM cannot support multiple attachments
758             switch (whichFragmentShader)
759             {
760                 case GLSL100:
761                     return k100ARMFS;
762                 case GLSL310_NO_FETCH_1ATTACHMENT:
763                     return k310NoFetch1AttachmentFS;
764                 case GLSL310_1ATTACHMENT:
765                     return k310ARM1AttachmentFS;
766                 case GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER:
767                     return k310ARMStorageBuffer;
768                 default:
769                     UNREACHABLE();
770                     return nullptr;
771             }
772         }
773         else if (mCoherentExtension)
774         {
775             switch (whichFragmentShader)
776             {
777                 case GLSL100:
778                     return k100CoherentFS;
779                 case GLSL310_NO_FETCH_1ATTACHMENT:
780                     return k310NoFetch1AttachmentFS;
781                 case GLSL310_1ATTACHMENT:
782                     return k310Coherent1AttachmentFS;
783                 case GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER:
784                     return k310CoherentStorageBuffer;
785                 case GLSL100_4ATTACHMENT:
786                     return k100Coherent4AttachmentFS;
787                 case GLSL310_4ATTACHMENT:
788                     return k310Coherent4AttachmentFS;
789                 case GLSL310_4ATTACHMENT_ARRAY:
790                     return k310Coherent4AttachmentArrayFS;
791                 case GLSL310_4ATTACHMENT_DIFFERENT1:
792                     return k310CoherentDifferent4AttachmentFS1;
793                 case GLSL310_4ATTACHMENT_DIFFERENT2:
794                     return k310CoherentDifferent4AttachmentFS2;
795                 case GLSL310_4ATTACHMENT_DIFFERENT3:
796                     return k310CoherentDifferent4AttachmentFS3;
797                 case GLSL310_4ATTACHMENT_DIFFERENT4:
798                     return k310CoherentDifferent4AttachmentFS4;
799                 case GLSL100_COMPLEX:
800                     return k100CoherentComplexFS;
801                 case GLSL310_COMPLEX:
802                     return k310CoherentComplexFS;
803                 default:
804                     UNREACHABLE();
805                     return nullptr;
806             }
807         }
808         else
809         {
810             switch (whichFragmentShader)
811             {
812                 case GLSL100:
813                     return k100NonCoherentFS;
814                 case GLSL310_NO_FETCH_1ATTACHMENT:
815                     return k310NoFetch1AttachmentFS;
816                 case GLSL310_1ATTACHMENT:
817                     return k310NonCoherent1AttachmentFS;
818                 case GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER:
819                     return k310NonCoherentStorageBuffer;
820                 case GLSL100_4ATTACHMENT:
821                     return k100NonCoherent4AttachmentFS;
822                 case GLSL310_4ATTACHMENT:
823                     return k310NonCoherent4AttachmentFS;
824                 case GLSL310_4ATTACHMENT_ARRAY:
825                     return k310NonCoherent4AttachmentArrayFS;
826                 case GLSL310_4ATTACHMENT_DIFFERENT1:
827                     return k310NonCoherentDifferent4AttachmentFS1;
828                 case GLSL310_4ATTACHMENT_DIFFERENT2:
829                     return k310NonCoherentDifferent4AttachmentFS2;
830                 case GLSL310_4ATTACHMENT_DIFFERENT3:
831                     return k310NonCoherentDifferent4AttachmentFS3;
832                 case GLSL310_4ATTACHMENT_DIFFERENT4:
833                     return k310NonCoherentDifferent4AttachmentFS4;
834                 case GLSL100_COMPLEX:
835                     return k100NonCoherentComplexFS;
836                 case GLSL310_COMPLEX:
837                     return k310NonCoherentComplexFS;
838                 default:
839                     UNREACHABLE();
840                     return nullptr;
841             }
842         }
843     }
844 
render(GLuint coordLoc,GLboolean needsFramebufferFetchBarrier)845     void render(GLuint coordLoc, GLboolean needsFramebufferFetchBarrier)
846     {
847         const GLfloat coords[] = {
848             -1.0f, -1.0f, +1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f,
849         };
850 
851         const GLushort indices[] = {
852             0, 1, 2, 2, 3, 0,
853         };
854 
855         glViewport(0, 0, kViewportWidth, kViewportHeight);
856 
857         GLBuffer coordinatesBuffer;
858         GLBuffer elementsBuffer;
859 
860         glBindBuffer(GL_ARRAY_BUFFER, coordinatesBuffer);
861         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW);
862         glEnableVertexAttribArray(coordLoc);
863         glVertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
864 
865         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementsBuffer);
866         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)sizeof(indices), &indices[0],
867                      GL_STATIC_DRAW);
868 
869         if (needsFramebufferFetchBarrier)
870         {
871             glFramebufferFetchBarrierEXT();
872         }
873 
874         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
875 
876         ASSERT_GL_NO_ERROR();
877     }
878 
BasicTest(GLProgram & program)879     void BasicTest(GLProgram &program)
880     {
881         GLFramebuffer framebuffer;
882         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
883         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
884         GLTexture colorBufferTex;
885         glBindTexture(GL_TEXTURE_2D, colorBufferTex);
886         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
887                      GL_UNSIGNED_BYTE, greenColor.data());
888         glBindTexture(GL_TEXTURE_2D, 0);
889         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
890                                0);
891 
892         ASSERT_GL_NO_ERROR();
893 
894         float color[4]      = {1.0f, 0.0f, 0.0f, 1.0f};
895         GLint colorLocation = glGetUniformLocation(program, "u_color");
896         glUniform4fv(colorLocation, 1, color);
897 
898         GLint positionLocation = glGetAttribLocation(program, "a_position");
899         render(positionLocation, !mCoherentExtension);
900 
901         ASSERT_GL_NO_ERROR();
902 
903         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
904 
905         glBindFramebuffer(GL_FRAMEBUFFER, 0);
906     }
907 
MultipleRenderTargetTest(GLProgram & program,WhichFragmentShader whichFragmentShader)908     void MultipleRenderTargetTest(GLProgram &program, WhichFragmentShader whichFragmentShader)
909     {
910         GLFramebuffer framebuffer;
911         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
912         std::vector<GLColor> color0(kViewportWidth * kViewportHeight, GLColor::cyan);
913         std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
914         std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
915         std::vector<GLColor> color3(kViewportWidth * kViewportHeight, GLColor::black);
916         GLTexture colorBufferTex[kMaxColorBuffer];
917         GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
918                                                     GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
919         glBindTexture(GL_TEXTURE_2D, colorBufferTex[0]);
920         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
921                      GL_UNSIGNED_BYTE, color0.data());
922         glBindTexture(GL_TEXTURE_2D, colorBufferTex[1]);
923         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
924                      GL_UNSIGNED_BYTE, color1.data());
925         glBindTexture(GL_TEXTURE_2D, colorBufferTex[2]);
926         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
927                      GL_UNSIGNED_BYTE, color2.data());
928         glBindTexture(GL_TEXTURE_2D, colorBufferTex[3]);
929         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
930                      GL_UNSIGNED_BYTE, color3.data());
931         glBindTexture(GL_TEXTURE_2D, 0);
932         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
933         {
934             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
935                                    colorBufferTex[i], 0);
936         }
937         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
938 
939         ASSERT_GL_NO_ERROR();
940 
941         float color[4]      = {1.0f, 0.0f, 0.0f, 1.0f};
942         GLint colorLocation = glGetUniformLocation(program, "u_color");
943         glUniform4fv(colorLocation, 1, color);
944 
945         GLint positionLocation = glGetAttribLocation(program, "a_position");
946         render(positionLocation, !mCoherentExtension);
947 
948         ASSERT_GL_NO_ERROR();
949 
950         // All fragment shaders add the input color with the uniform.  Except the COMPLEX shaders
951         // which initialize attachments 0 and 2, or 1 and 3 with the uniform only (and don't use
952         // input attachments for these indices).
953         GLColor expect0 = GLColor::white;
954         GLColor expect1 = GLColor::yellow;
955         GLColor expect2 = GLColor::magenta;
956         GLColor expect3 = GLColor::red;
957         switch (whichFragmentShader)
958         {
959             case GLSL100_COMPLEX:
960             case GLSL310_COMPLEX:
961                 if (mBothExtensions)
962                 {
963                     expect1 = GLColor::red;
964                     expect3 = GLColor::red;
965                 }
966                 else
967                 {
968                     expect0 = GLColor::red;
969                     expect2 = GLColor::red;
970                 }
971                 break;
972             default:
973                 break;
974         }
975 
976         glReadBuffer(colorAttachments[0]);
977         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, expect0);
978         glReadBuffer(colorAttachments[1]);
979         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, expect1);
980         glReadBuffer(colorAttachments[2]);
981         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, expect2);
982         glReadBuffer(colorAttachments[3]);
983         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, expect3);
984 
985         glBindFramebuffer(GL_FRAMEBUFFER, 0);
986     }
987 
MultipleRenderTargetArrayTest(GLProgram & program)988     void MultipleRenderTargetArrayTest(GLProgram &program)
989     {
990         GLFramebuffer framebuffer;
991         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
992         std::vector<GLColor> color0(kViewportWidth * kViewportHeight, GLColor::black);
993         std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
994         std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
995         std::vector<GLColor> color3(kViewportWidth * kViewportHeight, GLColor::cyan);
996         GLTexture colorBufferTex[kMaxColorBuffer];
997         GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
998                                                     GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
999         glBindTexture(GL_TEXTURE_2D, colorBufferTex[0]);
1000         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1001                      GL_UNSIGNED_BYTE, color0.data());
1002         glBindTexture(GL_TEXTURE_2D, colorBufferTex[1]);
1003         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1004                      GL_UNSIGNED_BYTE, color1.data());
1005         glBindTexture(GL_TEXTURE_2D, colorBufferTex[2]);
1006         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1007                      GL_UNSIGNED_BYTE, color2.data());
1008         glBindTexture(GL_TEXTURE_2D, colorBufferTex[3]);
1009         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1010                      GL_UNSIGNED_BYTE, color3.data());
1011         glBindTexture(GL_TEXTURE_2D, 0);
1012         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
1013         {
1014             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
1015                                    colorBufferTex[i], 0);
1016         }
1017         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
1018 
1019         ASSERT_GL_NO_ERROR();
1020 
1021         float color[4]      = {1.0f, 0.0f, 0.0f, 1.0f};
1022         GLint colorLocation = glGetUniformLocation(program, "u_color");
1023         glUniform4fv(colorLocation, 1, color);
1024 
1025         GLint positionLocation = glGetAttribLocation(program, "a_position");
1026         render(positionLocation, !mCoherentExtension);
1027 
1028         ASSERT_GL_NO_ERROR();
1029 
1030         glReadBuffer(colorAttachments[0]);
1031         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1032         glReadBuffer(colorAttachments[1]);
1033         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1034         glReadBuffer(colorAttachments[2]);
1035         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
1036         glReadBuffer(colorAttachments[3]);
1037         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::white);
1038 
1039         glBindFramebuffer(GL_FRAMEBUFFER, 0);
1040     }
1041 
MultipleDrawTest(GLProgram & program)1042     void MultipleDrawTest(GLProgram &program)
1043     {
1044         GLFramebuffer framebuffer;
1045         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1046         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
1047         GLTexture colorBufferTex;
1048         glBindTexture(GL_TEXTURE_2D, colorBufferTex);
1049         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1050                      GL_UNSIGNED_BYTE, greenColor.data());
1051         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
1052                                0);
1053 
1054         ASSERT_GL_NO_ERROR();
1055 
1056         float color1[4]     = {1.0f, 0.0f, 0.0f, 1.0f};
1057         GLint colorLocation = glGetUniformLocation(program, "u_color");
1058         glUniform4fv(colorLocation, 1, color1);
1059 
1060         GLint positionLocation = glGetAttribLocation(program, "a_position");
1061         render(positionLocation, !mCoherentExtension);
1062 
1063         float color2[4] = {0.0f, 0.0f, 1.0f, 1.0f};
1064         glUniform4fv(colorLocation, 1, color2);
1065 
1066         render(positionLocation, !mCoherentExtension);
1067 
1068         ASSERT_GL_NO_ERROR();
1069 
1070         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::white);
1071 
1072         glBindFramebuffer(GL_FRAMEBUFFER, 0);
1073     }
1074 
DrawNonFetchDrawFetchTest(GLProgram & programNonFetch,GLProgram & programFetch)1075     void DrawNonFetchDrawFetchTest(GLProgram &programNonFetch, GLProgram &programFetch)
1076     {
1077         glUseProgram(programNonFetch);
1078         ASSERT_GL_NO_ERROR();
1079 
1080         GLFramebuffer framebuffer;
1081         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1082         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
1083         GLTexture colorBufferTex;
1084         glBindTexture(GL_TEXTURE_2D, colorBufferTex);
1085         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1086                      GL_UNSIGNED_BYTE, greenColor.data());
1087         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
1088                                0);
1089 
1090         ASSERT_GL_NO_ERROR();
1091 
1092         float colorRed[4]           = {1.0f, 0.0f, 0.0f, 1.0f};
1093         GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
1094         glUniform4fv(colorLocationNonFetch, 1, colorRed);
1095 
1096         GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
1097         // Render without regard to glFramebufferFetchBarrierEXT()
1098         render(positionLocationNonFetch, GL_FALSE);
1099 
1100         ASSERT_GL_NO_ERROR();
1101 
1102         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1103 
1104         glUseProgram(programFetch);
1105 
1106         float colorGreen[4]      = {0.0f, 1.0f, 0.0f, 1.0f};
1107         GLint colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
1108         glUniform4fv(colorLocationFetch, 1, colorGreen);
1109 
1110         GLint positionLocationFetch = glGetAttribLocation(programFetch, "a_position");
1111         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1112         // extension being used
1113         render(positionLocationFetch, !mCoherentExtension);
1114 
1115         ASSERT_GL_NO_ERROR();
1116 
1117         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1118 
1119         glUseProgram(programNonFetch);
1120         glUniform4fv(colorLocationNonFetch, 1, colorRed);
1121         // Render without regard to glFramebufferFetchBarrierEXT()
1122         render(positionLocationNonFetch, GL_FALSE);
1123 
1124         ASSERT_GL_NO_ERROR();
1125 
1126         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1127 
1128         glUseProgram(programFetch);
1129         glUniform4fv(colorLocationFetch, 1, colorGreen);
1130         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1131         // extension being used
1132         render(positionLocationFetch, !mCoherentExtension);
1133 
1134         ASSERT_GL_NO_ERROR();
1135 
1136         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1137 
1138         glBindFramebuffer(GL_FRAMEBUFFER, 0);
1139     }
1140 
DrawFetchDrawNonFetchTest(GLProgram & programNonFetch,GLProgram & programFetch)1141     void DrawFetchDrawNonFetchTest(GLProgram &programNonFetch, GLProgram &programFetch)
1142     {
1143         glUseProgram(programFetch);
1144         ASSERT_GL_NO_ERROR();
1145 
1146         GLFramebuffer framebuffer;
1147         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1148         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
1149         GLTexture colorBufferTex;
1150         glBindTexture(GL_TEXTURE_2D, colorBufferTex);
1151         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1152                      GL_UNSIGNED_BYTE, greenColor.data());
1153         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
1154                                0);
1155 
1156         ASSERT_GL_NO_ERROR();
1157 
1158         float colorRed[4]        = {1.0f, 0.0f, 0.0f, 1.0f};
1159         GLint colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
1160         glUniform4fv(colorLocationFetch, 1, colorRed);
1161 
1162         GLint positionLocationFetch = glGetAttribLocation(programFetch, "a_position");
1163         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1164         // extension being used
1165         render(positionLocationFetch, !mCoherentExtension);
1166         ASSERT_GL_NO_ERROR();
1167 
1168         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1169 
1170         glUseProgram(programNonFetch);
1171 
1172         GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
1173         glUniform4fv(colorLocationNonFetch, 1, colorRed);
1174 
1175         GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
1176         // Render without regard to glFramebufferFetchBarrierEXT()
1177         render(positionLocationNonFetch, GL_FALSE);
1178         ASSERT_GL_NO_ERROR();
1179 
1180         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1181 
1182         float colorGreen[4] = {0.0f, 1.0f, 0.0f, 1.0f};
1183         glUseProgram(programFetch);
1184         glUniform4fv(colorLocationFetch, 1, colorGreen);
1185         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1186         // extension being used
1187         render(positionLocationFetch, !mCoherentExtension);
1188         ASSERT_GL_NO_ERROR();
1189 
1190         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1191 
1192         glUseProgram(programNonFetch);
1193         glUniform4fv(colorLocationNonFetch, 1, colorRed);
1194         // Render without regard to glFramebufferFetchBarrierEXT()
1195         render(positionLocationNonFetch, GL_FALSE);
1196 
1197         ASSERT_GL_NO_ERROR();
1198 
1199         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1200 
1201         glBindFramebuffer(GL_FRAMEBUFFER, 0);
1202     }
1203 
1204     enum class StorageBufferTestPostFetchAction
1205     {
1206         Nothing,
1207         Clear,
1208     };
1209 
DrawNonFetchDrawFetchInStorageBufferTest(GLProgram & programNonFetch,GLProgram & programFetch,StorageBufferTestPostFetchAction postFetchAction)1210     void DrawNonFetchDrawFetchInStorageBufferTest(GLProgram &programNonFetch,
1211                                                   GLProgram &programFetch,
1212                                                   StorageBufferTestPostFetchAction postFetchAction)
1213     {
1214         // Create output buffer
1215         constexpr GLsizei kBufferSize = kViewportWidth * kViewportHeight * sizeof(float[4]);
1216         GLBuffer buffer;
1217         glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
1218         glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
1219         glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, buffer, 0, kBufferSize);
1220 
1221         // Zero-initialize it
1222         void *bufferData = glMapBufferRange(
1223             GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,
1224             GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
1225         memset(bufferData, 0, kBufferSize);
1226         glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
1227 
1228         glUseProgram(programNonFetch);
1229         ASSERT_GL_NO_ERROR();
1230 
1231         GLFramebuffer framebuffer;
1232         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1233         std::vector<GLColor> initColor(kViewportWidth * kViewportHeight, GLColor{10, 20, 30, 40});
1234         GLTexture colorBufferTex;
1235         glBindTexture(GL_TEXTURE_2D, colorBufferTex);
1236         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1237                      GL_UNSIGNED_BYTE, initColor.data());
1238         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
1239                                0);
1240 
1241         ASSERT_GL_NO_ERROR();
1242 
1243         float colorRed[4]           = {1.0f, 0.0f, 0.0f, 1.0f};
1244         GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
1245         glUniform4fv(colorLocationNonFetch, 1, colorRed);
1246 
1247         GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
1248 
1249         // Mask color output.  The no-fetch draw call should be a no-op, and the fetch draw-call
1250         // should only output to the storage buffer, but not the color attachment.
1251         glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1252 
1253         // Render without regard to glFramebufferFetchBarrierEXT()
1254         render(positionLocationNonFetch, GL_FALSE);
1255 
1256         ASSERT_GL_NO_ERROR();
1257 
1258         glUseProgram(programFetch);
1259 
1260         float colorBlue[4]       = {0.0f, 0.0f, 1.0f, 1.0f};
1261         GLint colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
1262         glUniform4fv(colorLocationFetch, 1, colorBlue);
1263 
1264         GLint positionLocationFetch = glGetAttribLocation(programFetch, "a_position");
1265         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1266         // extension being used
1267         render(positionLocationFetch, !mCoherentExtension);
1268 
1269         ASSERT_GL_NO_ERROR();
1270 
1271         // Enable the color mask and clear the alpha channel.  This shouldn't be reordered with the
1272         // fetch draw.
1273         GLColor expect = initColor[0];
1274         if (postFetchAction == StorageBufferTestPostFetchAction::Clear)
1275         {
1276             expect.A = 200;
1277             glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
1278             glClearColor(0.5, 0.6, 0.7, expect.A / 255.0f);
1279             glClear(GL_COLOR_BUFFER_BIT);
1280         }
1281 
1282         // Since color is completely masked out, the texture should retain its original green color.
1283         EXPECT_PIXEL_COLOR_NEAR(kViewportWidth / 2, kViewportHeight / 2, expect, 1);
1284 
1285         // Read back the storage buffer and make sure framebuffer fetch worked as intended despite
1286         // masked color.
1287         glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
1288 
1289         const float *colorData = static_cast<const float *>(
1290             glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT));
1291         for (uint32_t y = 0; y < kViewportHeight; ++y)
1292         {
1293             for (uint32_t x = 0; x < kViewportWidth; ++x)
1294             {
1295                 uint32_t ssboIndex = (y * kViewportWidth + x) * 4;
1296                 EXPECT_NEAR(colorData[ssboIndex + 0], initColor[0].R / 255.0, 0.05);
1297                 EXPECT_NEAR(colorData[ssboIndex + 1], initColor[0].G / 255.0, 0.05);
1298                 EXPECT_NEAR(colorData[ssboIndex + 2], initColor[0].B / 255.0, 0.05);
1299                 EXPECT_NEAR(colorData[ssboIndex + 3], initColor[0].A / 255.0, 0.05);
1300             }
1301         }
1302         glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
1303 
1304         glBindFramebuffer(GL_FRAMEBUFFER, 0);
1305     }
1306 
DrawNonFetchDrawFetchWithDifferentAttachmentsTest(GLProgram & programNonFetch,GLProgram & programFetch)1307     void DrawNonFetchDrawFetchWithDifferentAttachmentsTest(GLProgram &programNonFetch,
1308                                                            GLProgram &programFetch)
1309     {
1310         glUseProgram(programNonFetch);
1311         ASSERT_GL_NO_ERROR();
1312 
1313         GLFramebuffer framebuffer;
1314         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1315         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
1316         GLTexture colorTex;
1317         glBindTexture(GL_TEXTURE_2D, colorTex);
1318         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1319                      GL_UNSIGNED_BYTE, greenColor.data());
1320         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
1321 
1322         ASSERT_GL_NO_ERROR();
1323 
1324         float colorRed[4]           = {1.0f, 0.0f, 0.0f, 1.0f};
1325         GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
1326         glUniform4fv(colorLocationNonFetch, 1, colorRed);
1327 
1328         GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
1329         // Render without regard to glFramebufferFetchBarrierEXT()
1330         render(positionLocationNonFetch, GL_FALSE);
1331         ASSERT_GL_NO_ERROR();
1332 
1333         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1334 
1335         glUseProgram(programFetch);
1336         ASSERT_GL_NO_ERROR();
1337 
1338         GLFramebuffer framebufferMRT1;
1339         glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT1);
1340         std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
1341         std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
1342         GLTexture colorBufferTex1[kMaxColorBuffer];
1343         GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
1344                                                     GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
1345         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[0]);
1346         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1347                      GL_UNSIGNED_BYTE, color1.data());
1348         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[1]);
1349         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1350                      GL_UNSIGNED_BYTE, color1.data());
1351         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[2]);
1352         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1353                      GL_UNSIGNED_BYTE, color2.data());
1354         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[3]);
1355         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1356                      GL_UNSIGNED_BYTE, color2.data());
1357         glBindTexture(GL_TEXTURE_2D, 0);
1358         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
1359         {
1360             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
1361                                    colorBufferTex1[i], 0);
1362         }
1363         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
1364         ASSERT_GL_NO_ERROR();
1365 
1366         GLint colorLocation = glGetUniformLocation(programFetch, "u_color");
1367         glUniform4fv(colorLocation, 1, colorRed);
1368 
1369         GLint positionLocation = glGetAttribLocation(programFetch, "a_position");
1370         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1371         // extension being used
1372         render(positionLocation, !mCoherentExtension);
1373         ASSERT_GL_NO_ERROR();
1374 
1375         glReadBuffer(colorAttachments[0]);
1376         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1377         glReadBuffer(colorAttachments[1]);
1378         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1379         glReadBuffer(colorAttachments[2]);
1380         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
1381         glReadBuffer(colorAttachments[3]);
1382         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1383 
1384         GLFramebuffer framebufferMRT2;
1385         glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT2);
1386         GLTexture colorBufferTex2[kMaxColorBuffer];
1387         glBindTexture(GL_TEXTURE_2D, colorBufferTex2[0]);
1388         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1389                      GL_UNSIGNED_BYTE, color2.data());
1390         glBindTexture(GL_TEXTURE_2D, colorBufferTex2[1]);
1391         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1392                      GL_UNSIGNED_BYTE, color2.data());
1393         glBindTexture(GL_TEXTURE_2D, colorBufferTex2[2]);
1394         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1395                      GL_UNSIGNED_BYTE, color1.data());
1396         glBindTexture(GL_TEXTURE_2D, colorBufferTex2[3]);
1397         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1398                      GL_UNSIGNED_BYTE, color1.data());
1399         glBindTexture(GL_TEXTURE_2D, 0);
1400         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
1401         {
1402             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
1403                                    colorBufferTex2[i], 0);
1404         }
1405         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
1406         ASSERT_GL_NO_ERROR();
1407 
1408         glUniform4fv(colorLocation, 1, colorRed);
1409         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1410         // extension being used
1411         render(positionLocation, !mCoherentExtension);
1412         ASSERT_GL_NO_ERROR();
1413 
1414         glReadBuffer(colorAttachments[0]);
1415         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
1416         glReadBuffer(colorAttachments[1]);
1417         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1418         glReadBuffer(colorAttachments[2]);
1419         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1420         glReadBuffer(colorAttachments[3]);
1421         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1422 
1423         glBindFramebuffer(GL_FRAMEBUFFER, 0);
1424     }
1425 
DrawNonFetchDrawFetchWithDifferentProgramsTest(GLProgram & programNonFetch,GLProgram & programFetch1,GLProgram & programFetch2)1426     void DrawNonFetchDrawFetchWithDifferentProgramsTest(GLProgram &programNonFetch,
1427                                                         GLProgram &programFetch1,
1428                                                         GLProgram &programFetch2)
1429     {
1430         glUseProgram(programNonFetch);
1431         ASSERT_GL_NO_ERROR();
1432         GLFramebuffer framebuffer;
1433         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1434         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
1435         GLTexture colorTex;
1436         glBindTexture(GL_TEXTURE_2D, colorTex);
1437         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1438                      GL_UNSIGNED_BYTE, greenColor.data());
1439         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
1440 
1441         ASSERT_GL_NO_ERROR();
1442 
1443         float colorRed[4]           = {1.0f, 0.0f, 0.0f, 1.0f};
1444         GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
1445         glUniform4fv(colorLocationNonFetch, 1, colorRed);
1446 
1447         GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
1448         // Render without regard to glFramebufferFetchBarrierEXT()
1449         render(positionLocationNonFetch, GL_FALSE);
1450         ASSERT_GL_NO_ERROR();
1451 
1452         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1453 
1454         glUseProgram(programFetch1);
1455         ASSERT_GL_NO_ERROR();
1456 
1457         GLFramebuffer framebufferMRT1;
1458         glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT1);
1459         std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
1460         GLTexture colorBufferTex1[kMaxColorBuffer];
1461         GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
1462                                                     GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
1463         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
1464         {
1465             glBindTexture(GL_TEXTURE_2D, colorBufferTex1[i]);
1466             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1467                          GL_UNSIGNED_BYTE, color1.data());
1468             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
1469                                    colorBufferTex1[i], 0);
1470         }
1471         glBindTexture(GL_TEXTURE_2D, 0);
1472         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
1473         ASSERT_GL_NO_ERROR();
1474 
1475         GLint colorLocation = glGetUniformLocation(programFetch1, "u_color");
1476         glUniform4fv(colorLocation, 1, colorRed);
1477 
1478         GLint positionLocation = glGetAttribLocation(programFetch1, "a_position");
1479         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1480         // extension being used
1481         render(positionLocation, !mCoherentExtension);
1482         ASSERT_GL_NO_ERROR();
1483 
1484         glReadBuffer(colorAttachments[0]);
1485         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1486         glReadBuffer(colorAttachments[1]);
1487         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1488         glReadBuffer(colorAttachments[2]);
1489         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1490         glReadBuffer(colorAttachments[3]);
1491         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1492 
1493         glUseProgram(programFetch2);
1494         ASSERT_GL_NO_ERROR();
1495 
1496         glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1497         glClear(GL_COLOR_BUFFER_BIT);
1498 
1499         GLint colorLocation1 = glGetUniformLocation(programFetch2, "u_color");
1500         glUniform4fv(colorLocation1, 1, colorRed);
1501 
1502         GLint positionLocation1 = glGetAttribLocation(programFetch2, "a_position");
1503         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1504         // extension being used
1505         render(positionLocation1, !mCoherentExtension);
1506         ASSERT_GL_NO_ERROR();
1507 
1508         glReadBuffer(colorAttachments[0]);
1509         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1510         glReadBuffer(colorAttachments[1]);
1511         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1512         glReadBuffer(colorAttachments[2]);
1513         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1514         glReadBuffer(colorAttachments[3]);
1515         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1516 
1517         glBindFramebuffer(GL_FRAMEBUFFER, 0);
1518     }
1519 
DrawFetchWithDifferentIndicesInSameRenderPassTest(GLProgram & programFetch1,GLProgram & programFetch2)1520     void DrawFetchWithDifferentIndicesInSameRenderPassTest(GLProgram &programFetch1,
1521                                                            GLProgram &programFetch2)
1522     {
1523         GLFramebuffer framebufferMRT1;
1524         glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT1);
1525         std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
1526         GLTexture colorBufferTex1[kMaxColorBuffer];
1527         GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
1528                                                     GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
1529         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
1530         {
1531             glBindTexture(GL_TEXTURE_2D, colorBufferTex1[i]);
1532             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1533                          GL_UNSIGNED_BYTE, color1.data());
1534             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
1535                                    colorBufferTex1[i], 0);
1536         }
1537         glBindTexture(GL_TEXTURE_2D, 0);
1538         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
1539         ASSERT_GL_NO_ERROR();
1540 
1541         glUseProgram(programFetch1);
1542         ASSERT_GL_NO_ERROR();
1543 
1544         GLint colorLocation     = glGetUniformLocation(programFetch1, "u_color");
1545         const float colorRed[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1546         glUniform4fv(colorLocation, 1, colorRed);
1547 
1548         GLint positionLocation = glGetAttribLocation(programFetch1, "a_position");
1549         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1550         // extension being used
1551         //
1552         // Attachments are red, yellow, yellow, red
1553         render(positionLocation, !mCoherentExtension);
1554         ASSERT_GL_NO_ERROR();
1555 
1556         glUseProgram(programFetch2);
1557         ASSERT_GL_NO_ERROR();
1558 
1559         GLint colorLocation1     = glGetUniformLocation(programFetch2, "u_color");
1560         const float colorBlue[4] = {0.0f, 0.0f, 1.0f, 1.0f};
1561         glUniform4fv(colorLocation1, 1, colorBlue);
1562 
1563         GLint positionLocation1 = glGetAttribLocation(programFetch2, "a_position");
1564         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1565         // extension being used
1566         //
1567         // Attachments are blue, blue, white, magenta
1568         render(positionLocation1, !mCoherentExtension);
1569         ASSERT_GL_NO_ERROR();
1570 
1571         glReadBuffer(colorAttachments[0]);
1572         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
1573         glReadBuffer(colorAttachments[1]);
1574         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
1575         glReadBuffer(colorAttachments[2]);
1576         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::white);
1577         glReadBuffer(colorAttachments[3]);
1578         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
1579 
1580         glBindFramebuffer(GL_FRAMEBUFFER, 0);
1581     }
1582 
DrawFetchBlitDrawFetchTest(GLProgram & programNonFetch,GLProgram & programFetch)1583     void DrawFetchBlitDrawFetchTest(GLProgram &programNonFetch, GLProgram &programFetch)
1584     {
1585         glUseProgram(programFetch);
1586         ASSERT_GL_NO_ERROR();
1587 
1588         GLFramebuffer framebufferMRT1;
1589         glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT1);
1590         std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
1591         std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
1592         GLTexture colorBufferTex1[kMaxColorBuffer];
1593         GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
1594                                                     GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
1595         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[0]);
1596         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1597                      GL_UNSIGNED_BYTE, color1.data());
1598         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[1]);
1599         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1600                      GL_UNSIGNED_BYTE, color1.data());
1601         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[2]);
1602         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1603                      GL_UNSIGNED_BYTE, color2.data());
1604         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[3]);
1605         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1606                      GL_UNSIGNED_BYTE, color2.data());
1607         glBindTexture(GL_TEXTURE_2D, 0);
1608         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
1609         {
1610             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
1611                                    colorBufferTex1[i], 0);
1612         }
1613         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
1614         ASSERT_GL_NO_ERROR();
1615 
1616         float colorRed[4]   = {1.0f, 0.0f, 0.0f, 1.0f};
1617         GLint colorLocation = glGetUniformLocation(programFetch, "u_color");
1618         glUniform4fv(colorLocation, 1, colorRed);
1619 
1620         GLint positionLocation = glGetAttribLocation(programFetch, "a_position");
1621         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1622         // extension being used
1623         render(positionLocation, !mCoherentExtension);
1624         ASSERT_GL_NO_ERROR();
1625 
1626         glReadBuffer(colorAttachments[0]);
1627         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1628         glReadBuffer(colorAttachments[1]);
1629         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1630         glReadBuffer(colorAttachments[2]);
1631         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
1632         glReadBuffer(colorAttachments[3]);
1633         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1634 
1635         GLFramebuffer framebufferColor;
1636         glBindFramebuffer(GL_FRAMEBUFFER, framebufferColor);
1637 
1638         GLTexture colorTex;
1639         glBindTexture(GL_TEXTURE_2D, colorTex);
1640         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1641                      GL_UNSIGNED_BYTE, color2.data());
1642         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
1643 
1644         glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, framebufferColor);
1645         glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, framebufferMRT1);
1646 
1647         glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth,
1648                           kViewportHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1649         ASSERT_GL_NO_ERROR();
1650 
1651         glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT1);
1652         glReadBuffer(colorAttachments[0]);
1653         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
1654         glReadBuffer(colorAttachments[1]);
1655         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
1656         glReadBuffer(colorAttachments[2]);
1657         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
1658         glReadBuffer(colorAttachments[3]);
1659         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
1660 
1661         float colorGreen[4] = {0.0f, 1.0f, 0.0f, 1.0f};
1662         glUniform4fv(colorLocation, 1, colorGreen);
1663 
1664         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1665         // extension being used
1666         render(positionLocation, !mCoherentExtension);
1667         ASSERT_GL_NO_ERROR();
1668 
1669         glReadBuffer(colorAttachments[0]);
1670         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::cyan);
1671         glReadBuffer(colorAttachments[1]);
1672         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
1673         glReadBuffer(colorAttachments[2]);
1674         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::cyan);
1675         glReadBuffer(colorAttachments[3]);
1676         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
1677 
1678         glBindFramebuffer(GL_FRAMEBUFFER, 0);
1679     }
1680 
makeProgramPipeline(GLProgramPipeline & pipeline,const char * vs,const char * fs)1681     void makeProgramPipeline(GLProgramPipeline &pipeline, const char *vs, const char *fs)
1682     {
1683         GLProgram programVS, programFS;
1684 
1685         GLShader vertShader(GL_VERTEX_SHADER);
1686         glShaderSource(vertShader, 1, &vs, nullptr);
1687         glCompileShader(vertShader);
1688         glProgramParameteri(programVS, GL_PROGRAM_SEPARABLE, GL_TRUE);
1689         glAttachShader(programVS, vertShader);
1690         glLinkProgram(programVS);
1691         ASSERT_GL_NO_ERROR();
1692 
1693         GLShader fragShader(GL_FRAGMENT_SHADER);
1694         glShaderSource(fragShader, 1, &fs, nullptr);
1695         glCompileShader(fragShader);
1696         glProgramParameteri(programFS, GL_PROGRAM_SEPARABLE, GL_TRUE);
1697         glAttachShader(programFS, fragShader);
1698         glLinkProgram(programFS);
1699         ASSERT_GL_NO_ERROR();
1700 
1701         glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, programVS);
1702         glUseProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, programFS);
1703 
1704         glUseProgram(0);
1705         glBindProgramPipeline(pipeline);
1706         ASSERT_GL_NO_ERROR();
1707     }
1708 
ProgramPipelineTest(const char * kVS,const char * kFS1,const char * kFS2)1709     void ProgramPipelineTest(const char *kVS, const char *kFS1, const char *kFS2)
1710     {
1711         GLProgram programVert, programNonFetch, programFetch;
1712         const char *sourceArray[3] = {kVS, kFS1, kFS2};
1713 
1714         GLShader vertShader(GL_VERTEX_SHADER);
1715         glShaderSource(vertShader, 1, &sourceArray[0], nullptr);
1716         glCompileShader(vertShader);
1717         glProgramParameteri(programVert, GL_PROGRAM_SEPARABLE, GL_TRUE);
1718         glAttachShader(programVert, vertShader);
1719         glLinkProgram(programVert);
1720         ASSERT_GL_NO_ERROR();
1721 
1722         GLShader fragShader1(GL_FRAGMENT_SHADER);
1723         glShaderSource(fragShader1, 1, &sourceArray[1], nullptr);
1724         glCompileShader(fragShader1);
1725         glProgramParameteri(programNonFetch, GL_PROGRAM_SEPARABLE, GL_TRUE);
1726         glAttachShader(programNonFetch, fragShader1);
1727         glLinkProgram(programNonFetch);
1728         ASSERT_GL_NO_ERROR();
1729 
1730         GLShader fragShader2(GL_FRAGMENT_SHADER);
1731         glShaderSource(fragShader2, 1, &sourceArray[2], nullptr);
1732         glCompileShader(fragShader2);
1733         glProgramParameteri(programFetch, GL_PROGRAM_SEPARABLE, GL_TRUE);
1734         glAttachShader(programFetch, fragShader2);
1735         glLinkProgram(programFetch);
1736         ASSERT_GL_NO_ERROR();
1737 
1738         GLProgramPipeline pipeline1, pipeline2, pipeline3, pipeline4;
1739         glUseProgramStages(pipeline1, GL_VERTEX_SHADER_BIT, programVert);
1740         glUseProgramStages(pipeline1, GL_FRAGMENT_SHADER_BIT, programNonFetch);
1741         glBindProgramPipeline(pipeline1);
1742         ASSERT_GL_NO_ERROR();
1743 
1744         GLFramebuffer framebuffer;
1745         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1746         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
1747         GLTexture colorBufferTex;
1748         glBindTexture(GL_TEXTURE_2D, colorBufferTex);
1749         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1750                      GL_UNSIGNED_BYTE, greenColor.data());
1751         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
1752                                0);
1753         ASSERT_GL_NO_ERROR();
1754 
1755         glActiveShaderProgram(pipeline1, programNonFetch);
1756         float colorRed[4]           = {1.0f, 0.0f, 0.0f, 1.0f};
1757         GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
1758         glUniform4fv(colorLocationNonFetch, 1, colorRed);
1759         ASSERT_GL_NO_ERROR();
1760 
1761         glActiveShaderProgram(pipeline1, programVert);
1762         GLint positionLocation = glGetAttribLocation(programVert, "a_position");
1763         // Render without regard to glFramebufferFetchBarrierEXT()
1764         render(positionLocation, GL_FALSE);
1765         ASSERT_GL_NO_ERROR();
1766 
1767         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1768 
1769         glUseProgramStages(pipeline2, GL_VERTEX_SHADER_BIT, programVert);
1770         glUseProgramStages(pipeline2, GL_FRAGMENT_SHADER_BIT, programFetch);
1771         glBindProgramPipeline(pipeline2);
1772         ASSERT_GL_NO_ERROR();
1773 
1774         glActiveShaderProgram(pipeline2, programFetch);
1775         float colorGreen[4]      = {0.0f, 1.0f, 0.0f, 1.0f};
1776         GLint colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
1777         glUniform4fv(colorLocationFetch, 1, colorGreen);
1778 
1779         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1780         // extension being used
1781         render(positionLocation, !mCoherentExtension);
1782         ASSERT_GL_NO_ERROR();
1783 
1784         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1785 
1786         glUseProgramStages(pipeline3, GL_VERTEX_SHADER_BIT, programVert);
1787         glUseProgramStages(pipeline3, GL_FRAGMENT_SHADER_BIT, programNonFetch);
1788         glBindProgramPipeline(pipeline3);
1789         ASSERT_GL_NO_ERROR();
1790 
1791         glActiveShaderProgram(pipeline3, programNonFetch);
1792         colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
1793         glUniform4fv(colorLocationNonFetch, 1, colorRed);
1794 
1795         ASSERT_GL_NO_ERROR();
1796 
1797         // Render without regard to glFramebufferFetchBarrierEXT()
1798         render(positionLocation, GL_FALSE);
1799         ASSERT_GL_NO_ERROR();
1800 
1801         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1802 
1803         glUseProgramStages(pipeline4, GL_VERTEX_SHADER_BIT, programVert);
1804         glUseProgramStages(pipeline4, GL_FRAGMENT_SHADER_BIT, programFetch);
1805         glBindProgramPipeline(pipeline4);
1806         ASSERT_GL_NO_ERROR();
1807 
1808         glActiveShaderProgram(pipeline4, programFetch);
1809         colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
1810         glUniform4fv(colorLocationFetch, 1, colorGreen);
1811         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1812         // extension being used
1813         render(positionLocation, !mCoherentExtension);
1814         ASSERT_GL_NO_ERROR();
1815 
1816         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1817 
1818         glBindFramebuffer(GL_FRAMEBUFFER, 0);
1819     }
1820 
1821     void createFramebufferWithDepthStencil(GLRenderbuffer *color,
1822                                            GLRenderbuffer *depthStencil,
1823                                            GLFramebuffer *fbo);
1824 
1825     // Helpers for tests that don't care whether coherent or non-coherent framebuffer fetch is
1826     // enabled, because they are testing something orthogonal to coherence.  They only account for
1827     // GL_EXT_shader_framebuffer_fetch and GL_EXT_shader_framebuffer_fetch_non_coherent, not the ARM
1828     // variant or depth/stencil.
1829     WhichExtension chooseBetweenCoherentOrIncoherent();
1830     std::string makeShaderPreamble(WhichExtension whichExtension,
1831                                    const char *otherExtensions,
1832                                    uint32_t colorAttachmentCount);
1833 
1834     bool mCoherentExtension;
1835     bool mARMExtension;
1836     bool mBothExtensions;
1837 };
1838 
1839 class FramebufferFetchAndAdvancedBlendES31 : public FramebufferFetchES31
1840 {};
1841 
createFramebufferWithDepthStencil(GLRenderbuffer * color,GLRenderbuffer * depthStencil,GLFramebuffer * fbo)1842 void FramebufferFetchES31::createFramebufferWithDepthStencil(GLRenderbuffer *color,
1843                                                              GLRenderbuffer *depthStencil,
1844                                                              GLFramebuffer *fbo)
1845 {
1846     glBindFramebuffer(GL_FRAMEBUFFER, *fbo);
1847 
1848     glBindRenderbuffer(GL_RENDERBUFFER, *color);
1849     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kViewportWidth, kViewportHeight);
1850     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *color);
1851 
1852     glBindRenderbuffer(GL_RENDERBUFFER, *depthStencil);
1853     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kViewportWidth, kViewportHeight);
1854     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1855                               *depthStencil);
1856 
1857     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1858     ASSERT_GL_NO_ERROR();
1859 }
1860 
chooseBetweenCoherentOrIncoherent()1861 FramebufferFetchES31::WhichExtension FramebufferFetchES31::chooseBetweenCoherentOrIncoherent()
1862 {
1863     const bool isCoherent = IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch");
1864     EXPECT_TRUE(isCoherent || IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1865 
1866     return isCoherent ? COHERENT : NON_COHERENT;
1867 }
1868 
makeShaderPreamble(WhichExtension whichExtension,const char * otherExtensions,uint32_t colorAttachmentCount)1869 std::string FramebufferFetchES31::makeShaderPreamble(WhichExtension whichExtension,
1870                                                      const char *otherExtensions,
1871                                                      uint32_t colorAttachmentCount)
1872 {
1873     std::ostringstream fs;
1874     fs << "#version 310 es\n";
1875     switch (whichExtension)
1876     {
1877         case COHERENT:
1878             fs << "#extension GL_EXT_shader_framebuffer_fetch : require\n";
1879             break;
1880         case NON_COHERENT:
1881             fs << "#extension GL_EXT_shader_framebuffer_fetch_non_coherent : require\n";
1882             break;
1883         default:
1884             UNREACHABLE();
1885             break;
1886     }
1887 
1888     if (otherExtensions != nullptr)
1889     {
1890         fs << otherExtensions << "\n";
1891     }
1892 
1893     for (uint32_t location = 0; location < colorAttachmentCount; ++location)
1894     {
1895         fs << "layout(";
1896         if (whichExtension == NON_COHERENT)
1897         {
1898             fs << "noncoherent, ";
1899         }
1900         fs << "location = " << location << ") inout highp vec4 color" << location << ";\n";
1901     }
1902 
1903     return fs.str();
1904 }
1905 
1906 // Test coherent extension with inout qualifier
TEST_P(FramebufferFetchES31,BasicInout_Coherent)1907 TEST_P(FramebufferFetchES31, BasicInout_Coherent)
1908 {
1909     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1910     setWhichExtension(COHERENT);
1911 
1912     GLProgram program;
1913     program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1914     glUseProgram(program);
1915     ASSERT_GL_NO_ERROR();
1916 
1917     BasicTest(program);
1918 }
1919 
1920 // Test non-coherent extension with inout qualifier
TEST_P(FramebufferFetchES31,BasicInout_NonCoherent)1921 TEST_P(FramebufferFetchES31, BasicInout_NonCoherent)
1922 {
1923     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1924     setWhichExtension(NON_COHERENT);
1925 
1926     GLProgram program;
1927     program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1928     glUseProgram(program);
1929     ASSERT_GL_NO_ERROR();
1930 
1931     BasicTest(program);
1932 }
1933 
1934 // Test coherent extension with gl_LastFragData
TEST_P(FramebufferFetchES31,BasicLastFragData_Coherent)1935 TEST_P(FramebufferFetchES31, BasicLastFragData_Coherent)
1936 {
1937     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1938     setWhichExtension(COHERENT);
1939 
1940     GLProgram program;
1941     program.makeRaster(k100VS, getFragmentShader(GLSL100));
1942     glUseProgram(program);
1943     ASSERT_GL_NO_ERROR();
1944 
1945     BasicTest(program);
1946 }
1947 
1948 // Test non-coherent extension with gl_LastFragData
TEST_P(FramebufferFetchES31,BasicLastFragData_NonCoherent)1949 TEST_P(FramebufferFetchES31, BasicLastFragData_NonCoherent)
1950 {
1951     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1952     setWhichExtension(NON_COHERENT);
1953 
1954     GLProgram program;
1955     program.makeRaster(k100VS, getFragmentShader(GLSL100));
1956     glUseProgram(program);
1957     ASSERT_GL_NO_ERROR();
1958 
1959     BasicTest(program);
1960 }
1961 
1962 // Testing coherent extension with multiple render target, using gl_FragData with constant indices
TEST_P(FramebufferFetchES31,MultipleRenderTarget_Coherent_FragData)1963 TEST_P(FramebufferFetchES31, MultipleRenderTarget_Coherent_FragData)
1964 {
1965     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1966     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_draw_buffers"));
1967     setWhichExtension(COHERENT);
1968 
1969     GLProgram program;
1970     program.makeRaster(k100VS, getFragmentShader(GLSL100_4ATTACHMENT));
1971     glUseProgram(program);
1972     ASSERT_GL_NO_ERROR();
1973 
1974     MultipleRenderTargetTest(program, GLSL100_4ATTACHMENT);
1975 }
1976 
1977 // Testing coherent extension with multiple render target, using gl_FragData with complex
1978 // expressions
TEST_P(FramebufferFetchES31,MultipleRenderTarget_Coherent_FragData_Complex)1979 TEST_P(FramebufferFetchES31, MultipleRenderTarget_Coherent_FragData_Complex)
1980 {
1981     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1982     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_draw_buffers"));
1983     setWhichExtension(COHERENT);
1984 
1985     GLProgram program;
1986     program.makeRaster(k100VS, getFragmentShader(GLSL100_COMPLEX));
1987     glUseProgram(program);
1988     ASSERT_GL_NO_ERROR();
1989 
1990     MultipleRenderTargetTest(program, GLSL100_COMPLEX);
1991 }
1992 
1993 // Testing coherent extension with multiple render target, using inouts with complex expressions
TEST_P(FramebufferFetchES31,MultipleRenderTarget_Coherent_Complex)1994 TEST_P(FramebufferFetchES31, MultipleRenderTarget_Coherent_Complex)
1995 {
1996     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1997     setWhichExtension(COHERENT);
1998 
1999     GLProgram program;
2000     program.makeRaster(k310VS, getFragmentShader(GLSL310_COMPLEX));
2001     glUseProgram(program);
2002     ASSERT_GL_NO_ERROR();
2003 
2004     MultipleRenderTargetTest(program, GLSL310_COMPLEX);
2005 }
2006 
2007 // Testing coherent extension with multiple render target
TEST_P(FramebufferFetchES31,MultipleRenderTarget_Coherent)2008 TEST_P(FramebufferFetchES31, MultipleRenderTarget_Coherent)
2009 {
2010     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2011     setWhichExtension(COHERENT);
2012 
2013     GLProgram program;
2014     program.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT));
2015     glUseProgram(program);
2016     ASSERT_GL_NO_ERROR();
2017 
2018     MultipleRenderTargetTest(program, GLSL310_4ATTACHMENT);
2019 }
2020 
2021 // Testing non-coherent extension with multiple render target, using gl_FragData with constant
2022 // indices
TEST_P(FramebufferFetchES31,MultipleRenderTarget_NonCoherent_FragData)2023 TEST_P(FramebufferFetchES31, MultipleRenderTarget_NonCoherent_FragData)
2024 {
2025     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2026     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_draw_buffers"));
2027     setWhichExtension(NON_COHERENT);
2028 
2029     GLProgram program;
2030     program.makeRaster(k100VS, getFragmentShader(GLSL100_4ATTACHMENT));
2031     glUseProgram(program);
2032     ASSERT_GL_NO_ERROR();
2033 
2034     MultipleRenderTargetTest(program, GLSL100_4ATTACHMENT);
2035 }
2036 
2037 // Testing non-coherent extension with multiple render target, using gl_FragData with complex
2038 // expressions
TEST_P(FramebufferFetchES31,MultipleRenderTarget_NonCoherent_FragData_Complex)2039 TEST_P(FramebufferFetchES31, MultipleRenderTarget_NonCoherent_FragData_Complex)
2040 {
2041     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2042     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_draw_buffers"));
2043     setWhichExtension(NON_COHERENT);
2044 
2045     GLProgram program;
2046     program.makeRaster(k100VS, getFragmentShader(GLSL100_COMPLEX));
2047     glUseProgram(program);
2048     ASSERT_GL_NO_ERROR();
2049 
2050     MultipleRenderTargetTest(program, GLSL100_COMPLEX);
2051 }
2052 
2053 // Testing non-coherent extension with multiple render target, using inouts with complex expressions
TEST_P(FramebufferFetchES31,MultipleRenderTarget_NonCoherent_Complex)2054 TEST_P(FramebufferFetchES31, MultipleRenderTarget_NonCoherent_Complex)
2055 {
2056     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2057     setWhichExtension(NON_COHERENT);
2058 
2059     GLProgram program;
2060     program.makeRaster(k310VS, getFragmentShader(GLSL310_COMPLEX));
2061     glUseProgram(program);
2062     ASSERT_GL_NO_ERROR();
2063 
2064     MultipleRenderTargetTest(program, GLSL310_COMPLEX);
2065 }
2066 
2067 // Testing non-coherent extension with multiple render target
TEST_P(FramebufferFetchES31,MultipleRenderTarget_NonCoherent)2068 TEST_P(FramebufferFetchES31, MultipleRenderTarget_NonCoherent)
2069 {
2070     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2071     setWhichExtension(NON_COHERENT);
2072 
2073     GLProgram program;
2074     program.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT));
2075     glUseProgram(program);
2076     ASSERT_GL_NO_ERROR();
2077 
2078     MultipleRenderTargetTest(program, GLSL310_4ATTACHMENT);
2079 }
2080 
2081 // Testing non-coherent extension with multiple render target using inout array
TEST_P(FramebufferFetchES31,MultipleRenderTargetWithInoutArray_NonCoherent)2082 TEST_P(FramebufferFetchES31, MultipleRenderTargetWithInoutArray_NonCoherent)
2083 {
2084     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2085     setWhichExtension(NON_COHERENT);
2086 
2087     GLProgram program;
2088     program.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT));
2089     glUseProgram(program);
2090     ASSERT_GL_NO_ERROR();
2091 
2092     MultipleRenderTargetTest(program, GLSL310_4ATTACHMENT);
2093 }
2094 
2095 // Testing coherent extension with multiple render target using inout array
TEST_P(FramebufferFetchES31,MultipleRenderTargetWithInoutArray_Coherent)2096 TEST_P(FramebufferFetchES31, MultipleRenderTargetWithInoutArray_Coherent)
2097 {
2098     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2099     setWhichExtension(COHERENT);
2100 
2101     GLProgram program;
2102     program.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT));
2103     glUseProgram(program);
2104     ASSERT_GL_NO_ERROR();
2105 
2106     MultipleRenderTargetTest(program, GLSL310_4ATTACHMENT);
2107 }
2108 
2109 // Test coherent extension with multiple draw
TEST_P(FramebufferFetchES31,MultipleDraw_Coherent)2110 TEST_P(FramebufferFetchES31, MultipleDraw_Coherent)
2111 {
2112     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2113     setWhichExtension(COHERENT);
2114 
2115     GLProgram program;
2116     program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
2117     glUseProgram(program);
2118     ASSERT_GL_NO_ERROR();
2119 
2120     MultipleDrawTest(program);
2121 }
2122 
2123 // Test non-coherent extension with multiple draw
TEST_P(FramebufferFetchES31,MultipleDraw_NonCoherent)2124 TEST_P(FramebufferFetchES31, MultipleDraw_NonCoherent)
2125 {
2126     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2127     setWhichExtension(NON_COHERENT);
2128 
2129     GLProgram program;
2130     program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
2131     glUseProgram(program);
2132     ASSERT_GL_NO_ERROR();
2133 
2134     MultipleDrawTest(program);
2135 }
2136 
2137 // Testing coherent extension with the order of non-fetch program and fetch program
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetch_Coherent)2138 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetch_Coherent)
2139 {
2140     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2141     setWhichExtension(COHERENT);
2142 
2143     GLProgram programNonFetch, programFetch;
2144     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2145     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
2146     ASSERT_GL_NO_ERROR();
2147 
2148     DrawNonFetchDrawFetchTest(programNonFetch, programFetch);
2149 }
2150 
2151 // Testing non-coherent extension with the order of non-fetch program and fetch program
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetch_NonCoherent)2152 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetch_NonCoherent)
2153 {
2154     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2155     setWhichExtension(NON_COHERENT);
2156 
2157     GLProgram programNonFetch, programFetch;
2158     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2159     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
2160     ASSERT_GL_NO_ERROR();
2161 
2162     DrawNonFetchDrawFetchTest(programNonFetch, programFetch);
2163 }
2164 
2165 // Testing coherent extension with the order of fetch program and non-fetch program
TEST_P(FramebufferFetchES31,DrawFetchDrawNonFetch_Coherent)2166 TEST_P(FramebufferFetchES31, DrawFetchDrawNonFetch_Coherent)
2167 {
2168     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2169     setWhichExtension(COHERENT);
2170 
2171     GLProgram programNonFetch, programFetch;
2172     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2173     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
2174     ASSERT_GL_NO_ERROR();
2175 
2176     DrawFetchDrawNonFetchTest(programNonFetch, programFetch);
2177 }
2178 
2179 // Testing non-coherent extension with the order of fetch program and non-fetch program
TEST_P(FramebufferFetchES31,DrawFetchDrawNonFetch_NonCoherent)2180 TEST_P(FramebufferFetchES31, DrawFetchDrawNonFetch_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_1ATTACHMENT));
2188     ASSERT_GL_NO_ERROR();
2189 
2190     DrawFetchDrawNonFetchTest(programNonFetch, programFetch);
2191 }
2192 
2193 // Testing coherent extension with framebuffer fetch read in combination with color attachment mask
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchInStorageBuffer_Coherent)2194 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchInStorageBuffer_Coherent)
2195 {
2196     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2197     setWhichExtension(COHERENT);
2198 
2199     GLint maxFragmentShaderStorageBlocks = 0;
2200     glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
2201     ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks == 0);
2202 
2203     GLProgram programNonFetch, programFetch;
2204     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2205     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER));
2206     ASSERT_GL_NO_ERROR();
2207 
2208     DrawNonFetchDrawFetchInStorageBufferTest(programNonFetch, programFetch,
2209                                              StorageBufferTestPostFetchAction::Nothing);
2210 }
2211 
2212 // Testing non-coherent extension with framebuffer fetch read in combination with color attachment
2213 // mask
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchInStorageBuffer_NonCoherent)2214 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchInStorageBuffer_NonCoherent)
2215 {
2216     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2217     setWhichExtension(NON_COHERENT);
2218 
2219     GLint maxFragmentShaderStorageBlocks = 0;
2220     glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
2221     ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks == 0);
2222 
2223     GLProgram programNonFetch, programFetch;
2224     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2225     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER));
2226     ASSERT_GL_NO_ERROR();
2227 
2228     DrawNonFetchDrawFetchInStorageBufferTest(programNonFetch, programFetch,
2229                                              StorageBufferTestPostFetchAction::Nothing);
2230 }
2231 
2232 // Testing coherent extension with the order of non-fetch program and fetch program with
2233 // different attachments
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchWithDifferentAttachments_Coherent)2234 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchWithDifferentAttachments_Coherent)
2235 {
2236     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2237     setWhichExtension(COHERENT);
2238 
2239     GLProgram programNonFetch, programFetch;
2240     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2241     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
2242     ASSERT_GL_NO_ERROR();
2243 
2244     DrawNonFetchDrawFetchWithDifferentAttachmentsTest(programNonFetch, programFetch);
2245 }
2246 
2247 // Testing coherent extension with framebuffer fetch read in combination with color attachment mask
2248 // and clear
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchInStorageBufferThenClear_Coherent)2249 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchInStorageBufferThenClear_Coherent)
2250 {
2251     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2252     setWhichExtension(COHERENT);
2253 
2254     GLint maxFragmentShaderStorageBlocks = 0;
2255     glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
2256     ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks == 0);
2257 
2258     GLProgram programNonFetch, programFetch;
2259     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2260     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER));
2261     ASSERT_GL_NO_ERROR();
2262 
2263     DrawNonFetchDrawFetchInStorageBufferTest(programNonFetch, programFetch,
2264                                              StorageBufferTestPostFetchAction::Clear);
2265 }
2266 
2267 // Testing non-coherent extension with framebuffer fetch read in combination with color attachment
2268 // mask and clear
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchInStorageBufferThenClear_NonCoherent)2269 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchInStorageBufferThenClear_NonCoherent)
2270 {
2271     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2272     setWhichExtension(NON_COHERENT);
2273 
2274     GLint maxFragmentShaderStorageBlocks = 0;
2275     glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
2276     ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks == 0);
2277 
2278     GLProgram programNonFetch, programFetch;
2279     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2280     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER));
2281     ASSERT_GL_NO_ERROR();
2282 
2283     DrawNonFetchDrawFetchInStorageBufferTest(programNonFetch, programFetch,
2284                                              StorageBufferTestPostFetchAction::Clear);
2285 }
2286 
2287 // Testing non-coherent extension with the order of non-fetch program and fetch program with
2288 // different attachments
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchWithDifferentAttachments_NonCoherent)2289 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchWithDifferentAttachments_NonCoherent)
2290 {
2291     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2292     setWhichExtension(NON_COHERENT);
2293 
2294     GLProgram programNonFetch, programFetch;
2295     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2296     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
2297     ASSERT_GL_NO_ERROR();
2298 
2299     DrawNonFetchDrawFetchWithDifferentAttachmentsTest(programNonFetch, programFetch);
2300 }
2301 
2302 // Testing coherent extension with the order of non-fetch program and fetch with different
2303 // programs
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchWithDifferentPrograms_Coherent)2304 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchWithDifferentPrograms_Coherent)
2305 {
2306     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2307     setWhichExtension(COHERENT);
2308 
2309     GLProgram programNonFetch, programFetch1, programFetch2;
2310     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2311     programFetch1.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
2312     programFetch2.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT2));
2313     ASSERT_GL_NO_ERROR();
2314 
2315     DrawNonFetchDrawFetchWithDifferentProgramsTest(programNonFetch, programFetch1, programFetch2);
2316 }
2317 
2318 // Testing non-coherent extension with the order of non-fetch program and fetch with different
2319 // programs
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchWithDifferentPrograms_NonCoherent)2320 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchWithDifferentPrograms_NonCoherent)
2321 {
2322     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2323     setWhichExtension(NON_COHERENT);
2324 
2325     GLProgram programNonFetch, programFetch1, programFetch2;
2326     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2327     programFetch1.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
2328     programFetch2.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT2));
2329     ASSERT_GL_NO_ERROR();
2330 
2331     DrawNonFetchDrawFetchWithDifferentProgramsTest(programNonFetch, programFetch1, programFetch2);
2332 }
2333 
2334 // Testing coherent extension with two fetch programs using different attachments.  The different
2335 // sets of attachments start at different non-zero indices.
TEST_P(FramebufferFetchES31,DrawFetchWithDifferentIndicesInSameRenderPass_Coherent)2336 TEST_P(FramebufferFetchES31, DrawFetchWithDifferentIndicesInSameRenderPass_Coherent)
2337 {
2338     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2339     setWhichExtension(COHERENT);
2340 
2341     GLProgram programFetch1, programFetch2;
2342     programFetch1.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT3));
2343     programFetch2.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT4));
2344     ASSERT_GL_NO_ERROR();
2345 
2346     DrawFetchWithDifferentIndicesInSameRenderPassTest(programFetch1, programFetch2);
2347 }
2348 
2349 // Testing non-coherent extension with two fetch programs using different attachments.  The
2350 // different sets of attachments start at different non-zero indices.
TEST_P(FramebufferFetchES31,DrawFetchWithDifferentIndicesInSameRenderPass_NonCoherent)2351 TEST_P(FramebufferFetchES31, DrawFetchWithDifferentIndicesInSameRenderPass_NonCoherent)
2352 {
2353     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2354     setWhichExtension(NON_COHERENT);
2355 
2356     GLProgram programFetch1, programFetch2;
2357     programFetch1.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT3));
2358     programFetch2.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT4));
2359     ASSERT_GL_NO_ERROR();
2360 
2361     DrawFetchWithDifferentIndicesInSameRenderPassTest(programFetch1, programFetch2);
2362 }
2363 
2364 // Testing coherent extension with the order of draw fetch, blit and draw fetch
TEST_P(FramebufferFetchES31,DrawFetchBlitDrawFetch_Coherent)2365 TEST_P(FramebufferFetchES31, DrawFetchBlitDrawFetch_Coherent)
2366 {
2367     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2368     setWhichExtension(COHERENT);
2369 
2370     GLProgram programNonFetch, programFetch;
2371     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2372     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
2373     ASSERT_GL_NO_ERROR();
2374 
2375     DrawFetchBlitDrawFetchTest(programNonFetch, programFetch);
2376 }
2377 
2378 // Testing non-coherent extension with the order of draw fetch, blit and draw fetch
TEST_P(FramebufferFetchES31,DrawFetchBlitDrawFetch_NonCoherent)2379 TEST_P(FramebufferFetchES31, DrawFetchBlitDrawFetch_NonCoherent)
2380 {
2381     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2382     setWhichExtension(NON_COHERENT);
2383 
2384     GLProgram programNonFetch, programFetch;
2385     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
2386     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
2387     ASSERT_GL_NO_ERROR();
2388 
2389     DrawFetchBlitDrawFetchTest(programNonFetch, programFetch);
2390 }
2391 
2392 // Testing coherent extension with program pipeline
TEST_P(FramebufferFetchES31,ProgramPipeline_Coherent)2393 TEST_P(FramebufferFetchES31, ProgramPipeline_Coherent)
2394 {
2395     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2396     setWhichExtension(COHERENT);
2397 
2398     ProgramPipelineTest(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT),
2399                         getFragmentShader(GLSL310_1ATTACHMENT));
2400 }
2401 
2402 // Testing non-coherent extension with program pipeline
TEST_P(FramebufferFetchES31,ProgramPipeline_NonCoherent)2403 TEST_P(FramebufferFetchES31, ProgramPipeline_NonCoherent)
2404 {
2405     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2406     setWhichExtension(NON_COHERENT);
2407 
2408     ProgramPipelineTest(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT),
2409                         getFragmentShader(GLSL310_1ATTACHMENT));
2410 }
2411 
2412 // Verify that sample shading is automatically enabled when framebuffer fetch is used with
2413 // multisampling.
TEST_P(FramebufferFetchES31,MultiSampled)2414 TEST_P(FramebufferFetchES31, MultiSampled)
2415 {
2416     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch") &&
2417                        !IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2418     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_sample_variables"));
2419 
2420     const WhichExtension whichExtension = chooseBetweenCoherentOrIncoherent();
2421 
2422     // Create a single-sampled framebuffer as the resolve target
2423     GLRenderbuffer resolve;
2424     glBindRenderbuffer(GL_RENDERBUFFER, resolve);
2425     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kViewportWidth, kViewportHeight);
2426     GLFramebuffer resolveFbo;
2427     glBindFramebuffer(GL_FRAMEBUFFER, resolveFbo);
2428     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, resolve);
2429 
2430     // Create a multisampled framebuffer
2431     GLRenderbuffer rbo;
2432     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
2433     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, kViewportWidth, kViewportHeight);
2434     GLFramebuffer fbo;
2435     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2436     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
2437 
2438     // Initialize every sample differently with per-sample shading.
2439     constexpr char kPrimeFS[] = R"(#version 310 es
2440 #extension GL_OES_sample_variables : require
2441 out highp vec4 color;
2442 void main (void)
2443 {
2444     switch (gl_SampleID)
2445     {
2446     case 0:
2447         color = vec4(1.0, 0.9, 0.8, 0.7);
2448         break;
2449     case 1:
2450         color = vec4(0.0, 0.1, 0.2, 0.3);
2451         break;
2452     case 2:
2453         color = vec4(0.5, 0.25, 0.75, 1.0);
2454         break;
2455     default:
2456         color = vec4(0.4, 0.6, 0.2, 0.8);
2457         break;
2458     }
2459 })";
2460     ANGLE_GL_PROGRAM(prime, essl31_shaders::vs::Passthrough(), kPrimeFS);
2461     glViewport(0, 0, kViewportWidth, kViewportHeight);
2462     drawQuad(prime, essl31_shaders::PositionAttrib(), 0.0f);
2463 
2464     // Break the render pass to make sure sample shading is not left enabled by accident.
2465     // The expected value is the average of the values set by the shader.
2466     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFbo);
2467     glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth, kViewportHeight,
2468                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
2469     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFbo);
2470     EXPECT_PIXEL_NEAR(0, 0, 121, 118, 124, 178, 1);
2471     ASSERT_GL_NO_ERROR();
2472 
2473     // Use framebuffer fetch to read the value of each sample, and store the square of that value.
2474     // Because square is non-linear, applied to the average value it would produce a different
2475     // result compared with it being applied to individual samples and then averaged.  The test thus
2476     // ensures that framebuffer fetch on a multisampled framebuffer implicitly enables sample
2477     // shading.
2478     std::ostringstream fs;
2479     fs << makeShaderPreamble(whichExtension, nullptr, 1);
2480     fs << R"(void main()
2481 {
2482     color0 *= color0;
2483 })";
2484 
2485     ANGLE_GL_PROGRAM(square, essl31_shaders::vs::Passthrough(), fs.str().c_str());
2486     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2487     drawQuad(square, essl31_shaders::PositionAttrib(), 0.0f);
2488 
2489     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFbo);
2490     glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth, kViewportHeight,
2491                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
2492     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFbo);
2493 
2494     // Verify that the result is average(square(samples)) and not square(average(samples)).
2495     EXPECT_PIXEL_NEAR(0, 0, 90, 79, 82, 141, 1);
2496 
2497     // For debugging purposes, the following would be true if framebuffer fetch _didn't_ implicitly
2498     // enable sample shading.
2499     // EXPECT_PIXEL_NEAR(0, 0, 57, 54, 60, 125, 1);
2500 
2501     ASSERT_GL_NO_ERROR();
2502 }
2503 
2504 // Test recovering a supposedly closed render pass that used framebuffer fetch..
TEST_P(FramebufferFetchES31,ReopenRenderPass)2505 TEST_P(FramebufferFetchES31, ReopenRenderPass)
2506 {
2507     const bool is_coherent = IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch");
2508     ANGLE_SKIP_TEST_IF(!is_coherent &&
2509                        !IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2510     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_sample_variables"));
2511 
2512     // Create two framebuffers
2513     GLRenderbuffer color[2];
2514     GLFramebuffer fbo[2];
2515     for (uint32_t i = 0; i < 2; ++i)
2516     {
2517         glBindRenderbuffer(GL_RENDERBUFFER, color[i]);
2518         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kViewportWidth, kViewportHeight);
2519         glBindFramebuffer(GL_FRAMEBUFFER, fbo[i]);
2520         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color[i]);
2521     }
2522 
2523     glBindFramebuffer(GL_FRAMEBUFFER, fbo[0]);
2524     glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
2525     glClear(GL_COLOR_BUFFER_BIT);
2526 
2527     // Use a framebuffer fetch program.
2528     std::ostringstream fs;
2529     fs << "#version 310 es\n";
2530     if (is_coherent)
2531     {
2532         fs << "#extension GL_EXT_shader_framebuffer_fetch : require\n";
2533     }
2534     else
2535     {
2536         fs << "#extension GL_EXT_shader_framebuffer_fetch_non_coherent : require\n";
2537     }
2538     fs << R"(inout highp vec4 color;
2539 void main (void)
2540 {
2541     color += vec4(0.25, 0.125, 0.5, 0.0);
2542 })";
2543 
2544     ANGLE_GL_PROGRAM(ff, essl31_shaders::vs::Passthrough(), fs.str().c_str());
2545     drawQuad(ff, essl31_shaders::PositionAttrib(), 0.0f);
2546 
2547     // Switch to another framebuffer and do a clear.  In the Vulkan backend, the previous render
2548     // pass stays around.
2549     glBindFramebuffer(GL_FRAMEBUFFER, fbo[1]);
2550     glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
2551     glClear(GL_COLOR_BUFFER_BIT);
2552 
2553     // Switch back to the original framebuffer and do a non-framebuffer fetch draw
2554     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
2555     glBindFramebuffer(GL_FRAMEBUFFER, fbo[0]);
2556     glEnable(GL_SCISSOR_TEST);
2557     glScissor(kViewportWidth / 2, kViewportHeight / 2, kViewportWidth - kViewportWidth / 2,
2558               kViewportHeight - kViewportHeight / 2);
2559     drawQuad(drawRed, essl31_shaders::PositionAttrib(), 0.0f);
2560 
2561     // Verify the results
2562     EXPECT_PIXEL_NEAR(0, 0, 191, 159, 255, 255, 1);
2563     EXPECT_PIXEL_COLOR_EQ(kViewportWidth - 1, kViewportHeight - 1, GLColor::red);
2564     ASSERT_GL_NO_ERROR();
2565 }
2566 
2567 // Test combination of inout and samplers.
TEST_P(FramebufferFetchES31,UniformUsageCombinations)2568 TEST_P(FramebufferFetchES31, UniformUsageCombinations)
2569 {
2570     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2571 
2572     constexpr char kVS[] = R"(#version 310 es
2573 in highp vec4 a_position;
2574 out highp vec2 texCoord;
2575 
2576 void main()
2577 {
2578     gl_Position = a_position;
2579     texCoord = (a_position.xy * 0.5) + 0.5;
2580 })";
2581 
2582     constexpr char kFS[] = R"(#version 310 es
2583 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
2584 
2585 layout(binding=0, offset=0) uniform atomic_uint atDiff;
2586 uniform sampler2D tex;
2587 
2588 layout(noncoherent, location = 0) inout highp vec4 o_color[4];
2589 in highp vec2 texCoord;
2590 
2591 void main()
2592 {
2593     highp vec4 texColor = texture(tex, texCoord);
2594 
2595     if (texColor != o_color[0])
2596     {
2597         atomicCounterIncrement(atDiff);
2598         o_color[0] = texColor;
2599     }
2600     else
2601     {
2602         if (atomicCounter(atDiff) > 0u)
2603         {
2604             atomicCounterDecrement(atDiff);
2605         }
2606     }
2607 
2608     if (texColor != o_color[1])
2609     {
2610         atomicCounterIncrement(atDiff);
2611         o_color[1] = texColor;
2612     }
2613     else
2614     {
2615         if (atomicCounter(atDiff) > 0u)
2616         {
2617             atomicCounterDecrement(atDiff);
2618         }
2619     }
2620 
2621     if (texColor != o_color[2])
2622     {
2623         atomicCounterIncrement(atDiff);
2624         o_color[2] = texColor;
2625     }
2626     else
2627     {
2628         if (atomicCounter(atDiff) > 0u)
2629         {
2630             atomicCounterDecrement(atDiff);
2631         }
2632     }
2633 
2634     if (texColor != o_color[3])
2635     {
2636         atomicCounterIncrement(atDiff);
2637         o_color[3] = texColor;
2638     }
2639     else
2640     {
2641         if (atomicCounter(atDiff) > 0u)
2642         {
2643             atomicCounterDecrement(atDiff);
2644         }
2645     }
2646 })";
2647 
2648     GLProgram program;
2649     program.makeRaster(kVS, kFS);
2650     glUseProgram(program);
2651 
2652     ASSERT_GL_NO_ERROR();
2653 
2654     GLFramebuffer framebuffer;
2655     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
2656     std::vector<GLColor> color0(kViewportWidth * kViewportHeight, GLColor::cyan);
2657     std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
2658     std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
2659     std::vector<GLColor> color3(kViewportWidth * kViewportHeight, GLColor::black);
2660     GLTexture colorBufferTex[kMaxColorBuffer];
2661     GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
2662                                                 GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
2663     glBindTexture(GL_TEXTURE_2D, colorBufferTex[0]);
2664     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
2665                  GL_UNSIGNED_BYTE, color0.data());
2666     glBindTexture(GL_TEXTURE_2D, colorBufferTex[1]);
2667     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
2668                  GL_UNSIGNED_BYTE, color1.data());
2669     glBindTexture(GL_TEXTURE_2D, colorBufferTex[2]);
2670     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
2671                  GL_UNSIGNED_BYTE, color2.data());
2672     glBindTexture(GL_TEXTURE_2D, colorBufferTex[3]);
2673     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
2674                  GL_UNSIGNED_BYTE, color3.data());
2675     glBindTexture(GL_TEXTURE_2D, 0);
2676     for (unsigned int i = 0; i < kMaxColorBuffer; i++)
2677     {
2678         glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
2679                                colorBufferTex[i], 0);
2680     }
2681     glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
2682 
2683     ASSERT_GL_NO_ERROR();
2684 
2685     GLBuffer atomicBuffer;
2686     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicBuffer);
2687     glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_DRAW);
2688 
2689     // Reset atomic counter buffer
2690     GLuint *userCounters;
2691     userCounters = static_cast<GLuint *>(glMapBufferRange(
2692         GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint),
2693         GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT));
2694     memset(userCounters, 0, sizeof(GLuint));
2695     glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
2696 
2697     glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicBuffer);
2698     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);
2699 
2700     float color[4]      = {1.0f, 0.0f, 0.0f, 1.0f};
2701     GLint colorLocation = glGetUniformLocation(program, "u_color");
2702     glUniform4fv(colorLocation, 1, color);
2703 
2704     GLint positionLocation = glGetAttribLocation(program, "a_position");
2705     render(positionLocation, GL_TRUE);
2706 
2707     ASSERT_GL_NO_ERROR();
2708 
2709     // Because no texture is bound, the shader samples black, increments the counter for every pixel
2710     // and sets all attachments to black.
2711     for (unsigned int i = 0; i < kMaxColorBuffer; i++)
2712     {
2713         glReadBuffer(colorAttachments[i]);
2714         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::black);
2715     }
2716 
2717     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicBuffer);
2718     userCounters = static_cast<GLuint *>(
2719         glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint), GL_MAP_READ_BIT));
2720     EXPECT_EQ(*userCounters, kViewportWidth * kViewportHeight * 2);
2721     glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
2722     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);
2723 
2724     glBindFramebuffer(GL_FRAMEBUFFER, 0);
2725 }
2726 
2727 // Testing that binding the location value using GLES API is conflicted to the location value of the
2728 // fragment inout.
TEST_P(FramebufferFetchES31,FixedUniformLocation)2729 TEST_P(FramebufferFetchES31, FixedUniformLocation)
2730 {
2731     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2732 
2733     constexpr char kVS[] = R"(#version 310 es
2734 in highp vec4 a_position;
2735 
2736 void main (void)
2737 {
2738     gl_Position = a_position;
2739 })";
2740 
2741     constexpr char kFS[] = R"(#version 310 es
2742 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
2743 layout(noncoherent, location = 0) inout highp vec4 o_color;
2744 
2745 layout(location = 0) uniform highp vec4 u_color;
2746 void main (void)
2747 {
2748     o_color += u_color;
2749 })";
2750 
2751     GLProgram program;
2752     program.makeRaster(kVS, kFS);
2753     glUseProgram(program);
2754 
2755     ASSERT_GL_NO_ERROR();
2756 
2757     GLFramebuffer framebuffer;
2758     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
2759     std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
2760     GLTexture colorBufferTex;
2761     glBindTexture(GL_TEXTURE_2D, colorBufferTex);
2762     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
2763                  GL_UNSIGNED_BYTE, greenColor.data());
2764     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex, 0);
2765 
2766     ASSERT_GL_NO_ERROR();
2767 
2768     float color[4]      = {1.0f, 0.0f, 0.0f, 1.0f};
2769     GLint colorLocation = glGetUniformLocation(program, "u_color");
2770     glUniform4fv(colorLocation, 1, color);
2771 
2772     GLint positionLocation = glGetAttribLocation(program, "a_position");
2773     render(positionLocation, GL_TRUE);
2774 
2775     ASSERT_GL_NO_ERROR();
2776 
2777     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
2778 
2779     glBindFramebuffer(GL_FRAMEBUFFER, 0);
2780 }
2781 
2782 // Verify we can use inout with the default framebuffer
2783 // http://anglebug.com/42265386
TEST_P(FramebufferFetchES31,DefaultFramebufferTest)2784 TEST_P(FramebufferFetchES31, DefaultFramebufferTest)
2785 {
2786     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2787 
2788     constexpr char kVS[] = R"(#version 300 es
2789 in highp vec4 a_position;
2790 
2791 void main (void)
2792 {
2793     gl_Position = a_position;
2794 })";
2795 
2796     constexpr char kFS[] = R"(#version 300 es
2797 #extension GL_EXT_shader_framebuffer_fetch : require
2798 layout(location = 0) inout highp vec4 o_color;
2799 
2800 uniform highp vec4 u_color;
2801 void main (void)
2802 {
2803     o_color += u_color;
2804 })";
2805 
2806     GLProgram program;
2807     program.makeRaster(kVS, kFS);
2808     glUseProgram(program);
2809 
2810     ASSERT_GL_NO_ERROR();
2811 
2812     // Ensure that we're rendering to the default framebuffer
2813     glBindFramebuffer(GL_FRAMEBUFFER, 0);
2814 
2815     // Start with a clear buffer
2816     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
2817     glClear(GL_COLOR_BUFFER_BIT);
2818 
2819     GLint positionLocation = glGetAttribLocation(program, "a_position");
2820     GLint colorLocation    = glGetUniformLocation(program, "u_color");
2821 
2822     // Draw once with red
2823     glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
2824     render(positionLocation, GL_FALSE);
2825     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
2826     ASSERT_GL_NO_ERROR();
2827 
2828     // Draw again with blue, adding it to the existing red, ending up with magenta
2829     glUniform4fv(colorLocation, 1, GLColor::blue.toNormalizedVector().data());
2830     render(positionLocation, GL_FALSE);
2831     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
2832     ASSERT_GL_NO_ERROR();
2833 }
2834 
2835 // Verify we can render to the default framebuffer without fetch, then switch to a program
2836 // that does fetch.
2837 // http://anglebug.com/42265386
TEST_P(FramebufferFetchES31,DefaultFramebufferMixedProgramsTest)2838 TEST_P(FramebufferFetchES31, DefaultFramebufferMixedProgramsTest)
2839 {
2840     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2841 
2842     constexpr char kVS[] = R"(#version 300 es
2843 in highp vec4 a_position;
2844 
2845 void main (void)
2846 {
2847     gl_Position = a_position;
2848 })";
2849 
2850     constexpr char kFS[] = R"(#version 300 es
2851 layout(location = 0) out highp vec4 o_color;
2852 
2853 uniform highp vec4 u_color;
2854 void main (void)
2855 {
2856     o_color = u_color;
2857 })";
2858 
2859     constexpr char kFetchFS[] = R"(#version 300 es
2860 #extension GL_EXT_shader_framebuffer_fetch : require
2861 layout(location = 0) inout highp vec4 o_color;
2862 
2863 uniform highp vec4 u_color;
2864 void main (void)
2865 {
2866     o_color += u_color;
2867 })";
2868 
2869     // Create a program that simply writes out a color, no fetching
2870     GLProgram program;
2871     program.makeRaster(kVS, kFS);
2872     glUseProgram(program);
2873 
2874     ASSERT_GL_NO_ERROR();
2875 
2876     // Ensure that we're rendering to the default framebuffer
2877     glBindFramebuffer(GL_FRAMEBUFFER, 0);
2878 
2879     // Start with a clear buffer
2880     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
2881     glClear(GL_COLOR_BUFFER_BIT);
2882 
2883     GLint positionLocation = glGetAttribLocation(program, "a_position");
2884     GLint colorLocation    = glGetUniformLocation(program, "u_color");
2885 
2886     // Draw once with red
2887     glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
2888     render(positionLocation, false);
2889     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
2890     ASSERT_GL_NO_ERROR();
2891 
2892     // Create another program that DOES fetch from the framebuffer
2893     GLProgram program2;
2894     program2.makeRaster(kVS, kFetchFS);
2895     glUseProgram(program2);
2896 
2897     GLint positionLocation2 = glGetAttribLocation(program2, "a_position");
2898     GLint colorLocation2    = glGetUniformLocation(program2, "u_color");
2899 
2900     // Draw again with blue, fetching red from the framebuffer, adding it together
2901     glUniform4fv(colorLocation2, 1, GLColor::blue.toNormalizedVector().data());
2902     render(positionLocation2, false);
2903     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
2904     ASSERT_GL_NO_ERROR();
2905 
2906     // Switch back to the non-fetched framebuffer, and render green
2907     glUseProgram(program);
2908     glUniform4fv(colorLocation, 1, GLColor::green.toNormalizedVector().data());
2909     render(positionLocation, false);
2910     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
2911     ASSERT_GL_NO_ERROR();
2912 }
2913 
2914 // Verify we can render to a framebuffer with fetch, then switch to another framebuffer (without
2915 // changing programs) http://anglebug.com/42265386
TEST_P(FramebufferFetchES31,FramebufferMixedFetchTest)2916 TEST_P(FramebufferFetchES31, FramebufferMixedFetchTest)
2917 {
2918     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
2919 
2920     constexpr char kVS[] = R"(#version 300 es
2921 in highp vec4 a_position;
2922 
2923 void main (void)
2924 {
2925     gl_Position = a_position;
2926 })";
2927 
2928     constexpr char kFS[] = R"(#version 300 es
2929 layout(location = 0) out highp vec4 o_color;
2930 
2931 uniform highp vec4 u_color;
2932 void main (void)
2933 {
2934     o_color = u_color;
2935 })";
2936 
2937     constexpr char kFetchFS[] = R"(#version 300 es
2938 #extension GL_EXT_shader_framebuffer_fetch : require
2939 layout(location = 0) inout highp vec4 o_color;
2940 
2941 uniform highp vec4 u_color;
2942 void main (void)
2943 {
2944     o_color += u_color;
2945 })";
2946 
2947     // Create a program that simply writes out a color, no fetching
2948     GLProgram program;
2949     program.makeRaster(kVS, kFS);
2950     GLint positionLocation = glGetAttribLocation(program, "a_position");
2951     GLint colorLocation    = glGetUniformLocation(program, "u_color");
2952     ASSERT_GL_NO_ERROR();
2953 
2954     // Create a program that DOES fetch from the framebuffer
2955     GLProgram fetchProgram;
2956     fetchProgram.makeRaster(kVS, kFetchFS);
2957     GLint fetchPositionLocation = glGetAttribLocation(fetchProgram, "a_position");
2958     GLint fetchColorLocation    = glGetUniformLocation(fetchProgram, "u_color");
2959     ASSERT_GL_NO_ERROR();
2960 
2961     // Create an empty framebuffer to use without fetch
2962     GLFramebuffer framebuffer1;
2963     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
2964     std::vector<GLColor> clearColor(kViewportWidth * kViewportHeight, GLColor::transparentBlack);
2965     GLTexture colorBufferTex1;
2966     glBindTexture(GL_TEXTURE_2D, colorBufferTex1);
2967     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
2968                  GL_UNSIGNED_BYTE, clearColor.data());
2969     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex1, 0);
2970     ASSERT_GL_NO_ERROR();
2971 
2972     // Draw to it with green, without using fetch, overwriting any contents
2973     glUseProgram(program);
2974     glUniform4fv(colorLocation, 1, GLColor::green.toNormalizedVector().data());
2975     render(positionLocation, false);
2976     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
2977     ASSERT_GL_NO_ERROR();
2978 
2979     // Create another framebuffer to use WITH fetch, and initialize it with blue
2980     GLFramebuffer framebuffer2;
2981     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2);
2982     std::vector<GLColor> blueColor(kViewportWidth * kViewportHeight, GLColor::blue);
2983     GLTexture colorBufferTex2;
2984     glBindTexture(GL_TEXTURE_2D, colorBufferTex2);
2985     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
2986                  GL_UNSIGNED_BYTE, blueColor.data());
2987     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex2, 0);
2988     ASSERT_GL_NO_ERROR();
2989 
2990     // Draw once with red, fetching blue from the framebuffer, adding it together
2991     glUseProgram(fetchProgram);
2992     glUniform4fv(fetchColorLocation, 1, GLColor::red.toNormalizedVector().data());
2993     render(fetchPositionLocation, false);
2994     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
2995     ASSERT_GL_NO_ERROR();
2996 
2997     // Now use the same program (WITH fetch) and render to the other framebuffer that was NOT used
2998     // with fetch. This verifies the framebuffer state is appropriately updated to match the
2999     // program.
3000     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
3001     render(fetchPositionLocation, false);
3002     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
3003     ASSERT_GL_NO_ERROR();
3004 }
3005 
3006 // Verify that switching between single sampled framebuffer fetch and multi sampled framebuffer
3007 // fetch works fine
TEST_P(FramebufferFetchES31,SingleSampledMultiSampledMixedTest)3008 TEST_P(FramebufferFetchES31, SingleSampledMultiSampledMixedTest)
3009 {
3010     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
3011     setWhichExtension(COHERENT);
3012 
3013     // Create a program that fetches from the framebuffer
3014     GLProgram fetchProgram;
3015     fetchProgram.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
3016     GLint positionLocation = glGetAttribLocation(fetchProgram, "a_position");
3017     GLint colorLocation    = glGetUniformLocation(fetchProgram, "u_color");
3018     ASSERT_GL_NO_ERROR();
3019 
3020     // Create two single sampled framebuffer
3021     GLRenderbuffer singleSampledRenderbuffer1;
3022     glBindRenderbuffer(GL_RENDERBUFFER, singleSampledRenderbuffer1);
3023     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kViewportWidth, kViewportHeight);
3024     GLFramebuffer singleSampledFramebuffer1;
3025     glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer1);
3026     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
3027                               singleSampledRenderbuffer1);
3028 
3029     GLRenderbuffer singleSampledRenderbuffer2;
3030     glBindRenderbuffer(GL_RENDERBUFFER, singleSampledRenderbuffer2);
3031     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kViewportWidth, kViewportHeight);
3032     GLFramebuffer singleSampledFramebuffer2;
3033     glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer2);
3034     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
3035                               singleSampledRenderbuffer2);
3036 
3037     // Create one multi sampled framebuffer
3038     GLRenderbuffer multiSampledRenderbuffer;
3039     glBindRenderbuffer(GL_RENDERBUFFER, multiSampledRenderbuffer);
3040     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, kViewportWidth, kViewportHeight);
3041     GLFramebuffer multiSampledFramebuffer;
3042     glBindFramebuffer(GL_FRAMEBUFFER, multiSampledFramebuffer);
3043     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
3044                               multiSampledRenderbuffer);
3045 
3046     // Create a singlesampled render buffer for blit and read
3047     GLRenderbuffer resolvedRbo;
3048     glBindRenderbuffer(GL_RENDERBUFFER, resolvedRbo);
3049     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kViewportWidth, kViewportHeight);
3050     GLFramebuffer resolvedFbo;
3051     glBindFramebuffer(GL_FRAMEBUFFER, resolvedFbo);
3052     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, resolvedRbo);
3053 
3054     // Clear three Framebuffers with different colors
3055     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
3056     glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer1);
3057     glClear(GL_COLOR_BUFFER_BIT);
3058     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::black);
3059 
3060     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
3061     glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer2);
3062     glClear(GL_COLOR_BUFFER_BIT);
3063     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
3064 
3065     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
3066     glBindFramebuffer(GL_FRAMEBUFFER, multiSampledFramebuffer);
3067     glClear(GL_COLOR_BUFFER_BIT);
3068     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolvedFbo);
3069     glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth, kViewportHeight,
3070                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
3071     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolvedFbo);
3072     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
3073 
3074     // Bind first single sampled framebuffer, draw once with red, fetching black from the
3075     // framebuffer
3076     glUseProgram(fetchProgram);
3077     glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
3078     glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer1);
3079     render(positionLocation, false);
3080     ASSERT_GL_NO_ERROR();
3081 
3082     // Bind the multi sampled framebuffer, draw once with red, fetching green from the framebuffer
3083     glBindFramebuffer(GL_FRAMEBUFFER, multiSampledFramebuffer);
3084     render(positionLocation, false);
3085     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolvedFbo);
3086     glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth, kViewportHeight,
3087                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
3088     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolvedFbo);
3089     ASSERT_GL_NO_ERROR();
3090 
3091     // Bind the single sampled framebuffer, draw once with red, fetching blue from the framebuffer
3092     glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
3093     glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer2);
3094     render(positionLocation, false);
3095     ASSERT_GL_NO_ERROR();
3096 
3097     // Verify the rendering result on all three framebuffers
3098 
3099     // Verify the last framebuffer being drawn: singleSampledFramebuffer2
3100     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
3101 
3102     // Verify the second last framebuffer being drawn: multisampledFramebuffer
3103     glBindFramebuffer(GL_READ_FRAMEBUFFER, multiSampledFramebuffer);
3104     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolvedFbo);
3105     glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth, kViewportHeight,
3106                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
3107     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolvedFbo);
3108     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
3109 
3110     // Verify the first framebuffer being drawn: singleSampledFramebuffer1
3111     glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer1);
3112     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
3113 }
3114 
3115 // Verify that calling glFramebufferFetchBarrierEXT without an open render pass is ok.
TEST_P(FramebufferFetchES31,BarrierBeforeDraw)3116 TEST_P(FramebufferFetchES31, BarrierBeforeDraw)
3117 {
3118     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch") ||
3119                        !IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
3120 
3121     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
3122 
3123     glFramebufferFetchBarrierEXT();
3124     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
3125 
3126     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3127 }
3128 
3129 // Test ARM extension with gl_LastFragColorARM
TEST_P(FramebufferFetchES31,BasicLastFragData_ARM)3130 TEST_P(FramebufferFetchES31, BasicLastFragData_ARM)
3131 {
3132     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3133     setWhichExtension(ARM);
3134 
3135     GLProgram program;
3136     program.makeRaster(k100VS, getFragmentShader(GLSL100));
3137     glUseProgram(program);
3138     ASSERT_GL_NO_ERROR();
3139 
3140     BasicTest(program);
3141 }
3142 
3143 // Test ARM extension with multiple draw
TEST_P(FramebufferFetchES31,MultipleDraw_ARM)3144 TEST_P(FramebufferFetchES31, MultipleDraw_ARM)
3145 {
3146     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3147     setWhichExtension(ARM);
3148 
3149     GLProgram program;
3150     program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
3151     glUseProgram(program);
3152     ASSERT_GL_NO_ERROR();
3153 
3154     MultipleDrawTest(program);
3155 }
3156 
3157 // Testing ARM extension with the order of non-fetch program and fetch program
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetch_ARM)3158 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetch_ARM)
3159 {
3160     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3161     setWhichExtension(ARM);
3162 
3163     GLProgram programNonFetch, programFetch;
3164     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
3165     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
3166     ASSERT_GL_NO_ERROR();
3167 
3168     DrawNonFetchDrawFetchTest(programNonFetch, programFetch);
3169 }
3170 
3171 // Testing ARM extension with the order of fetch program and non-fetch program
TEST_P(FramebufferFetchES31,DrawFetchDrawNonFetch_ARM)3172 TEST_P(FramebufferFetchES31, DrawFetchDrawNonFetch_ARM)
3173 {
3174     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3175     setWhichExtension(ARM);
3176 
3177     GLProgram programNonFetch, programFetch;
3178     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
3179     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
3180     ASSERT_GL_NO_ERROR();
3181 
3182     DrawFetchDrawNonFetchTest(programNonFetch, programFetch);
3183 }
3184 
3185 // Testing ARM extension with framebuffer fetch read in combination with color attachment mask
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchInStorageBuffer_ARM)3186 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchInStorageBuffer_ARM)
3187 {
3188     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3189     setWhichExtension(ARM);
3190 
3191     GLint maxFragmentShaderStorageBlocks = 0;
3192     glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
3193     ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks == 0);
3194 
3195     GLProgram programNonFetch, programFetch;
3196     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
3197     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER));
3198     ASSERT_GL_NO_ERROR();
3199 
3200     DrawNonFetchDrawFetchInStorageBufferTest(programNonFetch, programFetch,
3201                                              StorageBufferTestPostFetchAction::Nothing);
3202 }
3203 
3204 // Testing ARM extension with framebuffer fetch read in combination with color attachment mask
3205 // and clear
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchInStorageBufferThenClear_ARM)3206 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchInStorageBufferThenClear_ARM)
3207 {
3208     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3209     setWhichExtension(ARM);
3210 
3211     GLint maxFragmentShaderStorageBlocks = 0;
3212     glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
3213     ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks == 0);
3214 
3215     GLProgram programNonFetch, programFetch;
3216     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
3217     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER));
3218     ASSERT_GL_NO_ERROR();
3219 
3220     DrawNonFetchDrawFetchInStorageBufferTest(programNonFetch, programFetch,
3221                                              StorageBufferTestPostFetchAction::Clear);
3222 }
3223 
3224 // Testing ARM extension with program pipeline
TEST_P(FramebufferFetchES31,ProgramPipeline_ARM)3225 TEST_P(FramebufferFetchES31, ProgramPipeline_ARM)
3226 {
3227     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3228     setWhichExtension(ARM);
3229 
3230     ProgramPipelineTest(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT),
3231                         getFragmentShader(GLSL310_1ATTACHMENT));
3232 }
3233 
3234 // Verify we can use the default framebuffer
3235 // http://anglebug.com/42265386
TEST_P(FramebufferFetchES31,DefaultFramebufferTest_ARM)3236 TEST_P(FramebufferFetchES31, DefaultFramebufferTest_ARM)
3237 {
3238     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3239 
3240     constexpr char kVS[] = R"(#version 300 es
3241 in highp vec4 a_position;
3242 
3243 void main (void)
3244 {
3245     gl_Position = a_position;
3246 })";
3247 
3248     constexpr char kFS[] = R"(#version 300 es
3249 #extension GL_ARM_shader_framebuffer_fetch : require
3250 layout(location = 0) out highp vec4 o_color;
3251 
3252 uniform highp vec4 u_color;
3253 void main (void)
3254 {
3255     o_color = u_color + gl_LastFragColorARM;
3256 })";
3257 
3258     GLProgram program;
3259     program.makeRaster(kVS, kFS);
3260     glUseProgram(program);
3261 
3262     ASSERT_GL_NO_ERROR();
3263 
3264     // Ensure that we're rendering to the default framebuffer
3265     glBindFramebuffer(GL_FRAMEBUFFER, 0);
3266 
3267     // Start with a clear buffer
3268     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
3269     glClear(GL_COLOR_BUFFER_BIT);
3270 
3271     GLint positionLocation = glGetAttribLocation(program, "a_position");
3272     GLint colorLocation    = glGetUniformLocation(program, "u_color");
3273 
3274     // Draw once with red
3275     glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
3276     render(positionLocation, GL_FALSE);
3277     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
3278     ASSERT_GL_NO_ERROR();
3279 
3280     // Draw again with blue, adding it to the existing red, ending up with magenta
3281     glUniform4fv(colorLocation, 1, GLColor::blue.toNormalizedVector().data());
3282     render(positionLocation, GL_FALSE);
3283     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
3284     ASSERT_GL_NO_ERROR();
3285 }
3286 
3287 // Verify we can redeclare gl_LastFragColorARM with a new precision
3288 // http://anglebug.com/42265386
TEST_P(FramebufferFetchES31,NondefaultPrecisionTest_ARM)3289 TEST_P(FramebufferFetchES31, NondefaultPrecisionTest_ARM)
3290 {
3291     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3292 
3293     constexpr char kVS[] = R"(#version 300 es
3294 in highp vec4 a_position;
3295 
3296 void main (void)
3297 {
3298     gl_Position = a_position;
3299 })";
3300 
3301     constexpr char kFS[] = R"(#version 300 es
3302 #extension GL_ARM_shader_framebuffer_fetch : require
3303 highp vec4 gl_LastFragColorARM;
3304 layout(location = 0) out highp vec4 o_color;
3305 
3306 uniform highp vec4 u_color;
3307 void main (void)
3308 {
3309     o_color = u_color + gl_LastFragColorARM;
3310 })";
3311 
3312     GLProgram program;
3313     program.makeRaster(kVS, kFS);
3314     glUseProgram(program);
3315 
3316     ASSERT_GL_NO_ERROR();
3317 
3318     // Ensure that we're rendering to the default framebuffer
3319     glBindFramebuffer(GL_FRAMEBUFFER, 0);
3320 
3321     // Start with a clear buffer
3322     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
3323     glClear(GL_COLOR_BUFFER_BIT);
3324 
3325     GLint positionLocation = glGetAttribLocation(program, "a_position");
3326     GLint colorLocation    = glGetUniformLocation(program, "u_color");
3327 
3328     // Draw once with red
3329     glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
3330     render(positionLocation, GL_FALSE);
3331     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
3332     ASSERT_GL_NO_ERROR();
3333 
3334     // Draw again with blue, adding it to the existing red, ending up with magenta
3335     glUniform4fv(colorLocation, 1, GLColor::blue.toNormalizedVector().data());
3336     render(positionLocation, GL_FALSE);
3337     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
3338     ASSERT_GL_NO_ERROR();
3339 }
3340 
3341 // Verify we can render to the default framebuffer without fetch, then switch to a program
3342 // that does fetch.
3343 // http://anglebug.com/42265386
TEST_P(FramebufferFetchES31,DefaultFramebufferMixedProgramsTest_ARM)3344 TEST_P(FramebufferFetchES31, DefaultFramebufferMixedProgramsTest_ARM)
3345 {
3346     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3347 
3348     constexpr char kVS[] = R"(#version 300 es
3349 in highp vec4 a_position;
3350 
3351 void main (void)
3352 {
3353     gl_Position = a_position;
3354 })";
3355 
3356     constexpr char kFS[] = R"(#version 300 es
3357 layout(location = 0) out highp vec4 o_color;
3358 
3359 uniform highp vec4 u_color;
3360 void main (void)
3361 {
3362     o_color = u_color;
3363 })";
3364 
3365     constexpr char kFetchFS[] = R"(#version 300 es
3366 #extension GL_ARM_shader_framebuffer_fetch : require
3367 layout(location = 0) out highp vec4 o_color;
3368 
3369 uniform highp vec4 u_color;
3370 void main (void)
3371 {
3372     o_color = u_color + gl_LastFragColorARM;
3373 })";
3374 
3375     // Create a program that simply writes out a color, no fetching
3376     GLProgram program;
3377     program.makeRaster(kVS, kFS);
3378     glUseProgram(program);
3379 
3380     ASSERT_GL_NO_ERROR();
3381 
3382     // Ensure that we're rendering to the default framebuffer
3383     glBindFramebuffer(GL_FRAMEBUFFER, 0);
3384 
3385     // Start with a clear buffer
3386     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
3387     glClear(GL_COLOR_BUFFER_BIT);
3388 
3389     GLint positionLocation = glGetAttribLocation(program, "a_position");
3390     GLint colorLocation    = glGetUniformLocation(program, "u_color");
3391 
3392     // Draw once with red
3393     glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
3394     render(positionLocation, false);
3395     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
3396     ASSERT_GL_NO_ERROR();
3397 
3398     // Create another program that DOES fetch from the framebuffer
3399     GLProgram program2;
3400     program2.makeRaster(kVS, kFetchFS);
3401     glUseProgram(program2);
3402 
3403     GLint positionLocation2 = glGetAttribLocation(program2, "a_position");
3404     GLint colorLocation2    = glGetUniformLocation(program2, "u_color");
3405 
3406     // Draw again with blue, fetching red from the framebuffer, adding it together
3407     glUniform4fv(colorLocation2, 1, GLColor::blue.toNormalizedVector().data());
3408     render(positionLocation2, false);
3409     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
3410     ASSERT_GL_NO_ERROR();
3411 
3412     // Switch back to the non-fetched framebuffer, and render green
3413     glUseProgram(program);
3414     glUniform4fv(colorLocation, 1, GLColor::green.toNormalizedVector().data());
3415     render(positionLocation, false);
3416     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
3417     ASSERT_GL_NO_ERROR();
3418 }
3419 
3420 // Verify we can render to a framebuffer with fetch, then switch to another framebuffer (without
3421 // changing programs) http://anglebug.com/42265386
TEST_P(FramebufferFetchES31,FramebufferMixedFetchTest_ARM)3422 TEST_P(FramebufferFetchES31, FramebufferMixedFetchTest_ARM)
3423 {
3424     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3425 
3426     constexpr char kVS[] = R"(#version 300 es
3427 in highp vec4 a_position;
3428 
3429 void main (void)
3430 {
3431     gl_Position = a_position;
3432 })";
3433 
3434     constexpr char kFS[] = R"(#version 300 es
3435 layout(location = 0) out highp vec4 o_color;
3436 
3437 uniform highp vec4 u_color;
3438 void main (void)
3439 {
3440     o_color = u_color;
3441 })";
3442 
3443     constexpr char kFetchFS[] = R"(#version 300 es
3444 #extension GL_ARM_shader_framebuffer_fetch : require
3445 layout(location = 0) out highp vec4 o_color;
3446 
3447 uniform highp vec4 u_color;
3448 void main (void)
3449 {
3450     o_color = u_color + gl_LastFragColorARM;
3451 })";
3452 
3453     // Create a program that simply writes out a color, no fetching
3454     GLProgram program;
3455     program.makeRaster(kVS, kFS);
3456     GLint positionLocation = glGetAttribLocation(program, "a_position");
3457     GLint colorLocation    = glGetUniformLocation(program, "u_color");
3458     ASSERT_GL_NO_ERROR();
3459 
3460     // Create a program that DOES fetch from the framebuffer
3461     GLProgram fetchProgram;
3462     fetchProgram.makeRaster(kVS, kFetchFS);
3463     GLint fetchPositionLocation = glGetAttribLocation(fetchProgram, "a_position");
3464     GLint fetchColorLocation    = glGetUniformLocation(fetchProgram, "u_color");
3465     ASSERT_GL_NO_ERROR();
3466 
3467     // Create an empty framebuffer to use without fetch
3468     GLFramebuffer framebuffer1;
3469     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
3470     std::vector<GLColor> clearColor(kViewportWidth * kViewportHeight, GLColor::transparentBlack);
3471     GLTexture colorBufferTex1;
3472     glBindTexture(GL_TEXTURE_2D, colorBufferTex1);
3473     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
3474                  GL_UNSIGNED_BYTE, clearColor.data());
3475     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex1, 0);
3476     ASSERT_GL_NO_ERROR();
3477 
3478     // Draw to it with green, without using fetch, overwriting any contents
3479     glUseProgram(program);
3480     glUniform4fv(colorLocation, 1, GLColor::green.toNormalizedVector().data());
3481     render(positionLocation, false);
3482     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
3483     ASSERT_GL_NO_ERROR();
3484 
3485     // Create another framebuffer to use WITH fetch, and initialize it with blue
3486     GLFramebuffer framebuffer2;
3487     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2);
3488     std::vector<GLColor> blueColor(kViewportWidth * kViewportHeight, GLColor::blue);
3489     GLTexture colorBufferTex2;
3490     glBindTexture(GL_TEXTURE_2D, colorBufferTex2);
3491     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
3492                  GL_UNSIGNED_BYTE, blueColor.data());
3493     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex2, 0);
3494     ASSERT_GL_NO_ERROR();
3495 
3496     // Draw once with red, fetching blue from the framebuffer, adding it together
3497     glUseProgram(fetchProgram);
3498     glUniform4fv(fetchColorLocation, 1, GLColor::red.toNormalizedVector().data());
3499     render(fetchPositionLocation, false);
3500     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
3501     ASSERT_GL_NO_ERROR();
3502 
3503     // Now use the same program (WITH fetch) and render to the other framebuffer that was NOT used
3504     // with fetch. This verifies the framebuffer state is appropriately updated to match the
3505     // program.
3506     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
3507     render(fetchPositionLocation, false);
3508     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
3509     ASSERT_GL_NO_ERROR();
3510 }
3511 
3512 // Verify that switching between single sampled framebuffer fetch and multi sampled framebuffer
3513 // fetch works fine
TEST_P(FramebufferFetchES31,SingleSampledMultiSampledMixedTest_ARM)3514 TEST_P(FramebufferFetchES31, SingleSampledMultiSampledMixedTest_ARM)
3515 {
3516     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3517     setWhichExtension(ARM);
3518 
3519     // Create a program that fetches from the framebuffer
3520     GLProgram fetchProgram;
3521     fetchProgram.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
3522     GLint positionLocation = glGetAttribLocation(fetchProgram, "a_position");
3523     GLint colorLocation    = glGetUniformLocation(fetchProgram, "u_color");
3524     ASSERT_GL_NO_ERROR();
3525 
3526     // Create two single sampled framebuffer
3527     GLRenderbuffer singleSampledRenderbuffer1;
3528     glBindRenderbuffer(GL_RENDERBUFFER, singleSampledRenderbuffer1);
3529     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kViewportWidth, kViewportHeight);
3530     GLFramebuffer singleSampledFramebuffer1;
3531     glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer1);
3532     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
3533                               singleSampledRenderbuffer1);
3534 
3535     GLRenderbuffer singleSampledRenderbuffer2;
3536     glBindRenderbuffer(GL_RENDERBUFFER, singleSampledRenderbuffer2);
3537     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kViewportWidth, kViewportHeight);
3538     GLFramebuffer singleSampledFramebuffer2;
3539     glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer2);
3540     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
3541                               singleSampledRenderbuffer2);
3542 
3543     // Create one multi sampled framebuffer
3544     GLRenderbuffer multiSampledRenderbuffer;
3545     glBindRenderbuffer(GL_RENDERBUFFER, multiSampledRenderbuffer);
3546     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, kViewportWidth, kViewportHeight);
3547     GLFramebuffer multiSampledFramebuffer;
3548     glBindFramebuffer(GL_FRAMEBUFFER, multiSampledFramebuffer);
3549     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
3550                               multiSampledRenderbuffer);
3551 
3552     // Create a singlesampled render buffer for blit and read
3553     GLRenderbuffer resolvedRbo;
3554     glBindRenderbuffer(GL_RENDERBUFFER, resolvedRbo);
3555     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kViewportWidth, kViewportHeight);
3556     GLFramebuffer resolvedFbo;
3557     glBindFramebuffer(GL_FRAMEBUFFER, resolvedFbo);
3558     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, resolvedRbo);
3559 
3560     // Clear three Framebuffers with different colors
3561     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
3562     glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer1);
3563     glClear(GL_COLOR_BUFFER_BIT);
3564     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::black);
3565 
3566     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
3567     glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer2);
3568     glClear(GL_COLOR_BUFFER_BIT);
3569     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
3570 
3571     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
3572     glBindFramebuffer(GL_FRAMEBUFFER, multiSampledFramebuffer);
3573     glClear(GL_COLOR_BUFFER_BIT);
3574     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolvedFbo);
3575     glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth, kViewportHeight,
3576                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
3577     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolvedFbo);
3578     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
3579 
3580     // Bind first single sampled framebuffer, draw once with red, fetching black from the
3581     // framebuffer
3582     glUseProgram(fetchProgram);
3583     glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
3584     glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer1);
3585     render(positionLocation, false);
3586     ASSERT_GL_NO_ERROR();
3587 
3588     // Bind the multi sampled framebuffer, draw once with red, fetching green from the framebuffer
3589     glBindFramebuffer(GL_FRAMEBUFFER, multiSampledFramebuffer);
3590     render(positionLocation, false);
3591     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolvedFbo);
3592     glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth, kViewportHeight,
3593                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
3594     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolvedFbo);
3595     ASSERT_GL_NO_ERROR();
3596 
3597     // Bind the single sampled framebuffer, draw once with red, fetching blue from the framebuffer
3598     glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
3599     glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer2);
3600     render(positionLocation, false);
3601     ASSERT_GL_NO_ERROR();
3602 
3603     // Verify the rendering result on all three framebuffers
3604 
3605     // Verify the last framebuffer being drawn: singleSampledFramebuffer2
3606     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
3607 
3608     // Verify the second last framebuffer being drawn: multisampledFramebuffer
3609     glBindFramebuffer(GL_READ_FRAMEBUFFER, multiSampledFramebuffer);
3610     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolvedFbo);
3611     glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth, kViewportHeight,
3612                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
3613     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolvedFbo);
3614     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
3615 
3616     // Verify the first framebuffer being drawn: singleSampledFramebuffer1
3617     glBindFramebuffer(GL_FRAMEBUFFER, singleSampledFramebuffer1);
3618     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
3619 }
3620 
3621 // Test ARM extension with new tokens
TEST_P(FramebufferFetchES31,BasicTokenUsage_ARM)3622 TEST_P(FramebufferFetchES31, BasicTokenUsage_ARM)
3623 {
3624     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3625 
3626     // GL_FETCH_PER_SAMPLE_ARM can be set and queried
3627     GLboolean isFetchPerSampleEnabledBool = false;
3628     GLint isFetchPerSampleEnabledInt      = -1;
3629     GLfloat isFetchPerSampleEnabledFloat  = -1.0f;
3630 
3631     // Set GL_FETCH_PER_SAMPLE_ARM true
3632     glEnable(GL_FETCH_PER_SAMPLE_ARM);
3633     EXPECT_GL_TRUE(glIsEnabled(GL_FETCH_PER_SAMPLE_ARM));
3634 
3635     // Ensure it returns true
3636     glGetBooleanv(GL_FETCH_PER_SAMPLE_ARM, &isFetchPerSampleEnabledBool);
3637     EXPECT_GL_TRUE(isFetchPerSampleEnabledBool);
3638     glGetIntegerv(GL_FETCH_PER_SAMPLE_ARM, &isFetchPerSampleEnabledInt);
3639     ASSERT_EQ(isFetchPerSampleEnabledInt, 1);
3640     glGetFloatv(GL_FETCH_PER_SAMPLE_ARM, &isFetchPerSampleEnabledFloat);
3641     ASSERT_EQ(isFetchPerSampleEnabledFloat, 1.0);
3642 
3643     // Set GL_FETCH_PER_SAMPLE_ARM false
3644     glDisable(GL_FETCH_PER_SAMPLE_ARM);
3645     EXPECT_GL_FALSE(glIsEnabled(GL_FETCH_PER_SAMPLE_ARM));
3646 
3647     // Ensure it returns false
3648     glGetBooleanv(GL_FETCH_PER_SAMPLE_ARM, &isFetchPerSampleEnabledBool);
3649     EXPECT_GL_FALSE(isFetchPerSampleEnabledBool);
3650     glGetIntegerv(GL_FETCH_PER_SAMPLE_ARM, &isFetchPerSampleEnabledInt);
3651     ASSERT_EQ(isFetchPerSampleEnabledInt, 0);
3652     glGetFloatv(GL_FETCH_PER_SAMPLE_ARM, &isFetchPerSampleEnabledFloat);
3653     ASSERT_EQ(isFetchPerSampleEnabledFloat, 0.0);
3654 
3655     ASSERT_GL_NO_ERROR();
3656 
3657     // GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM can only be queried
3658     GLboolean isFragmentShaderFramebufferFetchMrtBool = false;
3659     GLint isFragmentShaderFramebufferFetchMrtInt      = -1;
3660     GLfloat isFragmentShaderFramebufferFetchMrtFloat  = -1.0f;
3661 
3662     // Try to set it, ensure we can't
3663     glEnable(GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM);
3664     EXPECT_GL_ERROR(GL_INVALID_ENUM);
3665     glDisable(GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM);
3666     EXPECT_GL_ERROR(GL_INVALID_ENUM);
3667 
3668     // Ensure we can't query its state with isEnabled
3669     // Commented out due to http://anglebug.com/42266484
3670     // glIsEnabled(GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM);
3671     // EXPECT_GL_ERROR(GL_INVALID_ENUM);
3672 
3673     // Ensure GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM returns consistent values
3674     glGetBooleanv(GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM,
3675                   &isFragmentShaderFramebufferFetchMrtBool);
3676     glGetIntegerv(GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM,
3677                   &isFragmentShaderFramebufferFetchMrtInt);
3678     ASSERT_EQ(isFragmentShaderFramebufferFetchMrtInt,
3679               static_cast<GLint>(isFragmentShaderFramebufferFetchMrtBool));
3680     glGetFloatv(GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM,
3681                 &isFragmentShaderFramebufferFetchMrtFloat);
3682     ASSERT_EQ(isFragmentShaderFramebufferFetchMrtFloat,
3683               static_cast<GLfloat>(isFragmentShaderFramebufferFetchMrtBool));
3684 
3685     ASSERT_GL_NO_ERROR();
3686 }
3687 
3688 // Test that depth/stencil framebuffer fetch with early_fragment_tests is disallowed
TEST_P(FramebufferFetchES31,NoEarlyFragmentTestsWithDepthStencil)3689 TEST_P(FramebufferFetchES31, NoEarlyFragmentTestsWithDepthStencil)
3690 {
3691     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
3692 
3693     const char kDepthFS[] = R"(#version 310 es
3694 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
3695 
3696 layout(early_fragment_tests) in;
3697 highp out vec4 color;
3698 
3699 void main()
3700 {
3701     color = vec4(gl_LastFragDepthARM, 0, 0, 1);
3702 })";
3703 
3704     GLuint shader = CompileShader(GL_FRAGMENT_SHADER, kDepthFS);
3705     EXPECT_EQ(0u, shader);
3706 
3707     const char kStencilFS[] = R"(#version 310 es
3708 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
3709 
3710 layout(early_fragment_tests) in;
3711 highp out vec4 color;
3712 
3713 void main()
3714 {
3715     bool correct = gl_LastFragStencilARM == 0xE5;
3716     color = vec4(correct, 0, 0, 1);
3717 })";
3718 
3719     shader = CompileShader(GL_FRAGMENT_SHADER, kStencilFS);
3720     EXPECT_EQ(0u, shader);
3721 }
3722 
3723 // Test using both extensions simultaneously with gl_LastFragData and gl_LastFragColorARM
TEST_P(FramebufferFetchES31,BasicLastFragData_Both)3724 TEST_P(FramebufferFetchES31, BasicLastFragData_Both)
3725 {
3726     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3727     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
3728     setWhichExtension(BOTH);
3729 
3730     GLProgram program;
3731     program.makeRaster(k100VS, getFragmentShader(GLSL100));
3732     glUseProgram(program);
3733     ASSERT_GL_NO_ERROR();
3734 
3735     BasicTest(program);
3736 }
3737 
3738 // Test using both extentions simultaneously with multiple draw
TEST_P(FramebufferFetchES31,MultipleDraw_Both)3739 TEST_P(FramebufferFetchES31, MultipleDraw_Both)
3740 {
3741     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3742     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
3743     setWhichExtension(BOTH);
3744 
3745     GLProgram program;
3746     program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
3747     glUseProgram(program);
3748     ASSERT_GL_NO_ERROR();
3749 
3750     MultipleDrawTest(program);
3751 }
3752 
3753 // Testing using both extentions simultaneously with the order of non-fetch program and fetch
3754 // program
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetch_Both)3755 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetch_Both)
3756 {
3757     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3758     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
3759     setWhichExtension(BOTH);
3760 
3761     GLProgram programNonFetch, programFetch;
3762     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
3763     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
3764     ASSERT_GL_NO_ERROR();
3765 
3766     DrawNonFetchDrawFetchTest(programNonFetch, programFetch);
3767 }
3768 
3769 // Testing using both extentions simultaneously with the order of fetch program and non-fetch
3770 // program
TEST_P(FramebufferFetchES31,DrawFetchDrawNonFetch_Both)3771 TEST_P(FramebufferFetchES31, DrawFetchDrawNonFetch_Both)
3772 {
3773     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3774     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
3775     setWhichExtension(BOTH);
3776 
3777     GLProgram programNonFetch, programFetch;
3778     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
3779     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
3780     ASSERT_GL_NO_ERROR();
3781 
3782     DrawFetchDrawNonFetchTest(programNonFetch, programFetch);
3783 }
3784 
3785 // Testing using both extentions simultaneously with multiple render target, using gl_FragData with
3786 // constant indices
TEST_P(FramebufferFetchES31,MultipleRenderTarget_Both_FragData)3787 TEST_P(FramebufferFetchES31, MultipleRenderTarget_Both_FragData)
3788 {
3789     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3790     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
3791     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_draw_buffers"));
3792 
3793     GLboolean isFragmentShaderFramebufferFetchMrt = false;
3794     glGetBooleanv(GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM,
3795                   &isFragmentShaderFramebufferFetchMrt);
3796     ANGLE_SKIP_TEST_IF(!isFragmentShaderFramebufferFetchMrt);
3797 
3798     setWhichExtension(BOTH);
3799 
3800     GLProgram program;
3801     program.makeRaster(k100VS, getFragmentShader(GLSL100_4ATTACHMENT));
3802     glUseProgram(program);
3803     ASSERT_GL_NO_ERROR();
3804 
3805     MultipleRenderTargetTest(program, GLSL100_4ATTACHMENT);
3806 }
3807 
3808 // Testing using both extentions simultaneously with multiple render target, using gl_FragData with
3809 // complex expressions
TEST_P(FramebufferFetchES31,MultipleRenderTarget_Both_FragData_Complex)3810 TEST_P(FramebufferFetchES31, MultipleRenderTarget_Both_FragData_Complex)
3811 {
3812     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3813     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
3814     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_draw_buffers"));
3815 
3816     GLboolean isFragmentShaderFramebufferFetchMrt = false;
3817     glGetBooleanv(GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM,
3818                   &isFragmentShaderFramebufferFetchMrt);
3819     ANGLE_SKIP_TEST_IF(!isFragmentShaderFramebufferFetchMrt);
3820 
3821     setWhichExtension(BOTH);
3822 
3823     GLProgram program;
3824     program.makeRaster(k100VS, getFragmentShader(GLSL100_COMPLEX));
3825     glUseProgram(program);
3826     ASSERT_GL_NO_ERROR();
3827 
3828     MultipleRenderTargetTest(program, GLSL100_COMPLEX);
3829 }
3830 
3831 // Testing using both extentions simultaneously with multiple render target, using inouts with
3832 // complex expressions
TEST_P(FramebufferFetchES31,MultipleRenderTarget_Both_Complex)3833 TEST_P(FramebufferFetchES31, MultipleRenderTarget_Both_Complex)
3834 {
3835     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch"));
3836     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
3837 
3838     GLboolean isFragmentShaderFramebufferFetchMrt = false;
3839     glGetBooleanv(GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM,
3840                   &isFragmentShaderFramebufferFetchMrt);
3841     ANGLE_SKIP_TEST_IF(!isFragmentShaderFramebufferFetchMrt);
3842 
3843     setWhichExtension(BOTH);
3844 
3845     GLProgram program;
3846     program.makeRaster(k310VS, getFragmentShader(GLSL310_COMPLEX));
3847     glUseProgram(program);
3848     ASSERT_GL_NO_ERROR();
3849 
3850     MultipleRenderTargetTest(program, GLSL310_COMPLEX);
3851 }
3852 
3853 // Test that using the maximum number of color attachments works.
TEST_P(FramebufferFetchES31,MaximumColorAttachments)3854 TEST_P(FramebufferFetchES31, MaximumColorAttachments)
3855 {
3856     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch") &&
3857                        !IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
3858     const WhichExtension whichExtension = chooseBetweenCoherentOrIncoherent();
3859 
3860     GLint maxDrawBuffers = 0;
3861     glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
3862 
3863     GLFramebuffer fbo;
3864     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3865 
3866     std::vector<GLTexture> color(maxDrawBuffers);
3867     std::vector<GLenum> buffers(maxDrawBuffers);
3868     for (GLint index = 0; index < maxDrawBuffers; ++index)
3869     {
3870         buffers[index] = GL_COLOR_ATTACHMENT0 + index;
3871 
3872         glBindTexture(GL_TEXTURE_2D, color[index]);
3873         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kViewportWidth, kViewportHeight);
3874         glFramebufferTexture2D(GL_FRAMEBUFFER, buffers[index], GL_TEXTURE_2D, color[index], 0);
3875     }
3876     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3877     ASSERT_GL_NO_ERROR();
3878 
3879     glDrawBuffers(maxDrawBuffers, buffers.data());
3880 
3881     // Create two programs, one to initialize the attachments and another to read back the contents
3882     // with framebuffer fetch and blend.
3883     std::ostringstream initFs;
3884     initFs << "#version 310 es\n";
3885     for (GLint index = 0; index < maxDrawBuffers; ++index)
3886     {
3887         initFs << "layout(location=" << index << ") out highp vec4 color" << index << ";\n";
3888     }
3889 
3890     std::ostringstream fetchFs;
3891     fetchFs << makeShaderPreamble(whichExtension, nullptr, maxDrawBuffers);
3892 
3893     initFs << R"(void main()
3894 {
3895 )";
3896     fetchFs << R"(void main()
3897 {
3898 )";
3899 
3900     for (GLint index = 0; index < maxDrawBuffers; ++index)
3901     {
3902         initFs << "  color" << index << " = vec4(" << ((index % 5) / 8.0) << ", "
3903                << ((index % 4) / 6.0) << ", " << ((index % 3) / 4.0) << ", " << ((index % 2) / 2.0)
3904                << ");\n";
3905 
3906         fetchFs << "  color" << index << " += vec4(" << (((index + 1) % 2) / 2.0) << ", "
3907                 << (((index + 1) % 3) / 4.0) << ", " << (((index + 1) % 4) / 6.0) << ", "
3908                 << (((index + 1) % 5) / 8.0) << ");\n";
3909     }
3910 
3911     initFs << "}\n";
3912     fetchFs << "}\n";
3913 
3914     ANGLE_GL_PROGRAM(init, essl31_shaders::vs::Passthrough(), initFs.str().c_str());
3915     ANGLE_GL_PROGRAM(fetch, essl31_shaders::vs::Passthrough(), fetchFs.str().c_str());
3916 
3917     drawQuad(init, essl31_shaders::PositionAttrib(), 0.0f);
3918     if (whichExtension == NON_COHERENT)
3919     {
3920         glFramebufferFetchBarrierEXT();
3921     }
3922     drawQuad(fetch, essl31_shaders::PositionAttrib(), 0.0f);
3923 
3924     for (GLint index = 0; index < maxDrawBuffers; ++index)
3925     {
3926         glReadBuffer(buffers[index]);
3927 
3928         uint32_t expectR = (255 * (index % 5) + 4) / 8;
3929         uint32_t expectG = (255 * (index % 4) + 3) / 6;
3930         uint32_t expectB = (255 * (index % 3) + 2) / 4;
3931         uint32_t expectA = (255 * (index % 2) + 1) / 2;
3932 
3933         expectR += (255 * ((index + 1) % 2) + 1) / 2;
3934         expectG += (255 * ((index + 1) % 3) + 2) / 4;
3935         expectB += (255 * ((index + 1) % 4) + 3) / 6;
3936         expectA += (255 * ((index + 1) % 5) + 4) / 8;
3937 
3938         EXPECT_PIXEL_NEAR(0, 0, expectR, expectG, expectB, expectA, 2);
3939     }
3940 
3941     ASSERT_GL_NO_ERROR();
3942 }
3943 
3944 // Test that depth framebuffer fetch works.
TEST_P(FramebufferFetchES31,Depth)3945 TEST_P(FramebufferFetchES31, Depth)
3946 {
3947     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
3948 
3949     const char kFS[] = R"(#version 310 es
3950 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
3951 
3952 highp out vec4 color;
3953 
3954 void main()
3955 {
3956     color = vec4(gl_LastFragDepthARM, 0, 0, 1);
3957 })";
3958 
3959     GLRenderbuffer color, depth;
3960     GLFramebuffer fbo;
3961 
3962     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3963 
3964     glBindRenderbuffer(GL_RENDERBUFFER, color);
3965     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kViewportWidth, kViewportHeight);
3966     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color);
3967 
3968     glBindRenderbuffer(GL_RENDERBUFFER, depth);
3969     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, kViewportWidth, kViewportHeight);
3970     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
3971 
3972     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3973     ASSERT_GL_NO_ERROR();
3974 
3975     glClearDepthf(0.4f);
3976     glClear(GL_DEPTH_BUFFER_BIT);
3977 
3978     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Passthrough(), kFS);
3979     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
3980 
3981     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor(102, 0, 0, 255));
3982     ASSERT_GL_NO_ERROR();
3983 }
3984 
3985 // Test that stencil framebuffer fetch works.
TEST_P(FramebufferFetchES31,Stencil)3986 TEST_P(FramebufferFetchES31, Stencil)
3987 {
3988     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
3989 
3990     const char kFS[] = R"(#version 310 es
3991 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
3992 
3993 highp out vec4 color;
3994 
3995 void main()
3996 {
3997     bool correct = gl_LastFragStencilARM == 0xE5;
3998     color = vec4(correct, 0, 0, 1);
3999 })";
4000 
4001     GLRenderbuffer color, stencil;
4002     GLFramebuffer fbo;
4003 
4004     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4005 
4006     glBindRenderbuffer(GL_RENDERBUFFER, color);
4007     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kViewportWidth, kViewportHeight);
4008     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color);
4009 
4010     glBindRenderbuffer(GL_RENDERBUFFER, stencil);
4011     glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kViewportWidth, kViewportHeight);
4012     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil);
4013 
4014     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4015     ASSERT_GL_NO_ERROR();
4016 
4017     glClearStencil(0xE5);
4018     glClear(GL_STENCIL_BUFFER_BIT);
4019 
4020     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Passthrough(), kFS);
4021     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
4022 
4023     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor::red);
4024     ASSERT_GL_NO_ERROR();
4025 }
4026 
4027 // Test that depth and stencil framebuffer fetch work simultaneously and with the built-ins
4028 // redeclared in the shader.
TEST_P(FramebufferFetchES31,DepthStencil)4029 TEST_P(FramebufferFetchES31, DepthStencil)
4030 {
4031     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4032 
4033     const char kFS[] = R"(#version 310 es
4034 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
4035 
4036 highp out vec4 color;
4037 
4038 highp float gl_LastFragDepthARM;
4039 highp int gl_LastFragStencilARM;
4040 
4041 void main()
4042 {
4043     bool correct = gl_LastFragStencilARM == 0x3C;
4044     color = vec4(correct, gl_LastFragDepthARM, 0, 1);
4045 })";
4046 
4047     GLRenderbuffer color, depthStencil;
4048     GLFramebuffer fbo;
4049     createFramebufferWithDepthStencil(&color, &depthStencil, &fbo);
4050 
4051     glClearDepthf(0.8f);
4052     glClearStencil(0x3C);
4053     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4054 
4055     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Passthrough(), kFS);
4056     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
4057 
4058     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor(255, 204, 0, 255));
4059     ASSERT_GL_NO_ERROR();
4060 }
4061 
4062 // Test that depth and stencil framebuffer fetch works with MSAA.
TEST_P(FramebufferFetchES31,DepthStencilMultisampled)4063 TEST_P(FramebufferFetchES31, DepthStencilMultisampled)
4064 {
4065     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4066 
4067     const char kFS[] = R"(#version 310 es
4068 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
4069 
4070 highp out vec4 color;
4071 
4072 void main()
4073 {
4074     bool correct = gl_LastFragStencilARM == 0x3C;
4075     color = vec4(correct, gl_LastFragDepthARM, 0, 1);
4076 })";
4077 
4078     GLRenderbuffer color, depthStencil;
4079     GLFramebuffer fbo;
4080 
4081     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4082 
4083     glBindRenderbuffer(GL_RENDERBUFFER, color);
4084     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, kViewportWidth, kViewportHeight);
4085     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color);
4086 
4087     glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
4088     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, kViewportWidth,
4089                                      kViewportHeight);
4090     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
4091                               depthStencil);
4092 
4093     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4094     ASSERT_GL_NO_ERROR();
4095 
4096     glClearDepthf(0.8f);
4097     glClearStencil(0x3C);
4098     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4099 
4100     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Passthrough(), kFS);
4101     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
4102 
4103     GLRenderbuffer resolveColor;
4104     GLFramebuffer resolveFbo;
4105     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFbo);
4106 
4107     glBindRenderbuffer(GL_RENDERBUFFER, resolveColor);
4108     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kViewportWidth, kViewportHeight);
4109     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
4110                               resolveColor);
4111 
4112     glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth, kViewportHeight,
4113                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
4114 
4115     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFbo);
4116     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor(255, 204, 0, 255));
4117     ASSERT_GL_NO_ERROR();
4118 }
4119 
4120 // Test that depth and stencil framebuffer fetch works with MSRTT textures.
TEST_P(FramebufferFetchES31,DepthStencilMSRTT)4121 TEST_P(FramebufferFetchES31, DepthStencilMSRTT)
4122 {
4123     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4124     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
4125 
4126     const char kFS[] = R"(#version 310 es
4127 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
4128 
4129 highp out vec4 color;
4130 
4131 void main()
4132 {
4133     bool correct = gl_LastFragStencilARM == 0x3C;
4134     color = vec4(correct, gl_LastFragDepthARM, 0, 1);
4135 })";
4136 
4137     GLTexture color, depthStencil;
4138     GLFramebuffer fbo;
4139 
4140     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4141 
4142     glBindTexture(GL_TEXTURE_2D, color);
4143     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kViewportWidth, kViewportHeight);
4144     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color,
4145                                          0, 4);
4146 
4147     glBindTexture(GL_TEXTURE_2D, depthStencil);
4148     glTexStorage2D(GL_TEXTURE_2D, 2, GL_DEPTH24_STENCIL8, 2 * kViewportWidth, 2 * kViewportHeight);
4149     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
4150                                          depthStencil, 1, 4);
4151 
4152     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4153     ASSERT_GL_NO_ERROR();
4154 
4155     glClearDepthf(0.8f);
4156     glClearStencil(0x3C);
4157     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4158 
4159     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Passthrough(), kFS);
4160     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
4161 
4162     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor(255, 204, 0, 255));
4163     ASSERT_GL_NO_ERROR();
4164 }
4165 
4166 // Test that depth and stencil framebuffer fetch works with MSRTT renderbuffers.
TEST_P(FramebufferFetchES31,DepthStencilMSRTTRenderbuffer)4167 TEST_P(FramebufferFetchES31, DepthStencilMSRTTRenderbuffer)
4168 {
4169     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4170     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
4171 
4172     const char kFS[] = R"(#version 310 es
4173 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
4174 
4175 highp out vec4 color;
4176 
4177 void main()
4178 {
4179     bool correct = gl_LastFragStencilARM == 0x3C;
4180     color = vec4(correct, gl_LastFragDepthARM, 0, 1);
4181 })";
4182 
4183     GLRenderbuffer color, depthStencil;
4184     GLFramebuffer fbo;
4185 
4186     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4187 
4188     glBindRenderbuffer(GL_RENDERBUFFER, color);
4189     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_RGBA8, kViewportWidth,
4190                                         kViewportHeight);
4191     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color);
4192 
4193     glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
4194     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, kViewportWidth,
4195                                         kViewportHeight);
4196     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
4197                               depthStencil);
4198 
4199     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4200     ASSERT_GL_NO_ERROR();
4201 
4202     glClearDepthf(0.8f);
4203     glClearStencil(0x3C);
4204     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4205 
4206     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Passthrough(), kFS);
4207     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
4208 
4209     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor(255, 204, 0, 255));
4210     ASSERT_GL_NO_ERROR();
4211 }
4212 
4213 // Test that depth and stencil framebuffer fetch works with textures
TEST_P(FramebufferFetchES31,DepthStencilTexture)4214 TEST_P(FramebufferFetchES31, DepthStencilTexture)
4215 {
4216     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4217 
4218     const char kFS[] = R"(#version 310 es
4219 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
4220 
4221 highp out vec4 color;
4222 
4223 void main()
4224 {
4225     bool correct = gl_LastFragStencilARM == 0x3C;
4226     color = vec4(correct, gl_LastFragDepthARM, 0, 1);
4227 })";
4228 
4229     GLTexture color, depthStencil;
4230     GLFramebuffer fbo;
4231 
4232     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4233 
4234     glBindTexture(GL_TEXTURE_2D, color);
4235     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kViewportWidth, kViewportHeight);
4236     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
4237 
4238     glBindTexture(GL_TEXTURE_2D, depthStencil);
4239     glTexStorage2D(GL_TEXTURE_2D, 2, GL_DEPTH24_STENCIL8, 2 * kViewportWidth, 2 * kViewportHeight);
4240     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthStencil,
4241                            1);
4242 
4243     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4244     ASSERT_GL_NO_ERROR();
4245 
4246     glClearDepthf(0.8f);
4247     glClearStencil(0x3C);
4248     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4249 
4250     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Passthrough(), kFS);
4251     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
4252 
4253     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor(255, 204, 0, 255));
4254     ASSERT_GL_NO_ERROR();
4255 }
4256 
4257 // Test that depth and stencil framebuffer fetch works with layered framebuffers
TEST_P(FramebufferFetchES31,DepthStencilLayered)4258 TEST_P(FramebufferFetchES31, DepthStencilLayered)
4259 {
4260     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4261     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader") &&
4262                        !IsGLExtensionEnabled("GL_OES_geometry_shader"));
4263 
4264     const char kFS[] = R"(#version 310 es
4265 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
4266 
4267 highp out vec4 color;
4268 
4269 void main()
4270 {
4271     bool correct = gl_LastFragStencilARM == 0x3C;
4272     color = vec4(correct, gl_LastFragDepthARM, 0, 1);
4273 })";
4274 
4275     GLTexture color, depthStencil;
4276     GLFramebuffer fbo;
4277 
4278     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4279 
4280     glBindTexture(GL_TEXTURE_2D_ARRAY, color);
4281     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, kViewportWidth, kViewportHeight, 7);
4282 
4283     glBindTexture(GL_TEXTURE_2D_ARRAY, depthStencil);
4284     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH24_STENCIL8, 3 * kViewportWidth,
4285                  3 * kViewportHeight, 5, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8_OES, nullptr);
4286     glTexImage3D(GL_TEXTURE_2D_ARRAY, 1, GL_DEPTH24_STENCIL8, 2 * kViewportWidth,
4287                  2 * kViewportHeight, 7, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8_OES, nullptr);
4288     glTexImage3D(GL_TEXTURE_2D_ARRAY, 2, GL_DEPTH24_STENCIL8, kViewportWidth, kViewportHeight, 7, 0,
4289                  GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8_OES, nullptr);
4290     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 1);
4291     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 2);
4292 
4293     if (IsGLExtensionEnabled("GL_OES_geometry_shader"))
4294     {
4295         glFramebufferTextureOES(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, color, 0);
4296         glFramebufferTextureOES(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, depthStencil, 2);
4297     }
4298     else
4299     {
4300         glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, color, 0);
4301         glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, depthStencil, 2);
4302     }
4303 
4304     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4305     ASSERT_GL_NO_ERROR();
4306 
4307     glClearDepthf(0.8f);
4308     glClearStencil(0x3C);
4309     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4310 
4311     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Passthrough(), kFS);
4312     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
4313 
4314     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor(255, 204, 0, 255));
4315     ASSERT_GL_NO_ERROR();
4316 }
4317 
4318 // Test that depth and stencil framebuffer fetch works with default framebuffer
TEST_P(FramebufferFetchES31,DepthStencilSurface)4319 TEST_P(FramebufferFetchES31, DepthStencilSurface)
4320 {
4321     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4322 
4323     const char kFS[] = R"(#version 310 es
4324 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
4325 
4326 highp out vec4 color;
4327 
4328 void main()
4329 {
4330     bool correct = gl_LastFragStencilARM == 0x3C;
4331     color = vec4(correct, gl_LastFragDepthARM, 0, 1);
4332 })";
4333 
4334     glBindFramebuffer(GL_FRAMEBUFFER, 0);
4335 
4336     glClearDepthf(0.8f);
4337     glClearStencil(0x3C);
4338     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4339 
4340     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Passthrough(), kFS);
4341     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
4342 
4343     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor(255, 204, 0, 255));
4344     ASSERT_GL_NO_ERROR();
4345 }
4346 
4347 // Tests that accessing gl_LastFragDepthARM or gl_LastFragStencilARM without attached depth or
4348 // stencil attachments produces undefined results without generating an error.
TEST_P(FramebufferFetchES31,DrawWithoutDepthAndStencil)4349 TEST_P(FramebufferFetchES31, DrawWithoutDepthAndStencil)
4350 {
4351     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4352 
4353     const char kFS[] = R"(#version 310 es
4354 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
4355 
4356 highp out vec4 color;
4357 
4358 void main()
4359 {
4360     bool correct = gl_LastFragStencilARM == 0x3C;
4361     color = vec4(correct, gl_LastFragDepthARM, 0, 1);
4362 })";
4363 
4364     ANGLE_GL_PROGRAM(mProgram, essl31_shaders::vs::Passthrough(), kFS);
4365     glUseProgram(mProgram);
4366     EXPECT_GL_NO_ERROR();
4367 
4368     GLFramebuffer fbo;
4369     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4370     EXPECT_GL_NO_ERROR();
4371 
4372     GLRenderbuffer renderbuffer;
4373     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
4374     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, getWindowWidth(), getWindowHeight());
4375     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
4376     EXPECT_GL_NO_ERROR();
4377 
4378     drawQuad(mProgram, essl31_shaders::PositionAttrib(), 0.0f);
4379     EXPECT_GL_NO_ERROR();
4380 }
4381 
4382 // Test that depth and stencil framebuffer fetch works with pbuffers
TEST_P(FramebufferFetchES31,DepthStencilPbuffer)4383 TEST_P(FramebufferFetchES31, DepthStencilPbuffer)
4384 {
4385     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4386 
4387     const char kFS[] = R"(#version 310 es
4388 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
4389 
4390 highp out vec4 color;
4391 
4392 void main()
4393 {
4394     bool correct = gl_LastFragStencilARM == 0x3C;
4395     color = vec4(correct, gl_LastFragDepthARM, 0, 1);
4396 })";
4397 
4398     EGLWindow *window = getEGLWindow();
4399     ASSERT(window);
4400     EGLConfig config   = window->getConfig();
4401     EGLContext context = window->getContext();
4402     EGLDisplay dpy     = window->getDisplay();
4403     EGLint surfaceType = 0;
4404 
4405     // Skip if pbuffer surface is not supported
4406     eglGetConfigAttrib(dpy, config, EGL_SURFACE_TYPE, &surfaceType);
4407     ANGLE_SKIP_TEST_IF((surfaceType & EGL_PBUFFER_BIT) == 0);
4408 
4409     const EGLint surfaceWidth        = static_cast<EGLint>(getWindowWidth());
4410     const EGLint surfaceHeight       = static_cast<EGLint>(getWindowHeight());
4411     const EGLint pBufferAttributes[] = {
4412         EGL_WIDTH, surfaceWidth, EGL_HEIGHT, surfaceHeight, EGL_NONE,
4413     };
4414 
4415     // Create Pbuffer surface
4416     EGLSurface pbufferSurface = eglCreatePbufferSurface(dpy, config, pBufferAttributes);
4417     ASSERT_NE(pbufferSurface, EGL_NO_SURFACE);
4418     ASSERT_EGL_SUCCESS();
4419 
4420     EXPECT_EGL_TRUE(eglMakeCurrent(dpy, pbufferSurface, pbufferSurface, context));
4421     ASSERT_EGL_SUCCESS();
4422 
4423     glBindFramebuffer(GL_FRAMEBUFFER, 0);
4424 
4425     glClearDepthf(0.8f);
4426     glClearStencil(0x3C);
4427     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4428 
4429     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Passthrough(), kFS);
4430     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
4431 
4432     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor(255, 204, 0, 255));
4433     ASSERT_GL_NO_ERROR();
4434 
4435     // Switch back to the window surface and destroy the pbuffer
4436     EXPECT_EGL_TRUE(eglMakeCurrent(dpy, window->getSurface(), window->getSurface(), context));
4437     ASSERT_EGL_SUCCESS();
4438 
4439     EXPECT_EGL_TRUE(eglDestroySurface(dpy, pbufferSurface));
4440     ASSERT_EGL_SUCCESS();
4441 }
4442 
4443 // Test that depth framebuffer fetch works with color framebuffer fetch
TEST_P(FramebufferFetchES31,DepthAndColor)4444 TEST_P(FramebufferFetchES31, DepthAndColor)
4445 {
4446     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4447     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch") &&
4448                        !IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
4449     const WhichExtension whichExtension = chooseBetweenCoherentOrIncoherent();
4450 
4451     std::ostringstream fs;
4452     fs << makeShaderPreamble(
4453         whichExtension, "#extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require", 1);
4454     fs << R"(void main()
4455 {
4456     color0 = vec4(gl_LastFragDepthARM, 0, 0, 1);
4457 })";
4458 
4459     GLRenderbuffer color, depthStencil;
4460     GLFramebuffer fbo;
4461     createFramebufferWithDepthStencil(&color, &depthStencil, &fbo);
4462 
4463     glClearDepthf(0.4f);
4464     glClear(GL_DEPTH_BUFFER_BIT);
4465 
4466     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Passthrough(), fs.str().c_str());
4467     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
4468 
4469     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor(102, 0, 0, 255));
4470     ASSERT_GL_NO_ERROR();
4471 }
4472 
4473 // Test that stencil framebuffer fetch works with color framebuffer fetch
TEST_P(FramebufferFetchES31,StencilAndColor)4474 TEST_P(FramebufferFetchES31, StencilAndColor)
4475 {
4476     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4477     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch") &&
4478                        !IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
4479     const WhichExtension whichExtension = chooseBetweenCoherentOrIncoherent();
4480 
4481     std::ostringstream fs;
4482     fs << makeShaderPreamble(
4483         whichExtension, "#extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require", 1);
4484     fs << R"(void main()
4485 {
4486     bool correct = gl_LastFragStencilARM == 0x7D;
4487     color0 = vec4(correct, 0, 0, 1);
4488 })";
4489 
4490     GLRenderbuffer color, depthStencil;
4491     GLFramebuffer fbo;
4492     createFramebufferWithDepthStencil(&color, &depthStencil, &fbo);
4493 
4494     glClearStencil(0x7D);
4495     glClear(GL_STENCIL_BUFFER_BIT);
4496 
4497     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Passthrough(), fs.str().c_str());
4498     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
4499 
4500     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor(255, 0, 0, 255));
4501     ASSERT_GL_NO_ERROR();
4502 }
4503 
4504 // Test that depth/stencil framebuffer fetch works with color framebuffer fetch
TEST_P(FramebufferFetchES31,DepthStencilAndColor)4505 TEST_P(FramebufferFetchES31, DepthStencilAndColor)
4506 {
4507     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4508     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch") &&
4509                        !IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
4510     const WhichExtension whichExtension = chooseBetweenCoherentOrIncoherent();
4511 
4512     std::ostringstream fs;
4513     fs << makeShaderPreamble(
4514         whichExtension, "#extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require", 1);
4515     fs << R"(void main()
4516 {
4517     bool correct = gl_LastFragStencilARM == 0x7D;
4518     color0 = vec4(correct, gl_LastFragDepthARM, 0, 1);
4519 })";
4520 
4521     GLRenderbuffer color, depthStencil;
4522     GLFramebuffer fbo;
4523     createFramebufferWithDepthStencil(&color, &depthStencil, &fbo);
4524 
4525     glClearDepthf(0.8f);
4526     glClearStencil(0x7D);
4527     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4528 
4529     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Passthrough(), fs.str().c_str());
4530     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
4531 
4532     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor(255, 204, 0, 255));
4533     ASSERT_GL_NO_ERROR();
4534 }
4535 
4536 // Test that mixing depth-only and stencil-only framebuffer fetch programs work
TEST_P(FramebufferFetchES31,DepthThenStencilThenNone)4537 TEST_P(FramebufferFetchES31, DepthThenStencilThenNone)
4538 {
4539     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4540 
4541     const char kDepthFS[] = R"(#version 310 es
4542 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
4543 
4544 highp out vec4 color;
4545 
4546 void main()
4547 {
4548     color = vec4(gl_LastFragDepthARM, 0, 0, 1);
4549 })";
4550 
4551     const char kStencilFS[] = R"(#version 310 es
4552 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
4553 
4554 highp out vec4 color;
4555 
4556 void main()
4557 {
4558     bool correct = gl_LastFragStencilARM == 0xE5;
4559     color = vec4(0, correct, 0, 1);
4560 })";
4561 
4562     const char kNoneFS[] = R"(#version 310 es
4563 
4564 highp out vec4 color;
4565 
4566 void main()
4567 {
4568     color = vec4(0, 0, 1, 1);
4569 })";
4570 
4571     GLRenderbuffer color, depthStencil;
4572     GLFramebuffer fbo;
4573     createFramebufferWithDepthStencil(&color, &depthStencil, &fbo);
4574 
4575     glClearDepthf(0.8f);
4576     glClearStencil(0xE5);
4577     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4578 
4579     ANGLE_GL_PROGRAM(depth, essl31_shaders::vs::Passthrough(), kDepthFS);
4580     ANGLE_GL_PROGRAM(stencil, essl31_shaders::vs::Passthrough(), kStencilFS);
4581     ANGLE_GL_PROGRAM(none, essl31_shaders::vs::Passthrough(), kNoneFS);
4582 
4583     drawQuad(depth, essl31_shaders::PositionAttrib(), 0.0f);
4584     glEnable(GL_BLEND);
4585     glBlendFunc(GL_ONE, GL_ONE);
4586     drawQuad(stencil, essl31_shaders::PositionAttrib(), 0.0f);
4587     drawQuad(none, essl31_shaders::PositionAttrib(), 0.0f);
4588 
4589     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor(204, 255, 255, 255));
4590     ASSERT_GL_NO_ERROR();
4591 }
4592 
4593 // Test that starting without framebuffer fetch, then doing framebuffer fetch works.
TEST_P(FramebufferFetchES31,NoneThenDepthThenStencil)4594 TEST_P(FramebufferFetchES31, NoneThenDepthThenStencil)
4595 {
4596     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4597 
4598     const char kDepthFS[] = R"(#version 310 es
4599 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
4600 
4601 highp out vec4 color;
4602 
4603 void main()
4604 {
4605     color = vec4(gl_LastFragDepthARM, 0, 0, 1);
4606 })";
4607 
4608     const char kStencilFS[] = R"(#version 310 es
4609 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
4610 
4611 highp out vec4 color;
4612 
4613 void main()
4614 {
4615     bool correct = gl_LastFragStencilARM == 0xE5;
4616     color = vec4(0, correct, 0, 1);
4617 })";
4618 
4619     const char kNoneFS[] = R"(#version 310 es
4620 
4621 highp out vec4 color;
4622 
4623 void main()
4624 {
4625     color = vec4(0, 0, 1, 1);
4626 })";
4627 
4628     GLRenderbuffer color, depthStencil;
4629     GLFramebuffer fbo;
4630     createFramebufferWithDepthStencil(&color, &depthStencil, &fbo);
4631 
4632     glClearDepthf(0.4f);
4633     glClearStencil(0xE5);
4634     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4635 
4636     ANGLE_GL_PROGRAM(depth, essl31_shaders::vs::Passthrough(), kDepthFS);
4637     ANGLE_GL_PROGRAM(stencil, essl31_shaders::vs::Passthrough(), kStencilFS);
4638     ANGLE_GL_PROGRAM(none, essl31_shaders::vs::Passthrough(), kNoneFS);
4639 
4640     drawQuad(none, essl31_shaders::PositionAttrib(), 0.0f);
4641     glEnable(GL_BLEND);
4642     glBlendFunc(GL_ONE, GL_ONE);
4643     drawQuad(depth, essl31_shaders::PositionAttrib(), 0.0f);
4644     drawQuad(stencil, essl31_shaders::PositionAttrib(), 0.0f);
4645 
4646     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor(102, 255, 255, 255));
4647     ASSERT_GL_NO_ERROR();
4648 }
4649 
4650 // Test that depth/stencil framebuffer fetch is actually coherent by writing to depth/stencil in one
4651 // draw call and reading from it in another.
TEST_P(FramebufferFetchES31,DepthStencilDrawThenRead)4652 TEST_P(FramebufferFetchES31, DepthStencilDrawThenRead)
4653 {
4654     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4655 
4656     const char kWriteDepthFS[] = R"(#version 310 es
4657 
4658 highp out vec4 color;
4659 
4660 void main()
4661 {
4662     if (gl_FragCoord.x < 8.)
4663         gl_FragDepth = 0.4f;
4664     else
4665         gl_FragDepth = 0.8f;
4666     color = vec4(0, 0, 1, 1);
4667 })";
4668 
4669     const char kFS[] = R"(#version 310 es
4670 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
4671 
4672 highp out vec4 color;
4673 
4674 void main()
4675 {
4676     bool correct = gl_LastFragStencilARM == 0x5B;
4677     color = vec4(correct, gl_LastFragDepthARM, 0, 1);
4678 })";
4679 
4680     GLRenderbuffer color, depthStencil;
4681     GLFramebuffer fbo;
4682     createFramebufferWithDepthStencil(&color, &depthStencil, &fbo);
4683 
4684     glClearDepthf(0);
4685     glClearStencil(0);
4686     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4687 
4688     ANGLE_GL_PROGRAM(writeDepth, essl31_shaders::vs::Passthrough(), kWriteDepthFS);
4689     ANGLE_GL_PROGRAM(read, essl31_shaders::vs::Passthrough(), kFS);
4690 
4691     // Write depth (0.4 or 0.8 by the shader) and stencil (0x5B) in one draw call
4692     glEnable(GL_DEPTH_TEST);
4693     glDepthFunc(GL_ALWAYS);
4694     glDepthMask(GL_TRUE);
4695 
4696     glEnable(GL_STENCIL_TEST);
4697     glStencilFunc(GL_ALWAYS, 0x5B, 0xFF);
4698     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
4699     glStencilMask(0xFF);
4700 
4701     drawQuad(writeDepth, essl31_shaders::PositionAttrib(), 0.0f);
4702 
4703     // Read them in the next draw call to verify
4704     glEnable(GL_BLEND);
4705     glBlendFunc(GL_ONE, GL_ONE);
4706     drawQuad(read, essl31_shaders::PositionAttrib(), 0.0f);
4707 
4708     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth / 2, kViewportHeight, GLColor(255, 102, 255, 255));
4709     EXPECT_PIXEL_RECT_EQ(kViewportWidth / 2, 0, kViewportWidth - kViewportWidth, kViewportHeight,
4710                          GLColor(255, 204, 255, 255));
4711     ASSERT_GL_NO_ERROR();
4712 }
4713 
4714 // Test that writing to gl_FragDepth does not affect gl_LastFragDepthARM.
TEST_P(FramebufferFetchES31,DepthWriteAndReadInSameShader)4715 TEST_P(FramebufferFetchES31, DepthWriteAndReadInSameShader)
4716 {
4717     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4718 
4719     const char kFS[] = R"(#version 310 es
4720 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
4721 
4722 highp out vec4 color;
4723 
4724 void main()
4725 {
4726     gl_FragDepth = 0.9;
4727     color = vec4(gl_LastFragDepthARM, 0, 0, 1);
4728 })";
4729 
4730     GLRenderbuffer color, depthStencil;
4731     GLFramebuffer fbo;
4732     createFramebufferWithDepthStencil(&color, &depthStencil, &fbo);
4733 
4734     glClearDepthf(0.4f);
4735     glClear(GL_DEPTH_BUFFER_BIT);
4736 
4737     glEnable(GL_DEPTH_TEST);
4738     glDepthFunc(GL_ALWAYS);
4739     glDepthMask(GL_TRUE);
4740 
4741     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Passthrough(), kFS);
4742     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
4743 
4744     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor(102, 0, 0, 255));
4745     ASSERT_GL_NO_ERROR();
4746 
4747     // For completeness, verify that gl_FragDepth did write to depth.
4748     glEnable(GL_DEPTH_TEST);
4749     glDepthFunc(GL_LESS);
4750     glDepthMask(GL_FALSE);
4751 
4752     ANGLE_GL_PROGRAM(red, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
4753     ANGLE_GL_PROGRAM(green, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
4754 
4755     drawQuad(red, essl1_shaders::PositionAttrib(), 0.79f);
4756     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor::red);
4757 
4758     drawQuad(green, essl1_shaders::PositionAttrib(), 0.81f);
4759     EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor::red);
4760 
4761     ASSERT_GL_NO_ERROR();
4762 }
4763 
4764 // Test that render pass can start with D/S framebuffer fetch, then color framebuffer fetch is used.
TEST_P(FramebufferFetchES31,DepthStencilThenColor)4765 TEST_P(FramebufferFetchES31, DepthStencilThenColor)
4766 {
4767     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4768     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch") &&
4769                        !IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
4770     const WhichExtension whichExtension = chooseBetweenCoherentOrIncoherent();
4771 
4772     const char kDepthStencilFS[] = R"(#version 310 es
4773 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
4774 
4775 highp out vec4 color;
4776 
4777 void main()
4778 {
4779     bool correct = gl_LastFragStencilARM == 0x7D;
4780     color = vec4(correct, gl_LastFragDepthARM, 0, 1);
4781 })";
4782 
4783     std::ostringstream colorFS;
4784     colorFS << makeShaderPreamble(whichExtension, nullptr, 1);
4785     colorFS << R"(void main()
4786 {
4787     color0.x /= 2.;
4788     color0.y *= 2.;
4789 })";
4790 
4791     GLRenderbuffer color, depthStencil;
4792     GLFramebuffer fbo;
4793     createFramebufferWithDepthStencil(&color, &depthStencil, &fbo);
4794 
4795     glClearDepthf(0.4f);
4796     glClearStencil(0x7D);
4797     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4798 
4799     ANGLE_GL_PROGRAM(readDepthStencil, essl31_shaders::vs::Passthrough(), kDepthStencilFS);
4800     ANGLE_GL_PROGRAM(readColor, essl31_shaders::vs::Passthrough(), colorFS.str().c_str());
4801 
4802     drawQuad(readDepthStencil, essl31_shaders::PositionAttrib(), 0.0f);
4803     drawQuad(readColor, essl31_shaders::PositionAttrib(), 0.0f);
4804 
4805     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(127, 204, 0, 255), 1);
4806     EXPECT_PIXEL_COLOR_NEAR(kViewportWidth - 1, kViewportHeight - 1, GLColor(127, 204, 0, 255), 1);
4807     ASSERT_GL_NO_ERROR();
4808 }
4809 
4810 // Test that render pass can start without framebuffer fetch, then do D/S framebuffer fetch, then
4811 // color framebuffer fetch.  This test uses PPOs.
TEST_P(FramebufferFetchES31,NoneThenDepthStencilThenColorPPO)4812 TEST_P(FramebufferFetchES31, NoneThenDepthStencilThenColorPPO)
4813 {
4814     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4815     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch") &&
4816                        !IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
4817     const WhichExtension whichExtension = chooseBetweenCoherentOrIncoherent();
4818 
4819     constexpr char kVS[] = R"(#version 310 es
4820 void main()
4821 {
4822     vec2 pos = vec2(0.0);
4823     switch (gl_VertexID) {
4824         case 0: pos = vec2(-1.0, -1.0); break;
4825         case 1: pos = vec2(3.0, -1.0); break;
4826         case 2: pos = vec2(-1.0, 3.0); break;
4827     };
4828     gl_Position = vec4(pos, 0.0, 1.0);
4829 })";
4830 
4831     const char kNoneFS[] = R"(#version 310 es
4832 
4833 highp out vec4 color;
4834 
4835 void main()
4836 {
4837     color = vec4(0, 0, 1, 1);
4838 })";
4839 
4840     const char kDepthStencilFS[] = R"(#version 310 es
4841 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
4842 
4843 highp out vec4 color;
4844 
4845 void main()
4846 {
4847     bool correct = gl_LastFragStencilARM == 0x7D;
4848     color = vec4(correct, gl_LastFragDepthARM, 0, 1);
4849 })";
4850 
4851     std::ostringstream colorFS;
4852     colorFS << makeShaderPreamble(whichExtension, nullptr, 1);
4853     colorFS << R"(void main()
4854 {
4855     color0.x /= 2.;
4856     color0.y *= 2.;
4857 })";
4858 
4859     GLRenderbuffer color, depthStencil;
4860     GLFramebuffer fbo;
4861     createFramebufferWithDepthStencil(&color, &depthStencil, &fbo);
4862 
4863     GLProgramPipeline nonePPO, depthStencilPPO, colorPPO;
4864     makeProgramPipeline(nonePPO, kVS, kNoneFS);
4865     makeProgramPipeline(depthStencilPPO, kVS, kDepthStencilFS);
4866     makeProgramPipeline(colorPPO, kVS, colorFS.str().c_str());
4867 
4868     glClearDepthf(0.4f);
4869     glClearStencil(0x7D);
4870     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4871 
4872     glBindProgramPipeline(nonePPO);
4873     glDrawArrays(GL_TRIANGLES, 0, 3);
4874 
4875     glEnable(GL_BLEND);
4876     glBlendFunc(GL_ONE, GL_ONE);
4877 
4878     glBindProgramPipeline(depthStencilPPO);
4879     glDrawArrays(GL_TRIANGLES, 0, 3);
4880 
4881     glDisable(GL_BLEND);
4882 
4883     glBindProgramPipeline(colorPPO);
4884     glDrawArrays(GL_TRIANGLES, 0, 3);
4885 
4886     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(127, 204, 255, 255), 1);
4887     EXPECT_PIXEL_COLOR_NEAR(kViewportWidth - 1, kViewportHeight - 1, GLColor(127, 204, 255, 255),
4888                             1);
4889     ASSERT_GL_NO_ERROR();
4890 }
4891 
4892 // Test that using the maximum number of color attachments works in conjunction with depth/stencil
4893 // framebuffer fetch.
TEST_P(FramebufferFetchES31,MaximumColorAttachmentsAndDepthStencil)4894 TEST_P(FramebufferFetchES31, MaximumColorAttachmentsAndDepthStencil)
4895 {
4896     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4897     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch") &&
4898                        !IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
4899     const WhichExtension whichExtension = chooseBetweenCoherentOrIncoherent();
4900 
4901     GLint maxDrawBuffers = 0;
4902     glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
4903 
4904     GLFramebuffer fbo;
4905     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4906 
4907     GLTexture depthStencil;
4908     std::vector<GLTexture> color(maxDrawBuffers);
4909     std::vector<GLenum> buffers(maxDrawBuffers);
4910     for (GLint index = 0; index < maxDrawBuffers; ++index)
4911     {
4912         buffers[index] = GL_COLOR_ATTACHMENT0 + index;
4913 
4914         glBindTexture(GL_TEXTURE_2D, color[index]);
4915         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kViewportWidth, kViewportHeight);
4916         glFramebufferTexture2D(GL_FRAMEBUFFER, buffers[index], GL_TEXTURE_2D, color[index], 0);
4917     }
4918 
4919     glBindTexture(GL_TEXTURE_2D, depthStencil);
4920     glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, kViewportWidth, kViewportHeight);
4921     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthStencil,
4922                            0);
4923 
4924     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4925     ASSERT_GL_NO_ERROR();
4926 
4927     glDrawBuffers(maxDrawBuffers, buffers.data());
4928 
4929     glClearColor(0, 0, 1, 0);
4930     glClearDepthf(0.8f);
4931     glClearStencil(0x7D);
4932     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4933 
4934     std::ostringstream fs;
4935     fs << makeShaderPreamble(whichExtension,
4936                              "#extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require",
4937                              maxDrawBuffers);
4938     fs << R"(void main()
4939 {
4940     bool correct = gl_LastFragStencilARM == 0x7D;
4941 )";
4942     for (GLint index = 0; index < maxDrawBuffers; ++index)
4943     {
4944         fs << "  color" << index << " += vec4(correct, gl_LastFragDepthARM, 0, 1);\n";
4945     }
4946     fs << "}\n";
4947 
4948     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Passthrough(), fs.str().c_str());
4949 
4950     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
4951 
4952     for (GLint index = 0; index < maxDrawBuffers; ++index)
4953     {
4954         glReadBuffer(buffers[index]);
4955         EXPECT_PIXEL_RECT_EQ(0, 0, kViewportWidth, kViewportHeight, GLColor(255, 204, 255, 255));
4956     }
4957     ASSERT_GL_NO_ERROR();
4958 }
4959 
4960 // Test that depth/stencil framebuffer fetch works with advanced blend
TEST_P(FramebufferFetchAndAdvancedBlendES31,DepthStencilAndAdvancedBlend)4961 TEST_P(FramebufferFetchAndAdvancedBlendES31, DepthStencilAndAdvancedBlend)
4962 {
4963     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ARM_shader_framebuffer_fetch_depth_stencil"));
4964     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_KHR_blend_equation_advanced"));
4965 
4966     const char kFS[] = R"(#version 310 es
4967 #extension GL_ARM_shader_framebuffer_fetch_depth_stencil : require
4968 #extension GL_KHR_blend_equation_advanced : require
4969 
4970 layout(blend_support_multiply) out;
4971 layout(location = 0) out mediump vec4 color;
4972 
4973 void main()
4974 {
4975     bool correct = gl_LastFragStencilARM == 0x7D;
4976     color = vec4(correct, gl_LastFragDepthARM, 0, 0.5);
4977 })";
4978 
4979     GLRenderbuffer color, depthStencil;
4980     GLFramebuffer fbo;
4981     createFramebufferWithDepthStencil(&color, &depthStencil, &fbo);
4982 
4983     glClearColor(0.5, 0.2, 0.4, 0.6);
4984     glClearDepthf(0.8f);
4985     glClearStencil(0x7D);
4986     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
4987 
4988     glEnable(GL_BLEND);
4989     glBlendEquation(GL_MULTIPLY_KHR);
4990 
4991     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Passthrough(), kFS);
4992     drawQuad(program, essl31_shaders::PositionAttrib(), 0.0f);
4993 
4994     EXPECT_PIXEL_NEAR(0, 0, 255, 148, 51, 204, 1);
4995     EXPECT_PIXEL_NEAR(kViewportWidth - 1, kViewportHeight - 1, 255, 148, 51, 204, 1);
4996     ASSERT_GL_NO_ERROR();
4997 }
4998 
4999 // Test switching between framebuffer fetch and non framebuffer fetch draw calls, with multiple
5000 // calls in each mode in between.  Tests Vulkan backend's emulation of coherent framebuffer fetch
5001 // over non-coherent hardware.  While this is untestable without adding counters, the test should
5002 // generate implicit framebuffer fetch barriers only when the current program uses framebuffer
5003 // fetch.  This can be observed in RenderDoc.
TEST_P(FramebufferFetchES31,SwitchWithAndWithoutFramebufferFetchPrograms)5004 TEST_P(FramebufferFetchES31, SwitchWithAndWithoutFramebufferFetchPrograms)
5005 {
5006     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
5007 
5008     constexpr char kVS[] = R"(#version 310 es
5009 void main()
5010 {
5011     // gl_VertexID    x    y
5012     //      0        -1   -1
5013     //      1         1   -1
5014     //      2        -1    1
5015     //      3         1    1
5016     int bit0 = gl_VertexID & 1;
5017     int bit1 = gl_VertexID >> 1;
5018     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
5019 })";
5020 
5021     // Program without framebuffer fetch
5022     constexpr char kFS1[] = R"(#version 310 es
5023 layout(location = 0) out highp vec4 o_color;
5024 uniform mediump vec4 u_color;
5025 void main (void)
5026 {
5027     o_color = u_color;
5028 })";
5029     ANGLE_GL_PROGRAM(drawColor, kVS, kFS1);
5030     glUseProgram(drawColor);
5031     GLint uniLoc = glGetUniformLocation(drawColor, "u_color");
5032     ASSERT_NE(uniLoc, -1);
5033 
5034     // Program with framebuffer fetch
5035     constexpr char kFS2[] = R"(#version 310 es
5036 #extension GL_EXT_shader_framebuffer_fetch : require
5037 layout(location = 0) inout highp vec4 o_color;
5038 void main (void)
5039 {
5040     o_color = o_color * o_color + vec4(0.1, 0.2, 0.3, 0.2);
5041 })";
5042     ANGLE_GL_PROGRAM(ff, kVS, kFS2);
5043 
5044     GLTexture color;
5045     glBindTexture(GL_TEXTURE_2D, color);
5046     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kViewportWidth, kViewportHeight);
5047 
5048     GLFramebuffer framebuffer;
5049     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
5050     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
5051     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
5052     ASSERT_GL_NO_ERROR();
5053 
5054     glClearColor(0, 0, 0.5, 0);
5055     glClear(GL_COLOR_BUFFER_BIT);
5056 
5057     // Start without framebuffer fetch.
5058     glUseProgram(drawColor);
5059     glEnable(GL_BLEND);
5060     glBlendFunc(GL_ONE, GL_ONE);
5061     glUniform4f(uniLoc, 0.7, 0, 0, 0.3);
5062     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5063     glUniform4f(uniLoc, 0.1, 0.4, 0, 0);
5064     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5065 
5066     // Switch to framebuffer fetch mode, and draw a few times
5067     glDisable(GL_BLEND);
5068     glUseProgram(ff);
5069     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5070     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5071 
5072     // Break the render pass.  Later continue drawing in framebuffer fetch mode without changing
5073     // programs to ensure that framebuffer fetch barrier is still added.
5074     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(165, 84, 153, 72), 3);
5075 
5076     // More FF calls
5077     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5078     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5079 
5080     // Back to no FF calls, no barrier should be added.
5081     glEnable(GL_BLEND);
5082     glUseProgram(drawColor);
5083     glUniform4f(uniLoc, 0.2, 0.1, 0.05, 0.15);
5084     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
5085 
5086     // Verify results
5087     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(145, 100, 201, 109), 3);
5088 }
5089 
5090 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FramebufferFetchES31);
5091 ANGLE_INSTANTIATE_TEST_ES31_AND(FramebufferFetchES31,
5092                                 ES31_VULKAN().disable(Feature::SupportsSPIRV14));
5093 
5094 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FramebufferFetchAndAdvancedBlendES31);
5095 ANGLE_INSTANTIATE_TEST_ES31_AND(FramebufferFetchAndAdvancedBlendES31,
5096                                 ES31_VULKAN_SWIFTSHADER()
5097                                     .disable(Feature::SupportsBlendOperationAdvanced)
5098                                     .enable(Feature::EmulateAdvancedBlendEquations));
5099 }  // namespace angle
5100