/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL (ES) Module
 * -----------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Texture buffer test case
 *//*--------------------------------------------------------------------*/

#include "glsTextureBufferCase.hpp"

#include "tcuFormatUtil.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuSurface.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuResultCollector.hpp"

#include "rrRenderer.hpp"
#include "rrShaders.hpp"

#include "gluObjectWrapper.hpp"
#include "gluPixelTransfer.hpp"
#include "gluShaderProgram.hpp"
#include "gluShaderUtil.hpp"
#include "gluStrUtil.hpp"
#include "gluTexture.hpp"
#include "gluTextureUtil.hpp"

#include "glwEnums.hpp"
#include "glwFunctions.hpp"

#include "deRandom.hpp"
#include "deStringUtil.hpp"
#include "deUniquePtr.hpp"

#include "deMemory.h"
#include "deString.h"
#include "deMath.h"

#include <sstream>
#include <string>
#include <vector>

using tcu::TestLog;

using std::map;
using std::string;
using std::vector;

using namespace deqp::gls::TextureBufferCaseUtil;

namespace deqp
{
namespace gls
{
namespace
{

enum
{
    MAX_VIEWPORT_WIDTH  = 256,
    MAX_VIEWPORT_HEIGHT = 256,
    MIN_VIEWPORT_WIDTH  = 64,
    MIN_VIEWPORT_HEIGHT = 64,
};

uint8_t extend2BitsToByte(uint8_t bits)
{
    DE_ASSERT((bits & (~0x03u)) == 0);

    return (uint8_t)(bits | (bits << 2) | (bits << 4) | (bits << 6));
}

void genRandomCoords(de::Random rng, vector<uint8_t> &coords, size_t offset, size_t size)
{
    const uint8_t bits    = 2;
    const uint8_t bitMask = uint8_t((0x1u << bits) - 1);

    coords.resize(size);

    for (int i = 0; i < (int)size; i++)
    {
        const uint8_t xBits = uint8_t(rng.getUint32() & bitMask);
        coords[i]           = extend2BitsToByte(xBits);
    }

    // Fill indices with nice quad
    {
        const uint8_t indices[] = {extend2BitsToByte(0x0u), extend2BitsToByte(0x1u), extend2BitsToByte(0x2u),
                                   extend2BitsToByte(0x3u)};

        for (int i = 0; i < DE_LENGTH_OF_ARRAY(indices); i++)
        {
            const uint8_t index = indices[i];
            const size_t posX   = (size_t(index) * 2) + 0;
            const size_t posY   = (size_t(index) * 2) + 1;

            if (posX >= offset && posX < offset + size)
                coords[posX - offset] = ((i % 2) == 0 ? extend2BitsToByte(0x0u) : extend2BitsToByte(0x3u));

            if (posY >= offset && posY < offset + size)
                coords[posY - offset] = ((i / 2) == 1 ? extend2BitsToByte(0x3u) : extend2BitsToByte(0x0u));
        }
    }

    // Fill beginning of buffer
    {
        const uint8_t indices[] = {extend2BitsToByte(0x0u), extend2BitsToByte(0x3u), extend2BitsToByte(0x1u),

                                   extend2BitsToByte(0x1u), extend2BitsToByte(0x2u), extend2BitsToByte(0x0u),

                                   extend2BitsToByte(0x0u), extend2BitsToByte(0x2u), extend2BitsToByte(0x1u),

                                   extend2BitsToByte(0x1u), extend2BitsToByte(0x3u), extend2BitsToByte(0x0u)};

        for (int i = (int)offset; i < DE_LENGTH_OF_ARRAY(indices) && i < (int)(offset + size); i++)
            coords[i - offset] = indices[i];
    }
}

class CoordVertexShader : public rr::VertexShader
{
public:
    CoordVertexShader(void) : rr::VertexShader(1, 1)
    {
        m_inputs[0].type  = rr::GENERICVECTYPE_FLOAT;
        m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
    }

    void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const
    {
        for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
        {
            rr::VertexPacket *const packet = packets[packetNdx];
            tcu::Vec4 position;

            readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx);

            packet->outputs[0] = tcu::Vec4(1.0f);
            packet->position   = tcu::Vec4(2.0f * (position.x() - 0.5f), 2.0f * (position.y() - 0.5f), 0.0f, 1.0f);
        }
    }
};

class TextureVertexShader : public rr::VertexShader
{
public:
    TextureVertexShader(const tcu::ConstPixelBufferAccess &texture) : rr::VertexShader(1, 1), m_texture(texture)
    {
        m_inputs[0].type  = rr::GENERICVECTYPE_FLOAT;
        m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
    }

