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