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