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