/*-------------------------------------------------------------------------
 * 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 Depth buffer performance tests.
 *//*--------------------------------------------------------------------*/

#include "es3pDepthTests.hpp"

#include "glsCalibration.hpp"

#include "gluShaderProgram.hpp"
#include "gluObjectWrapper.hpp"
#include "gluPixelTransfer.hpp"

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

#include "tcuTestLog.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuCPUWarmup.hpp"
#include "tcuCommandLine.hpp"
#include "tcuResultCollector.hpp"

#include "deClock.h"
#include "deString.h"
#include "deMath.h"
#include "deStringUtil.hpp"
#include "deRandom.hpp"
#include "deUniquePtr.hpp"

#include <vector>
#include <algorithm>

namespace deqp
{
namespace gles3
{
namespace Performance
{
namespace
{
using namespace glw;
using de::MovePtr;
using tcu::TestContext;
using tcu::TestLog;
using tcu::Vec4;
using tcu::Vec3;
using tcu::Vec2;
using glu::RenderContext;
using glu::ProgramSources;
using glu::ShaderSource;
using std::vector;
using std::string;
using std::map;

struct Sample
{
	deInt64	nullTime;
	deInt64	baseTime;
	deInt64	testTime;
	int		order;
	int		workload;
};

struct SampleParams
{
	int step;
	int measurement;

	SampleParams(int step_, int measurement_) : step(step_), measurement(measurement_) {}
};

typedef vector<float> Geometry;

struct ObjectData
{
	ProgramSources	shader;
	Geometry		geometry;

	ObjectData (const ProgramSources& shader_, const Geometry& geometry_) : shader(shader_), geometry(geometry_) {}
};

class RenderData
{
public:
								RenderData		(const ObjectData& object, const glu::RenderContext& renderCtx, TestLog& log);
								~RenderData		(void) {};

	const glu::ShaderProgram	m_program;
	const glu::VertexArray		m_vao;
	const glu::Buffer			m_vbo;

	const int					m_numVertices;
};

RenderData::RenderData (const ObjectData& object, const  glu::RenderContext& renderCtx, TestLog& log)
	: m_program		(renderCtx, object.shader)
	, m_vao			(renderCtx.getFunctions())
	, m_vbo			(renderCtx.getFunctions())
	, m_numVertices	(int(object.geometry.size())/4)
{
	const glw::Functions& gl = renderCtx.getFunctions();

	if (!m_program.isOk())
		log << m_program;

	gl.bindBuffer(GL_ARRAY_BUFFER, *m_vbo);
	gl.bufferData(GL_ARRAY_BUFFER, object.geometry.size() * sizeof(float), &object.geometry[0], GL_STATIC_DRAW);
	gl.bindAttribLocation(m_program.getProgram(), 0, "a_position");

	gl.bindVertexArray(*m_vao);
	gl.vertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
	gl.enableVertexAttribArray(0);
	gl.bindVertexArray(0);
}

namespace Utils
{
	vector<float> getFullscreenQuad (float depth)
	{
		const float data[] =
		{
			+1.0f, +1.0f, depth, 0.0f, // .w is gl_VertexId%3 since Nexus 4&5 can't handle that on their own
			+1.0f, -1.0f, depth, 1.0f,
			-1.0f, -1.0f, depth, 2.0f,
			-1.0f, -1.0f, depth, 0.0f,
			-1.0f, +1.0f, depth, 1.0f,
			+1.0f, +1.0f, depth, 2.0f,
		};

		return vector<float>(DE_ARRAY_BEGIN(data), DE_ARRAY_END(data));
	}

	vector<float> getFullscreenQuadWithGradient (float depth0, float depth1)
	{
		const float data[] =
		{
			+1.0f, +1.0f, depth0, 0.0f,
			+1.0f, -1.0f, depth0, 1.0f,
			-1.0f, -1.0f, depth1, 2.0f,
			-1.0f, -1.0f, depth1, 0.0f,
			-1.0f, +1.0f, depth1, 1.0f,
			+1.0f, +1.0f, depth0, 2.0f,
		};

		return vector<float>(DE_ARRAY_BEGIN(data), DE_ARRAY_END(data));
	}

	vector<float> getPartScreenQuad (float coverage, float depth)
	{
		const float xMax	= -1.0f + 2.0f*coverage;
		const float data[]	=
		{
			 xMax, +1.0f, depth, 0.0f,
			 xMax, -1.0f, depth, 1.0f,
			-1.0f, -1.0f, depth, 2.0f,
			-1.0f, -1.0f, depth, 0.0f,
			-1.0f, +1.0f, depth, 1.0f,
			 xMax, +1.0f, depth, 2.0f,
		};

		return vector<float>(DE_ARRAY_BEGIN(data), DE_ARRAY_END(data));
	}

	// Axis aligned grid. Depth of vertices is baseDepth +/- depthNoise
	vector<float> getFullScreenGrid (int resolution, deUint32 seed, float baseDepth, float depthNoise, float xyNoise)
	{
		const int		gridsize	= resolution+1;
		vector<Vec3>	vertices	(gridsize*gridsize);
		vector<float>	retval;
		de::Random		rng			(seed);

		for (int y = 0; y < gridsize; y++)
		for (int x = 0; x < gridsize; x++)
		{
			const bool	isEdge	= x == 0 || y == 0 || x == resolution || y == resolution;
			const float x_		= float(x)/float(resolution)*2.0f - 1.0f + (isEdge ? 0.0f : rng.getFloat(-xyNoise, +xyNoise));
			const float y_		= float(y)/float(resolution)*2.0f - 1.0f + (isEdge ? 0.0f : rng.getFloat(-xyNoise, +xyNoise));
			const float z_		= baseDepth + rng.getFloat(-depthNoise, +depthNoise);

			vertices[y*gridsize + x] = Vec3(x_, y_, z_);
		}

		retval.reserve(resolution*resolution*6);

		for (int y = 0; y < resolution; y++)
		for (int x = 0; x < resolution; x++)
		{
			const Vec3& p0 = vertices[(y+0)*gridsize + (x+0)];
			const Vec3& p1 = vertices[(y+0)*gridsize + (x+1)];
			const Vec3& p2 = vertices[(y+1)*gridsize + (x+0)];
			const Vec3& p3 = vertices[(y+1)*gridsize + (x+1)];

			const float temp[6*4] =
			{
				p0.x(), p0.y(), p0.z(), 0.0f,
				p2.x(), p2.y(), p2.z(), 1.0f,
				p1.x(), p1.y(), p1.z(), 2.0f,

				p3.x(), p3.y(), p3.z(), 0.0f,
				p1.x(), p1.y(), p1.z(), 1.0f,
				p2.x(), p2.y(), p2.z(), 2.0f,
			};

			retval.insert(retval.end(), DE_ARRAY_BEGIN(temp), DE_ARRAY_END(temp));
		}

		return retval;
	}

	// Outputs barycentric coordinates as v_bcoords. Otherwise a passthrough shader
	string getBaseVertexShader (void)
	{
		return "#version 300 es\n"
				"in highp vec4 a_position;\n"
				"out mediump vec3 v_bcoords;\n"
				"void main()\n"
				"{\n"
				"	v_bcoords = vec3(0, 0, 0);\n"
				"	v_bcoords[int(a_position.w)] = 1.0;\n"
				"	gl_Position = vec4(a_position.xyz, 1.0);\n"
				"}\n";
	}

	// Adds noise to coordinates based on InstanceID Outputs barycentric coordinates as v_bcoords
	string getInstanceNoiseVertexShader (void)
	{
		return "#version 300 es\n"
				"in highp vec4 a_position;\n"
				"out mediump vec3 v_bcoords;\n"
				"void main()\n"
				"{\n"
				"	v_bcoords = vec3(0, 0, 0);\n"
				"	v_bcoords[int(a_position.w)] = 1.0;\n"
				"	vec3 noise = vec3(sin(float(gl_InstanceID)*1.05), sin(float(gl_InstanceID)*1.23), sin(float(gl_InstanceID)*1.71));\n"
				"	gl_Position = vec4(a_position.xyz + noise * 0.005, 1.0);\n"
				"}\n";
	}

	// Renders green triangles with edges highlighted. Exact shade depends on depth.
	string getDepthAsGreenFragmentShader (void)
	{
		return	"#version 300 es\n"
				"in mediump vec3 v_bcoords;\n"
				"out mediump vec4 fragColor;\n"
				"void main()\n"
				"{\n"
				"	mediump float d = gl_FragCoord.z;\n"
				"	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
				"		fragColor = vec4(d,1,d,1);\n"
				"	else\n"
				"		fragColor = vec4(0,d,0,1);\n"
				"}\n";
	}

	// Renders green triangles with edges highlighted. Exact shade depends on depth.
	string getDepthAsRedFragmentShader (void)
	{
		return	"#version 300 es\n"
				"in mediump vec3 v_bcoords;\n"
				"out mediump vec4 fragColor;\n"
				"void main()\n"
				"{\n"
				"	mediump float d = gl_FragCoord.z;\n"
				"	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
				"		fragColor = vec4(1,d,d,1);\n"
				"	else\n"
				"		fragColor = vec4(d,0,0,1);\n"
				"}\n";
	}

