//
// Copyright 2017 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.
//
// ProgramPipelineTest:
//   Various tests related to Program Pipeline.
//

#include "common/unsafe_buffers.h"
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"

using namespace angle;

namespace
{

class ProgramPipelineTest : public ANGLETest<>
{
  protected:
    ProgramPipelineTest()
    {
        setWindowWidth(64);
        setWindowHeight(64);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }
};

// Verify that program pipeline is not supported in version lower than ES31.
TEST_P(ProgramPipelineTest, GenerateProgramPipelineObject)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    GLuint pipeline;
    glGenProgramPipelines(1, &pipeline);
    if (getClientMajorVersion() < 3 || getClientMinorVersion() < 1)
    {
        EXPECT_GL_ERROR(GL_INVALID_OPERATION);
    }
    else
    {
        EXPECT_GL_NO_ERROR();

        glDeleteProgramPipelines(1, &pipeline);
        EXPECT_GL_NO_ERROR();
    }
}

// Verify that program pipeline errors out without GL_EXT_separate_shader_objects extension.
TEST_P(ProgramPipelineTest, GenerateProgramPipelineObjectEXT)
{
    GLuint pipeline;
    glGenProgramPipelinesEXT(1, &pipeline);
    if (!IsGLExtensionEnabled("GL_EXT_separate_shader_objects"))
    {
        EXPECT_GL_ERROR(GL_INVALID_OPERATION);
    }
    else
    {
        EXPECT_GL_NO_ERROR();

        glDeleteProgramPipelinesEXT(1, &pipeline);
        EXPECT_GL_NO_ERROR();
    }
}

class ProgramPipelineTest31 : public ProgramPipelineTest
{
  protected:
    void testTearDown() override
    {
        glDeleteProgram(mVertProg);
        glDeleteProgram(mFragProg);
        glDeleteProgramPipelines(1, &mPipeline);
    }

    void bindProgramPipeline(const GLchar *vertString, const GLchar *fragString);
    void drawQuadWithPPO(const std::string &positionAttribName,
                         const GLfloat positionAttribZ,
                         const GLfloat positionAttribXYScale);
    GLint getAvailableProgramBinaryFormatCount() const;

    GLuint mVertProg = 0;
    GLuint mFragProg = 0;
    GLuint mPipeline = 0;
};

class ProgramPipelineXFBTest31 : public ProgramPipelineTest31
{
  protected:
    void testSetUp() override
    {
        glGenBuffers(1, &mTransformFeedbackBuffer);
        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, mTransformFeedbackBuffer);
        glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, mTransformFeedbackBufferSize, nullptr,
                     GL_STATIC_DRAW);

        glGenTransformFeedbacks(1, &mTransformFeedback);

        ASSERT_GL_NO_ERROR();
    }
    void testTearDown() override
    {
        if (mTransformFeedbackBuffer != 0)
        {
            glDeleteBuffers(1, &mTransformFeedbackBuffer);
            mTransformFeedbackBuffer = 0;
        }

        if (mTransformFeedback != 0)
        {
            glDeleteTransformFeedbacks(1, &mTransformFeedback);
            mTransformFeedback = 0;
        }
    }

    void bindProgramPipelineWithXFBVaryings(const GLchar *vertString,
                                            const GLchar *fragStringconst,
                                            const std::vector<std::string> &tfVaryings,
                                            GLenum bufferMode);

    static const size_t mTransformFeedbackBufferSize = 1 << 24;
    GLuint mTransformFeedbackBuffer;
    GLuint mTransformFeedback;
};

void ProgramPipelineTest31::bindProgramPipeline(const GLchar *vertString, const GLchar *fragString)
{
    mVertProg = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &vertString);
    ASSERT_NE(mVertProg, 0u);
    mFragProg = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragString);
    ASSERT_NE(mFragProg, 0u);

    // Generate a program pipeline and attach the programs to their respective stages
    glGenProgramPipelines(1, &mPipeline);
    EXPECT_GL_NO_ERROR();
    glUseProgramStages(mPipeline, GL_VERTEX_SHADER_BIT, mVertProg);
    EXPECT_GL_NO_ERROR();
    glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
    EXPECT_GL_NO_ERROR();
    glBindProgramPipeline(mPipeline);
    EXPECT_GL_NO_ERROR();
}

void ProgramPipelineXFBTest31::bindProgramPipelineWithXFBVaryings(
    const GLchar *vertString,
    const GLchar *fragString,
    const std::vector<std::string> &tfVaryings,
    GLenum bufferMode)
{
    GLShader vertShader(GL_VERTEX_SHADER);
    mVertProg = glCreateProgram();

    glShaderSource(vertShader, 1, &vertString, nullptr);
    glCompileShader(vertShader);
    glProgramParameteri(mVertProg, GL_PROGRAM_SEPARABLE, GL_TRUE);
    glAttachShader(mVertProg, vertShader);
    glLinkProgram(mVertProg);
    EXPECT_GL_NO_ERROR();

    mFragProg = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragString);
    ASSERT_NE(mFragProg, 0u);

    if (tfVaryings.size() > 0)
    {
        std::vector<const char *> constCharTFVaryings;

        for (const std::string &transformFeedbackVarying : tfVaryings)
        {
            constCharTFVaryings.push_back(transformFeedbackVarying.c_str());
        }

        glTransformFeedbackVaryings(mVertProg, static_cast<GLsizei>(tfVaryings.size()),
                                    &constCharTFVaryings[0], bufferMode);
        glLinkProgram(mVertProg);
    }
    // Generate a program pipeline and attach the programs to their respective stages
    glGenProgramPipelines(1, &mPipeline);
    EXPECT_GL_NO_ERROR();
    glUseProgramStages(mPipeline, GL_VERTEX_SHADER_BIT, mVertProg);
    EXPECT_GL_NO_ERROR();
    glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
    EXPECT_GL_NO_ERROR();
    glBindProgramPipeline(mPipeline);
    EXPECT_GL_NO_ERROR();
}

// Test generate or delete program pipeline.
TEST_P(ProgramPipelineTest31, GenOrDeleteProgramPipelineTest)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    GLuint pipeline;
    glGenProgramPipelines(-1, &pipeline);
    EXPECT_GL_ERROR(GL_INVALID_VALUE);
    glGenProgramPipelines(0, &pipeline);
    EXPECT_GL_NO_ERROR();

    glDeleteProgramPipelines(-1, &pipeline);
    EXPECT_GL_ERROR(GL_INVALID_VALUE);
    glDeleteProgramPipelines(0, &pipeline);
    EXPECT_GL_NO_ERROR();
}

// Test BindProgramPipeline.
TEST_P(ProgramPipelineTest31, BindProgramPipelineTest)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    glBindProgramPipeline(0);
    EXPECT_GL_NO_ERROR();

    glBindProgramPipeline(2);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    GLuint pipeline;
    glGenProgramPipelines(1, &pipeline);
    glBindProgramPipeline(pipeline);
    EXPECT_GL_NO_ERROR();

    glDeleteProgramPipelines(1, &pipeline);
    glBindProgramPipeline(pipeline);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}

// Test IsProgramPipeline
TEST_P(ProgramPipelineTest31, IsProgramPipelineTest)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    EXPECT_GL_FALSE(glIsProgramPipeline(0));
    EXPECT_GL_NO_ERROR();

    EXPECT_GL_FALSE(glIsProgramPipeline(2));
    EXPECT_GL_NO_ERROR();

    GLuint pipeline;
    glGenProgramPipelines(1, &pipeline);
    glBindProgramPipeline(pipeline);
    EXPECT_GL_TRUE(glIsProgramPipeline(pipeline));
    EXPECT_GL_NO_ERROR();

    glBindProgramPipeline(0);
    glDeleteProgramPipelines(1, &pipeline);
    EXPECT_GL_FALSE(glIsProgramPipeline(pipeline));
    EXPECT_GL_NO_ERROR();
}

// Simulates a call to glCreateShaderProgramv()
GLuint createShaderProgram(GLenum type,
                           const GLchar *shaderString,
                           unsigned int varyingsCount,
                           const char *const *varyings)
{
    GLShader shader(type);
    if (!shader)
    {
        return 0;
    }

    glShaderSource(shader, 1, &shaderString, nullptr);
    EXPECT_GL_NO_ERROR();

    glCompileShader(shader);

    GLint compiled;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);

    if (!compiled)
    {
        GLint infoLogLength;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
        std::vector<GLchar> infoLog(infoLogLength);
        glGetShaderInfoLog(shader, infoLogLength, NULL, infoLog.data());
        INFO() << "Compilation failed:\n"
               << (infoLogLength > 0 ? infoLog.data() : "") << "\n for shader:\n"
               << shaderString << "\n";
        return 0;
    }

    GLuint program = glCreateProgram();

    if (program)
    {
        glProgramParameteri(program, GL_PROGRAM_SEPARABLE, GL_TRUE);
        if (compiled)
        {
            glAttachShader(program, shader);
            EXPECT_GL_NO_ERROR();

            if (varyingsCount > 0)
            {
                glTransformFeedbackVaryings(program, varyingsCount, varyings, GL_SEPARATE_ATTRIBS);
                EXPECT_GL_NO_ERROR();
            }

            glLinkProgram(program);

            GLint linked = 0;
            glGetProgramiv(program, GL_LINK_STATUS, &linked);

            if (linked == 0)
            {
                glDeleteProgram(program);
                return 0;
            }
            glDetachShader(program, shader);
        }
    }

    EXPECT_GL_NO_ERROR();

    return program;
}

GLuint createShaderProgram(GLenum type, const GLchar *shaderString)
{
    return createShaderProgram(type, shaderString, 0, nullptr);
}

void ProgramPipelineTest31::drawQuadWithPPO(const std::string &positionAttribName,
                                            const GLfloat positionAttribZ,
                                            const GLfloat positionAttribXYScale)
{
    return drawQuadPPO(mVertProg, positionAttribName, positionAttribZ, positionAttribXYScale);
}

GLint ProgramPipelineTest31::getAvailableProgramBinaryFormatCount() const
{
    GLint formatCount = 0;
    glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS_OES, &formatCount);
    return formatCount;
}

// Test glUseProgramStages
TEST_P(ProgramPipelineTest31, UseProgramStages)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    // Create two separable program objects from a
    // single source string respectively (vertSrc and fragSrc)
    const GLchar *vertString = essl31_shaders::vs::Simple();
    const GLchar *fragString = essl31_shaders::fs::Red();

    mVertProg = createShaderProgram(GL_VERTEX_SHADER, vertString);
    ASSERT_NE(mVertProg, 0u);
    mFragProg = createShaderProgram(GL_FRAGMENT_SHADER, fragString);
    ASSERT_NE(mFragProg, 0u);

    // Generate a program pipeline and attach the programs to their respective stages
    GLuint pipeline;
    glGenProgramPipelines(1, &pipeline);
    EXPECT_GL_NO_ERROR();
    glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, mVertProg);
    EXPECT_GL_NO_ERROR();
    glUseProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
    EXPECT_GL_NO_ERROR();
    glBindProgramPipeline(pipeline);
    EXPECT_GL_NO_ERROR();

    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
}

// Test glUseProgramStages with different programs
TEST_P(ProgramPipelineTest31, UseProgramStagesWithDifferentPrograms)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    // Create two separable program objects from a
    // single source string respectively (vertSrc and fragSrc)
    const GLchar *vertString  = essl31_shaders::vs::Simple();
    const GLchar *fragString1 = R"(#version 310 es
precision highp float;
uniform float redColorIn;
uniform float greenColorIn;
out vec4 my_FragColor;
void main()
{
    my_FragColor = vec4(redColorIn, greenColorIn, 0.0, 1.0);
})";
    const GLchar *fragString2 = R"(#version 310 es
precision highp float;
uniform float greenColorIn;
uniform float blueColorIn;
out vec4 my_FragColor;
void main()
{
    my_FragColor = vec4(0.0, greenColorIn, blueColorIn, 1.0);
})";

    bindProgramPipeline(vertString, fragString1);

    // Set the output color to red
    GLint location = glGetUniformLocation(mFragProg, "redColorIn");
    glActiveShaderProgram(mPipeline, mFragProg);
    glUniform1f(location, 1.0);
    location = glGetUniformLocation(mFragProg, "greenColorIn");
    glActiveShaderProgram(mPipeline, mFragProg);
    glUniform1f(location, 0.0);

    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    GLuint fragProg;
    fragProg = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragString2);
    ASSERT_NE(fragProg, 0u);
    EXPECT_GL_NO_ERROR();

    glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, fragProg);
    EXPECT_GL_NO_ERROR();

    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    // Set the output color to blue
    location = glGetUniformLocation(fragProg, "greenColorIn");
    glActiveShaderProgram(mPipeline, fragProg);
    glUniform1f(location, 0.0);
    location = glGetUniformLocation(fragProg, "blueColorIn");
    glActiveShaderProgram(mPipeline, fragProg);
    glUniform1f(location, 1.0);

    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);

    glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
    EXPECT_GL_NO_ERROR();

    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    glDeleteProgram(mVertProg);
    glDeleteProgram(mFragProg);
    glDeleteProgram(fragProg);
}

// Test glUseProgramStages
TEST_P(ProgramPipelineTest31, UseCreateShaderProgramv)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    // Create two separable program objects from a
    // single source string respectively (vertSrc and fragSrc)
    const GLchar *vertString = essl31_shaders::vs::Simple();
    const GLchar *fragString = essl31_shaders::fs::Red();

    bindProgramPipeline(vertString, fragString);

    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
}

