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