	// Basic time waster. Renders red triangles with edges highlighted. Exact shade depends on depth.
	string getArithmeticWorkloadFragmentShader (void)
	{

		return	"#version 300 es\n"
				"in mediump vec3 v_bcoords;\n"
				"out mediump vec4 fragColor;\n"
				"uniform mediump int u_iterations;\n"
				"void main()\n"
				"{\n"
				"	mediump float d = gl_FragCoord.z;\n"
				"	for (int i = 0; i<u_iterations; i++)\n"
				// cos(a)^2 + sin(a)^2 == 1. since d is in range [0,1] this will lose a few ULP's of precision per iteration but should not significantly change the value of d without extreme iteration counts
				"		d = d*sin(d)*sin(d) + d*cos(d)*cos(d);\n"
				"	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
				"		fragColor = vec4(1,d,d,1);\n"
				"	else\n"
				"		fragColor = vec4(d,0,0,1);\n"
				"}\n";
	}

	// Arithmetic workload shader but contains discard
	string getArithmeticWorkloadDiscardFragmentShader (void)
	{
		return	"#version 300 es\n"
				"in mediump vec3 v_bcoords;\n"
				"out mediump vec4 fragColor;\n"
				"uniform mediump int u_iterations;\n"
				"void main()\n"
				"{\n"
				"	mediump float d = gl_FragCoord.z;\n"
				"	for (int i = 0; i<u_iterations; i++)\n"
				"		d = d*sin(d)*sin(d) + d*cos(d)*cos(d);\n"
				"	if (d < 0.5) discard;\n"
				"	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
				"		fragColor = vec4(1,d,d,1);\n"
				"	else\n"
				"		fragColor = vec4(d,0,0,1);\n"
				"}\n";
	}

	// Texture fetch based time waster. Renders red triangles with edges highlighted. Exact shade depends on depth.
	string getTextureWorkloadFragmentShader (void)
	{
		return  "#version 300 es\n"
				"in mediump vec3 v_bcoords;\n"
				"out mediump vec4 fragColor;\n"
				"uniform mediump int u_iterations;\n"
				"uniform sampler2D u_texture;\n"
				"void main()\n"
				"{\n"
				"	mediump float d = gl_FragCoord.z;\n"
				"	for (int i = 0; i<u_iterations; i++)\n"
				"		d *= texture(u_texture, (gl_FragCoord.xy+vec2(i))/512.0).r;\n" // Texture is expected to be fully white
				"	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
				"		fragColor = vec4(1,1,1,1);\n"
				"	else\n"
				"		fragColor = vec4(d,0,0,1);\n"
				"}\n";
	}

	// Discard fragments in a grid pattern
	string getGridDiscardFragmentShader (int gridsize)
	{
		const string		fragSrc = "#version 300 es\n"
									  "in mediump vec3 v_bcoords;\n"
									  "out mediump vec4 fragColor;\n"
									  "void main()\n"
									  "{\n"
									  "	mediump float d = gl_FragCoord.z;\n"
									  "	if ((int(gl_FragCoord.x)/${GRIDRENDER_SIZE} + int(gl_FragCoord.y)/${GRIDRENDER_SIZE})%2 == 0)\n"
									  "		discard;\n"
									  "	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
									  "		fragColor = vec4(d,1,d,1);\n"
									  "	else\n"
									  "		fragColor = vec4(0,d,0,1);\n"
									  "}\n";
		map<string, string>	params;

		params["GRIDRENDER_SIZE"] = de::toString(gridsize);

		return tcu::StringTemplate(fragSrc).specialize(params);
	}

	// A static increment to frag depth
	string getStaticFragDepthFragmentShader (void)
	{
		return	"#version 300 es\n"
				"in mediump vec3 v_bcoords;\n"
				"out mediump vec4 fragColor;\n"
				"void main()\n"
				"{\n"
				"	mediump float d = gl_FragCoord.z;\n"
				"	gl_FragDepth = gl_FragCoord.z + 0.1;\n"
				"	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
				"		fragColor = vec4(d,1,d,1);\n"
				"	else\n"
				"		fragColor = vec4(0,d,0,1);\n"
				"}\n";
	}

	// A trivial dynamic change to frag depth
	string getDynamicFragDepthFragmentShader (void)
	{
		return	"#version 300 es\n"
				"in mediump vec3 v_bcoords;\n"
				"out mediump vec4 fragColor;\n"
				"void main()\n"
				"{\n"
				"	mediump float d = gl_FragCoord.z;\n"
				"	gl_FragDepth = gl_FragCoord.z + (v_bcoords.x + v_bcoords.y + v_bcoords.z)*0.05;\n" // Sum of v_bcoords components is allways 1
				"	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
				"		fragColor = vec4(d,1,d,1);\n"
				"	else\n"
				"		fragColor = vec4(0,d,0,1);\n"
				"}\n";
	}

	// A static increment to frag depth
	string getStaticFragDepthArithmeticWorkloadFragmentShader (void)
	{
		return	"#version 300 es\n"
				"in mediump vec3 v_bcoords;\n"
				"out mediump vec4 fragColor;\n"
				"uniform mediump int u_iterations;\n"
				"void main()\n"
				"{\n"
				"	mediump float d = gl_FragCoord.z;\n"
				"	gl_FragDepth = gl_FragCoord.z + 0.1;\n"
				"	for (int i = 0; i<u_iterations; i++)\n"
				"		d = d*sin(d)*sin(d) + d*cos(d)*cos(d);\n"
				"	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
				"		fragColor = vec4(1,d,d,1);\n"
				"	else\n"
				"		fragColor = vec4(d,0,0,1);\n"
				"}\n";
	}

	// A trivial dynamic change to frag depth
	string getDynamicFragDepthArithmeticWorkloadFragmentShader (void)
	{
		return	"#version 300 es\n"
				"in mediump vec3 v_bcoords;\n"
				"out mediump vec4 fragColor;\n"
				"uniform mediump int u_iterations;\n"
				"void main()\n"
				"{\n"
				"	mediump float d = gl_FragCoord.z;\n"
				"	gl_FragDepth = gl_FragCoord.z + (v_bcoords.x + v_bcoords.y + v_bcoords.z)*0.05;\n" // Sum of v_bcoords components is allways 1
				"	for (int i = 0; i<u_iterations; i++)\n"
				"		d = d*sin(d)*sin(d) + d*cos(d)*cos(d);\n"
				"	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
				"		fragColor = vec4(1,d,d,1);\n"
				"	else\n"
				"		fragColor = vec4(d,0,0,1);\n"
				"}\n";
	}

	glu::ProgramSources getBaseShader (void)
	{
		return glu::makeVtxFragSources(getBaseVertexShader(), getDepthAsGreenFragmentShader());
	}

	glu::ProgramSources getArithmeticWorkloadShader (void)
	{
		return glu::makeVtxFragSources(getBaseVertexShader(), getArithmeticWorkloadFragmentShader());
	}

	glu::ProgramSources getArithmeticWorkloadDiscardShader (void)
	{
		return glu::makeVtxFragSources(getBaseVertexShader(), getArithmeticWorkloadDiscardFragmentShader());
	}

	glu::ProgramSources getTextureWorkloadShader (void)
	{
		return glu::makeVtxFragSources(getBaseVertexShader(), getTextureWorkloadFragmentShader());
	}

	glu::ProgramSources getGridDiscardShader (int gridsize)
	{
		return glu::makeVtxFragSources(getBaseVertexShader(), getGridDiscardFragmentShader(gridsize));
	}

	inline ObjectData quadWith (const glu::ProgramSources& shader, float depth)
	{
		return ObjectData(shader, getFullscreenQuad(depth));
	}

	inline ObjectData quadWith (const string& fragShader, float depth)
	{
		return ObjectData(glu::makeVtxFragSources(getBaseVertexShader(), fragShader), getFullscreenQuad(depth));
	}

	inline ObjectData variableQuad (float depth)
	{
		return ObjectData(glu::makeVtxFragSources(getInstanceNoiseVertexShader(), getDepthAsRedFragmentShader()), getFullscreenQuad(depth));
	}

	inline ObjectData fastQuad (float depth)
	{
		return ObjectData(getBaseShader(), getFullscreenQuad(depth));
	}

	inline ObjectData slowQuad (float depth)
	{
		return ObjectData(getArithmeticWorkloadShader(), getFullscreenQuad(depth));
	}

	inline ObjectData fastQuadWithGradient (float depth0, float depth1)
	{
		return ObjectData(getBaseShader(), getFullscreenQuadWithGradient(depth0, depth1));
	}
} // Utils

// Shared base
class BaseCase : public tcu::TestCase
{
public:
	enum {RENDER_SIZE = 512};

							BaseCase			(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc);
	virtual					~BaseCase			(void) {}

	virtual IterateResult	iterate				(void);

protected:
	void					logSamples			(const vector<Sample>& samples, const string& name, const string& desc);
	void					logGeometry			(const tcu::ConstPixelBufferAccess& sample, const glu::ShaderProgram& occluderProg, const glu::ShaderProgram& occludedProg);
	virtual void			logAnalysis			(const vector<Sample>& samples) = 0;
	virtual void			logDescription		(void) = 0;

	virtual ObjectData		genOccluderGeometry	(void) const = 0;
	virtual ObjectData		genOccludedGeometry	(void) const = 0;

	virtual int				calibrate			(void) const = 0;
	virtual Sample			renderSample		(const RenderData& occluder, const RenderData& occluded, int workload) const = 0;

	void					render				(const RenderData& data) const;
	void					render				(const RenderData& data, int instances) const;

	const RenderContext&	m_renderCtx;
	tcu::ResultCollector	m_results;

