//
// Copyright 2018 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.
//
// AttributeLayoutTest:
//   Test various layouts of vertex attribute data:
//   - in memory, in buffer object, or combination of both
//   - sequential or interleaved
//   - various combinations of data types
//

#include <array>
#include <vector>
#include "common/unsafe_buffers.h"

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

using namespace angle;

namespace
{

// Test will draw these four triangles.
// clang-format off
constexpr double kTriangleData[] = {
    // xy       rgb
    0,0,        1,1,0,
    -1,+1,      1,1,0,
    +1,+1,      1,1,0,

    0,0,        0,1,0,
    +1,+1,      0,1,0,
    +1,-1,      0,1,0,

    0,0,        0,1,1,
    +1,-1,      0,1,1,
    -1,-1,      0,1,1,

    0,0,        1,0,1,
    -1,-1,      1,0,1,
    -1,+1,      1,0,1,
};
// clang-format on

constexpr size_t kNumVertices = ArraySize(kTriangleData) / 5;

// Vertex data source description.
class VertexData
{
  public:
    VertexData(int dimension,
               const double *data,
               unsigned offset,
               unsigned stride,
               unsigned numVertices)
        : mNumVertices(numVertices),
          mDimension(dimension),
          mData(data),
          mOffset(offset),
          mStride(stride)
    {}
    int getDimension() const { return mDimension; }
    unsigned getNumVertices() const { return mNumVertices; }
    double getValue(unsigned vertexNumber, int component) const
    {
        return ANGLE_UNSAFE_TODO(mData[mOffset + mStride * vertexNumber + component]);
    }

  private:
    unsigned mNumVertices;
    int mDimension;
    const double *mData;
    // offset and stride in doubles
    unsigned mOffset;
    unsigned mStride;
};

// A container for one or more vertex attributes.
class Container
{
  public:
    static constexpr size_t kSize = 1024;

    void open(void) { ANGLE_UNSAFE_TODO(memset(mMemory, 0xff, kSize)); }
    void *getDestination(size_t offset) { return ANGLE_UNSAFE_TODO(mMemory + offset); }
    virtual void close(void) {}
    virtual ~Container() {}
    virtual const char *getAddress() = 0;
    virtual GLuint getBuffer()       = 0;

  protected:
    char mMemory[kSize];
};

// Vertex attribute data in client memory.
class Memory : public Container
{
  public:
    const char *getAddress() override { return mMemory; }
    GLuint getBuffer() override { return 0; }
};

// Vertex attribute data in buffer object.
class Buffer : public Container
{
  public:
    void close(void) override
    {
        glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(mMemory), mMemory, GL_STATIC_DRAW);
    }

    const char *getAddress() override { return nullptr; }
    GLuint getBuffer() override { return mBuffer; }

  protected:
    GLBuffer mBuffer;
};

// Encapsulate the storage, layout, format and data of a vertex attribute.
struct Attrib
{
    void openContainer(void) const { mContainer->open(); }

    void fillContainer(void) const
    {
        for (unsigned i = 0; i < mData.getNumVertices(); ++i)
        {
            for (int j = 0; j < mData.getDimension(); ++j)
            {
                size_t destOffset = mOffset + mStride * i + mCTypeSize * j;
                if (destOffset + mCTypeSize > Container::kSize)
                    FAIL() << "test case does not fit container";

                double value = mData.getValue(i, j);
                if (mGLType == GL_FIXED)
                    value *= 1 << 16;
                else if (mNormalized)
                {
                    if (value < mMinIn || value > mMaxIn)
                        FAIL() << "test data does not fit format";
                    value = (value - mMinIn) * mScale + mMinOut;
                }

                mStore(value, mContainer->getDestination(destOffset));
            }
        }
    }

    void closeContainer(void) const { mContainer->close(); }

