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