//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// MemoryBarrierTest:
//   Ensure that implementation of glMemoryBarrier is correct both in terms of memory barriers
//   issued and potential reordering of commands.
//
// The barrier bits accepted by glMemoryBarrier are used for synchronization as such:
//
//     VERTEX_ATTRIB_ARRAY_BARRIER_BIT: shader write -> vertex read
//     ELEMENT_ARRAY_BARRIER_BIT:       shader write -> index read
//     UNIFORM_BARRIER_BIT:             shader write -> uniform read
//     TEXTURE_FETCH_BARRIER_BIT:       shader write -> texture sample
//     SHADER_IMAGE_ACCESS_BARRIER_BIT: shader write -> image access
//                                      any access -> image write
//     COMMAND_BARRIER_BIT:             shader write -> indirect buffer read
//     PIXEL_BUFFER_BARRIER_BIT:        shader write -> pbo access
//     TEXTURE_UPDATE_BARRIER_BIT:      shader write -> texture data upload
//     BUFFER_UPDATE_BARRIER_BIT:       shader write -> buffer data upload/map
//     FRAMEBUFFER_BARRIER_BIT:         shader write -> access through framebuffer
//     TRANSFORM_FEEDBACK_BARRIER_BIT:  shader write -> transform feedback write
//     ATOMIC_COUNTER_BARRIER_BIT:      shader write -> atomic counter access
//     SHADER_STORAGE_BARRIER_BIT:      shader write -> buffer access
//                                      any access -> buffer write
//
// In summary, every bit defines a memory barrier for some access after a shader write.
// Additionally, SHADER_IMAGE_ACCESS_BARRIER_BIT and SHADER_STORAGE_BARRIER_BIT bits are used to
// define a memory barrier for shader writes after other accesses.

#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
#include "util/random_utils.h"

using namespace angle;

namespace
{
enum class ShaderWritePipeline
{
    Graphics,
    Compute,
};

enum class WriteResource
{
    Image,
    ImageBuffer,
    Buffer,
};

enum class NoopOp
{
    None,
    Draw,
    Dispatch,
};

// Variations corresponding to enums above.
using MemoryBarrierVariationsTestParams =
    std::tuple<angle::PlatformParameters, ShaderWritePipeline, WriteResource, NoopOp, NoopOp>;

void ParseMemoryBarrierVariationsTestParams(const MemoryBarrierVariationsTestParams &params,
                                            ShaderWritePipeline *writePipelineOut,
                                            WriteResource *writeResourceOut,
                                            NoopOp *preBarrierOpOut,
                                            NoopOp *postBarrierOpOut)
{
    *writePipelineOut = std::get<1>(params);
    *writeResourceOut = std::get<2>(params);
    *preBarrierOpOut  = std::get<3>(params);
    *postBarrierOpOut = std::get<4>(params);
}

std::string MemoryBarrierVariationsTestPrint(
    const ::testing::TestParamInfo<MemoryBarrierVariationsTestParams> &paramsInfo)
{
    const MemoryBarrierVariationsTestParams &params = paramsInfo.param;
    std::ostringstream out;

    out << std::get<0>(params);

    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;

    ParseMemoryBarrierVariationsTestParams(params, &writePipeline, &writeResource, &preBarrierOp,
                                           &postBarrierOp);

    out << "_";

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        out << "_graphics";
    }
    else
    {
        out << "_compute";
    }

    switch (writeResource)
    {
        case WriteResource::Image:
            out << "_image";
            break;
        case WriteResource::Buffer:
            out << "_buffer";
            break;
        case WriteResource::ImageBuffer:
            out << "_imagebuffer";
            break;
    }

    if (preBarrierOp == NoopOp::Draw)
    {
        out << "_prebarrierNoopDraw";
    }
    else if (preBarrierOp == NoopOp::Dispatch)
    {
        out << "_prebarrierNoopDispatch";
    }

    if (postBarrierOp == NoopOp::Draw)
    {
        out << "_postbarrierNoopDraw";
    }
    else if (postBarrierOp == NoopOp::Dispatch)
    {
        out << "_postbarrierNoopDispatch";
    }

    return out.str();
}

class MemoryBarrierTestBase
{
  protected:
    bool hasExtensions(WriteResource writeResource);

    // Helper functions
    void createFramebuffer(GLuint color, GLuint fbo, GLColor initialColor);
    void createStorageBuffer(WriteResource writeResource,
                             GLuint buffer,
                             GLuint textureBuffer,
                             size_t size,
                             const void *initialData);
    void createStorageImage(WriteResource writeResource,
                            GLuint bufferStorage,
                            GLuint texture,
                            const std::array<float, 4> &initialData);
    void createProgram(ShaderWritePipeline writePipeline,
                       WriteResource writeResource,
                       GLProgram *programOut);
    void createNoopGraphicsProgram(GLProgram *programOut);
    void createNoopComputeProgram(GLProgram *programOut);
    void createQuadVertexArray(GLuint positionBuffer);
    void setupVertexArray(ShaderWritePipeline writePipeline, GLuint program);
    void setUniformData(GLuint program, const std::array<float, 4> &data);
    void noopOp(NoopOp op);

    template <typename T>
    void verifyBufferContents(const std::array<T, 4> &expected);

    void verifyImageContents(GLuint texture, const std::array<float, 4> &expected);

    template <typename T>
    void verifyFramebufferAndBufferContents(ShaderWritePipeline writePipeline,
                                            const std::array<T, 4> &expected);

    void verifyFramebufferAndImageContents(ShaderWritePipeline writePipeline,
                                           WriteResource writeResource,
                                           GLuint texture,
                                           const std::array<float, 4> &expected);

    // Barrier bits affecting only buffers and imageBuffers
    void createVertexVerifyProgram(GLuint vertexBuffer, GLProgram *programOut);
    void vertexAttribArrayBitBufferWriteThenVertexRead(ShaderWritePipeline writePipeline,
                                                       WriteResource writeResource,
                                                       NoopOp preBarrierOp,
                                                       NoopOp postBarrierOp);
    void vertexAttribArrayBitVertexReadThenBufferWrite(ShaderWritePipeline writePipeline,
                                                       WriteResource writeResource,
                                                       NoopOp preBarrierOp,
                                                       NoopOp postBarrierOp,
                                                       GLbitfield barrierBit);

    void createIndexVerifyProgram(GLuint indexBuffer, GLProgram *programOut);
    void elementArrayBitBufferWriteThenIndexRead(ShaderWritePipeline writePipeline,
                                                 WriteResource writeResource,
                                                 NoopOp preBarrierOp,
                                                 NoopOp postBarrierOp);
    void elementArrayBitIndexReadThenBufferWrite(ShaderWritePipeline writePipeline,
                                                 WriteResource writeResource,
                                                 NoopOp preBarrierOp,
                                                 NoopOp postBarrierOp,
                                                 GLbitfield barrierBit);

    void createUBOVerifyProgram(GLuint buffer, GLProgram *programOut);
    void uniformBitBufferWriteThenUBORead(ShaderWritePipeline writePipeline,
                                          WriteResource writeResource,
                                          NoopOp preBarrierOp,
                                          NoopOp postBarrierOp);
    void uniformBitUBOReadThenBufferWrite(ShaderWritePipeline writePipeline,
                                          WriteResource writeResource,
                                          NoopOp preBarrierOp,
                                          NoopOp postBarrierOp,
                                          GLbitfield barrierBit);

    void createIndirectVerifyProgram(GLuint buffer, GLProgram *programOut);
    void commandBitBufferWriteThenIndirectRead(ShaderWritePipeline writePipeline,
                                               WriteResource writeResource,
                                               NoopOp preBarrierOp,
                                               NoopOp postBarrierOp);
    void commandBitIndirectReadThenBufferWrite(ShaderWritePipeline writePipeline,
                                               WriteResource writeResource,
                                               NoopOp preBarrierOp,
                                               NoopOp postBarrierOp,
                                               GLbitfield barrierBit);

    void pixelBufferBitBufferWriteThenPack(ShaderWritePipeline writePipeline,
                                           WriteResource writeResource,
                                           NoopOp preBarrierOp,
                                           NoopOp postBarrierOp);
    void pixelBufferBitBufferWriteThenUnpack(ShaderWritePipeline writePipeline,
                                             WriteResource writeResource,
                                             NoopOp preBarrierOp,
                                             NoopOp postBarrierOp);
    void pixelBufferBitPackThenBufferWrite(ShaderWritePipeline writePipeline,
                                           WriteResource writeResource,
                                           NoopOp preBarrierOp,
                                           NoopOp postBarrierOp,
                                           GLbitfield barrierBit);
    void pixelBufferBitUnpackThenBufferWrite(ShaderWritePipeline writePipeline,
                                             WriteResource writeResource,
                                             NoopOp preBarrierOp,
                                             NoopOp postBarrierOp,
                                             GLbitfield barrierBit);

    void bufferUpdateBitBufferWriteThenCopy(ShaderWritePipeline writePipeline,
                                            WriteResource writeResource,
                                            NoopOp preBarrierOp,
                                            NoopOp postBarrierOp);
    void bufferUpdateBitCopyThenBufferWrite(ShaderWritePipeline writePipeline,
                                            WriteResource writeResource,
                                            NoopOp preBarrierOp,
                                            NoopOp postBarrierOp,
                                            GLbitfield barrierBit);

    void createXfbVerifyProgram(GLuint buffer, GLProgram *programOut);
    void transformFeedbackBitBufferWriteThenCapture(ShaderWritePipeline writePipeline,
                                                    WriteResource writeResource,
                                                    NoopOp preBarrierOp,
                                                    NoopOp postBarrierOp);
    void transformFeedbackBitCaptureThenBufferWrite(ShaderWritePipeline writePipeline,
                                                    WriteResource writeResource,
                                                    NoopOp preBarrierOp,
                                                    NoopOp postBarrierOp,
                                                    GLbitfield barrierBit);

    void createAtomicCounterVerifyProgram(GLuint buffer, GLProgram *programOut);
    void atomicCounterBitBufferWriteThenAtomic(ShaderWritePipeline writePipeline,
                                               WriteResource writeResource,
                                               NoopOp preBarrierOp,
                                               NoopOp postBarrierOp);
    void atomicCounterBitAtomicThenBufferWrite(ShaderWritePipeline writePipeline,
                                               WriteResource writeResource,
                                               NoopOp preBarrierOp,
                                               NoopOp postBarrierOp,
                                               GLbitfield barrierBit);

    void createSsboVerifyProgram(WriteResource writeResourcee, GLProgram *programOut);
    void shaderStorageBitBufferWriteThenBufferRead(ShaderWritePipeline writePipeline,
                                                   WriteResource writeResource,
                                                   NoopOp preBarrierOp,
                                                   NoopOp postBarrierOp);
    void shaderStorageBitBufferReadThenBufferWrite(ShaderWritePipeline writePipeline,
                                                   WriteResource writeResource,
                                                   NoopOp preBarrierOp,
                                                   NoopOp postBarrierOp,
                                                   GLbitfield barrierBit);

    // Barrier bits affecting only images and imageBuffers
    void createTextureVerifyProgram(WriteResource writeResource,
                                    GLuint texture,
                                    GLProgram *programOut);
    void textureFetchBitImageWriteThenSamplerRead(ShaderWritePipeline writePipeline,
                                                  WriteResource writeResource,
                                                  NoopOp preBarrierOp,
                                                  NoopOp postBarrierOp);
    void textureFetchBitSamplerReadThenImageWrite(ShaderWritePipeline writePipeline,
                                                  WriteResource writeResource,
                                                  NoopOp preBarrierOp,
                                                  NoopOp postBarrierOp,
                                                  GLbitfield barrierBit);