	enum {ITERATION_STEPS = 10, ITERATION_SAMPLES = 16};
};

BaseCase::BaseCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
	: TestCase		(testCtx, tcu::NODETYPE_PERFORMANCE, name, desc)
	, m_renderCtx	(renderCtx)
{
}

BaseCase::IterateResult BaseCase::iterate (void)
{
	typedef de::MovePtr<RenderData> RenderDataP;

	const glw::Functions&	gl					= m_renderCtx.getFunctions();
	TestLog&				log					= m_testCtx.getLog();

	const glu::Framebuffer	framebuffer			(gl);
	const glu::Renderbuffer	renderbuffer		(gl);
	const glu::Renderbuffer	depthbuffer			(gl);

	vector<Sample>			results;
	vector<int>				params;
	RenderDataP				occluderData;
	RenderDataP				occludedData;
	tcu::TextureLevel		resultTex			(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), RENDER_SIZE, RENDER_SIZE);
	int						maxWorkload			= 0;
	de::Random				rng					(deInt32Hash(deStringHash(getName())) ^ m_testCtx.getCommandLine().getBaseSeed());

	logDescription();

	gl.bindRenderbuffer(GL_RENDERBUFFER, *renderbuffer);
	gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, RENDER_SIZE, RENDER_SIZE);
	gl.bindRenderbuffer(GL_RENDERBUFFER, *depthbuffer);
	gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, RENDER_SIZE, RENDER_SIZE);

	gl.bindFramebuffer(GL_FRAMEBUFFER, *framebuffer);
	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *renderbuffer);
	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *depthbuffer);
	gl.viewport(0, 0, RENDER_SIZE, RENDER_SIZE);
	gl.clearColor(0.125f, 0.25f, 0.5f, 1.0f);

	maxWorkload = calibrate();

	// Setup data
	occluderData = RenderDataP(new RenderData (genOccluderGeometry(), m_renderCtx, log));
	occludedData = RenderDataP(new RenderData (genOccludedGeometry(), m_renderCtx, log));

	TCU_CHECK(occluderData->m_program.isOk());
	TCU_CHECK(occludedData->m_program.isOk());

	// Force initialization of GPU resources
	gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	gl.enable(GL_DEPTH_TEST);

	render(*occluderData);
	render(*occludedData);
	glu::readPixels(m_renderCtx, 0, 0, resultTex.getAccess());

	logGeometry(resultTex.getAccess(), occluderData->m_program, occludedData->m_program);

	params.reserve(ITERATION_STEPS*ITERATION_SAMPLES);

	// Setup parameters
	for (int step = 0; step < ITERATION_STEPS; step++)
	{
		const int workload = maxWorkload*step/ITERATION_STEPS;

		for (int count = 0; count < ITERATION_SAMPLES; count++)
			params.push_back(workload);
	}

	rng.shuffle(params.begin(), params.end());

	// Render samples
	for (size_t ndx = 0; ndx < params.size(); ndx++)
	{
		const int	workload	= params[ndx];
		Sample		sample		= renderSample(*occluderData, *occludedData, workload);

		sample.workload = workload;
		sample.order = int(ndx);

		results.push_back(sample);
	}

	logSamples(results, "Samples", "Samples");
	logAnalysis(results);

	m_results.setTestContextResult(m_testCtx);

	return STOP;
}

void BaseCase::logSamples (const vector<Sample>& samples, const string& name, const string& desc)
{
	TestLog& log = m_testCtx.getLog();

	bool testOnly = true;

	for (size_t ndx = 0; ndx < samples.size(); ndx++)
	{
		if (samples[ndx].baseTime != 0 || samples[ndx].nullTime != 0)
		{
			testOnly = false;
			break;
		}
	}

	log << TestLog::SampleList(name, desc);

	if (testOnly)
	{
		log << TestLog::SampleInfo
			<< TestLog::ValueInfo("Workload",	"Workload",			"",				QP_SAMPLE_VALUE_TAG_PREDICTOR)
			<< TestLog::ValueInfo("Order",		"Order of sample",	"",				QP_SAMPLE_VALUE_TAG_PREDICTOR)
			<< TestLog::ValueInfo("TestTime",	"Test render time",	"us",			QP_SAMPLE_VALUE_TAG_RESPONSE)
			<< TestLog::EndSampleInfo;

		for (size_t sampleNdx = 0; sampleNdx < samples.size(); sampleNdx++)
		{
			const Sample& sample = samples[sampleNdx];

			log << TestLog::Sample << sample.workload << sample.order << sample.testTime << TestLog::EndSample;
		}
	}
	else
	{
		log << TestLog::SampleInfo
			<< TestLog::ValueInfo("Workload",	"Workload",			"",				QP_SAMPLE_VALUE_TAG_PREDICTOR)
			<< TestLog::ValueInfo("Order",		"Order of sample",	"",				QP_SAMPLE_VALUE_TAG_PREDICTOR)
			<< TestLog::ValueInfo("TestTime",	"Test render time",	"us",			QP_SAMPLE_VALUE_TAG_RESPONSE)
			<< TestLog::ValueInfo("NullTime",	"Read pixels time",	"us",			QP_SAMPLE_VALUE_TAG_RESPONSE)
			<< TestLog::ValueInfo("BaseTime",	"Base render time",	"us",			QP_SAMPLE_VALUE_TAG_RESPONSE)
			<< TestLog::EndSampleInfo;

		for (size_t sampleNdx = 0; sampleNdx < samples.size(); sampleNdx++)
		{
			const Sample& sample = samples[sampleNdx];

			log << TestLog::Sample << sample.workload << sample.order << sample.testTime << sample.nullTime << sample.baseTime << TestLog::EndSample;
		}
	}

	log << TestLog::EndSampleList;
}

void BaseCase::logGeometry (const tcu::ConstPixelBufferAccess& sample, const glu::ShaderProgram& occluderProg, const glu::ShaderProgram& occludedProg)
{
	TestLog& log = m_testCtx.getLog();

	log << TestLog::Section("Geometry", "Geometry");
	log << TestLog::Message << "Occluding geometry is green with shade dependent on depth (rgb == 0, depth, 0)" << TestLog::EndMessage;
	log << TestLog::Message << "Occluded geometry is red with shade dependent on depth (rgb == depth, 0, 0)" << TestLog::EndMessage;
	log << TestLog::Message << "Primitive edges are a lighter shade of red/green" << TestLog::EndMessage;

	log << TestLog::Image("Test Geometry", "Test Geometry",  sample);
	log << TestLog::EndSection;

	log << TestLog::Section("Occluder", "Occluder");
	log << occluderProg;
	log << TestLog::EndSection;

	log << TestLog::Section("Occluded", "Occluded");
	log << occludedProg;
	log << TestLog::EndSection;
}

void BaseCase::render (const RenderData& data) const
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	gl.useProgram(data.m_program.getProgram());

	gl.bindVertexArray(*data.m_vao);
	gl.drawArrays(GL_TRIANGLES, 0, data.m_numVertices);
	gl.bindVertexArray(0);
}

void BaseCase::render (const RenderData& data, int instances) const
{
	const glw::Functions& gl = m_renderCtx.getFunctions();

	gl.useProgram(data.m_program.getProgram());

	gl.bindVertexArray(*data.m_vao);
	gl.drawArraysInstanced(GL_TRIANGLES, 0, data.m_numVertices, instances);
	gl.bindVertexArray(0);
}

// Render occluder once, then repeatedly render occluded geometry. Sample with multiple repetition counts & establish time per call with linear regression
class RenderCountCase : public BaseCase
{
public:
					RenderCountCase		(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc);
					~RenderCountCase	(void) {}

protected:
	virtual void	logAnalysis			(const vector<Sample>& samples);

private:
	virtual int		calibrate			(void) const;
	virtual Sample	renderSample		(const RenderData& occluder, const RenderData& occluded, int callcount) const;
};

RenderCountCase::RenderCountCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
	: BaseCase	(testCtx, renderCtx, name, desc)
{
}

void RenderCountCase::logAnalysis (const vector<Sample>& samples)
{
	using namespace gls;

	TestLog&		log			= m_testCtx.getLog();
	int				maxWorkload	= 0;
	vector<Vec2>	testSamples	(samples.size());

	for (size_t ndx = 0; ndx < samples.size(); ndx++)
	{
		const Sample& sample = samples[ndx];

		testSamples[ndx] = Vec2((float)sample.workload, (float)sample.testTime);

		maxWorkload = de::max(maxWorkload, sample.workload);
	}

	{
		const float							confidence	= 0.60f;
		const LineParametersWithConfidence	testParam	= theilSenSiegelLinearRegression(testSamples, confidence);
		const float							usPerCall	= testParam.coefficient;
		const float							pxPerCall	= RENDER_SIZE*RENDER_SIZE;
		const float							pxPerUs		= pxPerCall/usPerCall;
		const float							mpxPerS		= pxPerUs;

		log << TestLog::Section("Linear Regression", "Linear Regression");
		log << TestLog::Message << "Offset & coefficient presented as [confidence interval min, estimate, confidence interval max]. Reported confidence interval for this test is " << confidence << TestLog::EndMessage;
		log << TestLog::Message << "Render time for scene with depth test was\n\t"
			<< "[" << testParam.offsetConfidenceLower << ", " << testParam.offset <<  ", " << testParam.offsetConfidenceUpper << "]us +"
			<< "[" << testParam.coefficientConfidenceLower << ", " << testParam.coefficient << ", " << testParam.coefficientConfidenceUpper << "]"
			<< "us/workload" << TestLog::EndMessage;
		log << TestLog::EndSection;

		log << TestLog::Section("Result", "Result");

		if (testParam.coefficientConfidenceLower < 0.0f)
		{
			log << TestLog::Message << "Coefficient confidence bounds include values below 0.0, the operation likely has neglible per-pixel cost" << TestLog::EndMessage;
			m_results.addResult(QP_TEST_RESULT_PASS, "Pass");
		}
		else if (testParam.coefficientConfidenceLower < testParam.coefficientConfidenceUpper*0.25)
		{
			log << TestLog::Message << "Coefficient confidence range is extremely large, cannot give reliable result" << TestLog::EndMessage;
			m_results.addResult(QP_TEST_RESULT_PASS, "Result confidence extremely low");
		}
		else
		{
			log << TestLog::Message << "Culled hidden pixels @ " << mpxPerS << "Mpx/s" << TestLog::EndMessage;
			m_results.addResult(QP_TEST_RESULT_PASS, de::floatToString(mpxPerS, 2));
		}

		log << TestLog::EndSection;
	}
}