// Test pipeline without vertex shader
TEST_P(ProgramPipelineTest31, PipelineWithoutVertexShader)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    // Create a separable program object with a fragment shader
    const GLchar *fragString = essl31_shaders::fs::Red();
    mFragProg                = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragString);
    ASSERT_NE(mFragProg, 0u);

    // Generate a program pipeline and attach the program to it's respective stage
    glGenProgramPipelines(1, &mPipeline);
    EXPECT_GL_NO_ERROR();
    glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
    EXPECT_GL_NO_ERROR();
    glBindProgramPipeline(mPipeline);
    EXPECT_GL_NO_ERROR();

    glDrawArrays(GL_POINTS, 0, 3);
    ASSERT_GL_NO_ERROR();
}

// Test pipeline without any shaders
TEST_P(ProgramPipelineTest31, PipelineWithoutShaders)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    // Generate a program pipeline
    glGenProgramPipelines(1, &mPipeline);
    EXPECT_GL_NO_ERROR();

    glBindProgramPipeline(mPipeline);
    EXPECT_GL_NO_ERROR();

    glDrawArrays(GL_POINTS, 0, 3);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    // Ensure validation fails
    GLint value;
    glValidateProgramPipeline(mPipeline);
    glGetProgramPipelineiv(mPipeline, GL_VALIDATE_STATUS, &value);
    EXPECT_FALSE(value);
}

// Test glUniform
TEST_P(ProgramPipelineTest31, FragmentStageUniformTest)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    // Create two separable program objects from a
    // single source string respectively (vertSrc and fragSrc)
    const GLchar *vertString = essl31_shaders::vs::Simple();
    const GLchar *fragString = R"(#version 310 es
precision highp float;
uniform float redColorIn;
uniform float greenColorIn;
out vec4 my_FragColor;
void main()
{
    my_FragColor = vec4(redColorIn, greenColorIn, 0.0, 1.0);
})";

    bindProgramPipeline(vertString, fragString);

    // Set the output color to yellow
    GLint location = glGetUniformLocation(mFragProg, "redColorIn");
    glActiveShaderProgram(mPipeline, mFragProg);
    glUniform1f(location, 1.0);
    location = glGetUniformLocation(mFragProg, "greenColorIn");
    glActiveShaderProgram(mPipeline, mFragProg);
    glUniform1f(location, 1.0);

    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);

    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);

    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    // Set the output color to red
    location = glGetUniformLocation(mFragProg, "redColorIn");
    glActiveShaderProgram(mPipeline, mFragProg);
    glUniform1f(location, 1.0);
    location = glGetUniformLocation(mFragProg, "greenColorIn");
    glActiveShaderProgram(mPipeline, mFragProg);
    glUniform1f(location, 0.0);

    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    glDeleteProgram(mVertProg);
    glDeleteProgram(mFragProg);
}

// Test glUniformBlockBinding and then glBufferData
TEST_P(ProgramPipelineTest31, FragmentStageUniformBlockBufferDataTest)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    // Create two separable program objects from a
    // single source string respectively (vertSrc and fragSrc)
    const GLchar *vertString = essl31_shaders::vs::Simple();
    const GLchar *fragString = R"(#version 310 es
precision highp float;
layout (std140) uniform color_ubo
{
    float redColorIn;
    float greenColorIn;
};

out vec4 my_FragColor;
void main()
{
    my_FragColor = vec4(redColorIn, greenColorIn, 0.0, 1.0);
})";

    bindProgramPipeline(vertString, fragString);

    // Set the output color to yellow
    glActiveShaderProgram(mPipeline, mFragProg);
    GLint uboIndex = glGetUniformBlockIndex(mFragProg, "color_ubo");
    GLBuffer uboBuf;
    glBindBufferBase(GL_UNIFORM_BUFFER, 0, uboBuf);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatRed, GL_STATIC_DRAW);
    glUniformBlockBinding(mFragProg, uboIndex, 0);
    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    // Clear and test again
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);
    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    // Set the output color to red
    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatGreen, GL_STATIC_DRAW);
    glBindBufferBase(GL_UNIFORM_BUFFER, 0, uboBuf);
    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    glDeleteProgram(mVertProg);
    glDeleteProgram(mFragProg);
}

// Test glUniformBlockBinding followed by glBindBufferRange
TEST_P(ProgramPipelineTest31, FragmentStageUniformBlockBindBufferRangeTest)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    // Create two separable program objects from a
    // single source string respectively (vertSrc and fragSrc)
    const GLchar *vertString = essl31_shaders::vs::Simple();
    const GLchar *fragString = R"(#version 310 es
precision highp float;
layout (std140) uniform color_ubo
{
    float redColorIn;
    float greenColorIn;
    float blueColorIn;
};

out vec4 my_FragColor;
void main()
{
    my_FragColor = vec4(redColorIn, greenColorIn, blueColorIn, 1.0);
})";

    // Setup three uniform buffers, one with red, one with green, and one with blue
    GLBuffer uboBufRed;
    glBindBuffer(GL_UNIFORM_BUFFER, uboBufRed);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatRed, GL_STATIC_DRAW);
    GLBuffer uboBufGreen;
    glBindBuffer(GL_UNIFORM_BUFFER, uboBufGreen);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatGreen, GL_STATIC_DRAW);
    GLBuffer uboBufBlue;
    glBindBuffer(GL_UNIFORM_BUFFER, uboBufBlue);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatBlue, GL_STATIC_DRAW);

    // Setup pipeline program using red uniform buffer
    bindProgramPipeline(vertString, fragString);
    glActiveShaderProgram(mPipeline, mFragProg);
    GLint uboIndex = glGetUniformBlockIndex(mFragProg, "color_ubo");
    glBindBufferBase(GL_UNIFORM_BUFFER, 0, uboBufRed);
    glUniformBlockBinding(mFragProg, uboIndex, 0);
    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    // Clear and test again
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);
    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    // bind to green uniform buffer
    glBindBufferBase(GL_UNIFORM_BUFFER, 0, uboBufGreen);
    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    // bind to blue uniform buffer
    glBindBufferBase(GL_UNIFORM_BUFFER, 0, uboBufBlue);
    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);

    glDeleteProgram(mVertProg);
    glDeleteProgram(mFragProg);
}

// Test that glUniformBlockBinding can successfully change the binding for PPOs
TEST_P(ProgramPipelineTest31, FragmentStageUniformBlockBinding)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    // Create two separable program objects from a
    // single source string respectively (vertSrc and fragSrc)
    const GLchar *vertString = essl31_shaders::vs::Simple();
    const GLchar *fragString = R"(#version 310 es
precision highp float;
layout (std140) uniform color_ubo
{
    float redColorIn;
    float greenColorIn;
    float blueColorIn;
};

out vec4 my_FragColor;
void main()
{
    my_FragColor = vec4(redColorIn, greenColorIn, blueColorIn, 1.0);
})";

    // Setup three uniform buffers, one with red, one with green, and one with blue
    GLBuffer uboBufRed;
    glBindBuffer(GL_UNIFORM_BUFFER, uboBufRed);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatRed, GL_STATIC_DRAW);
    GLBuffer uboBufGreen;
    glBindBuffer(GL_UNIFORM_BUFFER, uboBufGreen);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatGreen, GL_STATIC_DRAW);
    GLBuffer uboBufBlue;
    glBindBuffer(GL_UNIFORM_BUFFER, uboBufBlue);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatBlue, GL_STATIC_DRAW);

    // Setup pipeline program using red uniform buffer
    bindProgramPipeline(vertString, fragString);
    glActiveShaderProgram(mPipeline, mFragProg);
    GLint uboIndex = glGetUniformBlockIndex(mFragProg, "color_ubo");

    glBindBufferBase(GL_UNIFORM_BUFFER, 0, uboBufRed);
    glBindBufferBase(GL_UNIFORM_BUFFER, 1, uboBufGreen);
    glBindBufferBase(GL_UNIFORM_BUFFER, 2, uboBufBlue);

    // Bind the UBO to binding 0 and draw, should be red
    const int w = getWindowWidth();
    const int h = getWindowHeight();
    glEnable(GL_SCISSOR_TEST);
    glScissor(0, 0, w / 2, h / 2);
    glUniformBlockBinding(mFragProg, uboIndex, 0);
    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);

    // Bind it to binding 1 and draw, should be green
    glScissor(w / 2, 0, w - w / 2, h / 2);
    glUniformBlockBinding(mFragProg, uboIndex, 1);
    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);

    // Bind it to binding 2 and draw, should be blue
    glScissor(0, h / 2, w, h);
    glUniformBlockBinding(mFragProg, uboIndex, 2);
    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);

    EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::red);
    EXPECT_PIXEL_RECT_EQ(w / 2, 0, w - w / 2, h / 2, GLColor::green);
    EXPECT_PIXEL_RECT_EQ(0, h / 2, w, h - h / 2, GLColor::blue);
    ASSERT_GL_NO_ERROR();
}

// Test that dirty bits related to UBOs propagates to the PPO.
TEST_P(ProgramPipelineTest31, UniformBufferUpdatesBeforeBindToPPO)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    const GLchar *vertString = essl31_shaders::vs::Simple();
    const GLchar *fragString = R"(#version 310 es
precision highp float;
layout (std140) uniform color_ubo
{
    float redColorIn;
    float greenColorIn;
    float blueColorIn;
};

out vec4 my_FragColor;
void main()
{
    my_FragColor = vec4(redColorIn, greenColorIn, blueColorIn, 1.0);
})";

    GLuint vs = CompileShader(GL_VERTEX_SHADER, vertString);
    GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fragString);
    mVertProg = glCreateProgram();
    mFragProg = glCreateProgram();

    // Compile and link a separable vertex shader
    glProgramParameteri(mVertProg, GL_PROGRAM_SEPARABLE, GL_TRUE);
    glAttachShader(mVertProg, vs);
    glLinkProgram(mVertProg);
    EXPECT_GL_NO_ERROR();

    // Compile and link a separable fragment shader
    glProgramParameteri(mFragProg, GL_PROGRAM_SEPARABLE, GL_TRUE);
    glAttachShader(mFragProg, fs);
    glLinkProgram(mFragProg);
    EXPECT_GL_NO_ERROR();

    // Generate a program pipeline and attach the programs
    glGenProgramPipelines(1, &mPipeline);
    glUseProgramStages(mPipeline, GL_VERTEX_SHADER_BIT, mVertProg);
    glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
    glBindProgramPipeline(mPipeline);
    EXPECT_GL_NO_ERROR();

    GLBuffer uboBufRed;
    glBindBuffer(GL_UNIFORM_BUFFER, uboBufRed);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatRed, GL_STATIC_DRAW);
    GLBuffer uboBufGreen;
    glBindBuffer(GL_UNIFORM_BUFFER, uboBufGreen);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatGreen, GL_STATIC_DRAW);
    GLBuffer uboBufBlue;
    glBindBuffer(GL_UNIFORM_BUFFER, uboBufBlue);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatBlue, GL_STATIC_DRAW);

    glActiveShaderProgram(mPipeline, mFragProg);
    GLint uboIndex = glGetUniformBlockIndex(mFragProg, "color_ubo");
    glUniformBlockBinding(mFragProg, uboIndex, 0);
    glBindBufferBase(GL_UNIFORM_BUFFER, 0, uboBufRed);
    glBindBufferBase(GL_UNIFORM_BUFFER, 1, uboBufGreen);

    // Draw once so all dirty bits are handled.  Should be red
    const int w = getWindowWidth();
    const int h = getWindowHeight();
    glEnable(GL_SCISSOR_TEST);
    glScissor(0, 0, w / 2, h / 2);
    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);

    // Unbind the fragment program from the PPO
    glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, 0);
    EXPECT_GL_NO_ERROR();

    // Modify the UBO bindings, reattach the program and draw again.  Should be green
    glUniformBlockBinding(mFragProg, uboIndex, 1);

    glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
    glScissor(w / 2, 0, w - w / 2, h / 2);
    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);

    // Unbind the fragment program from the PPO again, and modify the UBO bindings differently.
    // Draw again, which should be blue.
    glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, 0);
    glBindBufferBase(GL_UNIFORM_BUFFER, 1, uboBufBlue);

    glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
    glScissor(0, h / 2, w, h);
    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);

    EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::red);
    EXPECT_PIXEL_RECT_EQ(w / 2, 0, w - w / 2, h / 2, GLColor::green);
    EXPECT_PIXEL_RECT_EQ(0, h / 2, w, h - h / 2, GLColor::blue);
    ASSERT_GL_NO_ERROR();
}

// Test glBindBufferRange between draw calls in the presence of multiple UBOs between VS and FS
TEST_P(ProgramPipelineTest31, BindBufferRangeForMultipleUBOsInMultipleStages)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    // Create two separable program objects from a
    // single source string respectively (vertSrc and fragSrc)
    const GLchar *vertString = R"(#version 310 es
precision highp float;
layout (std140) uniform vsUBO1
{
    float redIn;
};

layout (std140) uniform vsUBO2
{
    float greenIn;
};

out float red;
out float green;

void main()
{
    vec2 pos = vec2(0.0);
    switch (gl_VertexID) {
        case 0: pos = vec2(-1.0, -1.0); break;
        case 1: pos = vec2(3.0, -1.0); break;
        case 2: pos = vec2(-1.0, 3.0); break;
    };
    gl_Position = vec4(pos, 0.0, 1.0);
    red = redIn;
    green = greenIn;
})";
    const GLchar *fragString = R"(#version 310 es
