/*-------------------------------------------------------------------------
 * 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,
};

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

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

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

	coords.resize(size);

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

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

		for (int i = 0; i < DE_LENGTH_OF_ARRAY(indices); i++)
		{
			const deUint8	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 deUint8 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<deUint8> data;

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

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

	{
		// replace getRefBuffer with a new buffer
		de::ArrayBuffer<deUint8> 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<deUint8>				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((deUint8*)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<deUint8>				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());
	{
		deUint8* ptr = (deUint8*)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((deUint8*)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)));
	deUint8* const				refPtr		= (deUint8*)texture.getRefBuffer().getPtr() + offset;
	vector<deUint8>				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;
		deUint8* const	ptr				= (deUint8*)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,
			   deUint32					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<deUint8> 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 deInt32 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 deInt32 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,
					  deUint32						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<deUint8>						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 deUint32				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)))
	{
		deInt32 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"))
	{
		{
			deInt32 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;
		}

		{
			deInt32 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(DE_FALSE);
}

void logTextureInfo (TestLog&	log,
					 deUint32	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,
			   deUint32				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<deUint8>			bufferData;

		genRandomCoords(rng, bufferData, 0, bufferSize);

		for (deUint8 i = 0; i < 4; i++)
		{
			const deUint8 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);
	}
}

} // anonymous

TextureBufferCase::TextureBufferCase (tcu::TestContext&		testCtx,
									  glu::RenderContext&	renderCtx,
									  deUint32				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();
		deInt32					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;
}

} // gls
} // deqp
