/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 2.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 Draw call batching performance tests
 *//*--------------------------------------------------------------------*/

#include "es2pDrawCallBatchingTests.hpp"

#include "gluShaderProgram.hpp"
#include "gluRenderContext.hpp"

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

#include "tcuTestLog.hpp"

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

#include "deFile.h"
#include "deString.h"
#include "deClock.h"
#include "deThread.h"

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

using tcu::TestLog;

using namespace glw;

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

namespace deqp
{
namespace gles2
{
namespace Performance
{

namespace
{
const int CALIBRATION_SAMPLE_COUNT = 34;

class DrawCallBatchingTest : public tcu::TestCase
{
public:
	struct TestSpec
	{
		bool	useStaticBuffer;
		int		staticAttributeCount;

		bool	useDynamicBuffer;
		int		dynamicAttributeCount;

		int		triangleCount;
		int		drawCallCount;

		bool	useDrawElements;
		bool	useIndexBuffer;
		bool	dynamicIndices;
	};

					DrawCallBatchingTest	(Context& context, const char* name, const char* description, const TestSpec& spec);
					~DrawCallBatchingTest	(void);

	void			init					(void);
	void			deinit					(void);
	IterateResult	iterate					(void);

private:
	enum State
	{
		STATE_LOG_INFO = 0,
		STATE_WARMUP_BATCHED,
		STATE_WARMUP_UNBATCHED,
		STATE_CALC_CALIBRATION,
		STATE_SAMPLE
	};

	State						m_state;

	glu::RenderContext&			m_renderCtx;
	de::Random					m_rnd;
	int							m_sampleIteration;

	int							m_unbatchedSampleCount;
	int							m_batchedSampleCount;

	TestSpec					m_spec;

	glu::ShaderProgram*			m_program;

	vector<deUint8>				m_dynamicIndexData;
	vector<deUint8>				m_staticIndexData;

	vector<GLuint>				m_unbatchedDynamicIndexBuffers;
	GLuint						m_batchedDynamicIndexBuffer;

	GLuint						m_unbatchedStaticIndexBuffer;
	GLuint						m_batchedStaticIndexBuffer;

	vector<vector<deInt8> >		m_staticAttributeDatas;
	vector<vector<deInt8> >		m_dynamicAttributeDatas;

	vector<GLuint>				m_batchedStaticBuffers;
	vector<GLuint>				m_unbatchedStaticBuffers;

	vector<GLuint>				m_batchedDynamicBuffers;
	vector<vector<GLuint> >		m_unbatchedDynamicBuffers;

	vector<deUint64>			m_unbatchedSamplesUs;
	vector<deUint64>			m_batchedSamplesUs;

	void						logTestInfo				(void);

	deUint64					renderUnbatched			(void);
	deUint64					renderBatched			(void);

	void						createIndexData			(void);
	void						createIndexBuffer		(void);