precision highp float;
layout (std140) uniform fsUBO1
{
    float blueIn;
};

layout (std140) uniform fsUBO2
{
    float alphaIn;
};

in float red;
in float green;

out vec4 my_FragColor;
void main()
{
    my_FragColor = vec4(red, green, blueIn, alphaIn);
})";

    // Setup two uniform buffers, one with 1, one with 0
    GLBuffer ubo0;
    glBindBuffer(GL_UNIFORM_BUFFER, ubo0);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatBlack, GL_STATIC_DRAW);
    GLBuffer ubo1;
    glBindBuffer(GL_UNIFORM_BUFFER, ubo1);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatRed, GL_STATIC_DRAW);

    bindProgramPipeline(vertString, fragString);

    // Setup the initial bindings to draw red
    const GLint vsUBO1 = glGetUniformBlockIndex(mVertProg, "vsUBO1");
    const GLint vsUBO2 = glGetUniformBlockIndex(mVertProg, "vsUBO2");
    const GLint fsUBO1 = glGetUniformBlockIndex(mFragProg, "fsUBO1");
    const GLint fsUBO2 = glGetUniformBlockIndex(mFragProg, "fsUBO2");
    glUniformBlockBinding(mVertProg, vsUBO1, 0);
    glUniformBlockBinding(mVertProg, vsUBO2, 1);
    glUniformBlockBinding(mFragProg, fsUBO1, 2);
    glUniformBlockBinding(mFragProg, fsUBO2, 3);

    glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo1);
    glBindBufferBase(GL_UNIFORM_BUFFER, 1, ubo0);
    glBindBufferBase(GL_UNIFORM_BUFFER, 2, ubo0);
    glBindBufferBase(GL_UNIFORM_BUFFER, 3, ubo1);

    const int w = getWindowWidth();
    const int h = getWindowHeight();
    glEnable(GL_SCISSOR_TEST);
    glScissor(0, 0, w / 2, h / 2);

    glDrawArrays(GL_TRIANGLES, 0, 3);

    // Change the bindings in the vertex shader UBO binding and draw again, should be yellow.
    glBindBufferBase(GL_UNIFORM_BUFFER, 1, ubo1);
    glScissor(w / 2, 0, w - w / 2, h / 2);
    glDrawArrays(GL_TRIANGLES, 0, 3);

    // Change the bindings in the fragment shader UBO binding and draw again, should be white.
    glBindBufferBase(GL_UNIFORM_BUFFER, 2, ubo1);
    glScissor(0, h / 2, w / 2, h - h / 2);
    glDrawArrays(GL_TRIANGLES, 0, 3);

    // Change the bindings in both shader UBO bindings and draw again, should be green.
    glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo0);
    glBindBufferBase(GL_UNIFORM_BUFFER, 2, ubo0);
    glScissor(w / 2, h / 2, w - w / 2, h - h / 2);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::red);
    EXPECT_PIXEL_RECT_EQ(w / 2, 0, w - w / 2, h / 2, GLColor::yellow);
    EXPECT_PIXEL_RECT_EQ(0, h / 2, w / 2, h - h / 2, GLColor::white);
    EXPECT_PIXEL_RECT_EQ(w / 2, h / 2, w - w / 2, h - h / 2, GLColor::green);
    ASSERT_GL_NO_ERROR();
}

// Test varyings
TEST_P(ProgramPipelineTest31, ProgramPipelineVaryings)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    // Create two separable program objects from a
    // single source string respectively (vertSrc and fragSrc)
    const GLchar *vertString = essl31_shaders::vs::Passthrough();
    const GLchar *fragString = R"(#version 310 es
precision highp float;
in vec4 v_position;
out vec4 my_FragColor;
void main()
{
    my_FragColor = round(v_position);
})";

    bindProgramPipeline(vertString, fragString);

    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();

    int w = getWindowWidth() - 2;
    int h = getWindowHeight() - 2;

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
    EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow);
}

// Creates a program pipeline with a 2D texture and renders with it.
TEST_P(ProgramPipelineTest31, DrawWith2DTexture)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    const GLchar *vertString = R"(#version 310 es
precision highp float;
in vec4 a_position;
out vec2 texCoord;
void main()
{
    gl_Position = a_position;
    texCoord = vec2(a_position.x, a_position.y) * 0.5 + vec2(0.5);
})";

    const GLchar *fragString = R"(#version 310 es
precision highp float;
in vec2 texCoord;
uniform sampler2D tex;
out vec4 my_FragColor;
void main()
{
    my_FragColor = texture(tex, texCoord);
})";

    std::array<GLColor, 4> colors = {
        {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};

    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    bindProgramPipeline(vertString, fragString);

    drawQuadWithPPO("a_position", 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();

    int w = getWindowWidth() - 2;
    int h = getWindowHeight() - 2;

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow);
}

// Test modifying a shader after it has been detached from a pipeline
TEST_P(ProgramPipelineTest31, DetachAndModifyShader)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    const GLchar *vertString = essl31_shaders::vs::Simple();
    const GLchar *fragString = essl31_shaders::fs::Green();

    GLShader vertShader(GL_VERTEX_SHADER);
    GLShader fragShader(GL_FRAGMENT_SHADER);
    mVertProg = glCreateProgram();
    mFragProg = glCreateProgram();

    // Compile and link a separable vertex shader
    glShaderSource(vertShader, 1, &vertString, nullptr);
    glCompileShader(vertShader);
    glProgramParameteri(mVertProg, GL_PROGRAM_SEPARABLE, GL_TRUE);
    glAttachShader(mVertProg, vertShader);
    glLinkProgram(mVertProg);
    EXPECT_GL_NO_ERROR();

    // Compile and link a separable fragment shader
    glShaderSource(fragShader, 1, &fragString, nullptr);
    glCompileShader(fragShader);
    glProgramParameteri(mFragProg, GL_PROGRAM_SEPARABLE, GL_TRUE);
    glAttachShader(mFragProg, fragShader);
    glLinkProgram(mFragProg);
    EXPECT_GL_NO_ERROR();

    // Generate a program pipeline and attach the programs
    glGenProgramPipelines(1, &mPipeline);
    glUseProgramStages(mPipeline, GL_VERTEX_SHADER_BIT, mVertProg);
    glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
    glBindProgramPipeline(mPipeline);
    EXPECT_GL_NO_ERROR();

    // Draw once to ensure this worked fine
    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    // Detach the fragment shader and modify it such that it no longer fits with this pipeline
    glDetachShader(mFragProg, fragShader);

    // Add an input to the fragment shader, which will make it incompatible
    const GLchar *fragString2 = R"(#version 310 es
precision highp float;
in vec4 color;
out vec4 my_FragColor;
void main()
{
    my_FragColor = color;
})";
    glShaderSource(fragShader, 1, &fragString2, nullptr);
    glCompileShader(fragShader);

    // Link and draw with the program again, which should be fine since the shader was detached
    glLinkProgram(mFragProg);

    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
}

// Test binding two programs that use a texture as different types
TEST_P(ProgramPipelineTest31, DifferentTextureTypes)
{
    // Only the Vulkan backend supports PPO
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    // Per the OpenGL ES 3.1 spec:
    //
    // It is not allowed to have variables of different sampler types pointing to the same texture
    // image unit within a program object. This situation can only be detected at the next rendering
    // command issued which triggers shader invocations, and an INVALID_OPERATION error will then
    // be generated
    //

    // Create a vertex shader that uses the texture as 2D
    const GLchar *vertString = R"(#version 310 es
precision highp float;
in vec4 a_position;
uniform sampler2D tex2D;
layout(location = 0) out vec4 texColorOut;
layout(location = 1) out vec2 texCoordOut;
void main()
{
    gl_Position = a_position;
    vec2 texCoord = vec2(a_position.x, a_position.y) * 0.5 + vec2(0.5);
    texColorOut = textureLod(tex2D, texCoord, 0.0);
    texCoordOut = texCoord;
})";

    // Create a fragment shader that uses the texture as Cube
    const GLchar *fragString = R"(#version 310 es
precision highp float;
layout(location = 0) in vec4 texColor;
layout(location = 1) in vec2 texCoord;
uniform samplerCube texCube;
out vec4 my_FragColor;
void main()
{
    my_FragColor = texture(texCube, vec3(texCoord.x, texCoord.y, 0.0));
})";

    // Create and populate the 2D texture
    std::array<GLColor, 4> colors = {
        {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    // Create a pipeline that uses the bad combination.  This should fail to link the pipeline.
    bindProgramPipeline(vertString, fragString);
    drawQuadWithPPO("a_position", 0.5f, 1.0f);
    ASSERT_GL_ERROR(GL_INVALID_OPERATION);

    // Update the fragment shader to correctly use 2D texture
    const GLchar *fragString2 = R"(#version 310 es
precision highp float;
layout(location = 0) in vec4 texColor;
layout(location = 1) in vec2 texCoord;
uniform sampler2D tex2D;
out vec4 my_FragColor;
void main()
{
    my_FragColor = texture(tex2D, texCoord);
})";

    // Bind the pipeline again, which should succeed.
    bindProgramPipeline(vertString, fragString2);
    drawQuadWithPPO("a_position", 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
}

// Tests that we receive a PPO link validation error when attempting to draw with the bad PPO
TEST_P(ProgramPipelineTest31, VerifyPpoLinkErrorSignalledCorrectly)
{
    // Create pipeline that should fail link
    // Bind program
    // Draw
    // Unbind program
    // Draw  <<--- expect a link validation error here

    // Only the Vulkan backend supports PPOs
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    // Create two separable program objects from a
    // single source string respectively (vertSrc and fragSrc)
    const GLchar *vertString = essl31_shaders::vs::Simple();
    const GLchar *fragString = essl31_shaders::fs::Red();
    // Create a fragment shader that takes a color input
    // This should cause the PPO link to fail, since the varyings don't match (no output from VS).
    const GLchar *fragStringBad = R"(#version 310 es
precision highp float;
layout(location = 0) in vec4 colorIn;
out vec4 my_FragColor;
void main()
{
    my_FragColor = colorIn;
})";
    bindProgramPipeline(vertString, fragStringBad);

    ANGLE_GL_PROGRAM(program, vertString, fragString);
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f, 1.0f, true);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    // Draw with the PPO, which should generate an error due to the link failure.
    glUseProgram(0);
    ASSERT_GL_NO_ERROR();
    drawQuadWithPPO(essl1_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_ERROR(GL_INVALID_OPERATION);
}

// Tests creating two program pipelines with a common shader and a varying location mismatch.
TEST_P(ProgramPipelineTest31, VaryingLocationMismatch)
{
    // Only the Vulkan backend supports PPOs
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    // Create a fragment shader using the varying location "5".
    const char *kFS = R"(#version 310 es
precision mediump float;
layout(location = 5) in vec4 color;
out vec4 colorOut;
void main()
{
    colorOut = color;
})";

    // Create a pipeline with a vertex shader using varying location "5". Should succeed.
    const char *kVSGood = R"(#version 310 es
precision mediump float;
layout(location = 5) out vec4 color;
in vec4 position;
uniform float uniOne;
void main()
{
    gl_Position = position;
    color = vec4(0, uniOne, 0, 1);
})";

    mVertProg = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &kVSGood);
    ASSERT_NE(mVertProg, 0u);
    mFragProg = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &kFS);
    ASSERT_NE(mFragProg, 0u);

    // Generate a program pipeline and attach the programs to their respective stages
    glGenProgramPipelines(1, &mPipeline);
    glUseProgramStages(mPipeline, GL_VERTEX_SHADER_BIT, mVertProg);
    glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
    glBindProgramPipeline(mPipeline);
    ASSERT_GL_NO_ERROR();

    GLint location = glGetUniformLocation(mVertProg, "uniOne");
    ASSERT_NE(-1, location);
    glActiveShaderProgram(mPipeline, mVertProg);
    glUniform1f(location, 1.0);
    ASSERT_GL_NO_ERROR();

    drawQuadWithPPO("position", 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    // Create a pipeline with a vertex shader using varying location "3". Should fail.
    const char *kVSBad = R"(#version 310 es
precision mediump float;
layout(location = 3) out vec4 color;
in vec4 position;
uniform float uniOne;
void main()
{
    gl_Position = position;
    color = vec4(0, uniOne, 0, 1);
})";

    glDeleteProgram(mVertProg);
    mVertProg = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &kVSBad);
    ASSERT_NE(mVertProg, 0u);

    glUseProgramStages(mPipeline, GL_VERTEX_SHADER_BIT, mVertProg);
    ASSERT_GL_NO_ERROR();

    drawQuadWithPPO("position", 0.5f, 1.0f);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}

// Test that uniform updates are propagated with minimal state changes.
TEST_P(ProgramPipelineTest31, UniformUpdate)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    // Create two separable program objects from a
    // single source string respectively (vertSrc and fragSrc)
    const GLchar *vertString = essl31_shaders::vs::Simple();
    const GLchar *fragString = R"(#version 310 es