    void shadeVertices(const rr::VertexAttrib *inputs, rr::VertexPacket *const *packets, const int numPackets) const
    {
        for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
        {
            rr::VertexPacket *const packet = packets[packetNdx];
            tcu::Vec4 position;
            tcu::Vec4 texelValue;

            readVertexAttrib(position, inputs[0], packet->instanceNdx, packet->vertexNdx);

            texelValue = tcu::Vec4(m_texture.getPixel(de::clamp<int>((deRoundFloatToInt32(position.x() * 4) + 4) *
                                                                         (deRoundFloatToInt32(position.y() * 4) + 4),
                                                                     0, m_texture.getWidth() - 1),
                                                      0));

            packet->outputs[0] = texelValue;
            packet->position   = tcu::Vec4(2.0f * (position.x() - 0.5f), 2.0f * (position.y() - 0.5f), 0.0f, 1.0f);
        }
    }

private:
    const tcu::ConstPixelBufferAccess m_texture;
};

class CoordFragmentShader : public rr::FragmentShader
{
public:
    CoordFragmentShader(void) : rr::FragmentShader(1, 1)
    {
        m_inputs[0].type  = rr::GENERICVECTYPE_FLOAT;
        m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
    }

    void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
                        const rr::FragmentShadingContext &context) const
    {
        for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
        {
            rr::FragmentPacket &packet = packets[packetNdx];

            const tcu::Vec4 vtxColor0 = rr::readVarying<float>(packet, context, 0, 0);
            const tcu::Vec4 vtxColor1 = rr::readVarying<float>(packet, context, 0, 1);
            const tcu::Vec4 vtxColor2 = rr::readVarying<float>(packet, context, 0, 2);
            const tcu::Vec4 vtxColor3 = rr::readVarying<float>(packet, context, 0, 3);

            const tcu::Vec4 color0 = vtxColor0;
            const tcu::Vec4 color1 = vtxColor1;
            const tcu::Vec4 color2 = vtxColor2;
            const tcu::Vec4 color3 = vtxColor3;

            rr::writeFragmentOutput(
                context, packetNdx, 0, 0,
                tcu::Vec4(color0.x() * color0.w(), color0.y() * color0.w(), color0.z() * color0.w(), 1.0f));
            rr::writeFragmentOutput(
                context, packetNdx, 1, 0,
                tcu::Vec4(color1.x() * color1.w(), color1.y() * color1.w(), color1.z() * color1.w(), 1.0f));
            rr::writeFragmentOutput(
                context, packetNdx, 2, 0,
                tcu::Vec4(color2.x() * color2.w(), color2.y() * color2.w(), color2.z() * color2.w(), 1.0f));
            rr::writeFragmentOutput(
                context, packetNdx, 3, 0,
                tcu::Vec4(color3.x() * color3.w(), color3.y() * color3.w(), color3.z() * color3.w(), 1.0f));
        }
    }
};

class TextureFragmentShader : public rr::FragmentShader
{
public:
    TextureFragmentShader(const tcu::ConstPixelBufferAccess &texture) : rr::FragmentShader(1, 1), m_texture(texture)
    {
        m_inputs[0].type  = rr::GENERICVECTYPE_FLOAT;
        m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
    }