    void enable(unsigned index) const
    {
        glBindBuffer(GL_ARRAY_BUFFER, mContainer->getBuffer());
        if (mPureInteger)
        {
            glVertexAttribIPointer(index, mData.getDimension(), mGLType, mStride,
                                   getContainerOffset());
        }
        else
        {
            glVertexAttribPointer(index, mData.getDimension(), mGLType, mNormalized, mStride,
                                  getContainerOffset());
        }
        EXPECT_GL_NO_ERROR();
        glEnableVertexAttribArray(index);
    }

    bool inClientMemory() const { return mContainer->getAddress() != nullptr; }
    const char *getContainerOffset() const
    {
        return inClientMemory() ? ANGLE_UNSAFE_TODO(mContainer->getAddress() + mOffset)
                                : reinterpret_cast<const char *>(mOffset);
    }

    std::shared_ptr<Container> mContainer;
    unsigned mOffset;
    unsigned mStride;
    const VertexData &mData;
    void (*mStore)(double value, void *dest);
    GLenum mGLType;
    GLboolean mNormalized;
    GLboolean mPureInteger = GL_FALSE;
    size_t mCTypeSize;
    double mMinIn;
    double mMaxIn;
    double mMinOut;
    double mScale;
};

// Change type and store.
template <class T>
void Store(double value, void *dest)
{
    T v = static_cast<T>(value);
    ANGLE_UNSAFE_TODO(memcpy(dest, &v, sizeof(v)));
}

// Function object that makes Attrib structs according to a vertex format.
template <class CType, GLenum GLType, bool Normalized, bool PureInteger = false>
class Format
{
    static_assert(!(Normalized && GLType == GL_FLOAT), "Normalized float does not make sense.");

  public:
    Format(bool es3) : mES3(es3) {}

    Attrib operator()(std::shared_ptr<Container> container,
                      unsigned offset,
                      unsigned stride,
                      const VertexData &data) const
    {
        double minIn    = 0;
        double maxIn    = 1;
        double minOut   = std::numeric_limits<CType>::min();
        double rangeOut = std::numeric_limits<CType>::max() - minOut;

        if (std::is_signed<CType>::value)
        {
            minIn = -1;
            maxIn = +1;
            if (mES3)
            {
                minOut += 1;
                rangeOut -= 1;
            }
        }

        return {
            container,
            offset,
            stride,
            data,
            Store<CType>,
            GLType,
            Normalized,
            PureInteger,
            sizeof(CType),
            minIn,
            maxIn,
            minOut,
            rangeOut / (maxIn - minIn),
        };
    }

  protected:
    const bool mES3;
};

typedef std::vector<Attrib> TestCase;

void PrepareTestCase(const TestCase &tc)
{
    for (const Attrib &a : tc)
        a.openContainer();
    for (const Attrib &a : tc)
        a.fillContainer();
    for (const Attrib &a : tc)
        a.closeContainer();
    unsigned i = 0;
    for (const Attrib &a : tc)
        a.enable(i++);
}

class AttributeLayoutTest : public ANGLETest<>
{
  protected:
    AttributeLayoutTest()
        : mProgram(0),
          mCoord(2, kTriangleData, 0, 5, kNumVertices),
          mColor(3, kTriangleData, 2, 5, kNumVertices)
    {
        setWindowWidth(128);
        setWindowHeight(128);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }

    void GetTestCases(void);