precision highp float;
uniform float redColorIn;
uniform float greenColorIn;
out vec4 my_FragColor;
void main()
{
    my_FragColor = vec4(redColorIn, greenColorIn, 0.0, 1.0);
})";

    bindProgramPipeline(vertString, fragString);

    GLint redLoc = glGetUniformLocation(mFragProg, "redColorIn");
    ASSERT_NE(-1, redLoc);
    GLint greenLoc = glGetUniformLocation(mFragProg, "greenColorIn");
    ASSERT_NE(-1, greenLoc);

    glActiveShaderProgram(mPipeline, mFragProg);

    std::array<Vector3, 6> verts = GetQuadVertices();

    GLBuffer vbo;
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, verts.size() * sizeof(verts[0]), verts.data(), GL_STATIC_DRAW);

    GLint posLoc = glGetAttribLocation(mVertProg, essl31_shaders::PositionAttrib());
    glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnableVertexAttribArray(posLoc);

    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    // Set the output color to red, draw to left half of window.
    glUniform1f(redLoc, 1.0);
    glUniform1f(greenLoc, 0.0);
    glViewport(0, 0, getWindowWidth() / 2, getWindowHeight());
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    // Set the output color to green, draw to right half of window.
    glUniform1f(redLoc, 0.0);
    glUniform1f(greenLoc, 1.0);

    glViewport(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight());
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2 + 1, 0, GLColor::green);
}

// Test that uniform updates propagate to two pipelines.
TEST_P(ProgramPipelineTest31, UniformUpdateTwoPipelines)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    // Create two separable program objects from a
    // single source string respectively (vertSrc and fragSrc)
    const GLchar *vertString = essl31_shaders::vs::Simple();
    const GLchar *fragString = R"(#version 310 es
precision highp float;
uniform float redColorIn;
uniform float greenColorIn;
out vec4 my_FragColor;
void main()
{
    my_FragColor = vec4(redColorIn, greenColorIn, 0.0, 1.0);
})";

    mVertProg = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &vertString);
    ASSERT_NE(mVertProg, 0u);
    mFragProg = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragString);
    ASSERT_NE(mFragProg, 0u);

    GLint redLoc = glGetUniformLocation(mFragProg, "redColorIn");
    ASSERT_NE(-1, redLoc);
    GLint greenLoc = glGetUniformLocation(mFragProg, "greenColorIn");
    ASSERT_NE(-1, greenLoc);

    GLProgramPipeline ppo1;
    glUseProgramStages(ppo1, GL_VERTEX_SHADER_BIT, mVertProg);
    glUseProgramStages(ppo1, GL_FRAGMENT_SHADER_BIT, mFragProg);
    glBindProgramPipeline(ppo1);
    glActiveShaderProgram(ppo1, mFragProg);
    ASSERT_GL_NO_ERROR();

    GLProgramPipeline ppo2;
    glUseProgramStages(ppo2, GL_VERTEX_SHADER_BIT, mVertProg);
    glUseProgramStages(ppo2, GL_FRAGMENT_SHADER_BIT, mFragProg);
    glBindProgramPipeline(ppo2);
    glActiveShaderProgram(ppo2, mFragProg);
    ASSERT_GL_NO_ERROR();

    std::array<Vector3, 6> verts = GetQuadVertices();

    GLBuffer vbo;
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, verts.size() * sizeof(verts[0]), verts.data(), GL_STATIC_DRAW);

    GLint posLoc = glGetAttribLocation(mVertProg, essl31_shaders::PositionAttrib());
    glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnableVertexAttribArray(posLoc);

    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    const GLsizei w = getWindowWidth() / 2;
    const GLsizei h = getWindowHeight() / 2;

    // Set the output color to red, draw to UL quad of window with first PPO.
    glUniform1f(redLoc, 1.0);
    glUniform1f(greenLoc, 0.0);
    glBindProgramPipeline(ppo1);
    glViewport(0, 0, w, h);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    // Draw red to UR half of window with second PPO.
    glBindProgramPipeline(ppo2);
    glViewport(w, 0, w, h);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    // Draw green to LL corner of window with first PPO.
    glUniform1f(redLoc, 0.0);
    glUniform1f(greenLoc, 1.0);
    glBindProgramPipeline(ppo1);
    glViewport(0, h, w, h);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    // Draw green to LR half of window with second PPO.
    glBindProgramPipeline(ppo2);
    glViewport(w, h, w, h);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(w + 1, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(0, h + 1, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(w + 1, h + 1, GLColor::green);
}

// Tests that setting sampler bindings on a program before the pipeline works as expected.
TEST_P(ProgramPipelineTest31, BindSamplerBeforeCreatingPipeline)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    // Create two textures - red and green.
    GLTexture redTex;
    glBindTexture(GL_TEXTURE_2D, redTex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    GLTexture greenTex;
    glBindTexture(GL_TEXTURE_2D, greenTex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    // Bind red to texture unit 0 and green to unit 1.
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, redTex);

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, greenTex);

    // Create the separable programs.
    const char *vsSource = essl1_shaders::vs::Texture2D();
    mVertProg            = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &vsSource);
    ASSERT_NE(0u, mVertProg);

    const char *fsSource = essl1_shaders::fs::Texture2D();
    mFragProg            = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fsSource);
    ASSERT_NE(0u, mFragProg);

    // Set the program to sample from the green texture.
    GLint texLoc = glGetUniformLocation(mFragProg, essl1_shaders::Texture2DUniform());
    ASSERT_NE(-1, texLoc);

    glUseProgram(mFragProg);
    glUniform1i(texLoc, 1);

    ASSERT_GL_NO_ERROR();

    // Create and draw with the pipeline.
    GLProgramPipeline ppo;
    glUseProgramStages(ppo, GL_VERTEX_SHADER_BIT, mVertProg);
    glUseProgramStages(ppo, GL_FRAGMENT_SHADER_BIT, mFragProg);
    glBindProgramPipeline(ppo);

    ASSERT_GL_NO_ERROR();

    drawQuadWithPPO(essl1_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();

    // We should have sampled from the second texture bound to unit 1.
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}

// Test that a shader IO block varying with separable program links
// successfully.
TEST_P(ProgramPipelineTest31, VaryingIOBlockSeparableProgram)
{
    // Only the Vulkan backend supports PPOs
    ANGLE_SKIP_TEST_IF(!IsVulkan());
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_io_blocks"));

    constexpr char kVS[] =
        R"(#version 310 es
        #extension GL_EXT_shader_io_blocks : require

        precision highp float;
        in vec4 inputAttribute;
        out Block_inout { vec4 value; } user_out;

        void main()
        {
            gl_Position    = inputAttribute;
            user_out.value = vec4(4.0, 5.0, 6.0, 7.0);
        })";

    constexpr char kFS[] =
        R"(#version 310 es
        #extension GL_EXT_shader_io_blocks : require

        precision highp float;
        layout(location = 0) out mediump vec4 color;
        in Block_inout { vec4 value; } user_in;

        void main()
        {
            color = vec4(1, 0, 0, 1);
        })";

    bindProgramPipeline(kVS, kFS);
    drawQuadWithPPO("inputAttribute", 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
}

// Test that a shader IO block varying with separable program links
// successfully.
TEST_P(ProgramPipelineXFBTest31, VaryingIOBlockSeparableProgramWithXFB)
{
    // Only the Vulkan backend supports PPOs
    ANGLE_SKIP_TEST_IF(!IsVulkan());
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_io_blocks"));

    constexpr char kVS[] =
        R"(#version 310 es
        #extension GL_EXT_shader_io_blocks : require

        precision highp float;
        in vec4 inputAttribute;
        out Block_inout { vec4 value; vec4 value2; } user_out;

        void main()
        {
            gl_Position    = inputAttribute;
            user_out.value = vec4(4.0, 5.0, 6.0, 7.0);
            user_out.value2 = vec4(8.0, 9.0, 10.0, 11.0);
        })";

    constexpr char kFS[] =
        R"(#version 310 es
        #extension GL_EXT_shader_io_blocks : require

        precision highp float;
        layout(location = 0) out mediump vec4 color;
        in Block_inout { vec4 value; vec4 value2; } user_in;

        void main()
        {
            color = vec4(1, 0, 0, 1);
        })";
    std::vector<std::string> tfVaryings;
    tfVaryings.push_back("Block_inout.value");
    tfVaryings.push_back("Block_inout.value2");
    bindProgramPipelineWithXFBVaryings(kVS, kFS, tfVaryings, GL_INTERLEAVED_ATTRIBS);
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mTransformFeedbackBuffer);

    // Make sure reconfiguring the vertex shader's transform feedback varyings without a link does
    // not affect the pipeline.  Same with changing buffer modes
    std::vector<const char *> tfVaryingsBogus = {"some", "invalid[0]", "names"};
    glTransformFeedbackVaryings(mVertProg, static_cast<GLsizei>(tfVaryingsBogus.size()),
                                tfVaryingsBogus.data(), GL_SEPARATE_ATTRIBS);

    glBeginTransformFeedback(GL_TRIANGLES);
    drawQuadWithPPO("inputAttribute", 0.5f, 1.0f);
    glEndTransformFeedback();

    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    void *mappedBuffer =
        glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(float) * 8, GL_MAP_READ_BIT);
    ASSERT_NE(nullptr, mappedBuffer);

    float *mappedFloats = static_cast<float *>(mappedBuffer);
    for (unsigned int cnt = 0; cnt < 8; ++cnt)
    {
        ANGLE_UNSAFE_TODO(EXPECT_EQ(4 + cnt, mappedFloats[cnt]));
    }
    glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);

    EXPECT_GL_NO_ERROR();
}

// Test that XFB GL_SEPARATE_ATTRIBS behaves correctly with PPO.
TEST_P(ProgramPipelineXFBTest31, SeparableProgramWithXFBSeparateMode)
{
    // Only the Vulkan backend supports PPOs
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    const GLchar *vertString = R"(#version 310 es
precision highp float;
in vec4 inputAttribute;
uniform vec4 u_color;
out vec4 texCoord;
out vec4 unused1;
void main()
{
    gl_Position = inputAttribute;
    texCoord = u_color;
})";

    GLShader vertShader(GL_VERTEX_SHADER);
    mVertProg = glCreateProgram();

    // Compile and attach a separable vertex shader
    glShaderSource(vertShader, 1, &vertString, nullptr);
    glCompileShader(vertShader);
    glProgramParameteri(mVertProg, GL_PROGRAM_SEPARABLE, GL_TRUE);
    glAttachShader(mVertProg, vertShader);
    EXPECT_GL_NO_ERROR();

    // Select the varyings for XFB with GL_SEPARATE_ATTRIBS mode
    std::vector<const char *> tfVaryings = {"unused1", "texCoord"};
    glTransformFeedbackVaryings(mVertProg, static_cast<GLsizei>(tfVaryings.size()),
                                tfVaryings.data(), GL_SEPARATE_ATTRIBS);
    glLinkProgram(mVertProg);
    ASSERT_GL_NO_ERROR();

    GLint uniformLoc = glGetUniformLocation(mVertProg, "u_color");
    ASSERT_NE(uniformLoc, -1);
    glProgramUniform4f(mVertProg, uniformLoc, 1, 2, 3, 4);
    ASSERT_GL_NO_ERROR();

    // Generate a program pipeline and attach the program to respective stage
    glGenProgramPipelines(1, &mPipeline);
    glUseProgramStages(mPipeline, GL_VERTEX_SHADER_BIT, mVertProg);
    glBindProgramPipeline(mPipeline);
    ASSERT_GL_NO_ERROR();

    GLuint transformFeedbackBuffer[2] = {0};
    // Allocate space for vec4
    static const size_t transformFeedbackBufferSize = 16;
    glGenBuffers(2, &transformFeedbackBuffer[0]);

    // Bind buffers to the transform feedback binding points
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, transformFeedbackBuffer[0]);
    glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, transformFeedbackBufferSize, NULL, GL_STATIC_DRAW);

    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 1, transformFeedbackBuffer[1]);
    glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, transformFeedbackBufferSize, NULL, GL_STATIC_DRAW);

    // Process one point with transform feedback
    glBeginTransformFeedback(GL_POINTS);
    glDrawArrays(GL_POINTS, 0, 1);
    glEndTransformFeedback();
    ASSERT_GL_NO_ERROR();

    // Second XFB buffer
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 1, transformFeedbackBuffer[1]);
    void *mappedBuffer = glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0,
                                          transformFeedbackBufferSize, GL_MAP_READ_BIT);
    ASSERT_NE(nullptr, mappedBuffer);

    float *mappedFloats = static_cast<float *>(mappedBuffer);
    // Expect vec4(1, 2, 3, 4)
    EXPECT_EQ(1, mappedFloats[0]);
    ANGLE_UNSAFE_TODO({
        EXPECT_EQ(2, mappedFloats[1]);
        EXPECT_EQ(3, mappedFloats[2]);
        EXPECT_EQ(4, mappedFloats[3]);
    })

    glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    glDeleteBuffers(2, transformFeedbackBuffer);

    EXPECT_GL_NO_ERROR();
}

// Test that resuming transform feedback after changing a pipeline shader stage results in
// validation error.
TEST_P(ProgramPipelineXFBTest31, ChangeShaderStageDuringPauseAndResume)
{
    // Only the Vulkan backend supports PPOs
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    const char *kVS1 = R"(#version 310 es
out float tfVarying10;
out float tfVarying11;
out float tfVarying12;
out float tfVarying13;
void main() {
    tfVarying10 = 1.0;
    tfVarying11 = 2.0;
    tfVarying12 = 3.0;
    tfVarying13 = 4.0;
    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
})";
    const char *kVS2 = R"(#version 310 es