	void						createShader			(void);
	void						createAttributeDatas	(void);
	void						createArrayBuffers		(void);
};

DrawCallBatchingTest::DrawCallBatchingTest (Context& context, const char* name, const char* description, const TestSpec& spec)
	: tcu::TestCase					(context.getTestContext(), tcu::NODETYPE_PERFORMANCE, name, description)
	, m_state						(STATE_LOG_INFO)
	, m_renderCtx					(context.getRenderContext())
	, m_rnd							(deStringHash(name))
	, m_sampleIteration				(0)
	, m_unbatchedSampleCount		(CALIBRATION_SAMPLE_COUNT)
	, m_batchedSampleCount			(CALIBRATION_SAMPLE_COUNT)
	, m_spec						(spec)
	, m_program						(NULL)
	, m_batchedDynamicIndexBuffer	(0)
	, m_unbatchedStaticIndexBuffer	(0)
	, m_batchedStaticIndexBuffer	(0)
{
}

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

void DrawCallBatchingTest::createIndexData (void)
{
	if (m_spec.dynamicIndices)
	{
		for (int drawNdx = 0; drawNdx < m_spec.drawCallCount; drawNdx++)
		{
			for (int triangleNdx = 0; triangleNdx < m_spec.triangleCount; triangleNdx++)
			{
				m_dynamicIndexData.push_back(deUint8(triangleNdx * 3));
				m_dynamicIndexData.push_back(deUint8(triangleNdx * 3 + 1));
				m_dynamicIndexData.push_back(deUint8(triangleNdx * 3 + 2));
			}
		}
	}
	else
	{
		for (int drawNdx = 0; drawNdx < m_spec.drawCallCount; drawNdx++)
		{
			for (int triangleNdx = 0; triangleNdx < m_spec.triangleCount; triangleNdx++)
			{
				m_staticIndexData.push_back(deUint8(triangleNdx * 3));
				m_staticIndexData.push_back(deUint8(triangleNdx * 3 + 1));
				m_staticIndexData.push_back(deUint8(triangleNdx * 3 + 2));
			}
		}
	}
}

void DrawCallBatchingTest::createShader (void)
{
	std::ostringstream		vertexShader;
	std::ostringstream		fragmentShader;

	for (int attributeNdx = 0; attributeNdx < m_spec.staticAttributeCount; attributeNdx++)
		vertexShader << "attribute mediump vec4 a_static" << attributeNdx << ";\n";

	if (m_spec.staticAttributeCount > 0 && m_spec.dynamicAttributeCount > 0)
		vertexShader << "\n";

	for (int attributeNdx = 0; attributeNdx < m_spec.dynamicAttributeCount; attributeNdx++)
		vertexShader << "attribute mediump vec4 a_dyn" << attributeNdx << ";\n";

	vertexShader
	<< "\n"
	<< "varying mediump vec4 v_color;\n"
	<< "\n"
	<< "void main (void)\n"
	<< "{\n";

	vertexShader << "\tv_color = ";

	bool first = true;

	for (int attributeNdx = 0; attributeNdx < m_spec.staticAttributeCount; attributeNdx++)
	{
		if (!first)
			vertexShader << " + ";
		first = false;

		vertexShader << "a_static" << attributeNdx;
	}

	for (int attributeNdx = 0; attributeNdx < m_spec.dynamicAttributeCount; attributeNdx++)
	{
		if (!first)
			vertexShader << " + ";
		first = false;

		vertexShader << "a_dyn" << attributeNdx;
	}

	vertexShader << ";\n";

	if (m_spec.dynamicAttributeCount > 0)
		vertexShader << "\tgl_Position = a_dyn0;\n";
	else
		vertexShader << "\tgl_Position = a_static0;\n";

	vertexShader
	<< "}";

	fragmentShader
	<< "varying mediump vec4 v_color;\n"
	<< "\n"
	<< "void main(void)\n"
	<< "{\n"
	<< "\tgl_FragColor = v_color;\n"
	<< "}\n";

	m_program = new glu::ShaderProgram(m_renderCtx, glu::ProgramSources() << glu::VertexSource(vertexShader.str()) << glu::FragmentSource(fragmentShader.str()));

	m_testCtx.getLog() << (*m_program);
	TCU_CHECK(m_program->isOk());
}

void DrawCallBatchingTest::createAttributeDatas (void)
{
	// Generate data for static attributes
	for (int attribute = 0; attribute < m_spec.staticAttributeCount; attribute++)
	{
		vector<deInt8> data;

		if (m_spec.dynamicAttributeCount == 0 && attribute == 0)
		{
			data.reserve(4 * 3 * m_spec.triangleCount * m_spec.drawCallCount);

			for (int i = 0; i < m_spec.triangleCount * m_spec.drawCallCount; i++)
			{
				int sign = (m_spec.triangleCount % 2 == 1 || i % 2 == 0 ? 1 : -1);

				data.push_back(deInt8(-127 * sign));
				data.push_back(deInt8(-127 * sign));
				data.push_back(0);
				data.push_back(127);

				data.push_back(deInt8(127 * sign));
				data.push_back(deInt8(-127 * sign));
				data.push_back(0);
				data.push_back(127);

				data.push_back(deInt8(127 * sign));
				data.push_back(deInt8(127 * sign));
				data.push_back(0);
				data.push_back(127);
			}
		}
		else
		{
			data.reserve(4 * 3 * m_spec.triangleCount * m_spec.drawCallCount);

			for (int i = 0; i < 4 * 3 * m_spec.triangleCount * m_spec.drawCallCount; i++)
				data.push_back((deInt8)m_rnd.getUint32());
		}

		m_staticAttributeDatas.push_back(data);
	}

	// Generate data for dynamic attributes
	for (int attribute = 0; attribute < m_spec.dynamicAttributeCount; attribute++)
	{
		vector<deInt8> data;

		if (attribute == 0)
		{
			data.reserve(4 * 3 * m_spec.triangleCount * m_spec.drawCallCount);

			for (int i = 0; i < m_spec.triangleCount * m_spec.drawCallCount; i++)
			{
				int sign = (i % 2 == 0 ? 1 : -1);

				data.push_back(deInt8(-127 * sign));
				data.push_back(deInt8(-127 * sign));
				data.push_back(0);
				data.push_back(127);

				data.push_back(deInt8(127 * sign));
				data.push_back(deInt8(-127 * sign));
				data.push_back(0);
				data.push_back(127);

				data.push_back(deInt8(127 * sign));
				data.push_back(deInt8(127 * sign));
				data.push_back(0);
				data.push_back(127);
			}
		}
		else
		{
			data.reserve(4 * 3 * m_spec.triangleCount * m_spec.drawCallCount);

			for (int i = 0; i < 4 * 3 * m_spec.triangleCount * m_spec.drawCallCount; i++)
				data.push_back((deInt8)m_rnd.getUint32());
		}

		m_dynamicAttributeDatas.push_back(data);
	}
}

void DrawCallBatchingTest::createArrayBuffers (void)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	if (m_spec.useStaticBuffer)
	{
		// Upload static attributes for batched
		for (int attribute = 0; attribute < m_spec.staticAttributeCount; attribute++)
		{
			GLuint buffer;

			gl.genBuffers(1, &buffer);
			gl.bindBuffer(GL_ARRAY_BUFFER, buffer);
			gl.bufferData(GL_ARRAY_BUFFER, 4 * 3 * m_spec.triangleCount * m_spec.drawCallCount, &(m_staticAttributeDatas[attribute][0]), GL_STATIC_DRAW);
			gl.bindBuffer(GL_ARRAY_BUFFER, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Creating static buffer failed");

			m_batchedStaticBuffers.push_back(buffer);
		}

		// Upload static attributes for unbatched
		for (int attribute = 0; attribute < m_spec.staticAttributeCount; attribute++)
		{
			GLuint buffer;

			gl.genBuffers(1, &buffer);
			gl.bindBuffer(GL_ARRAY_BUFFER, buffer);
			gl.bufferData(GL_ARRAY_BUFFER, 4 * 3 * m_spec.triangleCount, &(m_staticAttributeDatas[attribute][0]), GL_STATIC_DRAW);
			gl.bindBuffer(GL_ARRAY_BUFFER, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Creating static buffer failed");

			m_unbatchedStaticBuffers.push_back(buffer);
		}
	}

	if (m_spec.useDynamicBuffer)
	{
		// Upload dynamic attributes for batched
		for (int attribute = 0; attribute < m_spec.dynamicAttributeCount; attribute++)
		{
			GLuint buffer;

			gl.genBuffers(1, &buffer);
			gl.bindBuffer(GL_ARRAY_BUFFER, buffer);
			gl.bufferData(GL_ARRAY_BUFFER, 4 * 3 * m_spec.triangleCount * m_spec.drawCallCount, &(m_dynamicAttributeDatas[attribute][0]), GL_STATIC_DRAW);
			gl.bindBuffer(GL_ARRAY_BUFFER, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Creating dynamic buffer failed");

			m_batchedDynamicBuffers.push_back(buffer);
		}

		// Upload dynamic attributes for unbatched
		for (int attribute = 0; attribute < m_spec.dynamicAttributeCount; attribute++)
		{
			vector<GLuint> buffers;

			for (int drawNdx = 0; drawNdx < m_spec.drawCallCount; drawNdx++)
			{
				GLuint buffer;

				gl.genBuffers(1, &buffer);
				gl.bindBuffer(GL_ARRAY_BUFFER, buffer);
				gl.bufferData(GL_ARRAY_BUFFER, 4 * 3 * m_spec.triangleCount * m_spec.drawCallCount, &(m_dynamicAttributeDatas[attribute][0]), GL_STATIC_DRAW);
				gl.bindBuffer(GL_ARRAY_BUFFER, 0);
				GLU_EXPECT_NO_ERROR(gl.getError(), "Creating dynamic buffer failed");

				buffers.push_back(buffer);
			}

			m_unbatchedDynamicBuffers.push_back(buffers);
		}
	}
}

void DrawCallBatchingTest::createIndexBuffer (void)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	if (m_spec.dynamicIndices)
	{
		for (int drawNdx = 0; drawNdx < m_spec.drawCallCount; drawNdx++)
		{
			GLuint buffer;

			gl.genBuffers(1, &buffer);
			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
			gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * m_spec.triangleCount, &(m_dynamicIndexData[drawNdx * m_spec.triangleCount * 3]), GL_STATIC_DRAW);
			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Creating dynamic index buffer failed");

			m_unbatchedDynamicIndexBuffers.push_back(buffer);
		}

		{
			GLuint buffer;

			gl.genBuffers(1, &buffer);
			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
			gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * m_spec.triangleCount * m_spec.drawCallCount, &(m_dynamicIndexData[0]), GL_STATIC_DRAW);
			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Creating dynamic index buffer failed");

			m_batchedDynamicIndexBuffer = buffer;
		}
	}
	else
	{
		{
			GLuint buffer;

			gl.genBuffers(1, &buffer);
			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
			gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * m_spec.triangleCount * m_spec.drawCallCount, &(m_staticIndexData[0]), GL_STATIC_DRAW);
			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Creating dynamic index buffer failed");

			m_batchedStaticIndexBuffer = buffer;
		}