Sample RenderCountCase::renderSample (const RenderData& occluder, const RenderData& occluded, int callcount) const
{
	const glw::Functions&	gl		= m_renderCtx.getFunctions();
	Sample					sample;
	deUint64				now		= 0;
	deUint64				prev	= 0;
	deUint8					buffer[4];

	// Stabilize
	{
		gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
		gl.enable(GL_DEPTH_TEST);
		gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
	}

	prev = deGetMicroseconds();

	gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	gl.enable(GL_DEPTH_TEST);

	render(occluder);
	render(occluded, callcount);

	gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

	now = deGetMicroseconds();

	sample.testTime = now - prev;
	sample.baseTime = 0;
	sample.nullTime = 0;
	sample.workload = callcount;

	return sample;
}

int RenderCountCase::calibrate (void) const
{
	using namespace gls;

	const glw::Functions&	gl					= m_renderCtx.getFunctions();
	TestLog&				log					= m_testCtx.getLog();

	const RenderData		occluderGeometry	(genOccluderGeometry(), m_renderCtx, log);
	const RenderData		occludedGeometry	(genOccludedGeometry(), m_renderCtx, log);

	TheilSenCalibrator		calibrator			(CalibratorParameters(20, // Initial workload
																	  10, // Max iteration frames
																	  20.0f, // Iteration shortcut threshold ms
																	  20, // Max iterations
																	  33.0f, // Target frame time
																	  40.0f, // Frame time cap
																	  1000.0f // Target measurement duration
																	  ));

	while (true)
	{
		switch(calibrator.getState())
		{
			case TheilSenCalibrator::STATE_FINISHED:
				logCalibrationInfo(m_testCtx.getLog(), calibrator);
				return calibrator.getCallCount();

			case TheilSenCalibrator::STATE_MEASURE:
			{
				deUint8	buffer[4];
				deInt64 now;
				deInt64 prev;

				prev = deGetMicroseconds();

				gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
				gl.disable(GL_DEPTH_TEST);

				render(occluderGeometry);
				render(occludedGeometry, calibrator.getCallCount());

				gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

				now = deGetMicroseconds();

				calibrator.recordIteration(now - prev);
				break;
			}

			case TheilSenCalibrator::STATE_RECOMPUTE_PARAMS:
				calibrator.recomputeParameters();
				break;
			default:
				DE_ASSERT(false);
				return 1;
		}
	}
}

// Compares time/workload gradients of same geometry with and without depth testing
class RelativeChangeCase : public BaseCase
{
public:
					RelativeChangeCase	(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc);
	virtual			~RelativeChangeCase	(void) {}

protected:
	Sample			renderSample		(const RenderData& occluder, const RenderData& occluded, int workload) const;

	virtual void	logAnalysis			(const vector<Sample>& samples);

private:
	int				calibrate			(void) const;
};

RelativeChangeCase::RelativeChangeCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
	: BaseCase		(testCtx, renderCtx, name, desc)
{
}

int RelativeChangeCase::calibrate (void) const
{
	using namespace gls;

	const glw::Functions&	gl		= m_renderCtx.getFunctions();
	TestLog&				log		= m_testCtx.getLog();

	const RenderData		geom	(genOccludedGeometry(), m_renderCtx, log);

	TheilSenCalibrator calibrator(CalibratorParameters( 20, // Initial workload
														10, // Max iteration frames
														20.0f, // Iteration shortcut threshold ms
														20, // Max iterations
														33.0f, // Target frame time
														40.0f, // Frame time cap
														1000.0f // Target measurement duration
														));

	while (true)
	{
		switch(calibrator.getState())
		{
			case TheilSenCalibrator::STATE_FINISHED:
				logCalibrationInfo(m_testCtx.getLog(), calibrator);
				return calibrator.getCallCount();

			case TheilSenCalibrator::STATE_MEASURE:
			{
				deUint8			buffer[4];
				const GLuint	program	= geom.m_program.getProgram();

				gl.useProgram(program);
				gl.uniform1i(gl.getUniformLocation(program, "u_iterations"), calibrator.getCallCount());

				const deInt64 prev = deGetMicroseconds();

				gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
				gl.disable(GL_DEPTH_TEST);

				render(geom);

				gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

				const deInt64 now = deGetMicroseconds();

				calibrator.recordIteration(now - prev);
				break;
			}

			case TheilSenCalibrator::STATE_RECOMPUTE_PARAMS:
				calibrator.recomputeParameters();
				break;
			default:
				DE_ASSERT(false);
				return 1;
		}
	}
}

Sample RelativeChangeCase::renderSample (const RenderData& occluder, const RenderData& occluded, int workload) const
{
	const glw::Functions&	gl		= m_renderCtx.getFunctions();
	const GLuint			program	= occluded.m_program.getProgram();
	Sample					sample;
	deUint64				now		= 0;
	deUint64				prev	= 0;
	deUint8					buffer[4];

	gl.useProgram(program);
	gl.uniform1i(gl.getUniformLocation(program, "u_iterations"), workload);

	// Warmup (this workload seems to reduce variation in following workloads)
	{
		gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
		gl.disable(GL_DEPTH_TEST);

		gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
	}

	// Null time
	{
		prev = deGetMicroseconds();

		gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
		gl.disable(GL_DEPTH_TEST);

		gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

		now = deGetMicroseconds();

		sample.nullTime = now - prev;
	}

	// Test time
	{
		prev = deGetMicroseconds();

		gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
		gl.enable(GL_DEPTH_TEST);

		render(occluder);
		render(occluded);

		gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

		now = deGetMicroseconds();

		sample.testTime = now - prev;
	}

	// Base time
	{
		prev = deGetMicroseconds();

		gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
		gl.disable(GL_DEPTH_TEST);

		render(occluder);
		render(occluded);

		gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

		now = deGetMicroseconds();

		sample.baseTime = now - prev;
	}

	sample.workload = 0;

	return sample;
}

void RelativeChangeCase::logAnalysis (const vector<Sample>& samples)
{
	using namespace gls;

	TestLog&		log			= m_testCtx.getLog();

	int				maxWorkload	= 0;

	vector<Vec2>	nullSamples	(samples.size());
	vector<Vec2>	baseSamples	(samples.size());
	vector<Vec2>	testSamples	(samples.size());

	for (size_t ndx = 0; ndx < samples.size(); ndx++)
	{
		const Sample& sample = samples[ndx];

		nullSamples[ndx] = Vec2((float)sample.workload, (float)sample.nullTime);
		baseSamples[ndx] = Vec2((float)sample.workload, (float)sample.baseTime);
		testSamples[ndx] = Vec2((float)sample.workload, (float)sample.testTime);

		maxWorkload = de::max(maxWorkload, sample.workload);
	}

	{
		const float							confidence	= 0.60f;

		const LineParametersWithConfidence	nullParam	= theilSenSiegelLinearRegression(nullSamples, confidence);
		const LineParametersWithConfidence	baseParam	= theilSenSiegelLinearRegression(baseSamples, confidence);
		const LineParametersWithConfidence	testParam	= theilSenSiegelLinearRegression(testSamples, confidence);

		if (!de::inRange(0.0f, nullParam.coefficientConfidenceLower, nullParam.coefficientConfidenceUpper))
		{
			m_results.addResult(QP_TEST_RESULT_FAIL, "Constant operation sequence duration not constant");
			log << TestLog::Message << "Constant operation sequence timing may vary as a function of workload. Result quality extremely low" << TestLog::EndMessage;
		}

		if (de::inRange(0.0f, baseParam.coefficientConfidenceLower, baseParam.coefficientConfidenceUpper))
		{
			m_results.addResult(QP_TEST_RESULT_FAIL, "Workload has no effect on duration");
			log << TestLog::Message << "Workload factor has no effect on duration of sample (smart optimizer?)" << TestLog::EndMessage;
		}

		log << TestLog::Section("Linear Regression", "Linear Regression");
		log << TestLog::Message << "Offset & coefficient presented as [confidence interval min, estimate, confidence interval max]. Reported confidence interval for this test is " << confidence << TestLog::EndMessage;

		log << TestLog::Message << "Render time for empty scene was\n\t"
			<< "[" << nullParam.offsetConfidenceLower << ", " << nullParam.offset <<  ", " << nullParam.offsetConfidenceUpper << "]us +"
			<< "[" << nullParam.coefficientConfidenceLower << ", " << nullParam.coefficient << ", " << nullParam.coefficientConfidenceUpper << "]"
			<< "us/workload" << TestLog::EndMessage;

		log << TestLog::Message << "Render time for scene without depth test was\n\t"
			<< "[" << baseParam.offsetConfidenceLower << ", " << baseParam.offset <<  ", " << baseParam.offsetConfidenceUpper << "]us +"
			<< "[" << baseParam.coefficientConfidenceLower << ", " << baseParam.coefficient << ", " << baseParam.coefficientConfidenceUpper << "]"
			<< "us/workload" << TestLog::EndMessage;

		log << TestLog::Message << "Render time for scene with depth test was\n\t"
			<< "[" << testParam.offsetConfidenceLower << ", " << testParam.offset <<  ", " << testParam.offsetConfidenceUpper << "]us +"
			<< "[" << testParam.coefficientConfidenceLower << ", " << testParam.coefficient << ", " << testParam.coefficientConfidenceUpper << "]"
			<< "us/workload" << TestLog::EndMessage;

		log << TestLog::EndSection;

		if (de::inRange(0.0f, testParam.coefficientConfidenceLower, testParam.coefficientConfidenceUpper))
		{
			log << TestLog::Message << "Test duration not dependent on culled workload" << TestLog::EndMessage;
			m_results.addResult(QP_TEST_RESULT_PASS, "0.0");
		}
		else if (testParam.coefficientConfidenceLower < testParam.coefficientConfidenceUpper*0.25)
		{
			log << TestLog::Message << "Coefficient confidence range is extremely large, cannot give reliable result" << TestLog::EndMessage;
			m_results.addResult(QP_TEST_RESULT_PASS, "Result confidence extremely low");
		}
		else if (baseParam.coefficientConfidenceLower < baseParam.coefficientConfidenceUpper*0.25)
		{
			log << TestLog::Message << "Coefficient confidence range for base render time is extremely large, cannot give reliable result" << TestLog::EndMessage;
			m_results.addResult(QP_TEST_RESULT_PASS, "Result confidence extremely low");
		}
		else
		{
			log << TestLog::Message << "Test duration is dependent on culled workload" << TestLog::EndMessage;
			m_results.addResult(QP_TEST_RESULT_PASS, de::floatToString(de::abs(testParam.coefficient)/de::abs(baseParam.coefficient), 2));
		}
	}
}

