/*-------------------------------------------------------------------------
 * 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 Vertex array and buffer unaligned access stress tests
 *//*--------------------------------------------------------------------*/

#include "es3sVertexArrayTests.hpp"
#include "glsVertexArrayTests.hpp"

#include <sstream>

using namespace deqp::gls;

namespace deqp
{
namespace gles3
{
namespace Stress
{
namespace
{


class SingleVertexArrayUsageGroup : public TestCaseGroup
{
public:
									SingleVertexArrayUsageGroup		(Context& context, Array::Usage usage);
	virtual							~SingleVertexArrayUsageGroup	(void);

	virtual void					init							(void);

private:
									SingleVertexArrayUsageGroup		(const SingleVertexArrayUsageGroup& other);
	SingleVertexArrayUsageGroup&	operator=						(const SingleVertexArrayUsageGroup& other);

	Array::Usage					m_usage;
};

SingleVertexArrayUsageGroup::SingleVertexArrayUsageGroup (Context& context, Array::Usage usage)
	: TestCaseGroup	(context, Array::usageTypeToString(usage).c_str(), Array::usageTypeToString(usage).c_str())
	, m_usage		(usage)
{
}

SingleVertexArrayUsageGroup::~SingleVertexArrayUsageGroup (void)
{
}

template<class T>
static std::string typeToString (T t)
{
	std::stringstream strm;
	strm << t;
	return strm.str();
}

void SingleVertexArrayUsageGroup::init (void)
{
	int					counts[]		= {1, 256};
	int					strides[]		= {0, -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.
	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_FIXED, Array::INPUTTYPE_SHORT, Array::INPUTTYPE_BYTE};

	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
	{
		for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
		{
			for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
			{
				const int			stride	= (strides[strideNdx] < 0 ? Array::inputTypeSize(inputTypes[inputTypeNdx]) * 2 : strides[strideNdx]);
				const bool			aligned	= (stride % Array::inputTypeSize(inputTypes[inputTypeNdx])) == 0;
				const std::string	name	= "stride" + typeToString(stride) + "_" + Array::inputTypeToString(inputTypes[inputTypeNdx]) + "_quads" + typeToString(counts[countNdx]);

				MultiVertexArrayTest::Spec::ArraySpec arraySpec(inputTypes[inputTypeNdx],
																Array::OUTPUTTYPE_VEC2,
																Array::STORAGE_BUFFER,
																m_usage,
																2,
																0,
																stride,
																false,
																GLValue::getMinValue(inputTypes[inputTypeNdx]),
																GLValue::getMaxValue(inputTypes[inputTypeNdx]));

				MultiVertexArrayTest::Spec spec;
				spec.primitive	= Array::PRIMITIVE_TRIANGLES;
				spec.drawCount	= counts[countNdx];
				spec.first		= 0;
				spec.arrays.push_back(arraySpec);

				if (!aligned)
					addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
			}
		}
	}
}

class SingleVertexArrayUsageTests : public TestCaseGroup
{
public:
									SingleVertexArrayUsageTests		(Context& context);
	virtual							~SingleVertexArrayUsageTests	(void);

	virtual void					init							(void);

private:
									SingleVertexArrayUsageTests		(const SingleVertexArrayUsageTests& other);
	SingleVertexArrayUsageTests&	operator=						(const SingleVertexArrayUsageTests& other);
};

SingleVertexArrayUsageTests::SingleVertexArrayUsageTests (Context& context)
	: TestCaseGroup(context, "usages", "Single vertex atribute, usage")
{
}

SingleVertexArrayUsageTests::~SingleVertexArrayUsageTests (void)
{
}

void SingleVertexArrayUsageTests::init (void)
{
	// Test usage
	Array::Usage		usages[]		= { Array::USAGE_STATIC_DRAW, Array::USAGE_STREAM_DRAW, Array::USAGE_DYNAMIC_DRAW, Array::USAGE_STATIC_COPY, Array::USAGE_STREAM_COPY, Array::USAGE_DYNAMIC_COPY, Array::USAGE_STATIC_READ, Array::USAGE_STREAM_READ, Array::USAGE_DYNAMIC_READ };
	for (int usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usages); usageNdx++)
	{
		addChild(new SingleVertexArrayUsageGroup(m_context, usages[usageNdx]));
	}
}

class SingleVertexArrayStrideGroup : public TestCaseGroup
{
public:
									SingleVertexArrayStrideGroup	(Context& context, Array::InputType type);
	virtual							~SingleVertexArrayStrideGroup	(void);