    void createImageVerifyProgram(WriteResource writeResource,
                                  GLuint texture,
                                  GLProgram *programOut);
    void shaderImageAccessBitImageWriteThenImageRead(ShaderWritePipeline writePipeline,
                                                     WriteResource writeResource,
                                                     NoopOp preBarrierOp,
                                                     NoopOp postBarrierOp);
    void shaderImageAccessBitImageReadThenImageWrite(ShaderWritePipeline writePipeline,
                                                     WriteResource writeResource,
                                                     NoopOp preBarrierOp,
                                                     NoopOp postBarrierOp);

    // Barrier bits affecting only images
    void textureUpdateBitImageWriteThenCopy(ShaderWritePipeline writePipeline,
                                            WriteResource writeResource,
                                            NoopOp preBarrierOp,
                                            NoopOp postBarrierOp);
    void textureUpdateBitCopyThenImageWrite(ShaderWritePipeline writePipeline,
                                            WriteResource writeResource,
                                            NoopOp preBarrierOp,
                                            NoopOp postBarrierOp,
                                            GLbitfield barrierBit);

    void framebufferBitImageWriteThenDraw(ShaderWritePipeline writePipeline,
                                          WriteResource writeResource,
                                          NoopOp preBarrierOp,
                                          NoopOp postBarrierOp);
    void framebufferBitImageWriteThenReadPixels(ShaderWritePipeline writePipeline,
                                                WriteResource writeResource,
                                                NoopOp preBarrierOp,
                                                NoopOp postBarrierOp);
    void framebufferBitImageWriteThenCopy(ShaderWritePipeline writePipeline,
                                          WriteResource writeResource,
                                          NoopOp preBarrierOp,
                                          NoopOp postBarrierOp);
    void framebufferBitImageWriteThenBlit(ShaderWritePipeline writePipeline,
                                          WriteResource writeResource,
                                          NoopOp preBarrierOp,
                                          NoopOp postBarrierOp);
    void framebufferBitDrawThenImageWrite(ShaderWritePipeline writePipeline,
                                          WriteResource writeResource,
                                          NoopOp preBarrierOp,
                                          NoopOp postBarrierOp,
                                          GLbitfield barrierBit);
    void framebufferBitReadPixelsThenImageWrite(ShaderWritePipeline writePipeline,
                                                WriteResource writeResource,
                                                NoopOp preBarrierOp,
                                                NoopOp postBarrierOp,
                                                GLbitfield barrierBit);
    void framebufferBitCopyThenImageWrite(ShaderWritePipeline writePipeline,
                                          WriteResource writeResource,
                                          NoopOp preBarrierOp,
                                          NoopOp postBarrierOp,
                                          GLbitfield barrierBit);
    void framebufferBitBlitThenImageWrite(ShaderWritePipeline writePipeline,
                                          WriteResource writeResource,
                                          NoopOp preBarrierOp,
                                          NoopOp postBarrierOp,
                                          GLbitfield barrierBit);

    static constexpr int kTextureSize    = 1;
    static constexpr char kUniformName[] = "uniformData";
};

// Can be removed with C++17
constexpr char MemoryBarrierTestBase::kUniformName[];

bool MemoryBarrierTestBase::hasExtensions(WriteResource writeResource)
{
    return writeResource != WriteResource::ImageBuffer ||
           IsGLExtensionEnabled("GL_OES_texture_buffer");
}

void MemoryBarrierTestBase::createFramebuffer(GLuint color, GLuint fbo, GLColor initialColor)
{
    glBindTexture(GL_TEXTURE_2D, color);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureSize, kTextureSize);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE,
                    &initialColor);
    EXPECT_GL_NO_ERROR();

    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    EXPECT_GL_NO_ERROR();

    // Ensure all staged data is flushed.
    EXPECT_PIXEL_COLOR_EQ(0, 0, initialColor);
}

void MemoryBarrierTestBase::createStorageBuffer(WriteResource writeResource,
                                                GLuint buffer,
                                                GLuint textureBuffer,
                                                size_t size,
                                                const void *initialData)
{
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
    glBufferData(GL_SHADER_STORAGE_BUFFER, size, initialData, GL_STATIC_DRAW);
    glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);
    EXPECT_GL_NO_ERROR();

    if (writeResource == WriteResource::ImageBuffer)
    {
        glBindTexture(GL_TEXTURE_BUFFER, textureBuffer);
        glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA32F, buffer);
        glBindImageTexture(0, textureBuffer, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
        EXPECT_GL_NO_ERROR();
    }
}

void MemoryBarrierTestBase::createStorageImage(WriteResource writeResource,
                                               GLuint bufferStorage,
                                               GLuint texture,
                                               const std::array<float, 4> &initialData)
{
    const std::array<uint8_t, 4> initialDataAsUnorm = {
        static_cast<uint8_t>(initialData[0] * 255),
        static_cast<uint8_t>(initialData[1] * 255),
        static_cast<uint8_t>(initialData[2] * 255),
        static_cast<uint8_t>(initialData[3] * 255),
    };

    if (writeResource == WriteResource::ImageBuffer)
    {
        glBindBuffer(GL_SHADER_STORAGE_BUFFER, bufferStorage);
        glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(initialData), initialData.data(),
                     GL_STATIC_DRAW);
        EXPECT_GL_NO_ERROR();

        glBindTexture(GL_TEXTURE_BUFFER, texture);
        glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA32F, bufferStorage);
        glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA32F);
        EXPECT_GL_NO_ERROR();
    }
    else
    {
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureSize, kTextureSize);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureSize, kTextureSize, GL_RGBA,
                        GL_UNSIGNED_BYTE, initialDataAsUnorm.data());
        glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
    }
}

void MemoryBarrierTestBase::createProgram(ShaderWritePipeline writePipeline,
                                          WriteResource writeResource,
                                          GLProgram *programOut)
{
    constexpr char kGraphicsImageFS[] = R"(#version 310 es
precision mediump float;
layout(rgba8, binding = 0) uniform highp writeonly image2D dst;
uniform vec4 uniformData;
out vec4 colorOut;
void main()
{
    colorOut = vec4(0, 0, 1.0, 1.0);
    imageStore(dst, ivec2(gl_FragCoord.xy), uniformData);
})";

    constexpr char kGraphicsBufferFS[] = R"(#version 310 es
precision mediump float;
uniform vec4 uniformData;
layout(std430, binding = 0) buffer block {
    vec4 data;
} outBlock;
out vec4 colorOut;
void main()
{
    colorOut = vec4(0, 0, 1.0, 1.0);
    outBlock.data = uniformData;
}
)";

    constexpr char kGraphicsImageBufferFS[] = R"(#version 310 es
#extension GL_OES_texture_buffer : require
precision mediump float;
layout(rgba32f, binding = 0) uniform highp writeonly imageBuffer dst;
uniform vec4 uniformData;
out vec4 colorOut;
void main()
{
    colorOut = vec4(0, 0, 1.0, 1.0);
    imageStore(dst, int(gl_FragCoord.x), uniformData);
})";

    constexpr char kComputeImage[] = R"(#version 310 es
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
layout(rgba8, binding = 0) uniform highp writeonly image2D dst;
uniform vec4 uniformData;
void main()
{
    imageStore(dst, ivec2(gl_GlobalInvocationID.xy), uniformData);
})";

    constexpr char kComputeBuffer[] = R"(#version 310 es
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
uniform vec4 uniformData;
layout(std430, binding = 0) buffer block {
    vec4 data;
} outBlock;
void main()
{
    outBlock.data = uniformData;
}
)";

    constexpr char kComputeImageBuffer[] = R"(#version 310 es
#extension GL_OES_texture_buffer : require
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
layout(rgba32f, binding = 0) uniform highp writeonly imageBuffer dst;
uniform vec4 uniformData;
void main()
{
    imageStore(dst, int(gl_GlobalInvocationID.x), uniformData);
})";

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        const char *fs = "";
        switch (writeResource)
        {
            case WriteResource::Image:
                fs = kGraphicsImageFS;
                break;
            case WriteResource::Buffer:
                fs = kGraphicsBufferFS;
                break;
            case WriteResource::ImageBuffer:
                fs = kGraphicsImageBufferFS;
                break;
        }

        programOut->makeRaster(essl31_shaders::vs::Simple(), fs);
    }
    else
    {
        const char *cs = "";
        switch (writeResource)
        {
            case WriteResource::Image:
                cs = kComputeImage;
                break;
            case WriteResource::Buffer:
                cs = kComputeBuffer;
                break;
            case WriteResource::ImageBuffer:
                cs = kComputeImageBuffer;
                break;
        }

        programOut->makeCompute(cs);
    }

    ASSERT_TRUE(programOut->valid());
    glUseProgram(*programOut);
}

void MemoryBarrierTestBase::createNoopGraphicsProgram(GLProgram *programOut)
{
    programOut->makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    ASSERT_TRUE(programOut->valid());
}

void MemoryBarrierTestBase::createNoopComputeProgram(GLProgram *programOut)
{
    constexpr char kCS[] = R"(#version 310 es
layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
void main()
{
})";

    programOut->makeCompute(kCS);
    ASSERT_TRUE(programOut->valid());
}

void MemoryBarrierTestBase::createQuadVertexArray(GLuint positionBuffer)
{
    const std::array<Vector3, 6> kQuadVertices = {{
        Vector3(-1.0f, 1.0f, 0.5f),
        Vector3(-1.0f, -1.0f, 0.5f),
        Vector3(1.0f, -1.0f, 0.5f),
        Vector3(-1.0f, 1.0f, 0.5f),
        Vector3(1.0f, -1.0f, 0.5f),
        Vector3(1.0f, 1.0f, 0.5f),
    }};

    const size_t bufferSize = kQuadVertices.size() * sizeof(Vector3);

    glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
    glBufferData(GL_ARRAY_BUFFER, bufferSize, kQuadVertices.data(), GL_STATIC_DRAW);
    EXPECT_GL_NO_ERROR();
}

void MemoryBarrierTestBase::setupVertexArray(ShaderWritePipeline writePipeline, GLuint program)
{
    if (writePipeline == ShaderWritePipeline::Compute)
    {
        return;
    }

    GLint positionLoc = glGetAttribLocation(program, essl31_shaders::PositionAttrib());
    ASSERT_NE(-1, positionLoc);

    glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnableVertexAttribArray(positionLoc);
    EXPECT_GL_NO_ERROR();
}

void MemoryBarrierTestBase::setUniformData(GLuint program, const std::array<float, 4> &data)
{
    GLint uniformLocation = glGetUniformLocation(program, kUniformName);
    ASSERT_NE(uniformLocation, -1);

    glUniform4f(uniformLocation, data[0], data[1], data[2], data[3]);
    EXPECT_GL_NO_ERROR();
}

void MemoryBarrierTestBase::noopOp(NoopOp op)
{
    if (op == NoopOp::None)
    {
        return;
    }

    GLProgram noopProgram;
    if (op == NoopOp::Draw)
    {
        createNoopGraphicsProgram(&noopProgram);

        glEnable(GL_BLEND);
        glBlendFunc(GL_ZERO, GL_ONE);

        glUseProgram(noopProgram);
        glDrawArrays(GL_TRIANGLES, 0, 3);

        glDisable(GL_BLEND);
    }
    else
    {
        createNoopComputeProgram(&noopProgram);
        glUseProgram(noopProgram);
        glDispatchCompute(1, 1, 1);
    }

    EXPECT_GL_NO_ERROR();
}