// Speed of trivial culling
class BaseCostCase : public RenderCountCase
{
public:
						BaseCostCase		(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
							: RenderCountCase (testCtx, renderCtx, name, desc) {}

						~BaseCostCase		(void) {}

private:
	virtual ObjectData	genOccluderGeometry	(void) const { return Utils::fastQuad(0.2f); }
	virtual ObjectData	genOccludedGeometry	(void) const { return Utils::variableQuad(0.8f); }

	virtual void		logDescription		(void)
	{
		TestLog& log = m_testCtx.getLog();

		log << TestLog::Section("Description", "Test description");
		log << TestLog::Message << "Testing hidden fragment culling speed" << TestLog::EndMessage;
		log << TestLog::Message << "Geometry consists of two fullsceen quads. The first (occluding) is rendered once, the second (occluded) is rendered repeatedly" << TestLog::EndMessage;
		log << TestLog::Message << "Workload indicates the number of times the occluded quad is rendered"  << TestLog::EndMessage;
		log << TestLog::Message << "The time per culled pixel is estimated from the rate of change of rendering time as a function of workload"  << TestLog::EndMessage;
		log << TestLog::EndSection;
	}
};

// Gradient
class GradientCostCase : public RenderCountCase
{
public:
						GradientCostCase	(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc, float gradientDistance)
							: RenderCountCase		(testCtx, renderCtx, name, desc)
							, m_gradientDistance	(gradientDistance)
						{
						}

						~GradientCostCase	(void) {}

private:
	virtual ObjectData	genOccluderGeometry	(void) const { return Utils::fastQuadWithGradient(0.0f, 1.0f - m_gradientDistance); }
	virtual ObjectData	genOccludedGeometry	(void) const
	{
		return ObjectData(glu::makeVtxFragSources(Utils::getInstanceNoiseVertexShader(), Utils::getDepthAsRedFragmentShader()), Utils::getFullscreenQuadWithGradient(m_gradientDistance, 1.0f));
	}

	virtual void		logDescription		(void)
	{
		TestLog& log = m_testCtx.getLog();

		log << TestLog::Section("Description", "Test description");
		log << TestLog::Message << "Testing hidden fragment culling speed" << TestLog::EndMessage;
		log << TestLog::Message << "Geometry consists of two fullsceen quads. The first (occluding) is rendered once, the second (occluded) is rendered repeatedly" << TestLog::EndMessage;
		log << TestLog::Message << "Workload indicates the number of times the occluded quad is rendered" << TestLog::EndMessage;
		log << TestLog::Message << "The quads are tilted so that the left edge of the occluded quad has a depth of 1.0 and the right edge of the occluding quad has a depth of 0.0." << TestLog::EndMessage;
		log << TestLog::Message << "The quads are spaced to have a depth difference of " << m_gradientDistance << " at all points." << TestLog::EndMessage;
		log << TestLog::Message << "The time per culled pixel is estimated from the rate of change of rendering time as a function of workload"  << TestLog::EndMessage;
		log << TestLog::EndSection;
	}

	const float			m_gradientDistance;
};

// Constant offset to frag depth in occluder
class OccluderStaticFragDepthCostCase : public RenderCountCase
{
public:
						OccluderStaticFragDepthCostCase		(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
							: RenderCountCase(testCtx, renderCtx, name, desc)
						{
						}

						~OccluderStaticFragDepthCostCase	(void) {}

private:
	virtual ObjectData	genOccluderGeometry					(void) const { return Utils::quadWith(Utils::getStaticFragDepthFragmentShader(), 0.2f); }
	virtual ObjectData	genOccludedGeometry					(void) const { return Utils::fastQuad(0.8f); }

	virtual void		logDescription						(void)
	{
		TestLog& log = m_testCtx.getLog();

		log << TestLog::Section("Description", "Test description");
		log << TestLog::Message << "Testing hidden fragment culling speed" << TestLog::EndMessage;
		log << TestLog::Message << "Geometry consists of two fullsceen quads. The first (occluding) is rendered once, the second (occluded) is rendered repeatedly" << TestLog::EndMessage;
		log << TestLog::Message << "Workload indicates the number of times the occluded quad is rendered" << TestLog::EndMessage;
		log << TestLog::Message << "The occluder quad has a static offset applied to gl_FragDepth" << TestLog::EndMessage;
		log << TestLog::Message << "The time per culled pixel is estimated from the rate of change of rendering time as a function of workload"  << TestLog::EndMessage;
		log << TestLog::EndSection;
	}
};

// Dynamic offset to frag depth in occluder
class OccluderDynamicFragDepthCostCase : public RenderCountCase
{
public:
						OccluderDynamicFragDepthCostCase	(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
							: RenderCountCase(testCtx, renderCtx, name, desc)
						{
						}

						~OccluderDynamicFragDepthCostCase	(void) {}

private:
	virtual ObjectData	genOccluderGeometry					(void) const { return Utils::quadWith(Utils::getDynamicFragDepthFragmentShader(), 0.2f); }
	virtual ObjectData	genOccludedGeometry					(void) const { return Utils::fastQuad(0.8f); }

	virtual void		logDescription						(void)
	{
		TestLog& log = m_testCtx.getLog();

		log << TestLog::Section("Description", "Test description");
		log << TestLog::Message << "Testing hidden fragment culling speed" << TestLog::EndMessage;
		log << TestLog::Message << "Geometry consists of two fullsceen quads. The first (occluding) is rendered once, the second (occluded) is rendered repeatedly" << TestLog::EndMessage;
		log << TestLog::Message << "Workload indicates the number of times the occluded quad is rendered" << TestLog::EndMessage;
		log << TestLog::Message << "The occluder quad has a dynamic offset applied to gl_FragDepth" << TestLog::EndMessage;
		log << TestLog::Message << "The time per culled pixel is estimated from the rate of change of rendering time as a function of workload"  << TestLog::EndMessage;
		log << TestLog::EndSection;
	}
};

// Constant offset to frag depth in occluder
class OccludedStaticFragDepthCostCase : public RenderCountCase
{
public:
						OccludedStaticFragDepthCostCase		(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
							: RenderCountCase(testCtx, renderCtx, name, desc)
						{
						}

						~OccludedStaticFragDepthCostCase	(void) {}

private:
	virtual ObjectData	genOccluderGeometry					(void) const { return Utils::fastQuad(0.2f); }
	virtual ObjectData	genOccludedGeometry					(void) const { return Utils::quadWith(Utils::getStaticFragDepthFragmentShader(), 0.2f); }

	virtual void		logDescription						(void)
	{
		TestLog& log = m_testCtx.getLog();

		log << TestLog::Section("Description", "Test description");
		log << TestLog::Message << "Testing hidden fragment culling speed" << TestLog::EndMessage;
		log << TestLog::Message << "Geometry consists of two fullsceen quads. The first (occluding) is rendered once, the second (occluded) is rendered repeatedly" << TestLog::EndMessage;
		log << TestLog::Message << "Workload indicates the number of times the occluded quad is rendered" << TestLog::EndMessage;
		log << TestLog::Message << "The occluded quad has a static offset applied to gl_FragDepth" << TestLog::EndMessage;
		log << TestLog::Message << "The time per culled pixel is estimated from the rate of change of rendering time as a function of workload"  << TestLog::EndMessage;
		log << TestLog::EndSection;
	}
};

// Dynamic offset to frag depth in occluder
class OccludedDynamicFragDepthCostCase : public RenderCountCase
{
public:
						OccludedDynamicFragDepthCostCase	(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
							: RenderCountCase(testCtx, renderCtx, name, desc)
						{
						}

						~OccludedDynamicFragDepthCostCase	(void) {}

private:
	virtual ObjectData	genOccluderGeometry					(void) const { return Utils::fastQuad(0.2f); }
	virtual ObjectData	genOccludedGeometry					(void) const { return Utils::quadWith(Utils::getDynamicFragDepthFragmentShader(), 0.2f); }

	virtual void		logDescription						(void)
	{
		TestLog& log = m_testCtx.getLog();

		log << TestLog::Section("Description", "Test description");
		log << TestLog::Message << "Testing hidden fragment culling speed" << TestLog::EndMessage;
		log << TestLog::Message << "Geometry consists of two fullsceen quads. The first (occluding) is rendered once, the second (occluded) is rendered repeatedly" << TestLog::EndMessage;
		log << TestLog::Message << "Workload indicates the number of times the occluded quad is rendered" << TestLog::EndMessage;
		log << TestLog::Message << "The occluded quad has a dynamic offset applied to gl_FragDepth" << TestLog::EndMessage;
		log << TestLog::Message << "The time per culled pixel is estimated from the rate of change of rendering time as a function of workload"  << TestLog::EndMessage;
		log << TestLog::EndSection;
	}
};

// Culling speed with slightly less trivial geometry
class OccludingGeometryComplexityCostCase : public RenderCountCase
{
public:
						OccludingGeometryComplexityCostCase		(TestContext&			testCtx,
																 const RenderContext&	renderCtx,
																 const char*			name,
																 const char*			desc,
																 int					resolution,
																 float					xyNoise,
																 float					zNoise)
							: RenderCountCase	(testCtx, renderCtx, name, desc)
							, m_resolution		(resolution)
							, m_xyNoise			(xyNoise)
							, m_zNoise			(zNoise)
						{
						}

