• 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 std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
1734     createStorageBuffer(writeResource, xfbBuffer, xfbTextureBuffer, sizeof(kInitData) * 6,
1735                         kInitData.data());
1736 
1737     constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
1738     setUniformData(writeProgram, kWriteData);
1739 
1740     // Fill the buffer
1741     if (writePipeline == ShaderWritePipeline::Graphics)
1742     {
1743         glDrawArrays(GL_TRIANGLES, 0, 6);
1744     }
1745     else
1746     {
1747         glDispatchCompute(1, 1, 1);
1748     }
1749 
1750     noopOp(preBarrierOp);
1751 
1752     // Issue the appropriate memory barrier
1753     glMemoryBarrier(GL_TRANSFORM_FEEDBACK_BARRIER_BIT);
1754 
1755     noopOp(postBarrierOp);
1756 
1757     // Use the buffer
1758     GLProgram xfbProgram;
1759     createXfbVerifyProgram(xfbBuffer, &xfbProgram);
1760 
1761     glBeginTransformFeedback(GL_TRIANGLES);
1762     glEnable(GL_BLEND);
1763     glBlendFunc(GL_ONE, GL_ONE);
1764     glDrawArrays(GL_TRIANGLES, 0, 6);
1765     glEndTransformFeedback();
1766     EXPECT_GL_NO_ERROR();
1767 
1768     const std::array<float, 4> kExpectedData = {-1.0, -1.0, 0.0, 1.0};
1769     verifyFramebufferAndBufferContents(writePipeline, kExpectedData);
1770 }
1771 
transformFeedbackBitCaptureThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)1772 void MemoryBarrierTestBase::transformFeedbackBitCaptureThenBufferWrite(
1773     ShaderWritePipeline writePipeline,
1774     WriteResource writeResource,
1775     NoopOp preBarrierOp,
1776     NoopOp postBarrierOp,
1777     GLbitfield barrierBit)
1778 {
1779     GLTexture color;
1780     GLFramebuffer fbo;
1781     GLProgram writeProgram;
1782 
1783     createFramebuffer(color, fbo, GLColor::black);
1784 
1785     GLBuffer xfbBuffer;
1786     GLTexture xfbTextureBuffer;
1787     constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
1788     createStorageBuffer(writeResource, xfbBuffer, xfbTextureBuffer, sizeof(kInitData) * 6,
1789                         kInitData.data());
1790 
1791     // Use the buffer
1792     GLProgram xfbProgram;
1793     createXfbVerifyProgram(xfbBuffer, &xfbProgram);
1794 
1795     glBeginTransformFeedback(GL_TRIANGLES);
1796     glDrawArrays(GL_TRIANGLES, 0, 6);
1797     glEndTransformFeedback();
1798     EXPECT_GL_NO_ERROR();
1799 
1800     noopOp(preBarrierOp);
1801 
1802     // Issue the appropriate memory barrier
1803     glMemoryBarrier(barrierBit);
1804 
1805     noopOp(postBarrierOp);
1806 
1807     // Fill the buffer
1808     createProgram(writePipeline, writeResource, &writeProgram);
1809 
1810     GLBuffer positionBuffer;
1811     createQuadVertexArray(positionBuffer);
1812     setupVertexArray(writePipeline, writeProgram);
1813 
1814     constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
1815     setUniformData(writeProgram, kWriteData);
1816 
1817     if (writePipeline == ShaderWritePipeline::Graphics)
1818     {
1819         glEnable(GL_BLEND);
1820         glBlendFunc(GL_ONE, GL_ONE);
1821         glDrawArrays(GL_TRIANGLES, 0, 6);
1822     }
1823     else
1824     {
1825         glDispatchCompute(1, 1, 1);
1826     }
1827 
1828     verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1829 }
1830 
createAtomicCounterVerifyProgram(GLuint buffer,GLProgram * programOut)1831 void MemoryBarrierTestBase::createAtomicCounterVerifyProgram(GLuint buffer, GLProgram *programOut)
1832 {
1833     constexpr char kVS[] = R"(#version 310 es
1834 void main()
1835 {
1836     // gl_VertexID    x    y
1837     //      0        -1   -1
1838     //      1         1   -1
1839     //      2        -1    1
1840     //      3         1    1
1841     int bit0 = gl_VertexID & 1;
1842     int bit1 = gl_VertexID >> 1;
1843     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
1844 })";
1845 
1846     constexpr char kFS[] = R"(#version 310 es
1847 precision mediump float;
1848 layout(binding = 0, offset = 0) uniform atomic_uint ac[4];
1849 out vec4 colorOut;
1850 void main()
1851 {
1852     uvec4 acValue = uvec4(atomicCounterIncrement(ac[0]),
1853                           atomicCounterIncrement(ac[1]),
1854                           atomicCounterIncrement(ac[2]),
1855                           atomicCounterIncrement(ac[3]));
1856 
1857     if (all(equal(acValue, uvec4(10, 20, 30, 40))))
1858         colorOut = vec4(0, 1.0, 0, 1.0);
1859     else
1860         colorOut = vec4(1.0, 0, 0, 1.0);
1861 })";
1862 
1863     programOut->makeRaster(kVS, kFS);
1864     ASSERT_TRUE(programOut->valid());
1865     glUseProgram(*programOut);
1866 
1867     glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, buffer);
1868     glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, buffer);
1869     EXPECT_GL_NO_ERROR();
1870 }
1871 
atomicCounterBitBufferWriteThenAtomic(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)1872 void MemoryBarrierTestBase::atomicCounterBitBufferWriteThenAtomic(ShaderWritePipeline writePipeline,
1873                                                                   WriteResource writeResource,
1874                                                                   NoopOp preBarrierOp,
1875                                                                   NoopOp postBarrierOp)
1876 {
1877     GLTexture color;
1878     GLFramebuffer fbo;
1879     GLProgram writeProgram;
1880 
1881     createFramebuffer(color, fbo, GLColor::black);
1882     createProgram(writePipeline, writeResource, &writeProgram);
1883 
1884     GLBuffer positionBuffer;
1885     createQuadVertexArray(positionBuffer);
1886     setupVertexArray(writePipeline, writeProgram);
1887 
1888     GLBuffer atomicCounterBuffer;
1889     GLTexture atomicCounterTextureBuffer;
1890     constexpr std::array<uint32_t, 4> kInitData = {0x12345678u, 0x9ABCDEF0u, 0x13579BDFu,
1891                                                    0x2468ACE0u};
1892     createStorageBuffer(writeResource, atomicCounterBuffer, atomicCounterTextureBuffer,
1893                         sizeof(kInitData), kInitData.data());
1894 
1895     constexpr std::array<uint32_t, 4> kWriteData = {10, 20, 30, 40};
1896     const std::array<float, 4> kWriteDataAsFloat = {
1897         *reinterpret_cast<const float *>(&kWriteData[0]),
1898         *reinterpret_cast<const float *>(&kWriteData[1]),
1899         *reinterpret_cast<const float *>(&kWriteData[2]),
1900         *reinterpret_cast<const float *>(&kWriteData[3]),
1901     };
1902     setUniformData(writeProgram, kWriteDataAsFloat);
1903 
1904     // Fill the buffer
1905     if (writePipeline == ShaderWritePipeline::Graphics)
1906     {
1907         glDrawArrays(GL_TRIANGLES, 0, 6);
1908     }
1909     else
1910     {
1911         glDispatchCompute(1, 1, 1);
1912     }
1913 
1914     noopOp(preBarrierOp);
1915 
1916     // Issue the appropriate memory barrier
1917     glMemoryBarrier(GL_ATOMIC_COUNTER_BARRIER_BIT);
1918 
1919     noopOp(postBarrierOp);
1920 
1921     // Use the buffer
1922     GLProgram readProgram;
1923     createAtomicCounterVerifyProgram(atomicCounterBuffer, &readProgram);
1924 
1925     glEnable(GL_BLEND);
1926     glBlendFunc(GL_ONE, GL_ONE);
1927     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1928     EXPECT_GL_NO_ERROR();
1929 
1930     constexpr std::array<uint32_t, 4> kExpectedData = {11, 21, 31, 41};
1931     verifyFramebufferAndBufferContents(writePipeline, kExpectedData);
1932 }
1933 
atomicCounterBitAtomicThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)1934 void MemoryBarrierTestBase::atomicCounterBitAtomicThenBufferWrite(ShaderWritePipeline writePipeline,
1935                                                                   WriteResource writeResource,
1936                                                                   NoopOp preBarrierOp,
1937                                                                   NoopOp postBarrierOp,
1938                                                                   GLbitfield barrierBit)
1939 {
1940     GLTexture color;
1941     GLFramebuffer fbo;
1942     GLProgram writeProgram;
1943 
1944     createFramebuffer(color, fbo, GLColor::black);
1945 
1946     GLBuffer atomicCounterBuffer;
1947     GLTexture atomicCounterTextureBuffer;
1948     constexpr std::array<uint32_t, 4> kInitData = {10, 20, 30, 40};
1949     createStorageBuffer(writeResource, atomicCounterBuffer, atomicCounterTextureBuffer,
1950                         sizeof(kInitData), kInitData.data());
1951 
1952     // Use the buffer
1953     GLProgram readProgram;
1954     createAtomicCounterVerifyProgram(atomicCounterBuffer, &readProgram);
1955 
1956     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1957     EXPECT_GL_NO_ERROR();
1958 
1959     noopOp(preBarrierOp);
1960 
1961     // Issue the appropriate memory barrier
1962     glMemoryBarrier(barrierBit);
1963 
1964     noopOp(postBarrierOp);
1965 
1966     // Fill the buffer
1967     createProgram(writePipeline, writeResource, &writeProgram);
1968 
1969     GLBuffer positionBuffer;
1970     createQuadVertexArray(positionBuffer);
1971     setupVertexArray(writePipeline, writeProgram);
1972 
1973     constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
1974     setUniformData(writeProgram, kWriteData);
1975 
1976     if (writePipeline == ShaderWritePipeline::Graphics)
1977     {
1978         glEnable(GL_BLEND);
1979         glBlendFunc(GL_ONE, GL_ONE);
1980         glDrawArrays(GL_TRIANGLES, 0, 6);
1981     }
1982     else
1983     {
1984         glDispatchCompute(1, 1, 1);
1985     }
1986 
1987     verifyFramebufferAndBufferContents(writePipeline, kWriteData);
1988 }
1989 
createSsboVerifyProgram(WriteResource writeResource,GLProgram * programOut)1990 void MemoryBarrierTestBase::createSsboVerifyProgram(WriteResource writeResource,
1991                                                     GLProgram *programOut)
1992 {
1993     constexpr char kVS[] = R"(#version 310 es
1994 void main()
1995 {
1996     // gl_VertexID    x    y
1997     //      0        -1   -1
1998     //      1         1   -1
1999     //      2        -1    1
2000     //      3         1    1
2001     int bit0 = gl_VertexID & 1;
2002     int bit1 = gl_VertexID >> 1;
2003     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
2004 })";
2005 
2006     constexpr char kFS[] = R"(#version 310 es
2007 precision mediump float;
2008 layout(std430, binding = 0) buffer block {
2009     vec4 data;
2010 } inBlock;
2011 out vec4 colorOut;
2012 void main()
2013 {
2014     if (all(lessThan(abs(inBlock.data - vec4(1.5, 3.75, 5.0, 12.125)), vec4(0.01))))
2015         colorOut = vec4(0, 1.0, 0, 1.0);
2016     else
2017         colorOut = vec4(1.0, 0, 0, 1.0);
2018 })";
2019 
2020     programOut->makeRaster(kVS, kFS);
2021     ASSERT_TRUE(programOut->valid());
2022     glUseProgram(*programOut);
2023 }
2024 
shaderStorageBitBufferWriteThenBufferRead(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2025 void MemoryBarrierTestBase::shaderStorageBitBufferWriteThenBufferRead(
2026     ShaderWritePipeline writePipeline,
2027     WriteResource writeResource,
2028     NoopOp preBarrierOp,
2029     NoopOp postBarrierOp)
2030 {
2031     GLTexture color;
2032     GLFramebuffer fbo;
2033     GLProgram writeProgram;
2034 
2035     createFramebuffer(color, fbo, GLColor::black);
2036     createProgram(writePipeline, writeResource, &writeProgram);
2037 
2038     GLBuffer positionBuffer;
2039     createQuadVertexArray(positionBuffer);
2040     setupVertexArray(writePipeline, writeProgram);
2041 
2042     GLBuffer writeBuffer;
2043     GLTexture writeTextureBuffer;
2044     constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
2045     createStorageBuffer(writeResource, writeBuffer, writeTextureBuffer, sizeof(kInitData),
2046                         kInitData.data());
2047 
2048     constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
2049     setUniformData(writeProgram, kWriteData);
2050 
2051     // Fill the buffer
2052     if (writePipeline == ShaderWritePipeline::Graphics)
2053     {
2054         glDrawArrays(GL_TRIANGLES, 0, 6);
2055     }
2056     else
2057     {
2058         glDispatchCompute(1, 1, 1);
2059     }
2060 
2061     noopOp(preBarrierOp);
2062 
2063     // Issue the appropriate memory barrier
2064     glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
2065 
2066     noopOp(postBarrierOp);
2067 
2068     // Use the buffer
2069     GLProgram readProgram;
2070     createSsboVerifyProgram(writeResource, &readProgram);
2071 
2072     glEnable(GL_BLEND);
2073     glBlendFunc(GL_ONE, GL_ONE);
2074     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2075     EXPECT_GL_NO_ERROR();
2076 
2077     verifyFramebufferAndBufferContents(writePipeline, kWriteData);
2078 }
2079 
shaderStorageBitBufferReadThenBufferWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)2080 void MemoryBarrierTestBase::shaderStorageBitBufferReadThenBufferWrite(
2081     ShaderWritePipeline writePipeline,
2082     WriteResource writeResource,
2083     NoopOp preBarrierOp,
2084     NoopOp postBarrierOp,
2085     GLbitfield barrierBit)
2086 {
2087     GLTexture color;
2088     GLFramebuffer fbo;
2089     GLProgram writeProgram;
2090 
2091     createFramebuffer(color, fbo, GLColor::black);
2092 
2093     GLBuffer writeBuffer;
2094     GLTexture writeTextureBuffer;
2095     constexpr std::array<float, 4> kInitData = {1.5, 3.75, 5.0, 12.125};
2096     createStorageBuffer(writeResource, writeBuffer, writeTextureBuffer, sizeof(kInitData),
2097                         kInitData.data());
2098 
2099     // Use the buffer
2100     GLProgram readProgram;
2101     createSsboVerifyProgram(writeResource, &readProgram);
2102 
2103     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2104     EXPECT_GL_NO_ERROR();
2105 
2106     noopOp(preBarrierOp);
2107 
2108     // Issue the appropriate memory barrier
2109     glMemoryBarrier(barrierBit);
2110 
2111     noopOp(postBarrierOp);
2112 
2113     // Fill the image
2114     createProgram(writePipeline, writeResource, &writeProgram);
2115 
2116     GLBuffer positionBuffer;
2117     createQuadVertexArray(positionBuffer);
2118     setupVertexArray(writePipeline, writeProgram);
2119 
2120     constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
2121     setUniformData(writeProgram, kWriteData);
2122 
2123     if (writePipeline == ShaderWritePipeline::Graphics)
2124     {
2125         glEnable(GL_BLEND);
2126         glBlendFunc(GL_ONE, GL_ONE);
2127         glDrawArrays(GL_TRIANGLES, 0, 6);
2128     }
2129     else
2130     {
2131         glDispatchCompute(1, 1, 1);
2132     }
2133 
2134     verifyFramebufferAndBufferContents(writePipeline, kWriteData);
2135 }
2136 
createTextureVerifyProgram(WriteResource writeResource,GLuint texture,GLProgram * programOut)2137 void MemoryBarrierTestBase::createTextureVerifyProgram(WriteResource writeResource,
2138                                                        GLuint texture,
2139                                                        GLProgram *programOut)
2140 {
2141     constexpr char kVS[] = R"(#version 310 es
2142 void main()
2143 {
2144     // gl_VertexID    x    y
2145     //      0        -1   -1
2146     //      1         1   -1
2147     //      2        -1    1
2148     //      3         1    1
2149     int bit0 = gl_VertexID & 1;
2150     int bit1 = gl_VertexID >> 1;
2151     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
2152 })";
2153 
2154     constexpr char kImageFS[] = R"(#version 310 es
2155 precision mediump float;
2156 uniform sampler2D s;
2157 out vec4 colorOut;
2158 void main()
2159 {
2160     if (all(lessThan(abs(texelFetch(s, ivec2(0, 0), 0)- vec4(0.125, 0.25, 0.5, 0.75)), vec4(0.01))))
2161         colorOut = vec4(0, 1.0, 0, 1.0);
2162     else
2163         colorOut = vec4(1.0, 0, 0, 1.0);
2164 })";
2165 
2166     constexpr char kImageBufferFS[] = R"(#version 310 es
2167 #extension GL_OES_texture_buffer : require
2168 precision mediump float;
2169 uniform highp samplerBuffer s;
2170 out vec4 colorOut;
2171 void main()
2172 {
2173     if (texelFetch(s, 0) == vec4(0.125, 0.25, 0.5, 0.75))
2174         colorOut = vec4(0, 1.0, 0, 1.0);
2175     else
2176         colorOut = vec4(1.0, 0, 0, 1.0);
2177 })";
2178 
2179     programOut->makeRaster(kVS,
2180                            writeResource == WriteResource::ImageBuffer ? kImageBufferFS : kImageFS);
2181     ASSERT_TRUE(programOut->valid());
2182     glUseProgram(*programOut);
2183 
2184     glBindTexture(writeResource == WriteResource::ImageBuffer ? GL_TEXTURE_BUFFER : GL_TEXTURE_2D,
2185                   texture);
2186     EXPECT_GL_NO_ERROR();
2187 }
2188 
textureFetchBitImageWriteThenSamplerRead(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2189 void MemoryBarrierTestBase::textureFetchBitImageWriteThenSamplerRead(
2190     ShaderWritePipeline writePipeline,
2191     WriteResource writeResource,
2192     NoopOp preBarrierOp,
2193     NoopOp postBarrierOp)
2194 {
2195     GLTexture color;
2196     GLFramebuffer fbo;
2197     GLProgram writeProgram;
2198 
2199     createFramebuffer(color, fbo, GLColor::black);
2200     createProgram(writePipeline, writeResource, &writeProgram);
2201 
2202     GLBuffer positionBuffer;
2203     createQuadVertexArray(positionBuffer);
2204     setupVertexArray(writePipeline, writeProgram);
2205 
2206     GLBuffer textureBufferStorage;
2207     GLTexture texture;
2208     constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2209     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2210 
2211     constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2212     setUniformData(writeProgram, kWriteData);
2213 
2214     // Fill the image
2215     if (writePipeline == ShaderWritePipeline::Graphics)
2216     {
2217         glDrawArrays(GL_TRIANGLES, 0, 6);
2218     }
2219     else
2220     {
2221         glDispatchCompute(1, 1, 1);
2222     }
2223 
2224     noopOp(preBarrierOp);
2225 
2226     // Issue the appropriate memory barrier
2227     glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
2228 
2229     noopOp(postBarrierOp);
2230 
2231     // Use the image
2232     GLProgram readProgram;
2233     createTextureVerifyProgram(writeResource, texture, &readProgram);
2234 
2235     glEnable(GL_BLEND);
2236     glBlendFunc(GL_ONE, GL_ONE);
2237     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2238     EXPECT_GL_NO_ERROR();
2239 
2240     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2241 }
2242 
textureFetchBitSamplerReadThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)2243 void MemoryBarrierTestBase::textureFetchBitSamplerReadThenImageWrite(
2244     ShaderWritePipeline writePipeline,
2245     WriteResource writeResource,
2246     NoopOp preBarrierOp,
2247     NoopOp postBarrierOp,
2248     GLbitfield barrierBit)
2249 {
2250     GLTexture color;
2251     GLFramebuffer fbo;
2252     GLProgram writeProgram;
2253 
2254     createFramebuffer(color, fbo, GLColor::black);
2255 
2256     GLBuffer textureBufferStorage;
2257     GLTexture texture;
2258     constexpr std::array<float, 4> kInitData = {0.125, 0.25, 0.5, 0.75};
2259     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2260 
2261     // Use the image
2262     GLProgram readProgram;
2263     createTextureVerifyProgram(writeResource, texture, &readProgram);
2264 
2265     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2266     EXPECT_GL_NO_ERROR();
2267 
2268     noopOp(preBarrierOp);
2269 
2270     // Issue the appropriate memory barrier
2271     glMemoryBarrier(barrierBit);
2272 
2273     noopOp(postBarrierOp);
2274 
2275     // Fill the image
2276     createProgram(writePipeline, writeResource, &writeProgram);
2277 
2278     GLBuffer positionBuffer;
2279     createQuadVertexArray(positionBuffer);
2280     setupVertexArray(writePipeline, writeProgram);
2281 
2282     constexpr std::array<float, 4> kWriteData = {0.65, 0.20, 0.40, 0.95};
2283     setUniformData(writeProgram, kWriteData);
2284 
2285     if (writePipeline == ShaderWritePipeline::Graphics)
2286     {
2287         glEnable(GL_BLEND);
2288         glBlendFunc(GL_ONE, GL_ONE);
2289         glDrawArrays(GL_TRIANGLES, 0, 6);
2290     }
2291     else
2292     {
2293         glDispatchCompute(1, 1, 1);
2294     }
2295 
2296     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2297 }
2298 
createImageVerifyProgram(WriteResource writeResource,GLuint texture,GLProgram * programOut)2299 void MemoryBarrierTestBase::createImageVerifyProgram(WriteResource writeResource,
2300                                                      GLuint texture,
2301                                                      GLProgram *programOut)
2302 {
2303     constexpr char kVS[] = R"(#version 310 es
2304 void main()
2305 {
2306     // gl_VertexID    x    y
2307     //      0        -1   -1
2308     //      1         1   -1
2309     //      2        -1    1
2310     //      3         1    1
2311     int bit0 = gl_VertexID & 1;
2312     int bit1 = gl_VertexID >> 1;
2313     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
2314 })";
2315 
2316     constexpr char kImageFS[] = R"(#version 310 es
2317 precision mediump float;
2318 layout(rgba8, binding = 0) uniform highp readonly image2D img;
2319 out vec4 colorOut;
2320 void main()
2321 {
2322     if (all(lessThan(abs(imageLoad(img, ivec2(0, 0))- vec4(0.125, 0.25, 0.5, 0.75)), vec4(0.01))))
2323         colorOut = vec4(0, 1.0, 0, 1.0);
2324     else
2325         colorOut = vec4(1.0, 0, 0, 1.0);
2326 })";
2327 
2328     constexpr char kImageBufferFS[] = R"(#version 310 es
2329 #extension GL_OES_texture_buffer : require
2330 precision mediump float;
2331 layout(rgba32f, binding = 0) uniform highp readonly imageBuffer img;
2332 out vec4 colorOut;
2333 void main()
2334 {
2335     if (imageLoad(img, 0) == vec4(0.125, 0.25, 0.5, 0.75))
2336         colorOut = vec4(0, 1.0, 0, 1.0);
2337     else
2338         colorOut = vec4(1.0, 0, 0, 1.0);
2339 })";
2340 
2341     programOut->makeRaster(kVS,
2342                            writeResource == WriteResource::ImageBuffer ? kImageBufferFS : kImageFS);
2343     ASSERT_TRUE(programOut->valid());
2344     glUseProgram(*programOut);
2345 
2346     if (writeResource == WriteResource::ImageBuffer)
2347     {
2348         glBindTexture(GL_TEXTURE_BUFFER, texture);
2349         glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
2350     }
2351     else
2352     {
2353         glBindTexture(GL_TEXTURE_2D, texture);
2354         glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
2355     }
2356     EXPECT_GL_NO_ERROR();
2357 }
2358 
shaderImageAccessBitImageWriteThenImageRead(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2359 void MemoryBarrierTestBase::shaderImageAccessBitImageWriteThenImageRead(
2360     ShaderWritePipeline writePipeline,
2361     WriteResource writeResource,
2362     NoopOp preBarrierOp,
2363     NoopOp postBarrierOp)
2364 {
2365     GLTexture color;
2366     GLFramebuffer fbo;
2367     GLProgram writeProgram;
2368 
2369     createFramebuffer(color, fbo, GLColor::black);
2370     createProgram(writePipeline, writeResource, &writeProgram);
2371 
2372     GLBuffer positionBuffer;
2373     createQuadVertexArray(positionBuffer);
2374     setupVertexArray(writePipeline, writeProgram);
2375 
2376     GLBuffer textureBufferStorage;
2377     GLTexture texture;
2378     constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2379     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2380 
2381     constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2382     setUniformData(writeProgram, kWriteData);
2383 
2384     // Fill the image
2385     if (writePipeline == ShaderWritePipeline::Graphics)
2386     {
2387         glDrawArrays(GL_TRIANGLES, 0, 6);
2388     }
2389     else
2390     {
2391         glDispatchCompute(1, 1, 1);
2392     }
2393 
2394     noopOp(preBarrierOp);
2395 
2396     // Issue the appropriate memory barrier
2397     glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
2398 
2399     noopOp(postBarrierOp);
2400 
2401     // Use the image
2402     GLProgram readProgram;
2403     createImageVerifyProgram(writeResource, texture, &readProgram);
2404 
2405     glEnable(GL_BLEND);
2406     glBlendFunc(GL_ONE, GL_ONE);
2407     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2408     EXPECT_GL_NO_ERROR();
2409 
2410     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2411 }
2412 
shaderImageAccessBitImageReadThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2413 void MemoryBarrierTestBase::shaderImageAccessBitImageReadThenImageWrite(
2414     ShaderWritePipeline writePipeline,
2415     WriteResource writeResource,
2416     NoopOp preBarrierOp,
2417     NoopOp postBarrierOp)
2418 {
2419     GLTexture color;
2420     GLFramebuffer fbo;
2421     GLProgram writeProgram;
2422 
2423     createFramebuffer(color, fbo, GLColor::black);
2424 
2425     GLBuffer textureBufferStorage;
2426     GLTexture texture;
2427     constexpr std::array<float, 4> kInitData = {0.125, 0.25, 0.5, 0.75};
2428     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2429 
2430     // Use the image
2431     GLProgram readProgram;
2432     createImageVerifyProgram(writeResource, texture, &readProgram);
2433 
2434     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
2435     EXPECT_GL_NO_ERROR();
2436 
2437     noopOp(preBarrierOp);
2438 
2439     // Issue the appropriate memory barrier
2440     glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
2441 
2442     noopOp(postBarrierOp);
2443 
2444     // Fill the image
2445     createProgram(writePipeline, writeResource, &writeProgram);
2446 
2447     GLBuffer positionBuffer;
2448     createQuadVertexArray(positionBuffer);
2449     setupVertexArray(writePipeline, writeProgram);
2450 
2451     constexpr std::array<float, 4> kWriteData = {0.65, 0.20, 0.40, 0.95};
2452     setUniformData(writeProgram, kWriteData);
2453 
2454     if (writePipeline == ShaderWritePipeline::Graphics)
2455     {
2456         glEnable(GL_BLEND);
2457         glBlendFunc(GL_ONE, GL_ONE);
2458         glDrawArrays(GL_TRIANGLES, 0, 6);
2459     }
2460     else
2461     {
2462         glDispatchCompute(1, 1, 1);
2463     }
2464 
2465     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2466 }
2467 
textureUpdateBitImageWriteThenCopy(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2468 void MemoryBarrierTestBase::textureUpdateBitImageWriteThenCopy(ShaderWritePipeline writePipeline,
2469                                                                WriteResource writeResource,
2470                                                                NoopOp preBarrierOp,
2471                                                                NoopOp postBarrierOp)
2472 {
2473     GLTexture color;
2474     GLFramebuffer fbo;
2475     GLProgram writeProgram;
2476 
2477     createFramebuffer(color, fbo, GLColor::green);
2478     createProgram(writePipeline, writeResource, &writeProgram);
2479 
2480     GLBuffer positionBuffer;
2481     createQuadVertexArray(positionBuffer);
2482     setupVertexArray(writePipeline, writeProgram);
2483 
2484     GLBuffer textureBufferStorage;
2485     GLTexture texture;
2486     constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2487     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2488 
2489     constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2490     setUniformData(writeProgram, kWriteData);
2491 
2492     // Fill the image
2493     if (writePipeline == ShaderWritePipeline::Graphics)
2494     {
2495         glEnable(GL_BLEND);
2496         glBlendFunc(GL_ONE, GL_ONE);
2497         glDrawArrays(GL_TRIANGLES, 0, 6);
2498         glDisable(GL_BLEND);
2499     }
2500     else
2501     {
2502         glDispatchCompute(1, 1, 1);
2503     }
2504 
2505     noopOp(preBarrierOp);
2506 
2507     // Issue the appropriate memory barrier
2508     glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
2509 
2510     noopOp(postBarrierOp);
2511 
2512     // Copy from framebuffer over the texture
2513     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kTextureSize, kTextureSize);
2514 
2515     const std::array<float, 4> kExpectedData = {
2516         0, 1.0f, writePipeline == ShaderWritePipeline::Graphics ? 1.0f : 0, 1.0f};
2517     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kExpectedData);
2518 }
2519 
textureUpdateBitCopyThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)2520 void MemoryBarrierTestBase::textureUpdateBitCopyThenImageWrite(ShaderWritePipeline writePipeline,
2521                                                                WriteResource writeResource,
2522                                                                NoopOp preBarrierOp,
2523                                                                NoopOp postBarrierOp,
2524                                                                GLbitfield barrierBit)
2525 {
2526     GLTexture color;
2527     GLFramebuffer fbo;
2528     GLProgram writeProgram;
2529 
2530     createFramebuffer(color, fbo, GLColor::green);
2531 
2532     GLBuffer textureBufferStorage;
2533     GLTexture texture;
2534     constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2535     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2536 
2537     // Copy from framebuffer over the texture
2538     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kTextureSize, kTextureSize);
2539 
2540     noopOp(preBarrierOp);
2541 
2542     // Issue the appropriate memory barrier
2543     glMemoryBarrier(barrierBit);
2544 
2545     noopOp(postBarrierOp);
2546 
2547     // Fill the image
2548     createProgram(writePipeline, writeResource, &writeProgram);
2549 
2550     GLBuffer positionBuffer;
2551     createQuadVertexArray(positionBuffer);
2552     setupVertexArray(writePipeline, writeProgram);
2553 
2554     constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2555     setUniformData(writeProgram, kWriteData);
2556 
2557     if (writePipeline == ShaderWritePipeline::Graphics)
2558     {
2559         glEnable(GL_BLEND);
2560         glBlendFunc(GL_ONE, GL_ONE);
2561         glDrawArrays(GL_TRIANGLES, 0, 6);
2562     }
2563     else
2564     {
2565         glDispatchCompute(1, 1, 1);
2566     }
2567 
2568     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2569 }
2570 
framebufferBitImageWriteThenDraw(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2571 void MemoryBarrierTestBase::framebufferBitImageWriteThenDraw(ShaderWritePipeline writePipeline,
2572                                                              WriteResource writeResource,
2573                                                              NoopOp preBarrierOp,
2574                                                              NoopOp postBarrierOp)
2575 {
2576     GLTexture color;
2577     GLFramebuffer fbo;
2578     GLProgram writeProgram;
2579 
2580     createFramebuffer(color, fbo, GLColor::green);
2581     createProgram(writePipeline, writeResource, &writeProgram);
2582 
2583     GLBuffer positionBuffer;
2584     createQuadVertexArray(positionBuffer);
2585     setupVertexArray(writePipeline, writeProgram);
2586 
2587     GLBuffer textureBufferStorage;
2588     GLTexture texture;
2589     constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2590     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2591 
2592     constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2593     setUniformData(writeProgram, kWriteData);
2594 
2595     // Fill the image
2596     if (writePipeline == ShaderWritePipeline::Graphics)
2597     {
2598         glEnable(GL_BLEND);
2599         glBlendFunc(GL_ONE, GL_ONE);
2600         glDrawArrays(GL_TRIANGLES, 0, 6);
2601         glDisable(GL_BLEND);
2602     }
2603     else
2604     {
2605         glDispatchCompute(1, 1, 1);
2606     }
2607 
2608     noopOp(preBarrierOp);
2609 
2610     // Issue the appropriate memory barrier
2611     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
2612 
2613     noopOp(postBarrierOp);
2614 
2615     // Draw to image via framebuffer
2616     ANGLE_GL_PROGRAM(verifyProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
2617     glUseProgram(verifyProgram);
2618     GLint colorUniformLocation =
2619         glGetUniformLocation(verifyProgram, angle::essl1_shaders::ColorUniform());
2620     ASSERT_NE(colorUniformLocation, -1);
2621     setupVertexArray(ShaderWritePipeline::Graphics, verifyProgram);
2622 
2623     GLFramebuffer drawFbo;
2624     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFbo);
2625     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2626     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
2627 
2628     constexpr std::array<float, 4> kBlendData = {0.125, 0.25, 0.5, 0.25};
2629     glUniform4fv(colorUniformLocation, 1, kBlendData.data());
2630 
2631     glEnable(GL_BLEND);
2632     glBlendFunc(GL_ONE, GL_ONE);
2633     glDrawArrays(GL_TRIANGLES, 0, 6);
2634     glDisable(GL_BLEND);
2635     EXPECT_GL_NO_ERROR();
2636 
2637     const std::array<float, 4> kExpectedData = {
2638         kWriteData[0] + kBlendData[0],
2639         kWriteData[1] + kBlendData[1],
2640         kWriteData[2] + kBlendData[2],
2641         kWriteData[3] + kBlendData[3],
2642     };
2643     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kExpectedData);
2644 }
2645 
framebufferBitImageWriteThenReadPixels(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2646 void MemoryBarrierTestBase::framebufferBitImageWriteThenReadPixels(
2647     ShaderWritePipeline writePipeline,
2648     WriteResource writeResource,
2649     NoopOp preBarrierOp,
2650     NoopOp postBarrierOp)
2651 {
2652     GLTexture color;
2653     GLFramebuffer fbo;
2654     GLProgram writeProgram;
2655 
2656     createFramebuffer(color, fbo, GLColor::green);
2657     createProgram(writePipeline, writeResource, &writeProgram);
2658 
2659     GLBuffer positionBuffer;
2660     createQuadVertexArray(positionBuffer);
2661     setupVertexArray(writePipeline, writeProgram);
2662 
2663     GLBuffer textureBufferStorage;
2664     GLTexture texture;
2665     constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2666     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2667 
2668     constexpr std::array<float, 4> kWriteData = {1.0, 1.0, 0.0, 1.0};
2669     setUniformData(writeProgram, kWriteData);
2670 
2671     // Fill the image
2672     if (writePipeline == ShaderWritePipeline::Graphics)
2673     {
2674         glEnable(GL_BLEND);
2675         glBlendFunc(GL_ONE, GL_ONE);
2676         glDrawArrays(GL_TRIANGLES, 0, 6);
2677         glDisable(GL_BLEND);
2678     }
2679     else
2680     {
2681         glDispatchCompute(1, 1, 1);
2682     }
2683 
2684     noopOp(preBarrierOp);
2685 
2686     // Issue the appropriate memory barrier
2687     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
2688 
2689     noopOp(postBarrierOp);
2690 
2691     // Read from image via framebuffer
2692     GLBuffer packBuffer;
2693     glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
2694     constexpr std::array<uint32_t, 4> kPBOInitData = {0x12345678u, 0x9ABCDEF0u, 0x13579BDFu,
2695                                                       0x2468ACE0u};
2696     glBufferData(GL_PIXEL_PACK_BUFFER, sizeof(kInitData), kPBOInitData.data(), GL_STATIC_DRAW);
2697     EXPECT_GL_NO_ERROR();
2698 
2699     GLFramebuffer readFbo;
2700     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
2701     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2702     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
2703 
2704     glReadPixels(0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2705     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2706     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
2707     EXPECT_GL_NO_ERROR();
2708 
2709     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2710 
2711     // Verify the PBO for completeness
2712     glBindBuffer(GL_SHADER_STORAGE_BUFFER, packBuffer);
2713     constexpr std::array<uint32_t, 4> kExpectedData = {
2714         0xFF00FFFFu,
2715         kPBOInitData[1],
2716         kPBOInitData[2],
2717         kPBOInitData[3],
2718     };
2719     verifyBufferContents(kExpectedData);
2720 }
2721 
framebufferBitImageWriteThenCopy(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2722 void MemoryBarrierTestBase::framebufferBitImageWriteThenCopy(ShaderWritePipeline writePipeline,
2723                                                              WriteResource writeResource,
2724                                                              NoopOp preBarrierOp,
2725                                                              NoopOp postBarrierOp)
2726 {
2727     GLTexture color;
2728     GLFramebuffer fbo;
2729     GLProgram writeProgram;
2730 
2731     createFramebuffer(color, fbo, GLColor::green);
2732     createProgram(writePipeline, writeResource, &writeProgram);
2733 
2734     GLBuffer positionBuffer;
2735     createQuadVertexArray(positionBuffer);
2736     setupVertexArray(writePipeline, writeProgram);
2737 
2738     GLBuffer textureBufferStorage;
2739     GLTexture texture;
2740     constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2741     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2742 
2743     constexpr std::array<float, 4> kWriteData = {1.0, 1.0, 0.0, 1.0};
2744     setUniformData(writeProgram, kWriteData);
2745 
2746     // Fill the image
2747     if (writePipeline == ShaderWritePipeline::Graphics)
2748     {
2749         glEnable(GL_BLEND);
2750         glBlendFunc(GL_ONE, GL_ONE);
2751         glDrawArrays(GL_TRIANGLES, 0, 6);
2752         glDisable(GL_BLEND);
2753     }
2754     else
2755     {
2756         glDispatchCompute(1, 1, 1);
2757     }
2758 
2759     noopOp(preBarrierOp);
2760 
2761     // Issue the appropriate memory barrier
2762     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
2763 
2764     noopOp(postBarrierOp);
2765 
2766     // Copy from framebuffer to another texture
2767     GLFramebuffer readFbo;
2768     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
2769     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2770     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
2771 
2772     GLTexture copyTexture;
2773     glBindTexture(GL_TEXTURE_2D, copyTexture);
2774     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureSize, kTextureSize);
2775     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kTextureSize, kTextureSize);
2776 
2777     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2778     EXPECT_GL_NO_ERROR();
2779 
2780     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2781 
2782     // Verify the copy texture for completeness
2783     verifyImageContents(copyTexture, kWriteData);
2784 }
2785 
framebufferBitImageWriteThenBlit(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp)2786 void MemoryBarrierTestBase::framebufferBitImageWriteThenBlit(ShaderWritePipeline writePipeline,
2787                                                              WriteResource writeResource,
2788                                                              NoopOp preBarrierOp,
2789                                                              NoopOp postBarrierOp)
2790 {
2791     GLTexture blitColor;
2792     GLFramebuffer blitFbo;
2793     createFramebuffer(blitColor, blitFbo, GLColor::black);
2794 
2795     GLTexture color;
2796     GLFramebuffer fbo;
2797     GLProgram writeProgram;
2798 
2799     createFramebuffer(color, fbo, GLColor::green);
2800     createProgram(writePipeline, writeResource, &writeProgram);
2801 
2802     GLBuffer positionBuffer;
2803     createQuadVertexArray(positionBuffer);
2804     setupVertexArray(writePipeline, writeProgram);
2805 
2806     GLBuffer textureBufferStorage;
2807     GLTexture texture;
2808     constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2809     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2810 
2811     constexpr std::array<float, 4> kWriteData = {1.0, 1.0, 0.0, 1.0};
2812     setUniformData(writeProgram, kWriteData);
2813 
2814     // Fill the image
2815     if (writePipeline == ShaderWritePipeline::Graphics)
2816     {
2817         glEnable(GL_BLEND);
2818         glBlendFunc(GL_ONE, GL_ONE);
2819         glDrawArrays(GL_TRIANGLES, 0, 6);
2820         glDisable(GL_BLEND);
2821     }
2822     else
2823     {
2824         glDispatchCompute(1, 1, 1);
2825     }
2826 
2827     noopOp(preBarrierOp);
2828 
2829     // Issue the appropriate memory barrier
2830     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
2831 
2832     noopOp(postBarrierOp);
2833 
2834     // Blit from framebuffer to another framebuffer
2835     GLFramebuffer readFbo;
2836     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
2837     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2838     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
2839 
2840     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, blitFbo);
2841     glBlitFramebuffer(0, 0, kTextureSize, kTextureSize, 0, 0, kTextureSize, kTextureSize,
2842                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
2843     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2844     EXPECT_GL_NO_ERROR();
2845 
2846     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2847 
2848     // Verify the blit fbo for completeness
2849     glBindFramebuffer(GL_READ_FRAMEBUFFER, blitFbo);
2850     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
2851 }
2852 
framebufferBitDrawThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)2853 void MemoryBarrierTestBase::framebufferBitDrawThenImageWrite(ShaderWritePipeline writePipeline,
2854                                                              WriteResource writeResource,
2855                                                              NoopOp preBarrierOp,
2856                                                              NoopOp postBarrierOp,
2857                                                              GLbitfield barrierBit)
2858 {
2859     GLTexture color;
2860     GLFramebuffer fbo;
2861     GLProgram writeProgram;
2862 
2863     createFramebuffer(color, fbo, GLColor::green);
2864 
2865     GLBuffer textureBufferStorage;
2866     GLTexture texture;
2867     constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
2868     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2869 
2870     // Draw to image via framebuffer
2871     ANGLE_GL_PROGRAM(verifyProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
2872     glUseProgram(verifyProgram);
2873 
2874     GLBuffer positionBuffer;
2875     createQuadVertexArray(positionBuffer);
2876     setupVertexArray(ShaderWritePipeline::Graphics, verifyProgram);
2877 
2878     GLFramebuffer drawFbo;
2879     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFbo);
2880     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2881     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
2882 
2883     glDrawArrays(GL_TRIANGLES, 0, 6);
2884     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
2885     EXPECT_GL_NO_ERROR();
2886 
2887     noopOp(preBarrierOp);
2888 
2889     // Issue the appropriate memory barrier
2890     glMemoryBarrier(barrierBit);
2891 
2892     noopOp(postBarrierOp);
2893 
2894     // Fill the image
2895     createProgram(writePipeline, writeResource, &writeProgram);
2896 
2897     setupVertexArray(writePipeline, writeProgram);
2898 
2899     constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2900     setUniformData(writeProgram, kWriteData);
2901 
2902     if (writePipeline == ShaderWritePipeline::Graphics)
2903     {
2904         glEnable(GL_BLEND);
2905         glBlendFunc(GL_ONE, GL_ONE);
2906         glDrawArrays(GL_TRIANGLES, 0, 6);
2907     }
2908     else
2909     {
2910         glDispatchCompute(1, 1, 1);
2911     }
2912 
2913     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2914 }
2915 
framebufferBitReadPixelsThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)2916 void MemoryBarrierTestBase::framebufferBitReadPixelsThenImageWrite(
2917     ShaderWritePipeline writePipeline,
2918     WriteResource writeResource,
2919     NoopOp preBarrierOp,
2920     NoopOp postBarrierOp,
2921     GLbitfield barrierBit)
2922 {
2923     GLTexture color;
2924     GLFramebuffer fbo;
2925     GLProgram writeProgram;
2926 
2927     createFramebuffer(color, fbo, GLColor::green);
2928 
2929     GLBuffer textureBufferStorage;
2930     GLTexture texture;
2931     constexpr std::array<float, 4> kInitData = {1.0, 1.0, 0.0, 1.0};
2932     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
2933 
2934     // Read from image via framebuffer
2935     GLBuffer packBuffer;
2936     glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
2937     constexpr std::array<uint32_t, 4> kPBOInitData = {0x12345678u, 0x9ABCDEF0u, 0x13579BDFu,
2938                                                       0x2468ACE0u};
2939     glBufferData(GL_PIXEL_PACK_BUFFER, sizeof(kInitData), kPBOInitData.data(), GL_STATIC_DRAW);
2940     EXPECT_GL_NO_ERROR();
2941 
2942     GLFramebuffer readFbo;
2943     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
2944     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
2945     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
2946 
2947     glReadPixels(0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2948     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2949     glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
2950     EXPECT_GL_NO_ERROR();
2951 
2952     noopOp(preBarrierOp);
2953 
2954     // Issue the appropriate memory barrier
2955     glMemoryBarrier(barrierBit);
2956 
2957     noopOp(postBarrierOp);
2958 
2959     // Fill the image
2960     createProgram(writePipeline, writeResource, &writeProgram);
2961 
2962     GLBuffer positionBuffer;
2963     createQuadVertexArray(positionBuffer);
2964     setupVertexArray(writePipeline, writeProgram);
2965 
2966     constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
2967     setUniformData(writeProgram, kWriteData);
2968 
2969     if (writePipeline == ShaderWritePipeline::Graphics)
2970     {
2971         glEnable(GL_BLEND);
2972         glBlendFunc(GL_ONE, GL_ONE);
2973         glDrawArrays(GL_TRIANGLES, 0, 6);
2974     }
2975     else
2976     {
2977         glDispatchCompute(1, 1, 1);
2978     }
2979 
2980     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
2981 
2982     // Verify the PBO for completeness
2983     glBindBuffer(GL_SHADER_STORAGE_BUFFER, packBuffer);
2984     constexpr std::array<uint32_t, 4> kExpectedData = {
2985         0xFF00FFFFu,
2986         kPBOInitData[1],
2987         kPBOInitData[2],
2988         kPBOInitData[3],
2989     };
2990     verifyBufferContents(kExpectedData);
2991 }
2992 
framebufferBitCopyThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)2993 void MemoryBarrierTestBase::framebufferBitCopyThenImageWrite(ShaderWritePipeline writePipeline,
2994                                                              WriteResource writeResource,
2995                                                              NoopOp preBarrierOp,
2996                                                              NoopOp postBarrierOp,
2997                                                              GLbitfield barrierBit)
2998 {
2999     GLTexture color;
3000     GLFramebuffer fbo;
3001     GLProgram writeProgram;
3002 
3003     createFramebuffer(color, fbo, GLColor::green);
3004 
3005     GLBuffer textureBufferStorage;
3006     GLTexture texture;
3007     constexpr std::array<float, 4> kInitData = {1.0, 1.0, 0.0, 1.0};
3008     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
3009 
3010     // Copy from framebuffer to another texture
3011     GLFramebuffer readFbo;
3012     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
3013     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3014     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
3015 
3016     GLTexture copyTexture;
3017     glBindTexture(GL_TEXTURE_2D, copyTexture);
3018     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureSize, kTextureSize);
3019     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kTextureSize, kTextureSize);
3020 
3021     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
3022     EXPECT_GL_NO_ERROR();
3023 
3024     noopOp(preBarrierOp);
3025 
3026     // Issue the appropriate memory barrier
3027     glMemoryBarrier(barrierBit);
3028 
3029     noopOp(postBarrierOp);
3030 
3031     // Fill the image
3032     createProgram(writePipeline, writeResource, &writeProgram);
3033 
3034     GLBuffer positionBuffer;
3035     createQuadVertexArray(positionBuffer);
3036     setupVertexArray(writePipeline, writeProgram);
3037 
3038     constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
3039     setUniformData(writeProgram, kWriteData);
3040 
3041     if (writePipeline == ShaderWritePipeline::Graphics)
3042     {
3043         glEnable(GL_BLEND);
3044         glBlendFunc(GL_ONE, GL_ONE);
3045         glDrawArrays(GL_TRIANGLES, 0, 6);
3046     }
3047     else
3048     {
3049         glDispatchCompute(1, 1, 1);
3050     }
3051 
3052     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
3053 
3054     // Verify the copy texture for completeness
3055     verifyImageContents(copyTexture, kInitData);
3056 }
3057 
framebufferBitBlitThenImageWrite(ShaderWritePipeline writePipeline,WriteResource writeResource,NoopOp preBarrierOp,NoopOp postBarrierOp,GLbitfield barrierBit)3058 void MemoryBarrierTestBase::framebufferBitBlitThenImageWrite(ShaderWritePipeline writePipeline,
3059                                                              WriteResource writeResource,
3060                                                              NoopOp preBarrierOp,
3061                                                              NoopOp postBarrierOp,
3062                                                              GLbitfield barrierBit)
3063 {
3064     GLTexture blitColor;
3065     GLFramebuffer blitFbo;
3066     createFramebuffer(blitColor, blitFbo, GLColor::black);
3067 
3068     GLTexture color;
3069     GLFramebuffer fbo;
3070     GLProgram writeProgram;
3071 
3072     createFramebuffer(color, fbo, GLColor::green);
3073 
3074     GLBuffer textureBufferStorage;
3075     GLTexture texture;
3076     constexpr std::array<float, 4> kInitData = {1.0, 1.0, 0.0, 1.0};
3077     createStorageImage(writeResource, textureBufferStorage, texture, kInitData);
3078 
3079     // Blit from framebuffer to another framebuffer
3080     GLFramebuffer readFbo;
3081     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
3082     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3083     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
3084 
3085     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, blitFbo);
3086     glBlitFramebuffer(0, 0, kTextureSize, kTextureSize, 0, 0, kTextureSize, kTextureSize,
3087                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
3088     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3089     EXPECT_GL_NO_ERROR();
3090 
3091     noopOp(preBarrierOp);
3092 
3093     // Issue the appropriate memory barrier
3094     glMemoryBarrier(barrierBit);
3095 
3096     noopOp(postBarrierOp);
3097 
3098     // Fill the image
3099     createProgram(writePipeline, writeResource, &writeProgram);
3100 
3101     GLBuffer positionBuffer;
3102     createQuadVertexArray(positionBuffer);
3103     setupVertexArray(writePipeline, writeProgram);
3104 
3105     constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
3106     setUniformData(writeProgram, kWriteData);
3107 
3108     if (writePipeline == ShaderWritePipeline::Graphics)
3109     {
3110         glEnable(GL_BLEND);
3111         glBlendFunc(GL_ONE, GL_ONE);
3112         glDrawArrays(GL_TRIANGLES, 0, 6);
3113     }
3114     else
3115     {
3116         glDispatchCompute(1, 1, 1);
3117     }
3118 
3119     verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
3120 
3121     // Verify the blit fbo for completeness
3122     glBindFramebuffer(GL_READ_FRAMEBUFFER, blitFbo);
3123     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
3124 }
3125 
3126 class MemoryBarrierBufferTest : public MemoryBarrierTestBase,
3127                                 public ANGLETestWithParam<MemoryBarrierVariationsTestParams>
3128 {
3129   protected:
MemoryBarrierBufferTest()3130     MemoryBarrierBufferTest()
3131     {
3132         setWindowWidth(16);
3133         setWindowHeight(32);
3134         setConfigRedBits(8);
3135         setConfigGreenBits(8);
3136         setConfigBlueBits(8);
3137         setConfigAlphaBits(8);
3138     }
3139 };
3140 
3141 class MemoryBarrierImageTest : public MemoryBarrierTestBase,
3142                                public ANGLETestWithParam<MemoryBarrierVariationsTestParams>
3143 {
3144   protected:
MemoryBarrierImageTest()3145     MemoryBarrierImageTest()
3146     {
3147         setWindowWidth(16);
3148         setWindowHeight(32);
3149         setConfigRedBits(8);
3150         setConfigGreenBits(8);
3151         setConfigBlueBits(8);
3152         setConfigAlphaBits(8);
3153     }
3154 };
3155 
3156 class MemoryBarrierImageBufferOnlyTest
3157     : public MemoryBarrierTestBase,
3158       public ANGLETestWithParam<MemoryBarrierVariationsTestParams>
3159 {
3160   protected:
MemoryBarrierImageBufferOnlyTest()3161     MemoryBarrierImageBufferOnlyTest()
3162     {
3163         setWindowWidth(16);
3164         setWindowHeight(32);
3165         setConfigRedBits(8);
3166         setConfigGreenBits(8);
3167         setConfigBlueBits(8);
3168         setConfigAlphaBits(8);
3169     }
3170 };
3171 
3172 class MemoryBarrierImageOnlyTest : public MemoryBarrierTestBase,
3173                                    public ANGLETestWithParam<MemoryBarrierVariationsTestParams>
3174 {
3175   protected:
MemoryBarrierImageOnlyTest()3176     MemoryBarrierImageOnlyTest()
3177     {
3178         setWindowWidth(16);
3179         setWindowHeight(32);
3180         setConfigRedBits(8);
3181         setConfigGreenBits(8);
3182         setConfigBlueBits(8);
3183         setConfigAlphaBits(8);
3184     }
3185 };
3186 
3187 class MemoryBarrierBufferOnlyTest : public MemoryBarrierTestBase,
3188                                     public ANGLETestWithParam<MemoryBarrierVariationsTestParams>
3189 {
3190   protected:
MemoryBarrierBufferOnlyTest()3191     MemoryBarrierBufferOnlyTest()
3192     {
3193         setWindowWidth(16);
3194         setWindowHeight(32);
3195         setConfigRedBits(8);
3196         setConfigGreenBits(8);
3197         setConfigBlueBits(8);
3198         setConfigAlphaBits(8);
3199     }
3200 };
3201 
3202 // Test GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT; shader write -> vertex read
TEST_P(MemoryBarrierBufferTest,VertexAtrribArrayBitWriteThenVertexRead)3203 TEST_P(MemoryBarrierBufferTest, VertexAtrribArrayBitWriteThenVertexRead)
3204 {
3205     ShaderWritePipeline writePipeline;
3206     WriteResource writeResource;
3207     NoopOp preBarrierOp;
3208     NoopOp postBarrierOp;
3209     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3210                                            &preBarrierOp, &postBarrierOp);
3211 
3212     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3213 
3214     vertexAttribArrayBitBufferWriteThenVertexRead(writePipeline, writeResource, preBarrierOp,
3215                                                   postBarrierOp);
3216 }
3217 
3218 // Test GL_ELEMENT_ARRAY_BARRIER_BIT; shader write -> index read
TEST_P(MemoryBarrierBufferTest,ElementArrayBitWriteThenIndexRead)3219 TEST_P(MemoryBarrierBufferTest, ElementArrayBitWriteThenIndexRead)
3220 {
3221     ShaderWritePipeline writePipeline;
3222     WriteResource writeResource;
3223     NoopOp preBarrierOp;
3224     NoopOp postBarrierOp;
3225     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3226                                            &preBarrierOp, &postBarrierOp);
3227 
3228     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3229 
3230     elementArrayBitBufferWriteThenIndexRead(writePipeline, writeResource, preBarrierOp,
3231                                             postBarrierOp);
3232 }
3233 
3234 // Test GL_UNIFORM_BARRIER_BIT; shader write -> ubo read
TEST_P(MemoryBarrierBufferTest,UniformBitWriteThenUBORead)3235 TEST_P(MemoryBarrierBufferTest, UniformBitWriteThenUBORead)
3236 {
3237     ShaderWritePipeline writePipeline;
3238     WriteResource writeResource;
3239     NoopOp preBarrierOp;
3240     NoopOp postBarrierOp;
3241     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3242                                            &preBarrierOp, &postBarrierOp);
3243 
3244     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3245 
3246     uniformBitBufferWriteThenUBORead(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3247 }
3248 
3249 // Test GL_TEXTURE_FETCH_BARRIER_BIT; shader write -> sampler read
TEST_P(MemoryBarrierImageTest,TextureFetchBitWriteThenSamplerRead)3250 TEST_P(MemoryBarrierImageTest, TextureFetchBitWriteThenSamplerRead)
3251 {
3252     ShaderWritePipeline writePipeline;
3253     WriteResource writeResource;
3254     NoopOp preBarrierOp;
3255     NoopOp postBarrierOp;
3256     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3257                                            &preBarrierOp, &postBarrierOp);
3258 
3259     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3260 
3261     textureFetchBitImageWriteThenSamplerRead(writePipeline, writeResource, preBarrierOp,
3262                                              postBarrierOp);
3263 }
3264 
3265 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; shader write -> image read
TEST_P(MemoryBarrierImageTest,ShaderImageAccessBitWriteThenImageRead)3266 TEST_P(MemoryBarrierImageTest, ShaderImageAccessBitWriteThenImageRead)
3267 {
3268     ShaderWritePipeline writePipeline;
3269     WriteResource writeResource;
3270     NoopOp preBarrierOp;
3271     NoopOp postBarrierOp;
3272     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3273                                            &preBarrierOp, &postBarrierOp);
3274 
3275     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3276 
3277     shaderImageAccessBitImageWriteThenImageRead(writePipeline, writeResource, preBarrierOp,
3278                                                 postBarrierOp);
3279 }
3280 
3281 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; image read -> shader write
TEST_P(MemoryBarrierImageTest,ShaderImageAccessBitImageReadThenWrite)3282 TEST_P(MemoryBarrierImageTest, ShaderImageAccessBitImageReadThenWrite)
3283 {
3284     ShaderWritePipeline writePipeline;
3285     WriteResource writeResource;
3286     NoopOp preBarrierOp;
3287     NoopOp postBarrierOp;
3288     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3289                                            &preBarrierOp, &postBarrierOp);
3290 
3291     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3292 
3293     // Looks like the implementation is missing this line from the spec:
3294     //
3295     // > Additionally, image stores issued after the barrier will not execute until all memory
3296     // > accesses (e.g., loads, stores, texture fetches, vertex fetches) initiated prior to the
3297     // > barrier complete.
3298     //
3299     // http://anglebug.com/5650
3300     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsNVIDIA() && writeResource == WriteResource::Image);
3301 
3302     shaderImageAccessBitImageReadThenImageWrite(writePipeline, writeResource, preBarrierOp,
3303                                                 postBarrierOp);
3304 }
3305 
3306 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; vertex read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitVertexReadThenWrite)3307 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitVertexReadThenWrite)
3308 {
3309     ShaderWritePipeline writePipeline;
3310     WriteResource writeResource;
3311     NoopOp preBarrierOp;
3312     NoopOp postBarrierOp;
3313     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3314                                            &preBarrierOp, &postBarrierOp);
3315 
3316     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3317 
3318     vertexAttribArrayBitVertexReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3319                                                   postBarrierOp,
3320                                                   GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3321 }
3322 
3323 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; index read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitIndexReadThenWrite)3324 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitIndexReadThenWrite)
3325 {
3326     ShaderWritePipeline writePipeline;
3327     WriteResource writeResource;
3328     NoopOp preBarrierOp;
3329     NoopOp postBarrierOp;
3330     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3331                                            &preBarrierOp, &postBarrierOp);
3332 
3333     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3334 
3335     elementArrayBitIndexReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3336                                             postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3337 }
3338 
3339 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; ubo read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitUBOReadThenWrite)3340 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitUBOReadThenWrite)
3341 {
3342     ShaderWritePipeline writePipeline;
3343     WriteResource writeResource;
3344     NoopOp preBarrierOp;
3345     NoopOp postBarrierOp;
3346     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3347                                            &preBarrierOp, &postBarrierOp);
3348 
3349     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3350 
3351     uniformBitUBOReadThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3352                                      GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3353 }
3354 
3355 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; sampler read -> shader write
TEST_P(MemoryBarrierImageTest,ShaderImageAccessBitSamplerReadThenWrite)3356 TEST_P(MemoryBarrierImageTest, ShaderImageAccessBitSamplerReadThenWrite)
3357 {
3358     ShaderWritePipeline writePipeline;
3359     WriteResource writeResource;
3360     NoopOp preBarrierOp;
3361     NoopOp postBarrierOp;
3362     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3363                                            &preBarrierOp, &postBarrierOp);
3364 
3365     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3366 
3367     textureFetchBitSamplerReadThenImageWrite(writePipeline, writeResource, preBarrierOp,
3368                                              postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3369 }
3370 
3371 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; indirect read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitIndirectReadThenWrite)3372 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitIndirectReadThenWrite)
3373 {
3374     ShaderWritePipeline writePipeline;
3375     WriteResource writeResource;
3376     NoopOp preBarrierOp;
3377     NoopOp postBarrierOp;
3378     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3379                                            &preBarrierOp, &postBarrierOp);
3380 
3381     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3382 
3383     commandBitIndirectReadThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3384                                           GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3385 }
3386 
3387 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; pixel pack -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitPackThenWrite)3388 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitPackThenWrite)
3389 {
3390     ShaderWritePipeline writePipeline;
3391     WriteResource writeResource;
3392     NoopOp preBarrierOp;
3393     NoopOp postBarrierOp;
3394     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3395                                            &preBarrierOp, &postBarrierOp);
3396 
3397     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3398 
3399     pixelBufferBitPackThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3400                                       GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3401 }
3402 
3403 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; pixel unpack -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitUnpackThenWrite)3404 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitUnpackThenWrite)
3405 {
3406     ShaderWritePipeline writePipeline;
3407     WriteResource writeResource;
3408     NoopOp preBarrierOp;
3409     NoopOp postBarrierOp;
3410     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3411                                            &preBarrierOp, &postBarrierOp);
3412 
3413     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3414 
3415     pixelBufferBitUnpackThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3416                                         GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3417 }
3418 
3419 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; texture copy -> shader write
TEST_P(MemoryBarrierImageOnlyTest,ShaderImageAccessBitCopyThenWrite)3420 TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitCopyThenWrite)
3421 {
3422     ShaderWritePipeline writePipeline;
3423     WriteResource writeResource;
3424     NoopOp preBarrierOp;
3425     NoopOp postBarrierOp;
3426     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3427                                            &preBarrierOp, &postBarrierOp);
3428 
3429     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3430 
3431     textureUpdateBitCopyThenImageWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3432                                        GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3433 }
3434 
3435 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; buffer copy -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitCopyThenWrite)3436 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitCopyThenWrite)
3437 {
3438     ShaderWritePipeline writePipeline;
3439     WriteResource writeResource;
3440     NoopOp preBarrierOp;
3441     NoopOp postBarrierOp;
3442     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3443                                            &preBarrierOp, &postBarrierOp);
3444 
3445     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3446 
3447     bufferUpdateBitCopyThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3448                                        GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3449 }
3450 
3451 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; draw -> shader write
TEST_P(MemoryBarrierImageOnlyTest,ShaderImageAccessBitDrawThenWrite)3452 TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitDrawThenWrite)
3453 {
3454     ShaderWritePipeline writePipeline;
3455     WriteResource writeResource;
3456     NoopOp preBarrierOp;
3457     NoopOp postBarrierOp;
3458     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3459                                            &preBarrierOp, &postBarrierOp);
3460 
3461     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3462 
3463     framebufferBitDrawThenImageWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3464                                      GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3465 }
3466 
3467 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; read pixels -> shader write
TEST_P(MemoryBarrierImageOnlyTest,ShaderImageAccessBitReadPixelsThenWrite)3468 TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitReadPixelsThenWrite)
3469 {
3470     ShaderWritePipeline writePipeline;
3471     WriteResource writeResource;
3472     NoopOp preBarrierOp;
3473     NoopOp postBarrierOp;
3474     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3475                                            &preBarrierOp, &postBarrierOp);
3476 
3477     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3478 
3479     framebufferBitReadPixelsThenImageWrite(writePipeline, writeResource, preBarrierOp,
3480                                            postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3481 }
3482 
3483 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; fbo copy -> shader write
TEST_P(MemoryBarrierImageOnlyTest,ShaderImageAccessBitFBOCopyThenWrite)3484 TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitFBOCopyThenWrite)
3485 {
3486     ShaderWritePipeline writePipeline;
3487     WriteResource writeResource;
3488     NoopOp preBarrierOp;
3489     NoopOp postBarrierOp;
3490     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3491                                            &preBarrierOp, &postBarrierOp);
3492 
3493     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3494 
3495     framebufferBitCopyThenImageWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3496                                      GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3497 }
3498 
3499 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; blit -> shader write
TEST_P(MemoryBarrierImageOnlyTest,ShaderImageAccessBitBlitThenWrite)3500 TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitBlitThenWrite)
3501 {
3502     ShaderWritePipeline writePipeline;
3503     WriteResource writeResource;
3504     NoopOp preBarrierOp;
3505     NoopOp postBarrierOp;
3506     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3507                                            &preBarrierOp, &postBarrierOp);
3508 
3509     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3510 
3511     framebufferBitBlitThenImageWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3512                                      GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3513 }
3514 
3515 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; xfb capture -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitCaptureThenWrite)3516 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitCaptureThenWrite)
3517 {
3518     ShaderWritePipeline writePipeline;
3519     WriteResource writeResource;
3520     NoopOp preBarrierOp;
3521     NoopOp postBarrierOp;
3522     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3523                                            &preBarrierOp, &postBarrierOp);
3524 
3525     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3526 
3527     transformFeedbackBitCaptureThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3528                                                postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3529 }
3530 
3531 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; atomic write -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitAtomicThenWrite)3532 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitAtomicThenWrite)
3533 {
3534     ShaderWritePipeline writePipeline;
3535     WriteResource writeResource;
3536     NoopOp preBarrierOp;
3537     NoopOp postBarrierOp;
3538     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3539                                            &preBarrierOp, &postBarrierOp);
3540 
3541     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3542 
3543     atomicCounterBitAtomicThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3544                                           GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3545 }
3546 
3547 // Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; buffer read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest,ShaderImageAccessBitBufferReadThenWrite)3548 TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitBufferReadThenWrite)
3549 {
3550     ShaderWritePipeline writePipeline;
3551     WriteResource writeResource;
3552     NoopOp preBarrierOp;
3553     NoopOp postBarrierOp;
3554     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3555                                            &preBarrierOp, &postBarrierOp);
3556 
3557     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3558 
3559     shaderStorageBitBufferReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3560                                               postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3561 }
3562 
3563 // Test GL_COMMAND_BARRIER_BIT; shader write -> indirect read
TEST_P(MemoryBarrierBufferTest,CommandBitWriteThenIndirectRead)3564 TEST_P(MemoryBarrierBufferTest, CommandBitWriteThenIndirectRead)
3565 {
3566     ShaderWritePipeline writePipeline;
3567     WriteResource writeResource;
3568     NoopOp preBarrierOp;
3569     NoopOp postBarrierOp;
3570     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3571                                            &preBarrierOp, &postBarrierOp);
3572 
3573     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3574 
3575     commandBitBufferWriteThenIndirectRead(writePipeline, writeResource, preBarrierOp,
3576                                           postBarrierOp);
3577 }
3578 
3579 // Test GL_PIXEL_BUFFER_BARRIER_BIT; shader write -> pixel pack
TEST_P(MemoryBarrierBufferTest,PixelBufferBitWriteThenPack)3580 TEST_P(MemoryBarrierBufferTest, PixelBufferBitWriteThenPack)
3581 {
3582     ShaderWritePipeline writePipeline;
3583     WriteResource writeResource;
3584     NoopOp preBarrierOp;
3585     NoopOp postBarrierOp;
3586     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3587                                            &preBarrierOp, &postBarrierOp);
3588 
3589     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3590 
3591     pixelBufferBitBufferWriteThenPack(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3592 }
3593 
3594 // Test GL_PIXEL_BUFFER_BARRIER_BIT; shader write -> pixel unpack
TEST_P(MemoryBarrierBufferTest,PixelBufferBitWriteThenUnpack)3595 TEST_P(MemoryBarrierBufferTest, PixelBufferBitWriteThenUnpack)
3596 {
3597     ShaderWritePipeline writePipeline;
3598     WriteResource writeResource;
3599     NoopOp preBarrierOp;
3600     NoopOp postBarrierOp;
3601     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3602                                            &preBarrierOp, &postBarrierOp);
3603 
3604     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3605 
3606     pixelBufferBitBufferWriteThenUnpack(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3607 }
3608 
3609 // Test GL_TEXTURE_UPDATE_BARRIER_BIT; shader write -> texture copy
TEST_P(MemoryBarrierImageOnlyTest,TextureUpdateBitWriteThenCopy)3610 TEST_P(MemoryBarrierImageOnlyTest, TextureUpdateBitWriteThenCopy)
3611 {
3612     ShaderWritePipeline writePipeline;
3613     WriteResource writeResource;
3614     NoopOp preBarrierOp;
3615     NoopOp postBarrierOp;
3616     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3617                                            &preBarrierOp, &postBarrierOp);
3618 
3619     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3620 
3621     textureUpdateBitImageWriteThenCopy(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3622 }
3623 
3624 // Test GL_BUFFER_UPDATE_BARRIER_BIT; shader write -> buffer copy
TEST_P(MemoryBarrierBufferTest,BufferUpdateBitWriteThenCopy)3625 TEST_P(MemoryBarrierBufferTest, BufferUpdateBitWriteThenCopy)
3626 {
3627     ShaderWritePipeline writePipeline;
3628     WriteResource writeResource;
3629     NoopOp preBarrierOp;
3630     NoopOp postBarrierOp;
3631     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3632                                            &preBarrierOp, &postBarrierOp);
3633 
3634     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3635 
3636     bufferUpdateBitBufferWriteThenCopy(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3637 }
3638 
3639 // Test GL_FRAMEBUFFER_BARRIER_BIT; shader write -> draw
TEST_P(MemoryBarrierImageOnlyTest,FramebufferBitWriteThenDraw)3640 TEST_P(MemoryBarrierImageOnlyTest, FramebufferBitWriteThenDraw)
3641 {
3642     ShaderWritePipeline writePipeline;
3643     WriteResource writeResource;
3644     NoopOp preBarrierOp;
3645     NoopOp postBarrierOp;
3646     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3647                                            &preBarrierOp, &postBarrierOp);
3648 
3649     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3650 
3651     framebufferBitImageWriteThenDraw(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3652 }
3653 
3654 // Test GL_FRAMEBUFFER_BARRIER_BIT; shader write -> read pixels
TEST_P(MemoryBarrierImageOnlyTest,FramebufferBitWriteThenReadPixels)3655 TEST_P(MemoryBarrierImageOnlyTest, FramebufferBitWriteThenReadPixels)
3656 {
3657     ShaderWritePipeline writePipeline;
3658     WriteResource writeResource;
3659     NoopOp preBarrierOp;
3660     NoopOp postBarrierOp;
3661     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3662                                            &preBarrierOp, &postBarrierOp);
3663 
3664     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3665 
3666     framebufferBitImageWriteThenReadPixels(writePipeline, writeResource, preBarrierOp,
3667                                            postBarrierOp);
3668 }
3669 
3670 // Test GL_FRAMEBUFFER_BARRIER_BIT; shader write -> copy
TEST_P(MemoryBarrierImageOnlyTest,FramebufferBitWriteThenCopy)3671 TEST_P(MemoryBarrierImageOnlyTest, FramebufferBitWriteThenCopy)
3672 {
3673     ShaderWritePipeline writePipeline;
3674     WriteResource writeResource;
3675     NoopOp preBarrierOp;
3676     NoopOp postBarrierOp;
3677     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3678                                            &preBarrierOp, &postBarrierOp);
3679 
3680     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3681 
3682     framebufferBitImageWriteThenCopy(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3683 }
3684 
3685 // Test GL_FRAMEBUFFER_BARRIER_BIT; shader write -> blit
TEST_P(MemoryBarrierImageOnlyTest,FramebufferBitWriteThenBlit)3686 TEST_P(MemoryBarrierImageOnlyTest, FramebufferBitWriteThenBlit)
3687 {
3688     ShaderWritePipeline writePipeline;
3689     WriteResource writeResource;
3690     NoopOp preBarrierOp;
3691     NoopOp postBarrierOp;
3692     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3693                                            &preBarrierOp, &postBarrierOp);
3694 
3695     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3696 
3697     framebufferBitImageWriteThenBlit(writePipeline, writeResource, preBarrierOp, postBarrierOp);
3698 }
3699 
3700 // Test GL_TRANSFORM_FEEDBACK_BARRIER_BIT; shader write -> xfb capture
TEST_P(MemoryBarrierBufferTest,TransformFeedbackBitWriteThenCapture)3701 TEST_P(MemoryBarrierBufferTest, TransformFeedbackBitWriteThenCapture)
3702 {
3703     ShaderWritePipeline writePipeline;
3704     WriteResource writeResource;
3705     NoopOp preBarrierOp;
3706     NoopOp postBarrierOp;
3707     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3708                                            &preBarrierOp, &postBarrierOp);
3709 
3710     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3711 
3712     transformFeedbackBitBufferWriteThenCapture(writePipeline, writeResource, preBarrierOp,
3713                                                postBarrierOp);
3714 }
3715 
3716 // Test GL_ATOMIC_COUNTER_BARRIER_BIT; shader write -> atomic write
TEST_P(MemoryBarrierBufferTest,AtomicCounterBitWriteThenAtomic)3717 TEST_P(MemoryBarrierBufferTest, AtomicCounterBitWriteThenAtomic)
3718 {
3719     ShaderWritePipeline writePipeline;
3720     WriteResource writeResource;
3721     NoopOp preBarrierOp;
3722     NoopOp postBarrierOp;
3723     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3724                                            &preBarrierOp, &postBarrierOp);
3725 
3726     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3727 
3728     atomicCounterBitBufferWriteThenAtomic(writePipeline, writeResource, preBarrierOp,
3729                                           postBarrierOp);
3730 }
3731 
3732 // Test GL_SHADER_STORAGE_BARRIER_BIT; shader write -> shader read
TEST_P(MemoryBarrierBufferTest,ShaderStorageBitWriteThenRead)3733 TEST_P(MemoryBarrierBufferTest, ShaderStorageBitWriteThenRead)
3734 {
3735     ShaderWritePipeline writePipeline;
3736     WriteResource writeResource;
3737     NoopOp preBarrierOp;
3738     NoopOp postBarrierOp;
3739     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3740                                            &preBarrierOp, &postBarrierOp);
3741 
3742     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3743 
3744     shaderStorageBitBufferWriteThenBufferRead(writePipeline, writeResource, preBarrierOp,
3745                                               postBarrierOp);
3746 }
3747 
3748 // Test GL_SHADER_STORAGE_BARRIER_BIT; shader read -> buffer write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitReadThenWrite)3749 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitReadThenWrite)
3750 {
3751     ShaderWritePipeline writePipeline;
3752     WriteResource writeResource;
3753     NoopOp preBarrierOp;
3754     NoopOp postBarrierOp;
3755     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3756                                            &preBarrierOp, &postBarrierOp);
3757 
3758     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3759 
3760     shaderStorageBitBufferReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3761                                               postBarrierOp, GL_SHADER_STORAGE_BARRIER_BIT);
3762 }
3763 
3764 // Test GL_SHADER_STORAGE_BARRIER_BIT; vertex read -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitVertexReadThenWrite)3765 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitVertexReadThenWrite)
3766 {
3767     ShaderWritePipeline writePipeline;
3768     WriteResource writeResource;
3769     NoopOp preBarrierOp;
3770     NoopOp postBarrierOp;
3771     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3772                                            &preBarrierOp, &postBarrierOp);
3773 
3774     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3775 
3776     vertexAttribArrayBitVertexReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3777                                                   postBarrierOp, GL_SHADER_STORAGE_BARRIER_BIT);
3778 }
3779 
3780 // Test GL_SHADER_STORAGE_BARRIER_BIT; index read -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitIndexReadThenWrite)3781 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitIndexReadThenWrite)
3782 {
3783     ShaderWritePipeline writePipeline;
3784     WriteResource writeResource;
3785     NoopOp preBarrierOp;
3786     NoopOp postBarrierOp;
3787     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3788                                            &preBarrierOp, &postBarrierOp);
3789 
3790     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3791 
3792     elementArrayBitIndexReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3793                                             postBarrierOp, GL_SHADER_STORAGE_BARRIER_BIT);
3794 }
3795 
3796 // Test GL_SHADER_STORAGE_BARRIER_BIT; ubo read -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitUBOReadThenWrite)3797 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitUBOReadThenWrite)
3798 {
3799     ShaderWritePipeline writePipeline;
3800     WriteResource writeResource;
3801     NoopOp preBarrierOp;
3802     NoopOp postBarrierOp;
3803     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3804                                            &preBarrierOp, &postBarrierOp);
3805 
3806     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3807 
3808     uniformBitUBOReadThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3809                                      GL_SHADER_STORAGE_BARRIER_BIT);
3810 }
3811 
3812 // Test GL_SHADER_STORAGE_BARRIER_BIT; indirect read -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitIndirectReadThenWrite)3813 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitIndirectReadThenWrite)
3814 {
3815     ShaderWritePipeline writePipeline;
3816     WriteResource writeResource;
3817     NoopOp preBarrierOp;
3818     NoopOp postBarrierOp;
3819     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3820                                            &preBarrierOp, &postBarrierOp);
3821 
3822     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3823 
3824     commandBitIndirectReadThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3825                                           GL_SHADER_STORAGE_BARRIER_BIT);
3826 }
3827 
3828 // Test GL_SHADER_STORAGE_BARRIER_BIT; pixel pack -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitPackThenWrite)3829 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitPackThenWrite)
3830 {
3831     ShaderWritePipeline writePipeline;
3832     WriteResource writeResource;
3833     NoopOp preBarrierOp;
3834     NoopOp postBarrierOp;
3835     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3836                                            &preBarrierOp, &postBarrierOp);
3837 
3838     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3839 
3840     pixelBufferBitPackThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3841                                       GL_SHADER_STORAGE_BARRIER_BIT);
3842 }
3843 
3844 // Test GL_SHADER_STORAGE_BARRIER_BIT; pixel unpack -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitUnpackThenWrite)3845 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitUnpackThenWrite)
3846 {
3847     ShaderWritePipeline writePipeline;
3848     WriteResource writeResource;
3849     NoopOp preBarrierOp;
3850     NoopOp postBarrierOp;
3851     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3852                                            &preBarrierOp, &postBarrierOp);
3853 
3854     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3855 
3856     pixelBufferBitUnpackThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3857                                         GL_SHADER_STORAGE_BARRIER_BIT);
3858 }
3859 
3860 // Test GL_SHADER_STORAGE_BARRIER_BIT; buffer copy -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitCopyThenWrite)3861 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitCopyThenWrite)
3862 {
3863     ShaderWritePipeline writePipeline;
3864     WriteResource writeResource;
3865     NoopOp preBarrierOp;
3866     NoopOp postBarrierOp;
3867     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3868                                            &preBarrierOp, &postBarrierOp);
3869 
3870     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3871 
3872     bufferUpdateBitCopyThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3873                                        GL_SHADER_STORAGE_BARRIER_BIT);
3874 }
3875 
3876 // Test GL_SHADER_STORAGE_BARRIER_BIT; xfb capture -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitCaptureThenWrite)3877 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitCaptureThenWrite)
3878 {
3879     ShaderWritePipeline writePipeline;
3880     WriteResource writeResource;
3881     NoopOp preBarrierOp;
3882     NoopOp postBarrierOp;
3883     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3884                                            &preBarrierOp, &postBarrierOp);
3885 
3886     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3887 
3888     transformFeedbackBitCaptureThenBufferWrite(writePipeline, writeResource, preBarrierOp,
3889                                                postBarrierOp, GL_SHADER_STORAGE_BARRIER_BIT);
3890 }
3891 
3892 // Test GL_SHADER_STORAGE_BARRIER_BIT; atomic write -> shader write
TEST_P(MemoryBarrierBufferOnlyTest,ShaderStorageBitAtomicThenWrite)3893 TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitAtomicThenWrite)
3894 {
3895     ShaderWritePipeline writePipeline;
3896     WriteResource writeResource;
3897     NoopOp preBarrierOp;
3898     NoopOp postBarrierOp;
3899     ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
3900                                            &preBarrierOp, &postBarrierOp);
3901 
3902     ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));
3903 
3904     atomicCounterBitAtomicThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
3905                                           GL_SHADER_STORAGE_BARRIER_BIT);
3906 }
3907 
3908 constexpr ShaderWritePipeline kWritePipelines[] = {
3909     ShaderWritePipeline::Graphics,
3910     ShaderWritePipeline::Compute,
3911 };
3912 constexpr WriteResource kBufferWriteResources[] = {
3913     WriteResource::Buffer,
3914     WriteResource::ImageBuffer,
3915 };
3916 constexpr WriteResource kImageWriteResources[] = {
3917     WriteResource::Image,
3918     WriteResource::ImageBuffer,
3919 };
3920 constexpr WriteResource kImageBufferOnlyWriteResources[] = {
3921     WriteResource::ImageBuffer,
3922 };
3923 constexpr WriteResource kImageOnlyWriteResources[] = {
3924     WriteResource::Image,
3925 };
3926 constexpr WriteResource kBufferOnlyWriteResources[] = {
3927     WriteResource::Buffer,
3928 };
3929 constexpr NoopOp kNoopOps[] = {
3930     NoopOp::None,
3931     NoopOp::Draw,
3932     NoopOp::Dispatch,
3933 };
3934 
3935 // Note: due to large number of tests, these are only run on Vulkan and a single configuration
3936 // (swiftshader).
3937 
3938 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierBufferTest);
3939 ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierBufferTest,
3940                                  MemoryBarrierVariationsTestPrint,
3941                                  testing::ValuesIn(kWritePipelines),
3942                                  testing::ValuesIn(kBufferWriteResources),
3943                                  testing::ValuesIn(kNoopOps),
3944                                  testing::ValuesIn(kNoopOps),
3945                                  ES31_VULKAN_SWIFTSHADER());
3946 
3947 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierImageTest);
3948 ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierImageTest,
3949                                  MemoryBarrierVariationsTestPrint,
3950                                  testing::ValuesIn(kWritePipelines),
3951                                  testing::ValuesIn(kImageWriteResources),
3952                                  testing::ValuesIn(kNoopOps),
3953                                  testing::ValuesIn(kNoopOps),
3954                                  ES31_VULKAN_SWIFTSHADER());
3955 
3956 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierImageBufferOnlyTest);
3957 ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierImageBufferOnlyTest,
3958                                  MemoryBarrierVariationsTestPrint,
3959                                  testing::ValuesIn(kWritePipelines),
3960                                  testing::ValuesIn(kImageBufferOnlyWriteResources),
3961                                  testing::ValuesIn(kNoopOps),
3962                                  testing::ValuesIn(kNoopOps),
3963                                  ES31_VULKAN_SWIFTSHADER());
3964 
3965 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierImageOnlyTest);
3966 ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierImageOnlyTest,
3967                                  MemoryBarrierVariationsTestPrint,
3968                                  testing::ValuesIn(kWritePipelines),
3969                                  testing::ValuesIn(kImageOnlyWriteResources),
3970                                  testing::ValuesIn(kNoopOps),
3971                                  testing::ValuesIn(kNoopOps),
3972                                  ES31_VULKAN_SWIFTSHADER());
3973 
3974 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierBufferOnlyTest);
3975 ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierBufferOnlyTest,
3976                                  MemoryBarrierVariationsTestPrint,
3977                                  testing::ValuesIn(kWritePipelines),
3978                                  testing::ValuesIn(kBufferOnlyWriteResources),
3979                                  testing::ValuesIn(kNoopOps),
3980                                  testing::ValuesIn(kNoopOps),
3981                                  ES31_VULKAN_SWIFTSHADER());
3982 
3983 }  // anonymous namespace
3984