/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.0 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 data upload tests.
 *//*--------------------------------------------------------------------*/

#include "es3fBufferWriteTests.hpp"
#include "glsBufferTestUtil.hpp"
#include "tcuTestLog.hpp"
#include "gluStrUtil.hpp"
#include "deMemory.h"
#include "deString.h"
#include "deRandom.hpp"
#include "deStringUtil.hpp"
#include "deMath.h"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"

#include <algorithm>
#include <list>

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

namespace deqp
{
namespace gles3
{
namespace Functional
{

using namespace gls::BufferTestUtil;

struct DataStoreSpec
{
	DataStoreSpec (void)
		: target	(0)
		, usage		(0)
		, size		(0)
	{
	}

	DataStoreSpec (deUint32 target_, deUint32 usage_, int size_)
		: target	(target_)
		, usage		(usage_)
		, size		(size_)
	{
	}

	deUint32	target;
	deUint32	usage;
	int			size;
};

struct DataStoreSpecVecBuilder
{
	std::vector<DataStoreSpec>& list;

	DataStoreSpecVecBuilder (std::vector<DataStoreSpec>& list_)
		: list(list_)
	{
	}

	DataStoreSpecVecBuilder& operator<< (const DataStoreSpec& spec)
	{
		list.push_back(spec);
		return *this;
	}
};

struct RangeVecBuilder
{
	std::vector<tcu::IVec2>& list;

	RangeVecBuilder (std::vector<tcu::IVec2>& list_)
		: list(list_)
	{
	}

	RangeVecBuilder& operator<< (const tcu::IVec2& vec)
	{
		list.push_back(vec);
		return *this;
	}
};

template<typename Iterator>
static bool isRangeListValid (Iterator begin, Iterator end)
{
	if (begin != end)
	{
		// Fetch first.
		tcu::IVec2 prev = *begin;
		++begin;

		for (; begin != end; ++begin)
		{
			tcu::IVec2 cur = *begin;
			if (cur.x() <= prev.x() || cur.x() <= prev.x()+prev.y())
				return false;
			prev = cur;
		}
	}

	return true;
}

inline bool rangesIntersect (const tcu::IVec2& a, const tcu::IVec2& b)
{
	return de::inRange(a.x(), b.x(), b.x()+b.y()) || de::inRange(a.x()+a.y(), b.x(), b.x()+b.y()) ||
		   de::inRange(b.x(), a.x(), a.x()+a.y()) || de::inRange(b.x()+b.y(), a.x(), a.x()+a.y());
}

inline tcu::IVec2 unionRanges (const tcu::IVec2& a, const tcu::IVec2& b)
{
	DE_ASSERT(rangesIntersect(a, b));

	int start	= de::min(a.x(), b.x());
	int end		= de::max(a.x()+a.y(), b.x()+b.y());

	return tcu::IVec2(start, end-start);
}

//! Updates range list (start, len) with a new range.
std::vector<tcu::IVec2> addRangeToList (const std::vector<tcu::IVec2>& oldList, const tcu::IVec2& newRange)
{
	DE_ASSERT(newRange.y() > 0);

	std::vector<tcu::IVec2>					newList;
	std::vector<tcu::IVec2>::const_iterator	oldListIter	= oldList.begin();

	// Append ranges that end before the new range.
	for (; oldListIter != oldList.end() && oldListIter->x()+oldListIter->y() < newRange.x(); ++oldListIter)
		newList.push_back(*oldListIter);

	// Join any ranges that intersect new range
	{
		tcu::IVec2 curRange = newRange;
		while (oldListIter != oldList.end() && rangesIntersect(curRange, *oldListIter))
		{
			curRange = unionRanges(curRange, *oldListIter);
			++oldListIter;
		}

		newList.push_back(curRange);
	}

	// Append remaining ranges.
	for (; oldListIter != oldList.end(); oldListIter++)
		newList.push_back(*oldListIter);

	DE_ASSERT(isRangeListValid(newList.begin(), newList.end()));

	return newList;
}

class BasicBufferDataCase : public BufferCase
{
public:
	BasicBufferDataCase (Context& context, const char* name, const char* desc, deUint32 target, deUint32 usage, int size, VerifyType verify)
		: BufferCase	(context.getTestContext(), context.getRenderContext(), name, desc)
		, m_target		(target)
		, m_usage		(usage)
		, m_size		(size)
		, m_verify		(verify)
	{
	}