						~OccludingGeometryComplexityCostCase	(void) {}

private:
	virtual ObjectData	genOccluderGeometry						(void) const
	{
		return ObjectData(Utils::getBaseShader(),
						  Utils::getFullScreenGrid(m_resolution,
						  deInt32Hash(deStringHash(getName())) ^ m_testCtx.getCommandLine().getBaseSeed(),
						  0.2f,
						  m_zNoise,
						  m_xyNoise));
	}

	virtual ObjectData	genOccludedGeometry						(void) const { return Utils::variableQuad(0.8f); }

	virtual void		logDescription		(void)
	{
		TestLog& log = m_testCtx.getLog();

		log << TestLog::Section("Description", "Test description");
		log << TestLog::Message << "Testing hidden fragment culling speed" << TestLog::EndMessage;
		log << TestLog::Message << "Geometry consists of an occluding grid and an occluded fullsceen quad. The occluding geometry is rendered once, the occluded one is rendered repeatedly" << TestLog::EndMessage;
		log << TestLog::Message << "Workload indicates the number of times the occluded quad is rendered"  << TestLog::EndMessage;
		log << TestLog::Message << "The time per culled pixel is estimated from the rate of change of rendering time as a function of workload"  << TestLog::EndMessage;
		log << TestLog::EndSection;
	}

	const int			m_resolution;
	const float			m_xyNoise;
	const float			m_zNoise;
};


// Cases with varying workloads in the fragment shader
class FragmentWorkloadCullCase : public RelativeChangeCase
{
public:
						FragmentWorkloadCullCase	(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc);
	virtual				~FragmentWorkloadCullCase	(void) {}

private:
	virtual ObjectData	genOccluderGeometry			(void) const { return Utils::fastQuad(0.2f); }

	virtual void		logDescription				(void);
};

FragmentWorkloadCullCase::FragmentWorkloadCullCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
	: RelativeChangeCase	(testCtx, renderCtx, name, desc)
{
}

void FragmentWorkloadCullCase::logDescription (void)
{
	TestLog& log = m_testCtx.getLog();

	log << TestLog::Section("Description", "Test description");
	log << TestLog::Message << "Testing effects of culled fragment workload on render time" << TestLog::EndMessage;
	log << TestLog::Message << "Geometry consists of two fullsceen quads. The first (occluding) quad uses a trivial shader,"
		"the second (occluded) contains significant fragment shader work" << TestLog::EndMessage;
	log << TestLog::Message << "Workload indicates the number of iterations of unused work done in the occluded quad's fragment shader"  << TestLog::EndMessage;
	log << TestLog::Message << "The ratio of rendering times of this scene with/without depth testing are compared"  << TestLog::EndMessage;
	log << TestLog::Message << "Successfull early Z-testing should result in no correlation between workload and render time"  << TestLog::EndMessage;
	log << TestLog::EndSection;
}

// Additional workload consists of texture lookups
class FragmentTextureWorkloadCullCase : public FragmentWorkloadCullCase
{
public:
						FragmentTextureWorkloadCullCase		(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc);
	virtual				~FragmentTextureWorkloadCullCase	(void) {}

	virtual void		init								(void);
	virtual void		deinit								(void);

private:
	typedef MovePtr<glu::Texture> TexPtr;

	virtual ObjectData	genOccludedGeometry					(void) const
	{
		return ObjectData(Utils::getTextureWorkloadShader(), Utils::getFullscreenQuad(0.8f));
	}

	TexPtr				m_texture;
};

FragmentTextureWorkloadCullCase::FragmentTextureWorkloadCullCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
	: FragmentWorkloadCullCase	(testCtx, renderCtx, name, desc)
{
}

void FragmentTextureWorkloadCullCase::init (void)
{
	const glw::Functions&	gl		= m_renderCtx.getFunctions();
	const int				size	= 128;
	const vector<deUint8>	data	(size*size*4, 255);

	m_texture = MovePtr<glu::Texture>(new glu::Texture(gl));

	gl.bindTexture(GL_TEXTURE_2D, m_texture);
	gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}

void FragmentTextureWorkloadCullCase::deinit (void)
{
	m_texture.clear();
}

// Additional workload consists of arithmetic
class FragmentArithmeticWorkloadCullCase : public FragmentWorkloadCullCase
{
public:
						FragmentArithmeticWorkloadCullCase	(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
						: FragmentWorkloadCullCase	(testCtx, renderCtx, name, desc)
					{
					}
	virtual				~FragmentArithmeticWorkloadCullCase	(void) {}

private:
	virtual ObjectData	genOccludedGeometry					(void) const
	{
		return ObjectData(Utils::getArithmeticWorkloadShader(), Utils::getFullscreenQuad(0.8f));
	}
};

// Contains dynamicly unused discard after a series of calculations
class FragmentDiscardArithmeticWorkloadCullCase : public FragmentWorkloadCullCase
{
public:
						FragmentDiscardArithmeticWorkloadCullCase	(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
						: FragmentWorkloadCullCase	(testCtx, renderCtx, name, desc)
					{
					}

	virtual				~FragmentDiscardArithmeticWorkloadCullCase	(void) {}

private:
	virtual ObjectData	genOccludedGeometry							(void) const
	{
		return ObjectData(Utils::getArithmeticWorkloadDiscardShader(), Utils::getFullscreenQuad(0.8f));
	}

	virtual void		logDescription								(void)
	{
		TestLog& log = m_testCtx.getLog();

		log << TestLog::Section("Description", "Test description");
		log << TestLog::Message << "Testing effects of culled fragment workload on render time" << TestLog::EndMessage;
		log << TestLog::Message << "Geometry consists of two fullsceen quads. The first (occluding) quad uses a trivial shader,"
			"the second (occluded) contains significant fragment shader work and a discard that is never triggers but has a dynamic condition" << TestLog::EndMessage;
		log << TestLog::Message << "Workload indicates the number of iterations of unused work done in the occluded quad's fragment shader"  << TestLog::EndMessage;
		log << TestLog::Message << "The ratio of rendering times of this scene with/without depth testing are compared"  << TestLog::EndMessage;
		log << TestLog::Message << "Successfull early Z-testing should result in no correlation between workload and render time"  << TestLog::EndMessage;
		log << TestLog::EndSection;
	}
};

// Discards fragments from the occluder in a grid pattern
class PartialOccluderDiscardCullCase : public RelativeChangeCase
{
public:
						PartialOccluderDiscardCullCase	(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc, int gridsize)
							: RelativeChangeCase		(testCtx, renderCtx, name, desc)
							, m_gridsize	(gridsize)
						{
						}
	virtual				~PartialOccluderDiscardCullCase	(void) {}

private:
	virtual ObjectData	genOccluderGeometry				(void) const { return Utils::quadWith(Utils::getGridDiscardShader(m_gridsize), 0.2f); }
	virtual ObjectData	genOccludedGeometry				(void) const { return Utils::slowQuad(0.8f); }

	virtual void		logDescription					(void)
	{
		TestLog& log = m_testCtx.getLog();

		log << TestLog::Section("Description", "Test description");
		log << TestLog::Message << "Testing effects of partially discarded occluder on rendering time" << TestLog::EndMessage;
		log << TestLog::Message << "Geometry consists of two fullsceen quads. The first (occluding) quad discards half the "
			"fragments in a grid pattern, the second (partially occluded) contains significant fragment shader work" << TestLog::EndMessage;
		log << TestLog::Message << "Workload indicates the number of iterations of unused work done in the occluded quad's fragment shader"  << TestLog::EndMessage;
		log << TestLog::Message << "The ratio of rendering times of this scene with/without depth testing are compared"  << TestLog::EndMessage;
		log << TestLog::Message << "Successfull early Z-testing should result in depth testing halving the render time"  << TestLog::EndMessage;
		log << TestLog::EndSection;
	}