    void shadeFragments(rr::FragmentPacket *packets, const int numPackets,
                        const rr::FragmentShadingContext &context) const
    {
        for (int packetNdx = 0; packetNdx < numPackets; packetNdx++)
        {
            rr::FragmentPacket &packet = packets[packetNdx];

            const tcu::IVec2 position0 = packet.position + tcu::IVec2(0, 0);
            const tcu::IVec2 position1 = packet.position + tcu::IVec2(1, 0);
            const tcu::IVec2 position2 = packet.position + tcu::IVec2(0, 1);
            const tcu::IVec2 position3 = packet.position + tcu::IVec2(1, 1);

            const tcu::Vec4 texColor0 =
                m_texture.getPixel(de::clamp((position0.x() * position0.y()), 0, m_texture.getWidth() - 1), 0);
            const tcu::Vec4 texColor1 =
                m_texture.getPixel(de::clamp((position1.x() * position1.y()), 0, m_texture.getWidth() - 1), 0);
            const tcu::Vec4 texColor2 =
                m_texture.getPixel(de::clamp((position2.x() * position2.y()), 0, m_texture.getWidth() - 1), 0);
            const tcu::Vec4 texColor3 =
                m_texture.getPixel(de::clamp((position3.x() * position3.y()), 0, m_texture.getWidth() - 1), 0);

            const tcu::Vec4 vtxColor0 = rr::readVarying<float>(packet, context, 0, 0);
            const tcu::Vec4 vtxColor1 = rr::readVarying<float>(packet, context, 0, 1);
            const tcu::Vec4 vtxColor2 = rr::readVarying<float>(packet, context, 0, 2);
            const tcu::Vec4 vtxColor3 = rr::readVarying<float>(packet, context, 0, 3);

            const tcu::Vec4 color0 = 0.5f * (vtxColor0 + texColor0);
            const tcu::Vec4 color1 = 0.5f * (vtxColor1 + texColor1);
            const tcu::Vec4 color2 = 0.5f * (vtxColor2 + texColor2);
            const tcu::Vec4 color3 = 0.5f * (vtxColor3 + texColor3);

            rr::writeFragmentOutput(
                context, packetNdx, 0, 0,
                tcu::Vec4(color0.x() * color0.w(), color0.y() * color0.w(), color0.z() * color0.w(), 1.0f));
            rr::writeFragmentOutput(
                context, packetNdx, 1, 0,
                tcu::Vec4(color1.x() * color1.w(), color1.y() * color1.w(), color1.z() * color1.w(), 1.0f));
            rr::writeFragmentOutput(
                context, packetNdx, 2, 0,
                tcu::Vec4(color2.x() * color2.w(), color2.y() * color2.w(), color2.z() * color2.w(), 1.0f));
            rr::writeFragmentOutput(
                context, packetNdx, 3, 0,
                tcu::Vec4(color3.x() * color3.w(), color3.y() * color3.w(), color3.z() * color3.w(), 1.0f));
        }
    }

private:
    const tcu::ConstPixelBufferAccess m_texture;
};

string generateVertexShaderTemplate(RenderBits renderBits)
{
    std::ostringstream stream;

    stream << "${VERSION_HEADER}\n";

    if (renderBits & RENDERBITS_AS_VERTEX_TEXTURE)
        stream << "${TEXTURE_BUFFER_EXT}";

    stream << "${VTX_INPUT} layout(location = 0) ${HIGHP} vec2 i_coord;\n"
              "${VTX_OUTPUT} ${HIGHP} vec4 v_color;\n";

    if (renderBits & RENDERBITS_AS_VERTEX_TEXTURE)
    {
        stream << "uniform ${HIGHP} samplerBuffer u_vtxSampler;\n";
    }

    stream << "\n"
              "void main (void)\n"
              "{\n";

    if (renderBits & RENDERBITS_AS_VERTEX_TEXTURE)
        stream << "\tv_color = texelFetch(u_vtxSampler, clamp((int(round(i_coord.x * 4.0)) + 4) * (int(round(i_coord.y "
                  "* 4.0)) + 4), 0, textureSize(u_vtxSampler)-1));\n";
    else
        stream << "\tv_color = vec4(1.0);\n";

    stream << "\tgl_Position = vec4(2.0 * (i_coord - vec2(0.5)), 0.0, 1.0);\n"
              "}\n";

    return stream.str();
}

string generateFragmentShaderTemplate(RenderBits renderBits)
{
    std::ostringstream stream;

    stream << "${VERSION_HEADER}\n";

    if (renderBits & RENDERBITS_AS_FRAGMENT_TEXTURE)
        stream << "${TEXTURE_BUFFER_EXT}";

    stream << "${FRAG_OUTPUT} layout(location = 0) ${HIGHP} vec4 dEQP_FragColor;\n"
              "${FRAG_INPUT} ${HIGHP} vec4 v_color;\n";

    if (renderBits & RENDERBITS_AS_FRAGMENT_TEXTURE)
        stream << "uniform ${HIGHP} samplerBuffer u_fragSampler;\n";

    stream << "\n"
              "void main (void)\n"
              "{\n";

    if (renderBits & RENDERBITS_AS_FRAGMENT_TEXTURE)
        stream << "\t${HIGHP} vec4 color = 0.5 * (v_color + texelFetch(u_fragSampler, clamp(int(gl_FragCoord.x) * "
                  "int(gl_FragCoord.y), 0, textureSize(u_fragSampler)-1)));\n";
    else
        stream << "\t${HIGHP} vec4 color = v_color;\n";

    stream << "\tdEQP_FragColor = vec4(color.xyz * color.w, 1.0);\n"
              "}\n";

    return stream.str();
}

string specializeShader(const string &shaderTemplateString, glu::GLSLVersion glslVersion)
{
    const tcu::StringTemplate shaderTemplate(shaderTemplateString);
    map<string, string> parameters;

    parameters["VERSION_HEADER"] = glu::getGLSLVersionDeclaration(glslVersion);
    parameters["VTX_OUTPUT"]     = "out";
    parameters["VTX_INPUT"]      = "in";
    parameters["FRAG_INPUT"]     = "in";
    parameters["FRAG_OUTPUT"]    = "out";
    parameters["HIGHP"]          = (glslVersion == glu::GLSL_VERSION_330 ? "" : "highp");
    parameters["TEXTURE_BUFFER_EXT"] =
        (glslVersion == glu::GLSL_VERSION_330 ? "" : "#extension GL_EXT_texture_buffer : enable\n");

    return shaderTemplate.specialize(parameters);
}

glu::ShaderProgram *createRenderProgram(glu::RenderContext &renderContext, RenderBits renderBits)
{
    const string vertexShaderTemplate   = generateVertexShaderTemplate(renderBits);
    const string fragmentShaderTemplate = generateFragmentShaderTemplate(renderBits);

    const glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(renderContext.getType());

    const string vertexShaderSource   = specializeShader(vertexShaderTemplate, glslVersion);
    const string fragmentShaderSource = specializeShader(fragmentShaderTemplate, glslVersion);

    glu::ShaderProgram *const program =
        new glu::ShaderProgram(renderContext, glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));

    return program;
}