    void testSetUp() override
    {
        glClearColor(.2f, .2f, .2f, .0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glDisable(GL_DEPTH_TEST);

        constexpr char kVS[] =
            "attribute mediump vec2 coord;\n"
            "attribute mediump vec3 color;\n"
            "varying mediump vec3 vcolor;\n"
            "void main(void)\n"
            "{\n"
            "    gl_Position = vec4(coord, 0, 1);\n"
            "    vcolor = color;\n"
            "}\n";

        constexpr char kFS[] =
            "varying mediump vec3 vcolor;\n"
            "void main(void)\n"
            "{\n"
            "    gl_FragColor = vec4(vcolor, 0);\n"
            "}\n";

        mProgram = CompileProgram(kVS, kFS);
        ASSERT_NE(0u, mProgram);
        glUseProgram(mProgram);

        glGenBuffers(1, &mIndexBuffer);

        GetTestCases();
    }

    void testTearDown() override
    {
        mTestCases.clear();
        glDeleteProgram(mProgram);
        glDeleteBuffers(1, &mIndexBuffer);
    }

    virtual bool Skip(const TestCase &) { return false; }
    virtual void Draw(int firstVertex, unsigned vertexCount, const GLushort *indices) = 0;

    void Run(bool drawFirstTriangle)
    {
        glViewport(0, 0, getWindowWidth(), getWindowHeight());
        glUseProgram(mProgram);

        for (unsigned i = 0; i < mTestCases.size(); ++i)
        {
            if (mTestCases[i].size() == 0 || Skip(mTestCases[i]))
                continue;

            PrepareTestCase(mTestCases[i]);

            glClear(GL_COLOR_BUFFER_BIT);

            std::string testCase;
            if (drawFirstTriangle)
            {
                Draw(0, kNumVertices, mIndices);
                testCase = "draw";
            }
            else
            {
                Draw(3, kNumVertices - 3, ANGLE_UNSAFE_TODO(mIndices + 3));
                testCase = "skip";
            }

            testCase += " first triangle case ";
            int w = getWindowWidth() / 4;
            int h = getWindowHeight() / 4;
            if (drawFirstTriangle)
            {
                EXPECT_PIXEL_EQ(w * 2, h * 3, 255, 255, 0, 0) << testCase << i;
            }
            else
            {
                EXPECT_PIXEL_EQ(w * 2, h * 3, 51, 51, 51, 0) << testCase << i;
            }
            EXPECT_PIXEL_EQ(w * 3, h * 2, 0, 255, 0, 0) << testCase << i;
            EXPECT_PIXEL_EQ(w * 2, h * 1, 0, 255, 255, 0) << testCase << i;
            EXPECT_PIXEL_EQ(w * 1, h * 2, 255, 0, 255, 0) << testCase << i;
        }
    }

    static const GLushort mIndices[kNumVertices];

    GLuint mProgram;
    GLuint mIndexBuffer;

    std::vector<TestCase> mTestCases;

    VertexData mCoord;
    VertexData mColor;
};
const GLushort AttributeLayoutTest::mIndices[kNumVertices] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};