	IterateResult iterate (void)
	{
		const deUint32			dataSeed	= deStringHash(getName()) ^ 0x125;
		BufferVerifier			verifier	(m_renderCtx, m_testCtx.getLog(), m_verify);
		ReferenceBuffer			refBuf;
		bool					isOk		= false;

		refBuf.setSize(m_size);
		fillWithRandomBytes(refBuf.getPtr(), m_size, dataSeed);

		deUint32 buf = genBuffer();
		glBindBuffer(m_target, buf);
		glBufferData(m_target, m_size, refBuf.getPtr(), m_usage);

		checkError();

		isOk = verifier.verify(buf, refBuf.getPtr(), 0, m_size, m_target);

		deleteBuffer(buf);

		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
								isOk ? "Pass"				: "Buffer verification failed");
		return STOP;
	}

private:
	deUint32		m_target;
	deUint32		m_usage;
	int				m_size;
	VerifyType		m_verify;
};

class RecreateBufferDataStoreCase : public BufferCase
{
public:
	RecreateBufferDataStoreCase (Context& context, const char* name, const char* desc, const DataStoreSpec* specs, int numSpecs, VerifyType verify)
		: BufferCase(context.getTestContext(), context.getRenderContext(), name, desc)
		, m_specs	(specs, specs+numSpecs)
		, m_verify	(verify)
	{
	}

	IterateResult iterate (void)
	{
		const deUint32			baseSeed	= deStringHash(getName()) ^ 0xbeef;
		BufferVerifier			verifier	(m_renderCtx, m_testCtx.getLog(), m_verify);
		ReferenceBuffer			refBuf;
		const deUint32			buf			= genBuffer();

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

		for (vector<DataStoreSpec>::const_iterator spec = m_specs.begin(); spec != m_specs.end(); spec++)
		{
			bool iterOk = false;

			refBuf.setSize(spec->size);
			fillWithRandomBytes(refBuf.getPtr(), spec->size, baseSeed ^ deInt32Hash(spec->size+spec->target+spec->usage));

			glBindBuffer(spec->target, buf);
			glBufferData(spec->target, spec->size, refBuf.getPtr(), spec->usage);

			checkError();

			iterOk = verifier.verify(buf, refBuf.getPtr(), 0, spec->size, spec->target);

			if (!iterOk)
			{
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
				break;
			}
		}

		deleteBuffer(buf);
		return STOP;
	}

private:
	std::vector<DataStoreSpec>	m_specs;
	VerifyType					m_verify;
};

class BasicBufferSubDataCase : public BufferCase
{
public:
	BasicBufferSubDataCase (Context& context, const char* name, const char* desc, deUint32 target, deUint32 usage, int size, int subDataOffs, int subDataSize, VerifyType verify)
		: BufferCase	(context.getTestContext(), context.getRenderContext(), name, desc)
		, m_target		(target)
		, m_usage		(usage)
		, m_size		(size)
		, m_subDataOffs	(subDataOffs)
		, m_subDataSize	(subDataSize)
		, m_verify		(verify)
	{
		DE_ASSERT(de::inBounds(subDataOffs, 0, size) && de::inRange(subDataOffs+subDataSize, 0, size));
	}

	IterateResult iterate (void)
	{
		const deUint32			dataSeed	= deStringHash(getName());
		BufferVerifier			verifier	(m_renderCtx, m_testCtx.getLog(), m_verify);
		ReferenceBuffer			refBuf;
		bool					isOk		= false;

		refBuf.setSize(m_size);

		deUint32 buf = genBuffer();
		glBindBuffer(m_target, buf);

		// Initialize with glBufferData()
		fillWithRandomBytes(refBuf.getPtr(), m_size, dataSeed ^ 0x80354f);
		glBufferData(m_target, m_size, refBuf.getPtr(), m_usage);
		checkError();

		// Re-specify part of buffer
		fillWithRandomBytes(refBuf.getPtr()+m_subDataOffs, m_subDataSize, dataSeed ^ 0xfac425c);
		glBufferSubData(m_target, m_subDataOffs, m_subDataSize, refBuf.getPtr()+m_subDataOffs);

		isOk = verifier.verify(buf, refBuf.getPtr(), 0, m_size, m_target);

		deleteBuffer(buf);

		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
								isOk ? "Pass"				: "Buffer verification failed");
		return STOP;
	}

private:
	deUint32		m_target;
	deUint32		m_usage;
	int				m_size;
	int				m_subDataOffs;
	int				m_subDataSize;
	VerifyType		m_verify;
};

class SubDataToUndefinedCase : public BufferCase
{
public:
	SubDataToUndefinedCase (Context& context, const char* name, const char* desc, deUint32 target, deUint32 usage, int size, const tcu::IVec2* ranges, int numRanges, VerifyType verify)
		: BufferCase	(context.getTestContext(), context.getRenderContext(), name, desc)
		, m_target		(target)
		, m_usage		(usage)
		, m_size		(size)
		, m_ranges		(ranges, ranges+numRanges)
		, m_verify		(verify)
	{
	}