void logModifications(TestLog &log, ModifyBits modifyBits)
{
    tcu::ScopedLogSection section(log, "Modify Operations", "Modify Operations");

    const struct
    {
        ModifyBits bit;
        const char *str;
    } bitInfos[] = {{MODIFYBITS_BUFFERDATA, "Recreate buffer data with glBufferData()."},
                    {MODIFYBITS_BUFFERSUBDATA, "Modify texture buffer with glBufferSubData()."},
                    {MODIFYBITS_MAPBUFFER_WRITE, "Map buffer write-only and rewrite data."},
                    {MODIFYBITS_MAPBUFFER_READWRITE, "Map buffer readw-write check and rewrite data."}};

    DE_ASSERT(modifyBits != 0);

    for (int infoNdx = 0; infoNdx < DE_LENGTH_OF_ARRAY(bitInfos); infoNdx++)
    {
        if (modifyBits & bitInfos[infoNdx].bit)
            log << TestLog::Message << bitInfos[infoNdx].str << TestLog::EndMessage;
    }
}

void modifyBufferData(TestLog &log, de::Random &rng, glu::TextureBuffer &texture)
{
    vector<uint8_t> data;

    genRandomCoords(rng, data, 0, texture.getBufferSize());

    log << TestLog::Message << "BufferData, Size: " << data.size() << TestLog::EndMessage;

    {
        // replace getRefBuffer with a new buffer
        de::ArrayBuffer<uint8_t> buffer(&(data[0]), data.size());
        texture.getRefBuffer().swap(buffer);
    }

    texture.upload();
}