template <typename T>
void MemoryBarrierTestBase::verifyBufferContents(const std::array<T, 4> &expected)
{
    glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
    T *bufferContents = static_cast<T *>(
        glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(expected), GL_MAP_READ_BIT));
    EXPECT_GL_NO_ERROR();

    EXPECT_EQ(bufferContents[0], expected[0]);
    EXPECT_EQ(bufferContents[1], expected[1]);
    EXPECT_EQ(bufferContents[2], expected[2]);
    EXPECT_EQ(bufferContents[3], expected[3]);
    glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
}

void MemoryBarrierTestBase::verifyImageContents(GLuint texture,
                                                const std::array<float, 4> &expected)
{
    glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
    glBindTexture(GL_TEXTURE_2D, texture);
    glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
    EXPECT_GL_NO_ERROR();

    const GLColor kExpected(expected[0] * 255, expected[1] * 255, expected[2] * 255,
                            expected[3] * 255);
    EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);
}

template <typename T>
void MemoryBarrierTestBase::verifyFramebufferAndBufferContents(ShaderWritePipeline writePipeline,
                                                               const std::array<T, 4> &expected)
{
    // Verify the result of the verify shader
    const GLColor kExpected =
        writePipeline == ShaderWritePipeline::Graphics ? GLColor::cyan : GLColor::green;
    EXPECT_PIXEL_COLOR_EQ(0, 0, kExpected);

    // Verify the contents of the buffer
    verifyBufferContents(expected);
}

void MemoryBarrierTestBase::verifyFramebufferAndImageContents(ShaderWritePipeline writePipeline,
                                                              WriteResource writeResource,
                                                              GLuint texture,
                                                              const std::array<float, 4> &expected)
{
    // Verify the result of the verify shader
    const GLColor kExpected =
        writePipeline == ShaderWritePipeline::Graphics ? GLColor::cyan : GLColor::green;
    EXPECT_PIXEL_COLOR_EQ(0, 0, kExpected);

    if (writeResource == WriteResource::ImageBuffer)
    {
        // Verify the contents of the buffer
        verifyBufferContents(expected);
    }
    else
    {
        // Verify the contents of the image
        verifyImageContents(texture, expected);
    }
}

void MemoryBarrierTestBase::createVertexVerifyProgram(GLuint vertexBuffer, GLProgram *programOut)
{
    constexpr char kVS[] = R"(#version 310 es
in float attribIn;
out float v;

void main()
{
    v = attribIn;
    // gl_VertexID    x    y
    //      0        -1   -1
    //      1         1   -1
    //      2        -1    1
    //      3         1    1
    int bit0 = gl_VertexID & 1;
    int bit1 = gl_VertexID >> 1;
    gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
})";

    constexpr char kFS[] = R"(#version 310 es
precision mediump float;
in float v;
out vec4 colorOut;
void main()
{
    if (v == 2.0)
        colorOut = vec4(0, 1.0, 0, 1.0);
    else
        colorOut = vec4(1.0, 0, 0, 1.0);
})";

    programOut->makeRaster(kVS, kFS);
    ASSERT_TRUE(programOut->valid());
    glUseProgram(*programOut);

    GLint attribLoc = glGetAttribLocation(*programOut, "attribIn");
    ASSERT_NE(-1, attribLoc);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glVertexAttribPointer(attribLoc, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnableVertexAttribArray(attribLoc);
    EXPECT_GL_NO_ERROR();
}

void MemoryBarrierTestBase::vertexAttribArrayBitBufferWriteThenVertexRead(
    ShaderWritePipeline writePipeline,
    WriteResource writeResource,
    NoopOp preBarrierOp,
    NoopOp postBarrierOp)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    GLBuffer vertexBuffer;
    GLTexture vertexTextureBuffer;
    constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
    createStorageBuffer(writeResource, vertexBuffer, vertexTextureBuffer, sizeof(kInitData),
                        kInitData.data());

    constexpr std::array<float, 4> kWriteData = {2.0, 2.0, 2.0, 2.0};
    setUniformData(writeProgram, kWriteData);

    // Fill the buffer
    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT);

    noopOp(postBarrierOp);

    // Use the buffer
    GLProgram readProgram;
    createVertexVerifyProgram(vertexBuffer, &readProgram);

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    EXPECT_GL_NO_ERROR();

    // Verify the vertex data was read correctly
    const GLColor kExpected =
        writePipeline == ShaderWritePipeline::Graphics ? GLColor::cyan : GLColor::green;
    EXPECT_PIXEL_COLOR_EQ(0, 0, kExpected);

    // Verify the contents of the buffer
    verifyBufferContents(kWriteData);
}

void MemoryBarrierTestBase::vertexAttribArrayBitVertexReadThenBufferWrite(
    ShaderWritePipeline writePipeline,
    WriteResource writeResource,
    NoopOp preBarrierOp,
    NoopOp postBarrierOp,
    GLbitfield barrierBit)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);

    GLBuffer vertexBuffer;
    GLTexture vertexTextureBuffer;
    constexpr std::array<float, 4> kInitData = {2.0, 2.0, 2.0, 2.0};
    createStorageBuffer(writeResource, vertexBuffer, vertexTextureBuffer, sizeof(kInitData),
                        kInitData.data());

    // Use the buffer
    GLProgram readProgram;
    createVertexVerifyProgram(vertexBuffer, &readProgram);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    EXPECT_GL_NO_ERROR();

    GLint attribLoc = glGetAttribLocation(readProgram, "attribIn");
    glDisableVertexAttribArray(attribLoc);

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(barrierBit);

    noopOp(postBarrierOp);

    // Fill the buffer
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
    setUniformData(writeProgram, kWriteData);

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    verifyFramebufferAndBufferContents(writePipeline, kWriteData);
}

void MemoryBarrierTestBase::createIndexVerifyProgram(GLuint indexBuffer, GLProgram *programOut)
{
    constexpr char kVS[] = R"(#version 310 es
void main()
{
    // gl_VertexID    x    y
    //      0        -1   -1
    //      1         1   -1
    //      2        -1    1
    //      3         1    1
    int bit0 = gl_VertexID & 1;
    int bit1 = gl_VertexID >> 1;
    gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
})";

    constexpr char kFS[] = R"(#version 310 es
precision mediump float;
out vec4 colorOut;
void main()
{
    colorOut = vec4(0, 1.0, 0, 1.0);
})";

    programOut->makeRaster(kVS, kFS);
    ASSERT_TRUE(programOut->valid());
    glUseProgram(*programOut);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    EXPECT_GL_NO_ERROR();
}

void MemoryBarrierTestBase::elementArrayBitBufferWriteThenIndexRead(
    ShaderWritePipeline writePipeline,
    WriteResource writeResource,
    NoopOp preBarrierOp,
    NoopOp postBarrierOp)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    GLBuffer indexBuffer;
    GLTexture indexTextureBuffer;
    constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
    createStorageBuffer(writeResource, indexBuffer, indexTextureBuffer, sizeof(kInitData),
                        kInitData.data());

    constexpr std::array<uint32_t, 4> kWriteData = {0, 1, 2, 3};
    const std::array<float, 4> kWriteDataAsFloat = {
        *reinterpret_cast<const float *>(&kWriteData[0]),
        *reinterpret_cast<const float *>(&kWriteData[1]),
        *reinterpret_cast<const float *>(&kWriteData[2]),
        *reinterpret_cast<const float *>(&kWriteData[3]),
    };
    setUniformData(writeProgram, kWriteDataAsFloat);

    // Fill the buffer
    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(GL_ELEMENT_ARRAY_BARRIER_BIT);

    noopOp(postBarrierOp);

    // Use the buffer
    GLProgram readProgram;
    createIndexVerifyProgram(indexBuffer, &readProgram);

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
    EXPECT_GL_NO_ERROR();

    verifyFramebufferAndBufferContents(writePipeline, kWriteData);
}

void MemoryBarrierTestBase::elementArrayBitIndexReadThenBufferWrite(
    ShaderWritePipeline writePipeline,
    WriteResource writeResource,
    NoopOp preBarrierOp,
    NoopOp postBarrierOp,
    GLbitfield barrierBit)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);

    GLBuffer indexBuffer;
    GLTexture indexTextureBuffer;
    constexpr std::array<uint32_t, 4> kInitData = {0, 1, 2, 3};
    createStorageBuffer(writeResource, indexBuffer, indexTextureBuffer, sizeof(kInitData),
                        kInitData.data());

    // Use the buffer
    GLProgram readProgram;
    createIndexVerifyProgram(indexBuffer, &readProgram);

    glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
    EXPECT_GL_NO_ERROR();

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(barrierBit);

    noopOp(postBarrierOp);

    // Fill the buffer
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
    setUniformData(writeProgram, kWriteData);

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    verifyFramebufferAndBufferContents(writePipeline, kWriteData);
}

void MemoryBarrierTestBase::createUBOVerifyProgram(GLuint buffer, GLProgram *programOut)
{
    constexpr char kVS[] = R"(#version 310 es
void main()
{
    // gl_VertexID    x    y
    //      0        -1   -1
    //      1         1   -1
    //      2        -1    1
    //      3         1    1
    int bit0 = gl_VertexID & 1;
    int bit1 = gl_VertexID >> 1;
    gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
})";

    constexpr char kFS[] = R"(#version 310 es
precision mediump float;
layout(binding = 0) uniform block {
    vec4 data;
} ubo;
out vec4 colorOut;
void main()
{
    if (ubo.data == vec4(1.5, 3.75, 5.0, 12.125))
        colorOut = vec4(0, 1.0, 0, 1.0);
    else
        colorOut = vec4(1.0, 0, 0, 1.0);
})";

    programOut->makeRaster(kVS, kFS);
    ASSERT_TRUE(programOut->valid());
    glUseProgram(*programOut);

    glBindBuffer(GL_UNIFORM_BUFFER, buffer);
    glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
    EXPECT_GL_NO_ERROR();
}

void MemoryBarrierTestBase::uniformBitBufferWriteThenUBORead(ShaderWritePipeline writePipeline,
                                                             WriteResource writeResource,
                                                             NoopOp preBarrierOp,
                                                             NoopOp postBarrierOp)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    GLBuffer uniformBuffer;
    GLTexture uniformTextureBuffer;
    constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
    createStorageBuffer(writeResource, uniformBuffer, uniformTextureBuffer, sizeof(kInitData),
                        kInitData.data());

    constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
    setUniformData(writeProgram, kWriteData);

    // Fill the buffer
    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(GL_UNIFORM_BARRIER_BIT);

    noopOp(postBarrierOp);

    // Use the buffer
    GLProgram readProgram;
    createUBOVerifyProgram(uniformBuffer, &readProgram);

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    EXPECT_GL_NO_ERROR();

    verifyFramebufferAndBufferContents(writePipeline, kWriteData);
}