	IterateResult iterate (void)
	{
		const deUint32			dataSeed	= deStringHash(getName());
		BufferVerifier			verifier	(m_renderCtx, m_testCtx.getLog(), m_verify);
		ReferenceBuffer			refBuf;
		bool					isOk		= true;
		std::vector<tcu::IVec2>	definedRanges;

		refBuf.setSize(m_size);

		deUint32 buf = genBuffer();
		glBindBuffer(m_target, buf);

		// Initialize storage with glBufferData()
		glBufferData(m_target, m_size, DE_NULL, m_usage);
		checkError();

		// Fill specified ranges with glBufferSubData()
		for (vector<tcu::IVec2>::const_iterator range = m_ranges.begin(); range != m_ranges.end(); range++)
		{
			fillWithRandomBytes(refBuf.getPtr()+range->x(), range->y(), dataSeed ^ deInt32Hash(range->x()+range->y()));
			glBufferSubData(m_target, range->x(), range->y(), refBuf.getPtr()+range->x());

			// Mark range as defined
			definedRanges = addRangeToList(definedRanges, *range);
		}

		// Verify defined parts
		for (vector<tcu::IVec2>::const_iterator range = definedRanges.begin(); range != definedRanges.end(); range++)
		{
			if (!verifier.verify(buf, refBuf.getPtr(), range->x(), range->y(), m_target))
				isOk = false;
		}

		deleteBuffer(buf);

		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
								isOk ? "Pass"				: "Buffer verification failed");
		return STOP;
	}

private:
	deUint32				m_target;
	deUint32				m_usage;
	int						m_size;
	std::vector<tcu::IVec2>	m_ranges;
	VerifyType				m_verify;
};

class RandomBufferWriteCase : public BufferCase
{
public:
	RandomBufferWriteCase (Context& context, const char* name, const char* desc, deUint32 seed)
		: BufferCase(context.getTestContext(), context.getRenderContext(), name, desc)
		, m_seed		(seed)
		, m_verifier	(DE_NULL)
		, m_buffer		(0)
		, m_curSize		(0)
		, m_iterNdx		(0)
	{
	}

	~RandomBufferWriteCase (void)
	{
		delete m_verifier;
	}

	void init (void)
	{
		BufferCase::init();

		m_iterNdx	= 0;
		m_buffer	= genBuffer();
		m_curSize	= 0;
		m_verifier	= new BufferVerifier(m_renderCtx, m_testCtx.getLog(), VERIFY_AS_VERTEX_ARRAY);

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}

	void deinit (void)
	{
		deleteBuffer(m_buffer);
		m_refBuffer.setSize(0);

		delete m_verifier;
		m_verifier = DE_NULL;

		BufferCase::deinit();
	}

