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