void MemoryBarrierTestBase::uniformBitUBOReadThenBufferWrite(ShaderWritePipeline writePipeline,
                                                             WriteResource writeResource,
                                                             NoopOp preBarrierOp,
                                                             NoopOp postBarrierOp,
                                                             GLbitfield barrierBit)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);

    GLBuffer uniformBuffer;
    GLTexture uniformTextureBuffer;
    constexpr std::array<float, 4> kInitData = {1.5, 3.75, 5.0, 12.125};
    createStorageBuffer(writeResource, uniformBuffer, uniformTextureBuffer, sizeof(kInitData),
                        kInitData.data());

    // Use the buffer
    GLProgram readProgram;
    createUBOVerifyProgram(uniformBuffer, &readProgram);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    EXPECT_GL_NO_ERROR();

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(barrierBit);

    noopOp(postBarrierOp);

    // Fill the buffer
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
    setUniformData(writeProgram, kWriteData);

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    verifyFramebufferAndBufferContents(writePipeline, kWriteData);
}

void MemoryBarrierTestBase::createIndirectVerifyProgram(GLuint buffer, GLProgram *programOut)
{
    constexpr char kVS[] = R"(#version 310 es
void main()
{
    // gl_VertexID    x    y
    //      0        -1   -1
    //      1         1   -1
    //      2        -1    1
    //      3         1    1
    int bit0 = gl_VertexID & 1;
    int bit1 = gl_VertexID >> 1;
    gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
})";

    constexpr char kFS[] = R"(#version 310 es
precision mediump float;
out vec4 colorOut;
void main()
{
    colorOut = vec4(0, 1.0, 0, 1.0);
})";

    programOut->makeRaster(kVS, kFS);
    ASSERT_TRUE(programOut->valid());
    glUseProgram(*programOut);

    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer);
    EXPECT_GL_NO_ERROR();
}

void MemoryBarrierTestBase::commandBitBufferWriteThenIndirectRead(ShaderWritePipeline writePipeline,
                                                                  WriteResource writeResource,
                                                                  NoopOp preBarrierOp,
                                                                  NoopOp postBarrierOp)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    GLBuffer indirectBuffer;
    GLTexture indirectTextureBuffer;
    constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
    createStorageBuffer(writeResource, indirectBuffer, indirectTextureBuffer, sizeof(kInitData),
                        kInitData.data());

    constexpr std::array<uint32_t, 4> kWriteData = {4, 1, 0, 0};
    const std::array<float, 4> kWriteDataAsFloat = {
        *reinterpret_cast<const float *>(&kWriteData[0]),
        *reinterpret_cast<const float *>(&kWriteData[1]),
        *reinterpret_cast<const float *>(&kWriteData[2]),
        *reinterpret_cast<const float *>(&kWriteData[3]),
    };
    setUniformData(writeProgram, kWriteDataAsFloat);

    // Fill the buffer
    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(GL_COMMAND_BARRIER_BIT);

    noopOp(postBarrierOp);

    // Use the buffer
    GLProgram readProgram;
    createIndirectVerifyProgram(indirectBuffer, &readProgram);

    GLVertexArray vao;
    glBindVertexArray(vao);

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    glDrawArraysIndirect(GL_TRIANGLE_STRIP, nullptr);
    EXPECT_GL_NO_ERROR();

    verifyFramebufferAndBufferContents(writePipeline, kWriteData);
}

void MemoryBarrierTestBase::commandBitIndirectReadThenBufferWrite(ShaderWritePipeline writePipeline,
                                                                  WriteResource writeResource,
                                                                  NoopOp preBarrierOp,
                                                                  NoopOp postBarrierOp,
                                                                  GLbitfield barrierBit)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);

    GLBuffer indirectBuffer;
    GLTexture indirectTextureBuffer;
    constexpr std::array<uint32_t, 4> kInitData = {4, 1, 0, 0};
    createStorageBuffer(writeResource, indirectBuffer, indirectTextureBuffer, sizeof(kInitData),
                        kInitData.data());

    // Use the buffer
    GLProgram readProgram;
    createIndirectVerifyProgram(indirectBuffer, &readProgram);

    GLVertexArray vao;
    glBindVertexArray(vao);

    glDrawArraysIndirect(GL_TRIANGLE_STRIP, nullptr);
    EXPECT_GL_NO_ERROR();

    glBindVertexArray(0);

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(barrierBit);

    noopOp(postBarrierOp);

    // Fill the buffer
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
    setUniformData(writeProgram, kWriteData);

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    verifyFramebufferAndBufferContents(writePipeline, kWriteData);
}

void MemoryBarrierTestBase::pixelBufferBitBufferWriteThenPack(ShaderWritePipeline writePipeline,
                                                              WriteResource writeResource,
                                                              NoopOp preBarrierOp,
                                                              NoopOp postBarrierOp)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::green);
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    GLBuffer packBuffer;
    GLTexture packTextureBuffer;
    constexpr std::array<float, 4> kInitData = {1.5, 3.75, 5.0, 12.125};
    createStorageBuffer(writeResource, packBuffer, packTextureBuffer, sizeof(kInitData),
                        kInitData.data());

    constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
    setUniformData(writeProgram, kWriteData);

    // Fill the buffer
    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
        glDisable(GL_BLEND);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);

    noopOp(postBarrierOp);

    // Use the buffer
    glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
    glReadPixels(0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

    const std::array<uint32_t, 4> kExpectedData = {
        writePipeline == ShaderWritePipeline::Graphics ? 0xFFFFFF00u : 0xFF00FF00u,
        *reinterpret_cast<const uint32_t *>(&kWriteData[1]),
        *reinterpret_cast<const uint32_t *>(&kWriteData[2]),
        *reinterpret_cast<const uint32_t *>(&kWriteData[3]),
    };
    verifyFramebufferAndBufferContents(writePipeline, kExpectedData);
}

void MemoryBarrierTestBase::pixelBufferBitBufferWriteThenUnpack(ShaderWritePipeline writePipeline,
                                                                WriteResource writeResource,
                                                                NoopOp preBarrierOp,
                                                                NoopOp postBarrierOp)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    GLBuffer unpackBuffer;
    GLTexture unpackTextureBuffer;
    constexpr std::array<float, 4> kInitData = {1.5, 3.75, 5.0, 12.125};
    createStorageBuffer(writeResource, unpackBuffer, unpackTextureBuffer, sizeof(kInitData),
                        kInitData.data());

    const std::array<float, 4> kWriteData = {*reinterpret_cast<const float *>(&GLColor::green), 5.6,
                                             78.91, 123.456};
    setUniformData(writeProgram, kWriteData);

    // Fill the buffer
    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
        glDisable(GL_BLEND);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(GL_PIXEL_BUFFER_BARRIER_BIT);

    noopOp(postBarrierOp);

    // Use the buffer
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE,
                    0);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

    // Verify the result of the unpack operation
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    // Verify the contents of the buffer
    verifyBufferContents(kWriteData);
}

void MemoryBarrierTestBase::pixelBufferBitPackThenBufferWrite(ShaderWritePipeline writePipeline,
                                                              WriteResource writeResource,
                                                              NoopOp preBarrierOp,
                                                              NoopOp postBarrierOp,
                                                              GLbitfield barrierBit)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::green);

    GLBuffer packBuffer;
    GLTexture packTextureBuffer;
    constexpr std::array<float, 4> kInitData = {1.5, 3.75, 5.0, 12.125};
    createStorageBuffer(writeResource, packBuffer, packTextureBuffer, sizeof(kInitData),
                        kInitData.data());

    // Use the buffer
    glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
    glReadPixels(0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(barrierBit);

    noopOp(postBarrierOp);

    // Fill the buffer
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
    setUniformData(writeProgram, kWriteData);

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    verifyFramebufferAndBufferContents(writePipeline, kWriteData);
}

void MemoryBarrierTestBase::pixelBufferBitUnpackThenBufferWrite(ShaderWritePipeline writePipeline,
                                                                WriteResource writeResource,
                                                                NoopOp preBarrierOp,
                                                                NoopOp postBarrierOp,
                                                                GLbitfield barrierBit)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);

    GLBuffer unpackBuffer;
    GLTexture unpackTextureBuffer;
    const std::array<float, 4> kInitData = {*reinterpret_cast<const float *>(&GLColor::green), 3.75,
                                            5.0, 12.125};
    createStorageBuffer(writeResource, unpackBuffer, unpackTextureBuffer, sizeof(kInitData),
                        kInitData.data());

    // Use the buffer
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, unpackBuffer);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE,
                    0);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(barrierBit);

    noopOp(postBarrierOp);

    // Fill the buffer
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
    setUniformData(writeProgram, kWriteData);

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    verifyFramebufferAndBufferContents(writePipeline, kWriteData);
}

void MemoryBarrierTestBase::bufferUpdateBitBufferWriteThenCopy(ShaderWritePipeline writePipeline,
                                                               WriteResource writeResource,
                                                               NoopOp preBarrierOp,
                                                               NoopOp postBarrierOp)
{
    GLBuffer srcBuffer;
    GLTexture srcTextureBuffer;
    constexpr std::array<float, 4> kSrcInitData = {9.3, 3.7, 11.34, 0.65};
    createStorageBuffer(WriteResource::Buffer, srcBuffer, srcTextureBuffer, sizeof(kSrcInitData),
                        kSrcInitData.data());

    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::green);
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    GLBuffer writeBuffer;
    GLTexture writeTextureBuffer;
    constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
    createStorageBuffer(writeResource, writeBuffer, writeTextureBuffer, sizeof(kInitData),
                        kInitData.data());

    constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
    setUniformData(writeProgram, kWriteData);

    // Fill the buffer
    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
        glDisable(GL_BLEND);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);

    noopOp(postBarrierOp);

    // Copy from src buffer over the buffer
    glBindBuffer(GL_UNIFORM_BUFFER, srcBuffer);
    glCopyBufferSubData(GL_UNIFORM_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 0, sizeof(kInitData));

    verifyFramebufferAndBufferContents(writePipeline, kSrcInitData);

    // Verify the src buffer is unaffected
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, srcBuffer);
    verifyBufferContents(kSrcInitData);
}

void MemoryBarrierTestBase::bufferUpdateBitCopyThenBufferWrite(ShaderWritePipeline writePipeline,
                                                               WriteResource writeResource,
                                                               NoopOp preBarrierOp,
                                                               NoopOp postBarrierOp,
                                                               GLbitfield barrierBit)
{
    GLBuffer srcBuffer;
    GLTexture srcTextureBuffer;
    constexpr std::array<float, 4> kSrcInitData = {9.3, 3.7, 11.34, 0.65};
    createStorageBuffer(WriteResource::Buffer, srcBuffer, srcTextureBuffer, sizeof(kSrcInitData),
                        kSrcInitData.data());

    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::green);

    GLBuffer writeBuffer;
    GLTexture writeTextureBuffer;
    constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
    createStorageBuffer(writeResource, writeBuffer, writeTextureBuffer, sizeof(kInitData),
                        kInitData.data());

    // Copy from src buffer over the buffer
    glBindBuffer(GL_UNIFORM_BUFFER, srcBuffer);
    glCopyBufferSubData(GL_UNIFORM_BUFFER, GL_SHADER_STORAGE_BUFFER, 0, 0, sizeof(kInitData));

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(barrierBit);

    noopOp(postBarrierOp);

    // Fill the buffer
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
    setUniformData(writeProgram, kWriteData);

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    verifyFramebufferAndBufferContents(writePipeline, kWriteData);

    // Verify the src buffer is unaffected
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, srcBuffer);
    verifyBufferContents(kSrcInitData);
}