	IterateResult iterate (void)
	{
		// Parameters.
		const int	numIterations				= 5;
		const int	uploadsPerIteration			= 7;
		const int	minSize						= 12;
		const int	maxSize						= 32*1024;
		const float	respecifyProbability		= 0.07f;
		const float	respecifyDataProbability	= 0.2f;

		static const deUint32 bufferTargets[] =
		{
			GL_ARRAY_BUFFER,
			GL_COPY_READ_BUFFER,
			GL_COPY_WRITE_BUFFER,
			GL_ELEMENT_ARRAY_BUFFER,
			GL_PIXEL_PACK_BUFFER,
			GL_PIXEL_UNPACK_BUFFER,
			GL_TRANSFORM_FEEDBACK_BUFFER,
			GL_UNIFORM_BUFFER
		};

		static const deUint32 usageHints[] =
		{
			GL_STREAM_DRAW,
			GL_STREAM_READ,
			GL_STREAM_COPY,
			GL_STATIC_DRAW,
			GL_STATIC_READ,
			GL_STATIC_COPY,
			GL_DYNAMIC_DRAW,
			GL_DYNAMIC_READ,
			GL_DYNAMIC_COPY
		};

		bool		iterOk					= true;
		deUint32	curBoundTarget			= GL_NONE;
		de::Random	rnd						(m_seed ^ deInt32Hash(m_iterNdx) ^ 0xacf92e);

		m_testCtx.getLog() << TestLog::Section(string("Iteration") + de::toString(m_iterNdx+1), string("Iteration ") + de::toString(m_iterNdx+1) + " / " + de::toString(numIterations));

		for (int uploadNdx = 0; uploadNdx < uploadsPerIteration; uploadNdx++)
		{
			const deUint32	target		= bufferTargets[rnd.getInt(0, DE_LENGTH_OF_ARRAY(bufferTargets)-1)];
			const bool		respecify	= m_curSize == 0 || rnd.getFloat() < respecifyProbability;

			if (target != curBoundTarget)
			{
				glBindBuffer(target, m_buffer);
				curBoundTarget = target;
			}

			if (respecify)
			{
				const int		size			= rnd.getInt(minSize, maxSize);
				const deUint32	hint			= usageHints[rnd.getInt(0, DE_LENGTH_OF_ARRAY(usageHints)-1)];
				const bool		fillWithData	= rnd.getFloat() < respecifyDataProbability;

				m_refBuffer.setSize(size);
				if (fillWithData)
					fillWithRandomBytes(m_refBuffer.getPtr(), size, rnd.getUint32());

				glBufferData(target, size, fillWithData ? m_refBuffer.getPtr() : DE_NULL, hint);

				m_validRanges.clear();
				if (fillWithData)
					m_validRanges.push_back(tcu::IVec2(0, size));

				m_curSize = size;
			}
			else
			{
				// \note Non-uniform size distribution.
				const int	size	= de::clamp(deRoundFloatToInt32((float)m_curSize * deFloatPow(rnd.getFloat(0.0f, 0.7f), 3.0f)), minSize, m_curSize);
				const int	offset	= rnd.getInt(0, m_curSize-size);

				fillWithRandomBytes(m_refBuffer.getPtr()+offset, size, rnd.getUint32());
				glBufferSubData(target, offset, size, m_refBuffer.getPtr()+offset);

				m_validRanges = addRangeToList(m_validRanges, tcu::IVec2(offset, size));
			}
		}

		// Check error.
		{
			deUint32 err = glGetError();
			if (err != GL_NO_ERROR)
				throw tcu::TestError(string("Got ") + glu::getErrorStr(err).toString());
		}

		// Verify valid ranges.
		for (vector<IVec2>::const_iterator range = m_validRanges.begin(); range != m_validRanges.end(); range++)
		{
			const deUint32 targetHint = GL_ARRAY_BUFFER;
			if (!m_verifier->verify(m_buffer, m_refBuffer.getPtr(), range->x(), range->y(), targetHint))
			{
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Buffer verification failed");
				iterOk = false;
				break;
			}
		}

		m_testCtx.getLog() << TestLog::EndSection;

		DE_ASSERT(iterOk || m_testCtx.getTestResult() != QP_TEST_RESULT_PASS);

		m_iterNdx += 1;
		return (iterOk && m_iterNdx < numIterations) ? CONTINUE : STOP;
	}

private:
	deUint32				m_seed;

	BufferVerifier*			m_verifier;
	deUint32				m_buffer;
	ReferenceBuffer			m_refBuffer;
	std::vector<tcu::IVec2>	m_validRanges;
	int						m_curSize;
	int						m_iterNdx;
};

BufferWriteTests::BufferWriteTests (Context& context)
	: TestCaseGroup(context, "write", "Buffer data upload tests")
{
}

BufferWriteTests::~BufferWriteTests (void)
{
}

