/*-------------------------------------------------------------------------
 * 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 Buffer test utilities.
 *//*--------------------------------------------------------------------*/

#include "glsBufferTestUtil.hpp"
#include "tcuRandomValueIterator.hpp"
#include "tcuSurface.hpp"
#include "tcuImageCompare.hpp"
#include "tcuVector.hpp"
#include "tcuFormatUtil.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuTestLog.hpp"
#include "gluPixelTransfer.hpp"
#include "gluRenderContext.hpp"
#include "gluStrUtil.hpp"
#include "gluShaderProgram.hpp"
#include "deMemory.h"
#include "deStringUtil.hpp"
#include "deArrayUtil.hpp"

#include <algorithm>

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

namespace deqp
{
namespace gls
{
namespace BufferTestUtil
{

enum
{
	VERIFY_QUAD_SIZE					= 8,		//!< Quad size in VertexArrayVerifier
	MAX_LINES_PER_INDEX_ARRAY_DRAW		= 128,		//!< Maximum number of lines per one draw in IndexArrayVerifier
	INDEX_ARRAY_DRAW_VIEWPORT_WIDTH		= 128,
	INDEX_ARRAY_DRAW_VIEWPORT_HEIGHT	= 128
};

using tcu::TestLog;
using std::vector;
using std::string;
using std::set;

// Helper functions.

void fillWithRandomBytes (deUint8* ptr, int numBytes, deUint32 seed)
{
	std::copy(tcu::RandomValueIterator<deUint8>::begin(seed, numBytes), tcu::RandomValueIterator<deUint8>::end(), ptr);
}

bool compareByteArrays (tcu::TestLog& log, const deUint8* resPtr, const deUint8* refPtr, int numBytes)
{
	bool			isOk			= true;
	const int		maxSpanLen		= 8;
	const int		maxDiffSpans	= 4;
	int				numDiffSpans	= 0;
	int				diffSpanStart	= -1;
	int				ndx				= 0;

	log << TestLog::Section("Verify", "Verification result");

	for (;ndx < numBytes; ndx++)
	{
		if (resPtr[ndx] != refPtr[ndx])
		{
			if (diffSpanStart < 0)
				diffSpanStart = ndx;

			isOk = false;
		}
		else if (diffSpanStart >= 0)
		{
			if (numDiffSpans < maxDiffSpans)
			{
				int len			= ndx-diffSpanStart;
				int	printLen	= de::min(len, maxSpanLen);

				log << TestLog::Message << len << " byte difference at offset " << diffSpanStart << "\n"
										<< "  expected "	<< tcu::formatArray(tcu::Format::HexIterator<deUint8>(refPtr+diffSpanStart), tcu::Format::HexIterator<deUint8>(refPtr+diffSpanStart+printLen)) << "\n"
										<< "  got "			<< tcu::formatArray(tcu::Format::HexIterator<deUint8>(resPtr+diffSpanStart), tcu::Format::HexIterator<deUint8>(resPtr+diffSpanStart+printLen))
					<< TestLog::EndMessage;
			}
			else
				log << TestLog::Message << "(output too long, truncated)" << TestLog::EndMessage;

			numDiffSpans	+= 1;
			diffSpanStart	 = -1;
		}
	}

	if (diffSpanStart >= 0)
	{
		if (numDiffSpans < maxDiffSpans)
		{
				int len			= ndx-diffSpanStart;
				int	printLen	= de::min(len, maxSpanLen);

				log << TestLog::Message << len << " byte difference at offset " << diffSpanStart << "\n"
										<< "  expected "	<< tcu::formatArray(tcu::Format::HexIterator<deUint8>(refPtr+diffSpanStart), tcu::Format::HexIterator<deUint8>(refPtr+diffSpanStart+printLen)) << "\n"
										<< "  got "			<< tcu::formatArray(tcu::Format::HexIterator<deUint8>(resPtr+diffSpanStart), tcu::Format::HexIterator<deUint8>(resPtr+diffSpanStart+printLen))
					<< TestLog::EndMessage;
		}
		else
			log << TestLog::Message << "(output too long, truncated)" << TestLog::EndMessage;
	}

	log << TestLog::Message << (isOk ? "Verification passed." : "Verification FAILED!") << TestLog::EndMessage;
	log << TestLog::EndSection;

	return isOk;
}

const char* getBufferTargetName (deUint32 target)
{
	switch (target)
	{
		case GL_ARRAY_BUFFER:				return "array";
		case GL_COPY_READ_BUFFER:			return "copy_read";
		case GL_COPY_WRITE_BUFFER:			return "copy_write";
		case GL_ELEMENT_ARRAY_BUFFER:		return "element_array";
		case GL_PIXEL_PACK_BUFFER:			return "pixel_pack";
		case GL_PIXEL_UNPACK_BUFFER:		return "pixel_unpack";
		case GL_TEXTURE_BUFFER:				return "texture";
		case GL_TRANSFORM_FEEDBACK_BUFFER:	return "transform_feedback";
		case GL_UNIFORM_BUFFER:				return "uniform";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

const char* getUsageHintName (deUint32 hint)
{
	switch (hint)
	{
		case GL_STREAM_DRAW:	return "stream_draw";
		case GL_STREAM_READ:	return "stream_read";
		case GL_STREAM_COPY:	return "stream_copy";
		case GL_STATIC_DRAW:	return "static_draw";
		case GL_STATIC_READ:	return "static_read";
		case GL_STATIC_COPY:	return "static_copy";
		case GL_DYNAMIC_DRAW:	return "dynamic_draw";
		case GL_DYNAMIC_READ:	return "dynamic_read";
		case GL_DYNAMIC_COPY:	return "dynamic_copy";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

// BufferCase

BufferCase::BufferCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description)
	: TestCase			(testCtx, name, description)
	, CallLogWrapper	(renderCtx.getFunctions(), testCtx.getLog())
	, m_renderCtx		(renderCtx)
{
}

BufferCase::~BufferCase (void)
{
	enableLogging(false);
	BufferCase::deinit();
}

void BufferCase::init (void)
{
	enableLogging(true);
}

void BufferCase::deinit (void)
{
	for (set<deUint32>::const_iterator bufIter = m_allocatedBuffers.begin(); bufIter != m_allocatedBuffers.end(); bufIter++)
		glDeleteBuffers(1, &(*bufIter));
}

deUint32 BufferCase::genBuffer (void)
{
	deUint32 buf = 0;
	glGenBuffers(1, &buf);
	if (buf != 0)
	{
		try
		{
			m_allocatedBuffers.insert(buf);
		}
		catch (const std::exception&)
		{
			glDeleteBuffers(1, &buf);
			throw;
		}
	}
	return buf;
}

void BufferCase::deleteBuffer (deUint32 buffer)
{
	glDeleteBuffers(1, &buffer);
	m_allocatedBuffers.erase(buffer);
}

void BufferCase::checkError (void)
{
	glw::GLenum err = glGetError();
	if (err != GL_NO_ERROR)
		throw tcu::TestError(string("Got ") + glu::getErrorStr(err).toString());
}

// ReferenceBuffer

void ReferenceBuffer::setSize (int numBytes)
{
	m_data.resize(numBytes);
}

void ReferenceBuffer::setData (int numBytes, const deUint8* bytes)
{
	m_data.resize(numBytes);
	std::copy(bytes, bytes+numBytes, m_data.begin());
}

void ReferenceBuffer::setSubData (int offset, int numBytes, const deUint8* bytes)
{
	DE_ASSERT(de::inBounds(offset, 0, (int)m_data.size()) && de::inRange(offset+numBytes, offset, (int)m_data.size()));
	std::copy(bytes, bytes+numBytes, m_data.begin()+offset);
}

// BufferWriterBase

BufferWriterBase::BufferWriterBase (glu::RenderContext& renderCtx, tcu::TestLog& log)
	: CallLogWrapper	(renderCtx.getFunctions(), log)
	, m_renderCtx		(renderCtx)
{
	enableLogging(true);
}

void BufferWriterBase::write (deUint32 buffer, int offset, int numBytes, const deUint8* bytes, deUint32 targetHint)
{
	DE_UNREF(targetHint);
	write(buffer, offset, numBytes, bytes);
}

// BufferWriter

BufferWriter::BufferWriter (glu::RenderContext& renderCtx, tcu::TestLog& log, WriteType writeType)
	: m_writer(DE_NULL)
{
	switch (writeType)
	{
		case WRITE_BUFFER_SUB_DATA:		m_writer = new BufferSubDataWriter	(renderCtx, log);	break;
		case WRITE_BUFFER_WRITE_MAP:	m_writer = new BufferWriteMapWriter	(renderCtx, log);	break;
		default:
			TCU_FAIL("Unsupported writer");
	}
}

BufferWriter::~BufferWriter (void)
{
	delete m_writer;
}

void BufferWriter::write (deUint32 buffer, int offset, int numBytes, const deUint8* bytes)
{
	DE_ASSERT(numBytes >= getMinSize());
	DE_ASSERT(offset%getAlignment() == 0);
	DE_ASSERT((offset+numBytes)%getAlignment() == 0);
	return m_writer->write(buffer, offset, numBytes, bytes);
}

void BufferWriter::write (deUint32 buffer, int offset, int numBytes, const deUint8* bytes, deUint32 targetHint)
{
	DE_ASSERT(numBytes >= getMinSize());
	DE_ASSERT(offset%getAlignment() == 0);
	DE_ASSERT((offset+numBytes)%getAlignment() == 0);
	return m_writer->write(buffer, offset, numBytes, bytes, targetHint);
}

// BufferSubDataWriter

void BufferSubDataWriter::write (deUint32 buffer, int offset, int numBytes, const deUint8* bytes)
{
	write(buffer, offset, numBytes, bytes, GL_ARRAY_BUFFER);
}

void BufferSubDataWriter::write (deUint32 buffer, int offset, int numBytes, const deUint8* bytes, deUint32 target)
{
	glBindBuffer(target, buffer);
	glBufferSubData(target, offset, numBytes, bytes);
	glBindBuffer(target, 0);
	GLU_CHECK();
}

// BufferWriteMapWriter

void BufferWriteMapWriter::write (deUint32 buffer, int offset, int numBytes, const deUint8* bytes)
{
	write(buffer, offset, numBytes, bytes, GL_ARRAY_BUFFER);
}

void BufferWriteMapWriter::write (deUint32 buffer, int offset, int numBytes, const deUint8* bytes, deUint32 target)
{
	glBindBuffer(target, buffer);

	void* ptr = glMapBufferRange(target, offset, numBytes, GL_MAP_WRITE_BIT);
	GLU_CHECK_MSG("glMapBufferRange");

	deMemcpy(ptr, bytes, numBytes);

	glUnmapBuffer(target);
	glBindBuffer(target, 0);
	GLU_CHECK();
}

// BufferVerifierBase

BufferVerifierBase::BufferVerifierBase (glu::RenderContext& renderCtx, tcu::TestLog& log)
	: CallLogWrapper	(renderCtx.getFunctions(), log)
	, m_renderCtx		(renderCtx)
	, m_log				(log)
{
	enableLogging(true);
}

bool BufferVerifierBase::verify (deUint32 buffer, const deUint8* reference, int offset, int numBytes, deUint32 targetHint)
{
	DE_UNREF(targetHint);
	return verify(buffer, reference, offset, numBytes);
}

// BufferVerifier

BufferVerifier::BufferVerifier (glu::RenderContext& renderCtx, tcu::TestLog& log, VerifyType verifyType)
	: m_verifier(DE_NULL)
{
	switch (verifyType)
	{
		case VERIFY_AS_VERTEX_ARRAY:	m_verifier = new VertexArrayVerifier(renderCtx, log);	break;
		case VERIFY_AS_INDEX_ARRAY:		m_verifier = new IndexArrayVerifier	(renderCtx, log);	break;
		case VERIFY_BUFFER_READ_MAP:	m_verifier = new BufferMapVerifier	(renderCtx, log);	break;
		default:
			TCU_FAIL("Unsupported verifier");
	}
}

BufferVerifier::~BufferVerifier (void)
{
	delete m_verifier;
}

bool BufferVerifier::verify (deUint32 buffer, const deUint8* reference, int offset, int numBytes)
{
	DE_ASSERT(numBytes >= getMinSize());
	DE_ASSERT(offset%getAlignment() == 0);
	DE_ASSERT((offset+numBytes)%getAlignment() == 0);
	return m_verifier->verify(buffer, reference, offset, numBytes);
}

bool BufferVerifier::verify (deUint32 buffer, const deUint8* reference, int offset, int numBytes, deUint32 targetHint)
{
	DE_ASSERT(numBytes >= getMinSize());
	DE_ASSERT(offset%getAlignment() == 0);
	DE_ASSERT((offset+numBytes)%getAlignment() == 0);
	return m_verifier->verify(buffer, reference, offset, numBytes, targetHint);
}

// BufferMapVerifier

bool BufferMapVerifier::verify (deUint32 buffer, const deUint8* reference, int offset, int numBytes)
{
	return verify(buffer, reference, offset, numBytes, GL_ARRAY_BUFFER);
}

bool BufferMapVerifier::verify (deUint32 buffer, const deUint8* reference, int offset, int numBytes, deUint32 target)
{
	const deUint8*	mapPtr		= DE_NULL;
	bool			isOk		= false;

	glBindBuffer(target, buffer);
	mapPtr = (const deUint8*)glMapBufferRange(target, offset, numBytes, GL_MAP_READ_BIT);
	GLU_CHECK_MSG("glMapBufferRange");
	TCU_CHECK(mapPtr);

	isOk = compareByteArrays(m_log, mapPtr, reference+offset, numBytes);

	glUnmapBuffer(target);
	GLU_CHECK_MSG("glUnmapBuffer");

	glBindBuffer(target, 0);

	return isOk;
}

// VertexArrayVerifier

VertexArrayVerifier::VertexArrayVerifier (glu::RenderContext& renderCtx, tcu::TestLog& log)
	: BufferVerifierBase	(renderCtx, log)
	, m_program				(DE_NULL)
	, m_posLoc				(0)
	, m_byteVecLoc			(0)
	, m_vao					(0)
{
	const glu::ContextType	ctxType		= renderCtx.getType();
	const glu::GLSLVersion	glslVersion	= glu::isContextTypeES(ctxType) ? glu::GLSL_VERSION_300_ES : glu::GLSL_VERSION_330;

	DE_ASSERT(glu::isGLSLVersionSupported(ctxType, glslVersion));

	m_program = new glu::ShaderProgram(m_renderCtx, glu::makeVtxFragSources(
		string(glu::getGLSLVersionDeclaration(glslVersion)) + "\n"
		"in highp vec2 a_position;\n"
		"in mediump vec3 a_byteVec;\n"
		"out mediump vec3 v_byteVec;\n"
		"void main (void)\n"
		"{\n"
		"	gl_Position = vec4(a_position, 0.0, 1.0);\n"
		"	v_byteVec = a_byteVec;\n"
		"}\n",

		string(glu::getGLSLVersionDeclaration(glslVersion)) + "\n"
		"in mediump vec3 v_byteVec;\n"
		"layout(location = 0) out mediump vec4 o_color;\n"
		"void main (void)\n"
		"{\n"
		"	o_color = vec4(v_byteVec, 1.0);\n"
		"}\n"));

	if (!m_program->isOk())
	{
		m_log << *m_program;
		delete m_program;
		TCU_FAIL("Compile failed");
	}

	const glw::Functions& gl = m_renderCtx.getFunctions();
	m_posLoc		= gl.getAttribLocation(m_program->getProgram(), "a_position");
	m_byteVecLoc	= gl.getAttribLocation(m_program->getProgram(), "a_byteVec");

	gl.genVertexArrays(1, &m_vao);
	gl.genBuffers(1, &m_positionBuf);
	gl.genBuffers(1, &m_indexBuf);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Initialization failed");
}

VertexArrayVerifier::~VertexArrayVerifier (void)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	if (m_vao)			gl.deleteVertexArrays(1, &m_vao);
	if (m_positionBuf)	gl.deleteBuffers(1, &m_positionBuf);
	if (m_indexBuf)		gl.deleteBuffers(1, &m_indexBuf);

	delete m_program;
}

static void computePositions (vector<tcu::Vec2>& positions, int gridSizeX, int gridSizeY)
{
	positions.resize(gridSizeX*gridSizeY*4);

	for (int y = 0; y < gridSizeY; y++)
	for (int x = 0; x < gridSizeX; x++)
	{
		float	sx0			= (x+0) / (float)gridSizeX;
		float	sy0			= (y+0) / (float)gridSizeY;
		float	sx1			= (x+1) / (float)gridSizeX;
		float	sy1			= (y+1) / (float)gridSizeY;
		float	fx0			= 2.0f * sx0 - 1.0f;
		float	fy0			= 2.0f * sy0 - 1.0f;
		float	fx1			= 2.0f * sx1 - 1.0f;
		float	fy1			= 2.0f * sy1 - 1.0f;
		int		baseNdx		= (y * gridSizeX + x)*4;

		positions[baseNdx+0] = tcu::Vec2(fx0, fy0);
		positions[baseNdx+1] = tcu::Vec2(fx0, fy1);
		positions[baseNdx+2] = tcu::Vec2(fx1, fy0);
		positions[baseNdx+3] = tcu::Vec2(fx1, fy1);
	}
}

static void computeIndices (vector<deUint16>& indices, int gridSizeX, int gridSizeY)
{
	indices.resize(3 * 2 * gridSizeX * gridSizeY);

	for (int quadNdx = 0; quadNdx < gridSizeX*gridSizeY; quadNdx++)
	{
		int v00 = quadNdx*4 + 0;
		int v01 = quadNdx*4 + 1;
		int v10 = quadNdx*4 + 2;
		int v11 = quadNdx*4 + 3;

		DE_ASSERT(v11 < (1<<16));

		indices[quadNdx*6 + 0] = (deUint16)v10;
		indices[quadNdx*6 + 1] = (deUint16)v00;
		indices[quadNdx*6 + 2] = (deUint16)v01;

		indices[quadNdx*6 + 3] = (deUint16)v10;
		indices[quadNdx*6 + 4] = (deUint16)v01;
		indices[quadNdx*6 + 5] = (deUint16)v11;
	}
}

static inline tcu::Vec4 fetchVtxColor (const deUint8* ptr, int vtxNdx)
{
	return tcu::RGBA(*(ptr + vtxNdx*3 + 0),
					 *(ptr + vtxNdx*3 + 1),
					 *(ptr + vtxNdx*3 + 2),
					 255).toVec();
}

static void renderQuadGridReference (tcu::Surface& dst, int numQuads, int rowLength, const deUint8* inPtr)
{
	using tcu::Vec4;

	dst.setSize(rowLength*VERIFY_QUAD_SIZE, (numQuads/rowLength + (numQuads%rowLength != 0 ? 1 : 0))*VERIFY_QUAD_SIZE);

	tcu::PixelBufferAccess dstAccess = dst.getAccess();
	tcu::clear(dstAccess, tcu::IVec4(0, 0, 0, 0xff));

	for (int quadNdx = 0; quadNdx < numQuads; quadNdx++)
	{
		int		x0		= (quadNdx%rowLength)*VERIFY_QUAD_SIZE;
		int		y0		= (quadNdx/rowLength)*VERIFY_QUAD_SIZE;
		Vec4	v00		= fetchVtxColor(inPtr, quadNdx*4 + 0);
		Vec4	v10		= fetchVtxColor(inPtr, quadNdx*4 + 1);
		Vec4	v01		= fetchVtxColor(inPtr, quadNdx*4 + 2);
		Vec4	v11		= fetchVtxColor(inPtr, quadNdx*4 + 3);

		for (int y = 0; y < VERIFY_QUAD_SIZE; y++)
		for (int x = 0; x < VERIFY_QUAD_SIZE; x++)
		{
			float		fx		= (float)(x+0.5f) / (float)VERIFY_QUAD_SIZE;
			float		fy		= (float)(y+0.5f) / (float)VERIFY_QUAD_SIZE;

			bool		tri		= fx + fy <= 1.0f;
			float		tx		= tri ? fx : (1.0f-fx);
			float		ty		= tri ? fy : (1.0f-fy);
			const Vec4&	t0		= tri ? v00 : v11;
			const Vec4&	t1		= tri ? v01 : v10;
			const Vec4&	t2		= tri ? v10 : v01;
			Vec4		color	= t0 + (t1-t0)*tx + (t2-t0)*ty;

			dstAccess.setPixel(color, x0+x, y0+y);
		}
	}
}

bool VertexArrayVerifier::verify (deUint32 buffer, const deUint8* refPtr, int offset, int numBytes)
{
	const tcu::RenderTarget&	renderTarget		= m_renderCtx.getRenderTarget();
	const int					numBytesInVtx		= 3;
	const int					numBytesInQuad		= numBytesInVtx*4;
	int							maxQuadsX			= de::min(128, renderTarget.getWidth()	/ VERIFY_QUAD_SIZE);
	int							maxQuadsY			= de::min(128, renderTarget.getHeight()	/ VERIFY_QUAD_SIZE);
	int							maxQuadsPerBatch	= maxQuadsX*maxQuadsY;
	int							numVerified			= 0;
	deUint32					program				= m_program->getProgram();
	tcu::RGBA					threshold			= renderTarget.getPixelFormat().getColorThreshold() + tcu::RGBA(3,3,3,3);
	bool						isOk				= true;

	vector<tcu::Vec2>			positions;
	vector<deUint16>			indices;

	tcu::Surface				rendered;
	tcu::Surface				reference;

	DE_ASSERT(numBytes >= numBytesInQuad); // Can't render full quad with smaller buffers.

	computePositions(positions, maxQuadsX, maxQuadsY);
	computeIndices(indices, maxQuadsX, maxQuadsY);

	// Reset buffer bindings.
	glBindBuffer				(GL_PIXEL_PACK_BUFFER, 0);

	// Setup rendering state.
	glViewport					(0, 0, maxQuadsX*VERIFY_QUAD_SIZE, maxQuadsY*VERIFY_QUAD_SIZE);
	glClearColor				(0.0f, 0.0f, 0.0f, 1.0f);
	glUseProgram				(program);
	glBindVertexArray			(m_vao);

	// Upload positions
	glBindBuffer				(GL_ARRAY_BUFFER, m_positionBuf);
	glBufferData				(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(positions.size()*sizeof(positions[0])), &positions[0], GL_STATIC_DRAW);
	glEnableVertexAttribArray	(m_posLoc);
	glVertexAttribPointer		(m_posLoc, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL);

	// Upload indices
	glBindBuffer				(GL_ELEMENT_ARRAY_BUFFER, m_indexBuf);
	glBufferData				(GL_ELEMENT_ARRAY_BUFFER, (glw::GLsizeiptr)(indices.size()*sizeof(indices[0])), &indices[0], GL_STATIC_DRAW);

	glEnableVertexAttribArray	(m_byteVecLoc);
	glBindBuffer				(GL_ARRAY_BUFFER, buffer);

	while (numVerified < numBytes)
	{
		int		numRemaining		= numBytes-numVerified;
		bool	isLeftoverBatch		= numRemaining < numBytesInQuad;
		int		numBytesToVerify	= isLeftoverBatch ? numBytesInQuad				: de::min(maxQuadsPerBatch*numBytesInQuad, numRemaining - numRemaining%numBytesInQuad);
		int		curOffset			= isLeftoverBatch ? (numBytes-numBytesInQuad)	: numVerified;
		int		numQuads			= numBytesToVerify/numBytesInQuad;
		int		numCols				= de::min(maxQuadsX, numQuads);
		int		numRows				= numQuads/maxQuadsX + (numQuads%maxQuadsX != 0 ? 1 : 0);
		string	imageSetDesc		= string("Bytes ") + de::toString(offset+curOffset) + " to " + de::toString(offset+curOffset+numBytesToVerify-1);

		DE_ASSERT(numBytesToVerify > 0 && numBytesToVerify%numBytesInQuad == 0);
		DE_ASSERT(de::inBounds(curOffset, 0, numBytes));
		DE_ASSERT(de::inRange(curOffset+numBytesToVerify, curOffset, numBytes));

		// Render batch.
		glClear					(GL_COLOR_BUFFER_BIT);
		glVertexAttribPointer	(m_byteVecLoc, 3, GL_UNSIGNED_BYTE, GL_TRUE, 0, (const glw::GLvoid*)(deUintptr)(offset + curOffset));
		glDrawElements			(GL_TRIANGLES, numQuads*6, GL_UNSIGNED_SHORT, DE_NULL);

		renderQuadGridReference(reference,  numQuads, numCols, refPtr + offset + curOffset);

		rendered.setSize(numCols*VERIFY_QUAD_SIZE, numRows*VERIFY_QUAD_SIZE);
		glu::readPixels(m_renderCtx, 0, 0, rendered.getAccess());

		if (!tcu::pixelThresholdCompare(m_log, "RenderResult", imageSetDesc.c_str(), reference, rendered, threshold, tcu::COMPARE_LOG_RESULT))
		{
			isOk = false;
			break;
		}

		numVerified += isLeftoverBatch ? numRemaining : numBytesToVerify;
	}

	glBindVertexArray(0);

	return isOk;
}

// IndexArrayVerifier

IndexArrayVerifier::IndexArrayVerifier (glu::RenderContext& renderCtx, tcu::TestLog& log)
	: BufferVerifierBase	(renderCtx, log)
	, m_program				(DE_NULL)
	, m_posLoc				(0)
	, m_colorLoc			(0)
{

	const glu::ContextType	ctxType		= renderCtx.getType();
	const glu::GLSLVersion	glslVersion	= glu::isContextTypeES(ctxType) ? glu::GLSL_VERSION_300_ES : glu::GLSL_VERSION_330;

	DE_ASSERT(glu::isGLSLVersionSupported(ctxType, glslVersion));

	m_program = new glu::ShaderProgram(m_renderCtx, glu::makeVtxFragSources(
		string(glu::getGLSLVersionDeclaration(glslVersion)) + "\n"
		"in highp vec2 a_position;\n"
		"in mediump vec3 a_color;\n"
		"out mediump vec3 v_color;\n"
		"void main (void)\n"
		"{\n"
		"	gl_Position = vec4(a_position, 0.0, 1.0);\n"
		"	v_color = a_color;\n"
		"}\n",

		string(glu::getGLSLVersionDeclaration(glslVersion)) + "\n"
		"in mediump vec3 v_color;\n"
		"layout(location = 0) out mediump vec4 o_color;\n"
		"void main (void)\n"
		"{\n"
		"	o_color = vec4(v_color, 1.0);\n"
		"}\n"));

	if (!m_program->isOk())
	{
		m_log << *m_program;
		delete m_program;
		TCU_FAIL("Compile failed");
	}

	const glw::Functions& gl = m_renderCtx.getFunctions();
	m_posLoc	= gl.getAttribLocation(m_program->getProgram(), "a_position");
	m_colorLoc	= gl.getAttribLocation(m_program->getProgram(), "a_color");

	gl.genVertexArrays(1, &m_vao);
	gl.genBuffers(1, &m_positionBuf);
	gl.genBuffers(1, &m_colorBuf);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Initialization failed");
}

IndexArrayVerifier::~IndexArrayVerifier (void)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	if (m_vao)			gl.deleteVertexArrays(1, &m_vao);
	if (m_positionBuf)	gl.deleteBuffers(1, &m_positionBuf);
	if (m_colorBuf)		gl.deleteBuffers(1, &m_colorBuf);

	delete m_program;
}

static void computeIndexVerifierPositions (std::vector<tcu::Vec2>& dst)
{
	const int	numPosX		= 16;
	const int	numPosY		= 16;

	dst.resize(numPosX*numPosY);

	for (int y = 0; y < numPosY; y++)
	{
		for (int x = 0; x < numPosX; x++)
		{
			float	xf	= float(x) / float(numPosX-1);
			float	yf	= float(y) / float(numPosY-1);

			dst[y*numPosX + x] = tcu::Vec2(2.0f*xf - 1.0f, 2.0f*yf - 1.0f);
		}
	}
}

static void computeIndexVerifierColors (std::vector<tcu::Vec3>& dst)
{
	const int	numColors	= 256;
	const float	minVal		= 0.1f;
	const float maxVal		= 0.5f;
	de::Random	rnd			(0xabc231);

	dst.resize(numColors);

	for (std::vector<tcu::Vec3>::iterator i = dst.begin(); i != dst.end(); ++i)
	{
		i->x()	= rnd.getFloat(minVal, maxVal);
		i->y()	= rnd.getFloat(minVal, maxVal);
		i->z()	= rnd.getFloat(minVal, maxVal);
	}
}

template<typename T>
static void execVertexFetch (T* dst, const T* src, const deUint8* indices, int numIndices)
{
	for (int i = 0; i < numIndices; ++i)
		dst[i] = src[indices[i]];
}

bool IndexArrayVerifier::verify (deUint32 buffer, const deUint8* refPtr, int offset, int numBytes)
{
	const tcu::RenderTarget&	renderTarget		= m_renderCtx.getRenderTarget();
	const int					viewportW			= de::min<int>(INDEX_ARRAY_DRAW_VIEWPORT_WIDTH, renderTarget.getWidth());
	const int					viewportH			= de::min<int>(INDEX_ARRAY_DRAW_VIEWPORT_HEIGHT, renderTarget.getHeight());
	const int					minBytesPerBatch	= 2;
	const tcu::RGBA				threshold			(0,0,0,0);

	std::vector<tcu::Vec2>		positions;
	std::vector<tcu::Vec3>		colors;

	std::vector<tcu::Vec2>		fetchedPos			(MAX_LINES_PER_INDEX_ARRAY_DRAW+1);
	std::vector<tcu::Vec3>		fetchedColor		(MAX_LINES_PER_INDEX_ARRAY_DRAW+1);

	tcu::Surface				indexBufferImg		(viewportW, viewportH);
	tcu::Surface				referenceImg		(viewportW, viewportH);

	int							numVerified			= 0;
	bool						isOk				= true;

	DE_STATIC_ASSERT(sizeof(tcu::Vec2) == sizeof(float)*2);
	DE_STATIC_ASSERT(sizeof(tcu::Vec3) == sizeof(float)*3);

	computeIndexVerifierPositions(positions);
	computeIndexVerifierColors(colors);

	// Reset buffer bindings.
	glBindVertexArray			(m_vao);
	glBindBuffer				(GL_PIXEL_PACK_BUFFER,		0);
	glBindBuffer				(GL_ELEMENT_ARRAY_BUFFER,	buffer);

	// Setup rendering state.
	glViewport					(0, 0, viewportW, viewportH);
	glClearColor				(0.0f, 0.0f, 0.0f, 1.0f);
	glUseProgram				(m_program->getProgram());
	glEnableVertexAttribArray	(m_posLoc);
	glEnableVertexAttribArray	(m_colorLoc);
	glEnable					(GL_BLEND);
	glBlendFunc					(GL_ONE, GL_ONE);
	glBlendEquation				(GL_FUNC_ADD);

	while (numVerified < numBytes)
	{
		int		numRemaining		= numBytes-numVerified;
		bool	isLeftoverBatch		= numRemaining < minBytesPerBatch;
		int		numBytesToVerify	= isLeftoverBatch ? minBytesPerBatch			: de::min(MAX_LINES_PER_INDEX_ARRAY_DRAW+1, numRemaining);
		int		curOffset			= isLeftoverBatch ? (numBytes-minBytesPerBatch)	: numVerified;
		string	imageSetDesc		= string("Bytes ") + de::toString(offset+curOffset) + " to " + de::toString(offset+curOffset+numBytesToVerify-1);

		// Step 1: Render using index buffer.
		glClear					(GL_COLOR_BUFFER_BIT);

		glBindBuffer			(GL_ARRAY_BUFFER, m_positionBuf);
		glBufferData			(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(positions.size()*sizeof(positions[0])), &positions[0], GL_STREAM_DRAW);
		glVertexAttribPointer	(m_posLoc, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL);

		glBindBuffer			(GL_ARRAY_BUFFER, m_colorBuf);
		glBufferData			(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(colors.size()*sizeof(colors[0])), &colors[0], GL_STREAM_DRAW);
		glVertexAttribPointer	(m_colorLoc, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);

		glDrawElements			(GL_LINE_STRIP, numBytesToVerify, GL_UNSIGNED_BYTE, (void*)(deUintptr)(offset+curOffset));
		glu::readPixels			(m_renderCtx, 0, 0, indexBufferImg.getAccess());

		// Step 2: Do manual fetch and render without index buffer.
		execVertexFetch(&fetchedPos[0], &positions[0], refPtr+offset+curOffset, numBytesToVerify);
		execVertexFetch(&fetchedColor[0], &colors[0], refPtr+offset+curOffset, numBytesToVerify);

		glClear					(GL_COLOR_BUFFER_BIT);

		glBindBuffer			(GL_ARRAY_BUFFER, m_positionBuf);
		glBufferData			(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(fetchedPos.size()*sizeof(fetchedPos[0])), &fetchedPos[0], GL_STREAM_DRAW);
		glVertexAttribPointer	(m_posLoc, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL);

		glBindBuffer			(GL_ARRAY_BUFFER, m_colorBuf);
		glBufferData			(GL_ARRAY_BUFFER, (glw::GLsizeiptr)(fetchedColor.size()*sizeof(fetchedColor[0])), &fetchedColor[0], GL_STREAM_DRAW);
		glVertexAttribPointer	(m_colorLoc, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);

		glDrawArrays			(GL_LINE_STRIP, 0, numBytesToVerify);
		glu::readPixels			(m_renderCtx, 0, 0, referenceImg.getAccess());

		if (!tcu::pixelThresholdCompare(m_log, "RenderResult", imageSetDesc.c_str(), referenceImg, indexBufferImg, threshold, tcu::COMPARE_LOG_RESULT))
		{
			isOk = false;
			break;
		}

		numVerified += isLeftoverBatch ? numRemaining : numBytesToVerify;
	}

	glBindVertexArray(0);

	return isOk;
}

const char* getWriteTypeDescription (WriteType write)
{
	static const char* s_desc[] =
	{
		"glBufferSubData()",
		"glMapBufferRange()",
		"transform feedback",
		"glReadPixels() into PBO binding"
	};
	return de::getSizedArrayElement<WRITE_LAST>(s_desc, write);
}

const char* getVerifyTypeDescription (VerifyType verify)
{
	static const char* s_desc[] =
	{
		"rendering as vertex data",
		"rendering as index data",
		"reading in shader as uniform buffer data",
		"using as PBO and uploading to texture",
		"reading back using glMapBufferRange()"
	};
	return de::getSizedArrayElement<VERIFY_LAST>(s_desc, verify);
}

} // BufferTestUtil
} // gls
} // deqp