void MemoryBarrierTestBase::createXfbVerifyProgram(GLuint buffer, GLProgram *programOut)
{
    constexpr char kVS[] = R"(#version 310 es
void main()
{
    // gl_VertexID    x    y
    //   0 (000)     -1   -1
    //   1 (001)      1   -1
    //   2 (010)     -1    1
    //   3 (011)      1    1
    //   4 (100)     -1    1
    //   5 (101)      1   -1
    int bit0 = gl_VertexID & 1;
    int bit1 = gl_VertexID < 4 ? gl_VertexID >> 1 & 1 : ~bit0 & 1;
    gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
})";

    constexpr char kFS[] = R"(#version 310 es
precision mediump float;
out vec4 colorOut;
void main()
{
    colorOut = vec4(0, 1.0, 0, 1.0);
})";

    const std::vector<std::string> &tfVaryings = {"gl_Position"};

    programOut->makeRasterWithTransformFeedback(kVS, kFS, tfVaryings, GL_INTERLEAVED_ATTRIBS);
    ASSERT_TRUE(programOut->valid());
    glUseProgram(*programOut);

    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffer);
    EXPECT_GL_NO_ERROR();
}

void MemoryBarrierTestBase::transformFeedbackBitBufferWriteThenCapture(
    ShaderWritePipeline writePipeline,
    WriteResource writeResource,
    NoopOp preBarrierOp,
    NoopOp postBarrierOp)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    GLBuffer xfbBuffer;
    GLTexture xfbTextureBuffer;
    constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
    createStorageBuffer(writeResource, xfbBuffer, xfbTextureBuffer, sizeof(kInitData) * 6,
                        kInitData.data());

    constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
    setUniformData(writeProgram, kWriteData);

    // Fill the buffer
    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(GL_TRANSFORM_FEEDBACK_BARRIER_BIT);

    noopOp(postBarrierOp);

    // Use the buffer
    GLProgram xfbProgram;
    createXfbVerifyProgram(xfbBuffer, &xfbProgram);

    glBeginTransformFeedback(GL_TRIANGLES);
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glEndTransformFeedback();
    EXPECT_GL_NO_ERROR();

    const std::array<float, 4> kExpectedData = {-1.0, -1.0, 0.0, 1.0};
    verifyFramebufferAndBufferContents(writePipeline, kExpectedData);
}

void MemoryBarrierTestBase::transformFeedbackBitCaptureThenBufferWrite(
    ShaderWritePipeline writePipeline,
    WriteResource writeResource,
    NoopOp preBarrierOp,
    NoopOp postBarrierOp,
    GLbitfield barrierBit)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);

    GLBuffer xfbBuffer;
    GLTexture xfbTextureBuffer;
    constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
    createStorageBuffer(writeResource, xfbBuffer, xfbTextureBuffer, sizeof(kInitData) * 6,
                        kInitData.data());

    // Use the buffer
    GLProgram xfbProgram;
    createXfbVerifyProgram(xfbBuffer, &xfbProgram);

    glBeginTransformFeedback(GL_TRIANGLES);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glEndTransformFeedback();
    EXPECT_GL_NO_ERROR();

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(barrierBit);

    noopOp(postBarrierOp);

    // Fill the buffer
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
    setUniformData(writeProgram, kWriteData);

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    verifyFramebufferAndBufferContents(writePipeline, kWriteData);
}

void MemoryBarrierTestBase::createAtomicCounterVerifyProgram(GLuint buffer, GLProgram *programOut)
{
    constexpr char kVS[] = R"(#version 310 es
void main()
{
    // gl_VertexID    x    y
    //      0        -1   -1
    //      1         1   -1
    //      2        -1    1
    //      3         1    1
    int bit0 = gl_VertexID & 1;
    int bit1 = gl_VertexID >> 1;
    gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
})";

    constexpr char kFS[] = R"(#version 310 es
precision mediump float;
layout(binding = 0, offset = 0) uniform atomic_uint ac[4];
out vec4 colorOut;
void main()
{
    uvec4 acValue = uvec4(atomicCounterIncrement(ac[0]),
                          atomicCounterIncrement(ac[1]),
                          atomicCounterIncrement(ac[2]),
                          atomicCounterIncrement(ac[3]));

    if (all(equal(acValue, uvec4(10, 20, 30, 40))))
        colorOut = vec4(0, 1.0, 0, 1.0);
    else
        colorOut = vec4(1.0, 0, 0, 1.0);
})";

    programOut->makeRaster(kVS, kFS);
    ASSERT_TRUE(programOut->valid());
    glUseProgram(*programOut);

    glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, buffer);
    glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, buffer);
    EXPECT_GL_NO_ERROR();
}

void MemoryBarrierTestBase::atomicCounterBitBufferWriteThenAtomic(ShaderWritePipeline writePipeline,
                                                                  WriteResource writeResource,
                                                                  NoopOp preBarrierOp,
                                                                  NoopOp postBarrierOp)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    GLBuffer atomicCounterBuffer;
    GLTexture atomicCounterTextureBuffer;
    constexpr std::array<uint32_t, 4> kInitData = {0x12345678u, 0x9ABCDEF0u, 0x13579BDFu,
                                                   0x2468ACE0u};
    createStorageBuffer(writeResource, atomicCounterBuffer, atomicCounterTextureBuffer,
                        sizeof(kInitData), kInitData.data());

    constexpr std::array<uint32_t, 4> kWriteData = {10, 20, 30, 40};
    const std::array<float, 4> kWriteDataAsFloat = {
        *reinterpret_cast<const float *>(&kWriteData[0]),
        *reinterpret_cast<const float *>(&kWriteData[1]),
        *reinterpret_cast<const float *>(&kWriteData[2]),
        *reinterpret_cast<const float *>(&kWriteData[3]),
    };
    setUniformData(writeProgram, kWriteDataAsFloat);

    // Fill the buffer
    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(GL_ATOMIC_COUNTER_BARRIER_BIT);

    noopOp(postBarrierOp);

    // Use the buffer
    GLProgram readProgram;
    createAtomicCounterVerifyProgram(atomicCounterBuffer, &readProgram);

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    EXPECT_GL_NO_ERROR();

    constexpr std::array<uint32_t, 4> kExpectedData = {11, 21, 31, 41};
    verifyFramebufferAndBufferContents(writePipeline, kExpectedData);
}

void MemoryBarrierTestBase::atomicCounterBitAtomicThenBufferWrite(ShaderWritePipeline writePipeline,
                                                                  WriteResource writeResource,
                                                                  NoopOp preBarrierOp,
                                                                  NoopOp postBarrierOp,
                                                                  GLbitfield barrierBit)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);

    GLBuffer atomicCounterBuffer;
    GLTexture atomicCounterTextureBuffer;
    constexpr std::array<uint32_t, 4> kInitData = {10, 20, 30, 40};
    createStorageBuffer(writeResource, atomicCounterBuffer, atomicCounterTextureBuffer,
                        sizeof(kInitData), kInitData.data());

    // Use the buffer
    GLProgram readProgram;
    createAtomicCounterVerifyProgram(atomicCounterBuffer, &readProgram);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    EXPECT_GL_NO_ERROR();

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(barrierBit);

    noopOp(postBarrierOp);

    // Fill the buffer
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
    setUniformData(writeProgram, kWriteData);

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    verifyFramebufferAndBufferContents(writePipeline, kWriteData);
}

void MemoryBarrierTestBase::createSsboVerifyProgram(WriteResource writeResource,
                                                    GLProgram *programOut)
{
    constexpr char kVS[] = R"(#version 310 es
void main()
{
    // gl_VertexID    x    y
    //      0        -1   -1
    //      1         1   -1
    //      2        -1    1
    //      3         1    1
    int bit0 = gl_VertexID & 1;
    int bit1 = gl_VertexID >> 1;
    gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
})";

    constexpr char kFS[] = R"(#version 310 es
precision mediump float;
layout(std430, binding = 0) buffer block {
    vec4 data;
} inBlock;
out vec4 colorOut;
void main()
{
    if (all(lessThan(abs(inBlock.data - vec4(1.5, 3.75, 5.0, 12.125)), vec4(0.01))))
        colorOut = vec4(0, 1.0, 0, 1.0);
    else
        colorOut = vec4(1.0, 0, 0, 1.0);
})";

    programOut->makeRaster(kVS, kFS);
    ASSERT_TRUE(programOut->valid());
    glUseProgram(*programOut);
}

void MemoryBarrierTestBase::shaderStorageBitBufferWriteThenBufferRead(
    ShaderWritePipeline writePipeline,
    WriteResource writeResource,
    NoopOp preBarrierOp,
    NoopOp postBarrierOp)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    GLBuffer writeBuffer;
    GLTexture writeTextureBuffer;
    constexpr std::array<float, 4> kInitData = {12.34, 5.6, 78.91, 123.456};
    createStorageBuffer(writeResource, writeBuffer, writeTextureBuffer, sizeof(kInitData),
                        kInitData.data());

    constexpr std::array<float, 4> kWriteData = {1.5, 3.75, 5.0, 12.125};
    setUniformData(writeProgram, kWriteData);

    // Fill the buffer
    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);

    noopOp(postBarrierOp);

    // Use the buffer
    GLProgram readProgram;
    createSsboVerifyProgram(writeResource, &readProgram);

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    EXPECT_GL_NO_ERROR();

    verifyFramebufferAndBufferContents(writePipeline, kWriteData);
}

void MemoryBarrierTestBase::shaderStorageBitBufferReadThenBufferWrite(
    ShaderWritePipeline writePipeline,
    WriteResource writeResource,
    NoopOp preBarrierOp,
    NoopOp postBarrierOp,
    GLbitfield barrierBit)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);

    GLBuffer writeBuffer;
    GLTexture writeTextureBuffer;
    constexpr std::array<float, 4> kInitData = {1.5, 3.75, 5.0, 12.125};
    createStorageBuffer(writeResource, writeBuffer, writeTextureBuffer, sizeof(kInitData),
                        kInitData.data());

    // Use the buffer
    GLProgram readProgram;
    createSsboVerifyProgram(writeResource, &readProgram);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    EXPECT_GL_NO_ERROR();

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(barrierBit);

    noopOp(postBarrierOp);

    // Fill the image
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    constexpr std::array<float, 4> kWriteData = {12.34, 5.6, 78.91, 123.456};
    setUniformData(writeProgram, kWriteData);

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    verifyFramebufferAndBufferContents(writePipeline, kWriteData);
}

void MemoryBarrierTestBase::createTextureVerifyProgram(WriteResource writeResource,
                                                       GLuint texture,
                                                       GLProgram *programOut)
{
    constexpr char kVS[] = R"(#version 310 es
void main()
{
    // gl_VertexID    x    y
    //      0        -1   -1
    //      1         1   -1
    //      2        -1    1
    //      3         1    1
    int bit0 = gl_VertexID & 1;
    int bit1 = gl_VertexID >> 1;
    gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
})";

    constexpr char kImageFS[] = R"(#version 310 es
precision mediump float;
uniform sampler2D s;
out vec4 colorOut;
void main()
{
    if (all(lessThan(abs(texelFetch(s, ivec2(0, 0), 0)- vec4(0.125, 0.25, 0.5, 0.75)), vec4(0.01))))
        colorOut = vec4(0, 1.0, 0, 1.0);
    else
        colorOut = vec4(1.0, 0, 0, 1.0);
})";

    constexpr char kImageBufferFS[] = R"(#version 310 es