void AttributeLayoutTest::GetTestCases(void)
{
    const bool es3 = getClientMajorVersion() >= 3;

    Format<GLfloat, GL_FLOAT, false> Float(es3);
    Format<GLint, GL_FIXED, false> Fixed(es3);

    Format<GLbyte, GL_BYTE, false> SByte(es3);
    Format<GLubyte, GL_UNSIGNED_BYTE, false> UByte(es3);
    Format<GLshort, GL_SHORT, false> SShort(es3);
    Format<GLushort, GL_UNSIGNED_SHORT, false> UShort(es3);
    Format<GLint, GL_INT, false> SInt(es3);
    Format<GLuint, GL_UNSIGNED_INT, false> UInt(es3);

    Format<GLbyte, GL_BYTE, true> NormSByte(es3);
    Format<GLubyte, GL_UNSIGNED_BYTE, true> NormUByte(es3);
    Format<GLshort, GL_SHORT, true> NormSShort(es3);
    Format<GLushort, GL_UNSIGNED_SHORT, true> NormUShort(es3);
    Format<GLint, GL_INT, true> NormSInt(es3);
    Format<GLuint, GL_UNSIGNED_INT, true> NormUInt(es3);

    std::shared_ptr<Container> M0 = std::make_shared<Memory>();
    std::shared_ptr<Container> M1 = std::make_shared<Memory>();
    std::shared_ptr<Container> B0 = std::make_shared<Buffer>();
    std::shared_ptr<Container> B1 = std::make_shared<Buffer>();

    // 0. two buffers
    mTestCases.push_back({Float(B0, 0, 8, mCoord), Float(B1, 0, 12, mColor)});

    // 1. two memory
    mTestCases.push_back({Float(M0, 0, 8, mCoord), Float(M1, 0, 12, mColor)});

    // 2. one memory, sequential
    mTestCases.push_back({Float(M0, 0, 8, mCoord), Float(M0, 96, 12, mColor)});

    // 3. one memory, interleaved
    mTestCases.push_back({Float(M0, 0, 20, mCoord), Float(M0, 8, 20, mColor)});

    // 4. buffer and memory
    mTestCases.push_back({Float(B0, 0, 8, mCoord), Float(M0, 0, 12, mColor)});

    // 5. stride != size
    mTestCases.push_back({Float(B0, 0, 16, mCoord), Float(B1, 0, 12, mColor)});

    // 6-7. same stride and format, switching data between memory and buffer
    mTestCases.push_back({Float(M0, 0, 16, mCoord), Float(M1, 0, 12, mColor)});
    mTestCases.push_back({Float(B0, 0, 16, mCoord), Float(B1, 0, 12, mColor)});

    // 8-9. same stride and format, offset change
    mTestCases.push_back({Float(B0, 0, 8, mCoord), Float(B1, 0, 12, mColor)});
    mTestCases.push_back({Float(B0, 3, 8, mCoord), Float(B1, 4, 12, mColor)});

    // 10-11. unaligned buffer data
    mTestCases.push_back({Float(M0, 0, 8, mCoord), Float(B0, 1, 13, mColor)});
    mTestCases.push_back({Float(M0, 0, 8, mCoord), Float(B1, 1, 13, mColor)});

    // 12-15. byte/short
    mTestCases.push_back({SByte(M0, 0, 20, mCoord), UByte(M0, 10, 20, mColor)});
    mTestCases.push_back({SShort(M0, 0, 20, mCoord), UShort(M0, 8, 20, mColor)});
    mTestCases.push_back({NormSByte(M0, 0, 8, mCoord), NormUByte(M0, 4, 8, mColor)});
    mTestCases.push_back({NormSShort(M0, 0, 20, mCoord), NormUShort(M0, 8, 20, mColor)});

    // 16. one buffer, sequential
    mTestCases.push_back({Fixed(B0, 0, 8, mCoord), Float(B0, 96, 12, mColor)});

    // 17. one buffer, interleaved
    mTestCases.push_back({Fixed(B0, 0, 20, mCoord), Float(B0, 8, 20, mColor)});

    // 18. memory and buffer, float and integer
    mTestCases.push_back({Float(M0, 0, 8, mCoord), SByte(B0, 0, 12, mColor)});

    // 19. buffer and memory, unusual offset and stride
    mTestCases.push_back({Float(B0, 11, 13, mCoord), Float(M0, 23, 17, mColor)});

    // 20-21. remaining ES3 formats
    if (es3)
    {
        mTestCases.push_back({SInt(M0, 0, 40, mCoord), UInt(M0, 16, 40, mColor)});
        // Fails on Nexus devices (anglebug.com/42261348)
        if (!IsNexus5X())
            mTestCases.push_back({NormSInt(M0, 0, 40, mCoord), NormUInt(M0, 16, 40, mColor)});
    }
}

class AttributeLayoutNonIndexed : public AttributeLayoutTest
{
    void Draw(int firstVertex, unsigned vertexCount, const GLushort *indices) override
    {
        glDrawArrays(GL_TRIANGLES, firstVertex, vertexCount);
    }
};

class AttributeLayoutMemoryIndexed : public AttributeLayoutTest
{
    void Draw(int firstVertex, unsigned vertexCount, const GLushort *indices) override
    {
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glDrawElements(GL_TRIANGLES, vertexCount, GL_UNSIGNED_SHORT, indices);
    }
};

class AttributeLayoutBufferIndexed : public AttributeLayoutTest
{
    void Draw(int firstVertex, unsigned vertexCount, const GLushort *indices) override
    {
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(*mIndices) * vertexCount, indices,
                     GL_STATIC_DRAW);
        glDrawElements(GL_TRIANGLES, vertexCount, GL_UNSIGNED_SHORT, nullptr);
    }
};

TEST_P(AttributeLayoutNonIndexed, Test)
{
    Run(true);
    ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
    Run(false);
}