void modifyBufferSubData(TestLog &log, de::Random &rng, const glw::Functions &gl, glu::TextureBuffer &texture)
{
    const size_t minSize = 4 * 16;
    const size_t size =
        de::max<size_t>(minSize, size_t((float)(texture.getSize() != 0 ? texture.getSize() : texture.getBufferSize()) *
                                        (0.7f + 0.3f * rng.getFloat())));
    const size_t minOffset = texture.getOffset();
    const size_t offset    = minOffset + (rng.getUint32() % (texture.getBufferSize() - (size + minOffset)));
    vector<uint8_t> data;

    genRandomCoords(rng, data, offset, size);

    log << TestLog::Message << "BufferSubData, Offset: " << offset << ", Size: " << size << TestLog::EndMessage;

    gl.bindBuffer(GL_TEXTURE_BUFFER, texture.getGLBuffer());
    gl.bufferSubData(GL_TEXTURE_BUFFER, (glw::GLsizei)offset, (glw::GLsizei)data.size(), &(data[0]));
    gl.bindBuffer(GL_TEXTURE_BUFFER, 0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to update data with glBufferSubData()");

    deMemcpy((uint8_t *)texture.getRefBuffer().getPtr() + offset, &(data[0]), int(data.size()));
}

void modifyMapWrite(TestLog &log, de::Random &rng, const glw::Functions &gl, glu::TextureBuffer &texture)
{
    const size_t minSize = 4 * 16;
    const size_t size =
        de::max<size_t>(minSize, size_t((float)(texture.getSize() != 0 ? texture.getSize() : texture.getBufferSize()) *
                                        (0.7f + 0.3f * rng.getFloat())));
    const size_t minOffset = texture.getOffset();
    const size_t offset    = minOffset + (rng.getUint32() % (texture.getBufferSize() - (size + minOffset)));
    vector<uint8_t> data;

    genRandomCoords(rng, data, offset, size);

    log << TestLog::Message << "glMapBufferRange, Write Only, Offset: " << offset << ", Size: " << size
        << TestLog::EndMessage;

    gl.bindBuffer(GL_TEXTURE_BUFFER, texture.getGLBuffer());
    {
        uint8_t *ptr =
            (uint8_t *)gl.mapBufferRange(GL_TEXTURE_BUFFER, (glw::GLsizei)offset, (glw::GLsizei)size, GL_MAP_WRITE_BIT);

        GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange()");
        TCU_CHECK(ptr);

        for (int i = 0; i < (int)data.size(); i++)
            ptr[i] = data[i];

        TCU_CHECK(gl.unmapBuffer(GL_TEXTURE_BUFFER));
    }
    gl.bindBuffer(GL_TEXTURE_BUFFER, 0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to update data with glMapBufferRange()");

    deMemcpy((uint8_t *)texture.getRefBuffer().getPtr() + offset, &(data[0]), int(data.size()));
}

void modifyMapReadWrite(TestLog &log, tcu::ResultCollector &resultCollector, de::Random &rng, const glw::Functions &gl,
                        glu::TextureBuffer &texture)
{
    const size_t minSize = 4 * 16;
    const size_t size =
        de::max<size_t>(minSize, size_t((float)(texture.getSize() != 0 ? texture.getSize() : texture.getBufferSize()) *
                                        (0.7f + 0.3f * rng.getFloat())));
    const size_t minOffset = texture.getOffset();
    const size_t offset    = minOffset + (rng.getUint32() % (texture.getBufferSize() - (size + minOffset)));
    uint8_t *const refPtr  = (uint8_t *)texture.getRefBuffer().getPtr() + offset;
    vector<uint8_t> data;

    genRandomCoords(rng, data, offset, size);

    log << TestLog::Message << "glMapBufferRange, Read Write, Offset: " << offset << ", Size: " << size
        << TestLog::EndMessage;

    gl.bindBuffer(GL_TEXTURE_BUFFER, texture.getGLBuffer());
    {
        size_t invalidBytes = 0;
        uint8_t *const ptr  = (uint8_t *)gl.mapBufferRange(GL_TEXTURE_BUFFER, (glw::GLsizei)offset, (glw::GLsizei)size,
                                                           GL_MAP_WRITE_BIT | GL_MAP_READ_BIT);

        GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBufferRange()");
        TCU_CHECK(ptr);

        for (int i = 0; i < (int)data.size(); i++)
        {
            if (ptr[i] != refPtr[i])
            {
                if (invalidBytes < 24)
                    log << TestLog::Message << "Invalid byte in mapped buffer. "
                        << tcu::Format::Hex<2>(data[i]).toString() << " at " << i << ", expected "
                        << tcu::Format::Hex<2>(refPtr[i]).toString() << TestLog::EndMessage;

                invalidBytes++;
            }

            ptr[i] = data[i];
        }

        TCU_CHECK(gl.unmapBuffer(GL_TEXTURE_BUFFER));

        if (invalidBytes > 0)
        {
            log << TestLog::Message << "Total of " << invalidBytes << " invalid bytes." << TestLog::EndMessage;
            resultCollector.fail("Invalid data in mapped buffer");
        }
    }

    gl.bindBuffer(GL_TEXTURE_BUFFER, 0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to update data with glMapBufferRange()");

    for (int i = 0; i < (int)data.size(); i++)
        refPtr[i] = data[i];
}

void modify(TestLog &log, tcu::ResultCollector &resultCollector, glu::RenderContext &renderContext,
            ModifyBits modifyBits, de::Random &rng, glu::TextureBuffer &texture)
{
    const tcu::ScopedLogSection modifySection(log, "Modifying Texture buffer", "Modifying Texture Buffer");

    logModifications(log, modifyBits);

    if (modifyBits & MODIFYBITS_BUFFERDATA)
        modifyBufferData(log, rng, texture);

    if (modifyBits & MODIFYBITS_BUFFERSUBDATA)
        modifyBufferSubData(log, rng, renderContext.getFunctions(), texture);

    if (modifyBits & MODIFYBITS_MAPBUFFER_WRITE)
        modifyMapWrite(log, rng, renderContext.getFunctions(), texture);

    if (modifyBits & MODIFYBITS_MAPBUFFER_READWRITE)
        modifyMapReadWrite(log, resultCollector, rng, renderContext.getFunctions(), texture);
}

void renderGL(glu::RenderContext &renderContext, RenderBits renderBits, uint32_t coordSeed, int triangleCount,
              glu::ShaderProgram &program, glu::TextureBuffer &texture)
{
    const glw::Functions &gl = renderContext.getFunctions();
    const glu::VertexArray vao(renderContext);
    const glu::Buffer coordBuffer(renderContext);

    gl.useProgram(program.getProgram());
    gl.bindVertexArray(*vao);

    gl.enableVertexAttribArray(0);

    if (renderBits & RENDERBITS_AS_VERTEX_ARRAY)
    {
        gl.bindBuffer(GL_ARRAY_BUFFER, texture.getGLBuffer());
        gl.vertexAttribPointer(0, 2, GL_UNSIGNED_BYTE, true, 0, DE_NULL);
    }
    else
    {
        de::Random rng(coordSeed);
        vector<uint8_t> coords;

        genRandomCoords(rng, coords, 0, 256 * 2);

        gl.bindBuffer(GL_ARRAY_BUFFER, *coordBuffer);
        gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizei)coords.size(), &(coords[0]), GL_STREAM_DRAW);
        gl.vertexAttribPointer(0, 2, GL_UNSIGNED_BYTE, true, 0, DE_NULL);
    }

    if (renderBits & RENDERBITS_AS_VERTEX_TEXTURE)
    {
        const int32_t location = gl.getUniformLocation(program.getProgram(), "u_vtxSampler");

        gl.activeTexture(GL_TEXTURE0);
        gl.bindTexture(GL_TEXTURE_BUFFER, texture.getGLTexture());
        gl.uniform1i(location, 0);
    }

    if (renderBits & RENDERBITS_AS_FRAGMENT_TEXTURE)
    {
        const int32_t location = gl.getUniformLocation(program.getProgram(), "u_fragSampler");

        gl.activeTexture(GL_TEXTURE1);
        gl.bindTexture(GL_TEXTURE_BUFFER, texture.getGLTexture());
        gl.uniform1i(location, 1);
        gl.activeTexture(GL_TEXTURE0);
    }

    if (renderBits & RENDERBITS_AS_INDEX_ARRAY)
    {
        gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, texture.getGLBuffer());
        gl.drawElements(GL_TRIANGLES, triangleCount * 3, GL_UNSIGNED_BYTE, DE_NULL);
        gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    }
    else
        gl.drawArrays(GL_TRIANGLES, 0, triangleCount * 3);

    if (renderBits & RENDERBITS_AS_FRAGMENT_TEXTURE)
    {
        gl.activeTexture(GL_TEXTURE1);
        gl.bindTexture(GL_TEXTURE_BUFFER, 0);
    }

    if (renderBits & RENDERBITS_AS_VERTEX_TEXTURE)
    {
        gl.activeTexture(GL_TEXTURE0);
        gl.bindTexture(GL_TEXTURE_BUFFER, 0);
    }

    gl.bindBuffer(GL_ARRAY_BUFFER, 0);
    gl.disableVertexAttribArray(0);

    gl.bindVertexArray(0);
    gl.useProgram(0);
    GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed");
}