		{
			GLuint buffer;

			gl.genBuffers(1, &buffer);
			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
			gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * m_spec.triangleCount, &(m_staticIndexData[0]), GL_STATIC_DRAW);
			gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
			GLU_EXPECT_NO_ERROR(gl.getError(), "Creating dynamic index buffer failed");

			m_unbatchedStaticIndexBuffer = buffer;
		}
	}
}

void DrawCallBatchingTest::init (void)
{
	createShader();
	createAttributeDatas();
	createArrayBuffers();

	if (m_spec.useDrawElements)
	{
		createIndexData();

		if (m_spec.useIndexBuffer)
			createIndexBuffer();
	}
}

void DrawCallBatchingTest::deinit (void)
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	delete m_program;
	m_program = NULL;

	m_dynamicIndexData	= vector<deUint8>();
	m_staticIndexData	= vector<deUint8>();

	if (!m_unbatchedDynamicIndexBuffers.empty())
	{
		gl.deleteBuffers((GLsizei)m_unbatchedDynamicIndexBuffers.size(), &(m_unbatchedDynamicIndexBuffers[0]));
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers()");

		m_unbatchedDynamicIndexBuffers = vector<GLuint>();
	}

	if (m_batchedDynamicIndexBuffer)
	{
		gl.deleteBuffers((GLsizei)1, &m_batchedDynamicIndexBuffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers()");

		m_batchedDynamicIndexBuffer = 0;
	}

	if (m_unbatchedStaticIndexBuffer)
	{
		gl.deleteBuffers((GLsizei)1, &m_unbatchedStaticIndexBuffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers()");

		m_unbatchedStaticIndexBuffer = 0;
	}

	if (m_batchedStaticIndexBuffer)
	{
		gl.deleteBuffers((GLsizei)1, &m_batchedStaticIndexBuffer);
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers()");

		m_batchedStaticIndexBuffer = 0;
	}

	m_staticAttributeDatas	= vector<vector<deInt8> >();
	m_dynamicAttributeDatas	= vector<vector<deInt8> >();

	if (!m_batchedStaticBuffers.empty())
	{
		gl.deleteBuffers((GLsizei)m_batchedStaticBuffers.size(), &(m_batchedStaticBuffers[0]));
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers()");

		m_batchedStaticBuffers = vector<GLuint>();
	}

	if (!m_unbatchedStaticBuffers.empty())
	{
		gl.deleteBuffers((GLsizei)m_unbatchedStaticBuffers.size(), &(m_unbatchedStaticBuffers[0]));
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers()");

		m_unbatchedStaticBuffers = vector<GLuint>();
	}

	if (!m_batchedDynamicBuffers.empty())
	{
		gl.deleteBuffers((GLsizei)m_batchedDynamicBuffers.size(), &(m_batchedDynamicBuffers[0]));
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers()");

		m_batchedDynamicBuffers = vector<GLuint>();
	}

	for (int i = 0; i < (int)m_unbatchedDynamicBuffers.size(); i++)
	{
		gl.deleteBuffers((GLsizei)m_unbatchedDynamicBuffers[i].size(), &(m_unbatchedDynamicBuffers[i][0]));
		GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers()");
	}

	m_unbatchedDynamicBuffers = vector<vector<GLuint> >();

	m_unbatchedSamplesUs	= vector<deUint64>();
	m_batchedSamplesUs		= vector<deUint64>();
}

deUint64 DrawCallBatchingTest::renderUnbatched (void)
{
	const glw::Functions&	gl		= m_renderCtx.getFunctions();
	deUint64				beginUs	= 0;
	deUint64				endUs	= 0;
	vector<GLint>			dynamicAttributeLocations;

	gl.viewport(0, 0, 32, 32);
	gl.useProgram(m_program->getProgram());

	// Setup static buffers
	for (int attribNdx = 0; attribNdx < m_spec.staticAttributeCount; attribNdx++)
	{
		GLint location = gl.getAttribLocation(m_program->getProgram(), ("a_static" + de::toString(attribNdx)).c_str());

		gl.enableVertexAttribArray(location);

		if (m_spec.useStaticBuffer)
		{
			gl.bindBuffer(GL_ARRAY_BUFFER, m_unbatchedStaticBuffers[attribNdx]);
			gl.vertexAttribPointer(location, 4, GL_BYTE, GL_TRUE, 0, NULL);
			gl.bindBuffer(GL_ARRAY_BUFFER, 0);
		}
		else
			gl.vertexAttribPointer(location, 4, GL_BYTE, GL_TRUE, 0, &(m_staticAttributeDatas[attribNdx][0]));
	}

	// Get locations of dynamic attributes
	for (int attribNdx = 0; attribNdx < m_spec.dynamicAttributeCount; attribNdx++)
	{
		GLint location = gl.getAttribLocation(m_program->getProgram(), ("a_dyn" + de::toString(attribNdx)).c_str());

		gl.enableVertexAttribArray(location);
		dynamicAttributeLocations.push_back(location);
	}

	if (m_spec.useDrawElements && m_spec.useIndexBuffer && !m_spec.dynamicIndices)
		gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_unbatchedStaticIndexBuffer);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup initial state for rendering.");

	gl.finish();

	beginUs = deGetMicroseconds();

	for (int drawNdx = 0; drawNdx < m_spec.drawCallCount; drawNdx++)
	{
		for (int attribNdx = 0; attribNdx < m_spec.dynamicAttributeCount; attribNdx++)
		{
			if (m_spec.useDynamicBuffer)
			{
				gl.bindBuffer(GL_ARRAY_BUFFER, m_unbatchedDynamicBuffers[attribNdx][drawNdx]);
				gl.vertexAttribPointer(dynamicAttributeLocations[attribNdx], 4, GL_BYTE, GL_TRUE, 0, NULL);
				gl.bindBuffer(GL_ARRAY_BUFFER, 0);
			}
			else
				gl.vertexAttribPointer(dynamicAttributeLocations[attribNdx], 4, GL_BYTE, GL_TRUE, 0, &(m_dynamicAttributeDatas[attribNdx][m_spec.triangleCount * 3 * drawNdx * 4]));
		}

		if (m_spec.useDrawElements)
		{
			if (m_spec.useIndexBuffer)
			{
				if (m_spec.dynamicIndices)
				{
					gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_unbatchedDynamicIndexBuffers[drawNdx]);
					gl.drawElements(GL_TRIANGLES, m_spec.triangleCount * 3, GL_UNSIGNED_BYTE, NULL);
					gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
				}
				else
					gl.drawElements(GL_TRIANGLES, m_spec.triangleCount * 3, GL_UNSIGNED_BYTE, NULL);
			}
			else
			{
				if (m_spec.dynamicIndices)
					gl.drawElements(GL_TRIANGLES, m_spec.triangleCount * 3, GL_UNSIGNED_BYTE, &(m_dynamicIndexData[drawNdx * m_spec.triangleCount * 3]));
				else
					gl.drawElements(GL_TRIANGLES, m_spec.triangleCount * 3, GL_UNSIGNED_BYTE, &(m_staticIndexData[0]));
			}
		}
		else
			gl.drawArrays(GL_TRIANGLES, 0, 3 * m_spec.triangleCount);
	}