out float tfVarying20;
out float tfVarying21;
void main() {
    tfVarying20 = -1.0;
    tfVarying21 = -2.0;
    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
})";

    const char *tfVaryings1[] = {"tfVarying10", "tfVarying11", "tfVarying12", "tfVarying13"};
    const char *tfVaryings2[] = {"tfVarying20", "tfVarying21"};

    GLShader vs1(GL_VERTEX_SHADER);
    GLuint vsProgram1 = glCreateProgram();
    glShaderSource(vs1, 1, &kVS1, nullptr);
    glCompileShader(vs1);
    glProgramParameteri(vsProgram1, GL_PROGRAM_SEPARABLE, GL_TRUE);
    glAttachShader(vsProgram1, vs1);
    glTransformFeedbackVaryings(vsProgram1, 4, tfVaryings1, GL_SEPARATE_ATTRIBS);
    glLinkProgram(vsProgram1);
    EXPECT_GL_NO_ERROR();

    GLShader vs2(GL_VERTEX_SHADER);
    GLuint vsProgram2 = glCreateProgram();
    glShaderSource(vs2, 1, &kVS2, nullptr);
    glCompileShader(vs2);
    glProgramParameteri(vsProgram2, GL_PROGRAM_SEPARABLE, GL_TRUE);
    glAttachShader(vsProgram2, vs2);
    glTransformFeedbackVaryings(vsProgram2, 2, tfVaryings2, GL_SEPARATE_ATTRIBS);
    glLinkProgram(vsProgram2);

    glEnable(GL_RASTERIZER_DISCARD);

    // XFB buffers
    GLBuffer xfbBuffers[4];
    constexpr GLsizei kInitSize = 4 * 1024;
    for (int i = 0; i < 4; ++i)
    {
        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, kInitSize, nullptr, GL_DYNAMIC_DRAW);
        glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        ASSERT_GL_NO_ERROR();
    }

    // Use the first program which uses four buffers.
    GLProgramPipeline pipeline;
    glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, vsProgram1);
    glBindProgramPipeline(pipeline);
    glUseProgram(0);

    glBeginTransformFeedback(GL_POINTS);
    glDrawArrays(GL_POINTS, 0, 1);
    glEndTransformFeedback();
    ASSERT_GL_NO_ERROR();

    // Validate the XFB values for the first program.
    for (int i = 0; i < 4; ++i)
    {
        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        const float *bufferData = reinterpret_cast<float *>(
            glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(GLfloat), GL_MAP_READ_BIT));
        ASSERT_NE(nullptr, bufferData);
        EXPECT_EQ(*bufferData, 1.0f + static_cast<float>(i));
        glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    }

    // Update the pipeline to use the second program which only uses the first two buffers.
    glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, vsProgram2);
    glBindProgramPipeline(pipeline);
    glUseProgram(0);
    glBeginTransformFeedback(GL_POINTS);
    glPauseTransformFeedback();
    ASSERT_GL_NO_ERROR();

    // Resuming transform feedback after changing a shader stage should result in validation error.
    glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, vsProgram1);
    glBindProgramPipeline(pipeline);
    glUseProgram(0);
    ASSERT_GL_NO_ERROR();
    glResumeTransformFeedback();
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    glDrawArrays(GL_POINTS, 0, 1);
    ASSERT_GL_NO_ERROR();

    // Resuming transform feedback with the same program from the beginning is OK.
    glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, vsProgram2);
    glBindProgramPipeline(pipeline);
    glUseProgram(0);
    ASSERT_GL_NO_ERROR();
    glResumeTransformFeedback();
    ASSERT_GL_NO_ERROR();

    glDrawArrays(GL_POINTS, 0, 1);
    ASSERT_GL_NO_ERROR();

    glEndTransformFeedback();
    ASSERT_GL_NO_ERROR();

    // Validate the XFB values for the second program.
    for (int i = 0; i < 2; ++i)
    {
        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        const float *bufferData = reinterpret_cast<float *>(
            glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(GLfloat), GL_MAP_READ_BIT));
        ASSERT_NE(nullptr, bufferData);
        EXPECT_EQ(*bufferData, -(1.0f + static_cast<float>(i)));
        glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    }

    glDeleteProgram(vsProgram1);
    glDeleteProgram(vsProgram2);
}

// Test that resuming transform feedback after changing a pipeline shader stage results in
// validation error, and using the original shader after updating the size of one of its buffers
// works.
TEST_P(ProgramPipelineXFBTest31, ChangeShaderStageDuringPauseAndResumeWithBufferChange)
{
    // Only the Vulkan backend supports PPOs
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    const char *kVS1 = R"(#version 310 es
out float tfVarying10;
out float tfVarying11;
out float tfVarying12;
out float tfVarying13;
void main() {
    tfVarying10 = 1.0;
    tfVarying11 = 2.0;
    tfVarying12 = 3.0;
    tfVarying13 = 4.0;
    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
})";
    const char *kVS2 = R"(#version 310 es
out float tfVarying20;
out float tfVarying21;
void main() {
    tfVarying20 = -1.0;
    tfVarying21 = -2.0;
    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
})";

    const char *tfVaryings1[] = {"tfVarying10", "tfVarying11", "tfVarying12", "tfVarying13"};
    const char *tfVaryings2[] = {"tfVarying20", "tfVarying21"};

    GLShader vs1(GL_VERTEX_SHADER);
    GLuint vsProgram1 = glCreateProgram();
    glShaderSource(vs1, 1, &kVS1, nullptr);
    glCompileShader(vs1);
    glProgramParameteri(vsProgram1, GL_PROGRAM_SEPARABLE, GL_TRUE);
    glAttachShader(vsProgram1, vs1);
    glTransformFeedbackVaryings(vsProgram1, 4, tfVaryings1, GL_SEPARATE_ATTRIBS);
    glLinkProgram(vsProgram1);
    EXPECT_GL_NO_ERROR();

    GLShader vs2(GL_VERTEX_SHADER);
    GLuint vsProgram2 = glCreateProgram();
    glShaderSource(vs2, 1, &kVS2, nullptr);
    glCompileShader(vs2);
    glProgramParameteri(vsProgram2, GL_PROGRAM_SEPARABLE, GL_TRUE);
    glAttachShader(vsProgram2, vs2);
    glTransformFeedbackVaryings(vsProgram2, 2, tfVaryings2, GL_SEPARATE_ATTRIBS);
    glLinkProgram(vsProgram2);

    glEnable(GL_RASTERIZER_DISCARD);

    // XFB buffers
    GLBuffer xfbBuffers[4];
    constexpr GLsizei kInitSize = 4 * 1024;
    for (int i = 0; i < 4; ++i)
    {
        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, kInitSize, nullptr, GL_DYNAMIC_DRAW);
        glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        ASSERT_GL_NO_ERROR();
    }

    // Use the first program which uses four buffers.
    GLProgramPipeline pipeline;
    glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, vsProgram1);
    glBindProgramPipeline(pipeline);
    glUseProgram(0);

    glBeginTransformFeedback(GL_POINTS);
    glDrawArrays(GL_POINTS, 0, 1);
    glEndTransformFeedback();
    ASSERT_GL_NO_ERROR();

    // Validate the XFB values for the first program.
    for (int i = 0; i < 4; ++i)
    {
        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        const float *bufferData = reinterpret_cast<float *>(
            glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(GLfloat), GL_MAP_READ_BIT));
        ASSERT_NE(nullptr, bufferData);
        EXPECT_EQ(*bufferData, 1.0f + static_cast<float>(i));
        glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    }

    // One of the buffers that will not be used in the second program is expanded.
    constexpr GLsizei kLargeSize = 8 * 1024 * 1024;
    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfbBuffers[2]);
    glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, kLargeSize, nullptr, GL_DYNAMIC_DRAW);
    ASSERT_GL_NO_ERROR();

    // Update the pipeline to use the second program which only uses the first two buffers.
    glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, vsProgram2);
    glBindProgramPipeline(pipeline);
    glUseProgram(0);
    glBeginTransformFeedback(GL_POINTS);
    glPauseTransformFeedback();
    ASSERT_GL_NO_ERROR();

    // Resuming transform feedback after changing a shader stage should result in validation error.
    glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, vsProgram1);
    glBindProgramPipeline(pipeline);
    glUseProgram(0);
    ASSERT_GL_NO_ERROR();
    glResumeTransformFeedback();
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    glDrawArrays(GL_POINTS, 0, 1);
    ASSERT_GL_NO_ERROR();

    // Resuming transform feedback with the same shaders from the beginning is OK.
    glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, vsProgram2);
    glBindProgramPipeline(pipeline);
    glUseProgram(0);
    ASSERT_GL_NO_ERROR();
    glResumeTransformFeedback();
    ASSERT_GL_NO_ERROR();

    glDrawArrays(GL_POINTS, 0, 1);
    ASSERT_GL_NO_ERROR();

    glEndTransformFeedback();
    ASSERT_GL_NO_ERROR();

    // Validate the XFB values for the second program.
    for (int i = 0; i < 2; ++i)
    {
        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        const float *bufferData = reinterpret_cast<float *>(
            glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(GLfloat), GL_MAP_READ_BIT));
        ASSERT_NE(nullptr, bufferData);
        EXPECT_EQ(*bufferData, -(1.0f + static_cast<float>(i)));
        glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    }

    // Use the original shaders again with the updated buffer.
    glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, vsProgram1);
    glBeginTransformFeedback(GL_POINTS);
    glDrawArrays(GL_POINTS, 0, 1);
    glEndTransformFeedback();
    ASSERT_GL_NO_ERROR();

    // Validate the XFB values for the first PPO again.
    for (int i = 0; i < 4; ++i)
    {
        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        const float *bufferData = reinterpret_cast<float *>(
            glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(GLfloat), GL_MAP_READ_BIT));
        ASSERT_NE(nullptr, bufferData);
        EXPECT_EQ(*bufferData, 1.0f + static_cast<float>(i));
        glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    }

    glDeleteProgram(vsProgram1);
    glDeleteProgram(vsProgram2);
}

// Test that resuming transform feedback with a different pipeline results in validation error.
TEST_P(ProgramPipelineXFBTest31, PipelineSwitchDuringPauseAndResume)
{
    // Only the Vulkan backend supports PPOs
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    const char *kVS1 = R"(#version 310 es
out float tfVarying10;
out float tfVarying11;
out float tfVarying12;
out float tfVarying13;
void main() {
    tfVarying10 = 1.0;
    tfVarying11 = 2.0;
    tfVarying12 = 3.0;
    tfVarying13 = 4.0;
    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
})";
    const char *kVS2 = R"(#version 310 es
out float tfVarying20;
out float tfVarying21;
void main() {
    tfVarying20 = -1.0;
    tfVarying21 = -2.0;
    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
})";

    const char *tfVaryings1[] = {"tfVarying10", "tfVarying11", "tfVarying12", "tfVarying13"};
    const char *tfVaryings2[] = {"tfVarying20", "tfVarying21"};

    GLShader vs1(GL_VERTEX_SHADER);
    GLuint vsProgram1 = glCreateProgram();
    glShaderSource(vs1, 1, &kVS1, nullptr);
    glCompileShader(vs1);
    glProgramParameteri(vsProgram1, GL_PROGRAM_SEPARABLE, GL_TRUE);
    glAttachShader(vsProgram1, vs1);
    glTransformFeedbackVaryings(vsProgram1, 4, tfVaryings1, GL_SEPARATE_ATTRIBS);
    glLinkProgram(vsProgram1);
    EXPECT_GL_NO_ERROR();

    GLShader vs2(GL_VERTEX_SHADER);
    GLuint vsProgram2 = glCreateProgram();
    glShaderSource(vs2, 1, &kVS2, nullptr);
    glCompileShader(vs2);
    glProgramParameteri(vsProgram2, GL_PROGRAM_SEPARABLE, GL_TRUE);
    glAttachShader(vsProgram2, vs2);
    glTransformFeedbackVaryings(vsProgram2, 2, tfVaryings2, GL_SEPARATE_ATTRIBS);
    glLinkProgram(vsProgram2);

    glEnable(GL_RASTERIZER_DISCARD);

    // XFB buffers
    GLBuffer xfbBuffers[4];
    constexpr GLsizei kInitSize = 4 * 1024;
    for (int i = 0; i < 4; ++i)
    {
        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, kInitSize, nullptr, GL_DYNAMIC_DRAW);
        glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        ASSERT_GL_NO_ERROR();
    }

    // Use the first pipeline with the first program which uses four buffers.
    GLProgramPipeline pipeline1;
    glUseProgramStages(pipeline1, GL_VERTEX_SHADER_BIT, vsProgram1);
    glBindProgramPipeline(pipeline1);
    glUseProgram(0);

    glBeginTransformFeedback(GL_POINTS);
    glDrawArrays(GL_POINTS, 0, 1);
    glEndTransformFeedback();
    ASSERT_GL_NO_ERROR();

    // Validate the XFB values for the first pipeline.
    for (int i = 0; i < 4; ++i)
    {
        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        const float *bufferData = reinterpret_cast<float *>(
            glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(GLfloat), GL_MAP_READ_BIT));
        ASSERT_NE(nullptr, bufferData);
        EXPECT_EQ(*bufferData, 1.0f + static_cast<float>(i));
        glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    }

    // Use the second pipeline with the second program which only uses the first two buffers.
    GLProgramPipeline pipeline2;
    glUseProgramStages(pipeline2, GL_VERTEX_SHADER_BIT, vsProgram2);
    glBindProgramPipeline(pipeline2);
    glUseProgram(0);
    glBeginTransformFeedback(GL_POINTS);
    glPauseTransformFeedback();
    ASSERT_GL_NO_ERROR();

    // Resuming transform feedback with another pipeline should result in validation error.
    glBindProgramPipeline(pipeline1);
    glUseProgram(0);
    ASSERT_GL_NO_ERROR();
    glResumeTransformFeedback();
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    glDrawArrays(GL_POINTS, 0, 1);
    ASSERT_GL_NO_ERROR();

    // Resuming transform feedback with the same pipeline from the beginning is OK.
    glBindProgramPipeline(pipeline2);
    glUseProgram(0);
    ASSERT_GL_NO_ERROR();
    glResumeTransformFeedback();
    ASSERT_GL_NO_ERROR();

    glDrawArrays(GL_POINTS, 0, 1);
    ASSERT_GL_NO_ERROR();

    glEndTransformFeedback();
    ASSERT_GL_NO_ERROR();

    // Validate the XFB values for the second pipeline.
    for (int i = 0; i < 2; ++i)
    {
        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        const float *bufferData = reinterpret_cast<float *>(
            glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(GLfloat), GL_MAP_READ_BIT));
        ASSERT_NE(nullptr, bufferData);
        EXPECT_EQ(*bufferData, -(1.0f + static_cast<float>(i)));
        glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    }

    glDeleteProgram(vsProgram1);
    glDeleteProgram(vsProgram2);
}