void renderReference(RenderBits renderBits, uint32_t coordSeed, int triangleCount, const glu::TextureBuffer &texture,
                     int maxTextureBufferSize, const tcu::PixelBufferAccess &target, int subpixelBits)
{
    const tcu::ConstPixelBufferAccess effectiveAccess =
        glu::getTextureBufferEffectiveRefTexture(texture, maxTextureBufferSize);

    const CoordVertexShader coordVertexShader;
    const TextureVertexShader textureVertexShader(effectiveAccess);
    const rr::VertexShader *const vertexShader =
        (renderBits & RENDERBITS_AS_VERTEX_TEXTURE ? static_cast<const rr::VertexShader *>(&textureVertexShader) :
                                                     &coordVertexShader);

    const CoordFragmentShader coordFragmmentShader;
    const TextureFragmentShader textureFragmentShader(effectiveAccess);
    const rr::FragmentShader *const fragmentShader =
        (renderBits & RENDERBITS_AS_FRAGMENT_TEXTURE ? static_cast<const rr::FragmentShader *>(&textureFragmentShader) :
                                                       &coordFragmmentShader);

    const rr::Renderer renderer;
    const rr::RenderState renderState(
        rr::ViewportState(rr::WindowRectangle(0, 0, target.getWidth(), target.getHeight())), subpixelBits);
    const rr::RenderTarget renderTarget(rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(target));

    const rr::Program program(vertexShader, fragmentShader);

    rr::VertexAttrib vertexAttribs[1];
    vector<uint8_t> coords;

    if (renderBits & RENDERBITS_AS_VERTEX_ARRAY)
    {
        vertexAttribs[0].type    = rr::VERTEXATTRIBTYPE_NONPURE_UNORM8;
        vertexAttribs[0].size    = 2;
        vertexAttribs[0].pointer = texture.getRefBuffer().getPtr();
    }
    else
    {
        de::Random rng(coordSeed);

        genRandomCoords(rng, coords, 0, 256 * 2);

        vertexAttribs[0].type    = rr::VERTEXATTRIBTYPE_NONPURE_UNORM8;
        vertexAttribs[0].size    = 2;
        vertexAttribs[0].pointer = &(coords[0]);
    }

    if (renderBits & RENDERBITS_AS_INDEX_ARRAY)
    {
        const rr::PrimitiveList primitives(rr::PRIMITIVETYPE_TRIANGLES, triangleCount * 3,
                                           rr::DrawIndices(texture.getRefBuffer().getPtr(), rr::INDEXTYPE_UINT8));
        const rr::DrawCommand cmd(renderState, renderTarget, program, 1, vertexAttribs, primitives);

        renderer.draw(cmd);
    }
    else
    {
        const rr::PrimitiveList primitives(rr::PRIMITIVETYPE_TRIANGLES, triangleCount * 3, 0);
        const rr::DrawCommand cmd(renderState, renderTarget, program, 1, vertexAttribs, primitives);

        renderer.draw(cmd);
    }
}

void logRendering(TestLog &log, RenderBits renderBits)
{
    const struct
    {
        RenderBits bit;
        const char *str;
    } bitInfos[] = {{RENDERBITS_AS_VERTEX_ARRAY, "vertex array"},
                    {RENDERBITS_AS_INDEX_ARRAY, "index array"},
                    {RENDERBITS_AS_VERTEX_TEXTURE, "vertex texture"},
                    {RENDERBITS_AS_FRAGMENT_TEXTURE, "fragment texture"}};

    std::ostringstream stream;
    vector<const char *> usedAs;

    DE_ASSERT(renderBits != 0);

    for (int infoNdx = 0; infoNdx < DE_LENGTH_OF_ARRAY(bitInfos); infoNdx++)
    {
        if (renderBits & bitInfos[infoNdx].bit)
            usedAs.push_back(bitInfos[infoNdx].str);
    }

    stream << "Render using texture buffer as ";

    for (int asNdx = 0; asNdx < (int)usedAs.size(); asNdx++)
    {
        if (asNdx + 1 == (int)usedAs.size() && (int)usedAs.size() > 1)
            stream << " and ";
        else if (asNdx > 0)
            stream << ", ";

        stream << usedAs[asNdx];
    }

    stream << ".";

    log << TestLog::Message << stream.str() << TestLog::EndMessage;
}