TEST_P(AttributeLayoutMemoryIndexed, Test)
{
    Run(true);
    ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
    Run(false);
}

TEST_P(AttributeLayoutBufferIndexed, Test)
{
    Run(true);
    ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
    Run(false);
}

ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(AttributeLayoutNonIndexed,
                                       ES3_VULKAN()
                                           .disable(Feature::SupportsExtendedDynamicState)
                                           .disable(Feature::SupportsExtendedDynamicState2));
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(AttributeLayoutMemoryIndexed,
                                       ES3_VULKAN()
                                           .disable(Feature::SupportsExtendedDynamicState)
                                           .disable(Feature::SupportsExtendedDynamicState2));
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(AttributeLayoutBufferIndexed,
                                       ES3_VULKAN()
                                           .disable(Feature::SupportsExtendedDynamicState)
                                           .disable(Feature::SupportsExtendedDynamicState2));

#define STRINGIFY2(X) #X
#define STRINGIFY(X) STRINGIFY2(X)

// clang-format off
#define VS_SHADER(ColorDataType) \
"#version 300 es\n"\
"in highp vec2 coord;\n"\
"in highp " STRINGIFY(ColorDataType) " color;\n"\
"flat out highp " STRINGIFY(ColorDataType) " vcolor;\n"\
"void main(void)\n"\
"{\n"\
"    gl_Position = vec4(coord, 0, 1);\n"\
"    vcolor = color;\n"\
"}\n"

#define PS_SHADER(ColorDataType) \
"#version 300 es\n"\
"flat in highp " STRINGIFY(ColorDataType) " vcolor;\n"\
"out highp " STRINGIFY(ColorDataType) " outColor;\n"\
"void main(void)\n"\
"{\n"\
"    outColor = vcolor;\n"\
"}\n"

// clang-format on

// clang-format off
constexpr double kVertexData[] = {
   //x   y       rgba
    -1, -1,      128, 128, 93, 255,
    +1, -1,      128, 128, 93, 255,
    -1, +1,      128, 128, 93, 255,
    +1, +1,      128, 128, 93, 255,
};
// clang-format on

template <class ResType>
ResType GetRefValue(const void *data, GLenum glType)
{
    switch (glType)
    {
        case GL_BYTE:
        {
            const int8_t *p = reinterpret_cast<const int8_t *>(data);
            return ANGLE_UNSAFE_TODO(ResType(p[0], p[1], p[2], p[3]));
        }
        case GL_SHORT:
        case GL_HALF_FLOAT:
        {
            const int16_t *p = reinterpret_cast<const int16_t *>(data);
            return ANGLE_UNSAFE_TODO(ResType(p[0], p[1], p[2], p[3]));
        }
        case GL_INT:
        case GL_FIXED:
        {
            const int32_t *p = reinterpret_cast<const int32_t *>(data);
            return ANGLE_UNSAFE_TODO(ResType(p[0], p[1], p[2], p[3]));
        }
        case GL_UNSIGNED_BYTE:
        {
            const uint8_t *p = reinterpret_cast<const uint8_t *>(data);
            return ANGLE_UNSAFE_TODO(ResType(p[0], p[1], p[2], p[3]));
        }
        case GL_UNSIGNED_SHORT:
        {
            const uint16_t *p = reinterpret_cast<const uint16_t *>(data);
            return ANGLE_UNSAFE_TODO(ResType(p[0], p[1], p[2], p[3]));
        }
        case GL_FLOAT:
        case GL_UNSIGNED_INT:
        {
            const uint32_t *p = reinterpret_cast<const uint32_t *>(data);
            return ANGLE_UNSAFE_TODO(ResType(p[0], p[1], p[2], p[3]));
        }
        default:
        {
            ASSERT(0);
            const uint32_t *p = reinterpret_cast<const uint32_t *>(data);
            return ANGLE_UNSAFE_TODO(ResType(p[0], p[1], p[2], p[3]));
        }
    }
}

constexpr size_t kIndexCount = 6;
constexpr int kRboSize       = 8;