void BufferWriteTests::init (void)
{
	static const deUint32 bufferTargets[] =
	{
		GL_ARRAY_BUFFER,
		GL_COPY_READ_BUFFER,
		GL_COPY_WRITE_BUFFER,
		GL_ELEMENT_ARRAY_BUFFER,
		GL_PIXEL_PACK_BUFFER,
		GL_PIXEL_UNPACK_BUFFER,
		GL_TRANSFORM_FEEDBACK_BUFFER,
		GL_UNIFORM_BUFFER
	};

	static const deUint32 usageHints[] =
	{
		GL_STREAM_DRAW,
		GL_STREAM_READ,
		GL_STREAM_COPY,
		GL_STATIC_DRAW,
		GL_STATIC_READ,
		GL_STATIC_COPY,
		GL_DYNAMIC_DRAW,
		GL_DYNAMIC_READ,
		GL_DYNAMIC_COPY
	};

	// .basic
	{
		tcu::TestCaseGroup* const basicGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic upload with glBufferData()");
		addChild(basicGroup);

		for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
		{
			for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usageHints); usageNdx++)
			{
				const deUint32		target	= bufferTargets[targetNdx];
				const deUint32		usage	= usageHints[usageNdx];
				const int			size	= 1020;
				const VerifyType	verify	= VERIFY_AS_VERTEX_ARRAY;
				const string		name	= string(getBufferTargetName(target)) + "_" + getUsageHintName(usage);

				basicGroup->addChild(new BasicBufferDataCase(m_context, name.c_str(), "", target, usage, size, verify));
			}
		}
	}

	// .recreate_store
	{
		tcu::TestCaseGroup* const recreateStoreGroup = new tcu::TestCaseGroup(m_testCtx, "recreate_store", "Data store recreate using glBufferData()");
		addChild(recreateStoreGroup);

#define RECREATE_STORE_CASE(NAME, DESC, SPECLIST)																												\
		do {																																				\
			std::vector<DataStoreSpec> specs;																												\
			DataStoreSpecVecBuilder builder(specs);																											\
			builder SPECLIST;																																\
			recreateStoreGroup->addChild(new RecreateBufferDataStoreCase(m_context, #NAME, DESC, &specs[0], (int)specs.size(), VERIFY_AS_VERTEX_ARRAY));	\
		} while (deGetFalse())

		RECREATE_STORE_CASE(identical_1, "Recreate with identical parameters",
			<< DataStoreSpec(GL_ARRAY_BUFFER, GL_STATIC_DRAW, 996)
			<< DataStoreSpec(GL_ARRAY_BUFFER, GL_STATIC_DRAW, 996)
			<< DataStoreSpec(GL_ARRAY_BUFFER, GL_STATIC_DRAW, 996));

		RECREATE_STORE_CASE(identical_2, "Recreate with identical parameters",
			<< DataStoreSpec(GL_COPY_WRITE_BUFFER, GL_STATIC_DRAW, 72)
			<< DataStoreSpec(GL_COPY_WRITE_BUFFER, GL_STATIC_DRAW, 72)
			<< DataStoreSpec(GL_COPY_WRITE_BUFFER, GL_STATIC_DRAW, 72));

		RECREATE_STORE_CASE(different_target, "Recreate with different target",
			<< DataStoreSpec(GL_ARRAY_BUFFER,				GL_STATIC_DRAW, 504)
			<< DataStoreSpec(GL_COPY_READ_BUFFER,			GL_STATIC_DRAW, 504)
			<< DataStoreSpec(GL_COPY_WRITE_BUFFER,			GL_STATIC_DRAW, 504)
			<< DataStoreSpec(GL_ELEMENT_ARRAY_BUFFER,		GL_STATIC_DRAW, 504)
			<< DataStoreSpec(GL_PIXEL_PACK_BUFFER,			GL_STATIC_DRAW, 504)
			<< DataStoreSpec(GL_PIXEL_UNPACK_BUFFER,		GL_STATIC_DRAW, 504)
			<< DataStoreSpec(GL_TRANSFORM_FEEDBACK_BUFFER,	GL_STATIC_DRAW, 504)
			<< DataStoreSpec(GL_UNIFORM_BUFFER,				GL_STATIC_DRAW, 504)
			<< DataStoreSpec(GL_ARRAY_BUFFER,				GL_STATIC_DRAW, 504));

		RECREATE_STORE_CASE(different_usage, "Recreate with different usage",
			<< DataStoreSpec(GL_ARRAY_BUFFER,				GL_STREAM_DRAW,		1644)
			<< DataStoreSpec(GL_ARRAY_BUFFER,				GL_STREAM_COPY,		1644)
			<< DataStoreSpec(GL_ARRAY_BUFFER,				GL_STATIC_READ,		1644)
			<< DataStoreSpec(GL_ARRAY_BUFFER,				GL_STREAM_READ,		1644)
			<< DataStoreSpec(GL_ARRAY_BUFFER,				GL_DYNAMIC_COPY,	1644)
			<< DataStoreSpec(GL_ARRAY_BUFFER,				GL_STATIC_COPY,		1644)
			<< DataStoreSpec(GL_ARRAY_BUFFER,				GL_DYNAMIC_READ,	1644)
			<< DataStoreSpec(GL_ARRAY_BUFFER,				GL_DYNAMIC_DRAW,	1644)
			<< DataStoreSpec(GL_ARRAY_BUFFER,				GL_STATIC_DRAW,		1644)
			<< DataStoreSpec(GL_ARRAY_BUFFER,				GL_STREAM_DRAW,		1644));

		RECREATE_STORE_CASE(different_size, "Recreate with different size",
			<< DataStoreSpec(GL_ARRAY_BUFFER,				GL_STREAM_DRAW,		1024)
			<< DataStoreSpec(GL_ARRAY_BUFFER,				GL_STREAM_DRAW,		12)
			<< DataStoreSpec(GL_ARRAY_BUFFER,				GL_STREAM_DRAW,		3327)
			<< DataStoreSpec(GL_ARRAY_BUFFER,				GL_STREAM_DRAW,		92)
			<< DataStoreSpec(GL_ARRAY_BUFFER,				GL_STREAM_DRAW,		123795)
			<< DataStoreSpec(GL_ARRAY_BUFFER,				GL_STREAM_DRAW,		571));

#undef RECREATE_STORE_CASE

		// Random cases.
		{
			const int			numRandomCases		= 4;
			const int			numUploadsPerCase	= 10;
			const int			minSize				= 12;
			const int			maxSize				= 65536;
			const VerifyType	verify				= VERIFY_AS_VERTEX_ARRAY;
			de::Random			rnd					(23921);

			for (int caseNdx = 0; caseNdx < numRandomCases; caseNdx++)
			{
				vector<DataStoreSpec> specs(numUploadsPerCase);

				for (vector<DataStoreSpec>::iterator spec = specs.begin(); spec != specs.end(); spec++)
				{
					spec->target	= bufferTargets[rnd.getInt(0, DE_LENGTH_OF_ARRAY(bufferTargets)-1)];
					spec->usage		= usageHints[rnd.getInt(0, DE_LENGTH_OF_ARRAY(usageHints)-1)];
					spec->size		= rnd.getInt(minSize, maxSize);
				}

				recreateStoreGroup->addChild(new RecreateBufferDataStoreCase(m_context, (string("random_") + de::toString(caseNdx+1)).c_str(), "", &specs[0], (int)specs.size(), verify));
			}
		}
	}

	// .basic_subdata
	{
		tcu::TestCaseGroup* const basicGroup = new tcu::TestCaseGroup(m_testCtx, "basic_subdata", "Basic glBufferSubData() usage");
		addChild(basicGroup);

		for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(bufferTargets); targetNdx++)
		{
			for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usageHints); usageNdx++)
			{
				const deUint32		target	= bufferTargets[targetNdx];
				const deUint32		usage	= usageHints[usageNdx];
				const int			size	= 1020;
				const VerifyType	verify	= VERIFY_AS_VERTEX_ARRAY;
				const string		name	= string(getBufferTargetName(target)) + "_" + getUsageHintName(usage);

				basicGroup->addChild(new BasicBufferDataCase(m_context, name.c_str(), "", target, usage, size, verify));
			}
		}
	}

	// .partial_specify
	{
		tcu::TestCaseGroup* const partialSpecifyGroup = new tcu::TestCaseGroup(m_testCtx, "partial_specify", "Partial buffer data specification with glBufferSubData()");
		addChild(partialSpecifyGroup);

#define PARTIAL_SPECIFY_CASE(NAME, DESC, TARGET, USAGE, SIZE, RANGELIST)																									\
		do {																																								\
			std::vector<tcu::IVec2> ranges;																																	\
			RangeVecBuilder builder(ranges);																																\
			builder RANGELIST;																																				\
			partialSpecifyGroup->addChild(new SubDataToUndefinedCase(m_context, #NAME, DESC, TARGET, USAGE, SIZE, &ranges[0], (int)ranges.size(), VERIFY_AS_VERTEX_ARRAY));	\
		} while (deGetFalse())

		PARTIAL_SPECIFY_CASE(whole_1, "Whole buffer specification with single glBufferSubData()", GL_ARRAY_BUFFER, GL_STATIC_DRAW, 996,
			<< IVec2(0, 996));
		PARTIAL_SPECIFY_CASE(whole_2, "Whole buffer specification with two calls", GL_UNIFORM_BUFFER, GL_DYNAMIC_READ, 1728,
			<< IVec2(729, 999)
			<< IVec2(0, 729));
		PARTIAL_SPECIFY_CASE(whole_3, "Whole buffer specification with three calls", GL_TRANSFORM_FEEDBACK_BUFFER, GL_STREAM_COPY, 1944,
			<< IVec2(0, 421)
			<< IVec2(1421, 523)
			<< IVec2(421, 1000));
		PARTIAL_SPECIFY_CASE(whole_4, "Whole buffer specification with three calls", GL_TRANSFORM_FEEDBACK_BUFFER, GL_STREAM_COPY, 1200,
			<< IVec2(0, 500)
			<< IVec2(429, 200)
			<< IVec2(513, 687));

		PARTIAL_SPECIFY_CASE(low_1, "Low part of buffer specified with single call", GL_ELEMENT_ARRAY_BUFFER, GL_DYNAMIC_DRAW, 1000,
			<< IVec2(0, 513));
		PARTIAL_SPECIFY_CASE(low_2, "Low part of buffer specified with two calls", GL_COPY_READ_BUFFER, GL_DYNAMIC_COPY, 996,
			<< IVec2(0, 98)
			<< IVec2(98, 511));
		PARTIAL_SPECIFY_CASE(low_3, "Low part of buffer specified with two calls", GL_COPY_READ_BUFFER, GL_DYNAMIC_COPY, 1200,
			<< IVec2(0, 591)
			<< IVec2(371, 400));

		PARTIAL_SPECIFY_CASE(high_1, "High part of buffer specified with single call", GL_COPY_WRITE_BUFFER, GL_STATIC_COPY, 1000,
			<< IVec2(500, 500));
		PARTIAL_SPECIFY_CASE(high_2, "High part of buffer specified with two calls", GL_TRANSFORM_FEEDBACK_BUFFER, GL_STREAM_DRAW, 1200,
			<< IVec2(600, 123)
			<< IVec2(723, 477));
		PARTIAL_SPECIFY_CASE(high_3, "High part of buffer specified with two calls", GL_PIXEL_PACK_BUFFER, GL_STREAM_READ, 1200,
			<< IVec2(600, 200)
			<< IVec2(601, 599));

		PARTIAL_SPECIFY_CASE(middle_1, "Middle part of buffer specified with single call", GL_PIXEL_UNPACK_BUFFER, GL_STREAM_READ, 2500,
			<< IVec2(1000, 799));
		PARTIAL_SPECIFY_CASE(middle_2, "Middle part of buffer specified with two calls", GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW, 2500,
			<< IVec2(780, 220)
			<< IVec2(1000, 500));
		PARTIAL_SPECIFY_CASE(middle_3, "Middle part of buffer specified with two calls", GL_ARRAY_BUFFER, GL_STREAM_READ, 2500,
			<< IVec2(780, 321)
			<< IVec2(1000, 501));

#undef PARTIAL_SPECIFY_CASE
	}

	// .random
	{
		tcu::TestCaseGroup* const randomGroup = new tcu::TestCaseGroup(m_testCtx, "random", "Randomized buffer data cases");
		addChild(randomGroup);

		for (int i = 0; i < 10; i++)
			randomGroup->addChild(new RandomBufferWriteCase(m_context, de::toString(i).c_str(), "", deInt32Hash(i)));
	}
}

} // Functional
} // gles3
} // deqp
