xref: /aosp_15_r20/external/angle/src/tests/gl_tests/MemoryBarrierTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 // MemoryBarrierTest:
7 //   Ensure that implementation of glMemoryBarrier is correct both in terms of memory barriers
8 //   issued and potential reordering of commands.
9 //
10 // The barrier bits accepted by glMemoryBarrier are used for synchronization as such:
11 //
12 //     VERTEX_ATTRIB_ARRAY_BARRIER_BIT: shader write -> vertex read
13 //     ELEMENT_ARRAY_BARRIER_BIT:       shader write -> index read
14 //     UNIFORM_BARRIER_BIT:             shader write -> uniform read
15 //     TEXTURE_FETCH_BARRIER_BIT:       shader write -> texture sample
16 //     SHADER_IMAGE_ACCESS_BARRIER_BIT: shader write -> image access
17 //                                      any access -> image write
18 //     COMMAND_BARRIER_BIT:             shader write -> indirect buffer read
19 //     PIXEL_BUFFER_BARRIER_BIT:        shader write -> pbo access
20 //     TEXTURE_UPDATE_BARRIER_BIT:      shader write -> texture data upload
21 //     BUFFER_UPDATE_BARRIER_BIT:       shader write -> buffer data upload/map
22 //     FRAMEBUFFER_BARRIER_BIT:         shader write -> access through framebuffer
23 //     TRANSFORM_FEEDBACK_BARRIER_BIT:  shader write -> transform feedback write
24 //     ATOMIC_COUNTER_BARRIER_BIT:      shader write -> atomic counter access
25 //     SHADER_STORAGE_BARRIER_BIT:      shader write -> buffer access
26 //                                      any access -> buffer write
27 //
28 // In summary, every bit defines a memory barrier for some access after a shader write.
29 // Additionally, SHADER_IMAGE_ACCESS_BARRIER_BIT and SHADER_STORAGE_BARRIER_BIT bits are used to
30 // define a memory barrier for shader writes after other accesses.
31 
32 #include "test_utils/ANGLETest.h"
33 #include "test_utils/gl_raii.h"
34 #include "util/random_utils.h"
35 
36 using namespace angle;
37 
38 namespace
39 {
40 enum class ShaderWritePipeline
41 {
42     Graphics,
43     Compute,
44 };
45 
46 enum class WriteResource
47 {
48     Image,
49     ImageBuffer,
50     Buffer,
51 };
52 
53 enum class NoopOp
54 {
55     None,
56     Draw,
57     Dispatch,
58 };
59 
60 // Variations corresponding to enums above.
61 using MemoryBarrierVariationsTestParams =
62     std::tuple<angle::PlatformParameters, ShaderWritePipeline, WriteResource, NoopOp, NoopOp>;
63 
operator <<(std::ostream & out,WriteResource writeResource)64 std::ostream &operator<<(std::ostream &out, WriteResource writeResource)
65 {
66     switch (writeResource)
67     {
68         case WriteResource::Image:
69             out << "image";
70             break;
71         case WriteResource::Buffer:
72             out << "buffer";
73             break;
74         case WriteResource::ImageBuffer:
75             out << "imagebuffer";
76             break;
77     }
78 
79     return out;
80 }
81 
operator <<(std::ostream & out,ShaderWritePipeline writePipeline)82 std::ostream &operator<<(std::ostream &out, ShaderWritePipeline writePipeline)
83 {
84     if (writePipeline == ShaderWritePipeline::Graphics)
85     {
86         out << "graphics";
87     }
88     else
89     {
90         out << "compute";
91     }
92 
93     return out;
94 }
95 
operator <<(std::ostream & out,NoopOp noop)96 std::ostream &operator<<(std::ostream &out, NoopOp noop)
97 {
98     switch (noop)
99     {
100         case NoopOp::Draw:
101             out << "NoopDraw";
102             break;
103         case NoopOp::Dispatch:
104             out << "NoopDispatch";
105             break;
106         case NoopOp::None:
107             out << "NoopNone";
108             break;
109     }
110 
111     return out;
112 }
113 
ParseMemoryBarrierVariationsTestParams(const MemoryBarrierVariationsTestParams & params,ShaderWritePipeline * writePipelineOut,WriteResource * writeResourceOut,NoopOp * preBarrierOpOut,NoopOp * postBarrierOpOut)114 void ParseMemoryBarrierVariationsTestParams(const MemoryBarrierVariationsTestParams &params,
115                                             ShaderWritePipeline *writePipelineOut,
116                                             WriteResource *writeResourceOut,
117                                             NoopOp *preBarrierOpOut,
118                                             NoopOp *postBarrierOpOut)
119 {
120     *writePipelineOut = std::get<1>(params);
121     *writeResourceOut = std::get<2>(params);
122     *preBarrierOpOut  = std::get<3>(params);
123     *postBarrierOpOut = std::get<4>(params);
124 }
125 
MemoryBarrierVariationsTestPrint(const::testing::TestParamInfo<MemoryBarrierVariationsTestParams> & paramsInfo)126 std::string MemoryBarrierVariationsTestPrint(
127     const ::testing::TestParamInfo<MemoryBarrierVariationsTestParams> &paramsInfo)
128 {
129     const MemoryBarrierVariationsTestParams &params = paramsInfo.param;
130     std::ostringstream out;
131 
132     out << std::get<0>(params);
133 
134     ShaderWritePipeline writePipeline;
135     WriteResource writeResource;
136     NoopOp preBarrierOp;
137     NoopOp postBarrierOp;
138 
139     ParseMemoryBarrierVariationsTestParams(params, &writePipeline, &writeResource, &preBarrierOp,
140                                            &postBarrierOp);
141 
142     out << "__" << writePipeline << "_" << writeResource;
143 
144     if (preBarrierOp != NoopOp::None)
145     {
146         out << "_prebarrier" << preBarrierOp;
147     }
148     if (postBarrierOp != NoopOp::None)
149     {
150         out << "_postbarrier" << postBarrierOp;
151     }
152     return out.str();
153 }
154 
155 class MemoryBarrierTestBase
156 {
157   protected:
158     bool hasExtensions(WriteResource writeResource);
159 
160     // Helper functions
161     void createFramebuffer(GLuint color, GLuint fbo, GLColor initialColor);
162     void createStorageBuffer(WriteResource writeResource,
163                              GLuint buffer,
164                              GLuint textureBuffer,
165                              size_t size,
166                              const void *initialData);
167     void createStorageImage(WriteResource writeResource,
168                             GLuint bufferStorage,
169                             GLuint texture,
170                             const std::array<float, 4> &initialData);
171     void createProgram(ShaderWritePipeline writePipeline,
172                        WriteResource writeResource,
173                        GLProgram *programOut);
174     void createNoopGraphicsProgram(GLProgram *programOut);
175     void createNoopComputeProgram(GLProgram *programOut);
176     void createQuadVertexArray(GLuint positionBuffer);
177     void setupVertexArray(ShaderWritePipeline writePipeline, GLuint program);
178     void setUniformData(GLuint program, const std::array<float, 4> &data);
179     void noopOp(NoopOp op);
180 
181     template <typename T>
182     void verifyBufferContents(const std::array<T, 4> &expected);
183 
184     void verifyImageContents(GLuint texture, const std::array<float, 4> &expected);
185 
186     template <typename T>
187     void verifyFramebufferAndBufferContents(ShaderWritePipeline writePipeline,
188                                             const std::array<T, 4> &expected);
189 
190     void verifyFramebufferAndImageContents(ShaderWritePipeline writePipeline,
191                                            WriteResource writeResource,
192                                            GLuint texture,
193                                            const std::array<float, 4> &expected);
194 
195     // Barrier bits affecting only buffers and imageBuffers
196     void createVertexVerifyProgram(GLuint vertexBuffer, GLProgram *programOut);
197     void vertexAttribArrayBitBufferWriteThenVertexRead(ShaderWritePipeline writePipeline,
198                                                        WriteResource writeResource,
199                                                        NoopOp preBarrierOp,
200                                                        NoopOp postBarrierOp);
201     void vertexAttribArrayBitVertexReadThenBufferWrite(ShaderWritePipeline writePipeline,
202                                                        WriteResource writeResource,
203                                                        NoopOp preBarrierOp,
204                                                        NoopOp postBarrierOp,
205                                                        GLbitfield barrierBit);
206 
207     void createIndexVerifyProgram(GLuint indexBuffer, GLProgram *programOut);
208     void elementArrayBitBufferWriteThenIndexRead(ShaderWritePipeline writePipeline,
209                                                  WriteResource writeResource,
210                                                  NoopOp preBarrierOp,
211                                                  NoopOp postBarrierOp);
212     void elementArrayBitIndexReadThenBufferWrite(ShaderWritePipeline writePipeline,
213                                                  WriteResource writeResource,
214                                                  NoopOp preBarrierOp,
215                                                  NoopOp postBarrierOp,
216                                                  GLbitfield barrierBit);
217 
218     void createUBOVerifyProgram(GLuint buffer, GLProgram *programOut);
219     void uniformBitBufferWriteThenUBORead(ShaderWritePipeline writePipeline,
220                                           WriteResource writeResource,
221                                           NoopOp preBarrierOp,
222                                           NoopOp postBarrierOp);
223     void uniformBitUBOReadThenBufferWrite(ShaderWritePipeline writePipeline,
224                                           WriteResource writeResource,
225                                           NoopOp preBarrierOp,
226                                           NoopOp postBarrierOp,
227                                           GLbitfield barrierBit);
228 
229     void createIndirectVerifyProgram(GLuint buffer, GLProgram *programOut);
230     void commandBitBufferWriteThenIndirectRead(ShaderWritePipeline writePipeline,
231                                                WriteResource writeResource,
232                                                NoopOp preBarrierOp,
233                                                NoopOp postBarrierOp);
234     void commandBitIndirectReadThenBufferWrite(ShaderWritePipeline writePipeline,
235                                                WriteResource writeResource,
236                                                NoopOp preBarrierOp,
237                                                NoopOp postBarrierOp,
238                                                GLbitfield barrierBit);
239 
240     void pixelBufferBitBufferWriteThenPack(ShaderWritePipeline writePipeline,
241                                            WriteResource writeResource,
242                                            NoopOp preBarrierOp,
243                                            NoopOp postBarrierOp);
244     void pixelBufferBitBufferWriteThenUnpack(ShaderWritePipeline writePipeline,
245                                              WriteResource writeResource,
246                                              NoopOp preBarrierOp,
247                                              NoopOp postBarrierOp);
248     void pixelBufferBitPackThenBufferWrite(ShaderWritePipeline writePipeline,
249                                            WriteResource writeResource,
250                                            NoopOp preBarrierOp,
251                                            NoopOp postBarrierOp,
252                                            GLbitfield barrierBit);
253     void pixelBufferBitUnpackThenBufferWrite(ShaderWritePipeline writePipeline,
254                                              WriteResource writeResource,
255                                              NoopOp preBarrierOp,
256                                              NoopOp postBarrierOp,
257                                              GLbitfield barrierBit);
258 
259     void bufferUpdateBitBufferWriteThenCopy(ShaderWritePipeline writePipeline,
260                                             WriteResource writeResource,
261                                             NoopOp preBarrierOp,
262                                             NoopOp postBarrierOp);
263     void bufferUpdateBitCopyThenBufferWrite(ShaderWritePipeline writePipeline,
264                                             WriteResource writeResource,
265                                             NoopOp preBarrierOp,
266                                             NoopOp postBarrierOp,
267                                             GLbitfield barrierBit);
268 
269     void createXfbVerifyProgram(GLuint buffer, GLProgram *programOut);
270     void transformFeedbackBitBufferWriteThenCapture(ShaderWritePipeline writePipeline,
271                                                     WriteResource writeResource,
272                                                     NoopOp preBarrierOp,
273                                                     NoopOp postBarrierOp);
274     void transformFeedbackBitCaptureThenBufferWrite(ShaderWritePipeline writePipeline,
275                                                     WriteResource writeResource,
276                                                     NoopOp preBarrierOp,
277                                                     NoopOp postBarrierOp,
278                                                     GLbitfield barrierBit);
279 
280     void createAtomicCounterVerifyProgram(GLuint buffer, GLProgram *programOut);
281     void atomicCounterBitBufferWriteThenAtomic(ShaderWritePipeline writePipeline,
282                                                WriteResource writeResource,
283                                                NoopOp preBarrierOp,
284                                                NoopOp postBarrierOp);
285     void atomicCounterBitAtomicThenBufferWrite(ShaderWritePipeline writePipeline,
286                                                WriteResource writeResource,
287                                                NoopOp preBarrierOp,
288                                                NoopOp postBarrierOp,
289                                                GLbitfield barrierBit);
290 
291     void createSsboVerifyProgram(WriteResource writeResourcee, GLProgram *programOut);
292     void shaderStorageBitBufferWriteThenBufferRead(ShaderWritePipeline writePipeline,
293                                                    WriteResource writeResource,
294                                                    NoopOp preBarrierOp,
295                                                    NoopOp postBarrierOp);
296     void shaderStorageBitBufferReadThenBufferWrite(ShaderWritePipeline writePipeline,
297                                                    WriteResource writeResource,
298                                                    NoopOp preBarrierOp,
299                                                    NoopOp postBarrierOp,
300                                                    GLbitfield barrierBit);
301 
302     // Barrier bits affecting only images and imageBuffers
303     void createTextureVerifyProgram(WriteResource writeResource,
304                                     GLuint texture,
305                                     GLProgram *programOut);
306     void textureFetchBitImageWriteThenSamplerRead(ShaderWritePipeline writePipeline,
307                                                   WriteResource writeResource,
308                                                   NoopOp preBarrierOp,
309                                                   NoopOp postBarrierOp);
310     void textureFetchBitSamplerReadThenImageWrite(ShaderWritePipeline writePipeline,
311                                                   WriteResource writeResource,
312                                                   NoopOp preBarrierOp,
313                                                   NoopOp postBarrierOp,
314                                                   GLbitfield barrierBit);
315 
316     void createImageVerifyProgram(WriteResource writeResource,
317                                   GLuint texture,
318                                   GLProgram *programOut);
319     void shaderImageAccessBitImageWriteThenImageRead(ShaderWritePipeline writePipeline,
320                                                      WriteResource writeResource,
321                                                      NoopOp preBarrierOp,
322                                                      NoopOp postBarrierOp);
323     void shaderImageAccessBitImageReadThenImageWrite(ShaderWritePipeline writePipeline,
324                                                      WriteResource writeResource,
325                                                      NoopOp preBarrierOp,
326                                                      NoopOp postBarrierOp);
327 
328     // Barrier bits affecting only images
329     void textureUpdateBitImageWriteThenCopy(ShaderWritePipeline writePipeline,
330                                             WriteResource writeResource,
331                                             NoopOp preBarrierOp,
332                                             NoopOp postBarrierOp);
333     void textureUpdateBitCopyThenImageWrite(ShaderWritePipeline writePipeline,
334                                             WriteResource writeResource,
335                                             NoopOp preBarrierOp,
336                                             NoopOp postBarrierOp,
337                                             GLbitfield barrierBit);
338 
339     void framebufferBitImageWriteThenDraw(ShaderWritePipeline writePipeline,
340                                           WriteResource writeResource,
341                                           NoopOp preBarrierOp,
342                                           NoopOp postBarrierOp);
343     void framebufferBitImageWriteThenReadPixels(ShaderWritePipeline writePipeline,
344                                                 WriteResource writeResource,
345                                                 NoopOp preBarrierOp,
346                                                 NoopOp postBarrierOp);
347     void framebufferBitImageWriteThenCopy(ShaderWritePipeline writePipeline,
348                                           WriteResource writeResource,
349                                           NoopOp preBarrierOp,
350                                           NoopOp postBarrierOp);
351     void framebufferBitImageWriteThenBlit(ShaderWritePipeline writePipeline,
352                                           WriteResource writeResource,
353                                           NoopOp preBarrierOp,
354                                           NoopOp postBarrierOp);
355     void framebufferBitDrawThenImageWrite(ShaderWritePipeline writePipeline,
356                                           WriteResource writeResource,
357                                           NoopOp preBarrierOp,
358                                           NoopOp postBarrierOp,
359                                           GLbitfield barrierBit);
360     void framebufferBitReadPixelsThenImageWrite(ShaderWritePipeline writePipeline,
361                                                 WriteResource writeResource,
362                                                 NoopOp preBarrierOp,
363                                                 NoopOp postBarrierOp,
364                                                 GLbitfield barrierBit);
365     void framebufferBitCopyThenImageWrite(ShaderWritePipeline writePipeline,
366                                           WriteResource writeResource,
367                                           NoopOp preBarrierOp,
368                                           NoopOp postBarrierOp,
369                                           GLbitfield barrierBit);
370     void framebufferBitBlitThenImageWrite(ShaderWritePipeline writePipeline,
371                                           WriteResource writeResource,
372                                           NoopOp preBarrierOp,
373                                           NoopOp postBarrierOp,
374                                           GLbitfield barrierBit);
375 
376     static constexpr int kTextureSize    = 1;
377     static constexpr char kUniformName[] = "uniformData";
378 };
379 
hasExtensions(WriteResource writeResource)380 bool MemoryBarrierTestBase::hasExtensions(WriteResource writeResource)
381 {
382     return writeResource != WriteResource::ImageBuffer ||
383            IsGLExtensionEnabled("GL_OES_texture_buffer");
384 }
385 
createFramebuffer(GLuint color,GLuint fbo,GLColor initialColor)386 void MemoryBarrierTestBase::createFramebuffer(GLuint color, GLuint fbo, GLColor initialColor)
387 {
388     glBindTexture(GL_TEXTURE_2D, color);
389     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureSize, kTextureSize);
390     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE,
391                     &initialColor);
392     EXPECT_GL_NO_ERROR();
393 
394     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
395     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
396     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
397     EXPECT_GL_NO_ERROR();
398 
399     // Ensure all staged data is flushed.
400     EXPECT_PIXEL_COLOR_EQ(0, 0, initialColor);
401 }
402 
createStorageBuffer(WriteResource writeResource,GLuint buffer,GLuint textureBuffer,size_t size,const void * initialData)403 void MemoryBarrierTestBase::createStorageBuffer(WriteResource writeResource,
404                                                 GLuint buffer,
405                                                 GLuint textureBuffer,
406                                                 size_t size,
407                                                 const void *initialData)
408 {
409     glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
410     glBufferData(GL_SHADER_STORAGE_BUFFER, size, initialData, GL_STATIC_DRAW);
411     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);
412     EXPECT_GL_NO_ERROR();
413 
414     if (writeResource == WriteResource::ImageBuffer)
415     {
416         glBindTexture(GL_TEXTURE_BUFFER, textureBuffer);
417         glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA32F, buffer);
418         glBindImageTexture(0, textureBuffer, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
419         EXPECT_GL_NO_ERROR();
420     }
421 }
422 
createStorageImage(WriteResource writeResource,GLuint bufferStorage,GLuint texture,const std::array<float,4> & initialData)423 void MemoryBarrierTestBase::createStorageImage(WriteResource writeResource,
424                                                GLuint bufferStorage,
425                                                GLuint texture,
426                                                const std::array<float, 4> &initialData)
427 {
428     const std::array<uint8_t, 4> initialDataAsUnorm = {
429         static_cast<uint8_t>(initialData[0] * 255),
430         static_cast<uint8_t>(initialData[1] * 255),
431         static_cast<uint8_t>(initialData[2] * 255),
432         static_cast<uint8_t>(initialData[3] * 255),
433     };
434 
435     if (writeResource == WriteResource::ImageBuffer)
436     {
437         glBindBuffer(GL_SHADER_STORAGE_BUFFER, bufferStorage);
438         glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(initialData), initialData.data(),
439                      GL_STATIC_DRAW);
440         EXPECT_GL_NO_ERROR();
441 
442         glBindTexture(GL_TEXTURE_BUFFER, texture);
443         glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA32F, bufferStorage);
444         glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
445         EXPECT_GL_NO_ERROR();
446     }
447     else
448     {
449         glBindTexture(GL_TEXTURE_2D, texture);
450         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureSize, kTextureSize);
451         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureSize, kTextureSize, GL_RGBA,
452                         GL_UNSIGNED_BYTE, initialDataAsUnorm.data());
453         glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
454     }
455 }
456 
createProgram(ShaderWritePipeline writePipeline,WriteResource writeResource,GLProgram * programOut)457 void MemoryBarrierTestBase::createProgram(ShaderWritePipeline writePipeline,
458                                           WriteResource writeResource,
459                                           GLProgram *programOut)
460 {
461     constexpr char kGraphicsImageFS[] = R"(#version 310 es
462 precision mediump float;
463 layout(rgba8, binding = 0) uniform highp writeonly image2D dst;
464 uniform vec4 uniformData;
465 out vec4 colorOut;
466 void main()
467 {
468     colorOut = vec4(0, 0, 1.0, 1.0);
469     imageStore(dst, ivec2(gl_FragCoord.xy), uniformData);
470 })";
471 
472     constexpr char kGraphicsBufferFS[] = R"(#version 310 es
473 precision mediump float;
474 uniform vec4 uniformData;
475 layout(std430, binding = 0) buffer block {
476     vec4 data;
477 } outBlock;
478 out vec4 colorOut;
479 void main()
480 {
481     colorOut = vec4(0, 0, 1.0, 1.0);
482     outBlock.data = uniformData;
483 }
484 )";
485 
486     constexpr char kGraphicsImageBufferFS[] = R"(#version 310 es
487 #extension GL_OES_texture_buffer : require
488 precision mediump float;
489 layout(rgba32f, binding = 0) uniform highp writeonly imageBuffer dst;
490 uniform vec4 uniformData;
491 out vec4 colorOut;
492 void main()
493 {
494     colorOut = vec4(0, 0, 1.0, 1.0);
495     imageStore(dst, int(gl_FragCoord.x), uniformData);
496 })";
497 
498     constexpr char kComputeImage[] = R"(#version 310 es
499 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
500 layout(rgba8, binding = 0) uniform highp writeonly image2D dst;
501 uniform vec4 uniformData;
502 void main()
503 {
504     imageStore(dst, ivec2(gl_GlobalInvocationID.xy), uniformData);
505 })";
506 
507     constexpr char kComputeBuffer[] = R"(#version 310 es
508 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
509 uniform vec4 uniformData;
510 layout(std430, binding = 0) buffer block {
511     vec4 data;
512 } outBlock;
513 void main()
514 {
515     outBlock.data = uniformData;
516 }
517 )";
518 
519     constexpr char kComputeImageBuffer[] = R"(#version 310 es
520 #extension GL_OES_texture_buffer : require
521 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
522 layout(rgba32f, binding = 0) uniform highp writeonly imageBuffer dst;
523 uniform vec4 uniformData;
524 void main()
525 {
526     imageStore(dst, int(gl_GlobalInvocationID.x), uniformData);
527 })";
528 
529     if (writePipeline == ShaderWritePipeline::Graphics)
530     {
531         const char *fs = "";
532         switch (writeResource)
533         {
534             case WriteResource::Image:
535                 fs = kGraphicsImageFS;
536                 break;
537             case WriteResource::Buffer:
538                 fs = kGraphicsBufferFS;
539                 break;
540             case WriteResource::ImageBuffer:
541                 fs = kGraphicsImageBufferFS;
542                 break;
543         }
544 
545         programOut->makeRaster(essl31_shaders::vs::Simple(), fs);
546     }
547     else
548     {
549         const char *cs = "";
550         switch (writeResource)
551         {
552             case WriteResource::Image:
553                 cs = kComputeImage;
554                 break;
555             case WriteResource::Buffer:
556                 cs = kComputeBuffer;
557                 break;
558             case WriteResource::ImageBuffer:
559                 cs = kComputeImageBuffer;
560                 break;
561         }
562 
563         programOut->makeCompute(cs);
564     }
565 
566     ASSERT_TRUE(programOut->valid());
567     glUseProgram(*programOut);
568 }
569 
createNoopGraphicsProgram(GLProgram * programOut)570 void MemoryBarrierTestBase::createNoopGraphicsProgram(GLProgram *programOut)
571 {
572     programOut->makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
573     ASSERT_TRUE(programOut->valid());
574 }
575 
createNoopComputeProgram(GLProgram * programOut)576 void MemoryBarrierTestBase::createNoopComputeProgram(GLProgram *programOut)
577 {
578     constexpr char kCS[] = R"(#version 310 es
579 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
580 void main()
581 {
582 })";
583 
584     programOut->makeCompute(kCS);
585     ASSERT_TRUE(programOut->valid());
586 }
587 
createQuadVertexArray(GLuint positionBuffer)588 void MemoryBarrierTestBase::createQuadVertexArray(GLuint positionBuffer)
589 {
590     const std::array<Vector3, 6> kQuadVertices = {{
591         Vector3(-1.0f, 1.0f, 0.5f),
592         Vector3(-1.0f, -1.0f, 0.5f),
593         Vector3(1.0f, -1.0f, 0.5f),
594         Vector3(-1.0f, 1.0f, 0.5f),
595         Vector3(1.0f, -1.0f, 0.5f),
596         Vector3(1.0f, 1.0f, 0.5f),
597     }};
598 
599     const size_t bufferSize = kQuadVertices.size() * sizeof(Vector3);
600 
601     glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
602     glBufferData(GL_ARRAY_BUFFER, bufferSize, kQuadVertices.data(), GL_STATIC_DRAW);
603     EXPECT_GL_NO_ERROR();
604 }
605 
setupVertexArray(ShaderWritePipeline writePipeline,GLuint program)606 void MemoryBarrierTestBase::setupVertexArray(ShaderWritePipeline writePipeline, GLuint program)
607 {
608     if (writePipeline == ShaderWritePipeline::Compute)
609     {
610         return;
611     }
612 
613     GLint positionLoc = glGetAttribLocation(program, essl31_shaders::PositionAttrib());
614     ASSERT_NE(-1, positionLoc);
615 
616     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
617     glEnableVertexAttribArray(positionLoc);
618     EXPECT_GL_NO_ERROR();
619 }
620 
setUniformData(GLuint program,const std::array<float,4> & data)621 void MemoryBarrierTestBase::setUniformData(GLuint program, const std::array<float, 4> &data)
622 {
623     GLint uniformLocation = glGetUniformLocation(program, kUniformName);
624     ASSERT_NE(uniformLocation, -1);
625 
626     glUniform4f(uniformLocation, data[0], data[1], data[2], data[3]);
627     EXPECT_GL_NO_ERROR();
628 }
629 
noopOp(NoopOp op)630 void MemoryBarrierTestBase::noopOp(NoopOp op)
631 {
632     if (op == NoopOp::None)
633     {
634         return;
635     }
636 
637     GLProgram noopProgram;
638     if (op == NoopOp::Draw)
639     {
640         createNoopGraphicsProgram(&noopProgram);
641 
642         glEnable(GL_BLEND);
643         glBlendFunc(GL_ZERO, GL_ONE);
644 
645         glUseProgram(noopProgram);
646         glDrawArrays(GL_TRIANGLES, 0, 3);
647 
648         glDisable(GL_BLEND);
649     }
650     else
651     {
652         createNoopComputeProgram(&noopProgram);
653         glUseProgram(noopProgram);
654         glDispatchCompute(1, 1, 1);
655     }
656 
657     EXPECT_GL_NO_ERROR();
658 }
659 
660 template <typename T>
verifyBufferContents(const std::array<T,4> & expected)661 void MemoryBarrierTestBase::verifyBufferContents(const std::array<T, 4> &expected)
662 {
663     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
664     T *bufferContents = static_cast<T *>(
665         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(expected), GL_MAP_READ_BIT));
666     EXPECT_GL_NO_ERROR();
667 
668     EXPECT_EQ(bufferContents[0], expected[0]);
669     EXPECT_EQ(bufferContents[1], expected[1]);
670     EXPECT_EQ(bufferContents[2], expected[2]);
671     EXPECT_EQ(bufferContents[3], expected[3]);
672     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
673 }
674 
verifyImageContents(GLuint texture,const std::array<float,4> & expected)675 void MemoryBarrierTestBase::verifyImageContents(GLuint texture,
676                                                 const std::array<float, 4> &expected)
677 {
678     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
679     glBindTexture(GL_TEXTURE_2D, texture);
680     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
681     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
682     EXPECT_GL_NO_ERROR();
683 
684     const GLColor kExpected(expected[0] * 255, expected[1] * 255, expected[2] * 255,
685                             expected[3] * 255);
686     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);
687 }
688 
689 template <typename T>
verifyFramebufferAndBufferContents(ShaderWritePipeline writePipeline,const std::array<T,4> & expected)690 void MemoryBarrierTestBase::verifyFramebufferAndBufferContents(ShaderWritePipeline writePipeline,
691                                                                const std::array<T, 4> &expected)
692 {
693     // Verify the result of the verify shader
694     const GLColor kExpected =
695         writePipeline == ShaderWritePipeline::Graphics ? GLColor::cyan : GLColor::green;
696     EXPECT_PIXEL_COLOR_EQ(0, 0, kExpected);
697 
698     // Verify the contents of the buffer
699     verifyBufferContents(expected);
700 }
701 
verifyFramebufferAndImageContents(ShaderWritePipeline writePipeline,WriteResource writeResource,GLuint texture,const std::array<float,4> & expected)702 void MemoryBarrierTestBase::verifyFramebufferAndImageContents(ShaderWritePipeline writePipeline,
703                                                               WriteResource writeResource,
704                                                               GLuint texture,
705                                                               const std::array<float, 4> &expected)
706 {
707     // Verify the result of the verify shader
708     const GLColor kExpected =
709         writePipeline == ShaderWritePipeline::Graphics ? GLColor::cyan : GLColor::green;
710     EXPECT_PIXEL_COLOR_EQ(0, 0, kExpected);
711 
712     if (writeResource == WriteResource::ImageBuffer)
713     {
714         // Verify the contents of the buffer
715         verifyBufferContents(expected);
716     }
717     else
718     {
719         // Verify the contents of the image
720         verifyImageContents(texture, expected);
721     }
722 }
723 
createVertexVerifyProgram(GLuint vertexBuffer,GLProgram * programOut)724 void MemoryBarrierTestBase::createVertexVerifyProgram(GLuint vertexBuffer, GLProgram *programOut)
725 {
726     constexpr char kVS[] = R"(#version 310 es
727 in float attribIn;
728 out float v;
729 
730 void main()
731 {
732     v = attribIn;
733     // gl_VertexID    x    y
734     //      0        -1   -1
735     //      1         1   -1
736     //      2        -1    1
737     //      3         1    1
738     int bit0 = gl_VertexID & 1;
739     int bit1 = gl_VertexID >> 1;
740     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
741 })";
742 
743     constexpr char kFS[] = R"(#version 310 es
744 precision mediump float;
745 in float v;
746 out vec4 colorOut;
747 void main()
748 {
749     if (v == 2.0)
750         colorOut = vec4(0, 1.0, 0, 1.0);
751     else
752         colorOut = vec4(1.0, 0, 0, 1.0);
753 })";
754 
755     programOut->makeRaster(kVS, kFS);
756     ASSERT_TRUE(programOut->valid());
757     glUseProgram(*programOut);
758 
759     GLint attribLoc = glGetAttribLocation(*programOut, "attribIn");
760     ASSERT_NE(-1, attribLoc);
761 
762     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
763     glVertexAttribPointer(attribLoc, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
764     glEnableVertexAttribArray(attribLoc);
765     EXPECT_GL_NO_ERROR();
766 }
767 
vertexAttribArrayBitBufferWriteThenVertexRead(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)768 void MemoryBarrierTestBase::vertexAttribArrayBitBufferWriteThenVertexRead(
769     ShaderWritePipeline writePipeline,
770     WriteResource writeResource,
771     NoopOp preBarrierOp,
772     NoopOp postBarrierOp)
773 {
774     GLTexture color;
775     GLFramebuffer fbo;
776     GLProgram writeProgram;
777 
778     createFramebuffer(color, fbo, GLColor::black);
779     createProgram(writePipeline, writeResource, &writeProgram);
780 
781     GLBuffer positionBuffer;
782     createQuadVertexArray(positionBuffer);
783     setupVertexArray(writePipeline, writeProgram);
784 
785     GLBuffer vertexBuffer;
786     GLTexture vertexTextureBuffer;
787     constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
788     createStorageBuffer(writeResource, vertexBuffer, vertexTextureBuffer, sizeof(kInitData),
789                         kInitData.data());
790 
791     constexpr std::array<float, 4> kWriteData = {2.0, 2.0, 2.0, 2.0};
792     setUniformData(writeProgram, kWriteData);
793 
794     // Fill the buffer
795     if (writePipeline == ShaderWritePipeline::Graphics)
796     {
797         glDrawArrays(GL_TRIANGLES, 0, 6);
798     }
799     else
800     {
801         glDispatchCompute(1, 1, 1);
802     }
803 
804     noopOp(preBarrierOp);
805 
806     // Issue the appropriate memory barrier
807     glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);
808 
809     noopOp(postBarrierOp);
810 
811     // Use the buffer
812     GLProgram readProgram;
813     createVertexVerifyProgram(vertexBuffer, &readProgram);
814 
815     glEnable(GL_BLEND);
816     glBlendFunc(GL_ONE, GL_ONE);
817     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
818     EXPECT_GL_NO_ERROR();
819 
820     // Verify the vertex data was read correctly
821     const GLColor kExpected =
822         writePipeline == ShaderWritePipeline::Graphics ? GLColor::cyan : GLColor::green;
823     EXPECT_PIXEL_COLOR_EQ(0, 0, kExpected);
824 
825     // Verify the contents of the buffer
826     verifyBufferContents(kWriteData);
827 }
828 
vertexAttribArrayBitVertexReadThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)829 void MemoryBarrierTestBase::vertexAttribArrayBitVertexReadThenBufferWrite(
830     ShaderWritePipeline writePipeline,
831     WriteResource writeResource,
832     NoopOp preBarrierOp,
833     NoopOp postBarrierOp,
834     GLbitfield barrierBit)
835 {
836     GLTexture color;
837     GLFramebuffer fbo;
838     GLProgram writeProgram;
839 
840     createFramebuffer(color, fbo, GLColor::black);
841 
842     GLBuffer vertexBuffer;
843     GLTexture vertexTextureBuffer;
844     constexpr std::array<float, 4> kInitData = {2.0, 2.0, 2.0, 2.0};
845     createStorageBuffer(writeResource, vertexBuffer, vertexTextureBuffer, sizeof(kInitData),
846                         kInitData.data());
847 
848     // Use the buffer
849     GLProgram readProgram;
850     createVertexVerifyProgram(vertexBuffer, &readProgram);
851 
852     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
853     EXPECT_GL_NO_ERROR();
854 
855     GLint attribLoc = glGetAttribLocation(readProgram, "attribIn");
856     glDisableVertexAttribArray(attribLoc);
857 
858     noopOp(preBarrierOp);
859 
860     // Issue the appropriate memory barrier
861     glMemoryBarrier(barrierBit);
862 
863     noopOp(postBarrierOp);
864 
865     // Fill the buffer
866     createProgram(writePipeline, writeResource, &writeProgram);
867 
868     GLBuffer positionBuffer;
869     createQuadVertexArray(positionBuffer);
870     setupVertexArray(writePipeline, writeProgram);
871 
872     constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
873     setUniformData(writeProgram, kWriteData);
874 
875     if (writePipeline == ShaderWritePipeline::Graphics)
876     {
877         glEnable(GL_BLEND);
878         glBlendFunc(GL_ONE, GL_ONE);
879         glDrawArrays(GL_TRIANGLES, 0, 6);
880     }
881     else
882     {
883         glDispatchCompute(1, 1, 1);
884     }
885 
886     verifyFramebufferAndBufferContents(writePipeline, kWriteData);
887 }
888 
createIndexVerifyProgram(GLuint indexBuffer,GLProgram * programOut)889 void MemoryBarrierTestBase::createIndexVerifyProgram(GLuint indexBuffer, GLProgram *programOut)
890 {
891     constexpr char kVS[] = R"(#version 310 es
892 void main()
893 {
894     // gl_VertexID    x    y
895     //      0        -1   -1
896     //      1         1   -1
897     //      2        -1    1
898     //      3         1    1
899     int bit0 = gl_VertexID & 1;
900     int bit1 = gl_VertexID >> 1;
901     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
902 })";
903 
904     constexpr char kFS[] = R"(#version 310 es
905 precision mediump float;
906 out vec4 colorOut;
907 void main()
908 {
909     colorOut = vec4(0, 1.0, 0, 1.0);
910 })";
911 
912     programOut->makeRaster(kVS, kFS);
913     ASSERT_TRUE(programOut->valid());
914     glUseProgram(*programOut);
915 
916     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
917     EXPECT_GL_NO_ERROR();
918 }
919 
elementArrayBitBufferWriteThenIndexRead(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)920 void MemoryBarrierTestBase::elementArrayBitBufferWriteThenIndexRead(
921     ShaderWritePipeline writePipeline,
922     WriteResource writeResource,
923     NoopOp preBarrierOp,
924     NoopOp postBarrierOp)
925 {
926     GLTexture color;
927     GLFramebuffer fbo;
928     GLProgram writeProgram;
929 
930     createFramebuffer(color, fbo, GLColor::black);
931     createProgram(writePipeline, writeResource, &writeProgram);
932 
933     GLBuffer positionBuffer;
934     createQuadVertexArray(positionBuffer);
935     setupVertexArray(writePipeline, writeProgram);
936 
937     GLBuffer indexBuffer;
938     GLTexture indexTextureBuffer;
939     constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
940     createStorageBuffer(writeResource, indexBuffer, indexTextureBuffer, sizeof(kInitData),
941                         kInitData.data());
942 
943     constexpr std::array<uint32_t, 4> kWriteData = {0, 1, 2, 3};
944     const std::array<float, 4> kWriteDataAsFloat = {
945         *reinterpret_cast<const float *>(&kWriteData[0]),
946         *reinterpret_cast<const float *>(&kWriteData[1]),
947         *reinterpret_cast<const float *>(&kWriteData[2]),
948         *reinterpret_cast<const float *>(&kWriteData[3]),
949     };
950     setUniformData(writeProgram, kWriteDataAsFloat);
951 
952     // Fill the buffer
953     if (writePipeline == ShaderWritePipeline::Graphics)
954     {
955         glDrawArrays(GL_TRIANGLES, 0, 6);
956     }
957     else
958     {
959         glDispatchCompute(1, 1, 1);
960     }
961 
962     noopOp(preBarrierOp);
963 
964     // Issue the appropriate memory barrier
965     glMemoryBarrier(GL_ELEMENT_ARRAY_BARRIER_BIT);
966 
967     noopOp(postBarrierOp);
968 
969     // Use the buffer
970     GLProgram readProgram;
971     createIndexVerifyProgram(indexBuffer, &readProgram);
972 
973     glEnable(GL_BLEND);
974     glBlendFunc(GL_ONE, GL_ONE);
975     glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
976     EXPECT_GL_NO_ERROR();
977 
978     verifyFramebufferAndBufferContents(writePipeline, kWriteData);
979 }
980 
elementArrayBitIndexReadThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)981 void MemoryBarrierTestBase::elementArrayBitIndexReadThenBufferWrite(
982     ShaderWritePipeline writePipeline,
983     WriteResource writeResource,
984     NoopOp preBarrierOp,
985     NoopOp postBarrierOp,
986     GLbitfield barrierBit)
987 {
988     GLTexture color;
989     GLFramebuffer fbo;
990     GLProgram writeProgram;
991 
992     createFramebuffer(color, fbo, GLColor::black);
993 
994     GLBuffer indexBuffer;
995     GLTexture indexTextureBuffer;
996     constexpr std::array<uint32_t, 4> kInitData = {0, 1, 2, 3};
997     createStorageBuffer(writeResource, indexBuffer, indexTextureBuffer, sizeof(kInitData),
998                         kInitData.data());
999 
1000     // Use the buffer
1001     GLProgram readProgram;
1002     createIndexVerifyProgram(indexBuffer, &readProgram);
1003 
1004     glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
1005     EXPECT_GL_NO_ERROR();
1006 
1007     noopOp(preBarrierOp);
1008 
1009     // Issue the appropriate memory barrier
1010     glMemoryBarrier(barrierBit);
1011 
1012     noopOp(postBarrierOp);
1013 
1014     // Fill the buffer
1015     createProgram(writePipeline, writeResource, &writeProgram);
1016 
1017     GLBuffer positionBuffer;
1018     createQuadVertexArray(positionBuffer);
1019     setupVertexArray(writePipeline, writeProgram);
1020 
1021     constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
1022     setUniformData(writeProgram, kWriteData);
1023 
1024     if (writePipeline == ShaderWritePipeline::Graphics)
1025     {
1026         glEnable(GL_BLEND);
1027         glBlendFunc(GL_ONE, GL_ONE);
1028         glDrawArrays(GL_TRIANGLES, 0, 6);
1029     }
1030     else
1031     {
1032         glDispatchCompute(1, 1, 1);
1033     }
1034 
1035     verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1036 }
1037 
createUBOVerifyProgram(GLuint buffer,GLProgram * programOut)1038 void MemoryBarrierTestBase::createUBOVerifyProgram(GLuint buffer, GLProgram *programOut)
1039 {
1040     constexpr char kVS[] = R"(#version 310 es
1041 void main()
1042 {
1043     // gl_VertexID    x    y
1044     //      0        -1   -1
1045     //      1         1   -1
1046     //      2        -1    1
1047     //      3         1    1
1048     int bit0 = gl_VertexID & 1;
1049     int bit1 = gl_VertexID >> 1;
1050     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
1051 })";
1052 
1053     constexpr char kFS[] = R"(#version 310 es
1054 precision mediump float;
1055 layout(binding = 0) uniform block {
1056     vec4 data;
1057 } ubo;
1058 out vec4 colorOut;
1059 void main()
1060 {
1061     if (ubo.data == vec4(1.5, 3.75, 5.0, 12.125))
1062         colorOut = vec4(0, 1.0, 0, 1.0);
1063     else
1064         colorOut = vec4(1.0, 0, 0, 1.0);
1065 })";
1066 
1067     programOut->makeRaster(kVS, kFS);
1068     ASSERT_TRUE(programOut->valid());
1069     glUseProgram(*programOut);
1070 
1071     glBindBuffer(GL_UNIFORM_BUFFER, buffer);
1072     glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
1073     EXPECT_GL_NO_ERROR();
1074 }
1075 
uniformBitBufferWriteThenUBORead(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)1076 void MemoryBarrierTestBase::uniformBitBufferWriteThenUBORead(ShaderWritePipeline writePipeline,
1077                                                              WriteResource writeResource,
1078                                                              NoopOp preBarrierOp,
1079                                                              NoopOp postBarrierOp)
1080 {
1081     GLTexture color;
1082     GLFramebuffer fbo;
1083     GLProgram writeProgram;
1084 
1085     createFramebuffer(color, fbo, GLColor::black);
1086     createProgram(writePipeline, writeResource, &writeProgram);
1087 
1088     GLBuffer positionBuffer;
1089     createQuadVertexArray(positionBuffer);
1090     setupVertexArray(writePipeline, writeProgram);
1091 
1092     GLBuffer uniformBuffer;
1093     GLTexture uniformTextureBuffer;
1094     constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
1095     createStorageBuffer(writeResource, uniformBuffer, uniformTextureBuffer, sizeof(kInitData),
1096                         kInitData.data());
1097 
1098     constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
1099     setUniformData(writeProgram, kWriteData);
1100 
1101     // Fill the buffer
1102     if (writePipeline == ShaderWritePipeline::Graphics)
1103     {
1104         glDrawArrays(GL_TRIANGLES, 0, 6);
1105     }
1106     else
1107     {
1108         glDispatchCompute(1, 1, 1);
1109     }
1110 
1111     noopOp(preBarrierOp);
1112 
1113     // Issue the appropriate memory barrier
1114     glMemoryBarrier(GL_UNIFORM_BARRIER_BIT);
1115 
1116     noopOp(postBarrierOp);
1117 
1118     // Use the buffer
1119     GLProgram readProgram;
1120     createUBOVerifyProgram(uniformBuffer, &readProgram);
1121 
1122     glEnable(GL_BLEND);
1123     glBlendFunc(GL_ONE, GL_ONE);
1124     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1125     EXPECT_GL_NO_ERROR();
1126 
1127     verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1128 }
1129 
uniformBitUBOReadThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)1130 void MemoryBarrierTestBase::uniformBitUBOReadThenBufferWrite(ShaderWritePipeline writePipeline,
1131                                                              WriteResource writeResource,
1132                                                              NoopOp preBarrierOp,
1133                                                              NoopOp postBarrierOp,
1134                                                              GLbitfield barrierBit)
1135 {
1136     GLTexture color;
1137     GLFramebuffer fbo;
1138     GLProgram writeProgram;
1139 
1140     createFramebuffer(color, fbo, GLColor::black);
1141 
1142     GLBuffer uniformBuffer;
1143     GLTexture uniformTextureBuffer;
1144     constexpr std::array<float, 4> kInitData = {1.5, 3.75, 5.0, 12.125};
1145     createStorageBuffer(writeResource, uniformBuffer, uniformTextureBuffer, sizeof(kInitData),
1146                         kInitData.data());
1147 
1148     // Use the buffer
1149     GLProgram readProgram;
1150     createUBOVerifyProgram(uniformBuffer, &readProgram);
1151 
1152     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1153     EXPECT_GL_NO_ERROR();
1154 
1155     noopOp(preBarrierOp);
1156 
1157     // Issue the appropriate memory barrier
1158     glMemoryBarrier(barrierBit);
1159 
1160     noopOp(postBarrierOp);
1161 
1162     // Fill the buffer
1163     createProgram(writePipeline, writeResource, &writeProgram);
1164 
1165     GLBuffer positionBuffer;
1166     createQuadVertexArray(positionBuffer);
1167     setupVertexArray(writePipeline, writeProgram);
1168 
1169     constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
1170     setUniformData(writeProgram, kWriteData);
1171 
1172     if (writePipeline == ShaderWritePipeline::Graphics)
1173     {
1174         glEnable(GL_BLEND);
1175         glBlendFunc(GL_ONE, GL_ONE);
1176         glDrawArrays(GL_TRIANGLES, 0, 6);
1177     }
1178     else
1179     {
1180         glDispatchCompute(1, 1, 1);
1181     }
1182 
1183     verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1184 }
1185 
createIndirectVerifyProgram(GLuint buffer,GLProgram * programOut)1186 void MemoryBarrierTestBase::createIndirectVerifyProgram(GLuint buffer, GLProgram *programOut)
1187 {
1188     constexpr char kVS[] = R"(#version 310 es
1189 void main()
1190 {
1191     // gl_VertexID    x    y
1192     //      0        -1   -1
1193     //      1         1   -1
1194     //      2        -1    1
1195     //      3         1    1
1196     int bit0 = gl_VertexID & 1;
1197     int bit1 = gl_VertexID >> 1;
1198     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
1199 })";
1200 
1201     constexpr char kFS[] = R"(#version 310 es
1202 precision mediump float;
1203 out vec4 colorOut;
1204 void main()
1205 {
1206     colorOut = vec4(0, 1.0, 0, 1.0);
1207 })";
1208 
1209     programOut->makeRaster(kVS, kFS);
1210     ASSERT_TRUE(programOut->valid());
1211     glUseProgram(*programOut);
1212 
1213     glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
1214     EXPECT_GL_NO_ERROR();
1215 }
1216 
commandBitBufferWriteThenIndirectRead(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)1217 void MemoryBarrierTestBase::commandBitBufferWriteThenIndirectRead(ShaderWritePipeline writePipeline,
1218                                                                   WriteResource writeResource,
1219                                                                   NoopOp preBarrierOp,
1220                                                                   NoopOp postBarrierOp)
1221 {
1222     GLTexture color;
1223     GLFramebuffer fbo;
1224     GLProgram writeProgram;
1225 
1226     createFramebuffer(color, fbo, GLColor::black);
1227     createProgram(writePipeline, writeResource, &writeProgram);
1228 
1229     GLBuffer positionBuffer;
1230     createQuadVertexArray(positionBuffer);
1231     setupVertexArray(writePipeline, writeProgram);
1232 
1233     GLBuffer indirectBuffer;
1234     GLTexture indirectTextureBuffer;
1235     constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
1236     createStorageBuffer(writeResource, indirectBuffer, indirectTextureBuffer, sizeof(kInitData),
1237                         kInitData.data());
1238 
1239     constexpr std::array<uint32_t, 4> kWriteData = {4, 1, 0, 0};
1240     const std::array<float, 4> kWriteDataAsFloat = {
1241         *reinterpret_cast<const float *>(&kWriteData[0]),
1242         *reinterpret_cast<const float *>(&kWriteData[1]),
1243         *reinterpret_cast<const float *>(&kWriteData[2]),
1244         *reinterpret_cast<const float *>(&kWriteData[3]),
1245     };
1246     setUniformData(writeProgram, kWriteDataAsFloat);
1247 
1248     // Fill the buffer
1249     if (writePipeline == ShaderWritePipeline::Graphics)
1250     {
1251         glDrawArrays(GL_TRIANGLES, 0, 6);
1252     }
1253     else
1254     {
1255         glDispatchCompute(1, 1, 1);
1256     }
1257 
1258     noopOp(preBarrierOp);
1259 
1260     // Issue the appropriate memory barrier
1261     glMemoryBarrier(GL_COMMAND_BARRIER_BIT);
1262 
1263     noopOp(postBarrierOp);
1264 
1265     // Use the buffer
1266     GLProgram readProgram;
1267     createIndirectVerifyProgram(indirectBuffer, &readProgram);
1268 
1269     GLVertexArray vao;
1270     glBindVertexArray(vao);
1271 
1272     glEnable(GL_BLEND);
1273     glBlendFunc(GL_ONE, GL_ONE);
1274     glDrawArraysIndirect(GL_TRIANGLE_STRIP, nullptr);
1275     EXPECT_GL_NO_ERROR();
1276 
1277     verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1278 }
1279 
commandBitIndirectReadThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)1280 void MemoryBarrierTestBase::commandBitIndirectReadThenBufferWrite(ShaderWritePipeline writePipeline,
1281                                                                   WriteResource writeResource,
1282                                                                   NoopOp preBarrierOp,
1283                                                                   NoopOp postBarrierOp,
1284                                                                   GLbitfield barrierBit)
1285 {
1286     GLTexture color;
1287     GLFramebuffer fbo;
1288     GLProgram writeProgram;
1289 
1290     createFramebuffer(color, fbo, GLColor::black);
1291 
1292     GLBuffer indirectBuffer;
1293     GLTexture indirectTextureBuffer;
1294     constexpr std::array<uint32_t, 4> kInitData = {4, 1, 0, 0};
1295     createStorageBuffer(writeResource, indirectBuffer, indirectTextureBuffer, sizeof(kInitData),
1296                         kInitData.data());
1297 
1298     // Use the buffer
1299     GLProgram readProgram;
1300     createIndirectVerifyProgram(indirectBuffer, &readProgram);
1301 
1302     GLVertexArray vao;
1303     glBindVertexArray(vao);
1304 
1305     glDrawArraysIndirect(GL_TRIANGLE_STRIP, nullptr);
1306     EXPECT_GL_NO_ERROR();
1307 
1308     glBindVertexArray(0);
1309 
1310     noopOp(preBarrierOp);
1311 
1312     // Issue the appropriate memory barrier
1313     glMemoryBarrier(barrierBit);
1314 
1315     noopOp(postBarrierOp);
1316 
1317     // Fill the buffer
1318     createProgram(writePipeline, writeResource, &writeProgram);
1319 
1320     GLBuffer positionBuffer;
1321     createQuadVertexArray(positionBuffer);
1322     setupVertexArray(writePipeline, writeProgram);
1323 
1324     constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
1325     setUniformData(writeProgram, kWriteData);
1326 
1327     if (writePipeline == ShaderWritePipeline::Graphics)
1328     {
1329         glEnable(GL_BLEND);
1330         glBlendFunc(GL_ONE, GL_ONE);
1331         glDrawArrays(GL_TRIANGLES, 0, 6);
1332     }
1333     else
1334     {
1335         glDispatchCompute(1, 1, 1);
1336     }
1337 
1338     verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1339 }
1340 
pixelBufferBitBufferWriteThenPack(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)1341 void MemoryBarrierTestBase::pixelBufferBitBufferWriteThenPack(ShaderWritePipeline writePipeline,
1342                                                               WriteResource writeResource,
1343                                                               NoopOp preBarrierOp,
1344                                                               NoopOp postBarrierOp)
1345 {
1346     GLTexture color;
1347     GLFramebuffer fbo;
1348     GLProgram writeProgram;
1349 
1350     createFramebuffer(color, fbo, GLColor::green);
1351     createProgram(writePipeline, writeResource, &writeProgram);
1352 
1353     GLBuffer positionBuffer;
1354     createQuadVertexArray(positionBuffer);
1355     setupVertexArray(writePipeline, writeProgram);
1356 
1357     GLBuffer packBuffer;
1358     GLTexture packTextureBuffer;
1359     constexpr std::array<float, 4> kInitData = {1.5, 3.75, 5.0, 12.125};
1360     createStorageBuffer(writeResource, packBuffer, packTextureBuffer, sizeof(kInitData),
1361                         kInitData.data());
1362 
1363     constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
1364     setUniformData(writeProgram, kWriteData);
1365 
1366     // Fill the buffer
1367     if (writePipeline == ShaderWritePipeline::Graphics)
1368     {
1369         glEnable(GL_BLEND);
1370         glBlendFunc(GL_ONE, GL_ONE);
1371         glDrawArrays(GL_TRIANGLES, 0, 6);
1372         glDisable(GL_BLEND);
1373     }
1374     else
1375     {
1376         glDispatchCompute(1, 1, 1);
1377     }
1378 
1379     noopOp(preBarrierOp);
1380 
1381     // Issue the appropriate memory barrier
1382     glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);
1383 
1384     noopOp(postBarrierOp);
1385 
1386     // Use the buffer
1387     glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
1388     glReadPixels(0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1389     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
1390 
1391     const std::array<uint32_t, 4> kExpectedData = {
1392         writePipeline == ShaderWritePipeline::Graphics ? 0xFFFFFF00u : 0xFF00FF00u,
1393         *reinterpret_cast<const uint32_t *>(&kWriteData[1]),
1394         *reinterpret_cast<const uint32_t *>(&kWriteData[2]),
1395         *reinterpret_cast<const uint32_t *>(&kWriteData[3]),
1396     };
1397     verifyFramebufferAndBufferContents(writePipeline, kExpectedData);
1398 }
1399 
pixelBufferBitBufferWriteThenUnpack(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)1400 void MemoryBarrierTestBase::pixelBufferBitBufferWriteThenUnpack(ShaderWritePipeline writePipeline,
1401                                                                 WriteResource writeResource,
1402                                                                 NoopOp preBarrierOp,
1403                                                                 NoopOp postBarrierOp)
1404 {
1405     GLTexture color;
1406     GLFramebuffer fbo;
1407     GLProgram writeProgram;
1408 
1409     createFramebuffer(color, fbo, GLColor::black);
1410     createProgram(writePipeline, writeResource, &writeProgram);
1411 
1412     GLBuffer positionBuffer;
1413     createQuadVertexArray(positionBuffer);
1414     setupVertexArray(writePipeline, writeProgram);
1415 
1416     GLBuffer unpackBuffer;
1417     GLTexture unpackTextureBuffer;
1418     constexpr std::array<float, 4> kInitData = {1.5, 3.75, 5.0, 12.125};
1419     createStorageBuffer(writeResource, unpackBuffer, unpackTextureBuffer, sizeof(kInitData),
1420                         kInitData.data());
1421 
1422     const std::array<float, 4> kWriteData = {*reinterpret_cast<const float *>(&GLColor::green), 5.6,
1423                                              78.91, 123.456};
1424     setUniformData(writeProgram, kWriteData);
1425 
1426     // Fill the buffer
1427     if (writePipeline == ShaderWritePipeline::Graphics)
1428     {
1429         glEnable(GL_BLEND);
1430         glBlendFunc(GL_ONE, GL_ONE);
1431         glDrawArrays(GL_TRIANGLES, 0, 6);
1432         glDisable(GL_BLEND);
1433     }
1434     else
1435     {
1436         glDispatchCompute(1, 1, 1);
1437     }
1438 
1439     noopOp(preBarrierOp);
1440 
1441     // Issue the appropriate memory barrier
1442     glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);
1443 
1444     noopOp(postBarrierOp);
1445 
1446     // Use the buffer
1447     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
1448     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE,
1449                     0);
1450     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
1451 
1452     // Verify the result of the unpack operation
1453     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1454 
1455     // Verify the contents of the buffer
1456     verifyBufferContents(kWriteData);
1457 }
1458 
pixelBufferBitPackThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)1459 void MemoryBarrierTestBase::pixelBufferBitPackThenBufferWrite(ShaderWritePipeline writePipeline,
1460                                                               WriteResource writeResource,
1461                                                               NoopOp preBarrierOp,
1462                                                               NoopOp postBarrierOp,
1463                                                               GLbitfield barrierBit)
1464 {
1465     GLTexture color;
1466     GLFramebuffer fbo;
1467     GLProgram writeProgram;
1468 
1469     createFramebuffer(color, fbo, GLColor::green);
1470 
1471     GLBuffer packBuffer;
1472     GLTexture packTextureBuffer;
1473     constexpr std::array<float, 4> kInitData = {1.5, 3.75, 5.0, 12.125};
1474     createStorageBuffer(writeResource, packBuffer, packTextureBuffer, sizeof(kInitData),
1475                         kInitData.data());
1476 
1477     // Use the buffer
1478     glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
1479     glReadPixels(0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1480     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
1481 
1482     noopOp(preBarrierOp);
1483 
1484     // Issue the appropriate memory barrier
1485     glMemoryBarrier(barrierBit);
1486 
1487     noopOp(postBarrierOp);
1488 
1489     // Fill the buffer
1490     createProgram(writePipeline, writeResource, &writeProgram);
1491 
1492     GLBuffer positionBuffer;
1493     createQuadVertexArray(positionBuffer);
1494     setupVertexArray(writePipeline, writeProgram);
1495 
1496     constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
1497     setUniformData(writeProgram, kWriteData);
1498 
1499     if (writePipeline == ShaderWritePipeline::Graphics)
1500     {
1501         glEnable(GL_BLEND);
1502         glBlendFunc(GL_ONE, GL_ONE);
1503         glDrawArrays(GL_TRIANGLES, 0, 6);
1504     }
1505     else
1506     {
1507         glDispatchCompute(1, 1, 1);
1508     }
1509 
1510     verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1511 }
1512 
pixelBufferBitUnpackThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)1513 void MemoryBarrierTestBase::pixelBufferBitUnpackThenBufferWrite(ShaderWritePipeline writePipeline,
1514                                                                 WriteResource writeResource,
1515                                                                 NoopOp preBarrierOp,
1516                                                                 NoopOp postBarrierOp,
1517                                                                 GLbitfield barrierBit)
1518 {
1519     GLTexture color;
1520     GLFramebuffer fbo;
1521     GLProgram writeProgram;
1522 
1523     createFramebuffer(color, fbo, GLColor::black);
1524 
1525     GLBuffer unpackBuffer;
1526     GLTexture unpackTextureBuffer;
1527     const std::array<float, 4> kInitData = {*reinterpret_cast<const float *>(&GLColor::green), 3.75,
1528                                             5.0, 12.125};
1529     createStorageBuffer(writeResource, unpackBuffer, unpackTextureBuffer, sizeof(kInitData),
1530                         kInitData.data());
1531 
1532     // Use the buffer
1533     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
1534     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE,
1535                     0);
1536     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
1537 
1538     noopOp(preBarrierOp);
1539 
1540     // Issue the appropriate memory barrier
1541     glMemoryBarrier(barrierBit);
1542 
1543     noopOp(postBarrierOp);
1544 
1545     // Fill the buffer
1546     createProgram(writePipeline, writeResource, &writeProgram);
1547 
1548     GLBuffer positionBuffer;
1549     createQuadVertexArray(positionBuffer);
1550     setupVertexArray(writePipeline, writeProgram);
1551 
1552     constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
1553     setUniformData(writeProgram, kWriteData);
1554 
1555     if (writePipeline == ShaderWritePipeline::Graphics)
1556     {
1557         glEnable(GL_BLEND);
1558         glBlendFunc(GL_ONE, GL_ONE);
1559         glDrawArrays(GL_TRIANGLES, 0, 6);
1560     }
1561     else
1562     {
1563         glDispatchCompute(1, 1, 1);
1564     }
1565 
1566     verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1567 }
1568 
bufferUpdateBitBufferWriteThenCopy(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)1569 void MemoryBarrierTestBase::bufferUpdateBitBufferWriteThenCopy(ShaderWritePipeline writePipeline,
1570                                                                WriteResource writeResource,
1571                                                                NoopOp preBarrierOp,
1572                                                                NoopOp postBarrierOp)
1573 {
1574     GLBuffer srcBuffer;
1575     GLTexture srcTextureBuffer;
1576     constexpr std::array<float, 4> kSrcInitData = {9.3, 3.7, 11.34, 0.65};
1577     createStorageBuffer(WriteResource::Buffer, srcBuffer, srcTextureBuffer, sizeof(kSrcInitData),
1578                         kSrcInitData.data());
1579 
1580     GLTexture color;
1581     GLFramebuffer fbo;
1582     GLProgram writeProgram;
1583 
1584     createFramebuffer(color, fbo, GLColor::green);
1585     createProgram(writePipeline, writeResource, &writeProgram);
1586 
1587     GLBuffer positionBuffer;
1588     createQuadVertexArray(positionBuffer);
1589     setupVertexArray(writePipeline, writeProgram);
1590 
1591     GLBuffer writeBuffer;
1592     GLTexture writeTextureBuffer;
1593     constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
1594     createStorageBuffer(writeResource, writeBuffer, writeTextureBuffer, sizeof(kInitData),
1595                         kInitData.data());
1596 
1597     constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
1598     setUniformData(writeProgram, kWriteData);
1599 
1600     // Fill the buffer
1601     if (writePipeline == ShaderWritePipeline::Graphics)
1602     {
1603         glEnable(GL_BLEND);
1604         glBlendFunc(GL_ONE, GL_ONE);
1605         glDrawArrays(GL_TRIANGLES, 0, 6);
1606         glDisable(GL_BLEND);
1607     }
1608     else
1609     {
1610         glDispatchCompute(1, 1, 1);
1611     }
1612 
1613     noopOp(preBarrierOp);
1614 
1615     // Issue the appropriate memory barrier
1616     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
1617 
1618     noopOp(postBarrierOp);
1619 
1620     // Copy from src buffer over the buffer
1621     glBindBuffer(GL_UNIFORM_BUFFER, srcBuffer);
1622     glCopyBufferSubData(GL_UNIFORM_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 0, sizeof(kInitData));
1623 
1624     verifyFramebufferAndBufferContents(writePipeline, kSrcInitData);
1625 
1626     // Verify the src buffer is unaffected
1627     glBindBuffer(GL_SHADER_STORAGE_BUFFER, srcBuffer);
1628     verifyBufferContents(kSrcInitData);
1629 }
1630 
bufferUpdateBitCopyThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)1631 void MemoryBarrierTestBase::bufferUpdateBitCopyThenBufferWrite(ShaderWritePipeline writePipeline,
1632                                                                WriteResource writeResource,
1633                                                                NoopOp preBarrierOp,
1634                                                                NoopOp postBarrierOp,
1635                                                                GLbitfield barrierBit)
1636 {
1637     GLBuffer srcBuffer;
1638     GLTexture srcTextureBuffer;
1639     constexpr std::array<float, 4> kSrcInitData = {9.3, 3.7, 11.34, 0.65};
1640     createStorageBuffer(WriteResource::Buffer, srcBuffer, srcTextureBuffer, sizeof(kSrcInitData),
1641                         kSrcInitData.data());
1642 
1643     GLTexture color;
1644     GLFramebuffer fbo;
1645     GLProgram writeProgram;
1646 
1647     createFramebuffer(color, fbo, GLColor::green);
1648 
1649     GLBuffer writeBuffer;
1650     GLTexture writeTextureBuffer;
1651     constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
1652     createStorageBuffer(writeResource, writeBuffer, writeTextureBuffer, sizeof(kInitData),
1653                         kInitData.data());
1654 
1655     // Copy from src buffer over the buffer
1656     glBindBuffer(GL_UNIFORM_BUFFER, srcBuffer);
1657     glCopyBufferSubData(GL_UNIFORM_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 0, sizeof(kInitData));
1658 
1659     noopOp(preBarrierOp);
1660 
1661     // Issue the appropriate memory barrier
1662     glMemoryBarrier(barrierBit);
1663 
1664     noopOp(postBarrierOp);
1665 
1666     // Fill the buffer
1667     createProgram(writePipeline, writeResource, &writeProgram);
1668 
1669     GLBuffer positionBuffer;
1670     createQuadVertexArray(positionBuffer);
1671     setupVertexArray(writePipeline, writeProgram);
1672 
1673     constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
1674     setUniformData(writeProgram, kWriteData);
1675 
1676     if (writePipeline == ShaderWritePipeline::Graphics)
1677     {
1678         glEnable(GL_BLEND);
1679         glBlendFunc(GL_ONE, GL_ONE);
1680         glDrawArrays(GL_TRIANGLES, 0, 6);
1681     }
1682     else
1683     {
1684         glDispatchCompute(1, 1, 1);
1685     }
1686 
1687     verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1688 
1689     // Verify the src buffer is unaffected
1690     glBindBuffer(GL_SHADER_STORAGE_BUFFER, srcBuffer);
1691     verifyBufferContents(kSrcInitData);
1692 }
1693 
createXfbVerifyProgram(GLuint buffer,GLProgram * programOut)1694 void MemoryBarrierTestBase::createXfbVerifyProgram(GLuint buffer, GLProgram *programOut)
1695 {
1696     constexpr char kVS[] = R"(#version 310 es
1697 void main()
1698 {
1699     // gl_VertexID    x    y
1700     //   0 (000)     -1   -1
1701     //   1 (001)      1   -1
1702     //   2 (010)     -1    1
1703     //   3 (011)      1    1
1704     //   4 (100)     -1    1
1705     //   5 (101)      1   -1
1706     int bit0 = gl_VertexID & 1;
1707     int bit1 = gl_VertexID < 4 ? gl_VertexID >> 1 & 1 : ~bit0 & 1;
1708     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
1709 })";
1710 
1711     constexpr char kFS[] = R"(#version 310 es
1712 precision mediump float;
1713 out vec4 colorOut;
1714 void main()
1715 {
1716     colorOut = vec4(0, 1.0, 0, 1.0);
1717 })";
1718 
1719     const std::vector<std::string> &tfVaryings = {"gl_Position"};
1720 
1721     programOut->makeRasterWithTransformFeedback(kVS, kFS, tfVaryings, GL_INTERLEAVED_ATTRIBS);
1722     ASSERT_TRUE(programOut->valid());
1723     glUseProgram(*programOut);
1724 
1725     glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffer);
1726     EXPECT_GL_NO_ERROR();
1727 }
1728 
transformFeedbackBitBufferWriteThenCapture(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)1729 void MemoryBarrierTestBase::transformFeedbackBitBufferWriteThenCapture(
1730     ShaderWritePipeline writePipeline,
1731     WriteResource writeResource,
1732     NoopOp preBarrierOp,
1733     NoopOp postBarrierOp)
1734 {
1735     GLTexture color;
1736     GLFramebuffer fbo;
1737     GLProgram writeProgram;
1738 
1739     createFramebuffer(color, fbo, GLColor::black);
1740     createProgram(writePipeline, writeResource, &writeProgram);
1741 
1742     GLBuffer positionBuffer;
1743     createQuadVertexArray(positionBuffer);
1744     setupVertexArray(writePipeline, writeProgram);
1745 
1746     GLBuffer xfbBuffer;
1747     GLTexture xfbTextureBuffer;
1748     constexpr size_t kOneInstanceDataSize                                        = 4;
1749     constexpr size_t kInstanceCount                                              = 6;
1750     constexpr std::array<float, kOneInstanceDataSize * kInstanceCount> kInitData = {12.34, 5.6,
1751                                                                                     78.91, 123.456};
1752     createStorageBuffer(writeResource, xfbBuffer, xfbTextureBuffer,
1753                         sizeof(kInitData[0]) * kInitData.size(), kInitData.data());
1754 
1755     constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
1756     setUniformData(writeProgram, kWriteData);
1757 
1758     // Fill the buffer
1759     if (writePipeline == ShaderWritePipeline::Graphics)
1760     {
1761         glDrawArrays(GL_TRIANGLES, 0, 6);
1762     }
1763     else
1764     {
1765         glDispatchCompute(1, 1, 1);
1766     }
1767 
1768     noopOp(preBarrierOp);
1769 
1770     // Issue the appropriate memory barrier
1771     glMemoryBarrier(GL_TRANSFORM_FEEDBACK_BARRIER_BIT);
1772 
1773     noopOp(postBarrierOp);
1774 
1775     // Use the buffer
1776     GLProgram xfbProgram;
1777     createXfbVerifyProgram(xfbBuffer, &xfbProgram);
1778 
1779     glBeginTransformFeedback(GL_TRIANGLES);
1780     glEnable(GL_BLEND);
1781     glBlendFunc(GL_ONE, GL_ONE);
1782     glDrawArrays(GL_TRIANGLES, 0, 6);
1783     glEndTransformFeedback();
1784     EXPECT_GL_NO_ERROR();
1785 
1786     const std::array<float, 4> kExpectedData = {-1.0, -1.0, 0.0, 1.0};
1787     verifyFramebufferAndBufferContents(writePipeline, kExpectedData);
1788 }
1789 
transformFeedbackBitCaptureThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)1790 void MemoryBarrierTestBase::transformFeedbackBitCaptureThenBufferWrite(
1791     ShaderWritePipeline writePipeline,
1792     WriteResource writeResource,
1793     NoopOp preBarrierOp,
1794     NoopOp postBarrierOp,
1795     GLbitfield barrierBit)
1796 {
1797     GLTexture color;
1798     GLFramebuffer fbo;
1799     GLProgram writeProgram;
1800 
1801     createFramebuffer(color, fbo, GLColor::black);
1802 
1803     GLBuffer xfbBuffer;
1804     GLTexture xfbTextureBuffer;
1805     constexpr size_t kOneInstanceDataSize                                        = 4;
1806     constexpr size_t kInstanceCount                                              = 6;
1807     constexpr std::array<float, kOneInstanceDataSize * kInstanceCount> kInitData = {12.34, 5.6,
1808                                                                                     78.91, 123.456};
1809     createStorageBuffer(writeResource, xfbBuffer, xfbTextureBuffer,
1810                         sizeof(kInitData[0]) * kInitData.size(), kInitData.data());
1811 
1812     // Use the buffer
1813     GLProgram xfbProgram;
1814     createXfbVerifyProgram(xfbBuffer, &xfbProgram);
1815 
1816     glBeginTransformFeedback(GL_TRIANGLES);
1817     glDrawArrays(GL_TRIANGLES, 0, 6);
1818     glEndTransformFeedback();
1819     EXPECT_GL_NO_ERROR();
1820 
1821     noopOp(preBarrierOp);
1822 
1823     // Issue the appropriate memory barrier
1824     glMemoryBarrier(barrierBit);
1825 
1826     noopOp(postBarrierOp);
1827 
1828     // Fill the buffer
1829     createProgram(writePipeline, writeResource, &writeProgram);
1830 
1831     GLBuffer positionBuffer;
1832     createQuadVertexArray(positionBuffer);
1833     setupVertexArray(writePipeline, writeProgram);
1834 
1835     constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
1836     setUniformData(writeProgram, kWriteData);
1837 
1838     if (writePipeline == ShaderWritePipeline::Graphics)
1839     {
1840         glEnable(GL_BLEND);
1841         glBlendFunc(GL_ONE, GL_ONE);
1842         glDrawArrays(GL_TRIANGLES, 0, 6);
1843     }
1844     else
1845     {
1846         glDispatchCompute(1, 1, 1);
1847     }
1848 
1849     verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1850 }
1851 
createAtomicCounterVerifyProgram(GLuint buffer,GLProgram * programOut)1852 void MemoryBarrierTestBase::createAtomicCounterVerifyProgram(GLuint buffer, GLProgram *programOut)
1853 {
1854     constexpr char kVS[] = R"(#version 310 es
1855 void main()
1856 {
1857     // gl_VertexID    x    y
1858     //      0        -1   -1
1859     //      1         1   -1
1860     //      2        -1    1
1861     //      3         1    1
1862     int bit0 = gl_VertexID & 1;
1863     int bit1 = gl_VertexID >> 1;
1864     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
1865 })";
1866 
1867     constexpr char kFS[] = R"(#version 310 es
1868 precision mediump float;
1869 layout(binding = 0, offset = 0) uniform atomic_uint ac[4];
1870 out vec4 colorOut;
1871 void main()
1872 {
1873     uvec4 acValue = uvec4(atomicCounterIncrement(ac[0]),
1874                           atomicCounterIncrement(ac[1]),
1875                           atomicCounterIncrement(ac[2]),
1876                           atomicCounterIncrement(ac[3]));
1877 
1878     if (all(equal(acValue, uvec4(10, 20, 30, 40))))
1879         colorOut = vec4(0, 1.0, 0, 1.0);
1880     else
1881         colorOut = vec4(1.0, 0, 0, 1.0);
1882 })";
1883 
1884     programOut->makeRaster(kVS, kFS);
1885     ASSERT_TRUE(programOut->valid());
1886     glUseProgram(*programOut);
1887 
1888     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, buffer);
1889     glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, buffer);
1890     EXPECT_GL_NO_ERROR();
1891 }
1892 
atomicCounterBitBufferWriteThenAtomic(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)1893 void MemoryBarrierTestBase::atomicCounterBitBufferWriteThenAtomic(ShaderWritePipeline writePipeline,
1894                                                                   WriteResource writeResource,
1895                                                                   NoopOp preBarrierOp,
1896                                                                   NoopOp postBarrierOp)
1897 {
1898     GLTexture color;
1899     GLFramebuffer fbo;
1900     GLProgram writeProgram;
1901 
1902     createFramebuffer(color, fbo, GLColor::black);
1903     createProgram(writePipeline, writeResource, &writeProgram);
1904 
1905     GLBuffer positionBuffer;
1906     createQuadVertexArray(positionBuffer);
1907     setupVertexArray(writePipeline, writeProgram);
1908 
1909     GLBuffer atomicCounterBuffer;
1910     GLTexture atomicCounterTextureBuffer;
1911     constexpr std::array<uint32_t, 4> kInitData = {0x12345678u, 0x9ABCDEF0u, 0x13579BDFu,
1912                                                    0x2468ACE0u};
1913     createStorageBuffer(writeResource, atomicCounterBuffer, atomicCounterTextureBuffer,
1914                         sizeof(kInitData), kInitData.data());
1915 
1916     constexpr std::array<uint32_t, 4> kWriteData = {10, 20, 30, 40};
1917     const std::array<float, 4> kWriteDataAsFloat = {
1918         *reinterpret_cast<const float *>(&kWriteData[0]),
1919         *reinterpret_cast<const float *>(&kWriteData[1]),
1920         *reinterpret_cast<const float *>(&kWriteData[2]),
1921         *reinterpret_cast<const float *>(&kWriteData[3]),
1922     };
1923     setUniformData(writeProgram, kWriteDataAsFloat);
1924 
1925     // Fill the buffer
1926     if (writePipeline == ShaderWritePipeline::Graphics)
1927     {
1928         glDrawArrays(GL_TRIANGLES, 0, 6);
1929     }
1930     else
1931     {
1932         glDispatchCompute(1, 1, 1);
1933     }
1934 
1935     noopOp(preBarrierOp);
1936 
1937     // Issue the appropriate memory barrier
1938     glMemoryBarrier(GL_ATOMIC_COUNTER_BARRIER_BIT);
1939 
1940     noopOp(postBarrierOp);
1941 
1942     // Use the buffer
1943     GLProgram readProgram;
1944     createAtomicCounterVerifyProgram(atomicCounterBuffer, &readProgram);
1945 
1946     glEnable(GL_BLEND);
1947     glBlendFunc(GL_ONE, GL_ONE);
1948     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1949     EXPECT_GL_NO_ERROR();
1950 
1951     constexpr std::array<uint32_t, 4> kExpectedData = {11, 21, 31, 41};
1952     verifyFramebufferAndBufferContents(writePipeline, kExpectedData);
1953 }
1954 
atomicCounterBitAtomicThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)1955 void MemoryBarrierTestBase::atomicCounterBitAtomicThenBufferWrite(ShaderWritePipeline writePipeline,
1956                                                                   WriteResource writeResource,
1957                                                                   NoopOp preBarrierOp,
1958                                                                   NoopOp postBarrierOp,
1959                                                                   GLbitfield barrierBit)
1960 {
1961     GLTexture color;
1962     GLFramebuffer fbo;
1963     GLProgram writeProgram;
1964 
1965     createFramebuffer(color, fbo, GLColor::black);
1966 
1967     GLBuffer atomicCounterBuffer;
1968     GLTexture atomicCounterTextureBuffer;
1969     constexpr std::array<uint32_t, 4> kInitData = {10, 20, 30, 40};
1970     createStorageBuffer(writeResource, atomicCounterBuffer, atomicCounterTextureBuffer,
1971                         sizeof(kInitData), kInitData.data());
1972 
1973     // Use the buffer
1974     GLProgram readProgram;
1975     createAtomicCounterVerifyProgram(atomicCounterBuffer, &readProgram);
1976 
1977     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1978     EXPECT_GL_NO_ERROR();
1979 
1980     noopOp(preBarrierOp);
1981 
1982     // Issue the appropriate memory barrier
1983     glMemoryBarrier(barrierBit);
1984 
1985     noopOp(postBarrierOp);
1986 
1987     // Fill the buffer
1988     createProgram(writePipeline, writeResource, &writeProgram);
1989 
1990     GLBuffer positionBuffer;
1991     createQuadVertexArray(positionBuffer);
1992     setupVertexArray(writePipeline, writeProgram);
1993 
1994     constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
1995     setUniformData(writeProgram, kWriteData);
1996 
1997     if (writePipeline == ShaderWritePipeline::Graphics)
1998     {
1999         glEnable(GL_BLEND);
2000         glBlendFunc(GL_ONE, GL_ONE);
2001         glDrawArrays(GL_TRIANGLES, 0, 6);
2002     }
2003     else
2004     {
2005         glDispatchCompute(1, 1, 1);
2006     }
2007 
2008     verifyFramebufferAndBufferContents(writePipeline, kWriteData);
2009 }
2010 
createSsboVerifyProgram(WriteResource writeResource,GLProgram * programOut)2011 void MemoryBarrierTestBase::createSsboVerifyProgram(WriteResource writeResource,
2012                                                     GLProgram *programOut)
2013 {
2014     constexpr char kVS[] = R"(#version 310 es
2015 void main()
2016 {
2017     // gl_VertexID    x    y
2018     //      0        -1   -1
2019     //      1         1   -1
2020     //      2        -1    1
2021     //      3         1    1
2022     int bit0 = gl_VertexID & 1;
2023     int bit1 = gl_VertexID >> 1;
2024     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
2025 })";
2026 
2027     constexpr char kFS[] = R"(#version 310 es
2028 precision mediump float;
2029 layout(std430, binding = 0) buffer block {
2030     vec4 data;
2031 } inBlock;
2032 out vec4 colorOut;
2033 void main()
2034 {
2035     if (all(lessThan(abs(inBlock.data - vec4(1.5, 3.75, 5.0, 12.125)), vec4(0.01))))
2036         colorOut = vec4(0, 1.0, 0, 1.0);
2037     else
2038         colorOut = vec4(1.0, 0, 0, 1.0);
2039 })";
2040 
2041     programOut->makeRaster(kVS, kFS);
2042     ASSERT_TRUE(programOut->valid());
2043     glUseProgram(*programOut);
2044 }
2045 
shaderStorageBitBufferWriteThenBufferRead(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2046 void MemoryBarrierTestBase::shaderStorageBitBufferWriteThenBufferRead(
2047     ShaderWritePipeline writePipeline,
2048     WriteResource writeResource,
2049     NoopOp preBarrierOp,
2050     NoopOp postBarrierOp)
2051 {
2052     GLTexture color;
2053     GLFramebuffer fbo;
2054     GLProgram writeProgram;
2055 
2056     createFramebuffer(color, fbo, GLColor::black);
2057     createProgram(writePipeline, writeResource, &writeProgram);
2058 
2059     GLBuffer positionBuffer;
2060     createQuadVertexArray(positionBuffer);
2061     setupVertexArray(writePipeline, writeProgram);
2062 
2063     GLBuffer writeBuffer;
2064     GLTexture writeTextureBuffer;
2065     constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
2066     createStorageBuffer(writeResource, writeBuffer, writeTextureBuffer, sizeof(kInitData),
2067                         kInitData.data());
2068 
2069     constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
2070     setUniformData(writeProgram, kWriteData);
2071 
2072     // Fill the buffer
2073     if (writePipeline == ShaderWritePipeline::Graphics)
2074     {
2075         glDrawArrays(GL_TRIANGLES, 0, 6);
2076     }
2077     else
2078     {
2079         glDispatchCompute(1, 1, 1);
2080     }
2081 
2082     noopOp(preBarrierOp);
2083 
2084     // Issue the appropriate memory barrier
2085     glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
2086 
2087     noopOp(postBarrierOp);
2088 
2089     // Use the buffer
2090     GLProgram readProgram;
2091     createSsboVerifyProgram(writeResource, &readProgram);
2092 
2093     glEnable(GL_BLEND);
2094     glBlendFunc(GL_ONE, GL_ONE);
2095     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2096     EXPECT_GL_NO_ERROR();
2097 
2098     verifyFramebufferAndBufferContents(writePipeline, kWriteData);
2099 }
2100 
shaderStorageBitBufferReadThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)2101 void MemoryBarrierTestBase::shaderStorageBitBufferReadThenBufferWrite(
2102     ShaderWritePipeline writePipeline,
2103     WriteResource writeResource,
2104     NoopOp preBarrierOp,
2105     NoopOp postBarrierOp,
2106     GLbitfield barrierBit)
2107 {
2108     GLTexture color;
2109     GLFramebuffer fbo;
2110     GLProgram writeProgram;
2111 
2112     createFramebuffer(color, fbo, GLColor::black);
2113 
2114     GLBuffer writeBuffer;
2115     GLTexture writeTextureBuffer;
2116     constexpr std::array<float, 4> kInitData = {1.5, 3.75, 5.0, 12.125};
2117     createStorageBuffer(writeResource, writeBuffer, writeTextureBuffer, sizeof(kInitData),
2118                         kInitData.data());
2119 
2120     // Use the buffer
2121     GLProgram readProgram;
2122     createSsboVerifyProgram(writeResource, &readProgram);
2123 
2124     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2125     EXPECT_GL_NO_ERROR();
2126 
2127     noopOp(preBarrierOp);
2128 
2129     // Issue the appropriate memory barrier
2130     glMemoryBarrier(barrierBit);
2131 
2132     noopOp(postBarrierOp);
2133 
2134     // Fill the image
2135     createProgram(writePipeline, writeResource, &writeProgram);
2136 
2137     GLBuffer positionBuffer;
2138     createQuadVertexArray(positionBuffer);
2139     setupVertexArray(writePipeline, writeProgram);
2140 
2141     constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
2142     setUniformData(writeProgram, kWriteData);
2143 
2144     if (writePipeline == ShaderWritePipeline::Graphics)
2145     {
2146         glEnable(GL_BLEND);
2147         glBlendFunc(GL_ONE, GL_ONE);
2148         glDrawArrays(GL_TRIANGLES, 0, 6);
2149     }
2150     else
2151     {
2152         glDispatchCompute(1, 1, 1);
2153     }
2154 
2155     verifyFramebufferAndBufferContents(writePipeline, kWriteData);
2156 }
2157 
createTextureVerifyProgram(WriteResource writeResource,GLuint texture,GLProgram * programOut)2158 void MemoryBarrierTestBase::createTextureVerifyProgram(WriteResource writeResource,
2159                                                        GLuint texture,
2160                                                        GLProgram *programOut)
2161 {
2162     constexpr char kVS[] = R"(#version 310 es
2163 void main()
2164 {
2165     // gl_VertexID    x    y
2166     //      0        -1   -1
2167     //      1         1   -1
2168     //      2        -1    1
2169     //      3         1    1
2170     int bit0 = gl_VertexID & 1;
2171     int bit1 = gl_VertexID >> 1;
2172     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
2173 })";
2174 
2175     constexpr char kImageFS[] = R"(#version 310 es
2176 precision mediump float;
2177 uniform sampler2D s;
2178 out vec4 colorOut;
2179 void main()
2180 {
2181     if (all(lessThan(abs(texelFetch(s, ivec2(0, 0), 0)- vec4(0.125, 0.25, 0.5, 0.75)), vec4(0.01))))
2182         colorOut = vec4(0, 1.0, 0, 1.0);
2183     else
2184         colorOut = vec4(1.0, 0, 0, 1.0);
2185 })";
2186 
2187     constexpr char kImageBufferFS[] = R"(#version 310 es
2188 #extension GL_OES_texture_buffer : require
2189 precision mediump float;
2190 uniform highp samplerBuffer s;
2191 out vec4 colorOut;
2192 void main()
2193 {
2194     if (texelFetch(s, 0) == vec4(0.125, 0.25, 0.5, 0.75))
2195         colorOut = vec4(0, 1.0, 0, 1.0);
2196     else
2197         colorOut = vec4(1.0, 0, 0, 1.0);
2198 })";
2199 
2200     programOut->makeRaster(kVS,
2201                            writeResource == WriteResource::ImageBuffer ? kImageBufferFS : kImageFS);
2202     ASSERT_TRUE(programOut->valid());
2203     glUseProgram(*programOut);
2204 
2205     glBindTexture(writeResource == WriteResource::ImageBuffer ? GL_TEXTURE_BUFFER : GL_TEXTURE_2D,
2206                   texture);
2207     EXPECT_GL_NO_ERROR();
2208 }
2209 
textureFetchBitImageWriteThenSamplerRead(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2210 void MemoryBarrierTestBase::textureFetchBitImageWriteThenSamplerRead(
2211     ShaderWritePipeline writePipeline,
2212     WriteResource writeResource,
2213     NoopOp preBarrierOp,
2214     NoopOp postBarrierOp)
2215 {
2216     GLTexture color;
2217     GLFramebuffer fbo;
2218     GLProgram writeProgram;
2219 
2220     createFramebuffer(color, fbo, GLColor::black);
2221     createProgram(writePipeline, writeResource, &writeProgram);
2222 
2223     GLBuffer positionBuffer;
2224     createQuadVertexArray(positionBuffer);
2225     setupVertexArray(writePipeline, writeProgram);
2226 
2227     GLBuffer textureBufferStorage;
2228     GLTexture texture;
2229     constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2230     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2231 
2232     constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2233     setUniformData(writeProgram, kWriteData);
2234 
2235     // Fill the image
2236     if (writePipeline == ShaderWritePipeline::Graphics)
2237     {
2238         glDrawArrays(GL_TRIANGLES, 0, 6);
2239     }
2240     else
2241     {
2242         glDispatchCompute(1, 1, 1);
2243     }
2244 
2245     noopOp(preBarrierOp);
2246 
2247     // Issue the appropriate memory barrier
2248     glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
2249 
2250     noopOp(postBarrierOp);
2251 
2252     // Use the image
2253     GLProgram readProgram;
2254     createTextureVerifyProgram(writeResource, texture, &readProgram);
2255 
2256     glEnable(GL_BLEND);
2257     glBlendFunc(GL_ONE, GL_ONE);
2258     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2259     EXPECT_GL_NO_ERROR();
2260 
2261     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2262 }
2263 
textureFetchBitSamplerReadThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)2264 void MemoryBarrierTestBase::textureFetchBitSamplerReadThenImageWrite(
2265     ShaderWritePipeline writePipeline,
2266     WriteResource writeResource,
2267     NoopOp preBarrierOp,
2268     NoopOp postBarrierOp,
2269     GLbitfield barrierBit)
2270 {
2271     GLTexture color;
2272     GLFramebuffer fbo;
2273     GLProgram writeProgram;
2274 
2275     createFramebuffer(color, fbo, GLColor::black);
2276 
2277     GLBuffer textureBufferStorage;
2278     GLTexture texture;
2279     constexpr std::array<float, 4> kInitData = {0.125, 0.25, 0.5, 0.75};
2280     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2281 
2282     // Use the image
2283     GLProgram readProgram;
2284     createTextureVerifyProgram(writeResource, texture, &readProgram);
2285 
2286     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2287     EXPECT_GL_NO_ERROR();
2288 
2289     noopOp(preBarrierOp);
2290 
2291     // Issue the appropriate memory barrier
2292     glMemoryBarrier(barrierBit);
2293 
2294     noopOp(postBarrierOp);
2295 
2296     // Fill the image
2297     createProgram(writePipeline, writeResource, &writeProgram);
2298 
2299     GLBuffer positionBuffer;
2300     createQuadVertexArray(positionBuffer);
2301     setupVertexArray(writePipeline, writeProgram);
2302 
2303     constexpr std::array<float, 4> kWriteData = {0.65, 0.20, 0.40, 0.95};
2304     setUniformData(writeProgram, kWriteData);
2305 
2306     if (writePipeline == ShaderWritePipeline::Graphics)
2307     {
2308         glEnable(GL_BLEND);
2309         glBlendFunc(GL_ONE, GL_ONE);
2310         glDrawArrays(GL_TRIANGLES, 0, 6);
2311     }
2312     else
2313     {
2314         glDispatchCompute(1, 1, 1);
2315     }
2316 
2317     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2318 }
2319 
createImageVerifyProgram(WriteResource writeResource,GLuint texture,GLProgram * programOut)2320 void MemoryBarrierTestBase::createImageVerifyProgram(WriteResource writeResource,
2321                                                      GLuint texture,
2322                                                      GLProgram *programOut)
2323 {
2324     constexpr char kVS[] = R"(#version 310 es
2325 void main()
2326 {
2327     // gl_VertexID    x    y
2328     //      0        -1   -1
2329     //      1         1   -1
2330     //      2        -1    1
2331     //      3         1    1
2332     int bit0 = gl_VertexID & 1;
2333     int bit1 = gl_VertexID >> 1;
2334     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
2335 })";
2336 
2337     constexpr char kImageFS[] = R"(#version 310 es
2338 precision mediump float;
2339 layout(rgba8, binding = 0) uniform highp readonly image2D img;
2340 out vec4 colorOut;
2341 void main()
2342 {
2343     if (all(lessThan(abs(imageLoad(img, ivec2(0, 0))- vec4(0.125, 0.25, 0.5, 0.75)), vec4(0.01))))
2344         colorOut = vec4(0, 1.0, 0, 1.0);
2345     else
2346         colorOut = vec4(1.0, 0, 0, 1.0);
2347 })";
2348 
2349     constexpr char kImageBufferFS[] = R"(#version 310 es
2350 #extension GL_OES_texture_buffer : require
2351 precision mediump float;
2352 layout(rgba32f, binding = 0) uniform highp readonly imageBuffer img;
2353 out vec4 colorOut;
2354 void main()
2355 {
2356     if (imageLoad(img, 0) == vec4(0.125, 0.25, 0.5, 0.75))
2357         colorOut = vec4(0, 1.0, 0, 1.0);
2358     else
2359         colorOut = vec4(1.0, 0, 0, 1.0);
2360 })";
2361 
2362     programOut->makeRaster(kVS,
2363                            writeResource == WriteResource::ImageBuffer ? kImageBufferFS : kImageFS);
2364     ASSERT_TRUE(programOut->valid());
2365     glUseProgram(*programOut);
2366 
2367     if (writeResource == WriteResource::ImageBuffer)
2368     {
2369         glBindTexture(GL_TEXTURE_BUFFER, texture);
2370         glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
2371     }
2372     else
2373     {
2374         glBindTexture(GL_TEXTURE_2D, texture);
2375         glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
2376     }
2377     EXPECT_GL_NO_ERROR();
2378 }
2379 
shaderImageAccessBitImageWriteThenImageRead(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2380 void MemoryBarrierTestBase::shaderImageAccessBitImageWriteThenImageRead(
2381     ShaderWritePipeline writePipeline,
2382     WriteResource writeResource,
2383     NoopOp preBarrierOp,
2384     NoopOp postBarrierOp)
2385 {
2386     GLTexture color;
2387     GLFramebuffer fbo;
2388     GLProgram writeProgram;
2389 
2390     createFramebuffer(color, fbo, GLColor::black);
2391     createProgram(writePipeline, writeResource, &writeProgram);
2392 
2393     GLBuffer positionBuffer;
2394     createQuadVertexArray(positionBuffer);
2395     setupVertexArray(writePipeline, writeProgram);
2396 
2397     GLBuffer textureBufferStorage;
2398     GLTexture texture;
2399     constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2400     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2401 
2402     constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2403     setUniformData(writeProgram, kWriteData);
2404 
2405     // Fill the image
2406     if (writePipeline == ShaderWritePipeline::Graphics)
2407     {
2408         glDrawArrays(GL_TRIANGLES, 0, 6);
2409     }
2410     else
2411     {
2412         glDispatchCompute(1, 1, 1);
2413     }
2414 
2415     noopOp(preBarrierOp);
2416 
2417     // Issue the appropriate memory barrier
2418     glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
2419 
2420     noopOp(postBarrierOp);
2421 
2422     // Use the image
2423     GLProgram readProgram;
2424     createImageVerifyProgram(writeResource, texture, &readProgram);
2425 
2426     glEnable(GL_BLEND);
2427     glBlendFunc(GL_ONE, GL_ONE);
2428     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2429     EXPECT_GL_NO_ERROR();
2430 
2431     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2432 }
2433 
shaderImageAccessBitImageReadThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2434 void MemoryBarrierTestBase::shaderImageAccessBitImageReadThenImageWrite(
2435     ShaderWritePipeline writePipeline,
2436     WriteResource writeResource,
2437     NoopOp preBarrierOp,
2438     NoopOp postBarrierOp)
2439 {
2440     GLTexture color;
2441     GLFramebuffer fbo;
2442     GLProgram writeProgram;
2443 
2444     createFramebuffer(color, fbo, GLColor::black);
2445 
2446     GLBuffer textureBufferStorage;
2447     GLTexture texture;
2448     constexpr std::array<float, 4> kInitData = {0.125, 0.25, 0.5, 0.75};
2449     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2450 
2451     // Use the image
2452     GLProgram readProgram;
2453     createImageVerifyProgram(writeResource, texture, &readProgram);
2454 
2455     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2456     EXPECT_GL_NO_ERROR();
2457 
2458     noopOp(preBarrierOp);
2459 
2460     // Issue the appropriate memory barrier
2461     glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
2462 
2463     noopOp(postBarrierOp);
2464 
2465     // Fill the image
2466     createProgram(writePipeline, writeResource, &writeProgram);
2467 
2468     GLBuffer positionBuffer;
2469     createQuadVertexArray(positionBuffer);
2470     setupVertexArray(writePipeline, writeProgram);
2471 
2472     constexpr std::array<float, 4> kWriteData = {0.65, 0.20, 0.40, 0.95};
2473     setUniformData(writeProgram, kWriteData);
2474 
2475     if (writePipeline == ShaderWritePipeline::Graphics)
2476     {
2477         glEnable(GL_BLEND);
2478         glBlendFunc(GL_ONE, GL_ONE);
2479         glDrawArrays(GL_TRIANGLES, 0, 6);
2480     }
2481     else
2482     {
2483         glDispatchCompute(1, 1, 1);
2484     }
2485 
2486     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2487 }
2488 
textureUpdateBitImageWriteThenCopy(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2489 void MemoryBarrierTestBase::textureUpdateBitImageWriteThenCopy(ShaderWritePipeline writePipeline,
2490                                                                WriteResource writeResource,
2491                                                                NoopOp preBarrierOp,
2492                                                                NoopOp postBarrierOp)
2493 {
2494     GLTexture color;
2495     GLFramebuffer fbo;
2496     GLProgram writeProgram;
2497 
2498     createFramebuffer(color, fbo, GLColor::green);
2499     createProgram(writePipeline, writeResource, &writeProgram);
2500 
2501     GLBuffer positionBuffer;
2502     createQuadVertexArray(positionBuffer);
2503     setupVertexArray(writePipeline, writeProgram);
2504 
2505     GLBuffer textureBufferStorage;
2506     GLTexture texture;
2507     constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2508     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2509 
2510     constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2511     setUniformData(writeProgram, kWriteData);
2512 
2513     // Fill the image
2514     if (writePipeline == ShaderWritePipeline::Graphics)
2515     {
2516         glEnable(GL_BLEND);
2517         glBlendFunc(GL_ONE, GL_ONE);
2518         glDrawArrays(GL_TRIANGLES, 0, 6);
2519         glDisable(GL_BLEND);
2520     }
2521     else
2522     {
2523         glDispatchCompute(1, 1, 1);
2524     }
2525 
2526     noopOp(preBarrierOp);
2527 
2528     // Issue the appropriate memory barrier
2529     glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
2530 
2531     noopOp(postBarrierOp);
2532 
2533     // Copy from framebuffer over the texture
2534     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kTextureSize, kTextureSize);
2535 
2536     const std::array<float, 4> kExpectedData = {
2537         0, 1.0f, writePipeline == ShaderWritePipeline::Graphics ? 1.0f : 0, 1.0f};
2538     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kExpectedData);
2539 }
2540 
textureUpdateBitCopyThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)2541 void MemoryBarrierTestBase::textureUpdateBitCopyThenImageWrite(ShaderWritePipeline writePipeline,
2542                                                                WriteResource writeResource,
2543                                                                NoopOp preBarrierOp,
2544                                                                NoopOp postBarrierOp,
2545                                                                GLbitfield barrierBit)
2546 {
2547     GLTexture color;
2548     GLFramebuffer fbo;
2549     GLProgram writeProgram;
2550 
2551     createFramebuffer(color, fbo, GLColor::green);
2552 
2553     GLBuffer textureBufferStorage;
2554     GLTexture texture;
2555     constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2556     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2557 
2558     // Copy from framebuffer over the texture
2559     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kTextureSize, kTextureSize);
2560 
2561     noopOp(preBarrierOp);
2562 
2563     // Issue the appropriate memory barrier
2564     glMemoryBarrier(barrierBit);
2565 
2566     noopOp(postBarrierOp);
2567 
2568     // Fill the image
2569     createProgram(writePipeline, writeResource, &writeProgram);
2570 
2571     GLBuffer positionBuffer;
2572     createQuadVertexArray(positionBuffer);
2573     setupVertexArray(writePipeline, writeProgram);
2574 
2575     constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2576     setUniformData(writeProgram, kWriteData);
2577 
2578     if (writePipeline == ShaderWritePipeline::Graphics)
2579     {
2580         glEnable(GL_BLEND);
2581         glBlendFunc(GL_ONE, GL_ONE);
2582         glDrawArrays(GL_TRIANGLES, 0, 6);
2583     }
2584     else
2585     {
2586         glDispatchCompute(1, 1, 1);
2587     }
2588 
2589     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2590 }
2591 
framebufferBitImageWriteThenDraw(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2592 void MemoryBarrierTestBase::framebufferBitImageWriteThenDraw(ShaderWritePipeline writePipeline,
2593                                                              WriteResource writeResource,
2594                                                              NoopOp preBarrierOp,
2595                                                              NoopOp postBarrierOp)
2596 {
2597     GLTexture color;
2598     GLFramebuffer fbo;
2599     GLProgram writeProgram;
2600 
2601     createFramebuffer(color, fbo, GLColor::green);
2602     createProgram(writePipeline, writeResource, &writeProgram);
2603 
2604     GLBuffer positionBuffer;
2605     createQuadVertexArray(positionBuffer);
2606     setupVertexArray(writePipeline, writeProgram);
2607 
2608     GLBuffer textureBufferStorage;
2609     GLTexture texture;
2610     constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2611     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2612 
2613     constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2614     setUniformData(writeProgram, kWriteData);
2615 
2616     // Fill the image
2617     if (writePipeline == ShaderWritePipeline::Graphics)
2618     {
2619         glEnable(GL_BLEND);
2620         glBlendFunc(GL_ONE, GL_ONE);
2621         glDrawArrays(GL_TRIANGLES, 0, 6);
2622         glDisable(GL_BLEND);
2623     }
2624     else
2625     {
2626         glDispatchCompute(1, 1, 1);
2627     }
2628 
2629     noopOp(preBarrierOp);
2630 
2631     // Issue the appropriate memory barrier
2632     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
2633 
2634     noopOp(postBarrierOp);
2635 
2636     // Draw to image via framebuffer
2637     ANGLE_GL_PROGRAM(verifyProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
2638     glUseProgram(verifyProgram);
2639     GLint colorUniformLocation =
2640         glGetUniformLocation(verifyProgram, angle::essl1_shaders::ColorUniform());
2641     ASSERT_NE(colorUniformLocation, -1);
2642     setupVertexArray(ShaderWritePipeline::Graphics, verifyProgram);
2643 
2644     GLFramebuffer drawFbo;
2645     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFbo);
2646     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2647     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
2648 
2649     constexpr std::array<float, 4> kBlendData = {0.125, 0.25, 0.5, 0.25};
2650     glUniform4fv(colorUniformLocation, 1, kBlendData.data());
2651 
2652     glEnable(GL_BLEND);
2653     glBlendFunc(GL_ONE, GL_ONE);
2654     glDrawArrays(GL_TRIANGLES, 0, 6);
2655     glDisable(GL_BLEND);
2656     EXPECT_GL_NO_ERROR();
2657 
2658     const std::array<float, 4> kExpectedData = {
2659         kWriteData[0] + kBlendData[0],
2660         kWriteData[1] + kBlendData[1],
2661         kWriteData[2] + kBlendData[2],
2662         kWriteData[3] + kBlendData[3],
2663     };
2664     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kExpectedData);
2665 }
2666 
framebufferBitImageWriteThenReadPixels(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2667 void MemoryBarrierTestBase::framebufferBitImageWriteThenReadPixels(
2668     ShaderWritePipeline writePipeline,
2669     WriteResource writeResource,
2670     NoopOp preBarrierOp,
2671     NoopOp postBarrierOp)
2672 {
2673     GLTexture color;
2674     GLFramebuffer fbo;
2675     GLProgram writeProgram;
2676 
2677     createFramebuffer(color, fbo, GLColor::green);
2678     createProgram(writePipeline, writeResource, &writeProgram);
2679 
2680     GLBuffer positionBuffer;
2681     createQuadVertexArray(positionBuffer);
2682     setupVertexArray(writePipeline, writeProgram);
2683 
2684     GLBuffer textureBufferStorage;
2685     GLTexture texture;
2686     constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2687     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2688 
2689     constexpr std::array<float, 4> kWriteData = {1.0, 1.0, 0.0, 1.0};
2690     setUniformData(writeProgram, kWriteData);
2691 
2692     // Fill the image
2693     if (writePipeline == ShaderWritePipeline::Graphics)
2694     {
2695         glEnable(GL_BLEND);
2696         glBlendFunc(GL_ONE, GL_ONE);
2697         glDrawArrays(GL_TRIANGLES, 0, 6);
2698         glDisable(GL_BLEND);
2699     }
2700     else
2701     {
2702         glDispatchCompute(1, 1, 1);
2703     }
2704 
2705     noopOp(preBarrierOp);
2706 
2707     // Issue the appropriate memory barrier
2708     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
2709 
2710     noopOp(postBarrierOp);
2711 
2712     // Read from image via framebuffer
2713     GLBuffer packBuffer;
2714     glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
2715     constexpr std::array<uint32_t, 4> kPBOInitData = {0x12345678u, 0x9ABCDEF0u, 0x13579BDFu,
2716                                                       0x2468ACE0u};
2717     glBufferData(GL_PIXEL_PACK_BUFFER, sizeof(kInitData), kPBOInitData.data(), GL_STATIC_DRAW);
2718     EXPECT_GL_NO_ERROR();
2719 
2720     GLFramebuffer readFbo;
2721     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
2722     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2723     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
2724 
2725     glReadPixels(0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2726     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2727     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
2728     EXPECT_GL_NO_ERROR();
2729 
2730     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2731 
2732     // Verify the PBO for completeness
2733     glBindBuffer(GL_SHADER_STORAGE_BUFFER, packBuffer);
2734     constexpr std::array<uint32_t, 4> kExpectedData = {
2735         0xFF00FFFFu,
2736         kPBOInitData[1],
2737         kPBOInitData[2],
2738         kPBOInitData[3],
2739     };
2740     verifyBufferContents(kExpectedData);
2741 }
2742 
framebufferBitImageWriteThenCopy(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2743 void MemoryBarrierTestBase::framebufferBitImageWriteThenCopy(ShaderWritePipeline writePipeline,
2744                                                              WriteResource writeResource,
2745                                                              NoopOp preBarrierOp,
2746                                                              NoopOp postBarrierOp)
2747 {
2748     GLTexture color;
2749     GLFramebuffer fbo;
2750     GLProgram writeProgram;
2751 
2752     createFramebuffer(color, fbo, GLColor::green);
2753     createProgram(writePipeline, writeResource, &writeProgram);
2754 
2755     GLBuffer positionBuffer;
2756     createQuadVertexArray(positionBuffer);
2757     setupVertexArray(writePipeline, writeProgram);
2758 
2759     GLBuffer textureBufferStorage;
2760     GLTexture texture;
2761     constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2762     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2763 
2764     constexpr std::array<float, 4> kWriteData = {1.0, 1.0, 0.0, 1.0};
2765     setUniformData(writeProgram, kWriteData);
2766 
2767     // Fill the image
2768     if (writePipeline == ShaderWritePipeline::Graphics)
2769     {
2770         glEnable(GL_BLEND);
2771         glBlendFunc(GL_ONE, GL_ONE);
2772         glDrawArrays(GL_TRIANGLES, 0, 6);
2773         glDisable(GL_BLEND);
2774     }
2775     else
2776     {
2777         glDispatchCompute(1, 1, 1);
2778     }
2779 
2780     noopOp(preBarrierOp);
2781 
2782     // Issue the appropriate memory barrier
2783     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
2784 
2785     noopOp(postBarrierOp);
2786 
2787     // Copy from framebuffer to another texture
2788     GLFramebuffer readFbo;
2789     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
2790     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2791     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
2792 
2793     GLTexture copyTexture;
2794     glBindTexture(GL_TEXTURE_2D, copyTexture);
2795     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureSize, kTextureSize);
2796     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kTextureSize, kTextureSize);
2797 
2798     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2799     EXPECT_GL_NO_ERROR();
2800 
2801     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2802 
2803     // Verify the copy texture for completeness
2804     verifyImageContents(copyTexture, kWriteData);
2805 }
2806 
framebufferBitImageWriteThenBlit(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2807 void MemoryBarrierTestBase::framebufferBitImageWriteThenBlit(ShaderWritePipeline writePipeline,
2808                                                              WriteResource writeResource,
2809                                                              NoopOp preBarrierOp,
2810                                                              NoopOp postBarrierOp)
2811 {
2812     GLTexture blitColor;
2813     GLFramebuffer blitFbo;
2814     createFramebuffer(blitColor, blitFbo, GLColor::black);
2815 
2816     GLTexture color;
2817     GLFramebuffer fbo;
2818     GLProgram writeProgram;
2819 
2820     createFramebuffer(color, fbo, GLColor::green);
2821     createProgram(writePipeline, writeResource, &writeProgram);
2822 
2823     GLBuffer positionBuffer;
2824     createQuadVertexArray(positionBuffer);
2825     setupVertexArray(writePipeline, writeProgram);
2826 
2827     GLBuffer textureBufferStorage;
2828     GLTexture texture;
2829     constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2830     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2831 
2832     constexpr std::array<float, 4> kWriteData = {1.0, 1.0, 0.0, 1.0};
2833     setUniformData(writeProgram, kWriteData);
2834 
2835     // Fill the image
2836     if (writePipeline == ShaderWritePipeline::Graphics)
2837     {
2838         glEnable(GL_BLEND);
2839         glBlendFunc(GL_ONE, GL_ONE);
2840         glDrawArrays(GL_TRIANGLES, 0, 6);
2841         glDisable(GL_BLEND);
2842     }
2843     else
2844     {
2845         glDispatchCompute(1, 1, 1);
2846     }
2847 
2848     noopOp(preBarrierOp);
2849 
2850     // Issue the appropriate memory barrier
2851     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
2852 
2853     noopOp(postBarrierOp);
2854 
2855     // Blit from framebuffer to another framebuffer
2856     GLFramebuffer readFbo;
2857     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
2858     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2859     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
2860 
2861     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, blitFbo);
2862     glBlitFramebuffer(0, 0, kTextureSize, kTextureSize, 0, 0, kTextureSize, kTextureSize,
2863                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
2864     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2865     EXPECT_GL_NO_ERROR();
2866 
2867     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2868 
2869     // Verify the blit fbo for completeness
2870     glBindFramebuffer(GL_READ_FRAMEBUFFER, blitFbo);
2871     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
2872 }
2873 
framebufferBitDrawThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)2874 void MemoryBarrierTestBase::framebufferBitDrawThenImageWrite(ShaderWritePipeline writePipeline,
2875                                                              WriteResource writeResource,
2876                                                              NoopOp preBarrierOp,
2877                                                              NoopOp postBarrierOp,
2878                                                              GLbitfield barrierBit)
2879 {
2880     GLTexture color;
2881     GLFramebuffer fbo;
2882     GLProgram writeProgram;
2883 
2884     createFramebuffer(color, fbo, GLColor::green);
2885 
2886     GLBuffer textureBufferStorage;
2887     GLTexture texture;
2888     constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2889     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2890 
2891     // Draw to image via framebuffer
2892     ANGLE_GL_PROGRAM(verifyProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
2893     glUseProgram(verifyProgram);
2894 
2895     GLBuffer positionBuffer;
2896     createQuadVertexArray(positionBuffer);
2897     setupVertexArray(ShaderWritePipeline::Graphics, verifyProgram);
2898 
2899     GLFramebuffer drawFbo;
2900     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFbo);
2901     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2902     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
2903 
2904     glDrawArrays(GL_TRIANGLES, 0, 6);
2905     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
2906     EXPECT_GL_NO_ERROR();
2907 
2908     noopOp(preBarrierOp);
2909 
2910     // Issue the appropriate memory barrier
2911     glMemoryBarrier(barrierBit);
2912 
2913     noopOp(postBarrierOp);
2914 
2915     // Fill the image
2916     createProgram(writePipeline, writeResource, &writeProgram);
2917 
2918     setupVertexArray(writePipeline, writeProgram);
2919 
2920     constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2921     setUniformData(writeProgram, kWriteData);
2922 
2923     if (writePipeline == ShaderWritePipeline::Graphics)
2924     {
2925         glEnable(GL_BLEND);
2926         glBlendFunc(GL_ONE, GL_ONE);
2927         glDrawArrays(GL_TRIANGLES, 0, 6);
2928     }
2929     else
2930     {
2931         glDispatchCompute(1, 1, 1);
2932     }
2933 
2934     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2935 }
2936 
framebufferBitReadPixelsThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)2937 void MemoryBarrierTestBase::framebufferBitReadPixelsThenImageWrite(
2938     ShaderWritePipeline writePipeline,
2939     WriteResource writeResource,
2940     NoopOp preBarrierOp,
2941     NoopOp postBarrierOp,
2942     GLbitfield barrierBit)
2943 {
2944     GLTexture color;
2945     GLFramebuffer fbo;
2946     GLProgram writeProgram;
2947 
2948     createFramebuffer(color, fbo, GLColor::green);
2949 
2950     GLBuffer textureBufferStorage;
2951     GLTexture texture;
2952     constexpr std::array<float, 4> kInitData = {1.0, 1.0, 0.0, 1.0};
2953     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2954 
2955     // Read from image via framebuffer
2956     GLBuffer packBuffer;
2957     glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
2958     constexpr std::array<uint32_t, 4> kPBOInitData = {0x12345678u, 0x9ABCDEF0u, 0x13579BDFu,
2959                                                       0x2468ACE0u};
2960     glBufferData(GL_PIXEL_PACK_BUFFER, sizeof(kInitData), kPBOInitData.data(), GL_STATIC_DRAW);
2961     EXPECT_GL_NO_ERROR();
2962 
2963     GLFramebuffer readFbo;
2964     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
2965     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2966     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
2967 
2968     glReadPixels(0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2969     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2970     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
2971     EXPECT_GL_NO_ERROR();
2972 
2973     noopOp(preBarrierOp);
2974 
2975     // Issue the appropriate memory barrier
2976     glMemoryBarrier(barrierBit);
2977 
2978     noopOp(postBarrierOp);
2979 
2980     // Fill the image
2981     createProgram(writePipeline, writeResource, &writeProgram);
2982 
2983     GLBuffer positionBuffer;
2984     createQuadVertexArray(positionBuffer);
2985     setupVertexArray(writePipeline, writeProgram);
2986 
2987     constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2988     setUniformData(writeProgram, kWriteData);
2989 
2990     if (writePipeline == ShaderWritePipeline::Graphics)
2991     {
2992         glEnable(GL_BLEND);
2993         glBlendFunc(GL_ONE, GL_ONE);
2994         glDrawArrays(GL_TRIANGLES, 0, 6);
2995     }
2996     else
2997     {
2998         glDispatchCompute(1, 1, 1);
2999     }
3000 
3001     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
3002 
3003     // Verify the PBO for completeness
3004     glBindBuffer(GL_SHADER_STORAGE_BUFFER, packBuffer);
3005     constexpr std::array<uint32_t, 4> kExpectedData = {
3006         0xFF00FFFFu,
3007         kPBOInitData[1],
3008         kPBOInitData[2],
3009         kPBOInitData[3],
3010     };
3011     verifyBufferContents(kExpectedData);
3012 }
3013 
framebufferBitCopyThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)3014 void MemoryBarrierTestBase::framebufferBitCopyThenImageWrite(ShaderWritePipeline writePipeline,
3015                                                              WriteResource writeResource,
3016                                                              NoopOp preBarrierOp,
3017                                                              NoopOp postBarrierOp,
3018                                                              GLbitfield barrierBit)
3019 {
3020     GLTexture color;
3021     GLFramebuffer fbo;
3022     GLProgram writeProgram;
3023 
3024     createFramebuffer(color, fbo, GLColor::green);
3025 
3026     GLBuffer textureBufferStorage;
3027     GLTexture texture;
3028     constexpr std::array<float, 4> kInitData = {1.0, 1.0, 0.0, 1.0};
3029     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
3030 
3031     // Copy from framebuffer to another texture
3032     GLFramebuffer readFbo;
3033     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
3034     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3035     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
3036 
3037     GLTexture copyTexture;
3038     glBindTexture(GL_TEXTURE_2D, copyTexture);
3039     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureSize, kTextureSize);
3040     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kTextureSize, kTextureSize);
3041 
3042     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
3043     EXPECT_GL_NO_ERROR();
3044 
3045     noopOp(preBarrierOp);
3046 
3047     // Issue the appropriate memory barrier
3048     glMemoryBarrier(barrierBit);
3049 
3050     noopOp(postBarrierOp);
3051 
3052     // Fill the image
3053     createProgram(writePipeline, writeResource, &writeProgram);
3054 
3055     GLBuffer positionBuffer;
3056     createQuadVertexArray(positionBuffer);
3057     setupVertexArray(writePipeline, writeProgram);
3058 
3059     constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
3060     setUniformData(writeProgram, kWriteData);
3061 
3062     if (writePipeline == ShaderWritePipeline::Graphics)
3063     {
3064         glEnable(GL_BLEND);
3065         glBlendFunc(GL_ONE, GL_ONE);
3066         glDrawArrays(GL_TRIANGLES, 0, 6);
3067     }
3068     else
3069     {
3070         glDispatchCompute(1, 1, 1);
3071     }
3072 
3073     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
3074 
3075     // Verify the copy texture for completeness
3076     verifyImageContents(copyTexture, kInitData);
3077 }
3078 
framebufferBitBlitThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)3079 void MemoryBarrierTestBase::framebufferBitBlitThenImageWrite(ShaderWritePipeline writePipeline,
3080                                                              WriteResource writeResource,
3081                                                              NoopOp preBarrierOp,
3082                                                              NoopOp postBarrierOp,
3083                                                              GLbitfield barrierBit)
3084 {
3085     GLTexture blitColor;
3086     GLFramebuffer blitFbo;
3087     createFramebuffer(blitColor, blitFbo, GLColor::black);
3088 
3089     GLTexture color;
3090     GLFramebuffer fbo;
3091     GLProgram writeProgram;
3092 
3093     createFramebuffer(color, fbo, GLColor::green);
3094 
3095     GLBuffer textureBufferStorage;
3096     GLTexture texture;
3097     constexpr std::array<float, 4> kInitData = {1.0, 1.0, 0.0, 1.0};
3098     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
3099 
3100     // Blit from framebuffer to another framebuffer
3101     GLFramebuffer readFbo;
3102     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
3103     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3104     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
3105 
3106     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, blitFbo);
3107     glBlitFramebuffer(0, 0, kTextureSize, kTextureSize, 0, 0, kTextureSize, kTextureSize,
3108                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
3109     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3110     EXPECT_GL_NO_ERROR();
3111 
3112     noopOp(preBarrierOp);
3113 
3114     // Issue the appropriate memory barrier
3115     glMemoryBarrier(barrierBit);
3116 
3117     noopOp(postBarrierOp);
3118 
3119     // Fill the image
3120     createProgram(writePipeline, writeResource, &writeProgram);
3121 
3122     GLBuffer positionBuffer;
3123     createQuadVertexArray(positionBuffer);
3124     setupVertexArray(writePipeline, writeProgram);
3125 
3126     constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
3127     setUniformData(writeProgram, kWriteData);
3128 
3129     if (writePipeline == ShaderWritePipeline::Graphics)
3130     {
3131         glEnable(GL_BLEND);
3132         glBlendFunc(GL_ONE, GL_ONE);
3133         glDrawArrays(GL_TRIANGLES, 0, 6);
3134     }
3135     else
3136     {
3137         glDispatchCompute(1, 1, 1);
3138     }
3139 
3140     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
3141 
3142     // Verify the blit fbo for completeness
3143     glBindFramebuffer(GL_READ_FRAMEBUFFER, blitFbo);
3144     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
3145 }
3146 
3147 class MemoryBarrierBufferTest : public MemoryBarrierTestBase,
3148                                 public ANGLETest<MemoryBarrierVariationsTestParams>
3149 {
3150   protected:
MemoryBarrierBufferTest()3151     MemoryBarrierBufferTest()
3152     {
3153         setWindowWidth(16);
3154         setWindowHeight(32);
3155         setConfigRedBits(8);
3156         setConfigGreenBits(8);
3157         setConfigBlueBits(8);
3158         setConfigAlphaBits(8);
3159     }
3160 };
3161 
3162 class MemoryBarrierImageTest : public MemoryBarrierTestBase,
3163                                public ANGLETest<MemoryBarrierVariationsTestParams>
3164 {
3165   protected:
MemoryBarrierImageTest()3166     MemoryBarrierImageTest()
3167     {
3168         setWindowWidth(16);
3169         setWindowHeight(32);
3170         setConfigRedBits(8);
3171         setConfigGreenBits(8);
3172         setConfigBlueBits(8);
3173         setConfigAlphaBits(8);
3174     }
3175 };
3176 
3177 class MemoryBarrierImageBufferOnlyTest : public MemoryBarrierTestBase,
3178                                          public ANGLETest<MemoryBarrierVariationsTestParams>
3179 {
3180   protected:
MemoryBarrierImageBufferOnlyTest()3181     MemoryBarrierImageBufferOnlyTest()
3182     {
3183         setWindowWidth(16);
3184         setWindowHeight(32);
3185         setConfigRedBits(8);
3186         setConfigGreenBits(8);
3187         setConfigBlueBits(8);
3188         setConfigAlphaBits(8);
3189     }
3190 };
3191 
3192 class MemoryBarrierImageOnlyTest : public MemoryBarrierTestBase,
3193                                    public ANGLETest<MemoryBarrierVariationsTestParams>
3194 {
3195   protected:
MemoryBarrierImageOnlyTest()3196     MemoryBarrierImageOnlyTest()
3197     {
3198         setWindowWidth(16);
3199         setWindowHeight(32);
3200         setConfigRedBits(8);
3201         setConfigGreenBits(8);
3202         setConfigBlueBits(8);
3203         setConfigAlphaBits(8);
3204     }
3205 };
3206 
3207 class MemoryBarrierBufferOnlyTest : public MemoryBarrierTestBase,
3208                                     public ANGLETest<MemoryBarrierVariationsTestParams>
3209 {
3210   protected:
MemoryBarrierBufferOnlyTest()3211     MemoryBarrierBufferOnlyTest()
3212     {
3213         setWindowWidth(16);
3214         setWindowHeight(32);
3215         setConfigRedBits(8);
3216         setConfigGreenBits(8);
3217         setConfigBlueBits(8);
3218         setConfigAlphaBits(8);
3219     }
3220 };
3221 
3222 // Test GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT; shader write -> vertex read
TEST_P(MemoryBarrierBufferTest,VertexAtrribArrayBitWriteThenVertexRead)3223 TEST_P(MemoryBarrierBufferTest, VertexAtrribArrayBitWriteThenVertexRead)
3224 {
3225     ShaderWritePipeline writePipeline;
3226     WriteResource writeResource;
3227     NoopOp preBarrierOp;
3228     NoopOp postBarrierOp;
3229     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3230                                            &preBarrierOp, &postBarrierOp);
3231 
3232     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3233 
3234     vertexAttribArrayBitBufferWriteThenVertexRead(writePipeline, writeResource, preBarrierOp,
3235                                                   postBarrierOp);
3236 }
3237 
3238 // Test GL_ELEMENT_ARRAY_BARRIER_BIT; shader write -> index read
TEST_P(MemoryBarrierBufferTest,ElementArrayBitWriteThenIndexRead)3239 TEST_P(MemoryBarrierBufferTest, ElementArrayBitWriteThenIndexRead)
3240 {
3241     ShaderWritePipeline writePipeline;
3242     WriteResource writeResource;
3243     NoopOp preBarrierOp;
3244     NoopOp postBarrierOp;
3245     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3246                                            &preBarrierOp, &postBarrierOp);
3247 
3248     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3249 
3250     elementArrayBitBufferWriteThenIndexRead(writePipeline, writeResource, preBarrierOp,
3251                                             postBarrierOp);
3252 }
3253 
3254 // Test GL_UNIFORM_BARRIER_BIT; shader write -> ubo read
TEST_P(MemoryBarrierBufferTest,UniformBitWriteThenUBORead)3255 TEST_P(MemoryBarrierBufferTest, UniformBitWriteThenUBORead)
3256 {
3257     ShaderWritePipeline writePipeline;
3258     WriteResource writeResource;
3259     NoopOp preBarrierOp;
3260     NoopOp postBarrierOp;
3261     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3262                                            &preBarrierOp, &postBarrierOp);
3263 
3264     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3265 
3266     uniformBitBufferWriteThenUBORead(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3267 }
3268 
3269 // Test GL_TEXTURE_FETCH_BARRIER_BIT; shader write -> sampler read
TEST_P(MemoryBarrierImageTest,TextureFetchBitWriteThenSamplerRead)3270 TEST_P(MemoryBarrierImageTest, TextureFetchBitWriteThenSamplerRead)
3271 {
3272     ShaderWritePipeline writePipeline;
3273     WriteResource writeResource;
3274     NoopOp preBarrierOp;
3275     NoopOp postBarrierOp;
3276     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3277                                            &preBarrierOp, &postBarrierOp);
3278 
3279     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3280 
3281     textureFetchBitImageWriteThenSamplerRead(writePipeline, writeResource, preBarrierOp,
3282                                              postBarrierOp);
3283 }
3284 
3285 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; shader write -> image read
TEST_P(MemoryBarrierImageTest,ShaderImageAccessBitWriteThenImageRead)3286 TEST_P(MemoryBarrierImageTest, ShaderImageAccessBitWriteThenImageRead)
3287 {
3288     ShaderWritePipeline writePipeline;
3289     WriteResource writeResource;
3290     NoopOp preBarrierOp;
3291     NoopOp postBarrierOp;
3292     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3293                                            &preBarrierOp, &postBarrierOp);
3294 
3295     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3296 
3297     shaderImageAccessBitImageWriteThenImageRead(writePipeline, writeResource, preBarrierOp,
3298                                                 postBarrierOp);
3299 }
3300 
3301 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; image read -> shader write
TEST_P(MemoryBarrierImageTest,ShaderImageAccessBitImageReadThenWrite)3302 TEST_P(MemoryBarrierImageTest, ShaderImageAccessBitImageReadThenWrite)
3303 {
3304     ShaderWritePipeline writePipeline;
3305     WriteResource writeResource;
3306     NoopOp preBarrierOp;
3307     NoopOp postBarrierOp;
3308     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3309                                            &preBarrierOp, &postBarrierOp);
3310 
3311     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3312 
3313     // Looks like the implementation is missing this line from the spec:
3314     //
3315     // > Additionally, image stores issued after the barrier will not execute until all memory
3316     // > accesses (e.g., loads, stores, texture fetches, vertex fetches) initiated prior to the
3317     // > barrier complete.
3318     //
3319     // http://anglebug.com/42264187
3320     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsNVIDIA() && writeResource == WriteResource::Image);
3321 
3322     shaderImageAccessBitImageReadThenImageWrite(writePipeline, writeResource, preBarrierOp,
3323                                                 postBarrierOp);
3324 }
3325 
3326 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; vertex read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitVertexReadThenWrite)3327 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitVertexReadThenWrite)
3328 {
3329     ShaderWritePipeline writePipeline;
3330     WriteResource writeResource;
3331     NoopOp preBarrierOp;
3332     NoopOp postBarrierOp;
3333     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3334                                            &preBarrierOp, &postBarrierOp);
3335 
3336     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3337 
3338     vertexAttribArrayBitVertexReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3339                                                   postBarrierOp,
3340                                                   GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3341 }
3342 
3343 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; index read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitIndexReadThenWrite)3344 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitIndexReadThenWrite)
3345 {
3346     ShaderWritePipeline writePipeline;
3347     WriteResource writeResource;
3348     NoopOp preBarrierOp;
3349     NoopOp postBarrierOp;
3350     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3351                                            &preBarrierOp, &postBarrierOp);
3352 
3353     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3354 
3355     elementArrayBitIndexReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3356                                             postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3357 }
3358 
3359 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; ubo read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitUBOReadThenWrite)3360 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitUBOReadThenWrite)
3361 {
3362     ShaderWritePipeline writePipeline;
3363     WriteResource writeResource;
3364     NoopOp preBarrierOp;
3365     NoopOp postBarrierOp;
3366     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3367                                            &preBarrierOp, &postBarrierOp);
3368 
3369     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3370 
3371     uniformBitUBOReadThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3372                                      GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3373 }
3374 
3375 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; sampler read -> shader write
TEST_P(MemoryBarrierImageTest,ShaderImageAccessBitSamplerReadThenWrite)3376 TEST_P(MemoryBarrierImageTest, ShaderImageAccessBitSamplerReadThenWrite)
3377 {
3378     ShaderWritePipeline writePipeline;
3379     WriteResource writeResource;
3380     NoopOp preBarrierOp;
3381     NoopOp postBarrierOp;
3382     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3383                                            &preBarrierOp, &postBarrierOp);
3384 
3385     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3386 
3387     textureFetchBitSamplerReadThenImageWrite(writePipeline, writeResource, preBarrierOp,
3388                                              postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3389 }
3390 
3391 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; indirect read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitIndirectReadThenWrite)3392 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitIndirectReadThenWrite)
3393 {
3394     ShaderWritePipeline writePipeline;
3395     WriteResource writeResource;
3396     NoopOp preBarrierOp;
3397     NoopOp postBarrierOp;
3398     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3399                                            &preBarrierOp, &postBarrierOp);
3400 
3401     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3402 
3403     commandBitIndirectReadThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3404                                           GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3405 }
3406 
3407 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; pixel pack -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitPackThenWrite)3408 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitPackThenWrite)
3409 {
3410     ShaderWritePipeline writePipeline;
3411     WriteResource writeResource;
3412     NoopOp preBarrierOp;
3413     NoopOp postBarrierOp;
3414     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3415                                            &preBarrierOp, &postBarrierOp);
3416 
3417     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3418 
3419     pixelBufferBitPackThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3420                                       GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3421 }
3422 
3423 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; pixel unpack -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitUnpackThenWrite)3424 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitUnpackThenWrite)
3425 {
3426     ShaderWritePipeline writePipeline;
3427     WriteResource writeResource;
3428     NoopOp preBarrierOp;
3429     NoopOp postBarrierOp;
3430     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3431                                            &preBarrierOp, &postBarrierOp);
3432 
3433     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3434 
3435     pixelBufferBitUnpackThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3436                                         GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3437 }
3438 
3439 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; texture copy -> shader write
TEST_P(MemoryBarrierImageOnlyTest,ShaderImageAccessBitCopyThenWrite)3440 TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitCopyThenWrite)
3441 {
3442     ShaderWritePipeline writePipeline;
3443     WriteResource writeResource;
3444     NoopOp preBarrierOp;
3445     NoopOp postBarrierOp;
3446     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3447                                            &preBarrierOp, &postBarrierOp);
3448 
3449     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3450 
3451     textureUpdateBitCopyThenImageWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3452                                        GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3453 }
3454 
3455 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; buffer copy -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitCopyThenWrite)3456 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitCopyThenWrite)
3457 {
3458     ShaderWritePipeline writePipeline;
3459     WriteResource writeResource;
3460     NoopOp preBarrierOp;
3461     NoopOp postBarrierOp;
3462     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3463                                            &preBarrierOp, &postBarrierOp);
3464 
3465     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3466 
3467     bufferUpdateBitCopyThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3468                                        GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3469 }
3470 
3471 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; draw -> shader write
TEST_P(MemoryBarrierImageOnlyTest,ShaderImageAccessBitDrawThenWrite)3472 TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitDrawThenWrite)
3473 {
3474     ShaderWritePipeline writePipeline;
3475     WriteResource writeResource;
3476     NoopOp preBarrierOp;
3477     NoopOp postBarrierOp;
3478     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3479                                            &preBarrierOp, &postBarrierOp);
3480 
3481     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3482 
3483     framebufferBitDrawThenImageWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3484                                      GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3485 }
3486 
3487 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; read pixels -> shader write
TEST_P(MemoryBarrierImageOnlyTest,ShaderImageAccessBitReadPixelsThenWrite)3488 TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitReadPixelsThenWrite)
3489 {
3490     ShaderWritePipeline writePipeline;
3491     WriteResource writeResource;
3492     NoopOp preBarrierOp;
3493     NoopOp postBarrierOp;
3494     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3495                                            &preBarrierOp, &postBarrierOp);
3496 
3497     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3498 
3499     framebufferBitReadPixelsThenImageWrite(writePipeline, writeResource, preBarrierOp,
3500                                            postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3501 }
3502 
3503 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; fbo copy -> shader write
TEST_P(MemoryBarrierImageOnlyTest,ShaderImageAccessBitFBOCopyThenWrite)3504 TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitFBOCopyThenWrite)
3505 {
3506     ShaderWritePipeline writePipeline;
3507     WriteResource writeResource;
3508     NoopOp preBarrierOp;
3509     NoopOp postBarrierOp;
3510     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3511                                            &preBarrierOp, &postBarrierOp);
3512 
3513     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3514 
3515     framebufferBitCopyThenImageWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3516                                      GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3517 }
3518 
3519 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; blit -> shader write
TEST_P(MemoryBarrierImageOnlyTest,ShaderImageAccessBitBlitThenWrite)3520 TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitBlitThenWrite)
3521 {
3522     ShaderWritePipeline writePipeline;
3523     WriteResource writeResource;
3524     NoopOp preBarrierOp;
3525     NoopOp postBarrierOp;
3526     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3527                                            &preBarrierOp, &postBarrierOp);
3528 
3529     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3530 
3531     framebufferBitBlitThenImageWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3532                                      GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3533 }
3534 
3535 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; xfb capture -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitCaptureThenWrite)3536 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitCaptureThenWrite)
3537 {
3538     ShaderWritePipeline writePipeline;
3539     WriteResource writeResource;
3540     NoopOp preBarrierOp;
3541     NoopOp postBarrierOp;
3542     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3543                                            &preBarrierOp, &postBarrierOp);
3544 
3545     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3546 
3547     transformFeedbackBitCaptureThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3548                                                postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3549 }
3550 
3551 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; atomic write -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitAtomicThenWrite)3552 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitAtomicThenWrite)
3553 {
3554     ShaderWritePipeline writePipeline;
3555     WriteResource writeResource;
3556     NoopOp preBarrierOp;
3557     NoopOp postBarrierOp;
3558     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3559                                            &preBarrierOp, &postBarrierOp);
3560 
3561     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3562 
3563     atomicCounterBitAtomicThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3564                                           GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3565 }
3566 
3567 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; buffer read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitBufferReadThenWrite)3568 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitBufferReadThenWrite)
3569 {
3570     ShaderWritePipeline writePipeline;
3571     WriteResource writeResource;
3572     NoopOp preBarrierOp;
3573     NoopOp postBarrierOp;
3574     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3575                                            &preBarrierOp, &postBarrierOp);
3576 
3577     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3578 
3579     shaderStorageBitBufferReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3580                                               postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3581 }
3582 
3583 // Test GL_COMMAND_BARRIER_BIT; shader write -> indirect read
TEST_P(MemoryBarrierBufferTest,CommandBitWriteThenIndirectRead)3584 TEST_P(MemoryBarrierBufferTest, CommandBitWriteThenIndirectRead)
3585 {
3586     ShaderWritePipeline writePipeline;
3587     WriteResource writeResource;
3588     NoopOp preBarrierOp;
3589     NoopOp postBarrierOp;
3590     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3591                                            &preBarrierOp, &postBarrierOp);
3592 
3593     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3594 
3595     commandBitBufferWriteThenIndirectRead(writePipeline, writeResource, preBarrierOp,
3596                                           postBarrierOp);
3597 }
3598 
3599 // Test GL_PIXEL_BUFFER_BARRIER_BIT; shader write -> pixel pack
TEST_P(MemoryBarrierBufferTest,PixelBufferBitWriteThenPack)3600 TEST_P(MemoryBarrierBufferTest, PixelBufferBitWriteThenPack)
3601 {
3602     ShaderWritePipeline writePipeline;
3603     WriteResource writeResource;
3604     NoopOp preBarrierOp;
3605     NoopOp postBarrierOp;
3606     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3607                                            &preBarrierOp, &postBarrierOp);
3608 
3609     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3610 
3611     pixelBufferBitBufferWriteThenPack(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3612 }
3613 
3614 // Test GL_PIXEL_BUFFER_BARRIER_BIT; shader write -> pixel unpack
TEST_P(MemoryBarrierBufferTest,PixelBufferBitWriteThenUnpack)3615 TEST_P(MemoryBarrierBufferTest, PixelBufferBitWriteThenUnpack)
3616 {
3617     ShaderWritePipeline writePipeline;
3618     WriteResource writeResource;
3619     NoopOp preBarrierOp;
3620     NoopOp postBarrierOp;
3621     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3622                                            &preBarrierOp, &postBarrierOp);
3623 
3624     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3625 
3626     pixelBufferBitBufferWriteThenUnpack(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3627 }
3628 
3629 // Test GL_TEXTURE_UPDATE_BARRIER_BIT; shader write -> texture copy
TEST_P(MemoryBarrierImageOnlyTest,TextureUpdateBitWriteThenCopy)3630 TEST_P(MemoryBarrierImageOnlyTest, TextureUpdateBitWriteThenCopy)
3631 {
3632     ShaderWritePipeline writePipeline;
3633     WriteResource writeResource;
3634     NoopOp preBarrierOp;
3635     NoopOp postBarrierOp;
3636     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3637                                            &preBarrierOp, &postBarrierOp);
3638 
3639     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3640 
3641     textureUpdateBitImageWriteThenCopy(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3642 }
3643 
3644 // Test GL_BUFFER_UPDATE_BARRIER_BIT; shader write -> buffer copy
TEST_P(MemoryBarrierBufferTest,BufferUpdateBitWriteThenCopy)3645 TEST_P(MemoryBarrierBufferTest, BufferUpdateBitWriteThenCopy)
3646 {
3647     ShaderWritePipeline writePipeline;
3648     WriteResource writeResource;
3649     NoopOp preBarrierOp;
3650     NoopOp postBarrierOp;
3651     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3652                                            &preBarrierOp, &postBarrierOp);
3653 
3654     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3655 
3656     bufferUpdateBitBufferWriteThenCopy(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3657 }
3658 
3659 // Test GL_FRAMEBUFFER_BARRIER_BIT; shader write -> draw
TEST_P(MemoryBarrierImageOnlyTest,FramebufferBitWriteThenDraw)3660 TEST_P(MemoryBarrierImageOnlyTest, FramebufferBitWriteThenDraw)
3661 {
3662     ShaderWritePipeline writePipeline;
3663     WriteResource writeResource;
3664     NoopOp preBarrierOp;
3665     NoopOp postBarrierOp;
3666     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3667                                            &preBarrierOp, &postBarrierOp);
3668 
3669     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3670 
3671     framebufferBitImageWriteThenDraw(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3672 }
3673 
3674 // Test GL_FRAMEBUFFER_BARRIER_BIT; shader write -> read pixels
TEST_P(MemoryBarrierImageOnlyTest,FramebufferBitWriteThenReadPixels)3675 TEST_P(MemoryBarrierImageOnlyTest, FramebufferBitWriteThenReadPixels)
3676 {
3677     ShaderWritePipeline writePipeline;
3678     WriteResource writeResource;
3679     NoopOp preBarrierOp;
3680     NoopOp postBarrierOp;
3681     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3682                                            &preBarrierOp, &postBarrierOp);
3683 
3684     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3685 
3686     framebufferBitImageWriteThenReadPixels(writePipeline, writeResource, preBarrierOp,
3687                                            postBarrierOp);
3688 }
3689 
3690 // Test GL_FRAMEBUFFER_BARRIER_BIT; shader write -> copy
TEST_P(MemoryBarrierImageOnlyTest,FramebufferBitWriteThenCopy)3691 TEST_P(MemoryBarrierImageOnlyTest, FramebufferBitWriteThenCopy)
3692 {
3693     ShaderWritePipeline writePipeline;
3694     WriteResource writeResource;
3695     NoopOp preBarrierOp;
3696     NoopOp postBarrierOp;
3697     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3698                                            &preBarrierOp, &postBarrierOp);
3699 
3700     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3701 
3702     framebufferBitImageWriteThenCopy(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3703 }
3704 
3705 // Test GL_FRAMEBUFFER_BARRIER_BIT; shader write -> blit
TEST_P(MemoryBarrierImageOnlyTest,FramebufferBitWriteThenBlit)3706 TEST_P(MemoryBarrierImageOnlyTest, FramebufferBitWriteThenBlit)
3707 {
3708     ShaderWritePipeline writePipeline;
3709     WriteResource writeResource;
3710     NoopOp preBarrierOp;
3711     NoopOp postBarrierOp;
3712     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3713                                            &preBarrierOp, &postBarrierOp);
3714 
3715     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3716 
3717     framebufferBitImageWriteThenBlit(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3718 }
3719 
3720 // Test GL_TRANSFORM_FEEDBACK_BARRIER_BIT; shader write -> xfb capture
TEST_P(MemoryBarrierBufferTest,TransformFeedbackBitWriteThenCapture)3721 TEST_P(MemoryBarrierBufferTest, TransformFeedbackBitWriteThenCapture)
3722 {
3723     ShaderWritePipeline writePipeline;
3724     WriteResource writeResource;
3725     NoopOp preBarrierOp;
3726     NoopOp postBarrierOp;
3727     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3728                                            &preBarrierOp, &postBarrierOp);
3729 
3730     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3731 
3732     transformFeedbackBitBufferWriteThenCapture(writePipeline, writeResource, preBarrierOp,
3733                                                postBarrierOp);
3734 }
3735 
3736 // Test GL_ATOMIC_COUNTER_BARRIER_BIT; shader write -> atomic write
TEST_P(MemoryBarrierBufferTest,AtomicCounterBitWriteThenAtomic)3737 TEST_P(MemoryBarrierBufferTest, AtomicCounterBitWriteThenAtomic)
3738 {
3739     ShaderWritePipeline writePipeline;
3740     WriteResource writeResource;
3741     NoopOp preBarrierOp;
3742     NoopOp postBarrierOp;
3743     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3744                                            &preBarrierOp, &postBarrierOp);
3745 
3746     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3747 
3748     atomicCounterBitBufferWriteThenAtomic(writePipeline, writeResource, preBarrierOp,
3749                                           postBarrierOp);
3750 }
3751 
3752 // Test GL_SHADER_STORAGE_BARRIER_BIT; shader write -> shader read
TEST_P(MemoryBarrierBufferTest,ShaderStorageBitWriteThenRead)3753 TEST_P(MemoryBarrierBufferTest, ShaderStorageBitWriteThenRead)
3754 {
3755     ShaderWritePipeline writePipeline;
3756     WriteResource writeResource;
3757     NoopOp preBarrierOp;
3758     NoopOp postBarrierOp;
3759     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3760                                            &preBarrierOp, &postBarrierOp);
3761 
3762     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3763 
3764     shaderStorageBitBufferWriteThenBufferRead(writePipeline, writeResource, preBarrierOp,
3765                                               postBarrierOp);
3766 }
3767 
3768 // Test GL_SHADER_STORAGE_BARRIER_BIT; shader read -> buffer write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitReadThenWrite)3769 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitReadThenWrite)
3770 {
3771     ShaderWritePipeline writePipeline;
3772     WriteResource writeResource;
3773     NoopOp preBarrierOp;
3774     NoopOp postBarrierOp;
3775     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3776                                            &preBarrierOp, &postBarrierOp);
3777 
3778     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3779 
3780     shaderStorageBitBufferReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3781                                               postBarrierOp, GL_SHADER_STORAGE_BARRIER_BIT);
3782 }
3783 
3784 // Test GL_SHADER_STORAGE_BARRIER_BIT; vertex read -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitVertexReadThenWrite)3785 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitVertexReadThenWrite)
3786 {
3787     ShaderWritePipeline writePipeline;
3788     WriteResource writeResource;
3789     NoopOp preBarrierOp;
3790     NoopOp postBarrierOp;
3791     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3792                                            &preBarrierOp, &postBarrierOp);
3793 
3794     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3795 
3796     vertexAttribArrayBitVertexReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3797                                                   postBarrierOp, GL_SHADER_STORAGE_BARRIER_BIT);
3798 }
3799 
3800 // Test GL_SHADER_STORAGE_BARRIER_BIT; index read -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitIndexReadThenWrite)3801 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitIndexReadThenWrite)
3802 {
3803     ShaderWritePipeline writePipeline;
3804     WriteResource writeResource;
3805     NoopOp preBarrierOp;
3806     NoopOp postBarrierOp;
3807     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3808                                            &preBarrierOp, &postBarrierOp);
3809 
3810     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3811 
3812     elementArrayBitIndexReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3813                                             postBarrierOp, GL_SHADER_STORAGE_BARRIER_BIT);
3814 }
3815 
3816 // Test GL_SHADER_STORAGE_BARRIER_BIT; ubo read -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitUBOReadThenWrite)3817 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitUBOReadThenWrite)
3818 {
3819     ShaderWritePipeline writePipeline;
3820     WriteResource writeResource;
3821     NoopOp preBarrierOp;
3822     NoopOp postBarrierOp;
3823     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3824                                            &preBarrierOp, &postBarrierOp);
3825 
3826     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3827 
3828     uniformBitUBOReadThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3829                                      GL_SHADER_STORAGE_BARRIER_BIT);
3830 }
3831 
3832 // Test GL_SHADER_STORAGE_BARRIER_BIT; indirect read -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitIndirectReadThenWrite)3833 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitIndirectReadThenWrite)
3834 {
3835     ShaderWritePipeline writePipeline;
3836     WriteResource writeResource;
3837     NoopOp preBarrierOp;
3838     NoopOp postBarrierOp;
3839     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3840                                            &preBarrierOp, &postBarrierOp);
3841 
3842     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3843 
3844     commandBitIndirectReadThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3845                                           GL_SHADER_STORAGE_BARRIER_BIT);
3846 }
3847 
3848 // Test GL_SHADER_STORAGE_BARRIER_BIT; pixel pack -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitPackThenWrite)3849 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitPackThenWrite)
3850 {
3851     ShaderWritePipeline writePipeline;
3852     WriteResource writeResource;
3853     NoopOp preBarrierOp;
3854     NoopOp postBarrierOp;
3855     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3856                                            &preBarrierOp, &postBarrierOp);
3857 
3858     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3859 
3860     pixelBufferBitPackThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3861                                       GL_SHADER_STORAGE_BARRIER_BIT);
3862 }
3863 
3864 // Test GL_SHADER_STORAGE_BARRIER_BIT; pixel unpack -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitUnpackThenWrite)3865 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitUnpackThenWrite)
3866 {
3867     ShaderWritePipeline writePipeline;
3868     WriteResource writeResource;
3869     NoopOp preBarrierOp;
3870     NoopOp postBarrierOp;
3871     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3872                                            &preBarrierOp, &postBarrierOp);
3873 
3874     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3875 
3876     pixelBufferBitUnpackThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3877                                         GL_SHADER_STORAGE_BARRIER_BIT);
3878 }
3879 
3880 // Test GL_SHADER_STORAGE_BARRIER_BIT; buffer copy -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitCopyThenWrite)3881 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitCopyThenWrite)
3882 {
3883     ShaderWritePipeline writePipeline;
3884     WriteResource writeResource;
3885     NoopOp preBarrierOp;
3886     NoopOp postBarrierOp;
3887     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3888                                            &preBarrierOp, &postBarrierOp);
3889 
3890     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3891 
3892     bufferUpdateBitCopyThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3893                                        GL_SHADER_STORAGE_BARRIER_BIT);
3894 }
3895 
3896 // Test GL_SHADER_STORAGE_BARRIER_BIT; xfb capture -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitCaptureThenWrite)3897 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitCaptureThenWrite)
3898 {
3899     ShaderWritePipeline writePipeline;
3900     WriteResource writeResource;
3901     NoopOp preBarrierOp;
3902     NoopOp postBarrierOp;
3903     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3904                                            &preBarrierOp, &postBarrierOp);
3905 
3906     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3907 
3908     transformFeedbackBitCaptureThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3909                                                postBarrierOp, GL_SHADER_STORAGE_BARRIER_BIT);
3910 }
3911 
3912 // Test GL_SHADER_STORAGE_BARRIER_BIT; atomic write -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitAtomicThenWrite)3913 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitAtomicThenWrite)
3914 {
3915     ShaderWritePipeline writePipeline;
3916     WriteResource writeResource;
3917     NoopOp preBarrierOp;
3918     NoopOp postBarrierOp;
3919     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3920                                            &preBarrierOp, &postBarrierOp);
3921 
3922     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3923 
3924     atomicCounterBitAtomicThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3925                                           GL_SHADER_STORAGE_BARRIER_BIT);
3926 }
3927 
3928 constexpr ShaderWritePipeline kWritePipelines[] = {
3929     ShaderWritePipeline::Graphics,
3930     ShaderWritePipeline::Compute,
3931 };
3932 constexpr WriteResource kBufferWriteResources[] = {
3933     WriteResource::Buffer,
3934     WriteResource::ImageBuffer,
3935 };
3936 constexpr WriteResource kImageWriteResources[] = {
3937     WriteResource::Image,
3938     WriteResource::ImageBuffer,
3939 };
3940 constexpr WriteResource kImageBufferOnlyWriteResources[] = {
3941     WriteResource::ImageBuffer,
3942 };
3943 constexpr WriteResource kImageOnlyWriteResources[] = {
3944     WriteResource::Image,
3945 };
3946 constexpr WriteResource kBufferOnlyWriteResources[] = {
3947     WriteResource::Buffer,
3948 };
3949 constexpr NoopOp kNoopOps[] = {
3950     NoopOp::None,
3951     NoopOp::Draw,
3952     NoopOp::Dispatch,
3953 };
3954 
3955 // Note: due to large number of tests, these are only run on Vulkan and a single configuration
3956 // (swiftshader).
3957 
3958 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierBufferTest);
3959 ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierBufferTest,
3960                                  MemoryBarrierVariationsTestPrint,
3961                                  testing::ValuesIn(kWritePipelines),
3962                                  testing::ValuesIn(kBufferWriteResources),
3963                                  testing::ValuesIn(kNoopOps),
3964                                  testing::ValuesIn(kNoopOps),
3965                                  ES31_VULKAN_SWIFTSHADER());
3966 
3967 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierImageTest);
3968 ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierImageTest,
3969                                  MemoryBarrierVariationsTestPrint,
3970                                  testing::ValuesIn(kWritePipelines),
3971                                  testing::ValuesIn(kImageWriteResources),
3972                                  testing::ValuesIn(kNoopOps),
3973                                  testing::ValuesIn(kNoopOps),
3974                                  ES31_VULKAN_SWIFTSHADER());
3975 
3976 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierImageBufferOnlyTest);
3977 ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierImageBufferOnlyTest,
3978                                  MemoryBarrierVariationsTestPrint,
3979                                  testing::ValuesIn(kWritePipelines),
3980                                  testing::ValuesIn(kImageBufferOnlyWriteResources),
3981                                  testing::ValuesIn(kNoopOps),
3982                                  testing::ValuesIn(kNoopOps),
3983                                  ES31_VULKAN_SWIFTSHADER());
3984 
3985 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierImageOnlyTest);
3986 ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierImageOnlyTest,
3987                                  MemoryBarrierVariationsTestPrint,
3988                                  testing::ValuesIn(kWritePipelines),
3989                                  testing::ValuesIn(kImageOnlyWriteResources),
3990                                  testing::ValuesIn(kNoopOps),
3991                                  testing::ValuesIn(kNoopOps),
3992                                  ES31_VULKAN_SWIFTSHADER());
3993 
3994 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierBufferOnlyTest);
3995 ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierBufferOnlyTest,
3996                                  MemoryBarrierVariationsTestPrint,
3997                                  testing::ValuesIn(kWritePipelines),
3998                                  testing::ValuesIn(kBufferOnlyWriteResources),
3999                                  testing::ValuesIn(kNoopOps),
4000                                  testing::ValuesIn(kNoopOps),
4001                                  ES31_VULKAN_SWIFTSHADER());
4002 
4003 }  // anonymous namespace
4004