GLColor ConvertFloatToUnorm8(const GLColor32F &color32f)
{
    float r = std::clamp(color32f.R, 0.0f, 1.0f);
    float g = std::clamp(color32f.G, 0.0f, 1.0f);
    float b = std::clamp(color32f.B, 0.0f, 1.0f);
    float a = std::clamp(color32f.A, 0.0f, 1.0f);
    return GLColor(std::round(r * 255), std::round(g * 255), std::round(b * 255),
                   std::round(a * 255));
}

void BindAttribLocation(GLuint program)
{
    glBindAttribLocation(program, 0, "coord");
    glBindAttribLocation(program, 1, "color");
}

class AttributeDataTypeMismatchTest : public ANGLETest<>
{
  public:
    enum VsInputDataType
    {
        FLOAT    = 0,
        INT      = 1,
        UNSIGNED = 2,
        COUNT    = 3,
    };

  protected:
    AttributeDataTypeMismatchTest()
        : mCoord(2, kVertexData, 0, 6, 4), mColor(4, kVertexData, 2, 6, 4)
    {
        setWindowWidth(128);
        setWindowHeight(128);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }

    GLuint createFbo(GLuint rbo)
    {

        GLuint fbo = 0;
        glGenFramebuffers(1, &fbo);
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        return fbo;
    }

    GLuint createRbo(VsInputDataType inputDataType)
    {
        GLuint rbo = 0;
        glGenRenderbuffers(1, &rbo);
        GLenum format = GL_RGBA8;
        if (inputDataType == VsInputDataType::INT)
        {
            format = GL_RGBA32I;
        }
        else if (inputDataType == VsInputDataType::UNSIGNED)
        {
            format = GL_RGBA32UI;
        }
        glBindRenderbuffer(GL_RENDERBUFFER, rbo);
        glRenderbufferStorage(GL_RENDERBUFFER, format, kRboSize, kRboSize);
        glBindRenderbuffer(GL_RENDERBUFFER, 0);
        return rbo;
    }

    void testSetUp() override
    {
        glClearColor(.2f, .2f, .2f, .0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glDisable(GL_DEPTH_TEST);

        constexpr std::array<const char *, VsInputDataType::COUNT> kVS = {
            VS_SHADER(vec4),
            VS_SHADER(ivec4),
            VS_SHADER(uvec4),
        };

        constexpr std::array<const char *, VsInputDataType::COUNT> kFS = {
            PS_SHADER(vec4),
            PS_SHADER(ivec4),
            PS_SHADER(uvec4),
        };

        for (int i = VsInputDataType::FLOAT; i < VsInputDataType::COUNT; ++i)
        {
            mProgram[i] = CompileProgram(kVS[i], kFS[i], BindAttribLocation);
            ASSERT_NE(0u, mProgram[i]);
            mRbo[i] = createRbo(static_cast<VsInputDataType>(i));
            ASSERT_NE(0u, mRbo[i]);
            mFbo[i] = createFbo(mRbo[i]);
            ASSERT_NE(0u, mFbo[i]);
        }

        glGenBuffers(1, &mIndexBuffer);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(mIndices), mIndices, GL_STATIC_DRAW);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    }