	virtual void					init							(void);

private:
									SingleVertexArrayStrideGroup	(const SingleVertexArrayStrideGroup& other);
	SingleVertexArrayStrideGroup&	operator=						(const SingleVertexArrayStrideGroup& other);

	Array::InputType				m_type;
};

SingleVertexArrayStrideGroup::SingleVertexArrayStrideGroup (Context& context, Array::InputType type)
	: TestCaseGroup	(context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
	, m_type		(type)
{
}

SingleVertexArrayStrideGroup::~SingleVertexArrayStrideGroup (void)
{
}

void SingleVertexArrayStrideGroup::init (void)
{
	Array::Storage		storages[]		= {Array::STORAGE_USER, Array::STORAGE_BUFFER};
	int					counts[]		= {1, 256};
	int					strides[]		= {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.

	for (int storageNdx = 0; storageNdx < DE_LENGTH_OF_ARRAY(storages); storageNdx++)
	{
		for (int componentCount = 2; componentCount < 5; componentCount++)
		{
			for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
			{
				for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
				{
					const bool	packed			= m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10;
					const int	stride			= (strides[strideNdx] < 0) ? ((packed) ? (16) : (Array::inputTypeSize(m_type) * componentCount)) : (strides[strideNdx]);
					const int	alignment		= (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type));
					const bool	bufferUnaligned	= (storages[storageNdx] == Array::STORAGE_BUFFER) && (stride % alignment) != 0;

					std::string name = Array::storageToString(storages[storageNdx]) + "_stride" + typeToString(stride) + "_components" + typeToString(componentCount) + "_quads" + typeToString(counts[countNdx]);

					if((m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10) && componentCount != 4)
						continue;

					MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
																	Array::OUTPUTTYPE_VEC4,
																	storages[storageNdx],
																	Array::USAGE_DYNAMIC_DRAW,
																	componentCount,
																	0,
																	stride,
																	false,
																	GLValue::getMinValue(m_type),
																	GLValue::getMaxValue(m_type));

					MultiVertexArrayTest::Spec spec;
					spec.primitive	= Array::PRIMITIVE_TRIANGLES;
					spec.drawCount	= counts[countNdx];
					spec.first		= 0;
					spec.arrays.push_back(arraySpec);

					if (bufferUnaligned)
						addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
				}
			}
		}
	}
}

class SingleVertexArrayStrideTests : public TestCaseGroup
{
public:
									SingleVertexArrayStrideTests	(Context& context);
	virtual							~SingleVertexArrayStrideTests	(void);

	virtual void					init							(void);

private:
									SingleVertexArrayStrideTests	(const SingleVertexArrayStrideTests& other);
	SingleVertexArrayStrideTests&	operator=						(const SingleVertexArrayStrideTests& other);
};

SingleVertexArrayStrideTests::SingleVertexArrayStrideTests (Context& context)
	: TestCaseGroup(context, "strides", "Single stride vertex atribute")
{
}

SingleVertexArrayStrideTests::~SingleVertexArrayStrideTests (void)
{
}

void SingleVertexArrayStrideTests::init (void)
{
	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_SHORT, /*Array::INPUTTYPE_UNSIGNED_SHORT, Array::INPUTTYPE_UNSIGNED_BYTE,*/ Array::INPUTTYPE_FIXED, Array::INPUTTYPE_INT_2_10_10_10 };

	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
	{
		addChild(new SingleVertexArrayStrideGroup(m_context, inputTypes[inputTypeNdx]));
	}
}

class SingleVertexArrayFirstGroup : public TestCaseGroup
{
public:
									SingleVertexArrayFirstGroup	(Context& context, Array::InputType type);
	virtual							~SingleVertexArrayFirstGroup	(void);