#extension GL_OES_texture_buffer : require
precision mediump float;
uniform highp samplerBuffer s;
out vec4 colorOut;
void main()
{
    if (texelFetch(s, 0) == vec4(0.125, 0.25, 0.5, 0.75))
        colorOut = vec4(0, 1.0, 0, 1.0);
    else
        colorOut = vec4(1.0, 0, 0, 1.0);
})";

    programOut->makeRaster(kVS,
                           writeResource == WriteResource::ImageBuffer ? kImageBufferFS : kImageFS);
    ASSERT_TRUE(programOut->valid());
    glUseProgram(*programOut);

    glBindTexture(writeResource == WriteResource::ImageBuffer ? GL_TEXTURE_BUFFER : GL_TEXTURE_2D,
                  texture);
    EXPECT_GL_NO_ERROR();
}

void MemoryBarrierTestBase::textureFetchBitImageWriteThenSamplerRead(
    ShaderWritePipeline writePipeline,
    WriteResource writeResource,
    NoopOp preBarrierOp,
    NoopOp postBarrierOp)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    GLBuffer textureBufferStorage;
    GLTexture texture;
    constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
    createStorageImage(writeResource, textureBufferStorage, texture, kInitData);

    constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
    setUniformData(writeProgram, kWriteData);

    // Fill the image
    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);

    noopOp(postBarrierOp);

    // Use the image
    GLProgram readProgram;
    createTextureVerifyProgram(writeResource, texture, &readProgram);

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    EXPECT_GL_NO_ERROR();

    verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
}

void MemoryBarrierTestBase::textureFetchBitSamplerReadThenImageWrite(
    ShaderWritePipeline writePipeline,
    WriteResource writeResource,
    NoopOp preBarrierOp,
    NoopOp postBarrierOp,
    GLbitfield barrierBit)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);

    GLBuffer textureBufferStorage;
    GLTexture texture;
    constexpr std::array<float, 4> kInitData = {0.125, 0.25, 0.5, 0.75};
    createStorageImage(writeResource, textureBufferStorage, texture, kInitData);

    // Use the image
    GLProgram readProgram;
    createTextureVerifyProgram(writeResource, texture, &readProgram);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    EXPECT_GL_NO_ERROR();

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(barrierBit);

    noopOp(postBarrierOp);

    // Fill the image
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    constexpr std::array<float, 4> kWriteData = {0.65, 0.20, 0.40, 0.95};
    setUniformData(writeProgram, kWriteData);

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
}

void MemoryBarrierTestBase::createImageVerifyProgram(WriteResource writeResource,
                                                     GLuint texture,
                                                     GLProgram *programOut)
{
    constexpr char kVS[] = R"(#version 310 es
void main()
{
    // gl_VertexID    x    y
    //      0        -1   -1
    //      1         1   -1
    //      2        -1    1
    //      3         1    1
    int bit0 = gl_VertexID & 1;
    int bit1 = gl_VertexID >> 1;
    gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
})";

    constexpr char kImageFS[] = R"(#version 310 es
precision mediump float;
layout(rgba8, binding = 0) uniform highp readonly image2D img;
out vec4 colorOut;
void main()
{
    if (all(lessThan(abs(imageLoad(img, ivec2(0, 0))- vec4(0.125, 0.25, 0.5, 0.75)), vec4(0.01))))
        colorOut = vec4(0, 1.0, 0, 1.0);
    else
        colorOut = vec4(1.0, 0, 0, 1.0);
})";

    constexpr char kImageBufferFS[] = R"(#version 310 es
#extension GL_OES_texture_buffer : require
precision mediump float;
layout(rgba32f, binding = 0) uniform highp readonly imageBuffer img;
out vec4 colorOut;
void main()
{
    if (imageLoad(img, 0) == vec4(0.125, 0.25, 0.5, 0.75))
        colorOut = vec4(0, 1.0, 0, 1.0);
    else
        colorOut = vec4(1.0, 0, 0, 1.0);
})";

    programOut->makeRaster(kVS,
                           writeResource == WriteResource::ImageBuffer ? kImageBufferFS : kImageFS);
    ASSERT_TRUE(programOut->valid());
    glUseProgram(*programOut);

    if (writeResource == WriteResource::ImageBuffer)
    {
        glBindTexture(GL_TEXTURE_BUFFER, texture);
        glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA32F);
    }
    else
    {
        glBindTexture(GL_TEXTURE_2D, texture);
        glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
    }
    EXPECT_GL_NO_ERROR();
}

void MemoryBarrierTestBase::shaderImageAccessBitImageWriteThenImageRead(
    ShaderWritePipeline writePipeline,
    WriteResource writeResource,
    NoopOp preBarrierOp,
    NoopOp postBarrierOp)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    GLBuffer textureBufferStorage;
    GLTexture texture;
    constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
    createStorageImage(writeResource, textureBufferStorage, texture, kInitData);

    constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
    setUniformData(writeProgram, kWriteData);

    // Fill the image
    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

    noopOp(postBarrierOp);

    // Use the image
    GLProgram readProgram;
    createImageVerifyProgram(writeResource, texture, &readProgram);

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    EXPECT_GL_NO_ERROR();

    verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
}

void MemoryBarrierTestBase::shaderImageAccessBitImageReadThenImageWrite(
    ShaderWritePipeline writePipeline,
    WriteResource writeResource,
    NoopOp preBarrierOp,
    NoopOp postBarrierOp)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::black);

    GLBuffer textureBufferStorage;
    GLTexture texture;
    constexpr std::array<float, 4> kInitData = {0.125, 0.25, 0.5, 0.75};
    createStorageImage(writeResource, textureBufferStorage, texture, kInitData);

    // Use the image
    GLProgram readProgram;
    createImageVerifyProgram(writeResource, texture, &readProgram);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    EXPECT_GL_NO_ERROR();

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

    noopOp(postBarrierOp);

    // Fill the image
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    constexpr std::array<float, 4> kWriteData = {0.65, 0.20, 0.40, 0.95};
    setUniformData(writeProgram, kWriteData);

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
}

void MemoryBarrierTestBase::textureUpdateBitImageWriteThenCopy(ShaderWritePipeline writePipeline,
                                                               WriteResource writeResource,
                                                               NoopOp preBarrierOp,
                                                               NoopOp postBarrierOp)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::green);
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    GLBuffer textureBufferStorage;
    GLTexture texture;
    constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
    createStorageImage(writeResource, textureBufferStorage, texture, kInitData);

    constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
    setUniformData(writeProgram, kWriteData);

    // Fill the image
    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
        glDisable(GL_BLEND);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);

    noopOp(postBarrierOp);

    // Copy from framebuffer over the texture
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kTextureSize, kTextureSize);

    const std::array<float, 4> kExpectedData = {
        0, 1.0f, writePipeline == ShaderWritePipeline::Graphics ? 1.0f : 0, 1.0f};
    verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kExpectedData);
}

void MemoryBarrierTestBase::textureUpdateBitCopyThenImageWrite(ShaderWritePipeline writePipeline,
                                                               WriteResource writeResource,
                                                               NoopOp preBarrierOp,
                                                               NoopOp postBarrierOp,
                                                               GLbitfield barrierBit)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::green);

    GLBuffer textureBufferStorage;
    GLTexture texture;
    constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
    createStorageImage(writeResource, textureBufferStorage, texture, kInitData);

    // Copy from framebuffer over the texture
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kTextureSize, kTextureSize);

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(barrierBit);

    noopOp(postBarrierOp);

    // Fill the image
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
    setUniformData(writeProgram, kWriteData);

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
}

void MemoryBarrierTestBase::framebufferBitImageWriteThenDraw(ShaderWritePipeline writePipeline,
                                                             WriteResource writeResource,
                                                             NoopOp preBarrierOp,
                                                             NoopOp postBarrierOp)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::green);
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    GLBuffer textureBufferStorage;
    GLTexture texture;
    constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
    createStorageImage(writeResource, textureBufferStorage, texture, kInitData);

    constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
    setUniformData(writeProgram, kWriteData);

    // Fill the image
    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
        glDisable(GL_BLEND);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);

    noopOp(postBarrierOp);

    // Draw to image via framebuffer
    ANGLE_GL_PROGRAM(verifyProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(verifyProgram);
    GLint colorUniformLocation =
        glGetUniformLocation(verifyProgram, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);
    setupVertexArray(ShaderWritePipeline::Graphics, verifyProgram);

    GLFramebuffer drawFbo;
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFbo);
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);

    constexpr std::array<float, 4> kBlendData = {0.125, 0.25, 0.5, 0.25};
    glUniform4fv(colorUniformLocation, 1, kBlendData.data());

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glDisable(GL_BLEND);
    EXPECT_GL_NO_ERROR();

    const std::array<float, 4> kExpectedData = {
        kWriteData[0] + kBlendData[0],
        kWriteData[1] + kBlendData[1],
        kWriteData[2] + kBlendData[2],
        kWriteData[3] + kBlendData[3],
    };
    verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kExpectedData);
}

void MemoryBarrierTestBase::framebufferBitImageWriteThenReadPixels(
    ShaderWritePipeline writePipeline,
    WriteResource writeResource,
    NoopOp preBarrierOp,
    NoopOp postBarrierOp)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::green);
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    GLBuffer textureBufferStorage;
    GLTexture texture;
    constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
    createStorageImage(writeResource, textureBufferStorage, texture, kInitData);

    constexpr std::array<float, 4> kWriteData = {1.0, 1.0, 0.0, 1.0};
    setUniformData(writeProgram, kWriteData);

    // Fill the image
    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
        glDisable(GL_BLEND);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);

    noopOp(postBarrierOp);

    // Read from image via framebuffer
    GLBuffer packBuffer;
    glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
    constexpr std::array<uint32_t, 4> kPBOInitData = {0x12345678u, 0x9ABCDEF0u, 0x13579BDFu,
                                                      0x2468ACE0u};
    glBufferData(GL_PIXEL_PACK_BUFFER, sizeof(kInitData), kPBOInitData.data(), GL_STATIC_DRAW);
    EXPECT_GL_NO_ERROR();

    GLFramebuffer readFbo;
    glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
    glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);

    glReadPixels(0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
    EXPECT_GL_NO_ERROR();

    verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);

    // Verify the PBO for completeness
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, packBuffer);
    constexpr std::array<uint32_t, 4> kExpectedData = {
        0xFF00FFFFu,
        kPBOInitData[1],
        kPBOInitData[2],
        kPBOInitData[3],
    };
    verifyBufferContents(kExpectedData);
}

void MemoryBarrierTestBase::framebufferBitImageWriteThenCopy(ShaderWritePipeline writePipeline,
                                                             WriteResource writeResource,
                                                             NoopOp preBarrierOp,
                                                             NoopOp postBarrierOp)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::green);
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    GLBuffer textureBufferStorage;
    GLTexture texture;
    constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
    createStorageImage(writeResource, textureBufferStorage, texture, kInitData);

    constexpr std::array<float, 4> kWriteData = {1.0, 1.0, 0.0, 1.0};
    setUniformData(writeProgram, kWriteData);

    // Fill the image
    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
        glDisable(GL_BLEND);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);

    noopOp(postBarrierOp);

    // Copy from framebuffer to another texture
    GLFramebuffer readFbo;
    glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
    glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);

    GLTexture copyTexture;
    glBindTexture(GL_TEXTURE_2D, copyTexture);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureSize, kTextureSize);
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kTextureSize, kTextureSize);

    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
    EXPECT_GL_NO_ERROR();

    verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);

    // Verify the copy texture for completeness
    verifyImageContents(copyTexture, kWriteData);
}