void render(TestLog &log, glu::RenderContext &renderContext, RenderBits renderBits, de::Random &rng,
            glu::ShaderProgram &program, glu::TextureBuffer &texture, const tcu::PixelBufferAccess &target)
{
    const tcu::ScopedLogSection renderSection(log, "Render Texture buffer", "Render Texture Buffer");
    const int triangleCount  = 8;
    const uint32_t coordSeed = rng.getUint32();
    int maxTextureBufferSize = 0;

    renderContext.getFunctions().getIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &maxTextureBufferSize);
    GLU_EXPECT_NO_ERROR(renderContext.getFunctions().getError(), "query GL_MAX_TEXTURE_BUFFER_SIZE");
    DE_ASSERT(maxTextureBufferSize > 0); // checked in init()

    logRendering(log, renderBits);

    renderGL(renderContext, renderBits, coordSeed, triangleCount, program, texture);

    int subpixelBits = 0;
    renderContext.getFunctions().getIntegerv(GL_SUBPIXEL_BITS, &subpixelBits);
    renderReference(renderBits, coordSeed, triangleCount, texture, maxTextureBufferSize, target, subpixelBits);
}

void verifyScreen(TestLog &log, tcu::ResultCollector &resultCollector, glu::RenderContext &renderContext,
                  const tcu::ConstPixelBufferAccess &referenceTarget)
{
    const tcu::ScopedLogSection verifySection(log, "Verify screen contents", "Verify screen contents");
    tcu::Surface screen(referenceTarget.getWidth(), referenceTarget.getHeight());

    glu::readPixels(renderContext, 0, 0, screen.getAccess());

    if (!tcu::fuzzyCompare(log, "Result of rendering", "Result of rendering", referenceTarget, screen.getAccess(),
                           0.05f, tcu::COMPARE_LOG_RESULT))
        resultCollector.fail("Rendering failed");
}

void logImplementationInfo(TestLog &log, glu::RenderContext &renderContext)
{
    const tcu::ScopedLogSection section(log, "Implementation Values", "Implementation Values");
    de::UniquePtr<glu::ContextInfo> info(glu::ContextInfo::create(renderContext));
    const glw::Functions &gl = renderContext.getFunctions();

    if (glu::contextSupports(renderContext.getType(), glu::ApiType(3, 3, glu::PROFILE_CORE)))
    {
        int32_t maxTextureSize = 0;

        gl.getIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &maxTextureSize);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE)");

        log << TestLog::Message << "GL_MAX_TEXTURE_BUFFER_SIZE : " << maxTextureSize << TestLog::EndMessage;
    }
    else if (glu::contextSupports(renderContext.getType(), glu::ApiType(3, 1, glu::PROFILE_ES)) &&
             info->isExtensionSupported("GL_EXT_texture_buffer"))
    {
        {
            int32_t maxTextureSize = 0;

            gl.getIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &maxTextureSize);
            GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE_EXT)");

            log << TestLog::Message << "GL_MAX_TEXTURE_BUFFER_SIZE_EXT : " << maxTextureSize << TestLog::EndMessage;
        }

        {
            int32_t textureBufferAlignment = 0;

            gl.getIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &textureBufferAlignment);
            GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT)");

            log << TestLog::Message << "GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_EXT : " << textureBufferAlignment
                << TestLog::EndMessage;
        }
    }
    else
        DE_ASSERT(false);
}

void logTextureInfo(TestLog &log, uint32_t format, size_t bufferSize, size_t offset, size_t size)
{
    const tcu::ScopedLogSection section(log, "Texture Info", "Texture Info");

    log << TestLog::Message << "Texture format : " << glu::getTextureFormatStr(format) << TestLog::EndMessage;
    log << TestLog::Message << "Buffer size : " << bufferSize << TestLog::EndMessage;

    if (offset != 0 || size != 0)
    {
        log << TestLog::Message << "Buffer range offset: " << offset << TestLog::EndMessage;
        log << TestLog::Message << "Buffer range size: " << size << TestLog::EndMessage;
    }
}

void runTests(tcu::TestContext &testCtx, glu::RenderContext &renderContext, de::Random &rng, uint32_t format,
              size_t bufferSize, size_t offset, size_t size, RenderBits preRender, glu::ShaderProgram *preRenderProgram,
              ModifyBits modifyType, RenderBits postRender, glu::ShaderProgram *postRenderProgram)
{
    const tcu::RenderTarget renderTarget(renderContext.getRenderTarget());
    const glw::Functions &gl = renderContext.getFunctions();

    const int width  = de::min<int>(renderTarget.getWidth(), MAX_VIEWPORT_WIDTH);
    const int height = de::min<int>(renderTarget.getHeight(), MAX_VIEWPORT_HEIGHT);
    const tcu::Vec4 clearColor(0.25f, 0.5f, 0.75f, 1.0f);

    TestLog &log = testCtx.getLog();
    tcu::ResultCollector resultCollector(log);

    logImplementationInfo(log, renderContext);
    logTextureInfo(log, format, bufferSize, offset, size);

    {
        tcu::Surface referenceTarget(width, height);
        vector<uint8_t> bufferData;

        genRandomCoords(rng, bufferData, 0, bufferSize);

        for (uint8_t i = 0; i < 4; i++)
        {
            const uint8_t val = extend2BitsToByte(i);

            if (val >= offset && val < offset + size)
            {
                bufferData[val * 2 + 0] = (i / 2 == 0 ? extend2BitsToByte(0x2u) : extend2BitsToByte(0x01u));
                bufferData[val * 2 + 1] = (i % 2 == 0 ? extend2BitsToByte(0x2u) : extend2BitsToByte(0x01u));
            }
        }

        {
            glu::TextureBuffer texture(renderContext, format, bufferSize, offset, size, &(bufferData[0]));

            TCU_CHECK_MSG(width >= MIN_VIEWPORT_WIDTH || height >= MIN_VIEWPORT_HEIGHT, "Too small viewport");

            DE_ASSERT(preRender == 0 || preRenderProgram);
            DE_ASSERT(postRender == 0 || postRenderProgram);

            gl.viewport(0, 0, width, height);
            gl.clearColor(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w());
            gl.clear(GL_COLOR_BUFFER_BIT);
            GLU_EXPECT_NO_ERROR(gl.getError(), "Screen setup failed");

            tcu::clear(referenceTarget.getAccess(), clearColor);

            texture.upload();

            if (preRender != 0)
                render(log, renderContext, preRender, rng, *preRenderProgram, texture, referenceTarget.getAccess());

            if (modifyType != 0)
                modify(log, resultCollector, renderContext, modifyType, rng, texture);

            if (postRender != 0)
                render(log, renderContext, postRender, rng, *postRenderProgram, texture, referenceTarget.getAccess());
        }

        verifyScreen(log, resultCollector, renderContext, referenceTarget.getAccess());

        resultCollector.setTestContextResult(testCtx);
    }
}

} // namespace