	gl.finish();

	endUs = deGetMicroseconds();

	GLU_EXPECT_NO_ERROR(gl.getError(), "Unbatched rendering failed");

	gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	for (int attribNdx = 0; attribNdx < m_spec.staticAttributeCount; attribNdx++)
	{
		GLint location = gl.getAttribLocation(m_program->getProgram(), ("a_static" + de::toString(attribNdx)).c_str());
		gl.disableVertexAttribArray(location);
	}

	for (int attribNdx = 0; attribNdx < m_spec.dynamicAttributeCount; attribNdx++)
		gl.disableVertexAttribArray(dynamicAttributeLocations[attribNdx]);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to reset state after unbatched rendering");

	return endUs - beginUs;
}

deUint64 DrawCallBatchingTest::renderBatched (void)
{
	const glw::Functions&	gl		= m_renderCtx.getFunctions();
	deUint64				beginUs	= 0;
	deUint64				endUs	= 0;
	vector<GLint>			dynamicAttributeLocations;

	gl.viewport(0, 0, 32, 32);
	gl.useProgram(m_program->getProgram());

	// Setup static buffers
	for (int attribNdx = 0; attribNdx < m_spec.staticAttributeCount; attribNdx++)
	{
		GLint location = gl.getAttribLocation(m_program->getProgram(), ("a_static" + de::toString(attribNdx)).c_str());

		gl.enableVertexAttribArray(location);

		if (m_spec.useStaticBuffer)
		{
			gl.bindBuffer(GL_ARRAY_BUFFER, m_batchedStaticBuffers[attribNdx]);
			gl.vertexAttribPointer(location, 4, GL_BYTE, GL_TRUE, 0, NULL);
			gl.bindBuffer(GL_ARRAY_BUFFER, 0);
		}
		else
			gl.vertexAttribPointer(location, 4, GL_BYTE, GL_TRUE, 0, &(m_staticAttributeDatas[attribNdx][0]));
	}

	// Get locations of dynamic attributes
	for (int attribNdx = 0; attribNdx < m_spec.dynamicAttributeCount; attribNdx++)
	{
		GLint location = gl.getAttribLocation(m_program->getProgram(), ("a_dyn" + de::toString(attribNdx)).c_str());

		gl.enableVertexAttribArray(location);
		dynamicAttributeLocations.push_back(location);
	}

	if (m_spec.useDrawElements && m_spec.useIndexBuffer && !m_spec.dynamicIndices)
		gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_batchedStaticIndexBuffer);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup initial state for rendering.");

	gl.finish();

	beginUs = deGetMicroseconds();

	for (int attribute = 0; attribute < m_spec.dynamicAttributeCount; attribute++)
	{
		if (m_spec.useDynamicBuffer)
		{
			gl.bindBuffer(GL_ARRAY_BUFFER, m_batchedDynamicBuffers[attribute]);
			gl.vertexAttribPointer(dynamicAttributeLocations[attribute], 4, GL_BYTE, GL_TRUE, 0, NULL);
			gl.bindBuffer(GL_ARRAY_BUFFER, 0);
		}
		else
			gl.vertexAttribPointer(dynamicAttributeLocations[attribute], 4, GL_BYTE, GL_TRUE, 0, &(m_dynamicAttributeDatas[attribute][0]));
	}

	if (m_spec.useDrawElements)
	{
		if (m_spec.useIndexBuffer)
		{
			if (m_spec.dynamicIndices)
			{
				gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_batchedDynamicIndexBuffer);
				gl.drawElements(GL_TRIANGLES, m_spec.triangleCount * 3 * m_spec.drawCallCount, GL_UNSIGNED_BYTE, NULL);
				gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
			}
			else
				gl.drawElements(GL_TRIANGLES, m_spec.triangleCount * 3 * m_spec.drawCallCount, GL_UNSIGNED_BYTE, NULL);
		}
		else
		{
			if (m_spec.dynamicIndices)
				gl.drawElements(GL_TRIANGLES, m_spec.triangleCount * 3 * m_spec.drawCallCount, GL_UNSIGNED_BYTE, &(m_dynamicIndexData[0]));
			else
				gl.drawElements(GL_TRIANGLES, m_spec.triangleCount * 3 * m_spec.drawCallCount, GL_UNSIGNED_BYTE, &(m_staticIndexData[0]));
		}
	}
	else
		gl.drawArrays(GL_TRIANGLES, 0, 3 * m_spec.triangleCount * m_spec.drawCallCount);

	gl.finish();

	endUs = deGetMicroseconds();

	GLU_EXPECT_NO_ERROR(gl.getError(), "Batched rendering failed");

	gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	for (int attribNdx = 0; attribNdx < m_spec.staticAttributeCount; attribNdx++)
	{
		GLint location = gl.getAttribLocation(m_program->getProgram(), ("a_static" + de::toString(attribNdx)).c_str());
		gl.disableVertexAttribArray(location);
	}

	for (int attribNdx = 0; attribNdx < m_spec.dynamicAttributeCount; attribNdx++)
		gl.disableVertexAttribArray(dynamicAttributeLocations[attribNdx]);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to reset state after batched rendering");

	return endUs - beginUs;
}