// Test that resuming transform feedback after enabling a shader program on top of the PPO results
// in validation error.
TEST_P(ProgramPipelineXFBTest31, BindProgramDuringPauseAndResume)
{
    // Only the Vulkan backend supports PPOs
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    const char *kVS1 = R"(#version 310 es
out float tfVarying10;
out float tfVarying11;
out float tfVarying12;
out float tfVarying13;
void main() {
    tfVarying10 = 1.0;
    tfVarying11 = 2.0;
    tfVarying12 = 3.0;
    tfVarying13 = 4.0;
    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
})";
    const char *kVS2 = R"(#version 310 es
out float tfVarying20;
out float tfVarying21;
void main() {
    tfVarying20 = -1.0;
    tfVarying21 = -2.0;
    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
})";
    const char *kFS  = R"(#version 310 es
precision mediump float;
out vec4 fragOut;
void main() {
    fragOut = vec4(1.0, 1.0, 1.0, 1.0);
})";

    const char *tfVaryings1[] = {"tfVarying10", "tfVarying11", "tfVarying12", "tfVarying13"};
    std::vector<std::string> tfVaryings2 = {"tfVarying20", "tfVarying21"};

    GLShader vs1(GL_VERTEX_SHADER);
    GLuint vsProgram1 = glCreateProgram();
    glShaderSource(vs1, 1, &kVS1, nullptr);
    glCompileShader(vs1);
    glProgramParameteri(vsProgram1, GL_PROGRAM_SEPARABLE, GL_TRUE);
    glAttachShader(vsProgram1, vs1);
    glTransformFeedbackVaryings(vsProgram1, 4, tfVaryings1, GL_SEPARATE_ATTRIBS);
    glLinkProgram(vsProgram1);
    EXPECT_GL_NO_ERROR();

    GLuint program2 =
        CompileProgramWithTransformFeedback(kVS2, kFS, tfVaryings2, GL_SEPARATE_ATTRIBS);
    ASSERT_NE(0u, program2);

    glEnable(GL_RASTERIZER_DISCARD);

    // XFB buffers
    GLBuffer xfbBuffers[4];
    constexpr GLsizei kInitSize = 4 * 1024;
    for (int i = 0; i < 4; ++i)
    {
        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, kInitSize, nullptr, GL_DYNAMIC_DRAW);
        glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        ASSERT_GL_NO_ERROR();
    }

    // Use the first program which uses four buffers through the PPO.
    GLProgramPipeline pipeline;
    glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, vsProgram1);
    glBindProgramPipeline(pipeline);
    glUseProgram(0);

    glBeginTransformFeedback(GL_POINTS);
    glDrawArrays(GL_POINTS, 0, 1);
    glEndTransformFeedback();
    ASSERT_GL_NO_ERROR();

    // Validate the XFB values for the first program.
    for (int i = 0; i < 4; ++i)
    {
        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        const float *bufferData = reinterpret_cast<float *>(
            glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(GLfloat), GL_MAP_READ_BIT));
        ASSERT_NE(nullptr, bufferData);
        EXPECT_EQ(*bufferData, 1.0f + static_cast<float>(i));
        glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    }

    // Use the PPO again, but use the second program after pausing XFB.
    glBeginTransformFeedback(GL_POINTS);
    glPauseTransformFeedback();
    ASSERT_GL_NO_ERROR();
    glUseProgram(program2);
    ASSERT_GL_NO_ERROR();

    // Resuming transform feedback after using the second program on top of the PPO should result in
    // validation error.
    glResumeTransformFeedback();
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    glDrawArrays(GL_POINTS, 0, 1);
    ASSERT_GL_NO_ERROR();

    // Resuming transform feedback after resetting the program and using the pipeline from the
    // beginning is OK.
    glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, vsProgram1);
    glBindProgramPipeline(pipeline);
    glUseProgram(0);
    ASSERT_GL_NO_ERROR();
    glResumeTransformFeedback();
    ASSERT_GL_NO_ERROR();

    glDrawArrays(GL_POINTS, 0, 1);
    ASSERT_GL_NO_ERROR();

    glEndTransformFeedback();
    ASSERT_GL_NO_ERROR();

    // Validate the XFB values for the first program.
    for (int i = 0; i < 4; ++i)
    {
        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        const float *bufferData = reinterpret_cast<float *>(
            glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(GLfloat), GL_MAP_READ_BIT));
        ASSERT_NE(nullptr, bufferData);
        EXPECT_EQ(*bufferData, 1.0f + static_cast<float>(i));
        glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    }

    glDeleteProgram(vsProgram1);
    glDeleteProgram(program2);
}

// Test that using a program and PPO together, the transform feedback will use the program over the
// PPO, and resuming after unbinding the program will result in validation error.
TEST_P(ProgramPipelineXFBTest31, UseProgramAndPPOThenUnbindProgramAndResume)
{
    // Only the Vulkan backend supports PPOs
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    const char *kVS1 = R"(#version 310 es
out float tfVarying10;
out float tfVarying11;
out float tfVarying12;
out float tfVarying13;
void main() {
    tfVarying10 = 1.0;
    tfVarying11 = 2.0;
    tfVarying12 = 3.0;
    tfVarying13 = 4.0;
    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
})";
    const char *kVS2 = R"(#version 310 es
out float tfVarying20;
out float tfVarying21;
void main() {
    tfVarying20 = -1.0;
    tfVarying21 = -2.0;
    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
})";
    const char *kFS  = R"(#version 310 es
precision mediump float;
out vec4 fragOut;
void main() {
    fragOut = vec4(1.0, 1.0, 1.0, 1.0);
})";

    std::vector<std::string> tfVaryings1 = {"tfVarying10", "tfVarying11", "tfVarying12",
                                            "tfVarying13"};
    const char *tfVaryings2[]            = {"tfVarying20", "tfVarying21"};

    GLuint program1 =
        CompileProgramWithTransformFeedback(kVS1, kFS, tfVaryings1, GL_SEPARATE_ATTRIBS);
    ASSERT_NE(0u, program1);

    GLShader vs2(GL_VERTEX_SHADER);
    GLuint vsProgram2 = glCreateProgram();
    glShaderSource(vs2, 1, &kVS2, nullptr);
    glCompileShader(vs2);
    glProgramParameteri(vsProgram2, GL_PROGRAM_SEPARABLE, GL_TRUE);
    glAttachShader(vsProgram2, vs2);
    glTransformFeedbackVaryings(vsProgram2, 2, tfVaryings2, GL_SEPARATE_ATTRIBS);
    glLinkProgram(vsProgram2);
    EXPECT_GL_NO_ERROR();

    glEnable(GL_RASTERIZER_DISCARD);

    // XFB buffers
    GLBuffer xfbBuffers[4];
    constexpr GLsizei kInitSize = 4 * 1024;
    for (int i = 0; i < 4; ++i)
    {
        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, kInitSize, nullptr, GL_DYNAMIC_DRAW);
        glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        ASSERT_GL_NO_ERROR();
    }

    // Use the first program and the PPO using the second program together.
    glUseProgram(program1);
    GLProgramPipeline pipeline;
    glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, vsProgram2);
    glBindProgramPipeline(pipeline);

    glBeginTransformFeedback(GL_POINTS);
    glDrawArrays(GL_POINTS, 0, 1);
    ASSERT_GL_NO_ERROR();

    // Pausing, unbinding the program and resuming should result in validation error.
    glPauseTransformFeedback();
    glUseProgram(0);
    glResumeTransformFeedback();
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    glUseProgram(program1);
    glResumeTransformFeedback();
    glEndTransformFeedback();
    ASSERT_GL_NO_ERROR();

    // Validate the XFB values, which should align with the bound program and not the PPO.
    for (int i = 0; i < 4; ++i)
    {
        glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, ANGLE_UNSAFE_TODO(xfbBuffers[i]));
        const float *bufferData = reinterpret_cast<float *>(
            glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(GLfloat), GL_MAP_READ_BIT));
        ASSERT_NE(nullptr, bufferData);
        EXPECT_EQ(*bufferData, 1.0f + static_cast<float>(i));
        glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    }

    glDeleteProgram(program1);
    glDeleteProgram(vsProgram2);
}

// Test modifying a shader and re-linking it updates the PPO too
TEST_P(ProgramPipelineTest31, ModifyAndRelinkShader)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    const GLchar *vertString      = essl31_shaders::vs::Simple();
    const GLchar *fragStringGreen = essl31_shaders::fs::Green();
    const GLchar *fragStringRed   = essl31_shaders::fs::Red();

    GLShader vertShader(GL_VERTEX_SHADER);
    GLShader fragShader(GL_FRAGMENT_SHADER);
    mVertProg = glCreateProgram();
    mFragProg = glCreateProgram();

    // Compile and link a separable vertex shader
    glShaderSource(vertShader, 1, &vertString, nullptr);
    glCompileShader(vertShader);
    glProgramParameteri(mVertProg, GL_PROGRAM_SEPARABLE, GL_TRUE);
    glAttachShader(mVertProg, vertShader);
    glLinkProgram(mVertProg);
    EXPECT_GL_NO_ERROR();

    // Compile and link a separable fragment shader
    glShaderSource(fragShader, 1, &fragStringGreen, nullptr);
    glCompileShader(fragShader);
    glProgramParameteri(mFragProg, GL_PROGRAM_SEPARABLE, GL_TRUE);
    glAttachShader(mFragProg, fragShader);
    glLinkProgram(mFragProg);
    EXPECT_GL_NO_ERROR();

    // Generate a program pipeline and attach the programs
    glGenProgramPipelines(1, &mPipeline);
    glUseProgramStages(mPipeline, GL_VERTEX_SHADER_BIT, mVertProg);
    glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
    glBindProgramPipeline(mPipeline);
    EXPECT_GL_NO_ERROR();

    // Draw once to ensure this worked fine
    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    // Detach the fragment shader and modify it such that it no longer fits with this pipeline
    glDetachShader(mFragProg, fragShader);

    // Modify the FS and re-link it
    glShaderSource(fragShader, 1, &fragStringRed, nullptr);
    glCompileShader(fragShader);
    glProgramParameteri(mFragProg, GL_PROGRAM_SEPARABLE, GL_TRUE);
    glAttachShader(mFragProg, fragShader);
    glLinkProgram(mFragProg);
    EXPECT_GL_NO_ERROR();

    // Draw with the PPO again and verify it's now red
    drawQuadWithPPO(essl31_shaders::PositionAttrib(), 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
}

// Test that a PPO can be used when the attached shader programs are created with glProgramBinary().
// This validates the necessary programs' information is serialized/deserialized so they can be
// linked by the PPO during glDrawArrays.
TEST_P(ProgramPipelineTest31, ProgramBinary)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());
    ANGLE_SKIP_TEST_IF(getAvailableProgramBinaryFormatCount() == 0);

    const GLchar *vertString = R"(#version 310 es
precision highp float;
in vec4 a_position;
out vec2 texCoord;
void main()
{
    gl_Position = a_position;
    texCoord = vec2(a_position.x, a_position.y) * 0.5 + vec2(0.5);
})";

    const GLchar *fragString = R"(#version 310 es
precision highp float;
in vec2 texCoord;
uniform sampler2D tex;
out vec4 my_FragColor;
void main()
{
    my_FragColor = texture(tex, texCoord);
})";

    std::array<GLColor, 4> colors = {
        {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};

    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    mVertProg = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &vertString);
    ASSERT_NE(mVertProg, 0u);
    mFragProg = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &fragString);
    ASSERT_NE(mFragProg, 0u);

    // Save the VS program binary out
    std::vector<uint8_t> vsBinary(0);
    GLint vsProgramLength = 0;
    GLint vsWrittenLength = 0;
    GLenum vsBinaryFormat = 0;
    glGetProgramiv(mVertProg, GL_PROGRAM_BINARY_LENGTH, &vsProgramLength);
    ASSERT_GL_NO_ERROR();
    vsBinary.resize(vsProgramLength);
    glGetProgramBinary(mVertProg, vsProgramLength, &vsWrittenLength, &vsBinaryFormat,
                       vsBinary.data());
    ASSERT_GL_NO_ERROR();

    // Save the FS program binary out
    std::vector<uint8_t> fsBinary(0);
    GLint fsProgramLength = 0;
    GLint fsWrittenLength = 0;
    GLenum fsBinaryFormat = 0;
    glGetProgramiv(mFragProg, GL_PROGRAM_BINARY_LENGTH, &fsProgramLength);
    ASSERT_GL_NO_ERROR();
    fsBinary.resize(fsProgramLength);
    glGetProgramBinary(mFragProg, fsProgramLength, &fsWrittenLength, &fsBinaryFormat,
                       fsBinary.data());
    ASSERT_GL_NO_ERROR();

    mVertProg = glCreateProgram();
    glProgramBinary(mVertProg, vsBinaryFormat, vsBinary.data(), vsWrittenLength);
    mFragProg = glCreateProgram();
    glProgramBinary(mFragProg, fsBinaryFormat, fsBinary.data(), fsWrittenLength);

    // Generate a program pipeline and attach the programs to their respective stages
    glGenProgramPipelines(1, &mPipeline);
    EXPECT_GL_NO_ERROR();
    glUseProgramStages(mPipeline, GL_VERTEX_SHADER_BIT, mVertProg);
    EXPECT_GL_NO_ERROR();
    glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
    EXPECT_GL_NO_ERROR();
    glBindProgramPipeline(mPipeline);
    EXPECT_GL_NO_ERROR();

    drawQuadWithPPO("a_position", 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();

    int w = getWindowWidth() - 2;
    int h = getWindowHeight() - 2;

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow);
}