	const int			m_gridsize;
};

// Trivial occluder covering part of screen
class PartialOccluderCullCase : public RelativeChangeCase
{
public:
						PartialOccluderCullCase		(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc, float coverage)
							: RelativeChangeCase		(testCtx, renderCtx, name, desc)
							, m_coverage	(coverage)
						{
						}
						~PartialOccluderCullCase	(void) {}

private:
	virtual ObjectData	genOccluderGeometry			(void) const { return ObjectData(Utils::getBaseShader(), Utils::getPartScreenQuad(m_coverage, 0.2f)); }
	virtual ObjectData	genOccludedGeometry			(void) const {return Utils::slowQuad(0.8f); }

	virtual void		logDescription				(void)
	{
		TestLog& log = m_testCtx.getLog();

		log << TestLog::Section("Description", "Test description");
		log << TestLog::Message << "Testing effects of partial occluder on rendering time" << TestLog::EndMessage;
		log << TestLog::Message << "Geometry consists of two quads. The first (occluding) quad covers " << m_coverage*100.0f
			<< "% of the screen, while the second (partially occluded, fullscreen) contains significant fragment shader work" << TestLog::EndMessage;
		log << TestLog::Message << "Workload indicates the number of iterations of unused work done in the occluded quad's fragment shader"  << TestLog::EndMessage;
		log << TestLog::Message << "The ratio of rendering times of this scene with/without depth testing are compared"  << TestLog::EndMessage;
		log << TestLog::Message << "Successfull early Z-testing should result in render time increasing proportionally with unoccluded area"  << TestLog::EndMessage;
		log << TestLog::EndSection;
	}

	const float			m_coverage;
};

// Constant offset to frag depth in occluder
class StaticOccluderFragDepthCullCase : public RelativeChangeCase
{
public:
						StaticOccluderFragDepthCullCase		(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
							: RelativeChangeCase(testCtx, renderCtx, name, desc)
						{
						}

						~StaticOccluderFragDepthCullCase	(void) {}

private:
	virtual ObjectData	genOccluderGeometry					(void) const { return Utils::quadWith(Utils::getStaticFragDepthFragmentShader(), 0.2f); }
	virtual ObjectData	genOccludedGeometry					(void) const { return Utils::slowQuad(0.8f); }

	virtual void		logDescription						(void)
	{
		TestLog& log = m_testCtx.getLog();

		log << TestLog::Section("Description", "Test description");
		log << TestLog::Message << "Testing effects of non-default frag depth on culling efficiency" << TestLog::EndMessage;
		log << TestLog::Message << "Geometry consists of two fullscreen quads. The first (occluding) quad is trivial, while the second (occluded) contains significant fragment shader work" << TestLog::EndMessage;
		log << TestLog::Message << "Workload indicates the number of iterations of unused work done in the occluded quad's fragment shader"  << TestLog::EndMessage;
		log << TestLog::Message << "The occluder quad has a static offset applied to gl_FragDepth" << TestLog::EndMessage;
		log << TestLog::Message << "The ratio of rendering times of this scene with/without depth testing are compared"  << TestLog::EndMessage;
		log << TestLog::Message << "Successfull early Z-testing should result in no correlation between workload and render time"  << TestLog::EndMessage;
		log << TestLog::EndSection;
	}
};

// Dynamic offset to frag depth in occluder
class DynamicOccluderFragDepthCullCase : public RelativeChangeCase
{
public:
						DynamicOccluderFragDepthCullCase	(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
							: RelativeChangeCase(testCtx, renderCtx, name, desc)
						{
						}

						~DynamicOccluderFragDepthCullCase	(void) {}

private:
	virtual ObjectData	genOccluderGeometry					(void) const { return Utils::quadWith(Utils::getDynamicFragDepthFragmentShader(), 0.2f); }
	virtual ObjectData	genOccludedGeometry					(void) const { return Utils::slowQuad(0.8f); }

	virtual void		logDescription						(void)
	{
		TestLog& log = m_testCtx.getLog();

		log << TestLog::Section("Description", "Test description");
		log << TestLog::Message << "Testing effects of non-default frag depth on culling efficiency" << TestLog::EndMessage;
		log << TestLog::Message << "Geometry consists of two fullscreen quads. The first (occluding) quad is trivial, while the second (occluded) contains significant fragment shader work" << TestLog::EndMessage;
		log << TestLog::Message << "Workload indicates the number of iterations of unused work done in the occluded quad's fragment shader"  << TestLog::EndMessage;
		log << TestLog::Message << "The occluder quad has a dynamic offset applied to gl_FragDepth" << TestLog::EndMessage;
		log << TestLog::Message << "The ratio of rendering times of this scene with/without depth testing are compared"  << TestLog::EndMessage;
		log << TestLog::Message << "Successfull early Z-testing should result in no correlation between workload and render time"  << TestLog::EndMessage;
		log << TestLog::EndSection;
	}
};

// Constant offset to frag depth in occluded
class StaticOccludedFragDepthCullCase : public RelativeChangeCase
{
public:
						StaticOccludedFragDepthCullCase	(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
							: RelativeChangeCase(testCtx, renderCtx, name, desc)
						{
						}

						~StaticOccludedFragDepthCullCase	(void) {}

private:
	virtual ObjectData	genOccluderGeometry					(void) const { return Utils::fastQuad(0.2f); }
	virtual ObjectData	genOccludedGeometry					(void) const { return Utils::quadWith(Utils::getStaticFragDepthArithmeticWorkloadFragmentShader(), 0.2f); }

	virtual void		logDescription						(void)
	{
		TestLog& log = m_testCtx.getLog();

		log << TestLog::Section("Description", "Test description");
		log << TestLog::Message << "Testing effects of non-default frag depth on rendering time" << TestLog::EndMessage;
		log << TestLog::Message << "Geometry consists of two fullscreen quads. The first (occluding) quad is trivial, while the second (occluded) contains significant fragment shader work" << TestLog::EndMessage;
		log << TestLog::Message << "Workload indicates the number of iterations of unused work done in the occluded quad's fragment shader"  << TestLog::EndMessage;
		log << TestLog::Message << "The occluded quad has a static offset applied to gl_FragDepth" << TestLog::EndMessage;
		log << TestLog::Message << "The ratio of rendering times of this scene with/without depth testing are compared"  << TestLog::EndMessage;
		log << TestLog::Message << "Successfull early Z-testing should result in no correlation between workload and render time"  << TestLog::EndMessage;
		log << TestLog::EndSection;
	}
};

// Dynamic offset to frag depth in occluded
class DynamicOccludedFragDepthCullCase : public RelativeChangeCase
{
public:
						DynamicOccludedFragDepthCullCase	(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
							: RelativeChangeCase(testCtx, renderCtx, name, desc)
						{
						}

						~DynamicOccludedFragDepthCullCase	(void) {}

private:
	virtual ObjectData	genOccluderGeometry					(void) const { return Utils::fastQuad(0.2f); }
	virtual ObjectData	genOccludedGeometry					(void) const { return Utils::quadWith(Utils::getDynamicFragDepthArithmeticWorkloadFragmentShader(), 0.2f); }

	virtual void		logDescription						(void)
	{
		TestLog& log = m_testCtx.getLog();

		log << TestLog::Section("Description", "Test description");
		log << TestLog::Message << "Testing effects of non-default frag depth on rendering time" << TestLog::EndMessage;
		log << TestLog::Message << "Geometry consists of two fullscreen quads. The first (occluding) quad is trivial, while the second (occluded) contains significant fragment shader work" << TestLog::EndMessage;
		log << TestLog::Message << "Workload indicates the number of iterations of unused work done in the occluded quad's fragment shader"  << TestLog::EndMessage;
		log << TestLog::Message << "The occluded quad has a dynamic offset applied to gl_FragDepth" << TestLog::EndMessage;
		log << TestLog::Message << "The ratio of rendering times of this scene with/without depth testing are compared"  << TestLog::EndMessage;
		log << TestLog::Message << "Successfull early Z-testing should result in no correlation between workload and render time"  << TestLog::EndMessage;
		log << TestLog::EndSection;
	}
};

// Dynamic offset to frag depth in occluded
class ReversedDepthOrderCullCase : public RelativeChangeCase
{
public:
						ReversedDepthOrderCullCase	(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
							: RelativeChangeCase(testCtx, renderCtx, name, desc)
						{
						}

						~ReversedDepthOrderCullCase	(void) {}

private:
	virtual ObjectData	genOccluderGeometry			(void) const { return Utils::fastQuad(0.2f); }
	virtual ObjectData	genOccludedGeometry			(void) const { return Utils::slowQuad(0.8f); }

	virtual void		logDescription				(void)
	{
		TestLog& log = m_testCtx.getLog();

		log << TestLog::Section("Description", "Test description");
		log << TestLog::Message << "Testing effects of of back first rendering order on culling efficiency" << TestLog::EndMessage;
		log << TestLog::Message << "Geometry consists of two fullscreen quads. The second (occluding) quad is trivial, while the first (occluded) contains significant fragment shader work" << TestLog::EndMessage;
		log << TestLog::Message << "Workload indicates the number of iterations of unused work done in the occluded quad's fragment shader"  << TestLog::EndMessage;
		log << TestLog::Message << "The ratio of rendering times of this scene with/without depth testing are compared"  << TestLog::EndMessage;
		log << TestLog::Message << "Successfull early Z-testing should result in no correlation between workload and render time"  << TestLog::EndMessage;
		log << TestLog::EndSection;
	}

	// Rendering order of occluder & occluded is reversed, otherwise identical to parent version
	Sample				renderSample				(const RenderData& occluder, const RenderData& occluded, int workload) const
	{
		const glw::Functions&	gl		= m_renderCtx.getFunctions();
		const GLuint			program	= occluded.m_program.getProgram();
		Sample					sample;
		deUint64				now		= 0;
		deUint64				prev	= 0;
		deUint8					buffer[4];

		gl.useProgram(program);
		gl.uniform1i(gl.getUniformLocation(program, "u_iterations"), workload);

		// Warmup (this workload seems to reduce variation in following workloads)
		{
			gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
			gl.disable(GL_DEPTH_TEST);

			gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
		}

		// Null time
		{
			prev = deGetMicroseconds();

			gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
			gl.disable(GL_DEPTH_TEST);

			gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

			now = deGetMicroseconds();

			sample.nullTime = now - prev;
		}

		// Test time
		{
			prev = deGetMicroseconds();

			gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
			gl.enable(GL_DEPTH_TEST);

			render(occluded);
			render(occluder);

			gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

			now = deGetMicroseconds();

			sample.testTime = now - prev;
		}

		// Base time
		{
			prev = deGetMicroseconds();

			gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
			gl.disable(GL_DEPTH_TEST);

			render(occluded);
			render(occluder);

			gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

			now = deGetMicroseconds();

			sample.baseTime = now - prev;
		}

		sample.workload = 0;

		return sample;
	}
};

} // Anonymous

DepthTests::DepthTests (Context& context)
	: TestCaseGroup (context, "depth", "Depth culling performance")
{
}

void DepthTests::init (void)
{
	TestContext&			testCtx		= m_context.getTestContext();
	const RenderContext&	renderCtx	= m_context.getRenderContext();

	{
		tcu::TestCaseGroup* const cullEfficiencyGroup = new tcu::TestCaseGroup(m_testCtx, "cull_efficiency", "Fragment cull efficiency");

		addChild(cullEfficiencyGroup);

		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "workload", "Workload");

			cullEfficiencyGroup->addChild(group);

			group->addChild(new FragmentTextureWorkloadCullCase(			testCtx, renderCtx, "workload_texture",				"Fragment shader with texture lookup workload"));
			group->addChild(new FragmentArithmeticWorkloadCullCase(			testCtx, renderCtx, "workload_arithmetic",			"Fragment shader with arithmetic workload"));
			group->addChild(new FragmentDiscardArithmeticWorkloadCullCase(	testCtx, renderCtx, "workload_arithmetic_discard",	"Fragment shader that may discard with arithmetic workload"));
		}

		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "occluder_discard", "Discard");