TextureBufferCase::TextureBufferCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, uint32_t format,
                                     size_t bufferSize, size_t offset, size_t size, RenderBits preRender,
                                     ModifyBits modify, RenderBits postRender, const char *name,
                                     const char *description)
    : tcu::TestCase(testCtx, name, description)
    , m_renderCtx(renderCtx)
    , m_format(format)
    , m_bufferSize(bufferSize)
    , m_offset(offset)
    , m_size(size)

    , m_preRender(preRender)
    , m_modify(modify)
    , m_postRender(postRender)

    , m_preRenderProgram(DE_NULL)
    , m_postRenderProgram(DE_NULL)
{
}

TextureBufferCase::~TextureBufferCase(void)
{
    TextureBufferCase::deinit();
}

void TextureBufferCase::init(void)
{
    de::UniquePtr<glu::ContextInfo> info(glu::ContextInfo::create(m_renderCtx));

    if (!glu::contextSupports(m_renderCtx.getType(), glu::ApiType(3, 3, glu::PROFILE_CORE)) &&
        !(glu::contextSupports(m_renderCtx.getType(), glu::ApiType(3, 1, glu::PROFILE_ES)) &&
          info->isExtensionSupported("GL_EXT_texture_buffer")))
        throw tcu::NotSupportedError("Texture buffers not supported", "", __FILE__, __LINE__);

    {
        const int maxTextureBufferSize = info->getInt(GL_MAX_TEXTURE_BUFFER_SIZE);
        if (maxTextureBufferSize <= 0)
            TCU_THROW(NotSupportedError, "GL_MAX_TEXTURE_BUFFER_SIZE > 0 required");
    }

    if (m_preRender != 0)
    {
        TestLog &log                  = m_testCtx.getLog();
        const char *const sectionName = (m_postRender != 0 ? "Primary render program" : "Render program");
        const tcu::ScopedLogSection section(log, sectionName, sectionName);

        m_preRenderProgram = createRenderProgram(m_renderCtx, m_preRender);
        m_testCtx.getLog() << (*m_preRenderProgram);

        TCU_CHECK(m_preRenderProgram->isOk());
    }

    if (m_postRender != 0)
    {
        // Reusing program
        if (m_preRender == m_postRender)
        {
            m_postRenderProgram = m_preRenderProgram;
        }
        else
        {
            TestLog &log                  = m_testCtx.getLog();
            const char *const sectionName = (m_preRender != 0 ? "Secondary render program" : "Render program");
            const tcu::ScopedLogSection section(log, sectionName, sectionName);

            m_postRenderProgram = createRenderProgram(m_renderCtx, m_postRender);
            m_testCtx.getLog() << (*m_postRenderProgram);

            TCU_CHECK(m_postRenderProgram->isOk());
        }
    }
}

void TextureBufferCase::deinit(void)
{
    if (m_preRenderProgram == m_postRenderProgram)
        m_postRenderProgram = DE_NULL;

    delete m_preRenderProgram;
    m_preRenderProgram = DE_NULL;

    delete m_postRenderProgram;
    m_postRenderProgram = DE_NULL;
}

tcu::TestCase::IterateResult TextureBufferCase::iterate(void)
{
    de::Random rng(deInt32Hash(deStringHash(getName())));
    size_t offset;

    if (m_offset != 0)
    {
        const glw::Functions &gl = m_renderCtx.getFunctions();
        int32_t alignment        = 0;

        gl.getIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &alignment);
        GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT)");

        offset = m_offset * alignment;
    }
    else
        offset = 0;

    runTests(m_testCtx, m_renderCtx, rng, m_format, m_bufferSize, offset, m_size, m_preRender, m_preRenderProgram,
             m_modify, m_postRender, m_postRenderProgram);

    return STOP;
}

} // namespace gls
} // namespace deqp
