• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2021 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // FramebufferFetchTest:
7 //   Tests the correctness of the EXT_shader_framebuffer_fetch and the
8 //   EXT_shader_framebuffer_fetch_non_coherent extensions.
9 //
10 
11 #include "common/debug.h"
12 #include "test_utils/ANGLETest.h"
13 #include "test_utils/gl_raii.h"
14 #include "util/EGLWindow.h"
15 
16 namespace angle
17 {
18 //
19 // Shared Vertex Shaders for the tests below
20 //
21 // A 1.0 GLSL vertex shader
22 static constexpr char k100VS[] = R"(#version 100
23 attribute vec4 a_position;
24 
25 void main (void)
26 {
27     gl_Position = a_position;
28 })";
29 
30 // A 3.1 GLSL vertex shader
31 static constexpr char k310VS[] = R"(#version 310 es
32 in highp vec4 a_position;
33 
34 void main (void)
35 {
36     gl_Position = a_position;
37 })";
38 
39 // Shared simple (i.e. no framebuffer fetch) Fragment Shaders for the tests below
40 //
41 // Simple (i.e. no framebuffer fetch) 3.1 GLSL fragment shader that writes to 1 attachment
42 static constexpr char k310NoFetch1AttachmentFS[] = R"(#version 310 es
43 layout(location = 0) out highp vec4 o_color;
44 
45 uniform highp vec4 u_color;
46 void main (void)
47 {
48     o_color = u_color;
49 })";
50 
51 // Shared Coherent Fragment Shaders for the tests below
52 //
53 // Coherent version of a 1.0 GLSL fragment shader that uses gl_LastFragData
54 static constexpr char k100CoherentFS[] = R"(#version 100
55 #extension GL_EXT_shader_framebuffer_fetch : require
56 mediump vec4 gl_LastFragData[gl_MaxDrawBuffers];
57 uniform highp vec4 u_color;
58 
59 void main (void)
60 {
61     gl_FragColor = u_color + gl_LastFragData[0];
62 })";
63 
64 // Coherent version of a 3.1 GLSL fragment shader that writes to 1 attachment
65 static constexpr char k310Coherent1AttachmentFS[] = R"(#version 310 es
66 #extension GL_EXT_shader_framebuffer_fetch : require
67 layout(location = 0) inout highp vec4 o_color;
68 
69 uniform highp vec4 u_color;
70 void main (void)
71 {
72     o_color += u_color;
73 })";
74 
75 // Coherent version of a 3.1 GLSL fragment shader that writes the output to a storage buffer.
76 static constexpr char k310CoherentStorageBuffer[] = R"(#version 310 es
77 #extension GL_EXT_shader_framebuffer_fetch : require
78 layout(location = 0) inout highp vec4 o_color;
79 
80 layout(std140, binding = 0) buffer outBlock {
81     highp vec4 data[256];
82 };
83 
84 uniform highp vec4 u_color;
85 void main (void)
86 {
87     uint index = uint(gl_FragCoord.y) * 16u + uint(gl_FragCoord.x);
88     data[index] = o_color;
89     o_color += u_color;
90 })";
91 
92 // Coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments
93 static constexpr char k310Coherent4AttachmentFS[] = R"(#version 310 es
94 #extension GL_EXT_shader_framebuffer_fetch : require
95 layout(location = 0) inout highp vec4 o_color0;
96 layout(location = 1) inout highp vec4 o_color1;
97 layout(location = 2) inout highp vec4 o_color2;
98 layout(location = 3) inout highp vec4 o_color3;
99 uniform highp vec4 u_color;
100 
101 void main (void)
102 {
103     o_color0 += u_color;
104     o_color1 += u_color;
105     o_color2 += u_color;
106     o_color3 += u_color;
107 })";
108 
109 // Coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments via an inout
110 // array
111 static constexpr char k310Coherent4AttachmentArrayFS[] = R"(#version 310 es
112 #extension GL_EXT_shader_framebuffer_fetch : require
113 inout highp vec4 o_color[4];
114 uniform highp vec4 u_color;
115 
116 void main (void)
117 {
118     o_color[0] += u_color;
119     o_color[1] += u_color;
120     o_color[2] += u_color;
121     o_color[3] += u_color;
122 })";
123 
124 // Coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments with the order of
125 // non-fetch program and fetch program with different attachments (version 1)
126 static constexpr char k310CoherentDifferent4AttachmentFS1[] = R"(#version 310 es
127 #extension GL_EXT_shader_framebuffer_fetch : require
128 layout(location = 0) inout highp vec4 o_color0;
129 layout(location = 1) out highp vec4 o_color1;
130 layout(location = 2) inout highp vec4 o_color2;
131 layout(location = 3) out highp vec4 o_color3;
132 uniform highp vec4 u_color;
133 
134 void main (void)
135 {
136     o_color0 += u_color;
137     o_color1 = u_color;
138     o_color2 += u_color;
139     o_color3 = u_color;
140 })";
141 
142 // Coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments with the order
143 // of non-fetch program and fetch program with different attachments (version 2)
144 static constexpr char k310CoherentDifferent4AttachmentFS2[] = R"(#version 310 es
145 #extension GL_EXT_shader_framebuffer_fetch : require
146 layout(location = 0) inout highp vec4 o_color0;
147 layout(location = 1) out highp vec4 o_color1;
148 layout(location = 2) out highp vec4 o_color2;
149 layout(location = 3) inout highp vec4 o_color3;
150 uniform highp vec4 u_color;
151 
152 void main (void)
153 {
154     o_color0 += u_color;
155     o_color1 = u_color;
156     o_color2 = u_color;
157     o_color3 += u_color;
158 })";
159 
160 // Shared Non-Coherent Fragment Shaders for the tests below
161 //
162 // Non-coherent version of a 1.0 GLSL fragment shader that uses gl_LastFragData
163 static constexpr char k100NonCoherentFS[] = R"(#version 100
164 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
165 layout(noncoherent) mediump vec4 gl_LastFragData[gl_MaxDrawBuffers];
166 uniform highp vec4 u_color;
167 
168 void main (void)
169 {
170     gl_FragColor = u_color + gl_LastFragData[0];
171 })";
172 
173 // Non-coherent version of a 3.1 GLSL fragment shader that writes to 1 attachment
174 static constexpr char k310NonCoherent1AttachmentFS[] = R"(#version 310 es
175 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
176 layout(noncoherent, location = 0) inout highp vec4 o_color;
177 
178 uniform highp vec4 u_color;
179 void main (void)
180 {
181     o_color += u_color;
182 })";
183 
184 // Non-coherent version of a 3.1 GLSL fragment shader that writes the output to a storage buffer.
185 static constexpr char k310NonCoherentStorageBuffer[] = R"(#version 310 es
186 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
187 layout(noncoherent) inout highp vec4 o_color;
188 
189 layout(std140, binding = 0) buffer outBlock {
190     highp vec4 data[256];
191 };
192 
193 uniform highp vec4 u_color;
194 void main (void)
195 {
196     uint index = uint(gl_FragCoord.y) * 16u + uint(gl_FragCoord.x);
197     data[index] = o_color;
198     o_color += u_color;
199 })";
200 
201 // Non-coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments
202 static constexpr char k310NonCoherent4AttachmentFS[] = R"(#version 310 es
203 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
204 layout(noncoherent, location = 0) inout highp vec4 o_color0;
205 layout(noncoherent, location = 1) inout highp vec4 o_color1;
206 layout(noncoherent, location = 2) inout highp vec4 o_color2;
207 layout(noncoherent, location = 3) inout highp vec4 o_color3;
208 uniform highp vec4 u_color;
209 
210 void main (void)
211 {
212     o_color0 += u_color;
213     o_color1 += u_color;
214     o_color2 += u_color;
215     o_color3 += u_color;
216 })";
217 
218 // Non-coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments via an inout
219 // array
220 static constexpr char k310NonCoherent4AttachmentArrayFS[] = R"(#version 310 es
221 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
222 layout(noncoherent, location = 0) inout highp vec4 o_color[4];
223 uniform highp vec4 u_color;
224 
225 void main (void)
226 {
227     o_color[0] += u_color;
228     o_color[1] += u_color;
229     o_color[2] += u_color;
230     o_color[3] += u_color;
231 })";
232 
233 // Non-coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments with the order
234 // of non-fetch program and fetch program with different attachments (version 1)
235 static constexpr char k310NonCoherentDifferent4AttachmentFS1[] = R"(#version 310 es
236 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
237 layout(noncoherent, location = 0) inout highp vec4 o_color0;
238 layout(location = 1) out highp vec4 o_color1;
239 layout(noncoherent, location = 2) inout highp vec4 o_color2;
240 layout(location = 3) out highp vec4 o_color3;
241 uniform highp vec4 u_color;
242 
243 void main (void)
244 {
245     o_color0 += u_color;
246     o_color1 = u_color;
247     o_color2 += u_color;
248     o_color3 = u_color;
249 })";
250 
251 // Non-coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments with the order
252 // of non-fetch program and fetch program with different attachments (version 2)
253 static constexpr char k310NonCoherentDifferent4AttachmentFS2[] = R"(#version 310 es
254 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
255 layout(noncoherent, location = 0) inout highp vec4 o_color0;
256 layout(location = 1) out highp vec4 o_color1;
257 layout(location = 2) out highp vec4 o_color2;
258 layout(noncoherent, location = 3) inout highp vec4 o_color3;
259 uniform highp vec4 u_color;
260 
261 void main (void)
262 {
263     o_color0 += u_color;
264     o_color1 = u_color;
265     o_color2 = u_color;
266     o_color3 += u_color;
267 })";
268 
269 class FramebufferFetchES31 : public ANGLETest
270 {
271   protected:
272     static constexpr GLuint kMaxColorBuffer = 4u;
273     static constexpr GLuint kViewportWidth  = 16u;
274     static constexpr GLuint kViewportHeight = 16u;
275 
FramebufferFetchES31()276     FramebufferFetchES31()
277     {
278         setWindowWidth(16);
279         setWindowHeight(16);
280         setConfigRedBits(8);
281         setConfigGreenBits(8);
282         setConfigBlueBits(8);
283         setConfigAlphaBits(8);
284         setConfigDepthBits(24);
285 
286         mCoherentExtension = false;
287     }
288 
289     enum WhichExtension
290     {
291         COHERENT,
292         NON_COHERENT,
293     };
setWhichExtension(WhichExtension whichExtension)294     void setWhichExtension(WhichExtension whichExtension)
295     {
296         mCoherentExtension = (whichExtension == COHERENT) ? true : false;
297     }
298 
299     enum WhichFragmentShader
300     {
301         GLSL100,
302         GLSL310_NO_FETCH_1ATTACHMENT,
303         GLSL310_1ATTACHMENT,
304         GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER,
305         GLSL310_4ATTACHMENT,
306         GLSL310_4ATTACHMENT_ARRAY,
307         GLSL310_4ATTACHMENT_DIFFERENT1,
308         GLSL310_4ATTACHMENT_DIFFERENT2,
309     };
getFragmentShader(WhichFragmentShader whichFragmentShader)310     const char *getFragmentShader(WhichFragmentShader whichFragmentShader)
311     {
312         if (mCoherentExtension)
313         {
314             switch (whichFragmentShader)
315             {
316                 case GLSL100:
317                     return k100CoherentFS;
318                 case GLSL310_NO_FETCH_1ATTACHMENT:
319                     return k310NoFetch1AttachmentFS;
320                 case GLSL310_1ATTACHMENT:
321                     return k310Coherent1AttachmentFS;
322                 case GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER:
323                     return k310CoherentStorageBuffer;
324                 case GLSL310_4ATTACHMENT:
325                     return k310Coherent4AttachmentFS;
326                 case GLSL310_4ATTACHMENT_ARRAY:
327                     return k310Coherent4AttachmentArrayFS;
328                 case GLSL310_4ATTACHMENT_DIFFERENT1:
329                     return k310CoherentDifferent4AttachmentFS1;
330                 case GLSL310_4ATTACHMENT_DIFFERENT2:
331                     return k310CoherentDifferent4AttachmentFS2;
332                 default:
333                     UNREACHABLE();
334                     return nullptr;
335             }
336         }
337         else
338         {
339             switch (whichFragmentShader)
340             {
341                 case GLSL100:
342                     return k100NonCoherentFS;
343                 case GLSL310_NO_FETCH_1ATTACHMENT:
344                     return k310NoFetch1AttachmentFS;
345                 case GLSL310_1ATTACHMENT:
346                     return k310NonCoherent1AttachmentFS;
347                 case GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER:
348                     return k310NonCoherentStorageBuffer;
349                 case GLSL310_4ATTACHMENT:
350                     return k310NonCoherent4AttachmentFS;
351                 case GLSL310_4ATTACHMENT_ARRAY:
352                     return k310NonCoherent4AttachmentArrayFS;
353                 case GLSL310_4ATTACHMENT_DIFFERENT1:
354                     return k310NonCoherentDifferent4AttachmentFS1;
355                 case GLSL310_4ATTACHMENT_DIFFERENT2:
356                     return k310NonCoherentDifferent4AttachmentFS2;
357                 default:
358                     UNREACHABLE();
359                     return nullptr;
360             }
361         }
362     }
363 
render(GLuint coordLoc,GLboolean needsFramebufferFetchBarrier)364     void render(GLuint coordLoc, GLboolean needsFramebufferFetchBarrier)
365     {
366         const GLfloat coords[] = {
367             -1.0f, -1.0f, +1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f,
368         };
369 
370         const GLushort indices[] = {
371             0, 1, 2, 2, 3, 0,
372         };
373 
374         glViewport(0, 0, kViewportWidth, kViewportHeight);
375 
376         GLBuffer coordinatesBuffer;
377         GLBuffer elementsBuffer;
378 
379         glBindBuffer(GL_ARRAY_BUFFER, coordinatesBuffer);
380         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW);
381         glEnableVertexAttribArray(coordLoc);
382         glVertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
383 
384         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementsBuffer);
385         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)sizeof(indices), &indices[0],
386                      GL_STATIC_DRAW);
387 
388         if (needsFramebufferFetchBarrier)
389         {
390             glFramebufferFetchBarrierEXT();
391         }
392 
393         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
394 
395         ASSERT_GL_NO_ERROR();
396     }
397 
BasicTest(GLProgram program)398     void BasicTest(GLProgram program)
399     {
400         GLFramebuffer framebuffer;
401         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
402         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
403         GLTexture colorBufferTex;
404         glBindTexture(GL_TEXTURE_2D, colorBufferTex);
405         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
406                      GL_UNSIGNED_BYTE, greenColor.data());
407         glBindTexture(GL_TEXTURE_2D, 0);
408         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
409                                0);
410 
411         ASSERT_GL_NO_ERROR();
412 
413         float color[4]      = {1.0f, 0.0f, 0.0f, 1.0f};
414         GLint colorLocation = glGetUniformLocation(program, "u_color");
415         glUniform4fv(colorLocation, 1, color);
416 
417         GLint positionLocation = glGetAttribLocation(program, "a_position");
418         render(positionLocation, !mCoherentExtension);
419 
420         ASSERT_GL_NO_ERROR();
421 
422         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
423 
424         glBindFramebuffer(GL_FRAMEBUFFER, 0);
425     }
426 
MultipleRenderTargetTest(GLProgram program)427     void MultipleRenderTargetTest(GLProgram program)
428     {
429         GLFramebuffer framebuffer;
430         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
431         std::vector<GLColor> color0(kViewportWidth * kViewportHeight, GLColor::black);
432         std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
433         std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
434         std::vector<GLColor> color3(kViewportWidth * kViewportHeight, GLColor::cyan);
435         GLTexture colorBufferTex[kMaxColorBuffer];
436         GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
437                                                     GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
438         glBindTexture(GL_TEXTURE_2D, colorBufferTex[0]);
439         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
440                      GL_UNSIGNED_BYTE, color0.data());
441         glBindTexture(GL_TEXTURE_2D, colorBufferTex[1]);
442         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
443                      GL_UNSIGNED_BYTE, color1.data());
444         glBindTexture(GL_TEXTURE_2D, colorBufferTex[2]);
445         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
446                      GL_UNSIGNED_BYTE, color2.data());
447         glBindTexture(GL_TEXTURE_2D, colorBufferTex[3]);
448         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
449                      GL_UNSIGNED_BYTE, color3.data());
450         glBindTexture(GL_TEXTURE_2D, 0);
451         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
452         {
453             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
454                                    colorBufferTex[i], 0);
455         }
456         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
457 
458         ASSERT_GL_NO_ERROR();
459 
460         float color[4]      = {1.0f, 0.0f, 0.0f, 1.0f};
461         GLint colorLocation = glGetUniformLocation(program, "u_color");
462         glUniform4fv(colorLocation, 1, color);
463 
464         GLint positionLocation = glGetAttribLocation(program, "a_position");
465         render(positionLocation, !mCoherentExtension);
466 
467         ASSERT_GL_NO_ERROR();
468 
469         glReadBuffer(colorAttachments[0]);
470         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
471         glReadBuffer(colorAttachments[1]);
472         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
473         glReadBuffer(colorAttachments[2]);
474         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
475         glReadBuffer(colorAttachments[3]);
476         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::white);
477 
478         glBindFramebuffer(GL_FRAMEBUFFER, 0);
479     }
480 
MultipleRenderTargetArrayTest(GLProgram program)481     void MultipleRenderTargetArrayTest(GLProgram program)
482     {
483         GLFramebuffer framebuffer;
484         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
485         std::vector<GLColor> color0(kViewportWidth * kViewportHeight, GLColor::black);
486         std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
487         std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
488         std::vector<GLColor> color3(kViewportWidth * kViewportHeight, GLColor::cyan);
489         GLTexture colorBufferTex[kMaxColorBuffer];
490         GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
491                                                     GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
492         glBindTexture(GL_TEXTURE_2D, colorBufferTex[0]);
493         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
494                      GL_UNSIGNED_BYTE, color0.data());
495         glBindTexture(GL_TEXTURE_2D, colorBufferTex[1]);
496         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
497                      GL_UNSIGNED_BYTE, color1.data());
498         glBindTexture(GL_TEXTURE_2D, colorBufferTex[2]);
499         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
500                      GL_UNSIGNED_BYTE, color2.data());
501         glBindTexture(GL_TEXTURE_2D, colorBufferTex[3]);
502         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
503                      GL_UNSIGNED_BYTE, color3.data());
504         glBindTexture(GL_TEXTURE_2D, 0);
505         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
506         {
507             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
508                                    colorBufferTex[i], 0);
509         }
510         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
511 
512         ASSERT_GL_NO_ERROR();
513 
514         float color[4]      = {1.0f, 0.0f, 0.0f, 1.0f};
515         GLint colorLocation = glGetUniformLocation(program, "u_color");
516         glUniform4fv(colorLocation, 1, color);
517 
518         GLint positionLocation = glGetAttribLocation(program, "a_position");
519         render(positionLocation, !mCoherentExtension);
520 
521         ASSERT_GL_NO_ERROR();
522 
523         glReadBuffer(colorAttachments[0]);
524         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
525         glReadBuffer(colorAttachments[1]);
526         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
527         glReadBuffer(colorAttachments[2]);
528         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
529         glReadBuffer(colorAttachments[3]);
530         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::white);
531 
532         glBindFramebuffer(GL_FRAMEBUFFER, 0);
533     }
534 
MultipleDrawTest(GLProgram program)535     void MultipleDrawTest(GLProgram program)
536     {
537         GLFramebuffer framebuffer;
538         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
539         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
540         GLTexture colorBufferTex;
541         glBindTexture(GL_TEXTURE_2D, colorBufferTex);
542         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
543                      GL_UNSIGNED_BYTE, greenColor.data());
544         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
545                                0);
546 
547         ASSERT_GL_NO_ERROR();
548 
549         float color1[4]     = {1.0f, 0.0f, 0.0f, 1.0f};
550         GLint colorLocation = glGetUniformLocation(program, "u_color");
551         glUniform4fv(colorLocation, 1, color1);
552 
553         GLint positionLocation = glGetAttribLocation(program, "a_position");
554         render(positionLocation, !mCoherentExtension);
555 
556         float color2[4] = {0.0f, 0.0f, 1.0f, 1.0f};
557         glUniform4fv(colorLocation, 1, color2);
558 
559         render(positionLocation, !mCoherentExtension);
560 
561         ASSERT_GL_NO_ERROR();
562 
563         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::white);
564 
565         glBindFramebuffer(GL_FRAMEBUFFER, 0);
566     }
567 
DrawNonFetchDrawFetchTest(GLProgram programNonFetch,GLProgram programFetch)568     void DrawNonFetchDrawFetchTest(GLProgram programNonFetch, GLProgram programFetch)
569     {
570         glUseProgram(programNonFetch);
571         ASSERT_GL_NO_ERROR();
572 
573         GLFramebuffer framebuffer;
574         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
575         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
576         GLTexture colorBufferTex;
577         glBindTexture(GL_TEXTURE_2D, colorBufferTex);
578         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
579                      GL_UNSIGNED_BYTE, greenColor.data());
580         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
581                                0);
582 
583         ASSERT_GL_NO_ERROR();
584 
585         float colorRed[4]           = {1.0f, 0.0f, 0.0f, 1.0f};
586         GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
587         glUniform4fv(colorLocationNonFetch, 1, colorRed);
588 
589         GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
590         // Render without regard to glFramebufferFetchBarrierEXT()
591         render(positionLocationNonFetch, GL_FALSE);
592 
593         ASSERT_GL_NO_ERROR();
594 
595         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
596 
597         glUseProgram(programFetch);
598 
599         float colorGreen[4]      = {0.0f, 1.0f, 0.0f, 1.0f};
600         GLint colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
601         glUniform4fv(colorLocationFetch, 1, colorGreen);
602 
603         GLint positionLocationFetch = glGetAttribLocation(programFetch, "a_position");
604         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
605         // extension being used
606         render(positionLocationFetch, !mCoherentExtension);
607 
608         ASSERT_GL_NO_ERROR();
609 
610         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
611 
612         glUseProgram(programNonFetch);
613         glUniform4fv(colorLocationNonFetch, 1, colorRed);
614         // Render without regard to glFramebufferFetchBarrierEXT()
615         render(positionLocationNonFetch, GL_FALSE);
616 
617         ASSERT_GL_NO_ERROR();
618 
619         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
620 
621         glUseProgram(programFetch);
622         glUniform4fv(colorLocationFetch, 1, colorGreen);
623         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
624         // extension being used
625         render(positionLocationFetch, !mCoherentExtension);
626 
627         ASSERT_GL_NO_ERROR();
628 
629         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
630 
631         glBindFramebuffer(GL_FRAMEBUFFER, 0);
632     }
633 
DrawFetchDrawNonFetchTest(GLProgram programNonFetch,GLProgram programFetch)634     void DrawFetchDrawNonFetchTest(GLProgram programNonFetch, GLProgram programFetch)
635     {
636         glUseProgram(programFetch);
637         ASSERT_GL_NO_ERROR();
638 
639         GLFramebuffer framebuffer;
640         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
641         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
642         GLTexture colorBufferTex;
643         glBindTexture(GL_TEXTURE_2D, colorBufferTex);
644         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
645                      GL_UNSIGNED_BYTE, greenColor.data());
646         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
647                                0);
648 
649         ASSERT_GL_NO_ERROR();
650 
651         float colorRed[4]        = {1.0f, 0.0f, 0.0f, 1.0f};
652         GLint colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
653         glUniform4fv(colorLocationFetch, 1, colorRed);
654 
655         GLint positionLocationFetch = glGetAttribLocation(programFetch, "a_position");
656         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
657         // extension being used
658         render(positionLocationFetch, !mCoherentExtension);
659         ASSERT_GL_NO_ERROR();
660 
661         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
662 
663         glUseProgram(programNonFetch);
664 
665         GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
666         glUniform4fv(colorLocationNonFetch, 1, colorRed);
667 
668         GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
669         // Render without regard to glFramebufferFetchBarrierEXT()
670         render(positionLocationNonFetch, GL_FALSE);
671         ASSERT_GL_NO_ERROR();
672 
673         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
674 
675         float colorGreen[4] = {0.0f, 1.0f, 0.0f, 1.0f};
676         glUseProgram(programFetch);
677         glUniform4fv(colorLocationFetch, 1, colorGreen);
678         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
679         // extension being used
680         render(positionLocationFetch, !mCoherentExtension);
681         ASSERT_GL_NO_ERROR();
682 
683         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
684 
685         glUseProgram(programNonFetch);
686         glUniform4fv(colorLocationNonFetch, 1, colorRed);
687         // Render without regard to glFramebufferFetchBarrierEXT()
688         render(positionLocationNonFetch, GL_FALSE);
689 
690         ASSERT_GL_NO_ERROR();
691 
692         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
693 
694         glBindFramebuffer(GL_FRAMEBUFFER, 0);
695     }
696 
697     enum class StorageBufferTestPostFetchAction
698     {
699         Nothing,
700         Clear,
701     };
702 
DrawNonFetchDrawFetchInStorageBufferTest(GLProgram programNonFetch,GLProgram programFetch,StorageBufferTestPostFetchAction postFetchAction)703     void DrawNonFetchDrawFetchInStorageBufferTest(GLProgram programNonFetch,
704                                                   GLProgram programFetch,
705                                                   StorageBufferTestPostFetchAction postFetchAction)
706     {
707         // Create output buffer
708         constexpr GLsizei kBufferSize = kViewportWidth * kViewportHeight * sizeof(float[4]);
709         GLBuffer buffer;
710         glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
711         glBufferData(GL_SHADER_STORAGE_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
712         glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, buffer, 0, kBufferSize);
713 
714         // Zero-initialize it
715         void *bufferData = glMapBufferRange(
716             GL_SHADER_STORAGE_BUFFER, 0, kBufferSize,
717             GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
718         memset(bufferData, 0, kBufferSize);
719         glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
720 
721         glUseProgram(programNonFetch);
722         ASSERT_GL_NO_ERROR();
723 
724         GLFramebuffer framebuffer;
725         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
726         std::vector<GLColor> initColor(kViewportWidth * kViewportHeight, GLColor{10, 20, 30, 40});
727         GLTexture colorBufferTex;
728         glBindTexture(GL_TEXTURE_2D, colorBufferTex);
729         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
730                      GL_UNSIGNED_BYTE, initColor.data());
731         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
732                                0);
733 
734         ASSERT_GL_NO_ERROR();
735 
736         float colorRed[4]           = {1.0f, 0.0f, 0.0f, 1.0f};
737         GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
738         glUniform4fv(colorLocationNonFetch, 1, colorRed);
739 
740         GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
741 
742         // Mask color output.  The no-fetch draw call should be a no-op, and the fetch draw-call
743         // should only output to the storage buffer, but not the color attachment.
744         glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
745 
746         // Render without regard to glFramebufferFetchBarrierEXT()
747         render(positionLocationNonFetch, GL_FALSE);
748 
749         ASSERT_GL_NO_ERROR();
750 
751         glUseProgram(programFetch);
752 
753         float colorBlue[4]       = {0.0f, 0.0f, 1.0f, 1.0f};
754         GLint colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
755         glUniform4fv(colorLocationFetch, 1, colorBlue);
756 
757         GLint positionLocationFetch = glGetAttribLocation(programFetch, "a_position");
758         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
759         // extension being used
760         render(positionLocationFetch, !mCoherentExtension);
761 
762         ASSERT_GL_NO_ERROR();
763 
764         // Enable the color mask and clear the alpha channel.  This shouldn't be reordered with the
765         // fetch draw.
766         GLColor expect = initColor[0];
767         if (postFetchAction == StorageBufferTestPostFetchAction::Clear)
768         {
769             expect.A = 200;
770             glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
771             glClearColor(0.5, 0.6, 0.7, expect.A / 255.0f);
772             glClear(GL_COLOR_BUFFER_BIT);
773         }
774 
775         // Since color is completely masked out, the texture should retain its original green color.
776         EXPECT_PIXEL_COLOR_NEAR(kViewportWidth / 2, kViewportHeight / 2, expect, 1);
777 
778         // Read back the storage buffer and make sure framebuffer fetch worked as intended despite
779         // masked color.
780         glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
781 
782         const float *colorData = static_cast<const float *>(
783             glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kBufferSize, GL_MAP_READ_BIT));
784         for (uint32_t y = 0; y < kViewportHeight; ++y)
785         {
786             for (uint32_t x = 0; x < kViewportWidth; ++x)
787             {
788                 uint32_t ssboIndex = (y * kViewportWidth + x) * 4;
789                 EXPECT_NEAR(colorData[ssboIndex + 0], initColor[0].R / 255.0, 0.05);
790                 EXPECT_NEAR(colorData[ssboIndex + 1], initColor[0].G / 255.0, 0.05);
791                 EXPECT_NEAR(colorData[ssboIndex + 2], initColor[0].B / 255.0, 0.05);
792                 EXPECT_NEAR(colorData[ssboIndex + 3], initColor[0].A / 255.0, 0.05);
793             }
794         }
795         glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
796 
797         glBindFramebuffer(GL_FRAMEBUFFER, 0);
798     }
799 
DrawNonFetchDrawFetchWithDifferentAttachmentsTest(GLProgram programNonFetch,GLProgram programFetch)800     void DrawNonFetchDrawFetchWithDifferentAttachmentsTest(GLProgram programNonFetch,
801                                                            GLProgram programFetch)
802     {
803         glUseProgram(programNonFetch);
804         ASSERT_GL_NO_ERROR();
805 
806         GLFramebuffer framebuffer;
807         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
808         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
809         GLTexture colorTex;
810         glBindTexture(GL_TEXTURE_2D, colorTex);
811         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
812                      GL_UNSIGNED_BYTE, greenColor.data());
813         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
814 
815         ASSERT_GL_NO_ERROR();
816 
817         float colorRed[4]           = {1.0f, 0.0f, 0.0f, 1.0f};
818         GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
819         glUniform4fv(colorLocationNonFetch, 1, colorRed);
820 
821         GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
822         // Render without regard to glFramebufferFetchBarrierEXT()
823         render(positionLocationNonFetch, GL_FALSE);
824         ASSERT_GL_NO_ERROR();
825 
826         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
827 
828         glUseProgram(programFetch);
829         ASSERT_GL_NO_ERROR();
830 
831         GLFramebuffer framebufferMRT1;
832         glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT1);
833         std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
834         std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
835         GLTexture colorBufferTex1[kMaxColorBuffer];
836         GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
837                                                     GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
838         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[0]);
839         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
840                      GL_UNSIGNED_BYTE, color1.data());
841         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[1]);
842         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
843                      GL_UNSIGNED_BYTE, color1.data());
844         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[2]);
845         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
846                      GL_UNSIGNED_BYTE, color2.data());
847         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[3]);
848         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
849                      GL_UNSIGNED_BYTE, color2.data());
850         glBindTexture(GL_TEXTURE_2D, 0);
851         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
852         {
853             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
854                                    colorBufferTex1[i], 0);
855         }
856         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
857         ASSERT_GL_NO_ERROR();
858 
859         GLint colorLocation = glGetUniformLocation(programFetch, "u_color");
860         glUniform4fv(colorLocation, 1, colorRed);
861 
862         GLint positionLocation = glGetAttribLocation(programFetch, "a_position");
863         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
864         // extension being used
865         render(positionLocation, !mCoherentExtension);
866         ASSERT_GL_NO_ERROR();
867 
868         glReadBuffer(colorAttachments[0]);
869         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
870         glReadBuffer(colorAttachments[1]);
871         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
872         glReadBuffer(colorAttachments[2]);
873         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
874         glReadBuffer(colorAttachments[3]);
875         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
876 
877         GLFramebuffer framebufferMRT2;
878         glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT2);
879         GLTexture colorBufferTex2[kMaxColorBuffer];
880         glBindTexture(GL_TEXTURE_2D, colorBufferTex2[0]);
881         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
882                      GL_UNSIGNED_BYTE, color2.data());
883         glBindTexture(GL_TEXTURE_2D, colorBufferTex2[1]);
884         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
885                      GL_UNSIGNED_BYTE, color2.data());
886         glBindTexture(GL_TEXTURE_2D, colorBufferTex2[2]);
887         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
888                      GL_UNSIGNED_BYTE, color1.data());
889         glBindTexture(GL_TEXTURE_2D, colorBufferTex2[3]);
890         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
891                      GL_UNSIGNED_BYTE, color1.data());
892         glBindTexture(GL_TEXTURE_2D, 0);
893         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
894         {
895             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
896                                    colorBufferTex2[i], 0);
897         }
898         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
899         ASSERT_GL_NO_ERROR();
900 
901         glUniform4fv(colorLocation, 1, colorRed);
902         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
903         // extension being used
904         render(positionLocation, !mCoherentExtension);
905         ASSERT_GL_NO_ERROR();
906 
907         glReadBuffer(colorAttachments[0]);
908         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
909         glReadBuffer(colorAttachments[1]);
910         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
911         glReadBuffer(colorAttachments[2]);
912         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
913         glReadBuffer(colorAttachments[3]);
914         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
915 
916         glBindFramebuffer(GL_FRAMEBUFFER, 0);
917     }
918 
DrawNonFetchDrawFetchWithDifferentProgramsTest(GLProgram programNonFetch,GLProgram programFetch1,GLProgram programFetch2)919     void DrawNonFetchDrawFetchWithDifferentProgramsTest(GLProgram programNonFetch,
920                                                         GLProgram programFetch1,
921                                                         GLProgram programFetch2)
922     {
923         glUseProgram(programNonFetch);
924         ASSERT_GL_NO_ERROR();
925         GLFramebuffer framebuffer;
926         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
927         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
928         GLTexture colorTex;
929         glBindTexture(GL_TEXTURE_2D, colorTex);
930         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
931                      GL_UNSIGNED_BYTE, greenColor.data());
932         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
933 
934         ASSERT_GL_NO_ERROR();
935 
936         float colorRed[4]           = {1.0f, 0.0f, 0.0f, 1.0f};
937         GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
938         glUniform4fv(colorLocationNonFetch, 1, colorRed);
939 
940         GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
941         // Render without regard to glFramebufferFetchBarrierEXT()
942         render(positionLocationNonFetch, GL_FALSE);
943         ASSERT_GL_NO_ERROR();
944 
945         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
946 
947         glUseProgram(programFetch1);
948         ASSERT_GL_NO_ERROR();
949 
950         GLFramebuffer framebufferMRT1;
951         glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT1);
952         std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
953         GLTexture colorBufferTex1[kMaxColorBuffer];
954         GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
955                                                     GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
956         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[0]);
957         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
958                      GL_UNSIGNED_BYTE, color1.data());
959         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[1]);
960         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
961                      GL_UNSIGNED_BYTE, color1.data());
962         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[2]);
963         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
964                      GL_UNSIGNED_BYTE, color1.data());
965         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[3]);
966         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
967                      GL_UNSIGNED_BYTE, color1.data());
968         glBindTexture(GL_TEXTURE_2D, 0);
969         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
970         {
971             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
972                                    colorBufferTex1[i], 0);
973         }
974         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
975         ASSERT_GL_NO_ERROR();
976 
977         GLint colorLocation = glGetUniformLocation(programFetch1, "u_color");
978         glUniform4fv(colorLocation, 1, colorRed);
979 
980         GLint positionLocation = glGetAttribLocation(programFetch1, "a_position");
981         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
982         // extension being used
983         render(positionLocation, !mCoherentExtension);
984         ASSERT_GL_NO_ERROR();
985 
986         glReadBuffer(colorAttachments[0]);
987         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
988         glReadBuffer(colorAttachments[1]);
989         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
990         glReadBuffer(colorAttachments[2]);
991         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
992         glReadBuffer(colorAttachments[3]);
993         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
994 
995         glUseProgram(programFetch2);
996         ASSERT_GL_NO_ERROR();
997 
998         glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
999         glClear(GL_COLOR_BUFFER_BIT);
1000 
1001         GLint colorLocation1 = glGetUniformLocation(programFetch2, "u_color");
1002         glUniform4fv(colorLocation1, 1, colorRed);
1003 
1004         GLint positionLocation1 = glGetAttribLocation(programFetch2, "a_position");
1005         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1006         // extension being used
1007         render(positionLocation1, !mCoherentExtension);
1008         ASSERT_GL_NO_ERROR();
1009 
1010         glReadBuffer(colorAttachments[0]);
1011         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1012         glReadBuffer(colorAttachments[1]);
1013         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1014         glReadBuffer(colorAttachments[2]);
1015         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1016         glReadBuffer(colorAttachments[3]);
1017         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1018 
1019         glBindFramebuffer(GL_FRAMEBUFFER, 0);
1020     }
1021 
DrawFetchBlitDrawFetchTest(GLProgram programNonFetch,GLProgram programFetch)1022     void DrawFetchBlitDrawFetchTest(GLProgram programNonFetch, GLProgram programFetch)
1023     {
1024         glUseProgram(programFetch);
1025         ASSERT_GL_NO_ERROR();
1026 
1027         GLFramebuffer framebufferMRT1;
1028         glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT1);
1029         std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
1030         std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
1031         GLTexture colorBufferTex1[kMaxColorBuffer];
1032         GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
1033                                                     GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
1034         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[0]);
1035         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1036                      GL_UNSIGNED_BYTE, color1.data());
1037         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[1]);
1038         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1039                      GL_UNSIGNED_BYTE, color1.data());
1040         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[2]);
1041         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1042                      GL_UNSIGNED_BYTE, color2.data());
1043         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[3]);
1044         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1045                      GL_UNSIGNED_BYTE, color2.data());
1046         glBindTexture(GL_TEXTURE_2D, 0);
1047         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
1048         {
1049             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
1050                                    colorBufferTex1[i], 0);
1051         }
1052         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
1053         ASSERT_GL_NO_ERROR();
1054 
1055         float colorRed[4]   = {1.0f, 0.0f, 0.0f, 1.0f};
1056         GLint colorLocation = glGetUniformLocation(programFetch, "u_color");
1057         glUniform4fv(colorLocation, 1, colorRed);
1058 
1059         GLint positionLocation = glGetAttribLocation(programFetch, "a_position");
1060         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1061         // extension being used
1062         render(positionLocation, !mCoherentExtension);
1063         ASSERT_GL_NO_ERROR();
1064 
1065         glReadBuffer(colorAttachments[0]);
1066         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1067         glReadBuffer(colorAttachments[1]);
1068         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1069         glReadBuffer(colorAttachments[2]);
1070         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
1071         glReadBuffer(colorAttachments[3]);
1072         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1073 
1074         GLFramebuffer framebufferColor;
1075         glBindFramebuffer(GL_FRAMEBUFFER, framebufferColor);
1076 
1077         GLTexture colorTex;
1078         glBindTexture(GL_TEXTURE_2D, colorTex);
1079         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1080                      GL_UNSIGNED_BYTE, color2.data());
1081         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
1082 
1083         glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, framebufferColor);
1084         glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, framebufferMRT1);
1085 
1086         glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth,
1087                           kViewportHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1088         ASSERT_GL_NO_ERROR();
1089 
1090         glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT1);
1091         glReadBuffer(colorAttachments[0]);
1092         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
1093         glReadBuffer(colorAttachments[1]);
1094         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
1095         glReadBuffer(colorAttachments[2]);
1096         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
1097         glReadBuffer(colorAttachments[3]);
1098         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
1099 
1100         float colorGreen[4] = {0.0f, 1.0f, 0.0f, 1.0f};
1101         glUniform4fv(colorLocation, 1, colorGreen);
1102 
1103         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1104         // extension being used
1105         render(positionLocation, !mCoherentExtension);
1106         ASSERT_GL_NO_ERROR();
1107 
1108         glReadBuffer(colorAttachments[0]);
1109         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::cyan);
1110         glReadBuffer(colorAttachments[1]);
1111         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
1112         glReadBuffer(colorAttachments[2]);
1113         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::cyan);
1114         glReadBuffer(colorAttachments[3]);
1115         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
1116 
1117         glBindFramebuffer(GL_FRAMEBUFFER, 0);
1118     }
1119 
ProgramPipelineTest(const char * kVS,const char * kFS1,const char * kFS2)1120     void ProgramPipelineTest(const char *kVS, const char *kFS1, const char *kFS2)
1121     {
1122         GLProgram programVert, programNonFetch, programFetch;
1123         const char *sourceArray[3] = {kVS, kFS1, kFS2};
1124 
1125         GLShader vertShader(GL_VERTEX_SHADER);
1126         glShaderSource(vertShader, 1, &sourceArray[0], nullptr);
1127         glCompileShader(vertShader);
1128         glProgramParameteri(programVert, GL_PROGRAM_SEPARABLE, GL_TRUE);
1129         glAttachShader(programVert, vertShader);
1130         glLinkProgram(programVert);
1131         ASSERT_GL_NO_ERROR();
1132 
1133         GLShader fragShader1(GL_FRAGMENT_SHADER);
1134         glShaderSource(fragShader1, 1, &sourceArray[1], nullptr);
1135         glCompileShader(fragShader1);
1136         glProgramParameteri(programNonFetch, GL_PROGRAM_SEPARABLE, GL_TRUE);
1137         glAttachShader(programNonFetch, fragShader1);
1138         glLinkProgram(programNonFetch);
1139         ASSERT_GL_NO_ERROR();
1140 
1141         GLShader fragShader2(GL_FRAGMENT_SHADER);
1142         glShaderSource(fragShader2, 1, &sourceArray[2], nullptr);
1143         glCompileShader(fragShader2);
1144         glProgramParameteri(programFetch, GL_PROGRAM_SEPARABLE, GL_TRUE);
1145         glAttachShader(programFetch, fragShader2);
1146         glLinkProgram(programFetch);
1147         ASSERT_GL_NO_ERROR();
1148 
1149         GLProgramPipeline pipeline1, pipeline2, pipeline3, pipeline4;
1150         glUseProgramStages(pipeline1, GL_VERTEX_SHADER_BIT, programVert);
1151         glUseProgramStages(pipeline1, GL_FRAGMENT_SHADER_BIT, programNonFetch);
1152         glBindProgramPipeline(pipeline1);
1153         ASSERT_GL_NO_ERROR();
1154 
1155         GLFramebuffer framebuffer;
1156         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1157         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
1158         GLTexture colorBufferTex;
1159         glBindTexture(GL_TEXTURE_2D, colorBufferTex);
1160         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1161                      GL_UNSIGNED_BYTE, greenColor.data());
1162         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
1163                                0);
1164         ASSERT_GL_NO_ERROR();
1165 
1166         glActiveShaderProgram(pipeline1, programNonFetch);
1167         float colorRed[4]           = {1.0f, 0.0f, 0.0f, 1.0f};
1168         GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
1169         glUniform4fv(colorLocationNonFetch, 1, colorRed);
1170         ASSERT_GL_NO_ERROR();
1171 
1172         glActiveShaderProgram(pipeline1, programVert);
1173         GLint positionLocation = glGetAttribLocation(programVert, "a_position");
1174         // Render without regard to glFramebufferFetchBarrierEXT()
1175         render(positionLocation, GL_FALSE);
1176         ASSERT_GL_NO_ERROR();
1177 
1178         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1179 
1180         glUseProgramStages(pipeline2, GL_VERTEX_SHADER_BIT, programVert);
1181         glUseProgramStages(pipeline2, GL_FRAGMENT_SHADER_BIT, programFetch);
1182         glBindProgramPipeline(pipeline2);
1183         ASSERT_GL_NO_ERROR();
1184 
1185         glActiveShaderProgram(pipeline2, programFetch);
1186         float colorGreen[4]      = {0.0f, 1.0f, 0.0f, 1.0f};
1187         GLint colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
1188         glUniform4fv(colorLocationFetch, 1, colorGreen);
1189 
1190         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1191         // extension being used
1192         render(positionLocation, !mCoherentExtension);
1193         ASSERT_GL_NO_ERROR();
1194 
1195         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1196 
1197         glUseProgramStages(pipeline3, GL_VERTEX_SHADER_BIT, programVert);
1198         glUseProgramStages(pipeline3, GL_FRAGMENT_SHADER_BIT, programNonFetch);
1199         glBindProgramPipeline(pipeline3);
1200         ASSERT_GL_NO_ERROR();
1201 
1202         glActiveShaderProgram(pipeline3, programNonFetch);
1203         colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
1204         glUniform4fv(colorLocationNonFetch, 1, colorRed);
1205 
1206         ASSERT_GL_NO_ERROR();
1207 
1208         // Render without regard to glFramebufferFetchBarrierEXT()
1209         render(positionLocation, GL_FALSE);
1210         ASSERT_GL_NO_ERROR();
1211 
1212         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1213 
1214         glUseProgramStages(pipeline4, GL_VERTEX_SHADER_BIT, programVert);
1215         glUseProgramStages(pipeline4, GL_FRAGMENT_SHADER_BIT, programFetch);
1216         glBindProgramPipeline(pipeline4);
1217         ASSERT_GL_NO_ERROR();
1218 
1219         glActiveShaderProgram(pipeline4, programFetch);
1220         colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
1221         glUniform4fv(colorLocationFetch, 1, colorGreen);
1222         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1223         // extension being used
1224         render(positionLocation, !mCoherentExtension);
1225         ASSERT_GL_NO_ERROR();
1226 
1227         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1228 
1229         glBindFramebuffer(GL_FRAMEBUFFER, 0);
1230     }
1231 
1232     bool mCoherentExtension;
1233 };
1234 
1235 // Test coherent extension with inout qualifier
TEST_P(FramebufferFetchES31,BasicInout_Coherent)1236 TEST_P(FramebufferFetchES31, BasicInout_Coherent)
1237 {
1238     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1239     setWhichExtension(COHERENT);
1240 
1241     GLProgram program;
1242     program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1243     glUseProgram(program);
1244     ASSERT_GL_NO_ERROR();
1245 
1246     BasicTest(program);
1247 }
1248 
1249 // Test non-coherent extension with inout qualifier
TEST_P(FramebufferFetchES31,BasicInout_NonCoherent)1250 TEST_P(FramebufferFetchES31, BasicInout_NonCoherent)
1251 {
1252     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1253     setWhichExtension(NON_COHERENT);
1254 
1255     GLProgram program;
1256     program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1257     glUseProgram(program);
1258     ASSERT_GL_NO_ERROR();
1259 
1260     BasicTest(program);
1261 }
1262 
1263 // Test coherent extension with gl_LastFragData
TEST_P(FramebufferFetchES31,BasicLastFragData_Coherent)1264 TEST_P(FramebufferFetchES31, BasicLastFragData_Coherent)
1265 {
1266     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1267     setWhichExtension(COHERENT);
1268 
1269     GLProgram program;
1270     program.makeRaster(k100VS, getFragmentShader(GLSL100));
1271     glUseProgram(program);
1272     ASSERT_GL_NO_ERROR();
1273 
1274     BasicTest(program);
1275 }
1276 
1277 // Test non-coherent extension with gl_LastFragData
TEST_P(FramebufferFetchES31,BasicLastFragData_NonCoherent)1278 TEST_P(FramebufferFetchES31, BasicLastFragData_NonCoherent)
1279 {
1280     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1281     setWhichExtension(NON_COHERENT);
1282 
1283     GLProgram program;
1284     program.makeRaster(k100VS, getFragmentShader(GLSL100));
1285     glUseProgram(program);
1286     ASSERT_GL_NO_ERROR();
1287 
1288     BasicTest(program);
1289 }
1290 
1291 // Testing coherent extension with multiple render target
TEST_P(FramebufferFetchES31,MultipleRenderTarget_Coherent)1292 TEST_P(FramebufferFetchES31, MultipleRenderTarget_Coherent)
1293 {
1294     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1295     setWhichExtension(COHERENT);
1296 
1297     GLProgram program;
1298     program.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT));
1299     glUseProgram(program);
1300     ASSERT_GL_NO_ERROR();
1301 
1302     MultipleRenderTargetTest(program);
1303 }
1304 
1305 // Testing non-coherent extension with multiple render target
TEST_P(FramebufferFetchES31,MultipleRenderTarget_NonCoherent)1306 TEST_P(FramebufferFetchES31, MultipleRenderTarget_NonCoherent)
1307 {
1308     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1309     setWhichExtension(NON_COHERENT);
1310 
1311     GLProgram program;
1312     program.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT));
1313     glUseProgram(program);
1314     ASSERT_GL_NO_ERROR();
1315 
1316     MultipleRenderTargetTest(program);
1317 }
1318 
1319 // Testing non-coherent extension with multiple render target using inout array
TEST_P(FramebufferFetchES31,MultipleRenderTargetWithInoutArray_NonCoherent)1320 TEST_P(FramebufferFetchES31, MultipleRenderTargetWithInoutArray_NonCoherent)
1321 {
1322     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1323     setWhichExtension(NON_COHERENT);
1324 
1325     GLProgram program;
1326     program.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT));
1327     glUseProgram(program);
1328     ASSERT_GL_NO_ERROR();
1329 
1330     MultipleRenderTargetTest(program);
1331 }
1332 
1333 // Testing coherent extension with multiple render target using inout array
TEST_P(FramebufferFetchES31,MultipleRenderTargetWithInoutArray_Coherent)1334 TEST_P(FramebufferFetchES31, MultipleRenderTargetWithInoutArray_Coherent)
1335 {
1336     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1337     setWhichExtension(COHERENT);
1338 
1339     GLProgram program;
1340     program.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT));
1341     glUseProgram(program);
1342     ASSERT_GL_NO_ERROR();
1343 
1344     MultipleRenderTargetTest(program);
1345 }
1346 
1347 // Test coherent extension with multiple draw
TEST_P(FramebufferFetchES31,MultipleDraw_Coherent)1348 TEST_P(FramebufferFetchES31, MultipleDraw_Coherent)
1349 {
1350     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1351     setWhichExtension(COHERENT);
1352 
1353     GLProgram program;
1354     program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1355     glUseProgram(program);
1356     ASSERT_GL_NO_ERROR();
1357 
1358     MultipleDrawTest(program);
1359 }
1360 
1361 // Test non-coherent extension with multiple draw
TEST_P(FramebufferFetchES31,MultipleDraw_NonCoherent)1362 TEST_P(FramebufferFetchES31, MultipleDraw_NonCoherent)
1363 {
1364     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1365     setWhichExtension(NON_COHERENT);
1366 
1367     GLProgram program;
1368     program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1369     glUseProgram(program);
1370     ASSERT_GL_NO_ERROR();
1371 
1372     MultipleDrawTest(program);
1373 }
1374 
1375 // Testing coherent extension with the order of non-fetch program and fetch program
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetch_Coherent)1376 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetch_Coherent)
1377 {
1378     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1379     setWhichExtension(COHERENT);
1380 
1381     GLProgram programNonFetch, programFetch;
1382     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1383     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1384     ASSERT_GL_NO_ERROR();
1385 
1386     DrawNonFetchDrawFetchTest(programNonFetch, programFetch);
1387 }
1388 
1389 // Testing non-coherent extension with the order of non-fetch program and fetch program
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetch_NonCoherent)1390 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetch_NonCoherent)
1391 {
1392     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1393     setWhichExtension(NON_COHERENT);
1394 
1395     GLProgram programNonFetch, programFetch;
1396     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1397     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1398     ASSERT_GL_NO_ERROR();
1399 
1400     DrawNonFetchDrawFetchTest(programNonFetch, programFetch);
1401 }
1402 
1403 // Testing coherent extension with the order of fetch program and non-fetch program
TEST_P(FramebufferFetchES31,DrawFetchDrawNonFetch_Coherent)1404 TEST_P(FramebufferFetchES31, DrawFetchDrawNonFetch_Coherent)
1405 {
1406     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1407     setWhichExtension(COHERENT);
1408 
1409     GLProgram programNonFetch, programFetch;
1410     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1411     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1412     ASSERT_GL_NO_ERROR();
1413 
1414     DrawFetchDrawNonFetchTest(programNonFetch, programFetch);
1415 }
1416 
1417 // Testing non-coherent extension with the order of fetch program and non-fetch program
TEST_P(FramebufferFetchES31,DrawFetchDrawNonFetch_NonCoherent)1418 TEST_P(FramebufferFetchES31, DrawFetchDrawNonFetch_NonCoherent)
1419 {
1420     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1421     setWhichExtension(NON_COHERENT);
1422 
1423     GLProgram programNonFetch, programFetch;
1424     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1425     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1426     ASSERT_GL_NO_ERROR();
1427 
1428     DrawFetchDrawNonFetchTest(programNonFetch, programFetch);
1429 }
1430 
1431 // Testing coherent extension with framebuffer fetch read in combination with color attachment mask
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchInStorageBuffer_Coherent)1432 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchInStorageBuffer_Coherent)
1433 {
1434     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1435     setWhichExtension(COHERENT);
1436 
1437     GLint maxFragmentShaderStorageBlocks = 0;
1438     glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
1439     ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks == 0);
1440 
1441     GLProgram programNonFetch, programFetch;
1442     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1443     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER));
1444     ASSERT_GL_NO_ERROR();
1445 
1446     DrawNonFetchDrawFetchInStorageBufferTest(programNonFetch, programFetch,
1447                                              StorageBufferTestPostFetchAction::Nothing);
1448 }
1449 
1450 // Testing non-coherent extension with framebuffer fetch read in combination with color attachment
1451 // mask
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchInStorageBuffer_NonCoherent)1452 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchInStorageBuffer_NonCoherent)
1453 {
1454     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1455     setWhichExtension(NON_COHERENT);
1456 
1457     GLint maxFragmentShaderStorageBlocks = 0;
1458     glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
1459     ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks == 0);
1460 
1461     GLProgram programNonFetch, programFetch;
1462     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1463     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER));
1464     ASSERT_GL_NO_ERROR();
1465 
1466     DrawNonFetchDrawFetchInStorageBufferTest(programNonFetch, programFetch,
1467                                              StorageBufferTestPostFetchAction::Nothing);
1468 }
1469 
1470 // Testing coherent extension with the order of non-fetch program and fetch program with
1471 // different attachments
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchWithDifferentAttachments_Coherent)1472 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchWithDifferentAttachments_Coherent)
1473 {
1474     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1475     setWhichExtension(COHERENT);
1476 
1477     GLProgram programNonFetch, programFetch;
1478     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1479     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
1480     ASSERT_GL_NO_ERROR();
1481 
1482     DrawNonFetchDrawFetchWithDifferentAttachmentsTest(programNonFetch, programFetch);
1483 }
1484 
1485 // Testing coherent extension with framebuffer fetch read in combination with color attachment mask
1486 // and clear
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchInStorageBufferThenClear_Coherent)1487 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchInStorageBufferThenClear_Coherent)
1488 {
1489     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1490     setWhichExtension(COHERENT);
1491 
1492     GLint maxFragmentShaderStorageBlocks = 0;
1493     glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
1494     ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks == 0);
1495 
1496     GLProgram programNonFetch, programFetch;
1497     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1498     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER));
1499     ASSERT_GL_NO_ERROR();
1500 
1501     DrawNonFetchDrawFetchInStorageBufferTest(programNonFetch, programFetch,
1502                                              StorageBufferTestPostFetchAction::Clear);
1503 }
1504 
1505 // Testing non-coherent extension with framebuffer fetch read in combination with color attachment
1506 // mask and clear
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchInStorageBufferThenClear_NonCoherent)1507 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchInStorageBufferThenClear_NonCoherent)
1508 {
1509     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1510     setWhichExtension(NON_COHERENT);
1511 
1512     GLint maxFragmentShaderStorageBlocks = 0;
1513     glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
1514     ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks == 0);
1515 
1516     GLProgram programNonFetch, programFetch;
1517     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1518     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT_WITH_STORAGE_BUFFER));
1519     ASSERT_GL_NO_ERROR();
1520 
1521     DrawNonFetchDrawFetchInStorageBufferTest(programNonFetch, programFetch,
1522                                              StorageBufferTestPostFetchAction::Clear);
1523 }
1524 
1525 // Testing non-coherent extension with the order of non-fetch program and fetch program with
1526 // different attachments
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchWithDifferentAttachments_NonCoherent)1527 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchWithDifferentAttachments_NonCoherent)
1528 {
1529     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1530     setWhichExtension(NON_COHERENT);
1531 
1532     GLProgram programNonFetch, programFetch;
1533     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1534     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
1535     ASSERT_GL_NO_ERROR();
1536 
1537     DrawNonFetchDrawFetchWithDifferentAttachmentsTest(programNonFetch, programFetch);
1538 }
1539 
1540 // Testing coherent extension with the order of non-fetch program and fetch with different
1541 // programs
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchWithDifferentPrograms_Coherent)1542 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchWithDifferentPrograms_Coherent)
1543 {
1544     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1545     setWhichExtension(COHERENT);
1546 
1547     GLProgram programNonFetch, programFetch1, programFetch2;
1548     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1549     programFetch1.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
1550     programFetch2.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT2));
1551     ASSERT_GL_NO_ERROR();
1552 
1553     DrawNonFetchDrawFetchWithDifferentProgramsTest(programNonFetch, programFetch1, programFetch2);
1554 }
1555 
1556 // Testing non-coherent extension with the order of non-fetch program and fetch with different
1557 // programs
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchWithDifferentPrograms_NonCoherent)1558 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchWithDifferentPrograms_NonCoherent)
1559 {
1560     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1561     setWhichExtension(NON_COHERENT);
1562 
1563     GLProgram programNonFetch, programFetch1, programFetch2;
1564     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1565     programFetch1.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
1566     programFetch2.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT2));
1567     ASSERT_GL_NO_ERROR();
1568 
1569     DrawNonFetchDrawFetchWithDifferentProgramsTest(programNonFetch, programFetch1, programFetch2);
1570 }
1571 
1572 // Testing coherent extension with the order of draw fetch, blit and draw fetch
TEST_P(FramebufferFetchES31,DrawFetchBlitDrawFetch_Coherent)1573 TEST_P(FramebufferFetchES31, DrawFetchBlitDrawFetch_Coherent)
1574 {
1575     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1576     setWhichExtension(COHERENT);
1577 
1578     GLProgram programNonFetch, programFetch;
1579     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1580     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
1581     ASSERT_GL_NO_ERROR();
1582 
1583     DrawFetchBlitDrawFetchTest(programNonFetch, programFetch);
1584 }
1585 
1586 // Testing non-coherent extension with the order of draw fetch, blit and draw fetch
TEST_P(FramebufferFetchES31,DrawFetchBlitDrawFetch_NonCoherent)1587 TEST_P(FramebufferFetchES31, DrawFetchBlitDrawFetch_NonCoherent)
1588 {
1589     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1590     setWhichExtension(NON_COHERENT);
1591 
1592     GLProgram programNonFetch, programFetch;
1593     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1594     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
1595     ASSERT_GL_NO_ERROR();
1596 
1597     DrawFetchBlitDrawFetchTest(programNonFetch, programFetch);
1598 }
1599 
1600 // Testing coherent extension with program pipeline
TEST_P(FramebufferFetchES31,ProgramPipeline_Coherent)1601 TEST_P(FramebufferFetchES31, ProgramPipeline_Coherent)
1602 {
1603     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1604     setWhichExtension(COHERENT);
1605 
1606     ProgramPipelineTest(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT),
1607                         getFragmentShader(GLSL310_1ATTACHMENT));
1608 }
1609 
1610 // Testing non-coherent extension with program pipeline
TEST_P(FramebufferFetchES31,ProgramPipeline_NonCoherent)1611 TEST_P(FramebufferFetchES31, ProgramPipeline_NonCoherent)
1612 {
1613     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1614     setWhichExtension(NON_COHERENT);
1615 
1616     ProgramPipelineTest(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT),
1617                         getFragmentShader(GLSL310_1ATTACHMENT));
1618 }
1619 
1620 // TODO: http://anglebug.com/5792
TEST_P(FramebufferFetchES31,DISABLED_UniformUsageCombinations)1621 TEST_P(FramebufferFetchES31, DISABLED_UniformUsageCombinations)
1622 {
1623     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1624 
1625     constexpr char kVS[] = R"(#version 310 es
1626 in highp vec4 a_position;
1627 out highp vec2 texCoord;
1628 
1629 void main()
1630 {
1631     gl_Position = a_position;
1632     texCoord = (a_position.xy * 0.5) + 0.5;
1633 })";
1634 
1635     constexpr char kFS[] = R"(#version 310 es
1636 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
1637 
1638 layout(binding=0, offset=0) uniform atomic_uint atDiff;
1639 uniform sampler2D tex;
1640 
1641 layout(noncoherent, location = 0) inout highp vec4 o_color[4];
1642 in highp vec2 texCoord;
1643 
1644 void main()
1645 {
1646     highp vec4 texColor = texture(tex, texCoord);
1647 
1648     if (texColor != o_color[0])
1649     {
1650         atomicCounterIncrement(atDiff);
1651         o_color[0] = texColor;
1652     }
1653     else
1654     {
1655         if (atomicCounter(atDiff) > 0u)
1656         {
1657             atomicCounterDecrement(atDiff);
1658         }
1659     }
1660 
1661     if (texColor != o_color[1])
1662     {
1663         atomicCounterIncrement(atDiff);
1664         o_color[1] = texColor;
1665     }
1666     else
1667     {
1668         if (atomicCounter(atDiff) > 0u)
1669         {
1670             atomicCounterDecrement(atDiff);
1671         }
1672     }
1673 
1674     if (texColor != o_color[2])
1675     {
1676         atomicCounterIncrement(atDiff);
1677         o_color[2] = texColor;
1678     }
1679     else
1680     {
1681         if (atomicCounter(atDiff) > 0u)
1682         {
1683             atomicCounterDecrement(atDiff);
1684         }
1685     }
1686 
1687     if (texColor != o_color[3])
1688     {
1689         atomicCounterIncrement(atDiff);
1690         o_color[3] = texColor;
1691     }
1692     else
1693     {
1694         if (atomicCounter(atDiff) > 0u)
1695         {
1696             atomicCounterDecrement(atDiff);
1697         }
1698     }
1699 })";
1700 
1701     GLProgram program;
1702     program.makeRaster(kVS, kFS);
1703     glUseProgram(program);
1704 
1705     ASSERT_GL_NO_ERROR();
1706 
1707     GLFramebuffer framebuffer;
1708     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1709     std::vector<GLColor> color0(kViewportWidth * kViewportHeight, GLColor::cyan);
1710     std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
1711     std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
1712     std::vector<GLColor> color3(kViewportWidth * kViewportHeight, GLColor::black);
1713     GLTexture colorBufferTex[kMaxColorBuffer];
1714     GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
1715                                                 GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
1716     glBindTexture(GL_TEXTURE_2D, colorBufferTex[0]);
1717     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1718                  GL_UNSIGNED_BYTE, color0.data());
1719     glBindTexture(GL_TEXTURE_2D, colorBufferTex[1]);
1720     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1721                  GL_UNSIGNED_BYTE, color1.data());
1722     glBindTexture(GL_TEXTURE_2D, colorBufferTex[2]);
1723     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1724                  GL_UNSIGNED_BYTE, color2.data());
1725     glBindTexture(GL_TEXTURE_2D, colorBufferTex[3]);
1726     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1727                  GL_UNSIGNED_BYTE, color3.data());
1728     glBindTexture(GL_TEXTURE_2D, 0);
1729     for (unsigned int i = 0; i < kMaxColorBuffer; i++)
1730     {
1731         glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
1732                                colorBufferTex[i], 0);
1733     }
1734     glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
1735 
1736     ASSERT_GL_NO_ERROR();
1737 
1738     GLBuffer atomicBuffer;
1739     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicBuffer);
1740     glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_DRAW);
1741 
1742     // Reset atomic counter buffer
1743     GLuint *userCounters;
1744     userCounters = static_cast<GLuint *>(glMapBufferRange(
1745         GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint),
1746         GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT));
1747     memset(userCounters, 0, sizeof(GLuint));
1748     glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
1749 
1750     glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicBuffer);
1751     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);
1752 
1753     float color[4]      = {1.0f, 0.0f, 0.0f, 1.0f};
1754     GLint colorLocation = glGetUniformLocation(program, "u_color");
1755     glUniform4fv(colorLocation, 1, color);
1756 
1757     GLint positionLocation = glGetAttribLocation(program, "a_position");
1758     render(positionLocation, GL_TRUE);
1759 
1760     ASSERT_GL_NO_ERROR();
1761 
1762     for (unsigned int i = 0; i < kMaxColorBuffer; i++)
1763     {
1764         glReadBuffer(colorAttachments[i]);
1765         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::black);
1766     }
1767 
1768     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicBuffer);
1769     userCounters = static_cast<GLuint *>(
1770         glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint), GL_MAP_READ_BIT));
1771     EXPECT_EQ(*userCounters, kViewportWidth * kViewportHeight * 2);
1772     glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
1773     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);
1774 
1775     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1776 }
1777 
1778 // Testing that binding the location value using GLES API is conflicted to the location value of the
1779 // fragment inout.
TEST_P(FramebufferFetchES31,FixedUniformLocation)1780 TEST_P(FramebufferFetchES31, FixedUniformLocation)
1781 {
1782     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1783 
1784     constexpr char kVS[] = R"(#version 310 es
1785 in highp vec4 a_position;
1786 
1787 void main (void)
1788 {
1789     gl_Position = a_position;
1790 })";
1791 
1792     constexpr char kFS[] = R"(#version 310 es
1793 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
1794 layout(noncoherent, location = 0) inout highp vec4 o_color;
1795 
1796 layout(location = 0) uniform highp vec4 u_color;
1797 void main (void)
1798 {
1799     o_color += u_color;
1800 })";
1801 
1802     GLProgram program;
1803     program.makeRaster(kVS, kFS);
1804     glUseProgram(program);
1805 
1806     ASSERT_GL_NO_ERROR();
1807 
1808     GLFramebuffer framebuffer;
1809     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1810     std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
1811     GLTexture colorBufferTex;
1812     glBindTexture(GL_TEXTURE_2D, colorBufferTex);
1813     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1814                  GL_UNSIGNED_BYTE, greenColor.data());
1815     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex, 0);
1816 
1817     ASSERT_GL_NO_ERROR();
1818 
1819     float color[4]      = {1.0f, 0.0f, 0.0f, 1.0f};
1820     GLint colorLocation = glGetUniformLocation(program, "u_color");
1821     glUniform4fv(colorLocation, 1, color);
1822 
1823     GLint positionLocation = glGetAttribLocation(program, "a_position");
1824     render(positionLocation, GL_TRUE);
1825 
1826     ASSERT_GL_NO_ERROR();
1827 
1828     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1829 
1830     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1831 }
1832 
1833 // Verify we can use inout with the default framebuffer
1834 // http://anglebug.com/6893
TEST_P(FramebufferFetchES31,DefaultFramebufferTest)1835 TEST_P(FramebufferFetchES31, DefaultFramebufferTest)
1836 {
1837     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1838 
1839     constexpr char kVS[] = R"(#version 300 es
1840 in highp vec4 a_position;
1841 
1842 void main (void)
1843 {
1844     gl_Position = a_position;
1845 })";
1846 
1847     constexpr char kFS[] = R"(#version 300 es
1848 #extension GL_EXT_shader_framebuffer_fetch : require
1849 layout(location = 0) inout highp vec4 o_color;
1850 
1851 uniform highp vec4 u_color;
1852 void main (void)
1853 {
1854     o_color += u_color;
1855 })";
1856 
1857     GLProgram program;
1858     program.makeRaster(kVS, kFS);
1859     glUseProgram(program);
1860 
1861     ASSERT_GL_NO_ERROR();
1862 
1863     // Ensure that we're rendering to the default framebuffer
1864     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1865 
1866     // Start with a clear buffer
1867     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1868     glClear(GL_COLOR_BUFFER_BIT);
1869 
1870     GLint positionLocation = glGetAttribLocation(program, "a_position");
1871     GLint colorLocation    = glGetUniformLocation(program, "u_color");
1872 
1873     // Draw once with red
1874     glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
1875     render(positionLocation, GL_FALSE);
1876     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1877     ASSERT_GL_NO_ERROR();
1878 
1879     // Draw again with blue, adding it to the existing red, ending up with magenta
1880     glUniform4fv(colorLocation, 1, GLColor::blue.toNormalizedVector().data());
1881     render(positionLocation, GL_FALSE);
1882     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
1883     ASSERT_GL_NO_ERROR();
1884 }
1885 
1886 // Verify we can render to the default framebuffer without fetch, then switch to a program
1887 // that does fetch.
1888 // http://anglebug.com/6893
TEST_P(FramebufferFetchES31,DefaultFramebufferMixedProgramsTest)1889 TEST_P(FramebufferFetchES31, DefaultFramebufferMixedProgramsTest)
1890 {
1891     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1892 
1893     constexpr char kVS[] = R"(#version 300 es
1894 in highp vec4 a_position;
1895 
1896 void main (void)
1897 {
1898     gl_Position = a_position;
1899 })";
1900 
1901     constexpr char kFS[] = R"(#version 300 es
1902 layout(location = 0) out highp vec4 o_color;
1903 
1904 uniform highp vec4 u_color;
1905 void main (void)
1906 {
1907     o_color = u_color;
1908 })";
1909 
1910     constexpr char kFetchFS[] = R"(#version 300 es
1911 #extension GL_EXT_shader_framebuffer_fetch : require
1912 layout(location = 0) inout highp vec4 o_color;
1913 
1914 uniform highp vec4 u_color;
1915 void main (void)
1916 {
1917     o_color += u_color;
1918 })";
1919 
1920     // Create a program that simply writes out a color, no fetching
1921     GLProgram program;
1922     program.makeRaster(kVS, kFS);
1923     glUseProgram(program);
1924 
1925     ASSERT_GL_NO_ERROR();
1926 
1927     // Ensure that we're rendering to the default framebuffer
1928     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1929 
1930     // Start with a clear buffer
1931     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1932     glClear(GL_COLOR_BUFFER_BIT);
1933 
1934     GLint positionLocation = glGetAttribLocation(program, "a_position");
1935     GLint colorLocation    = glGetUniformLocation(program, "u_color");
1936 
1937     // Draw once with red
1938     glUniform4fv(colorLocation, 1, GLColor::red.toNormalizedVector().data());
1939     render(positionLocation, false);
1940     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1941     ASSERT_GL_NO_ERROR();
1942 
1943     // Create another program that DOES fetch from the framebuffer
1944     GLProgram program2;
1945     program2.makeRaster(kVS, kFetchFS);
1946     glUseProgram(program2);
1947 
1948     GLint positionLocation2 = glGetAttribLocation(program2, "a_position");
1949     GLint colorLocation2    = glGetUniformLocation(program2, "u_color");
1950 
1951     // Draw again with blue, fetching red from the framebuffer, adding it together
1952     glUniform4fv(colorLocation2, 1, GLColor::blue.toNormalizedVector().data());
1953     render(positionLocation2, false);
1954     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
1955     ASSERT_GL_NO_ERROR();
1956 
1957     // Switch back to the non-fetched framebuffer, and render green
1958     glUseProgram(program);
1959     glUniform4fv(colorLocation, 1, GLColor::green.toNormalizedVector().data());
1960     render(positionLocation, false);
1961     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
1962     ASSERT_GL_NO_ERROR();
1963 }
1964 
1965 // Verify we can render to a framebuffer with fetch, then switch to another framebuffer (without
1966 // changing programs) http://anglebug.com/6893
TEST_P(FramebufferFetchES31,FramebufferMixedFetchTest)1967 TEST_P(FramebufferFetchES31, FramebufferMixedFetchTest)
1968 {
1969     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1970 
1971     constexpr char kVS[] = R"(#version 300 es
1972 in highp vec4 a_position;
1973 
1974 void main (void)
1975 {
1976     gl_Position = a_position;
1977 })";
1978 
1979     constexpr char kFS[] = R"(#version 300 es
1980 layout(location = 0) out highp vec4 o_color;
1981 
1982 uniform highp vec4 u_color;
1983 void main (void)
1984 {
1985     o_color = u_color;
1986 })";
1987 
1988     constexpr char kFetchFS[] = R"(#version 300 es
1989 #extension GL_EXT_shader_framebuffer_fetch : require
1990 layout(location = 0) inout highp vec4 o_color;
1991 
1992 uniform highp vec4 u_color;
1993 void main (void)
1994 {
1995     o_color += u_color;
1996 })";
1997 
1998     // Create a program that simply writes out a color, no fetching
1999     GLProgram program;
2000     program.makeRaster(kVS, kFS);
2001     GLint positionLocation = glGetAttribLocation(program, "a_position");
2002     GLint colorLocation    = glGetUniformLocation(program, "u_color");
2003     ASSERT_GL_NO_ERROR();
2004 
2005     // Create a program that DOES fetch from the framebuffer
2006     GLProgram fetchProgram;
2007     fetchProgram.makeRaster(kVS, kFetchFS);
2008     GLint fetchPositionLocation = glGetAttribLocation(fetchProgram, "a_position");
2009     GLint fetchColorLocation    = glGetUniformLocation(fetchProgram, "u_color");
2010     ASSERT_GL_NO_ERROR();
2011 
2012     // Create an empty framebuffer to use without fetch
2013     GLFramebuffer framebuffer1;
2014     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
2015     std::vector<GLColor> clearColor(kViewportWidth * kViewportHeight, GLColor::transparentBlack);
2016     GLTexture colorBufferTex1;
2017     glBindTexture(GL_TEXTURE_2D, colorBufferTex1);
2018     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
2019                  GL_UNSIGNED_BYTE, clearColor.data());
2020     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex1, 0);
2021     ASSERT_GL_NO_ERROR();
2022 
2023     // Draw to it with green, without using fetch, overwriting any contents
2024     glUseProgram(program);
2025     glUniform4fv(colorLocation, 1, GLColor::green.toNormalizedVector().data());
2026     render(positionLocation, false);
2027     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
2028     ASSERT_GL_NO_ERROR();
2029 
2030     // Create another framebuffer to use WITH fetch, and initialize it with blue
2031     GLFramebuffer framebuffer2;
2032     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2);
2033     std::vector<GLColor> blueColor(kViewportWidth * kViewportHeight, GLColor::blue);
2034     GLTexture colorBufferTex2;
2035     glBindTexture(GL_TEXTURE_2D, colorBufferTex2);
2036     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
2037                  GL_UNSIGNED_BYTE, blueColor.data());
2038     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex2, 0);
2039     ASSERT_GL_NO_ERROR();
2040 
2041     // Draw once with red, fetching blue from the framebuffer, adding it together
2042     glUseProgram(fetchProgram);
2043     glUniform4fv(fetchColorLocation, 1, GLColor::red.toNormalizedVector().data());
2044     render(fetchPositionLocation, false);
2045     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
2046     ASSERT_GL_NO_ERROR();
2047 
2048     // Now use the same program (WITH fetch) and render to the other framebuffer that was NOT used
2049     // with fetch. This verifies the framebuffer state is appropriately updated to match the
2050     // program.
2051     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
2052     render(fetchPositionLocation, false);
2053     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
2054     ASSERT_GL_NO_ERROR();
2055 }
2056 
2057 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FramebufferFetchES31);
2058 ANGLE_INSTANTIATE_TEST_ES31(FramebufferFetchES31);
2059 }  // namespace angle
2060