    void GetTestCases(VsInputDataType dataType)
    {
        const bool es3 = getClientMajorVersion() >= 3;

        std::shared_ptr<Container> B0 = std::make_shared<Buffer>();
        if (dataType != VsInputDataType::FLOAT)
        {
            // float and fixed.
            Format<GLfloat, GL_FLOAT, false> Float(es3);
            Format<GLint, GL_FIXED, false> Fixed(es3);
            Format<GLshort, GL_HALF_FLOAT, false> halfFloat(es3);
            // for UScale, SScale.
            Format<GLbyte, GL_BYTE, false> SByte(es3);
            Format<GLubyte, GL_UNSIGNED_BYTE, false> UByte(es3);
            Format<GLshort, GL_SHORT, false> SShort(es3);
            Format<GLushort, GL_UNSIGNED_SHORT, false> UShort(es3);
            // UScale32, Scale32 may emulated. testing unsigned<-->int
            Format<GLint, GL_INT, false, true> SInt(es3);
            Format<GLuint, GL_UNSIGNED_INT, false, true> UInt(es3);
            mTestCases.push_back({Float(B0, 0, 12, mCoord), SByte(B0, 8, 12, mColor)});
            mTestCases.push_back({Float(B0, 0, 12, mCoord), UByte(B0, 8, 12, mColor)});
            mTestCases.push_back({Float(B0, 0, 16, mCoord), SShort(B0, 8, 16, mColor)});
            mTestCases.push_back({Float(B0, 0, 16, mCoord), UShort(B0, 8, 16, mColor)});
            mTestCases.push_back({Float(B0, 0, 16, mCoord), halfFloat(B0, 8, 16, mColor)});
            mTestCases.push_back({Float(B0, 0, 24, mCoord), SInt(B0, 8, 24, mColor)});
            mTestCases.push_back({Float(B0, 0, 24, mCoord), UInt(B0, 8, 24, mColor)});
            mTestCases.push_back({Float(B0, 0, 24, mCoord), Float(B0, 8, 24, mColor)});
            // for GL_FIXED, angle may use GLfloat emulated.
            // mTestCases.push_back({Float(B0, 0, 24, mCoord), Fixed(B0, 8, 24, mColor)});
        }
        else
        {
            Format<GLfloat, GL_FLOAT, false> Float(es3);
            Format<GLbyte, GL_BYTE, false, true> SByte(es3);
            Format<GLubyte, GL_UNSIGNED_BYTE, false, true> UByte(es3);
            Format<GLshort, GL_SHORT, false, true> SShort(es3);
            Format<GLushort, GL_UNSIGNED_SHORT, false, true> UShort(es3);
            Format<GLint, GL_INT, false, true> SInt(es3);
            Format<GLuint, GL_UNSIGNED_INT, false, true> UInt(es3);
            mTestCases.push_back({Float(B0, 0, 12, mCoord), SByte(B0, 8, 12, mColor)});
            mTestCases.push_back({Float(B0, 0, 12, mCoord), UByte(B0, 8, 12, mColor)});
            mTestCases.push_back({Float(B0, 0, 16, mCoord), SShort(B0, 8, 16, mColor)});
            mTestCases.push_back({Float(B0, 0, 16, mCoord), UShort(B0, 8, 16, mColor)});
            // UScale32, Scale32 may emulated.
            // mTestCases.push_back({Float(B0, 0, 24, mCoord), SInt(B0, 8, 24, mColor)});
            // mTestCases.push_back({Float(B0, 0, 24, mCoord), UInt(B0, 8, 24, mColor)});
        }
    }

    void testTearDown() override
    {
        mTestCases.clear();
        for (int i = 0; i < VsInputDataType::COUNT; ++i)
        {
            glDeleteProgram(mProgram[i]);
            glDeleteFramebuffers(1, &mFbo[i]);
            glDeleteRenderbuffers(1, &mRbo[i]);
        }
        glDeleteBuffers(1, &mIndexBuffer);
    }

    GLenum GetMappedGLType(GLenum glType, VsInputDataType vsInputDataType)
    {
        switch (glType)
        {
            case GL_BYTE:
                return vsInputDataType != VsInputDataType::UNSIGNED ? GL_BYTE : GL_UNSIGNED_BYTE;
            case GL_SHORT:
            case GL_HALF_FLOAT:
                return vsInputDataType != VsInputDataType::UNSIGNED ? GL_SHORT : GL_UNSIGNED_SHORT;
            case GL_INT:
            case GL_FIXED:
                return vsInputDataType != VsInputDataType::UNSIGNED ? GL_INT : GL_UNSIGNED_INT;
            case GL_UNSIGNED_BYTE:
                return vsInputDataType != VsInputDataType::INT ? GL_UNSIGNED_BYTE : GL_BYTE;
            case GL_UNSIGNED_SHORT:
                return vsInputDataType != VsInputDataType::INT ? GL_UNSIGNED_SHORT : GL_SHORT;
            case GL_FLOAT:
            case GL_UNSIGNED_INT:
                return vsInputDataType != VsInputDataType::INT ? GL_UNSIGNED_INT : GL_INT;
            default:
                ASSERT(0);
                return vsInputDataType != VsInputDataType::INT ? GL_UNSIGNED_INT : GL_INT;
        }
    }