void MemoryBarrierTestBase::framebufferBitImageWriteThenBlit(ShaderWritePipeline writePipeline,
                                                             WriteResource writeResource,
                                                             NoopOp preBarrierOp,
                                                             NoopOp postBarrierOp)
{
    GLTexture blitColor;
    GLFramebuffer blitFbo;
    createFramebuffer(blitColor, blitFbo, GLColor::black);

    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::green);
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    GLBuffer textureBufferStorage;
    GLTexture texture;
    constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
    createStorageImage(writeResource, textureBufferStorage, texture, kInitData);

    constexpr std::array<float, 4> kWriteData = {1.0, 1.0, 0.0, 1.0};
    setUniformData(writeProgram, kWriteData);

    // Fill the image
    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
        glDisable(GL_BLEND);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);

    noopOp(postBarrierOp);

    // Blit from framebuffer to another framebuffer
    GLFramebuffer readFbo;
    glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
    glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);

    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, blitFbo);
    glBlitFramebuffer(0, 0, kTextureSize, kTextureSize, 0, 0, kTextureSize, kTextureSize,
                      GL_COLOR_BUFFER_BIT, GL_NEAREST);
    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
    EXPECT_GL_NO_ERROR();

    verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);

    // Verify the blit fbo for completeness
    glBindFramebuffer(GL_READ_FRAMEBUFFER, blitFbo);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
}

void MemoryBarrierTestBase::framebufferBitDrawThenImageWrite(ShaderWritePipeline writePipeline,
                                                             WriteResource writeResource,
                                                             NoopOp preBarrierOp,
                                                             NoopOp postBarrierOp,
                                                             GLbitfield barrierBit)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::green);

    GLBuffer textureBufferStorage;
    GLTexture texture;
    constexpr std::array<float, 4> kInitData = {0.65, 0.92, 0.11, 0.54};
    createStorageImage(writeResource, textureBufferStorage, texture, kInitData);

    // Draw to image via framebuffer
    ANGLE_GL_PROGRAM(verifyProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    glUseProgram(verifyProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(ShaderWritePipeline::Graphics, verifyProgram);

    GLFramebuffer drawFbo;
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFbo);
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);

    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
    EXPECT_GL_NO_ERROR();

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(barrierBit);

    noopOp(postBarrierOp);

    // Fill the image
    createProgram(writePipeline, writeResource, &writeProgram);

    setupVertexArray(writePipeline, writeProgram);

    constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
    setUniformData(writeProgram, kWriteData);

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);
}

void MemoryBarrierTestBase::framebufferBitReadPixelsThenImageWrite(
    ShaderWritePipeline writePipeline,
    WriteResource writeResource,
    NoopOp preBarrierOp,
    NoopOp postBarrierOp,
    GLbitfield barrierBit)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::green);

    GLBuffer textureBufferStorage;
    GLTexture texture;
    constexpr std::array<float, 4> kInitData = {1.0, 1.0, 0.0, 1.0};
    createStorageImage(writeResource, textureBufferStorage, texture, kInitData);

    // Read from image via framebuffer
    GLBuffer packBuffer;
    glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
    constexpr std::array<uint32_t, 4> kPBOInitData = {0x12345678u, 0x9ABCDEF0u, 0x13579BDFu,
                                                      0x2468ACE0u};
    glBufferData(GL_PIXEL_PACK_BUFFER, sizeof(kInitData), kPBOInitData.data(), GL_STATIC_DRAW);
    EXPECT_GL_NO_ERROR();

    GLFramebuffer readFbo;
    glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
    glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);

    glReadPixels(0, 0, kTextureSize, kTextureSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
    EXPECT_GL_NO_ERROR();

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(barrierBit);

    noopOp(postBarrierOp);

    // Fill the image
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
    setUniformData(writeProgram, kWriteData);

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);

    // Verify the PBO for completeness
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, packBuffer);
    constexpr std::array<uint32_t, 4> kExpectedData = {
        0xFF00FFFFu,
        kPBOInitData[1],
        kPBOInitData[2],
        kPBOInitData[3],
    };
    verifyBufferContents(kExpectedData);
}

void MemoryBarrierTestBase::framebufferBitCopyThenImageWrite(ShaderWritePipeline writePipeline,
                                                             WriteResource writeResource,
                                                             NoopOp preBarrierOp,
                                                             NoopOp postBarrierOp,
                                                             GLbitfield barrierBit)
{
    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::green);

    GLBuffer textureBufferStorage;
    GLTexture texture;
    constexpr std::array<float, 4> kInitData = {1.0, 1.0, 0.0, 1.0};
    createStorageImage(writeResource, textureBufferStorage, texture, kInitData);

    // Copy from framebuffer to another texture
    GLFramebuffer readFbo;
    glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
    glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);

    GLTexture copyTexture;
    glBindTexture(GL_TEXTURE_2D, copyTexture);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTextureSize, kTextureSize);
    glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kTextureSize, kTextureSize);

    glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
    EXPECT_GL_NO_ERROR();

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(barrierBit);

    noopOp(postBarrierOp);

    // Fill the image
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
    setUniformData(writeProgram, kWriteData);

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);

    // Verify the copy texture for completeness
    verifyImageContents(copyTexture, kInitData);
}

void MemoryBarrierTestBase::framebufferBitBlitThenImageWrite(ShaderWritePipeline writePipeline,
                                                             WriteResource writeResource,
                                                             NoopOp preBarrierOp,
                                                             NoopOp postBarrierOp,
                                                             GLbitfield barrierBit)
{
    GLTexture blitColor;
    GLFramebuffer blitFbo;
    createFramebuffer(blitColor, blitFbo, GLColor::black);

    GLTexture color;
    GLFramebuffer fbo;
    GLProgram writeProgram;

    createFramebuffer(color, fbo, GLColor::green);

    GLBuffer textureBufferStorage;
    GLTexture texture;
    constexpr std::array<float, 4> kInitData = {1.0, 1.0, 0.0, 1.0};
    createStorageImage(writeResource, textureBufferStorage, texture, kInitData);

    // Blit from framebuffer to another framebuffer
    GLFramebuffer readFbo;
    glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
    glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);

    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, blitFbo);
    glBlitFramebuffer(0, 0, kTextureSize, kTextureSize, 0, 0, kTextureSize, kTextureSize,
                      GL_COLOR_BUFFER_BIT, GL_NEAREST);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    EXPECT_GL_NO_ERROR();

    noopOp(preBarrierOp);

    // Issue the appropriate memory barrier
    glMemoryBarrier(barrierBit);

    noopOp(postBarrierOp);

    // Fill the image
    createProgram(writePipeline, writeResource, &writeProgram);

    GLBuffer positionBuffer;
    createQuadVertexArray(positionBuffer);
    setupVertexArray(writePipeline, writeProgram);

    constexpr std::array<float, 4> kWriteData = {0.125, 0.25, 0.5, 0.75};
    setUniformData(writeProgram, kWriteData);

    if (writePipeline == ShaderWritePipeline::Graphics)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    else
    {
        glDispatchCompute(1, 1, 1);
    }

    verifyFramebufferAndImageContents(writePipeline, writeResource, texture, kWriteData);

    // Verify the blit fbo for completeness
    glBindFramebuffer(GL_READ_FRAMEBUFFER, blitFbo);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
}

class MemoryBarrierBufferTest : public MemoryBarrierTestBase,
                                public ANGLETestWithParam<MemoryBarrierVariationsTestParams>
{
  protected:
    MemoryBarrierBufferTest()
    {
        setWindowWidth(16);
        setWindowHeight(32);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }
};

class MemoryBarrierImageTest : public MemoryBarrierTestBase,
                               public ANGLETestWithParam<MemoryBarrierVariationsTestParams>
{
  protected:
    MemoryBarrierImageTest()
    {
        setWindowWidth(16);
        setWindowHeight(32);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }
};

class MemoryBarrierImageBufferOnlyTest
    : public MemoryBarrierTestBase,
      public ANGLETestWithParam<MemoryBarrierVariationsTestParams>
{
  protected:
    MemoryBarrierImageBufferOnlyTest()
    {
        setWindowWidth(16);
        setWindowHeight(32);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }
};

class MemoryBarrierImageOnlyTest : public MemoryBarrierTestBase,
                                   public ANGLETestWithParam<MemoryBarrierVariationsTestParams>
{
  protected:
    MemoryBarrierImageOnlyTest()
    {
        setWindowWidth(16);
        setWindowHeight(32);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }
};

class MemoryBarrierBufferOnlyTest : public MemoryBarrierTestBase,
                                    public ANGLETestWithParam<MemoryBarrierVariationsTestParams>
{
  protected:
    MemoryBarrierBufferOnlyTest()
    {
        setWindowWidth(16);
        setWindowHeight(32);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }
};

// Test GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT; shader write -> vertex read
TEST_P(MemoryBarrierBufferTest, VertexAtrribArrayBitWriteThenVertexRead)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    vertexAttribArrayBitBufferWriteThenVertexRead(writePipeline, writeResource, preBarrierOp,
                                                  postBarrierOp);
}

// Test GL_ELEMENT_ARRAY_BARRIER_BIT; shader write -> index read
TEST_P(MemoryBarrierBufferTest, ElementArrayBitWriteThenIndexRead)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    elementArrayBitBufferWriteThenIndexRead(writePipeline, writeResource, preBarrierOp,
                                            postBarrierOp);
}

// Test GL_UNIFORM_BARRIER_BIT; shader write -> ubo read
TEST_P(MemoryBarrierBufferTest, UniformBitWriteThenUBORead)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    uniformBitBufferWriteThenUBORead(writePipeline, writeResource, preBarrierOp, postBarrierOp);
}

// Test GL_TEXTURE_FETCH_BARRIER_BIT; shader write -> sampler read
TEST_P(MemoryBarrierImageTest, TextureFetchBitWriteThenSamplerRead)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    textureFetchBitImageWriteThenSamplerRead(writePipeline, writeResource, preBarrierOp,
                                             postBarrierOp);
}

// Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; shader write -> image read
TEST_P(MemoryBarrierImageTest, ShaderImageAccessBitWriteThenImageRead)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    shaderImageAccessBitImageWriteThenImageRead(writePipeline, writeResource, preBarrierOp,
                                                postBarrierOp);
}

// Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; image read -> shader write
TEST_P(MemoryBarrierImageTest, ShaderImageAccessBitImageReadThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    // Looks like the implementation is missing this line from the spec:
    //
    // > Additionally, image stores issued after the barrier will not execute until all memory
    // > accesses (e.g., loads, stores, texture fetches, vertex fetches) initiated prior to the
    // > barrier complete.
    //
    // http://anglebug.com/5650
    ANGLE_SKIP_TEST_IF(IsOpenGL() && IsNVIDIA() && writeResource == WriteResource::Image);

    shaderImageAccessBitImageReadThenImageWrite(writePipeline, writeResource, preBarrierOp,
                                                postBarrierOp);
}

// Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; vertex read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitVertexReadThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    vertexAttribArrayBitVertexReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
                                                  postBarrierOp,
                                                  GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}

// Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; index read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitIndexReadThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    elementArrayBitIndexReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
                                            postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}

// Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; ubo read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitUBOReadThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    uniformBitUBOReadThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
                                     GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}

// Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; sampler read -> shader write
TEST_P(MemoryBarrierImageTest, ShaderImageAccessBitSamplerReadThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    textureFetchBitSamplerReadThenImageWrite(writePipeline, writeResource, preBarrierOp,
                                             postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}

// Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; indirect read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitIndirectReadThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    commandBitIndirectReadThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
                                          GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}

// Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; pixel pack -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitPackThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    pixelBufferBitPackThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
                                      GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}

// Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; pixel unpack -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitUnpackThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    pixelBufferBitUnpackThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
                                        GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}

// Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; texture copy -> shader write
TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitCopyThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    textureUpdateBitCopyThenImageWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
                                       GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}

// Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; buffer copy -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitCopyThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    bufferUpdateBitCopyThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
                                       GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}

// Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; draw -> shader write
TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitDrawThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    framebufferBitDrawThenImageWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
                                     GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}

// Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; read pixels -> shader write
TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitReadPixelsThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    framebufferBitReadPixelsThenImageWrite(writePipeline, writeResource, preBarrierOp,
                                           postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}

// Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; fbo copy -> shader write
TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitFBOCopyThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    framebufferBitCopyThenImageWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
                                     GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}

// Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; blit -> shader write
TEST_P(MemoryBarrierImageOnlyTest, ShaderImageAccessBitBlitThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    framebufferBitBlitThenImageWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
                                     GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}

// Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; xfb capture -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitCaptureThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    transformFeedbackBitCaptureThenBufferWrite(writePipeline, writeResource, preBarrierOp,
                                               postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}

// Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; atomic write -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitAtomicThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    atomicCounterBitAtomicThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
                                          GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}

// Test GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; buffer read -> shader write
TEST_P(MemoryBarrierImageBufferOnlyTest, ShaderImageAccessBitBufferReadThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    shaderStorageBitBufferReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
                                              postBarrierOp, GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}

// Test GL_COMMAND_BARRIER_BIT; shader write -> indirect read
TEST_P(MemoryBarrierBufferTest, CommandBitWriteThenIndirectRead)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    commandBitBufferWriteThenIndirectRead(writePipeline, writeResource, preBarrierOp,
                                          postBarrierOp);
}

// Test GL_PIXEL_BUFFER_BARRIER_BIT; shader write -> pixel pack
TEST_P(MemoryBarrierBufferTest, PixelBufferBitWriteThenPack)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    pixelBufferBitBufferWriteThenPack(writePipeline, writeResource, preBarrierOp, postBarrierOp);
}

// Test GL_PIXEL_BUFFER_BARRIER_BIT; shader write -> pixel unpack
TEST_P(MemoryBarrierBufferTest, PixelBufferBitWriteThenUnpack)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    pixelBufferBitBufferWriteThenUnpack(writePipeline, writeResource, preBarrierOp, postBarrierOp);
}

// Test GL_TEXTURE_UPDATE_BARRIER_BIT; shader write -> texture copy
TEST_P(MemoryBarrierImageOnlyTest, TextureUpdateBitWriteThenCopy)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    textureUpdateBitImageWriteThenCopy(writePipeline, writeResource, preBarrierOp, postBarrierOp);
}

// Test GL_BUFFER_UPDATE_BARRIER_BIT; shader write -> buffer copy
TEST_P(MemoryBarrierBufferTest, BufferUpdateBitWriteThenCopy)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    bufferUpdateBitBufferWriteThenCopy(writePipeline, writeResource, preBarrierOp, postBarrierOp);
}

// Test GL_FRAMEBUFFER_BARRIER_BIT; shader write -> draw
TEST_P(MemoryBarrierImageOnlyTest, FramebufferBitWriteThenDraw)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    framebufferBitImageWriteThenDraw(writePipeline, writeResource, preBarrierOp, postBarrierOp);
}

// Test GL_FRAMEBUFFER_BARRIER_BIT; shader write -> read pixels
TEST_P(MemoryBarrierImageOnlyTest, FramebufferBitWriteThenReadPixels)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    framebufferBitImageWriteThenReadPixels(writePipeline, writeResource, preBarrierOp,
                                           postBarrierOp);
}

// Test GL_FRAMEBUFFER_BARRIER_BIT; shader write -> copy
TEST_P(MemoryBarrierImageOnlyTest, FramebufferBitWriteThenCopy)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    framebufferBitImageWriteThenCopy(writePipeline, writeResource, preBarrierOp, postBarrierOp);
}

// Test GL_FRAMEBUFFER_BARRIER_BIT; shader write -> blit
TEST_P(MemoryBarrierImageOnlyTest, FramebufferBitWriteThenBlit)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    framebufferBitImageWriteThenBlit(writePipeline, writeResource, preBarrierOp, postBarrierOp);
}

// Test GL_TRANSFORM_FEEDBACK_BARRIER_BIT; shader write -> xfb capture
TEST_P(MemoryBarrierBufferTest, TransformFeedbackBitWriteThenCapture)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    transformFeedbackBitBufferWriteThenCapture(writePipeline, writeResource, preBarrierOp,
                                               postBarrierOp);
}

// Test GL_ATOMIC_COUNTER_BARRIER_BIT; shader write -> atomic write
TEST_P(MemoryBarrierBufferTest, AtomicCounterBitWriteThenAtomic)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    atomicCounterBitBufferWriteThenAtomic(writePipeline, writeResource, preBarrierOp,
                                          postBarrierOp);
}

// Test GL_SHADER_STORAGE_BARRIER_BIT; shader write -> shader read
TEST_P(MemoryBarrierBufferTest, ShaderStorageBitWriteThenRead)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    shaderStorageBitBufferWriteThenBufferRead(writePipeline, writeResource, preBarrierOp,
                                              postBarrierOp);
}

// Test GL_SHADER_STORAGE_BARRIER_BIT; shader read -> buffer write
TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitReadThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    shaderStorageBitBufferReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
                                              postBarrierOp, GL_SHADER_STORAGE_BARRIER_BIT);
}

// Test GL_SHADER_STORAGE_BARRIER_BIT; vertex read -> shader write
TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitVertexReadThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    vertexAttribArrayBitVertexReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
                                                  postBarrierOp, GL_SHADER_STORAGE_BARRIER_BIT);
}

// Test GL_SHADER_STORAGE_BARRIER_BIT; index read -> shader write
TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitIndexReadThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    elementArrayBitIndexReadThenBufferWrite(writePipeline, writeResource, preBarrierOp,
                                            postBarrierOp, GL_SHADER_STORAGE_BARRIER_BIT);
}

// Test GL_SHADER_STORAGE_BARRIER_BIT; ubo read -> shader write
TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitUBOReadThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    uniformBitUBOReadThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
                                     GL_SHADER_STORAGE_BARRIER_BIT);
}

// Test GL_SHADER_STORAGE_BARRIER_BIT; indirect read -> shader write
TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitIndirectReadThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    commandBitIndirectReadThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
                                          GL_SHADER_STORAGE_BARRIER_BIT);
}

// Test GL_SHADER_STORAGE_BARRIER_BIT; pixel pack -> shader write
TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitPackThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    pixelBufferBitPackThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
                                      GL_SHADER_STORAGE_BARRIER_BIT);
}

// Test GL_SHADER_STORAGE_BARRIER_BIT; pixel unpack -> shader write
TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitUnpackThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    pixelBufferBitUnpackThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
                                        GL_SHADER_STORAGE_BARRIER_BIT);
}

// Test GL_SHADER_STORAGE_BARRIER_BIT; buffer copy -> shader write
TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitCopyThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    bufferUpdateBitCopyThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
                                       GL_SHADER_STORAGE_BARRIER_BIT);
}

// Test GL_SHADER_STORAGE_BARRIER_BIT; xfb capture -> shader write
TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitCaptureThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    transformFeedbackBitCaptureThenBufferWrite(writePipeline, writeResource, preBarrierOp,
                                               postBarrierOp, GL_SHADER_STORAGE_BARRIER_BIT);
}

// Test GL_SHADER_STORAGE_BARRIER_BIT; atomic write -> shader write
TEST_P(MemoryBarrierBufferOnlyTest, ShaderStorageBitAtomicThenWrite)
{
    ShaderWritePipeline writePipeline;
    WriteResource writeResource;
    NoopOp preBarrierOp;
    NoopOp postBarrierOp;
    ParseMemoryBarrierVariationsTestParams(GetParam(), &writePipeline, &writeResource,
                                           &preBarrierOp, &postBarrierOp);

    ANGLE_SKIP_TEST_IF(!hasExtensions(writeResource));

    atomicCounterBitAtomicThenBufferWrite(writePipeline, writeResource, preBarrierOp, postBarrierOp,
                                          GL_SHADER_STORAGE_BARRIER_BIT);
}

constexpr ShaderWritePipeline kWritePipelines[] = {
    ShaderWritePipeline::Graphics,
    ShaderWritePipeline::Compute,
};
constexpr WriteResource kBufferWriteResources[] = {
    WriteResource::Buffer,
    WriteResource::ImageBuffer,
};
constexpr WriteResource kImageWriteResources[] = {
    WriteResource::Image,
    WriteResource::ImageBuffer,
};
constexpr WriteResource kImageBufferOnlyWriteResources[] = {
    WriteResource::ImageBuffer,
};
constexpr WriteResource kImageOnlyWriteResources[] = {
    WriteResource::Image,
};
constexpr WriteResource kBufferOnlyWriteResources[] = {
    WriteResource::Buffer,
};
constexpr NoopOp kNoopOps[] = {
    NoopOp::None,
    NoopOp::Draw,
    NoopOp::Dispatch,
};

// Note: due to large number of tests, these are only run on Vulkan and a single configuration
// (swiftshader).

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierBufferTest);
ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierBufferTest,
                                 MemoryBarrierVariationsTestPrint,
                                 testing::ValuesIn(kWritePipelines),
                                 testing::ValuesIn(kBufferWriteResources),
                                 testing::ValuesIn(kNoopOps),
                                 testing::ValuesIn(kNoopOps),
                                 ES31_VULKAN_SWIFTSHADER());

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierImageTest);
ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierImageTest,
                                 MemoryBarrierVariationsTestPrint,
                                 testing::ValuesIn(kWritePipelines),
                                 testing::ValuesIn(kImageWriteResources),
                                 testing::ValuesIn(kNoopOps),
                                 testing::ValuesIn(kNoopOps),
                                 ES31_VULKAN_SWIFTSHADER());

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierImageBufferOnlyTest);
ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierImageBufferOnlyTest,
                                 MemoryBarrierVariationsTestPrint,
                                 testing::ValuesIn(kWritePipelines),
                                 testing::ValuesIn(kImageBufferOnlyWriteResources),
                                 testing::ValuesIn(kNoopOps),
                                 testing::ValuesIn(kNoopOps),
                                 ES31_VULKAN_SWIFTSHADER());

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierImageOnlyTest);
ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierImageOnlyTest,
                                 MemoryBarrierVariationsTestPrint,
                                 testing::ValuesIn(kWritePipelines),
                                 testing::ValuesIn(kImageOnlyWriteResources),
                                 testing::ValuesIn(kNoopOps),
                                 testing::ValuesIn(kNoopOps),
                                 ES31_VULKAN_SWIFTSHADER());

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MemoryBarrierBufferOnlyTest);
ANGLE_INSTANTIATE_TEST_COMBINE_4(MemoryBarrierBufferOnlyTest,
                                 MemoryBarrierVariationsTestPrint,
                                 testing::ValuesIn(kWritePipelines),
                                 testing::ValuesIn(kBufferOnlyWriteResources),
                                 testing::ValuesIn(kNoopOps),
                                 testing::ValuesIn(kNoopOps),
                                 ES31_VULKAN_SWIFTSHADER());

}  // anonymous namespace