struct Statistics
{
	double mean;
	double standardDeviation;
	double standardErrorOfMean;
};

Statistics calculateStats (const vector<deUint64>& samples)
{
	double mean = 0.0;

	for (int i = 0; i < (int)samples.size(); i++)
		mean += (double)samples[i];

	mean /= (double)samples.size();

	double standardDeviation = 0.0;

	for (int i = 0; i < (int)samples.size(); i++)
	{
		double x = (double)samples[i];
		standardDeviation += (x - mean) * (x - mean);
	}

	standardDeviation /= (double)samples.size();
	standardDeviation = std::sqrt(standardDeviation);

	double standardErrorOfMean = standardDeviation / std::sqrt((double)samples.size());

	Statistics stats;

	stats.mean					= mean;
	stats.standardDeviation		= standardDeviation;
	stats.standardErrorOfMean	= standardErrorOfMean;

	return stats;
}

void DrawCallBatchingTest::logTestInfo (void)
{
	TestLog&				log		= m_testCtx.getLog();
	tcu::ScopedLogSection	section	(log, "Test info", "Test info");

	log << TestLog::Message << "Rendering using " << (m_spec.useDrawElements ? "glDrawElements()" : "glDrawArrays()") << "." << TestLog::EndMessage;

	if (m_spec.useDrawElements)
		log << TestLog::Message << "Using " << (m_spec.dynamicIndices ? "dynamic " : "") << "indices from " << (m_spec.useIndexBuffer ? "buffer" : "pointer") << "." << TestLog::EndMessage;

	if (m_spec.staticAttributeCount > 0)
		log << TestLog::Message << "Using " << m_spec.staticAttributeCount << " static attribute" << (m_spec.staticAttributeCount > 1 ? "s" : "") << " from " << (m_spec.useStaticBuffer ? "buffer" : "pointer") << "." << TestLog::EndMessage;

	if (m_spec.dynamicAttributeCount > 0)
		log << TestLog::Message << "Using " << m_spec.dynamicAttributeCount << " dynamic attribute" << (m_spec.dynamicAttributeCount > 1 ? "s" : "") << " from " << (m_spec.useDynamicBuffer ? "buffer" : "pointer") << "." << TestLog::EndMessage;

	log << TestLog::Message << "Rendering " << m_spec.drawCallCount << " draw calls with " << m_spec.triangleCount << " triangles per call." << TestLog::EndMessage;
}