    void Run(VsInputDataType dataType)
    {
        GetTestCases(dataType);
        ASSERT(dataType < VsInputDataType::COUNT);
        glBindFramebuffer(GL_FRAMEBUFFER, mFbo[dataType]);
        glViewport(0, 0, kRboSize, kRboSize);
        glUseProgram(mProgram[dataType]);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
        for (unsigned i = 0; i < mTestCases.size(); ++i)
        {
            if (mTestCases[i].size() == 0)
                continue;
            ASSERT(mTestCases[i].size() == 2);
            PrepareTestCase(mTestCases[i]);
            EXPECT_GL_NO_ERROR();
            GLint iClearValue[]   = {0, 0, 0, 1};
            GLfloat fClearValue[] = {1.0f, 0.0f, 0.0f, 1.0f};
            switch (dataType)
            {
                case VsInputDataType::FLOAT:
                    glClearBufferfv(GL_COLOR, 0, fClearValue);
                    break;
                case VsInputDataType::INT:
                    glClearBufferiv(GL_COLOR, 0, iClearValue);
                    break;
                case VsInputDataType::UNSIGNED:
                    glClearBufferuiv(GL_COLOR, 0, reinterpret_cast<const GLuint *>(iClearValue));
                    break;
                default:
                    ASSERT(0);
            }
            EXPECT_GL_NO_ERROR();
            glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
            EXPECT_GL_NO_ERROR();

            std::shared_ptr<Container> container = mTestCases[i][1].mContainer;
            size_t offset                        = mTestCases[i][1].mOffset;
            GLenum glType = GetMappedGLType(mTestCases[i][1].mGLType, dataType);
            switch (dataType)
            {
                case VsInputDataType::FLOAT:
                    EXPECT_PIXEL_COLOR_EQ(0, 0,
                                          ConvertFloatToUnorm8(GetRefValue<GLColor32F>(
                                              container->getDestination(offset), glType)));
                    break;
                case VsInputDataType::INT:
                    EXPECT_PIXEL_RECT32I_EQ(
                        0, 0, 1, 1,
                        GetRefValue<GLColor32I>(container->getDestination(offset), glType));
                    break;
                case VsInputDataType::UNSIGNED:
                    EXPECT_PIXEL_RECT32UI_EQ(
                        0, 0, 1, 1,
                        GetRefValue<GLColor32UI>(container->getDestination(offset), glType));
                    break;
                default:
                    ASSERT(0);
            }
        }
        mTestCases.clear();
    }

    static const GLushort mIndices[kIndexCount];

    std::array<GLuint, VsInputDataType::COUNT> mProgram;
    std::array<GLuint, VsInputDataType::COUNT> mFbo;
    std::array<GLuint, VsInputDataType::COUNT> mRbo;
    GLuint mIndexBuffer;

    std::vector<TestCase> mTestCases;

    VertexData mCoord;
    VertexData mColor;
};

const GLushort AttributeDataTypeMismatchTest::mIndices[kIndexCount] = {0, 1, 2, 2, 1, 3};

// Test Attribute input data type mismatch with vertex shader input.
// Change the attribute input data type to vertex shader input data type.
TEST_P(AttributeDataTypeMismatchTest, Test)
{
    // At some device. UScale and Scale are emulated.
    // Restrict tests running at nvidia device only.
    ANGLE_SKIP_TEST_IF(!IsVulkan() || !IsNVIDIA());
    Run(VsInputDataType::FLOAT);
    Run(VsInputDataType::INT);
    Run(VsInputDataType::UNSIGNED);
}

ANGLE_INSTANTIATE_TEST_ES3(AttributeDataTypeMismatchTest);

}  // anonymous namespace