			cullEfficiencyGroup->addChild(group);

			group->addChild(new PartialOccluderDiscardCullCase(testCtx, renderCtx, "grid_256",	"Parts of occluder geometry discarded", 256));
			group->addChild(new PartialOccluderDiscardCullCase(testCtx, renderCtx, "grid_128",	"Parts of occluder geometry discarded", 128));
			group->addChild(new PartialOccluderDiscardCullCase(testCtx, renderCtx, "grid_64",	"Parts of occluder geometry discarded", 64));
			group->addChild(new PartialOccluderDiscardCullCase(testCtx, renderCtx, "grid_32",	"Parts of occluder geometry discarded", 32));
			group->addChild(new PartialOccluderDiscardCullCase(testCtx, renderCtx, "grid_16",	"Parts of occluder geometry discarded", 16));
			group->addChild(new PartialOccluderDiscardCullCase(testCtx, renderCtx, "grid_8",	"Parts of occluder geometry discarded", 8));
			group->addChild(new PartialOccluderDiscardCullCase(testCtx, renderCtx, "grid_4",	"Parts of occluder geometry discarded", 4));
			group->addChild(new PartialOccluderDiscardCullCase(testCtx, renderCtx, "grid_2",	"Parts of occluder geometry discarded", 2));
			group->addChild(new PartialOccluderDiscardCullCase(testCtx, renderCtx, "grid_1",	"Parts of occluder geometry discarded", 1));
		}

		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "partial_coverage", "Partial Coverage");

			cullEfficiencyGroup->addChild(group);

			group->addChild(new PartialOccluderCullCase(testCtx, renderCtx, "100", "Occluder covering only part of occluded geometry", 1.00f));
			group->addChild(new PartialOccluderCullCase(testCtx, renderCtx, "099", "Occluder covering only part of occluded geometry", 0.99f));
			group->addChild(new PartialOccluderCullCase(testCtx, renderCtx, "095", "Occluder covering only part of occluded geometry", 0.95f));
			group->addChild(new PartialOccluderCullCase(testCtx, renderCtx, "090", "Occluder covering only part of occluded geometry", 0.90f));
			group->addChild(new PartialOccluderCullCase(testCtx, renderCtx, "080", "Occluder covering only part of occluded geometry", 0.80f));
			group->addChild(new PartialOccluderCullCase(testCtx, renderCtx, "070", "Occluder covering only part of occluded geometry", 0.70f));
			group->addChild(new PartialOccluderCullCase(testCtx, renderCtx, "050", "Occluder covering only part of occluded geometry", 0.50f));
			group->addChild(new PartialOccluderCullCase(testCtx, renderCtx, "025", "Occluder covering only part of occluded geometry", 0.25f));
			group->addChild(new PartialOccluderCullCase(testCtx, renderCtx, "010", "Occluder covering only part of occluded geometry", 0.10f));
		}

		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "frag_depth", "Partial Coverage");

			cullEfficiencyGroup->addChild(group);

			group->addChild(new StaticOccluderFragDepthCullCase( testCtx, renderCtx, "occluder_static", ""));
			group->addChild(new DynamicOccluderFragDepthCullCase(testCtx, renderCtx, "occluder_dynamic", ""));
			group->addChild(new StaticOccludedFragDepthCullCase( testCtx, renderCtx, "occluded_static", ""));
			group->addChild(new DynamicOccludedFragDepthCullCase(testCtx, renderCtx, "occluded_dynamic", ""));
		}

		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "order", "Rendering order");

			cullEfficiencyGroup->addChild(group);

			group->addChild(new ReversedDepthOrderCullCase(testCtx, renderCtx, "reversed", "Back to front rendering order"));
		}
	}

	{
		tcu::TestCaseGroup* const testCostGroup = new tcu::TestCaseGroup(m_testCtx, "culled_pixel_cost", "Fragment cull efficiency");

		addChild(testCostGroup);

		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "gradient", "Gradients with small depth differences");

			testCostGroup->addChild(group);

			group->addChild(new BaseCostCase(testCtx, renderCtx, "flat", ""));
			group->addChild(new GradientCostCase(testCtx, renderCtx, "gradient_050", "", 0.50f));
			group->addChild(new GradientCostCase(testCtx, renderCtx, "gradient_010", "", 0.10f));
			group->addChild(new GradientCostCase(testCtx, renderCtx, "gradient_005", "", 0.05f));
			group->addChild(new GradientCostCase(testCtx, renderCtx, "gradient_002", "", 0.02f));
			group->addChild(new GradientCostCase(testCtx, renderCtx, "gradient_001", "", 0.01f));
		}

		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "occluder_geometry", "Occluders with varying geometry complexity");

			testCostGroup->addChild(group);

			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_uniform_grid_5",   "", 5,   0.0f, 0.0f));
			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_uniform_grid_15",  "", 15,  0.0f, 0.0f));
			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_uniform_grid_25",  "", 25,  0.0f, 0.0f));
			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_uniform_grid_50",  "", 50,  0.0f, 0.0f));
			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_uniform_grid_100", "", 100, 0.0f, 0.0f));

			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_noisy_grid_5",   "", 5,   1.0f/5.0f,   0.0f));
			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_noisy_grid_15",  "", 15,  1.0f/15.0f,  0.0f));
			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_noisy_grid_25",  "", 25,  1.0f/25.0f,  0.0f));
			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_noisy_grid_50",  "", 50,  1.0f/50.0f,  0.0f));
			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "flat_noisy_grid_100", "", 100, 1.0f/100.0f, 0.0f));

			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_uniform_grid_5",   "", 5,   0.0f, 0.2f));
			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_uniform_grid_15",  "", 15,  0.0f, 0.2f));
			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_uniform_grid_25",  "", 25,  0.0f, 0.2f));
			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_uniform_grid_50",  "", 50,  0.0f, 0.2f));
			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_uniform_grid_100", "", 100, 0.0f, 0.2f));

			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_noisy_grid_5",   "", 5,   1.0f/5.0f,   0.2f));
			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_noisy_grid_15",  "", 15,  1.0f/15.0f,  0.2f));
			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_noisy_grid_25",  "", 25,  1.0f/25.0f,  0.2f));
			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_noisy_grid_50",  "", 50,  1.0f/50.0f,  0.2f));
			group->addChild(new OccludingGeometryComplexityCostCase(testCtx, renderCtx, "uneven_noisy_grid_100", "", 100, 1.0f/100.0f, 0.2f));
		}

		{
			tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(m_testCtx, "frag_depth", "Modifying gl_FragDepth");

			testCostGroup->addChild(group);

			group->addChild(new OccluderStaticFragDepthCostCase( testCtx, renderCtx, "occluder_static", ""));
			group->addChild(new OccluderDynamicFragDepthCostCase(testCtx, renderCtx, "occluder_dynamic", ""));
			group->addChild(new OccludedStaticFragDepthCostCase( testCtx, renderCtx, "occluded_static", ""));
			group->addChild(new OccludedDynamicFragDepthCostCase(testCtx, renderCtx, "occluded_dynamic", ""));
		}
	}
}

} // Performance
} // gles3
} // deqp