tcu::TestCase::IterateResult DrawCallBatchingTest::iterate (void)
{
	if (m_state == STATE_LOG_INFO)
	{
		logTestInfo();
		m_state = STATE_WARMUP_BATCHED;
	}
	else if (m_state == STATE_WARMUP_BATCHED)
	{
		renderBatched();
		m_state = STATE_WARMUP_UNBATCHED;
	}
	else if (m_state == STATE_WARMUP_UNBATCHED)
	{
		renderUnbatched();
		m_state = STATE_SAMPLE;
	}
	else if (m_state == STATE_SAMPLE)
	{
		if ((int)m_unbatchedSamplesUs.size() < m_unbatchedSampleCount && ((double)m_unbatchedSamplesUs.size() / ((double)m_unbatchedSampleCount) < (double)m_batchedSamplesUs.size() / ((double)m_batchedSampleCount) || (int)m_batchedSamplesUs.size() >= m_batchedSampleCount))
			m_unbatchedSamplesUs.push_back(renderUnbatched());
		else if ((int)m_batchedSamplesUs.size() < m_batchedSampleCount)
			m_batchedSamplesUs.push_back(renderBatched());
		else
			m_state = STATE_CALC_CALIBRATION;
	}
	else if (m_state == STATE_CALC_CALIBRATION)
	{
		TestLog& log = m_testCtx.getLog();

		tcu::ScopedLogSection	section(log, ("Sampling iteration " + de::toString(m_sampleIteration)).c_str(), ("Sampling iteration " + de::toString(m_sampleIteration)).c_str());
		const double targetSEM	= 0.02;
		const double limitSEM	= 0.025;

		Statistics unbatchedStats	= calculateStats(m_unbatchedSamplesUs);
		Statistics batchedStats		= calculateStats(m_batchedSamplesUs);

		log << TestLog::Message << "Batched samples; Count: " << m_batchedSamplesUs.size() << ", Mean: " << batchedStats.mean << "us, Standard deviation: " << batchedStats.standardDeviation << "us, Standard error of mean: " << batchedStats.standardErrorOfMean << "us(" << (batchedStats.standardErrorOfMean/batchedStats.mean) << ")" << TestLog::EndMessage;
		log << TestLog::Message << "Unbatched samples; Count: " << m_unbatchedSamplesUs.size() << ", Mean: " << unbatchedStats.mean << "us, Standard deviation: " << unbatchedStats.standardDeviation << "us, Standard error of mean: " << unbatchedStats.standardErrorOfMean << "us(" << (unbatchedStats.standardErrorOfMean/unbatchedStats.mean) << ")" << TestLog::EndMessage;

		if (m_sampleIteration > 2 || (m_sampleIteration > 0 && (unbatchedStats.standardErrorOfMean/unbatchedStats.mean) + (batchedStats.standardErrorOfMean/batchedStats.mean) <= 2.0 * limitSEM))
		{
			if (m_sampleIteration > 2)
				log << TestLog::Message << "Maximum iteration count reached." << TestLog::EndMessage;

			log << TestLog::Message << "Standard errors in target range." << TestLog::EndMessage;
			log << TestLog::Message << "Batched/Unbatched ratio: " << (batchedStats.mean / unbatchedStats.mean) << TestLog::EndMessage;

			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString((float)(batchedStats.mean/unbatchedStats.mean), 1).c_str());
			return STOP;
		}
		else
		{
			if ((unbatchedStats.standardErrorOfMean/unbatchedStats.mean) > targetSEM)
				log << TestLog::Message << "Unbatched standard error of mean outside of range." << TestLog::EndMessage;

			if ((batchedStats.standardErrorOfMean/batchedStats.mean) > targetSEM)
				log << TestLog::Message << "Batched standard error of mean outside of range." << TestLog::EndMessage;

			if (unbatchedStats.standardDeviation > 0.0)
			{
				double x = (unbatchedStats.standardDeviation / unbatchedStats.mean) / targetSEM;
				m_unbatchedSampleCount = std::max((int)m_unbatchedSamplesUs.size(), (int)(x * x));
			}
			else
				m_unbatchedSampleCount = (int)m_unbatchedSamplesUs.size();

			if (batchedStats.standardDeviation > 0.0)
			{
				double x = (batchedStats.standardDeviation / batchedStats.mean) / targetSEM;
				m_batchedSampleCount = std::max((int)m_batchedSamplesUs.size(), (int)(x * x));
			}
			else
				m_batchedSampleCount = (int)m_batchedSamplesUs.size();

			m_batchedSamplesUs.clear();
			m_unbatchedSamplesUs.clear();

			m_sampleIteration++;
			m_state = STATE_SAMPLE;
		}
	}
	else
		DE_ASSERT(false);

	return CONTINUE;
}