// Test that updating a sampler uniform in a separable program behaves correctly with PPOs.
TEST_P(ProgramPipelineTest31, SampleTextureAThenTextureB)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    constexpr int kWidth  = 2;
    constexpr int kHeight = 2;

    const GLchar *vertString = R"(#version 310 es
precision highp float;
in vec2 a_position;
out vec2 texCoord;
void main()
{
    gl_Position = vec4(a_position, 0, 1);
    texCoord = a_position * 0.5 + vec2(0.5);
})";

    const GLchar *fragString = R"(#version 310 es
precision highp float;
in vec2 texCoord;
uniform sampler2D tex;
out vec4 my_FragColor;
void main()
{
    my_FragColor = texture(tex, texCoord);
})";

    std::array<GLColor, kWidth * kHeight> redColor = {
        {GLColor::red, GLColor::red, GLColor::red, GLColor::red}};
    std::array<GLColor, kWidth * kHeight> greenColor = {
        {GLColor::green, GLColor::green, GLColor::green, GLColor::green}};

    // Create a red texture and bind to texture unit 0
    GLTexture redTex;
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, redTex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 redColor.data());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    ASSERT_GL_NO_ERROR();
    // Create a green texture and bind to texture unit 1
    GLTexture greenTex;
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, greenTex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 greenColor.data());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glActiveTexture(GL_TEXTURE0);
    ASSERT_GL_NO_ERROR();

    bindProgramPipeline(vertString, fragString);

    GLint location1 = glGetUniformLocation(mFragProg, "tex");
    ASSERT_NE(location1, -1);
    glActiveShaderProgram(mPipeline, mFragProg);
    ASSERT_GL_NO_ERROR();

    glEnable(GL_BLEND);
    glBlendEquation(GL_FUNC_ADD);
    glBlendFunc(GL_ONE, GL_ONE);

    // Draw red
    glUniform1i(location1, 0);
    ASSERT_GL_NO_ERROR();
    drawQuadWithPPO("a_position", 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();

    // Draw green
    glUniform1i(location1, 1);
    ASSERT_GL_NO_ERROR();
    drawQuadWithPPO("a_position", 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::yellow);
}

// Verify that image uniforms can be used with separable programs
TEST_P(ProgramPipelineTest31, ImageUniforms)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    GLint maxVertexImageUniforms;
    glGetIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &maxVertexImageUniforms);
    ANGLE_SKIP_TEST_IF(maxVertexImageUniforms == 0);

    const GLchar *vertString = R"(#version 310 es
precision highp float;
precision highp image2D;
layout(binding = 0, r32f) uniform image2D img;

void main()
{
    gl_Position = imageLoad(img, ivec2(0, 0));
})";

    const GLchar *fragString = essl31_shaders::fs::Red();

    bindProgramPipeline(vertString, fragString);

    GLTexture texture;
    GLfloat value = 1.0;

    glBindTexture(GL_TEXTURE_2D, texture);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, 1, 1);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RED, GL_FLOAT, &value);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32F);

    glDrawArrays(GL_POINTS, 0, 6);
    ASSERT_GL_NO_ERROR();
}

// Verify that image uniforms can link in separable programs
TEST_P(ProgramPipelineTest31, LinkedImageUniforms)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    GLint maxVertexImageUniforms;
    glGetIntegerv(GL_MAX_VERTEX_IMAGE_UNIFORMS, &maxVertexImageUniforms);
    ANGLE_SKIP_TEST_IF(maxVertexImageUniforms == 0);

    const GLchar *vertString = R"(#version 310 es
precision highp float;
precision highp image2D;
layout(binding = 0, r32f) uniform image2D img;

void main()
{
    vec2 position = -imageLoad(img, ivec2(0, 0)).rr;
    if (gl_VertexID == 1)
        position = vec2(3, -1);
    else if (gl_VertexID == 2)
        position = vec2(-1, 3);

    gl_Position = vec4(position, 0, 1);
})";

    const GLchar *fragString = R"(#version 310 es
precision highp float;
precision highp image2D;
layout(binding = 0, r32f) uniform image2D img;
layout(location = 0) out vec4 color;

void main()
{
    color = imageLoad(img, ivec2(0, 0));
})";

    bindProgramPipeline(vertString, fragString);

    GLTexture texture;
    GLfloat value = 1.0;

    glBindTexture(GL_TEXTURE_2D, texture);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, 1, 1);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RED, GL_FLOAT, &value);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32F);

    glDrawArrays(GL_TRIANGLES, 0, 3);

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    ASSERT_GL_NO_ERROR();
}

// Verify that we can have the max amount of uniform buffer objects as part of a program
// pipeline.
TEST_P(ProgramPipelineTest31, MaxFragmentUniformBufferObjects)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    GLint maxUniformBlocks;
    glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &maxUniformBlocks);

    const GLchar *vertString = essl31_shaders::vs::Simple();
    std::stringstream fragStringStream;
    fragStringStream << R"(#version 310 es
precision highp float;
out vec4 my_FragColor;
layout(binding = 0) uniform block {
    float data;
} ubo[)";
    fragStringStream << maxUniformBlocks;
    fragStringStream << R"(];
void main()
{
    my_FragColor = vec4(1.0);
)";
    for (GLint index = 0; index < maxUniformBlocks; index++)
    {
        fragStringStream << "my_FragColor.x + ubo[" << index << "].data;" << std::endl;
    }
    fragStringStream << "}" << std::endl;

    bindProgramPipeline(vertString, fragStringStream.str().c_str());

    std::vector<GLBuffer> buffers(maxUniformBlocks);
    for (GLint index = 0; index < maxUniformBlocks; ++index)
    {
        glBindBuffer(GL_UNIFORM_BUFFER, buffers[index]);
        glBufferData(GL_UNIFORM_BUFFER, sizeof(GLfloat), NULL, GL_STATIC_DRAW);
        glBindBufferBase(GL_UNIFORM_BUFFER, index, buffers[index]);
    }

    glDrawArrays(GL_POINTS, 0, 6);
    ASSERT_GL_NO_ERROR();
}

// Verify that we can have the max amount of shader storage buffer objects as part of a program
// pipeline.
TEST_P(ProgramPipelineTest31, MaxFragmentShaderStorageBufferObjects)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    GLint maxShaderStorageBuffers;
    glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxShaderStorageBuffers);
    const GLchar *vertString = essl31_shaders::vs::Simple();
    std::stringstream fragStringStream;
    fragStringStream << R"(#version 310 es
precision highp float;
out vec4 my_FragColor;
layout(binding = 0) buffer buf {
    float data;
} ssbo[)";
    fragStringStream << maxShaderStorageBuffers;
    fragStringStream << R"(];
void main()
{
    my_FragColor = vec4(1.0);
)";
    for (GLint index = 0; index < maxShaderStorageBuffers; index++)
    {
        fragStringStream << "my_FragColor.x + ssbo[" << index << "].data;" << std::endl;
    }
    fragStringStream << "}" << std::endl;

    bindProgramPipeline(vertString, fragStringStream.str().c_str());

    std::vector<GLBuffer> buffers(maxShaderStorageBuffers);
    for (GLint index = 0; index < maxShaderStorageBuffers; ++index)
    {
        glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffers[index]);
        glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLfloat), NULL, GL_STATIC_DRAW);
        glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, buffers[index]);
    }

    glDrawArrays(GL_POINTS, 0, 6);
    ASSERT_GL_NO_ERROR();
}

// Test validation of redefinition of gl_Position and gl_PointSize in the vertex shader when
// GL_EXT_separate_shader_objects is enabled.
TEST_P(ProgramPipelineTest31, ValidatePositionPointSizeRedefinition)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_separate_shader_objects"));

    {
        constexpr char kVS[] = R"(#version 310 es
#extension GL_EXT_separate_shader_objects: require

out float gl_PointSize;

void main()
{
    gl_Position = vec4(0);
    gl_PointSize = 1.;
})";

        // Should fail because gl_Position is not declared.
        GLuint shader = createShaderProgram(GL_VERTEX_SHADER, kVS);
        EXPECT_EQ(shader, 0u);
    }

    {
        constexpr char kVS[] = R"(#version 310 es
#extension GL_EXT_separate_shader_objects: require

out float gl_PointSize;

void f()
{
    gl_PointSize = 1.;
}

out vec4 gl_Position;

void main()
{
    gl_Position = vec4(0);
})";

        // Should fail because gl_PointSize is used before gl_Position is declared.
        GLuint shader = createShaderProgram(GL_VERTEX_SHADER, kVS);
        EXPECT_EQ(shader, 0u);
    }

    {
        constexpr char kVS[] = R"(#version 310 es
#extension GL_EXT_separate_shader_objects: require

out float gl_PointSize;
out vec4 gl_Position;

void main()
{
    gl_Position = vec4(0);
    gl_PointSize = 1.;
})";

        // Should compile.
        GLuint shader = createShaderProgram(GL_VERTEX_SHADER, kVS);
        EXPECT_NE(shader, 0u);
    }
}

// Basic draw test with GL_EXT_separate_shader_objects enabled in the vertex shader
TEST_P(ProgramPipelineTest31, BasicDrawWithPositionPointSizeRedefinition)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_separate_shader_objects"));

    const char kVS[] = R"(#version 310 es
#extension GL_EXT_separate_shader_objects: require

out float gl_PointSize;
out vec4 gl_Position;

in vec4 a_position;

void main()
{
    gl_Position = a_position;
})";

    mVertProg = createShaderProgram(GL_VERTEX_SHADER, kVS);
    ASSERT_NE(mVertProg, 0u);
    mFragProg = createShaderProgram(GL_FRAGMENT_SHADER, essl31_shaders::fs::Red());
    ASSERT_NE(mFragProg, 0u);

    // Generate a program pipeline and attach the programs to their respective stages
    GLuint pipeline;
    glGenProgramPipelines(1, &pipeline);
    glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, mVertProg);
    glUseProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
    glBindProgramPipeline(pipeline);
    EXPECT_GL_NO_ERROR();

    drawQuadWithPPO("a_position", 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
}

// Test a PPO scenario from a game, calling glBindBufferRange between two draws with
// multiple binding points, some unused.  This would result in a crash without the fix.
// https://issuetracker.google.com/issues/299532942
TEST_P(ProgramPipelineTest31, ProgramPipelineBindBufferRange)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    const GLchar *vertString = R"(#version 310 es
in vec4 position;
layout(std140, binding = 0) uniform ubo1 {
    vec4 color;
};
layout(location=0) out vec4 vsColor;
void main()
{
    vsColor = color;
    gl_Position = position;
})";

    const GLchar *fragString = R"(#version 310 es
