• 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 //
40 // Shared simple (i.e. no framebuffer fetch) Fragment Shaders for the tests below
41 //
42 // Simple (i.e. no framebuffer fetch) 3.1 GLSL fragment shader that writes to 1 attachment
43 static constexpr char k310NoFetch1AttachmentFS[] = R"(#version 310 es
44 layout(location = 0) out highp vec4 o_color;
45 
46 uniform highp vec4 u_color;
47 void main (void)
48 {
49     o_color = u_color;
50 })";
51 
52 //
53 // Shared Coherent Fragment Shaders for the tests below
54 //
55 // Coherent version of a 1.0 GLSL fragment shader that uses gl_LastFragData
56 static constexpr char k100CoherentFS[] = R"(#version 100
57 #extension GL_EXT_shader_framebuffer_fetch : require
58 mediump vec4 gl_LastFragData[gl_MaxDrawBuffers];
59 uniform highp vec4 u_color;
60 
61 void main (void)
62 {
63     gl_FragColor = u_color + gl_LastFragData[0];
64 })";
65 
66 // Coherent version of a 3.1 GLSL fragment shader that writes to 1 attachment
67 static constexpr char k310Coherent1AttachmentFS[] = R"(#version 310 es
68 #extension GL_EXT_shader_framebuffer_fetch : require
69 layout(location = 0) inout highp vec4 o_color;
70 
71 uniform highp vec4 u_color;
72 void main (void)
73 {
74     o_color += u_color;
75 })";
76 
77 // Coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments
78 static constexpr char k310Coherent4AttachmentFS[] = R"(#version 310 es
79 #extension GL_EXT_shader_framebuffer_fetch : require
80 layout(location = 0) inout highp vec4 o_color0;
81 layout(location = 1) inout highp vec4 o_color1;
82 layout(location = 2) inout highp vec4 o_color2;
83 layout(location = 3) inout highp vec4 o_color3;
84 uniform highp vec4 u_color;
85 
86 void main (void)
87 {
88     o_color0 += u_color;
89     o_color1 += u_color;
90     o_color2 += u_color;
91     o_color3 += u_color;
92 })";
93 
94 // Coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments via an inout
95 // array
96 static constexpr char k310Coherent4AttachmentArrayFS[] = R"(#version 310 es
97 #extension GL_EXT_shader_framebuffer_fetch : require
98 layout(location = 0) inout highp vec4 o_color[4];
99 uniform highp vec4 u_color;
100 
101 void main (void)
102 {
103     o_color[0] += u_color;
104     o_color[1] += u_color;
105     o_color[2] += u_color;
106     o_color[3] += u_color;
107 })";
108 
109 // Coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments with the order of
110 // non-fetch program and fetch program with different attachments (version 1)
111 static constexpr char k310CoherentDifferent4AttachmentFS1[] = R"(#version 310 es
112 #extension GL_EXT_shader_framebuffer_fetch : require
113 layout(location = 0) inout highp vec4 o_color0;
114 layout(location = 1) out highp vec4 o_color1;
115 layout(location = 2) inout highp vec4 o_color2;
116 layout(location = 3) out highp vec4 o_color3;
117 uniform highp vec4 u_color;
118 
119 void main (void)
120 {
121     o_color0 += u_color;
122     o_color1 = u_color;
123     o_color2 += u_color;
124     o_color3 = u_color;
125 })";
126 
127 // Coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments with the order
128 // of non-fetch program and fetch program with different attachments (version 2)
129 static constexpr char k310CoherentDifferent4AttachmentFS2[] = R"(#version 310 es
130 #extension GL_EXT_shader_framebuffer_fetch : require
131 layout(location = 0) inout highp vec4 o_color0;
132 layout(location = 1) out highp vec4 o_color1;
133 layout(location = 2) out highp vec4 o_color2;
134 layout(location = 3) inout highp vec4 o_color3;
135 uniform highp vec4 u_color;
136 
137 void main (void)
138 {
139     o_color0 += u_color;
140     o_color1 = u_color;
141     o_color2 = u_color;
142     o_color3 += u_color;
143 })";
144 
145 //
146 // Shared Non-Coherent Fragment Shaders for the tests below
147 //
148 // Non-coherent version of a 1.0 GLSL fragment shader that uses gl_LastFragData
149 static constexpr char k100NonCoherentFS[] = R"(#version 100
150 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
151 layout(noncoherent) mediump vec4 gl_LastFragData[gl_MaxDrawBuffers];
152 uniform highp vec4 u_color;
153 
154 void main (void)
155 {
156     gl_FragColor = u_color + gl_LastFragData[0];
157 })";
158 
159 // Non-coherent version of a 3.1 GLSL fragment shader that writes to 1 attachment
160 static constexpr char k310NonCoherent1AttachmentFS[] = R"(#version 310 es
161 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
162 layout(noncoherent, location = 0) inout highp vec4 o_color;
163 
164 uniform highp vec4 u_color;
165 void main (void)
166 {
167     o_color += u_color;
168 })";
169 
170 // Non-coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments
171 static constexpr char k310NonCoherent4AttachmentFS[] = R"(#version 310 es
172 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
173 layout(noncoherent, location = 0) inout highp vec4 o_color0;
174 layout(noncoherent, location = 1) inout highp vec4 o_color1;
175 layout(noncoherent, location = 2) inout highp vec4 o_color2;
176 layout(noncoherent, location = 3) inout highp vec4 o_color3;
177 uniform highp vec4 u_color;
178 
179 void main (void)
180 {
181     o_color0 += u_color;
182     o_color1 += u_color;
183     o_color2 += u_color;
184     o_color3 += u_color;
185 })";
186 
187 // Non-coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments via an inout
188 // array
189 static constexpr char k310NonCoherent4AttachmentArrayFS[] = R"(#version 310 es
190 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
191 layout(noncoherent, location = 0) inout highp vec4 o_color[4];
192 uniform highp vec4 u_color;
193 
194 void main (void)
195 {
196     o_color[0] += u_color;
197     o_color[1] += u_color;
198     o_color[2] += u_color;
199     o_color[3] += u_color;
200 })";
201 
202 // Non-coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments with the order
203 // of non-fetch program and fetch program with different attachments (version 1)
204 static constexpr char k310NonCoherentDifferent4AttachmentFS1[] = R"(#version 310 es
205 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
206 layout(noncoherent, location = 0) inout highp vec4 o_color0;
207 layout(location = 1) out highp vec4 o_color1;
208 layout(noncoherent, location = 2) inout highp vec4 o_color2;
209 layout(location = 3) out highp vec4 o_color3;
210 uniform highp vec4 u_color;
211 
212 void main (void)
213 {
214     o_color0 += u_color;
215     o_color1 = u_color;
216     o_color2 += u_color;
217     o_color3 = u_color;
218 })";
219 
220 // Non-coherent version of a 3.1 GLSL fragment shader that writes to 4 attachments with the order
221 // of non-fetch program and fetch program with different attachments (version 2)
222 static constexpr char k310NonCoherentDifferent4AttachmentFS2[] = R"(#version 310 es
223 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
224 layout(noncoherent, location = 0) inout highp vec4 o_color0;
225 layout(location = 1) out highp vec4 o_color1;
226 layout(location = 2) out highp vec4 o_color2;
227 layout(noncoherent, location = 3) inout highp vec4 o_color3;
228 uniform highp vec4 u_color;
229 
230 void main (void)
231 {
232     o_color0 += u_color;
233     o_color1 = u_color;
234     o_color2 = u_color;
235     o_color3 += u_color;
236 })";
237 
238 class FramebufferFetchES31 : public ANGLETest
239 {
240   protected:
241     static constexpr GLuint kMaxColorBuffer = 4u;
242     static constexpr GLuint kViewportWidth  = 16u;
243     static constexpr GLuint kViewportHeight = 16u;
244 
FramebufferFetchES31()245     FramebufferFetchES31()
246     {
247         setWindowWidth(16);
248         setWindowHeight(16);
249         setConfigRedBits(8);
250         setConfigGreenBits(8);
251         setConfigBlueBits(8);
252         setConfigAlphaBits(8);
253         setConfigDepthBits(24);
254 
255         mCoherentExtension = false;
256     }
257 
258     enum WhichExtension
259     {
260         COHERENT,
261         NON_COHERENT,
262     };
setWhichExtension(WhichExtension whichExtension)263     void setWhichExtension(WhichExtension whichExtension)
264     {
265         mCoherentExtension = (whichExtension == COHERENT) ? true : false;
266     }
267 
268     enum WhichFragmentShader
269     {
270         GLSL100,
271         GLSL310_NO_FETCH_1ATTACHMENT,
272         GLSL310_1ATTACHMENT,
273         GLSL310_4ATTACHMENT,
274         GLSL310_4ATTACHMENT_ARRAY,
275         GLSL310_4ATTACHMENT_DIFFERENT1,
276         GLSL310_4ATTACHMENT_DIFFERENT2,
277     };
getFragmentShader(WhichFragmentShader whichFragmentShader)278     const char *getFragmentShader(WhichFragmentShader whichFragmentShader)
279     {
280         if (mCoherentExtension)
281         {
282             switch (whichFragmentShader)
283             {
284                 case GLSL100:
285                     return k100CoherentFS;
286                 case GLSL310_NO_FETCH_1ATTACHMENT:
287                     return k310NoFetch1AttachmentFS;
288                 case GLSL310_1ATTACHMENT:
289                     return k310Coherent1AttachmentFS;
290                 case GLSL310_4ATTACHMENT:
291                     return k310Coherent4AttachmentFS;
292                 case GLSL310_4ATTACHMENT_ARRAY:
293                     return k310Coherent4AttachmentArrayFS;
294                 case GLSL310_4ATTACHMENT_DIFFERENT1:
295                     return k310CoherentDifferent4AttachmentFS1;
296                 case GLSL310_4ATTACHMENT_DIFFERENT2:
297                     return k310CoherentDifferent4AttachmentFS2;
298                 default:
299                     UNREACHABLE();
300                     return nullptr;
301             }
302         }
303         else
304         {
305             switch (whichFragmentShader)
306             {
307                 case GLSL100:
308                     return k100NonCoherentFS;
309                 case GLSL310_NO_FETCH_1ATTACHMENT:
310                     return k310NoFetch1AttachmentFS;
311                 case GLSL310_1ATTACHMENT:
312                     return k310NonCoherent1AttachmentFS;
313                 case GLSL310_4ATTACHMENT:
314                     return k310NonCoherent4AttachmentFS;
315                 case GLSL310_4ATTACHMENT_ARRAY:
316                     return k310NonCoherent4AttachmentArrayFS;
317                 case GLSL310_4ATTACHMENT_DIFFERENT1:
318                     return k310NonCoherentDifferent4AttachmentFS1;
319                 case GLSL310_4ATTACHMENT_DIFFERENT2:
320                     return k310NonCoherentDifferent4AttachmentFS2;
321                 default:
322                     UNREACHABLE();
323                     return nullptr;
324             }
325         }
326     }
327 
render(GLuint coordLoc,GLboolean needsFramebufferFetchBarrier)328     void render(GLuint coordLoc, GLboolean needsFramebufferFetchBarrier)
329     {
330         const GLfloat coords[] = {
331             -1.0f, -1.0f, +1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f,
332         };
333 
334         const GLushort indices[] = {
335             0, 1, 2, 2, 3, 0,
336         };
337 
338         glViewport(0, 0, kViewportWidth, kViewportHeight);
339 
340         GLBuffer coordinatesBuffer;
341         GLBuffer elementsBuffer;
342 
343         glBindBuffer(GL_ARRAY_BUFFER, coordinatesBuffer);
344         glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW);
345         glEnableVertexAttribArray(coordLoc);
346         glVertexAttribPointer(coordLoc, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
347 
348         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementsBuffer);
349         glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)sizeof(indices), &indices[0],
350                      GL_STATIC_DRAW);
351 
352         if (needsFramebufferFetchBarrier)
353         {
354             glFramebufferFetchBarrierEXT();
355         }
356 
357         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
358 
359         ASSERT_GL_NO_ERROR();
360     }
361 
BasicTest(GLProgram program)362     void BasicTest(GLProgram program)
363     {
364         GLFramebuffer framebuffer;
365         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
366         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
367         GLTexture colorBufferTex;
368         glBindTexture(GL_TEXTURE_2D, colorBufferTex);
369         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
370                      GL_UNSIGNED_BYTE, greenColor.data());
371         glBindTexture(GL_TEXTURE_2D, 0);
372         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
373                                0);
374 
375         ASSERT_GL_NO_ERROR();
376 
377         float color[4]      = {1.0f, 0.0f, 0.0f, 1.0f};
378         GLint colorLocation = glGetUniformLocation(program, "u_color");
379         glUniform4fv(colorLocation, 1, color);
380 
381         GLint positionLocation = glGetAttribLocation(program, "a_position");
382         render(positionLocation, !mCoherentExtension);
383 
384         ASSERT_GL_NO_ERROR();
385 
386         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
387 
388         glBindFramebuffer(GL_FRAMEBUFFER, 0);
389     }
390 
MultipleRenderTargetTest(GLProgram program)391     void MultipleRenderTargetTest(GLProgram program)
392     {
393         GLFramebuffer framebuffer;
394         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
395         std::vector<GLColor> color0(kViewportWidth * kViewportHeight, GLColor::black);
396         std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
397         std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
398         std::vector<GLColor> color3(kViewportWidth * kViewportHeight, GLColor::cyan);
399         GLTexture colorBufferTex[kMaxColorBuffer];
400         GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
401                                                     GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
402         glBindTexture(GL_TEXTURE_2D, colorBufferTex[0]);
403         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
404                      GL_UNSIGNED_BYTE, color0.data());
405         glBindTexture(GL_TEXTURE_2D, colorBufferTex[1]);
406         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
407                      GL_UNSIGNED_BYTE, color1.data());
408         glBindTexture(GL_TEXTURE_2D, colorBufferTex[2]);
409         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
410                      GL_UNSIGNED_BYTE, color2.data());
411         glBindTexture(GL_TEXTURE_2D, colorBufferTex[3]);
412         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
413                      GL_UNSIGNED_BYTE, color3.data());
414         glBindTexture(GL_TEXTURE_2D, 0);
415         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
416         {
417             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
418                                    colorBufferTex[i], 0);
419         }
420         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
421 
422         ASSERT_GL_NO_ERROR();
423 
424         float color[4]      = {1.0f, 0.0f, 0.0f, 1.0f};
425         GLint colorLocation = glGetUniformLocation(program, "u_color");
426         glUniform4fv(colorLocation, 1, color);
427 
428         GLint positionLocation = glGetAttribLocation(program, "a_position");
429         render(positionLocation, !mCoherentExtension);
430 
431         ASSERT_GL_NO_ERROR();
432 
433         glReadBuffer(colorAttachments[0]);
434         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
435         glReadBuffer(colorAttachments[1]);
436         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
437         glReadBuffer(colorAttachments[2]);
438         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
439         glReadBuffer(colorAttachments[3]);
440         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::white);
441 
442         glBindFramebuffer(GL_FRAMEBUFFER, 0);
443     }
444 
MultipleRenderTargetArrayTest(GLProgram program)445     void MultipleRenderTargetArrayTest(GLProgram program)
446     {
447         GLFramebuffer framebuffer;
448         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
449         std::vector<GLColor> color0(kViewportWidth * kViewportHeight, GLColor::black);
450         std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
451         std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
452         std::vector<GLColor> color3(kViewportWidth * kViewportHeight, GLColor::cyan);
453         GLTexture colorBufferTex[kMaxColorBuffer];
454         GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
455                                                     GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
456         glBindTexture(GL_TEXTURE_2D, colorBufferTex[0]);
457         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
458                      GL_UNSIGNED_BYTE, color0.data());
459         glBindTexture(GL_TEXTURE_2D, colorBufferTex[1]);
460         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
461                      GL_UNSIGNED_BYTE, color1.data());
462         glBindTexture(GL_TEXTURE_2D, colorBufferTex[2]);
463         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
464                      GL_UNSIGNED_BYTE, color2.data());
465         glBindTexture(GL_TEXTURE_2D, colorBufferTex[3]);
466         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
467                      GL_UNSIGNED_BYTE, color3.data());
468         glBindTexture(GL_TEXTURE_2D, 0);
469         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
470         {
471             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
472                                    colorBufferTex[i], 0);
473         }
474         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
475 
476         ASSERT_GL_NO_ERROR();
477 
478         float color[4]      = {1.0f, 0.0f, 0.0f, 1.0f};
479         GLint colorLocation = glGetUniformLocation(program, "u_color");
480         glUniform4fv(colorLocation, 1, color);
481 
482         GLint positionLocation = glGetAttribLocation(program, "a_position");
483         render(positionLocation, !mCoherentExtension);
484 
485         ASSERT_GL_NO_ERROR();
486 
487         glReadBuffer(colorAttachments[0]);
488         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
489         glReadBuffer(colorAttachments[1]);
490         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
491         glReadBuffer(colorAttachments[2]);
492         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
493         glReadBuffer(colorAttachments[3]);
494         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::white);
495 
496         glBindFramebuffer(GL_FRAMEBUFFER, 0);
497     }
498 
MultipleDrawTest(GLProgram program)499     void MultipleDrawTest(GLProgram program)
500     {
501         GLFramebuffer framebuffer;
502         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
503         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
504         GLTexture colorBufferTex;
505         glBindTexture(GL_TEXTURE_2D, colorBufferTex);
506         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
507                      GL_UNSIGNED_BYTE, greenColor.data());
508         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
509                                0);
510 
511         ASSERT_GL_NO_ERROR();
512 
513         float color1[4]     = {1.0f, 0.0f, 0.0f, 1.0f};
514         GLint colorLocation = glGetUniformLocation(program, "u_color");
515         glUniform4fv(colorLocation, 1, color1);
516 
517         GLint positionLocation = glGetAttribLocation(program, "a_position");
518         render(positionLocation, !mCoherentExtension);
519 
520         float color2[4] = {0.0f, 0.0f, 1.0f, 1.0f};
521         glUniform4fv(colorLocation, 1, color2);
522 
523         render(positionLocation, !mCoherentExtension);
524 
525         ASSERT_GL_NO_ERROR();
526 
527         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::white);
528 
529         glBindFramebuffer(GL_FRAMEBUFFER, 0);
530     }
531 
DrawNonFetchDrawFetchTest(GLProgram programNonFetch,GLProgram programFetch)532     void DrawNonFetchDrawFetchTest(GLProgram programNonFetch, GLProgram programFetch)
533     {
534         glUseProgram(programNonFetch);
535         ASSERT_GL_NO_ERROR();
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 colorRed[4]           = {1.0f, 0.0f, 0.0f, 1.0f};
550         GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
551         glUniform4fv(colorLocationNonFetch, 1, colorRed);
552 
553         GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
554         // Render without regard to glFramebufferFetchBarrierEXT()
555         render(positionLocationNonFetch, GL_FALSE);
556 
557         ASSERT_GL_NO_ERROR();
558 
559         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
560 
561         glUseProgram(programFetch);
562 
563         float colorGreen[4]      = {0.0f, 1.0f, 0.0f, 1.0f};
564         GLint colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
565         glUniform4fv(colorLocationFetch, 1, colorGreen);
566 
567         GLint positionLocationFetch = glGetAttribLocation(programFetch, "a_position");
568         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
569         // extension being used
570         render(positionLocationFetch, !mCoherentExtension);
571 
572         ASSERT_GL_NO_ERROR();
573 
574         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
575 
576         glUseProgram(programNonFetch);
577         glUniform4fv(colorLocationNonFetch, 1, colorRed);
578         // Render without regard to glFramebufferFetchBarrierEXT()
579         render(positionLocationNonFetch, GL_FALSE);
580 
581         ASSERT_GL_NO_ERROR();
582 
583         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
584 
585         glUseProgram(programFetch);
586         glUniform4fv(colorLocationFetch, 1, colorGreen);
587         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
588         // extension being used
589         render(positionLocationFetch, !mCoherentExtension);
590 
591         ASSERT_GL_NO_ERROR();
592 
593         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
594 
595         glBindFramebuffer(GL_FRAMEBUFFER, 0);
596     }
597 
DrawFetchDrawNonFetchTest(GLProgram programNonFetch,GLProgram programFetch)598     void DrawFetchDrawNonFetchTest(GLProgram programNonFetch, GLProgram programFetch)
599     {
600         glUseProgram(programFetch);
601         ASSERT_GL_NO_ERROR();
602 
603         GLFramebuffer framebuffer;
604         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
605         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
606         GLTexture colorBufferTex;
607         glBindTexture(GL_TEXTURE_2D, colorBufferTex);
608         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
609                      GL_UNSIGNED_BYTE, greenColor.data());
610         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
611                                0);
612 
613         ASSERT_GL_NO_ERROR();
614 
615         float colorRed[4]        = {1.0f, 0.0f, 0.0f, 1.0f};
616         GLint colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
617         glUniform4fv(colorLocationFetch, 1, colorRed);
618 
619         GLint positionLocationFetch = glGetAttribLocation(programFetch, "a_position");
620         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
621         // extension being used
622         render(positionLocationFetch, !mCoherentExtension);
623         ASSERT_GL_NO_ERROR();
624 
625         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
626 
627         glUseProgram(programNonFetch);
628 
629         GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
630         glUniform4fv(colorLocationNonFetch, 1, colorRed);
631 
632         GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
633         // Render without regard to glFramebufferFetchBarrierEXT()
634         render(positionLocationNonFetch, GL_FALSE);
635         ASSERT_GL_NO_ERROR();
636 
637         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
638 
639         float colorGreen[4] = {0.0f, 1.0f, 0.0f, 1.0f};
640         glUseProgram(programFetch);
641         glUniform4fv(colorLocationFetch, 1, colorGreen);
642         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
643         // extension being used
644         render(positionLocationFetch, !mCoherentExtension);
645         ASSERT_GL_NO_ERROR();
646 
647         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
648 
649         glUseProgram(programNonFetch);
650         glUniform4fv(colorLocationNonFetch, 1, colorRed);
651         // Render without regard to glFramebufferFetchBarrierEXT()
652         render(positionLocationNonFetch, GL_FALSE);
653 
654         ASSERT_GL_NO_ERROR();
655 
656         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
657 
658         glBindFramebuffer(GL_FRAMEBUFFER, 0);
659     }
660 
DrawNonFetchDrawFetchWithDifferentAttachmentsTest(GLProgram programNonFetch,GLProgram programFetch)661     void DrawNonFetchDrawFetchWithDifferentAttachmentsTest(GLProgram programNonFetch,
662                                                            GLProgram programFetch)
663     {
664         glUseProgram(programNonFetch);
665         ASSERT_GL_NO_ERROR();
666 
667         GLFramebuffer framebuffer;
668         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
669         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
670         GLTexture colorTex;
671         glBindTexture(GL_TEXTURE_2D, colorTex);
672         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
673                      GL_UNSIGNED_BYTE, greenColor.data());
674         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
675 
676         ASSERT_GL_NO_ERROR();
677 
678         float colorRed[4]           = {1.0f, 0.0f, 0.0f, 1.0f};
679         GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
680         glUniform4fv(colorLocationNonFetch, 1, colorRed);
681 
682         GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
683         // Render without regard to glFramebufferFetchBarrierEXT()
684         render(positionLocationNonFetch, GL_FALSE);
685         ASSERT_GL_NO_ERROR();
686 
687         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
688 
689         glUseProgram(programFetch);
690         ASSERT_GL_NO_ERROR();
691 
692         GLFramebuffer framebufferMRT1;
693         glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT1);
694         std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
695         std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
696         GLTexture colorBufferTex1[kMaxColorBuffer];
697         GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
698                                                     GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
699         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[0]);
700         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
701                      GL_UNSIGNED_BYTE, color1.data());
702         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[1]);
703         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
704                      GL_UNSIGNED_BYTE, color1.data());
705         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[2]);
706         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
707                      GL_UNSIGNED_BYTE, color2.data());
708         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[3]);
709         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
710                      GL_UNSIGNED_BYTE, color2.data());
711         glBindTexture(GL_TEXTURE_2D, 0);
712         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
713         {
714             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
715                                    colorBufferTex1[i], 0);
716         }
717         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
718         ASSERT_GL_NO_ERROR();
719 
720         GLint colorLocation = glGetUniformLocation(programFetch, "u_color");
721         glUniform4fv(colorLocation, 1, colorRed);
722 
723         GLint positionLocation = glGetAttribLocation(programFetch, "a_position");
724         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
725         // extension being used
726         render(positionLocation, !mCoherentExtension);
727         ASSERT_GL_NO_ERROR();
728 
729         glReadBuffer(colorAttachments[0]);
730         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
731         glReadBuffer(colorAttachments[1]);
732         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
733         glReadBuffer(colorAttachments[2]);
734         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
735         glReadBuffer(colorAttachments[3]);
736         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
737 
738         GLFramebuffer framebufferMRT2;
739         glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT2);
740         GLTexture colorBufferTex2[kMaxColorBuffer];
741         glBindTexture(GL_TEXTURE_2D, colorBufferTex2[0]);
742         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
743                      GL_UNSIGNED_BYTE, color2.data());
744         glBindTexture(GL_TEXTURE_2D, colorBufferTex2[1]);
745         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
746                      GL_UNSIGNED_BYTE, color2.data());
747         glBindTexture(GL_TEXTURE_2D, colorBufferTex2[2]);
748         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
749                      GL_UNSIGNED_BYTE, color1.data());
750         glBindTexture(GL_TEXTURE_2D, colorBufferTex2[3]);
751         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
752                      GL_UNSIGNED_BYTE, color1.data());
753         glBindTexture(GL_TEXTURE_2D, 0);
754         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
755         {
756             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
757                                    colorBufferTex2[i], 0);
758         }
759         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
760         ASSERT_GL_NO_ERROR();
761 
762         glUniform4fv(colorLocation, 1, colorRed);
763         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
764         // extension being used
765         render(positionLocation, !mCoherentExtension);
766         ASSERT_GL_NO_ERROR();
767 
768         glReadBuffer(colorAttachments[0]);
769         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
770         glReadBuffer(colorAttachments[1]);
771         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
772         glReadBuffer(colorAttachments[2]);
773         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
774         glReadBuffer(colorAttachments[3]);
775         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
776 
777         glBindFramebuffer(GL_FRAMEBUFFER, 0);
778     }
779 
DrawNonFetchDrawFetchWithDifferentProgramsTest(GLProgram programNonFetch,GLProgram programFetch1,GLProgram programFetch2)780     void DrawNonFetchDrawFetchWithDifferentProgramsTest(GLProgram programNonFetch,
781                                                         GLProgram programFetch1,
782                                                         GLProgram programFetch2)
783     {
784         glUseProgram(programNonFetch);
785         ASSERT_GL_NO_ERROR();
786         GLFramebuffer framebuffer;
787         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
788         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
789         GLTexture colorTex;
790         glBindTexture(GL_TEXTURE_2D, colorTex);
791         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
792                      GL_UNSIGNED_BYTE, greenColor.data());
793         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
794 
795         ASSERT_GL_NO_ERROR();
796 
797         float colorRed[4]           = {1.0f, 0.0f, 0.0f, 1.0f};
798         GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
799         glUniform4fv(colorLocationNonFetch, 1, colorRed);
800 
801         GLint positionLocationNonFetch = glGetAttribLocation(programNonFetch, "a_position");
802         // Render without regard to glFramebufferFetchBarrierEXT()
803         render(positionLocationNonFetch, GL_FALSE);
804         ASSERT_GL_NO_ERROR();
805 
806         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
807 
808         glUseProgram(programFetch1);
809         ASSERT_GL_NO_ERROR();
810 
811         GLFramebuffer framebufferMRT1;
812         glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT1);
813         std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
814         GLTexture colorBufferTex1[kMaxColorBuffer];
815         GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
816                                                     GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
817         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[0]);
818         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
819                      GL_UNSIGNED_BYTE, color1.data());
820         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[1]);
821         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
822                      GL_UNSIGNED_BYTE, color1.data());
823         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[2]);
824         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
825                      GL_UNSIGNED_BYTE, color1.data());
826         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[3]);
827         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
828                      GL_UNSIGNED_BYTE, color1.data());
829         glBindTexture(GL_TEXTURE_2D, 0);
830         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
831         {
832             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
833                                    colorBufferTex1[i], 0);
834         }
835         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
836         ASSERT_GL_NO_ERROR();
837 
838         GLint colorLocation = glGetUniformLocation(programFetch1, "u_color");
839         glUniform4fv(colorLocation, 1, colorRed);
840 
841         GLint positionLocation = glGetAttribLocation(programFetch1, "a_position");
842         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
843         // extension being used
844         render(positionLocation, !mCoherentExtension);
845         ASSERT_GL_NO_ERROR();
846 
847         glReadBuffer(colorAttachments[0]);
848         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
849         glReadBuffer(colorAttachments[1]);
850         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
851         glReadBuffer(colorAttachments[2]);
852         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
853         glReadBuffer(colorAttachments[3]);
854         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
855 
856         glUseProgram(programFetch2);
857         ASSERT_GL_NO_ERROR();
858 
859         glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
860         glClear(GL_COLOR_BUFFER_BIT);
861 
862         GLint colorLocation1 = glGetUniformLocation(programFetch2, "u_color");
863         glUniform4fv(colorLocation1, 1, colorRed);
864 
865         GLint positionLocation1 = glGetAttribLocation(programFetch2, "a_position");
866         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
867         // extension being used
868         render(positionLocation1, !mCoherentExtension);
869         ASSERT_GL_NO_ERROR();
870 
871         glReadBuffer(colorAttachments[0]);
872         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
873         glReadBuffer(colorAttachments[1]);
874         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
875         glReadBuffer(colorAttachments[2]);
876         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
877         glReadBuffer(colorAttachments[3]);
878         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
879 
880         glBindFramebuffer(GL_FRAMEBUFFER, 0);
881     }
882 
DrawFetchBlitDrawFetchTest(GLProgram programNonFetch,GLProgram programFetch)883     void DrawFetchBlitDrawFetchTest(GLProgram programNonFetch, GLProgram programFetch)
884     {
885         glUseProgram(programFetch);
886         ASSERT_GL_NO_ERROR();
887 
888         GLFramebuffer framebufferMRT1;
889         glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT1);
890         std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
891         std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
892         GLTexture colorBufferTex1[kMaxColorBuffer];
893         GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
894                                                     GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
895         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[0]);
896         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
897                      GL_UNSIGNED_BYTE, color1.data());
898         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[1]);
899         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
900                      GL_UNSIGNED_BYTE, color1.data());
901         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[2]);
902         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
903                      GL_UNSIGNED_BYTE, color2.data());
904         glBindTexture(GL_TEXTURE_2D, colorBufferTex1[3]);
905         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
906                      GL_UNSIGNED_BYTE, color2.data());
907         glBindTexture(GL_TEXTURE_2D, 0);
908         for (unsigned int i = 0; i < kMaxColorBuffer; i++)
909         {
910             glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
911                                    colorBufferTex1[i], 0);
912         }
913         glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
914         ASSERT_GL_NO_ERROR();
915 
916         float colorRed[4]   = {1.0f, 0.0f, 0.0f, 1.0f};
917         GLint colorLocation = glGetUniformLocation(programFetch, "u_color");
918         glUniform4fv(colorLocation, 1, colorRed);
919 
920         GLint positionLocation = glGetAttribLocation(programFetch, "a_position");
921         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
922         // extension being used
923         render(positionLocation, !mCoherentExtension);
924         ASSERT_GL_NO_ERROR();
925 
926         glReadBuffer(colorAttachments[0]);
927         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
928         glReadBuffer(colorAttachments[1]);
929         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
930         glReadBuffer(colorAttachments[2]);
931         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::magenta);
932         glReadBuffer(colorAttachments[3]);
933         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
934 
935         GLFramebuffer framebufferColor;
936         glBindFramebuffer(GL_FRAMEBUFFER, framebufferColor);
937 
938         GLTexture colorTex;
939         glBindTexture(GL_TEXTURE_2D, colorTex);
940         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
941                      GL_UNSIGNED_BYTE, color2.data());
942         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
943 
944         glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, framebufferColor);
945         glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, framebufferMRT1);
946 
947         glBlitFramebuffer(0, 0, kViewportWidth, kViewportHeight, 0, 0, kViewportWidth,
948                           kViewportHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
949         ASSERT_GL_NO_ERROR();
950 
951         glBindFramebuffer(GL_FRAMEBUFFER, framebufferMRT1);
952         glReadBuffer(colorAttachments[0]);
953         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
954         glReadBuffer(colorAttachments[1]);
955         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
956         glReadBuffer(colorAttachments[2]);
957         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
958         glReadBuffer(colorAttachments[3]);
959         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::blue);
960 
961         float colorGreen[4] = {0.0f, 1.0f, 0.0f, 1.0f};
962         glUniform4fv(colorLocation, 1, colorGreen);
963 
964         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
965         // extension being used
966         render(positionLocation, !mCoherentExtension);
967         ASSERT_GL_NO_ERROR();
968 
969         glReadBuffer(colorAttachments[0]);
970         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::cyan);
971         glReadBuffer(colorAttachments[1]);
972         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
973         glReadBuffer(colorAttachments[2]);
974         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::cyan);
975         glReadBuffer(colorAttachments[3]);
976         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::green);
977 
978         glBindFramebuffer(GL_FRAMEBUFFER, 0);
979     }
980 
ProgramPipelineTest(const char * kVS,const char * kFS1,const char * kFS2)981     void ProgramPipelineTest(const char *kVS, const char *kFS1, const char *kFS2)
982     {
983         GLProgram programVert, programNonFetch, programFetch;
984         const char *sourceArray[3] = {kVS, kFS1, kFS2};
985 
986         GLShader vertShader(GL_VERTEX_SHADER);
987         glShaderSource(vertShader, 1, &sourceArray[0], nullptr);
988         glCompileShader(vertShader);
989         glProgramParameteri(programVert, GL_PROGRAM_SEPARABLE, GL_TRUE);
990         glAttachShader(programVert, vertShader);
991         glLinkProgram(programVert);
992         ASSERT_GL_NO_ERROR();
993 
994         GLShader fragShader1(GL_FRAGMENT_SHADER);
995         glShaderSource(fragShader1, 1, &sourceArray[1], nullptr);
996         glCompileShader(fragShader1);
997         glProgramParameteri(programNonFetch, GL_PROGRAM_SEPARABLE, GL_TRUE);
998         glAttachShader(programNonFetch, fragShader1);
999         glLinkProgram(programNonFetch);
1000         ASSERT_GL_NO_ERROR();
1001 
1002         GLShader fragShader2(GL_FRAGMENT_SHADER);
1003         glShaderSource(fragShader2, 1, &sourceArray[2], nullptr);
1004         glCompileShader(fragShader2);
1005         glProgramParameteri(programFetch, GL_PROGRAM_SEPARABLE, GL_TRUE);
1006         glAttachShader(programFetch, fragShader2);
1007         glLinkProgram(programFetch);
1008         ASSERT_GL_NO_ERROR();
1009 
1010         GLProgramPipeline pipeline1, pipeline2, pipeline3, pipeline4;
1011         glUseProgramStages(pipeline1, GL_VERTEX_SHADER_BIT, programVert);
1012         glUseProgramStages(pipeline1, GL_FRAGMENT_SHADER_BIT, programNonFetch);
1013         glBindProgramPipeline(pipeline1);
1014         ASSERT_GL_NO_ERROR();
1015 
1016         GLFramebuffer framebuffer;
1017         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1018         std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
1019         GLTexture colorBufferTex;
1020         glBindTexture(GL_TEXTURE_2D, colorBufferTex);
1021         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1022                      GL_UNSIGNED_BYTE, greenColor.data());
1023         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex,
1024                                0);
1025         ASSERT_GL_NO_ERROR();
1026 
1027         glActiveShaderProgram(pipeline1, programNonFetch);
1028         float colorRed[4]           = {1.0f, 0.0f, 0.0f, 1.0f};
1029         GLint colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
1030         glUniform4fv(colorLocationNonFetch, 1, colorRed);
1031         ASSERT_GL_NO_ERROR();
1032 
1033         glActiveShaderProgram(pipeline1, programVert);
1034         GLint positionLocation = glGetAttribLocation(programVert, "a_position");
1035         // Render without regard to glFramebufferFetchBarrierEXT()
1036         render(positionLocation, GL_FALSE);
1037         ASSERT_GL_NO_ERROR();
1038 
1039         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1040 
1041         glUseProgramStages(pipeline2, GL_VERTEX_SHADER_BIT, programVert);
1042         glUseProgramStages(pipeline2, GL_FRAGMENT_SHADER_BIT, programFetch);
1043         glBindProgramPipeline(pipeline2);
1044         ASSERT_GL_NO_ERROR();
1045 
1046         glActiveShaderProgram(pipeline2, programFetch);
1047         float colorGreen[4]      = {0.0f, 1.0f, 0.0f, 1.0f};
1048         GLint colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
1049         glUniform4fv(colorLocationFetch, 1, colorGreen);
1050 
1051         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1052         // extension being used
1053         render(positionLocation, !mCoherentExtension);
1054         ASSERT_GL_NO_ERROR();
1055 
1056         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1057 
1058         glUseProgramStages(pipeline3, GL_VERTEX_SHADER_BIT, programVert);
1059         glUseProgramStages(pipeline3, GL_FRAGMENT_SHADER_BIT, programNonFetch);
1060         glBindProgramPipeline(pipeline3);
1061         ASSERT_GL_NO_ERROR();
1062 
1063         glActiveShaderProgram(pipeline3, programNonFetch);
1064         colorLocationNonFetch = glGetUniformLocation(programNonFetch, "u_color");
1065         glUniform4fv(colorLocationNonFetch, 1, colorRed);
1066 
1067         ASSERT_GL_NO_ERROR();
1068 
1069         // Render without regard to glFramebufferFetchBarrierEXT()
1070         render(positionLocation, GL_FALSE);
1071         ASSERT_GL_NO_ERROR();
1072 
1073         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::red);
1074 
1075         glUseProgramStages(pipeline4, GL_VERTEX_SHADER_BIT, programVert);
1076         glUseProgramStages(pipeline4, GL_FRAGMENT_SHADER_BIT, programFetch);
1077         glBindProgramPipeline(pipeline4);
1078         ASSERT_GL_NO_ERROR();
1079 
1080         glActiveShaderProgram(pipeline4, programFetch);
1081         colorLocationFetch = glGetUniformLocation(programFetch, "u_color");
1082         glUniform4fv(colorLocationFetch, 1, colorGreen);
1083         // Render potentially with a glFramebufferFetchBarrierEXT() depending on the [non-]coherent
1084         // extension being used
1085         render(positionLocation, !mCoherentExtension);
1086         ASSERT_GL_NO_ERROR();
1087 
1088         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1089 
1090         glBindFramebuffer(GL_FRAMEBUFFER, 0);
1091     }
1092 
1093     bool mCoherentExtension;
1094 };
1095 
1096 // Test coherent extension with inout qualifier
TEST_P(FramebufferFetchES31,BasicInout_Coherent)1097 TEST_P(FramebufferFetchES31, BasicInout_Coherent)
1098 {
1099     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1100     setWhichExtension(COHERENT);
1101 
1102     GLProgram program;
1103     program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1104     glUseProgram(program);
1105     ASSERT_GL_NO_ERROR();
1106 
1107     BasicTest(program);
1108 }
1109 
1110 // Test non-coherent extension with inout qualifier
TEST_P(FramebufferFetchES31,BasicInout_NonCoherent)1111 TEST_P(FramebufferFetchES31, BasicInout_NonCoherent)
1112 {
1113     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1114     setWhichExtension(NON_COHERENT);
1115 
1116     GLProgram program;
1117     program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1118     glUseProgram(program);
1119     ASSERT_GL_NO_ERROR();
1120 
1121     BasicTest(program);
1122 }
1123 
1124 // Test coherent extension with gl_LastFragData
TEST_P(FramebufferFetchES31,BasicLastFragData_Coherent)1125 TEST_P(FramebufferFetchES31, BasicLastFragData_Coherent)
1126 {
1127     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1128     setWhichExtension(COHERENT);
1129 
1130     GLProgram program;
1131     program.makeRaster(k100VS, getFragmentShader(GLSL100));
1132     glUseProgram(program);
1133     ASSERT_GL_NO_ERROR();
1134 
1135     BasicTest(program);
1136 }
1137 
1138 // Test non-coherent extension with gl_LastFragData
TEST_P(FramebufferFetchES31,BasicLastFragData_NonCoherent)1139 TEST_P(FramebufferFetchES31, BasicLastFragData_NonCoherent)
1140 {
1141     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1142     setWhichExtension(NON_COHERENT);
1143 
1144     GLProgram program;
1145     program.makeRaster(k100VS, getFragmentShader(GLSL100));
1146     glUseProgram(program);
1147     ASSERT_GL_NO_ERROR();
1148 
1149     BasicTest(program);
1150 }
1151 
1152 // Testing coherent extension with multiple render target
TEST_P(FramebufferFetchES31,MultipleRenderTarget_Coherent)1153 TEST_P(FramebufferFetchES31, MultipleRenderTarget_Coherent)
1154 {
1155     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1156     setWhichExtension(COHERENT);
1157 
1158     GLProgram program;
1159     program.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT));
1160     glUseProgram(program);
1161     ASSERT_GL_NO_ERROR();
1162 
1163     MultipleRenderTargetTest(program);
1164 }
1165 
1166 // Testing non-coherent extension with multiple render target
TEST_P(FramebufferFetchES31,MultipleRenderTarget_NonCoherent)1167 TEST_P(FramebufferFetchES31, MultipleRenderTarget_NonCoherent)
1168 {
1169     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1170     setWhichExtension(NON_COHERENT);
1171 
1172     GLProgram program;
1173     program.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT));
1174     glUseProgram(program);
1175     ASSERT_GL_NO_ERROR();
1176 
1177     MultipleRenderTargetTest(program);
1178 }
1179 
1180 // Testing non-coherent extension with multiple render target using inout array
TEST_P(FramebufferFetchES31,MultipleRenderTargetWithInoutArray_NonCoherent)1181 TEST_P(FramebufferFetchES31, MultipleRenderTargetWithInoutArray_NonCoherent)
1182 {
1183     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1184     setWhichExtension(NON_COHERENT);
1185 
1186     GLProgram program;
1187     program.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT));
1188     glUseProgram(program);
1189     ASSERT_GL_NO_ERROR();
1190 
1191     MultipleRenderTargetTest(program);
1192 }
1193 
1194 // Testing coherent extension with multiple render target using inout array
TEST_P(FramebufferFetchES31,MultipleRenderTargetWithInoutArray_Coherent)1195 TEST_P(FramebufferFetchES31, MultipleRenderTargetWithInoutArray_Coherent)
1196 {
1197     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1198     setWhichExtension(COHERENT);
1199 
1200     GLProgram program;
1201     program.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT));
1202     glUseProgram(program);
1203     ASSERT_GL_NO_ERROR();
1204 
1205     MultipleRenderTargetTest(program);
1206 }
1207 
1208 // Test coherent extension with multiple draw
TEST_P(FramebufferFetchES31,MultipleDraw_Coherent)1209 TEST_P(FramebufferFetchES31, MultipleDraw_Coherent)
1210 {
1211     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1212     setWhichExtension(COHERENT);
1213 
1214     GLProgram program;
1215     program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1216     glUseProgram(program);
1217     ASSERT_GL_NO_ERROR();
1218 
1219     MultipleDrawTest(program);
1220 }
1221 
1222 // Test non-coherent extension with multiple draw
TEST_P(FramebufferFetchES31,MultipleDraw_NonCoherent)1223 TEST_P(FramebufferFetchES31, MultipleDraw_NonCoherent)
1224 {
1225     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1226     setWhichExtension(NON_COHERENT);
1227 
1228     GLProgram program;
1229     program.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1230     glUseProgram(program);
1231     ASSERT_GL_NO_ERROR();
1232 
1233     MultipleDrawTest(program);
1234 }
1235 
1236 // Testing coherent extension with the order of non-fetch program and fetch program
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetch_Coherent)1237 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetch_Coherent)
1238 {
1239     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1240     setWhichExtension(COHERENT);
1241 
1242     GLProgram programNonFetch, programFetch;
1243     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1244     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1245     ASSERT_GL_NO_ERROR();
1246 
1247     DrawNonFetchDrawFetchTest(programNonFetch, programFetch);
1248 }
1249 
1250 // Testing non-coherent extension with the order of non-fetch program and fetch program
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetch_NonCoherent)1251 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetch_NonCoherent)
1252 {
1253     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1254     setWhichExtension(NON_COHERENT);
1255 
1256     GLProgram programNonFetch, programFetch;
1257     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1258     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1259     ASSERT_GL_NO_ERROR();
1260 
1261     DrawNonFetchDrawFetchTest(programNonFetch, programFetch);
1262 }
1263 
1264 // Testing coherent extension with the order of fetch program and non-fetch program
TEST_P(FramebufferFetchES31,DrawFetchDrawNonFetch_Coherent)1265 TEST_P(FramebufferFetchES31, DrawFetchDrawNonFetch_Coherent)
1266 {
1267     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1268     setWhichExtension(COHERENT);
1269 
1270     GLProgram programNonFetch, programFetch;
1271     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1272     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1273     ASSERT_GL_NO_ERROR();
1274 
1275     DrawFetchDrawNonFetchTest(programNonFetch, programFetch);
1276 }
1277 
1278 // Testing non-coherent extension with the order of fetch program and non-fetch program
TEST_P(FramebufferFetchES31,DrawFetchDrawNonFetch_NonCoherent)1279 TEST_P(FramebufferFetchES31, DrawFetchDrawNonFetch_NonCoherent)
1280 {
1281     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1282     setWhichExtension(NON_COHERENT);
1283 
1284     GLProgram programNonFetch, programFetch;
1285     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1286     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_1ATTACHMENT));
1287     ASSERT_GL_NO_ERROR();
1288 
1289     DrawFetchDrawNonFetchTest(programNonFetch, programFetch);
1290 }
1291 
1292 // Testing coherent extension with the order of non-fetch program and fetch program with
1293 // different attachments
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchWithDifferentAttachments_Coherent)1294 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchWithDifferentAttachments_Coherent)
1295 {
1296     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1297     setWhichExtension(COHERENT);
1298 
1299     GLProgram programNonFetch, programFetch;
1300     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1301     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
1302     ASSERT_GL_NO_ERROR();
1303 
1304     DrawNonFetchDrawFetchWithDifferentAttachmentsTest(programNonFetch, programFetch);
1305 }
1306 
1307 // Testing non-coherent extension with the order of non-fetch program and fetch program with
1308 // different attachments
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchWithDifferentAttachments_NonCoherent)1309 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchWithDifferentAttachments_NonCoherent)
1310 {
1311     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1312     setWhichExtension(NON_COHERENT);
1313 
1314     GLProgram programNonFetch, programFetch;
1315     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1316     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
1317     ASSERT_GL_NO_ERROR();
1318 
1319     DrawNonFetchDrawFetchWithDifferentAttachmentsTest(programNonFetch, programFetch);
1320 }
1321 
1322 // Testing coherent extension with the order of non-fetch program and fetch with different
1323 // programs
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchWithDifferentPrograms_Coherent)1324 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchWithDifferentPrograms_Coherent)
1325 {
1326     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1327     setWhichExtension(COHERENT);
1328 
1329     GLProgram programNonFetch, programFetch1, programFetch2;
1330     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1331     programFetch1.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
1332     programFetch2.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT2));
1333     ASSERT_GL_NO_ERROR();
1334 
1335     DrawNonFetchDrawFetchWithDifferentProgramsTest(programNonFetch, programFetch1, programFetch2);
1336 }
1337 
1338 // Testing non-coherent extension with the order of non-fetch program and fetch with different
1339 // programs
TEST_P(FramebufferFetchES31,DrawNonFetchDrawFetchWithDifferentPrograms_NonCoherent)1340 TEST_P(FramebufferFetchES31, DrawNonFetchDrawFetchWithDifferentPrograms_NonCoherent)
1341 {
1342     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1343     setWhichExtension(NON_COHERENT);
1344 
1345     GLProgram programNonFetch, programFetch1, programFetch2;
1346     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1347     programFetch1.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
1348     programFetch2.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT2));
1349     ASSERT_GL_NO_ERROR();
1350 
1351     DrawNonFetchDrawFetchWithDifferentProgramsTest(programNonFetch, programFetch1, programFetch2);
1352 }
1353 
1354 // Testing coherent extension with the order of draw fetch, blit and draw fetch
TEST_P(FramebufferFetchES31,DrawFetchBlitDrawFetch_Coherent)1355 TEST_P(FramebufferFetchES31, DrawFetchBlitDrawFetch_Coherent)
1356 {
1357     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1358     setWhichExtension(COHERENT);
1359 
1360     GLProgram programNonFetch, programFetch;
1361     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1362     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
1363     ASSERT_GL_NO_ERROR();
1364 
1365     DrawFetchBlitDrawFetchTest(programNonFetch, programFetch);
1366 }
1367 
1368 // Testing non-coherent extension with the order of draw fetch, blit and draw fetch
TEST_P(FramebufferFetchES31,DrawFetchBlitDrawFetch_NonCoherent)1369 TEST_P(FramebufferFetchES31, DrawFetchBlitDrawFetch_NonCoherent)
1370 {
1371     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1372     setWhichExtension(NON_COHERENT);
1373 
1374     GLProgram programNonFetch, programFetch;
1375     programNonFetch.makeRaster(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT));
1376     programFetch.makeRaster(k310VS, getFragmentShader(GLSL310_4ATTACHMENT_DIFFERENT1));
1377     ASSERT_GL_NO_ERROR();
1378 
1379     DrawFetchBlitDrawFetchTest(programNonFetch, programFetch);
1380 }
1381 
1382 // Testing coherent extension with program pipeline
TEST_P(FramebufferFetchES31,ProgramPipeline_Coherent)1383 TEST_P(FramebufferFetchES31, ProgramPipeline_Coherent)
1384 {
1385     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch"));
1386     setWhichExtension(COHERENT);
1387 
1388     ProgramPipelineTest(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT),
1389                         getFragmentShader(GLSL310_1ATTACHMENT));
1390 }
1391 
1392 // Testing non-coherent extension with program pipeline
TEST_P(FramebufferFetchES31,ProgramPipeline_NonCoherent)1393 TEST_P(FramebufferFetchES31, ProgramPipeline_NonCoherent)
1394 {
1395     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1396     setWhichExtension(NON_COHERENT);
1397 
1398     ProgramPipelineTest(k310VS, getFragmentShader(GLSL310_NO_FETCH_1ATTACHMENT),
1399                         getFragmentShader(GLSL310_1ATTACHMENT));
1400 }
1401 
1402 // TODO: http://anglebug.com/5792
TEST_P(FramebufferFetchES31,DISABLED_UniformUsageCombinations)1403 TEST_P(FramebufferFetchES31, DISABLED_UniformUsageCombinations)
1404 {
1405     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1406 
1407     constexpr char kVS[] = R"(#version 310 es
1408 in highp vec4 a_position;
1409 out highp vec2 texCoord;
1410 
1411 void main()
1412 {
1413     gl_Position = a_position;
1414     texCoord = (a_position.xy * 0.5) + 0.5;
1415 })";
1416 
1417     constexpr char kFS[] = R"(#version 310 es
1418 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
1419 
1420 layout(binding=0, offset=0) uniform atomic_uint atDiff;
1421 uniform sampler2D tex;
1422 
1423 layout(noncoherent, location = 0) inout highp vec4 o_color[4];
1424 in highp vec2 texCoord;
1425 
1426 void main()
1427 {
1428     highp vec4 texColor = texture(tex, texCoord);
1429 
1430     if (texColor != o_color[0])
1431     {
1432         atomicCounterIncrement(atDiff);
1433         o_color[0] = texColor;
1434     }
1435     else
1436     {
1437         if (atomicCounter(atDiff) > 0u)
1438         {
1439             atomicCounterDecrement(atDiff);
1440         }
1441     }
1442 
1443     if (texColor != o_color[1])
1444     {
1445         atomicCounterIncrement(atDiff);
1446         o_color[1] = texColor;
1447     }
1448     else
1449     {
1450         if (atomicCounter(atDiff) > 0u)
1451         {
1452             atomicCounterDecrement(atDiff);
1453         }
1454     }
1455 
1456     if (texColor != o_color[2])
1457     {
1458         atomicCounterIncrement(atDiff);
1459         o_color[2] = texColor;
1460     }
1461     else
1462     {
1463         if (atomicCounter(atDiff) > 0u)
1464         {
1465             atomicCounterDecrement(atDiff);
1466         }
1467     }
1468 
1469     if (texColor != o_color[3])
1470     {
1471         atomicCounterIncrement(atDiff);
1472         o_color[3] = texColor;
1473     }
1474     else
1475     {
1476         if (atomicCounter(atDiff) > 0u)
1477         {
1478             atomicCounterDecrement(atDiff);
1479         }
1480     }
1481 })";
1482 
1483     GLProgram program;
1484     program.makeRaster(kVS, kFS);
1485     glUseProgram(program);
1486 
1487     ASSERT_GL_NO_ERROR();
1488 
1489     GLFramebuffer framebuffer;
1490     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1491     std::vector<GLColor> color0(kViewportWidth * kViewportHeight, GLColor::cyan);
1492     std::vector<GLColor> color1(kViewportWidth * kViewportHeight, GLColor::green);
1493     std::vector<GLColor> color2(kViewportWidth * kViewportHeight, GLColor::blue);
1494     std::vector<GLColor> color3(kViewportWidth * kViewportHeight, GLColor::black);
1495     GLTexture colorBufferTex[kMaxColorBuffer];
1496     GLenum colorAttachments[kMaxColorBuffer] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
1497                                                 GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
1498     glBindTexture(GL_TEXTURE_2D, colorBufferTex[0]);
1499     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1500                  GL_UNSIGNED_BYTE, color0.data());
1501     glBindTexture(GL_TEXTURE_2D, colorBufferTex[1]);
1502     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1503                  GL_UNSIGNED_BYTE, color1.data());
1504     glBindTexture(GL_TEXTURE_2D, colorBufferTex[2]);
1505     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1506                  GL_UNSIGNED_BYTE, color2.data());
1507     glBindTexture(GL_TEXTURE_2D, colorBufferTex[3]);
1508     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1509                  GL_UNSIGNED_BYTE, color3.data());
1510     glBindTexture(GL_TEXTURE_2D, 0);
1511     for (unsigned int i = 0; i < kMaxColorBuffer; i++)
1512     {
1513         glFramebufferTexture2D(GL_FRAMEBUFFER, colorAttachments[i], GL_TEXTURE_2D,
1514                                colorBufferTex[i], 0);
1515     }
1516     glDrawBuffers(kMaxColorBuffer, &colorAttachments[0]);
1517 
1518     ASSERT_GL_NO_ERROR();
1519 
1520     GLBuffer atomicBuffer;
1521     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicBuffer);
1522     glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_DRAW);
1523 
1524     // Reset atomic counter buffer
1525     GLuint *userCounters;
1526     userCounters = static_cast<GLuint *>(glMapBufferRange(
1527         GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint),
1528         GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT));
1529     memset(userCounters, 0, sizeof(GLuint));
1530     glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
1531 
1532     glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, atomicBuffer);
1533     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);
1534 
1535     float color[4]      = {1.0f, 0.0f, 0.0f, 1.0f};
1536     GLint colorLocation = glGetUniformLocation(program, "u_color");
1537     glUniform4fv(colorLocation, 1, color);
1538 
1539     GLint positionLocation = glGetAttribLocation(program, "a_position");
1540     render(positionLocation, GL_TRUE);
1541 
1542     ASSERT_GL_NO_ERROR();
1543 
1544     for (unsigned int i = 0; i < kMaxColorBuffer; i++)
1545     {
1546         glReadBuffer(colorAttachments[i]);
1547         EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::black);
1548     }
1549 
1550     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, atomicBuffer);
1551     userCounters = static_cast<GLuint *>(
1552         glMapBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(GLuint), GL_MAP_READ_BIT));
1553     EXPECT_EQ(*userCounters, kViewportWidth * kViewportHeight * 2);
1554     glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER);
1555     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, 0);
1556 
1557     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1558 }
1559 
1560 // Testing that binding the location value using GLES API is conflicted to the location value of the
1561 // fragment inout.
TEST_P(FramebufferFetchES31,FixedUniformLocation)1562 TEST_P(FramebufferFetchES31, FixedUniformLocation)
1563 {
1564     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));
1565 
1566     constexpr char kVS[] = R"(#version 310 es
1567 in highp vec4 a_position;
1568 
1569 void main (void)
1570 {
1571     gl_Position = a_position;
1572 })";
1573 
1574     constexpr char kFS[] = R"(#version 310 es
1575 #extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
1576 layout(noncoherent, location = 0) inout highp vec4 o_color;
1577 
1578 layout(location = 0) uniform highp vec4 u_color;
1579 void main (void)
1580 {
1581     o_color += u_color;
1582 })";
1583 
1584     GLProgram program;
1585     program.makeRaster(kVS, kFS);
1586     glUseProgram(program);
1587 
1588     ASSERT_GL_NO_ERROR();
1589 
1590     GLFramebuffer framebuffer;
1591     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1592     std::vector<GLColor> greenColor(kViewportWidth * kViewportHeight, GLColor::green);
1593     GLTexture colorBufferTex;
1594     glBindTexture(GL_TEXTURE_2D, colorBufferTex);
1595     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kViewportWidth, kViewportHeight, 0, GL_RGBA,
1596                  GL_UNSIGNED_BYTE, greenColor.data());
1597     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTex, 0);
1598 
1599     ASSERT_GL_NO_ERROR();
1600 
1601     float color[4]      = {1.0f, 0.0f, 0.0f, 1.0f};
1602     GLint colorLocation = glGetUniformLocation(program, "u_color");
1603     glUniform4fv(colorLocation, 1, color);
1604 
1605     GLint positionLocation = glGetAttribLocation(program, "a_position");
1606     render(positionLocation, GL_TRUE);
1607 
1608     ASSERT_GL_NO_ERROR();
1609 
1610     EXPECT_PIXEL_COLOR_EQ(kViewportWidth / 2, kViewportHeight / 2, GLColor::yellow);
1611 
1612     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1613 }
1614 
1615 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FramebufferFetchES31);
1616 ANGLE_INSTANTIATE_TEST_ES31(FramebufferFetchES31);
1617 }  // namespace angle
1618