string specToName (const DrawCallBatchingTest::TestSpec& spec)
{
	std::ostringstream stream;

	DE_ASSERT(!spec.useStaticBuffer || spec.staticAttributeCount > 0);
	DE_ASSERT(!spec.useDynamicBuffer|| spec.dynamicAttributeCount > 0);

	if (spec.staticAttributeCount > 0)
		stream << spec.staticAttributeCount << "_static_";

	if (spec.useStaticBuffer)
		stream << (spec.staticAttributeCount == 1 ? "buffer_" : "buffers_");

	if (spec.dynamicAttributeCount > 0)
		stream << spec.dynamicAttributeCount << "_dynamic_";

	if (spec.useDynamicBuffer)
		stream << (spec.dynamicAttributeCount == 1 ? "buffer_" : "buffers_");

	stream << spec.triangleCount << "_triangles";

	return stream.str();
}

string specToDescrpition (const DrawCallBatchingTest::TestSpec& spec)
{
	DE_UNREF(spec);
	return "Test performance of batched rendering against non-batched rendering.";
}

} // anonymous

DrawCallBatchingTests::DrawCallBatchingTests (Context& context)
	: TestCaseGroup(context, "draw_call_batching", "Draw call batching performance tests.")
{
}

DrawCallBatchingTests::~DrawCallBatchingTests (void)
{
}