	virtual void					init							(void);

private:
									SingleVertexArrayFirstGroup	(const SingleVertexArrayFirstGroup& other);
	SingleVertexArrayFirstGroup&	operator=						(const SingleVertexArrayFirstGroup& other);
	Array::InputType				m_type;
};

SingleVertexArrayFirstGroup::SingleVertexArrayFirstGroup (Context& context, Array::InputType type)
	: TestCaseGroup	(context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
	, m_type		(type)
{
}

SingleVertexArrayFirstGroup::~SingleVertexArrayFirstGroup (void)
{
}

void SingleVertexArrayFirstGroup::init (void)
{
	int					counts[]		= {5, 256};
	int					firsts[]		= {6, 24};
	int					offsets[]		= {1, 17};
	int					strides[]		= {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.

	for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
	{
		for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
		{
			for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
			{
				for (int firstNdx = 0; firstNdx < DE_LENGTH_OF_ARRAY(firsts); firstNdx++)
				{
					const bool	packed			= m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10;
					const int	componentCount	= (packed) ? (4) : (2);
					const int	stride			= (strides[strideNdx] < 0) ? ((packed) ? (8) : (Array::inputTypeSize(m_type) * componentCount)) : (strides[strideNdx]);
					const int	alignment		= (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type));
					const bool	aligned			= ((stride % alignment) == 0) && ((offsets[offsetNdx] % alignment) == 0);
					std::string name			= "first" + typeToString(firsts[firstNdx]) + "_offset" + typeToString(offsets[offsetNdx]) + "_stride" + typeToString(stride) + "_quads" + typeToString(counts[countNdx]);

					MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
																	Array::OUTPUTTYPE_VEC2,
																	Array::STORAGE_BUFFER,
																	Array::USAGE_DYNAMIC_DRAW,
																	componentCount,
																	offsets[offsetNdx],
																	stride,
																	false,
																	GLValue::getMinValue(m_type),
																	GLValue::getMaxValue(m_type));

					MultiVertexArrayTest::Spec spec;
					spec.primitive	= Array::PRIMITIVE_TRIANGLES;
					spec.drawCount	= counts[countNdx];
					spec.first		= firsts[firstNdx];
					spec.arrays.push_back(arraySpec);

					if (!aligned)
						addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
				}
			}
		}
	}
}

class SingleVertexArrayFirstTests : public TestCaseGroup
{
public:
									SingleVertexArrayFirstTests	(Context& context);
	virtual							~SingleVertexArrayFirstTests	(void);

	virtual void					init							(void);

private:
									SingleVertexArrayFirstTests	(const SingleVertexArrayFirstTests& other);
	SingleVertexArrayFirstTests&	operator=						(const SingleVertexArrayFirstTests& other);
};

SingleVertexArrayFirstTests::SingleVertexArrayFirstTests (Context& context)
	: TestCaseGroup(context, "first", "Single vertex attribute, different first values to drawArrays")
{
}

SingleVertexArrayFirstTests::~SingleVertexArrayFirstTests (void)
{
}

void SingleVertexArrayFirstTests::init (void)
{
	// Test offset with different input types, component counts and storage, Usage(?)
	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_INT_2_10_10_10 };

	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
	{
		addChild(new SingleVertexArrayFirstGroup(m_context, inputTypes[inputTypeNdx]));
	}
}

class SingleVertexArrayOffsetGroup : public TestCaseGroup
{
public:
									SingleVertexArrayOffsetGroup	(Context& context, Array::InputType type);
	virtual							~SingleVertexArrayOffsetGroup	(void);