precision mediump float;
layout(std140, binding = 1) uniform globals {
    vec4 fsColor;
};
layout(std140, binding = 2) uniform params {
    vec4 foo;
};
layout(std140, binding = 3) uniform layer {
    vec4 bar;
};
layout(location=0) highp in vec4 vsColor;
layout(location=0) out vec4 diffuse;
void main()
{
    diffuse = vsColor + fsColor;
})";

    // Create the pipeline
    GLProgramPipeline programPipeline;
    glBindProgramPipeline(programPipeline);

    // Create the vertex shader
    GLShader vertShader(GL_VERTEX_SHADER);
    glShaderSource(vertShader, 1, &vertString, nullptr);
    glCompileShader(vertShader);
    mVertProg = glCreateProgram();
    glProgramParameteri(mVertProg, GL_PROGRAM_SEPARABLE, 1);
    glAttachShader(mVertProg, vertShader);
    glLinkProgram(mVertProg);
    glUseProgramStages(programPipeline, GL_VERTEX_SHADER_BIT, mVertProg);
    EXPECT_GL_NO_ERROR();

    // Create the fragment shader
    GLShader fragShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragShader, 1, &fragString, nullptr);
    glCompileShader(fragShader);
    mFragProg = glCreateProgram();
    glProgramParameteri(mFragProg, GL_PROGRAM_SEPARABLE, 1);
    glAttachShader(mFragProg, fragShader);
    glLinkProgram(mFragProg);
    glUseProgramStages(programPipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
    EXPECT_GL_NO_ERROR();

    // Set up a uniform buffer with room for five offsets, four active at a time
    GLBuffer ubo;
    glBindBuffer(GL_UNIFORM_BUFFER, ubo);
    glBufferData(GL_UNIFORM_BUFFER, 2048, 0, GL_DYNAMIC_DRAW);
    uint8_t *mappedBuffer =
        static_cast<uint8_t *>(glMapBufferRange(GL_UNIFORM_BUFFER, 0, 2048, GL_MAP_WRITE_BIT));
    ASSERT_NE(nullptr, mappedBuffer);

    // Only set up three of the five offsets. The other two must be present, but unused.
    GLColor32F *binding0 = reinterpret_cast<GLColor32F *>(mappedBuffer);
    GLColor32F *binding1 = reinterpret_cast<GLColor32F *>(ANGLE_UNSAFE_TODO(mappedBuffer + 256));
    GLColor32F *binding4 = reinterpret_cast<GLColor32F *>(ANGLE_UNSAFE_TODO(mappedBuffer + 1024));
    *binding0            = kFloatRed;
    *binding1            = kFloatGreen;
    *binding4            = kFloatBlue;
    glUnmapBuffer(GL_UNIFORM_BUFFER);

    // Start with binding0=red and binding1=green
    glBindBufferRange(GL_UNIFORM_BUFFER, 0, ubo, 0, 256);
    glBindBufferRange(GL_UNIFORM_BUFFER, 1, ubo, 256, 512);
    glBindBufferRange(GL_UNIFORM_BUFFER, 2, ubo, 512, 768);
    glBindBufferRange(GL_UNIFORM_BUFFER, 3, ubo, 768, 1024);
    EXPECT_GL_NO_ERROR();

    // Set up data for draw
    std::array<Vector3, 6> verts = GetQuadVertices();
    GLBuffer vbo;
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, verts.size() * sizeof(verts[0]), verts.data(), GL_STATIC_DRAW);
    GLint posLoc = glGetAttribLocation(mVertProg, "position");
    glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnableVertexAttribArray(posLoc);
    EXPECT_GL_NO_ERROR();

    // Perform the first draw
    glDrawArrays(GL_TRIANGLES, 0, 6);

    // At this point we have red+green=yellow, but read-back changes dirty bits and breaks the test
    // EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
    EXPECT_GL_NO_ERROR();

    // This is the key here - call glBindBufferRange between glDraw* calls, changing binding0=blue
    glBindBufferRange(GL_UNIFORM_BUFFER, 0, ubo, 1024, 1280);
    EXPECT_GL_NO_ERROR();

    // The next draw would crash in handleDirtyGraphicsUniformBuffers without the accompanying fix
    glDrawArrays(GL_TRIANGLES, 0, 6);

    // We should now have green+blue=cyan
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
    EXPECT_GL_NO_ERROR();
}

// Test that GetProgramPipelineivf works.
TEST_P(ProgramPipelineTest31, ProgramPipelineivTest)
{
    GLuint pipeline;
    GLint log_length = -1;
    glGenProgramPipelines(1, &pipeline);
    glGetProgramPipelineiv(pipeline, GL_INFO_LOG_LENGTH, &log_length);
    glGetProgramPipelineInfoLog(pipeline, 0, NULL, NULL);
    EXPECT_GL_NO_ERROR();
    glDeleteProgramPipelines(1, &pipeline);
    EXPECT_GL_NO_ERROR();
}

// Test that shader interface matching does not accidentally match by name
// when location is specified in separable programs.
TEST_P(ProgramPipelineTest31, ShaderInterfaceMatchingTest)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    const GLchar *vertString = R"(#version 310 es
precision highp float;
in vec4 a_position;
layout(location = 0) flat out uvec3 u3;
layout(location = 1) out float f[2];
void main()
{
    gl_Position = a_position;
})";

    const GLchar *fragString = R"(#version 310 es
precision highp float;
layout(location = 0) flat in uvec3 f;
layout(location = 1) in float u3[2];
out vec4 my_FragColor;
void main()
{
    my_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
})";
    bindProgramPipeline(vertString, fragString);

    drawQuadWithPPO("a_position", 0.5f, 1.0f);
    ASSERT_GL_NO_ERROR();
}

class ProgramPipelineTest32 : public ProgramPipelineTest
{
  protected:
    void testTearDown() override
    {
        glDeleteProgram(mVertProg);
        glDeleteProgram(mFragProg);
        glDeleteProgramPipelines(1, &mPipeline);
    }

    void bindProgramPipeline(const GLchar *vertString,
                             const GLchar *fragString,
                             const GLchar *geomString);
    void drawQuadWithPPO(const std::string &positionAttribName,
                         const GLfloat positionAttribZ,
                         const GLfloat positionAttribXYScale);

    GLuint mVertProg = 0;
    GLuint mFragProg = 0;
    GLuint mGeomProg = 0;
    GLuint mPipeline = 0;
};

void ProgramPipelineTest32::bindProgramPipeline(const GLchar *vertString,
                                                const GLchar *fragString,
                                                const GLchar *geomString)
{
    mVertProg = createShaderProgram(GL_VERTEX_SHADER, vertString);
    ASSERT_NE(mVertProg, 0u);
    mFragProg = createShaderProgram(GL_FRAGMENT_SHADER, fragString);
    ASSERT_NE(mFragProg, 0u);
    mGeomProg = createShaderProgram(GL_GEOMETRY_SHADER, geomString);
    ASSERT_NE(mGeomProg, 0u);

    // Generate a program pipeline and attach the programs to their respective stages
    glGenProgramPipelines(1, &mPipeline);
    EXPECT_GL_NO_ERROR();
    glUseProgramStages(mPipeline, GL_VERTEX_SHADER_BIT, mVertProg);
    EXPECT_GL_NO_ERROR();
    glUseProgramStages(mPipeline, GL_FRAGMENT_SHADER_BIT, mFragProg);
    EXPECT_GL_NO_ERROR();
    glUseProgramStages(mPipeline, GL_GEOMETRY_SHADER_BIT, mGeomProg);
    EXPECT_GL_NO_ERROR();
    glBindProgramPipeline(mPipeline);
    EXPECT_GL_NO_ERROR();
}

// Verify that we can have the max amount of uniforms with a geometry shader as part of a program
// pipeline.
TEST_P(ProgramPipelineTest32, MaxGeometryImageUniforms)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan() || !IsGLExtensionEnabled("GL_EXT_geometry_shader"));

    GLint maxGeometryImageUnits;
    glGetIntegerv(GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT, &maxGeometryImageUnits);

    const GLchar *vertString = essl31_shaders::vs::Simple();
    const GLchar *fragString = R"(#version 310 es
precision highp float;
out vec4 my_FragColor;
void main()
{
    my_FragColor = vec4(1.0);
})";

    std::stringstream geomStringStream;

    geomStringStream << R"(#version 310 es
#extension GL_OES_geometry_shader : require
layout (points)                   in;
layout (points, max_vertices = 1) out;

precision highp iimage2D;

ivec4 counter = ivec4(0);
)";

    for (GLint index = 0; index < maxGeometryImageUnits; ++index)
    {
        geomStringStream << "layout(binding = " << index << ", r32i) uniform iimage2D img" << index
                         << ";" << std::endl;
    }

    geomStringStream << R"(
void main()
{
)";

    for (GLint index = 0; index < maxGeometryImageUnits; ++index)
    {
        geomStringStream << "counter += imageLoad(img" << index << ", ivec2(0, 0));" << std::endl;
    }

    geomStringStream << R"(
    gl_Position = vec4(float(counter.x), 0.0, 0.0, 1.0);
    EmitVertex();
}
)";

    bindProgramPipeline(vertString, fragString, geomStringStream.str().c_str());

    std::vector<GLTexture> textures(maxGeometryImageUnits);
    for (GLint index = 0; index < maxGeometryImageUnits; ++index)
    {
        GLint value = index + 1;

        glBindTexture(GL_TEXTURE_2D, textures[index]);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32I, 1, 1);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RED_INTEGER, GL_INT, &value);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        glBindImageTexture(index, textures[index], 0, GL_FALSE, 0, GL_READ_ONLY, GL_R32I);
    }

    glDrawArrays(GL_POINTS, 0, 6);
    ASSERT_GL_NO_ERROR();
}

// Verify creation of seperable tessellation control shader program with transform feeback varying
TEST_P(ProgramPipelineTest32, CreateProgramWithTransformFeedbackVarying)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_tessellation_shader"));

    const char *kVS =
        "#version 320 es\n"
        "\n"
        "#extension GL_EXT_shader_io_blocks : require\n"
        "\n"
        "precision highp float;\n"

        "out BLOCK_INOUT { vec4 value; } user_out;\n"
        "\n"
        "void main()\n"
        "{\n"
        "    gl_Position    = vec4(1.0, 0.0, 0.0, 1.0);\n"
        "    user_out.value = vec4(4.0, 5.0, 6.0, 7.0);\n"
        "}\n";

    // Fragment shader body
    const char *kFS =
        "#version 320 es\n"
        "\n"
        "#extension GL_EXT_shader_io_blocks : require\n"
        "\n"
        "precision highp float;\n"
        "in BLOCK_INOUT { vec4 value; } user_in;\n"
        "\n"
        "void main()\n"
        "{\n"
        "}\n";

    // Geometry shader body
    const char *kGS =
        "#version 320 es\n"
        "\n"
        "#extension GL_EXT_geometry_shader : require\n"
        "\n"
        "layout(points)                   in;\n"
        "layout(points, max_vertices = 1) out;\n"
        "\n"
        "precision highp float;\n"
        "//${IN_PER_VERTEX_DECL_ARRAY}\n"
        "//${OUT_PER_VERTEX_DECL}\n"
        "in  BLOCK_INOUT { vec4 value; } user_in[];\n"
        "out BLOCK_INOUT { vec4 value; } user_out;\n"
        "\n"
        "void main()\n"
        "{\n"
        "    user_out.value = vec4(1.0, 2.0, 3.0, 4.0);\n"
        "    gl_Position    = vec4(0.0, 0.0, 0.0, 1.0);\n"
        "\n"
        "    EmitVertex();\n"
        "}\n";

    // tessellation control shader body
    const char *kTCS =
        "#version 320 es\n"
        "\n"
        "#extension GL_EXT_tessellation_shader : require\n"
        "#extension GL_EXT_shader_io_blocks : require\n"
        "\n"
        "layout (vertices=4) out;\n"
        "\n"
        "precision highp float;\n"
        "in  BLOCK_INOUT { vec4 value; } user_in[];\n"
        "out BLOCK_INOUT { vec4 value; } user_out[];\n"
        "\n"
        "void main()\n"
        "{\n"
        "    gl_out   [gl_InvocationID].gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
        "    user_out [gl_InvocationID].value       = vec4(2.0, 3.0, 4.0, 5.0);\n"
        "\n"
        "    gl_TessLevelOuter[0] = 1.0;\n"
        "    gl_TessLevelOuter[1] = 1.0;\n"
        "}\n";

    // Tessellation evaluation shader
    const char *kTES =
        "#version 320 es\n"
        "\n"
        "#extension GL_EXT_tessellation_shader : require\n"
        "#extension GL_EXT_shader_io_blocks : require\n"
        "\n"
        "layout (isolines, point_mode) in;\n"
        "\n"
        "precision highp float;\n"
        "in  BLOCK_INOUT { vec4 value; } user_in[];\n"
        "out BLOCK_INOUT { vec4 value; } user_out;\n"
        "\n"
        "void main()\n"
        "{\n"
        "    gl_Position     = gl_in[0].gl_Position;\n"
        "    user_out.value = vec4(3.0, 4.0, 5.0, 6.0);\n"
        "}\n";
    const GLchar *kVaryingName = "BLOCK_INOUT.value";

    GLuint fsProgram = createShaderProgram(GL_FRAGMENT_SHADER, kFS);
    ASSERT_NE(0u, fsProgram);

    GLuint vsProgram = createShaderProgram(GL_VERTEX_SHADER, kVS, 1, &kVaryingName);
    ASSERT_NE(0u, vsProgram);

    GLuint gsProgram = 0u;
    if (IsGLExtensionEnabled("GL_EXT_geometry_shader"))
    {
        gsProgram = createShaderProgram(GL_GEOMETRY_SHADER, kGS, 1, &kVaryingName);
        ASSERT_NE(0u, gsProgram);
    }

    GLuint tcsProgram = createShaderProgram(GL_TESS_CONTROL_SHADER, kTCS, 1, &kVaryingName);
    // Should fail here.
    ASSERT_EQ(0u, tcsProgram);

    // try compiling without transform feedback varying it should pass
    tcsProgram = createShaderProgram(GL_TESS_CONTROL_SHADER, kTCS);
    ASSERT_NE(0u, tcsProgram);

    GLuint tesProgram = createShaderProgram(GL_TESS_EVALUATION_SHADER, kTES, 1, &kVaryingName);
    ASSERT_NE(0u, tesProgram);

    glDeleteProgram(fsProgram);
    glDeleteProgram(vsProgram);
    if (gsProgram != 0u)
    {
        glDeleteProgram(gsProgram);
    }
    glDeleteProgram(tcsProgram);
    glDeleteProgram(tesProgram);
}

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ProgramPipelineTest);
ANGLE_INSTANTIATE_TEST_ES3_AND_ES31(ProgramPipelineTest);

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ProgramPipelineTest31);
ANGLE_INSTANTIATE_TEST_ES31(ProgramPipelineTest31);

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ProgramPipelineXFBTest31);
ANGLE_INSTANTIATE_TEST_ES31(ProgramPipelineXFBTest31);

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ProgramPipelineTest32);
ANGLE_INSTANTIATE_TEST_ES32(ProgramPipelineTest32);

}  // namespace