void DrawCallBatchingTests::init (void)
{
	int drawCallCounts[] = {
		10, 100
	};

	int triangleCounts[] = {
		2, 10
	};

	int staticAttributeCounts[] = {
		1, 0, 4, 8, 0
	};

	int dynamicAttributeCounts[] = {
		0, 1, 4, 0, 8
	};

	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(staticAttributeCounts) == DE_LENGTH_OF_ARRAY(dynamicAttributeCounts));

	for (int drawType = 0; drawType < 2; drawType++)
	{
		bool drawElements = (drawType == 1);

		for (int indexBufferNdx = 0; indexBufferNdx < 2; indexBufferNdx++)
		{
			bool useIndexBuffer = (indexBufferNdx == 1);

			if (useIndexBuffer && !drawElements)
				continue;

			for (int dynamicIndexNdx = 0; dynamicIndexNdx < 2; dynamicIndexNdx++)
			{
				bool dynamicIndices = (dynamicIndexNdx == 1);

				if (dynamicIndices && !drawElements)
					continue;

				if (dynamicIndices && !useIndexBuffer)
					continue;

				TestCaseGroup* drawTypeGroup = new TestCaseGroup(m_context, (string(dynamicIndices ? "dynamic_" : "") + (useIndexBuffer ? "buffer_" : "" ) + (drawElements ? "draw_elements" : "draw_arrays")).c_str(), (string("Test batched rendering with ") + (drawElements ? "draw_elements" : "draw_arrays")).c_str());

				addChild(drawTypeGroup);

				for (int drawCallCountNdx = 0; drawCallCountNdx < DE_LENGTH_OF_ARRAY(drawCallCounts); drawCallCountNdx++)
				{
					int drawCallCount = drawCallCounts[drawCallCountNdx];

					TestCaseGroup*	callCountGroup			= new TestCaseGroup(m_context, (de::toString(drawCallCount) + (drawCallCount == 1 ? "_draw" : "_draws")).c_str(), ("Test batched rendering performance with " + de::toString(drawCallCount) + " draw calls.").c_str());
					TestCaseGroup*	attributeCount1Group	= new TestCaseGroup(m_context, "1_attribute", "Test draw call batching with 1 attribute.");
					TestCaseGroup*	attributeCount8Group	= new TestCaseGroup(m_context, "8_attributes", "Test draw call batching with 8 attributes.");

					callCountGroup->addChild(attributeCount1Group);
					callCountGroup->addChild(attributeCount8Group);

					drawTypeGroup->addChild(callCountGroup);

					for (int attributeCountNdx = 0; attributeCountNdx < DE_LENGTH_OF_ARRAY(dynamicAttributeCounts); attributeCountNdx++)
					{
						TestCaseGroup*	attributeCountGroup		= NULL;

						int				staticAttributeCount	= staticAttributeCounts[attributeCountNdx];
						int				dynamicAttributeCount	= dynamicAttributeCounts[attributeCountNdx];

						if (staticAttributeCount + dynamicAttributeCount == 1)
							attributeCountGroup = attributeCount1Group;
						else if (staticAttributeCount + dynamicAttributeCount == 8)
							attributeCountGroup = attributeCount8Group;
						else
							DE_ASSERT(false);

						for (int triangleCountNdx = 0; triangleCountNdx < DE_LENGTH_OF_ARRAY(triangleCounts); triangleCountNdx++)
						{
							int triangleCount = triangleCounts[triangleCountNdx];

							for (int dynamicBufferNdx = 0; dynamicBufferNdx < 2; dynamicBufferNdx++)
							{
								bool useDynamicBuffer = (dynamicBufferNdx != 0);

								for (int staticBufferNdx = 0; staticBufferNdx < 2; staticBufferNdx++)
								{
									bool useStaticBuffer = (staticBufferNdx != 0);

									DrawCallBatchingTest::TestSpec spec;

									spec.useStaticBuffer		= useStaticBuffer;
									spec.staticAttributeCount	= staticAttributeCount;

									spec.useDynamicBuffer		= useDynamicBuffer;
									spec.dynamicAttributeCount	= dynamicAttributeCount;

									spec.drawCallCount			= drawCallCount;
									spec.triangleCount			= triangleCount;

									spec.useDrawElements		= drawElements;
									spec.useIndexBuffer			= useIndexBuffer;
									spec.dynamicIndices			= dynamicIndices;

									if (spec.useStaticBuffer && spec.staticAttributeCount == 0)
										continue;

									if (spec.useDynamicBuffer && spec.dynamicAttributeCount == 0)
										continue;

									attributeCountGroup->addChild(new DrawCallBatchingTest(m_context, specToName(spec).c_str(), specToDescrpition(spec).c_str(), spec));
								}
							}
						}
					}
				}
			}
		}
	}
}

} // Performance
} // gles2
} // deqp