	virtual void					init							(void);

private:
									SingleVertexArrayOffsetGroup	(const SingleVertexArrayOffsetGroup& other);
	SingleVertexArrayOffsetGroup&	operator=						(const SingleVertexArrayOffsetGroup& other);
	Array::InputType				m_type;
};

SingleVertexArrayOffsetGroup::SingleVertexArrayOffsetGroup (Context& context, Array::InputType type)
	: TestCaseGroup	(context, Array::inputTypeToString(type).c_str(), Array::inputTypeToString(type).c_str())
	, m_type		(type)
{
}

SingleVertexArrayOffsetGroup::~SingleVertexArrayOffsetGroup (void)
{
}

void SingleVertexArrayOffsetGroup::init (void)
{
	int					counts[]		= {1, 256};
	int					offsets[]		= {1, 4, 17, 32};
	int					strides[]		= {/*0,*/ -1, 17, 32}; // Tread negative value as sizeof input. Same as 0, but done outside of GL.

	for (int offsetNdx = 0; offsetNdx < DE_LENGTH_OF_ARRAY(offsets); offsetNdx++)
	{
		for (int countNdx = 0; countNdx < DE_LENGTH_OF_ARRAY(counts); countNdx++)
		{
			for (int strideNdx = 0; strideNdx < DE_LENGTH_OF_ARRAY(strides); strideNdx++)
			{
				const bool			packed			= m_type == Array::INPUTTYPE_UNSIGNED_INT_2_10_10_10 || m_type == Array::INPUTTYPE_INT_2_10_10_10;
				const int			componentCount	= (packed) ? (4) : (2);
				const int			stride			= (strides[strideNdx] < 0 ? Array::inputTypeSize(m_type) * componentCount : strides[strideNdx]);
				const int			alignment		= (packed) ? (Array::inputTypeSize(m_type) * componentCount) : (Array::inputTypeSize(m_type));
				const bool			aligned			= ((stride % alignment) == 0) && ((offsets[offsetNdx] % alignment) == 0);
				const std::string	name			= "offset" + typeToString(offsets[offsetNdx]) + "_stride" + typeToString(strides[strideNdx]) + "_quads" + typeToString(counts[countNdx]);

				MultiVertexArrayTest::Spec::ArraySpec arraySpec(m_type,
																Array::OUTPUTTYPE_VEC2,
																Array::STORAGE_BUFFER,
																Array::USAGE_DYNAMIC_DRAW,
																componentCount,
																offsets[offsetNdx],
																stride,
																false,
																GLValue::getMinValue(m_type),
																GLValue::getMaxValue(m_type));

				MultiVertexArrayTest::Spec spec;
				spec.primitive	= Array::PRIMITIVE_TRIANGLES;
				spec.drawCount	= counts[countNdx];
				spec.first		= 0;
				spec.arrays.push_back(arraySpec);

				if (!aligned)
					addChild(new MultiVertexArrayTest(m_testCtx, m_context.getRenderContext(), spec, name.c_str(), name.c_str()));
			}
		}
	}
}

class SingleVertexArrayOffsetTests : public TestCaseGroup
{
public:
									SingleVertexArrayOffsetTests	(Context& context);
	virtual							~SingleVertexArrayOffsetTests	(void);

	virtual void					init							(void);

private:
									SingleVertexArrayOffsetTests	(const SingleVertexArrayOffsetTests& other);
	SingleVertexArrayOffsetTests&	operator=						(const SingleVertexArrayOffsetTests& other);
};

SingleVertexArrayOffsetTests::SingleVertexArrayOffsetTests (Context& context)
	: TestCaseGroup(context, "offset", "Single vertex atribute offset element")
{
}

SingleVertexArrayOffsetTests::~SingleVertexArrayOffsetTests (void)
{
}

void SingleVertexArrayOffsetTests::init (void)
{
	// Test offset with different input types, component counts and storage, Usage(?)
	Array::InputType	inputTypes[]	= {Array::INPUTTYPE_FLOAT, Array::INPUTTYPE_INT_2_10_10_10 };

	for (int inputTypeNdx = 0; inputTypeNdx < DE_LENGTH_OF_ARRAY(inputTypes); inputTypeNdx++)
	{
		addChild(new SingleVertexArrayOffsetGroup(m_context, inputTypes[inputTypeNdx]));
	}
}

} // anonymous

VertexArrayTests::VertexArrayTests (Context& context)
	: TestCaseGroup(context, "vertex_arrays", "Vertex array and array tests")
{
}

VertexArrayTests::~VertexArrayTests (void)
{
}

void VertexArrayTests::init (void)
{
	tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "single_attribute", "Single attribute");
	addChild(group);

	// .single_attribute
	{
		group->addChild(new SingleVertexArrayStrideTests(m_context));
		group->addChild(new SingleVertexArrayUsageTests(m_context));
		group->addChild(new SingleVertexArrayOffsetTests(m_context));
		group->addChild(new SingleVertexArrayFirstTests(m_context));
	}
}

} // Stress
} // gles3
} // deqp
