18852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry/*-------------------------------------------------------------------------
28852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * drawElements Quality Program OpenGL ES 3.0 Module
38852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * -------------------------------------------------
48852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry *
58852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * Copyright 2014 The Android Open Source Project
68852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry *
78852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
88852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * you may not use this file except in compliance with the License.
98852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * You may obtain a copy of the License at
108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry *
118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry *
138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * See the License for the specific language governing permissions and
178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * limitations under the License.
188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry *
198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry *//*!
208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * \file
218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry * \brief Depth buffer performance tests.
228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry *//*--------------------------------------------------------------------*/
238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "es3pDepthTests.hpp"
258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "glsCalibration.hpp"
278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "gluShaderProgram.hpp"
298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "gluObjectWrapper.hpp"
308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "gluPixelTransfer.hpp"
318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "glwFunctions.hpp"
338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "glwEnums.hpp"
348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "tcuTestLog.hpp"
368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "tcuStringTemplate.hpp"
378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "tcuCPUWarmup.hpp"
388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "tcuCommandLine.hpp"
398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "deClock.h"
418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "deString.h"
428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "deMath.h"
438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "deStringUtil.hpp"
448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "deRandom.hpp"
458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include "deUniquePtr.hpp"
468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include <vector>
488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry#include <algorithm>
498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrynamespace deqp
518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrynamespace gles3
538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrynamespace Performance
558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrynamespace
578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryusing namespace glw;
598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryusing de::MovePtr;
608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryusing tcu::TestContext;
618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryusing tcu::TestLog;
628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryusing tcu::Vec4;
638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryusing tcu::Vec3;
648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryusing tcu::Vec2;
658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryusing glu::RenderContext;
668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryusing glu::ProgramSources;
678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryusing glu::ShaderSource;
688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryusing std::vector;
698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryusing std::string;
708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryusing std::map;
718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrystruct Sample
738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	deInt64	nullTime;
758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	deInt64	baseTime;
768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	deInt64	testTime;
778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	int		order;
788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	int		workload;
798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry};
808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrystruct SampleParams
828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	int step;
848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	int measurement;
858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	SampleParams(int step_, int measurement_) : step(step_), measurement(measurement_) {}
878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry};
888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrytypedef vector<float> Geometry;
908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrystruct ObjectData
928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	ProgramSources	shader;
948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	Geometry		geometry;
958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	ObjectData (const ProgramSources& shader_, const Geometry& geometry_) : shader(shader_), geometry(geometry_) {}
978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry};
988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryclass RenderData
1008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
1018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrypublic:
1028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry								RenderData		(const ObjectData& object, const glu::RenderContext& renderCtx, TestLog& log);
1038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry								~RenderData		(void) {};
1048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const glu::ShaderProgram	m_program;
1068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const glu::VertexArray		m_vao;
1078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const glu::Buffer			m_vbo;
1088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const int					m_numVertices;
1108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry};
1118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko PoyryRenderData::RenderData (const ObjectData& object, const  glu::RenderContext& renderCtx, TestLog& log)
1138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	: m_program		(renderCtx, object.shader)
1148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	, m_vao			(renderCtx.getFunctions())
1158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	, m_vbo			(renderCtx.getFunctions())
1168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	, m_numVertices	(int(object.geometry.size())/4)
1178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
1188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const glw::Functions& gl = renderCtx.getFunctions();
1198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	if (!m_program.isOk())
1218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		log << m_program;
1228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.bindBuffer(GL_ARRAY_BUFFER, *m_vbo);
1248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.bufferData(GL_ARRAY_BUFFER, object.geometry.size() * sizeof(float), &object.geometry[0], GL_STATIC_DRAW);
1258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.bindAttribLocation(m_program.getProgram(), 0, "a_position");
1268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.bindVertexArray(*m_vao);
1288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.vertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, DE_NULL);
1298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.enableVertexAttribArray(0);
1308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.bindVertexArray(0);
1318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
1328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrynamespace Utils
1348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
1358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	vector<float> getFullscreenQuad (float depth)
1368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
1378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		const float data[] =
1388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		{
1398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			+1.0f, +1.0f, depth, 0.0f, // .w is gl_VertexId%3 since Nexus 4&5 can't handle that on their own
1408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			+1.0f, -1.0f, depth, 1.0f,
1418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			-1.0f, -1.0f, depth, 2.0f,
1428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			-1.0f, -1.0f, depth, 0.0f,
1438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			-1.0f, +1.0f, depth, 1.0f,
1448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			+1.0f, +1.0f, depth, 2.0f,
1458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		};
1468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return vector<float>(DE_ARRAY_BEGIN(data), DE_ARRAY_END(data));
1488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
1498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	vector<float> getFullscreenQuadWithGradient (float depth0, float depth1)
1518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
1528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		const float data[] =
1538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		{
1548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			+1.0f, +1.0f, depth0, 0.0f,
1558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			+1.0f, -1.0f, depth0, 1.0f,
1568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			-1.0f, -1.0f, depth1, 2.0f,
1578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			-1.0f, -1.0f, depth1, 0.0f,
1588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			-1.0f, +1.0f, depth1, 1.0f,
1598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			+1.0f, +1.0f, depth0, 2.0f,
1608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		};
1618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return vector<float>(DE_ARRAY_BEGIN(data), DE_ARRAY_END(data));
1638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
1648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	vector<float> getPartScreenQuad (float coverage, float depth)
1668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
1678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		const float xMax	= -1.0f + 2.0f*coverage;
1688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		const float data[]	=
1698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		{
1708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			 xMax, +1.0f, depth, 0.0f,
1718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			 xMax, -1.0f, depth, 1.0f,
1728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			-1.0f, -1.0f, depth, 2.0f,
1738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			-1.0f, -1.0f, depth, 0.0f,
1748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			-1.0f, +1.0f, depth, 1.0f,
1758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			 xMax, +1.0f, depth, 2.0f,
1768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		};
1778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return vector<float>(DE_ARRAY_BEGIN(data), DE_ARRAY_END(data));
1798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
1808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	// Axis aligned grid. Depth of vertices is baseDepth +/- depthNoise
1828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	vector<float> getFullScreenGrid (int resolution, deUint32 seed, float baseDepth, float depthNoise, float xyNoise)
1838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
1848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		const int		gridsize	= resolution+1;
1858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		vector<Vec3>	vertices	(gridsize*gridsize);
1868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		vector<float>	retval;
1878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		de::Random		rng			(seed);
1888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		for (int y = 0; y < gridsize; y++)
1908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		for (int x = 0; x < gridsize; x++)
1918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		{
1928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			const bool	isEdge	= x == 0 || y == 0 || x == resolution || y == resolution;
1938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			const float x_		= float(x)/float(resolution)*2.0f - 1.0f + (isEdge ? 0.0f : rng.getFloat(-xyNoise, +xyNoise));
1948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			const float y_		= float(y)/float(resolution)*2.0f - 1.0f + (isEdge ? 0.0f : rng.getFloat(-xyNoise, +xyNoise));
1958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			const float z_		= baseDepth + rng.getFloat(-depthNoise, +depthNoise);
1968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
1978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			vertices[y*gridsize + x] = Vec3(x_, y_, z_);
1988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		}
1998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		retval.reserve(resolution*resolution*6);
2018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		for (int y = 0; y < resolution; y++)
2038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		for (int x = 0; x < resolution; x++)
2048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		{
2058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			const Vec3& p0 = vertices[(y+0)*gridsize + (x+0)];
2068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			const Vec3& p1 = vertices[(y+0)*gridsize + (x+1)];
2078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			const Vec3& p2 = vertices[(y+1)*gridsize + (x+0)];
2088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			const Vec3& p3 = vertices[(y+1)*gridsize + (x+1)];
2098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			const float temp[6*4] =
2118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			{
2128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				p0.x(), p0.y(), p0.z(), 0.0f,
2138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				p2.x(), p2.y(), p2.z(), 1.0f,
2148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				p1.x(), p1.y(), p1.z(), 2.0f,
2158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				p3.x(), p3.y(), p3.z(), 0.0f,
2178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				p1.x(), p1.y(), p1.z(), 1.0f,
2188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				p2.x(), p2.y(), p2.z(), 2.0f,
2198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			};
2208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			retval.insert(retval.end(), DE_ARRAY_BEGIN(temp), DE_ARRAY_END(temp));
2228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		}
2238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return retval;
2258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
2268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	// Outputs barycentric coordinates as v_bcoords. Otherwise a passthrough shader
2288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	string getBaseVertexShader (void)
2298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
2308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return "#version 300 es\n"
2318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"in highp vec4 a_position;\n"
2328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"out mediump vec3 v_bcoords;\n"
2338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"void main()\n"
2348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"{\n"
2358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	v_bcoords = vec3(0, 0, 0);\n"
2368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	v_bcoords[int(a_position.w)] = 1.0;\n"
2378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	gl_Position = vec4(a_position.xyz, 1.0);\n"
2388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"}\n";
2398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
2408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	// Adds noise to coordinates based on InstanceID Outputs barycentric coordinates as v_bcoords
2428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	string getInstanceNoiseVertexShader (void)
2438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
2448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return "#version 300 es\n"
2458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"in highp vec4 a_position;\n"
2468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"out mediump vec3 v_bcoords;\n"
2478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"void main()\n"
2488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"{\n"
2498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	v_bcoords = vec3(0, 0, 0);\n"
2508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	v_bcoords[int(a_position.w)] = 1.0;\n"
2518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	vec3 noise = vec3(sin(float(gl_InstanceID)*1.05), sin(float(gl_InstanceID)*1.23), sin(float(gl_InstanceID)*1.71));\n"
2528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	gl_Position = vec4(a_position.xyz + noise * 0.005, 1.0);\n"
2538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"}\n";
2548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
2558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	// Renders green triangles with edges highlighted. Exact shade depends on depth.
2578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	string getDepthAsGreenFragmentShader (void)
2588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
2598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return	"#version 300 es\n"
2608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"in mediump vec3 v_bcoords;\n"
2618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"out mediump vec4 fragColor;\n"
2628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"void main()\n"
2638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"{\n"
2648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	mediump float d = gl_FragCoord.z;\n"
2658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
2668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		fragColor = vec4(d,1,d,1);\n"
2678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	else\n"
2688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		fragColor = vec4(0,d,0,1);\n"
2698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"}\n";
2708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
2718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	// Renders green triangles with edges highlighted. Exact shade depends on depth.
2738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	string getDepthAsRedFragmentShader (void)
2748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
2758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return	"#version 300 es\n"
2768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"in mediump vec3 v_bcoords;\n"
2778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"out mediump vec4 fragColor;\n"
2788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"void main()\n"
2798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"{\n"
2808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	mediump float d = gl_FragCoord.z;\n"
2818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
2828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		fragColor = vec4(1,d,d,1);\n"
2838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	else\n"
2848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		fragColor = vec4(d,0,0,1);\n"
2858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"}\n";
2868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
2878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	// Basic time waster. Renders red triangles with edges highlighted. Exact shade depends on depth.
2898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	string getArithmeticWorkloadFragmentShader (void)
2908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
2918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
2928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return	"#version 300 es\n"
2938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"in mediump vec3 v_bcoords;\n"
2948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"out mediump vec4 fragColor;\n"
2958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"uniform mediump int u_iterations;\n"
2968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"void main()\n"
2978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"{\n"
2988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	mediump float d = gl_FragCoord.z;\n"
2998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	for (int i = 0; i<u_iterations; i++)\n"
3008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				// 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
3018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		d = d*sin(d)*sin(d) + d*cos(d)*cos(d);\n"
3028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
3038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		fragColor = vec4(1,d,d,1);\n"
3048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	else\n"
3058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		fragColor = vec4(d,0,0,1);\n"
3068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"}\n";
3078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
3088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
3098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	// Arithmetic workload shader but contains discard
3108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	string getArithmeticWorkloadDiscardFragmentShader (void)
3118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
3128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return	"#version 300 es\n"
3138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"in mediump vec3 v_bcoords;\n"
3148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"out mediump vec4 fragColor;\n"
3158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"uniform mediump int u_iterations;\n"
3168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"void main()\n"
3178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"{\n"
3188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	mediump float d = gl_FragCoord.z;\n"
3198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	for (int i = 0; i<u_iterations; i++)\n"
3208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		d = d*sin(d)*sin(d) + d*cos(d)*cos(d);\n"
3218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	if (d < 0.5) discard;\n"
3228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
3238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		fragColor = vec4(1,d,d,1);\n"
3248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	else\n"
3258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		fragColor = vec4(d,0,0,1);\n"
3268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"}\n";
3278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
3288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
3298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	// Texture fetch based time waster. Renders red triangles with edges highlighted. Exact shade depends on depth.
3308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	string getTextureWorkloadFragmentShader (void)
3318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
3328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return  "#version 300 es\n"
3338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"in mediump vec3 v_bcoords;\n"
3348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"out mediump vec4 fragColor;\n"
3358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"uniform mediump int u_iterations;\n"
3368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"uniform sampler2D u_texture;\n"
3378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"void main()\n"
3388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"{\n"
3398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	mediump float d = gl_FragCoord.z;\n"
3408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	for (int i = 0; i<u_iterations; i++)\n"
3418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		d *= texture(u_texture, (gl_FragCoord.xy+vec2(i))/512.0).r;\n" // Texture is expected to be fully white
3428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
3438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		fragColor = vec4(1,1,1,1);\n"
3448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	else\n"
3458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		fragColor = vec4(d,0,0,1);\n"
3468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"}\n";
3478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
3488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
3498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	// Discard fragments in a grid pattern
3508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	string getGridDiscardFragmentShader (int gridsize)
3518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
3528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		const string		fragSrc = "#version 300 es\n"
3538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry									  "in mediump vec3 v_bcoords;\n"
3548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry									  "out mediump vec4 fragColor;\n"
3558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry									  "void main()\n"
3568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry									  "{\n"
3578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry									  "	mediump float d = gl_FragCoord.z;\n"
3588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry									  "	if ((int(gl_FragCoord.x)/${GRIDRENDER_SIZE} + int(gl_FragCoord.y)/${GRIDRENDER_SIZE})%2 == 0)\n"
3598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry									  "		discard;\n"
3608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry									  "	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
3618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry									  "		fragColor = vec4(d,1,d,1);\n"
3628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry									  "	else\n"
3638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry									  "		fragColor = vec4(0,d,0,1);\n"
3648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry									  "}\n";
3658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		map<string, string>	params;
3668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
3678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		params["GRIDRENDER_SIZE"] = de::toString(gridsize);
3688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
3698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return tcu::StringTemplate(fragSrc).specialize(params);
3708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
3718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
3728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	// A static increment to frag depth
3738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	string getStaticFragDepthFragmentShader (void)
3748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
3758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return	"#version 300 es\n"
3768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"in mediump vec3 v_bcoords;\n"
3778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"out mediump vec4 fragColor;\n"
3788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"void main()\n"
3798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"{\n"
3808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	mediump float d = gl_FragCoord.z;\n"
3818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	gl_FragDepth = gl_FragCoord.z + 0.1;\n"
3828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
3838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		fragColor = vec4(d,1,d,1);\n"
3848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	else\n"
3858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		fragColor = vec4(0,d,0,1);\n"
3868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"}\n";
3878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
3888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
3898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	// A trivial dynamic change to frag depth
3908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	string getDynamicFragDepthFragmentShader (void)
3918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
3928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return	"#version 300 es\n"
3938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"in mediump vec3 v_bcoords;\n"
3948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"out mediump vec4 fragColor;\n"
3958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"void main()\n"
3968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"{\n"
3978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	mediump float d = gl_FragCoord.z;\n"
3988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	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
3998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
4008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		fragColor = vec4(d,1,d,1);\n"
4018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	else\n"
4028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		fragColor = vec4(0,d,0,1);\n"
4038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"}\n";
4048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
4058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
4068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	// A static increment to frag depth
4078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	string getStaticFragDepthArithmeticWorkloadFragmentShader (void)
4088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
4098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return	"#version 300 es\n"
4108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"in mediump vec3 v_bcoords;\n"
4118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"out mediump vec4 fragColor;\n"
4128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"uniform mediump int u_iterations;\n"
4138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"void main()\n"
4148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"{\n"
4158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	mediump float d = gl_FragCoord.z;\n"
4168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	gl_FragDepth = gl_FragCoord.z + 0.1;\n"
4178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	for (int i = 0; i<u_iterations; i++)\n"
4188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		d = d*sin(d)*sin(d) + d*cos(d)*cos(d);\n"
4198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
4208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		fragColor = vec4(1,d,d,1);\n"
4218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	else\n"
4228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		fragColor = vec4(d,0,0,1);\n"
4238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"}\n";
4248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
4258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
4268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	// A trivial dynamic change to frag depth
4278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	string getDynamicFragDepthArithmeticWorkloadFragmentShader (void)
4288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
4298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return	"#version 300 es\n"
4308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"in mediump vec3 v_bcoords;\n"
4318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"out mediump vec4 fragColor;\n"
4328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"uniform mediump int u_iterations;\n"
4338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"void main()\n"
4348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"{\n"
4358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	mediump float d = gl_FragCoord.z;\n"
4368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	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
4378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	for (int i = 0; i<u_iterations; i++)\n"
4388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		d = d*sin(d)*sin(d) + d*cos(d)*cos(d);\n"
4398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	if (v_bcoords.x < 0.02 || v_bcoords.y < 0.02 || v_bcoords.z < 0.02)\n"
4408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		fragColor = vec4(1,d,d,1);\n"
4418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"	else\n"
4428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"		fragColor = vec4(d,0,0,1);\n"
4438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				"}\n";
4448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
4458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
4468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	glu::ProgramSources getBaseShader (void)
4478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
4488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return glu::makeVtxFragSources(getBaseVertexShader(), getDepthAsGreenFragmentShader());
4498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
4508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
4518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	glu::ProgramSources getArithmeticWorkloadShader (void)
4528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
4538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return glu::makeVtxFragSources(getBaseVertexShader(), getArithmeticWorkloadFragmentShader());
4548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
4558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
4568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	glu::ProgramSources getArithmeticWorkloadDiscardShader (void)
4578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
4588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return glu::makeVtxFragSources(getBaseVertexShader(), getArithmeticWorkloadDiscardFragmentShader());
4598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
4608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
4618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	glu::ProgramSources getTextureWorkloadShader (void)
4628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
4638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return glu::makeVtxFragSources(getBaseVertexShader(), getTextureWorkloadFragmentShader());
4648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
4658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
4668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	glu::ProgramSources getGridDiscardShader (int gridsize)
4678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
4688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return glu::makeVtxFragSources(getBaseVertexShader(), getGridDiscardFragmentShader(gridsize));
4698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
4708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
4718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	inline ObjectData quadWith (const glu::ProgramSources& shader, float depth)
4728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
4738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return ObjectData(shader, getFullscreenQuad(depth));
4748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
4758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
4768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	inline ObjectData quadWith (const string& fragShader, float depth)
4778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
4788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return ObjectData(glu::makeVtxFragSources(getBaseVertexShader(), fragShader), getFullscreenQuad(depth));
4798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
4808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
4818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	inline ObjectData variableQuad (float depth)
4828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
4838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return ObjectData(glu::makeVtxFragSources(getInstanceNoiseVertexShader(), getDepthAsRedFragmentShader()), getFullscreenQuad(depth));
4848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
4858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
4868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	inline ObjectData fastQuad (float depth)
4878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
4888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return ObjectData(getBaseShader(), getFullscreenQuad(depth));
4898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
4908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
4918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	inline ObjectData slowQuad (float depth)
4928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
4938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return ObjectData(getArithmeticWorkloadShader(), getFullscreenQuad(depth));
4948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
4958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
4968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	inline ObjectData fastQuadWithGradient (float depth0, float depth1)
4978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
4988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		return ObjectData(getBaseShader(), getFullscreenQuadWithGradient(depth0, depth1));
4998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
5008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry} // Utils
5018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry// Shared base
5038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryclass BaseCase : public tcu::TestCase
5048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
5058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrypublic:
5068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	enum {RENDER_SIZE = 512};
5078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry							BaseCase			(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc);
5098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	virtual					~BaseCase			(void) {}
5108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	virtual IterateResult	iterate				(void);
5128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryprotected:
5148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	void					logSamples			(const vector<Sample>& samples, const string& name, const string& desc);
5158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	void					logGeometry			(const tcu::ConstPixelBufferAccess& sample, const glu::ShaderProgram& occluderProg, const glu::ShaderProgram& occludedProg);
5168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	virtual void			logAnalysis			(const vector<Sample>& samples) = 0;
5178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	virtual void			logDescription		(void) = 0;
5188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	virtual ObjectData		genOccluderGeometry	(void) const = 0;
5208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	virtual ObjectData		genOccludedGeometry	(void) const = 0;
5218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	virtual int				calibrate			(void) const = 0;
5238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	virtual Sample			renderSample		(const RenderData& occluder, const RenderData& occluded, int workload) const = 0;
5248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	void					render				(const RenderData& data) const;
5268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	void					render				(const RenderData& data, int instances) const;
5278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const RenderContext&	m_renderCtx;
5298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	tcu::ResultCollector	m_results;
5308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	enum {ITERATION_STEPS = 10, ITERATION_SAMPLES = 16};
5328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry};
5338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko PoyryBaseCase::BaseCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
5358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	: TestCase		(testCtx, tcu::NODETYPE_PERFORMANCE, name, desc)
5368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	, m_renderCtx	(renderCtx)
5378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
5388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
5398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko PoyryBaseCase::IterateResult BaseCase::iterate (void)
5418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
5428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	typedef de::MovePtr<RenderData> RenderDataP;
5438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const glw::Functions&	gl					= m_renderCtx.getFunctions();
5458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	TestLog&				log					= m_testCtx.getLog();
5468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const glu::Framebuffer	framebuffer			(gl);
5488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const glu::Renderbuffer	renderbuffer		(gl);
5498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const glu::Renderbuffer	depthbuffer			(gl);
5508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	vector<Sample>			results;
5528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	vector<int>				params;
5538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	RenderDataP				occluderData;
5548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	RenderDataP				occludedData;
5558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	tcu::TextureLevel		resultTex			(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), RENDER_SIZE, RENDER_SIZE);
5568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	int						maxWorkload			= 0;
5578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	de::Random				rng					(deInt32Hash(deStringHash(getName())) ^ m_testCtx.getCommandLine().getBaseSeed());
5588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	logDescription();
5608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.bindRenderbuffer(GL_RENDERBUFFER, *renderbuffer);
5628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, RENDER_SIZE, RENDER_SIZE);
5638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.bindRenderbuffer(GL_RENDERBUFFER, *depthbuffer);
5648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, RENDER_SIZE, RENDER_SIZE);
5658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.bindFramebuffer(GL_FRAMEBUFFER, *framebuffer);
5678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *renderbuffer);
5688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *depthbuffer);
5698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.viewport(0, 0, RENDER_SIZE, RENDER_SIZE);
5708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.clearColor(0.125f, 0.25f, 0.5f, 1.0f);
5718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	maxWorkload = calibrate();
5738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	// Setup data
5758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	occluderData = RenderDataP(new RenderData (genOccluderGeometry(), m_renderCtx, log));
5768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	occludedData = RenderDataP(new RenderData (genOccludedGeometry(), m_renderCtx, log));
5778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	TCU_CHECK(occluderData->m_program.isOk());
5798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	TCU_CHECK(occludedData->m_program.isOk());
5808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	// Force initialization of GPU resources
5828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
5838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.enable(GL_DEPTH_TEST);
5848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	render(*occluderData);
5868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	render(*occludedData);
5878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	glu::readPixels(m_renderCtx, 0, 0, resultTex.getAccess());
5888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	logGeometry(resultTex.getAccess(), occluderData->m_program, occludedData->m_program);
5908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	params.reserve(ITERATION_STEPS*ITERATION_SAMPLES);
5928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	// Setup parameters
5948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	for (int step = 0; step < ITERATION_STEPS; step++)
5958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
5968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		const int workload = maxWorkload*step/ITERATION_STEPS;
5978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
5988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		for (int count = 0; count < ITERATION_SAMPLES; count++)
5998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			params.push_back(workload);
6008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
6018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	rng.shuffle(params.begin(), params.end());
6038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	// Render samples
6058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	for (size_t ndx = 0; ndx < params.size(); ndx++)
6068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
6078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		const int	workload	= params[ndx];
6088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		Sample		sample		= renderSample(*occluderData, *occludedData, workload);
6098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		sample.workload = workload;
6118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		sample.order = int(ndx);
6128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		results.push_back(sample);
6148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
6158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	logSamples(results, "Samples", "Samples");
6178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	logAnalysis(results);
6188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	m_results.setTestContextResult(m_testCtx);
6208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	return STOP;
6228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
6238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryvoid BaseCase::logSamples (const vector<Sample>& samples, const string& name, const string& desc)
6258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
6268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	TestLog& log = m_testCtx.getLog();
6278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	bool testOnly = true;
6298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	for (size_t ndx = 0; ndx < samples.size(); ndx++)
6318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
6328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		if (samples[ndx].baseTime != 0 || samples[ndx].nullTime != 0)
6338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		{
6348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			testOnly = false;
6358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			break;
6368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		}
6378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
6388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	log << TestLog::SampleList(name, desc);
6408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	if (testOnly)
6428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
6438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		log << TestLog::SampleInfo
6448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			<< TestLog::ValueInfo("Workload",	"Workload",			"",				QP_SAMPLE_VALUE_TAG_PREDICTOR)
6458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			<< TestLog::ValueInfo("Order",		"Order of sample",	"",				QP_SAMPLE_VALUE_TAG_PREDICTOR)
6468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			<< TestLog::ValueInfo("TestTime",	"Test render time",	"us",			QP_SAMPLE_VALUE_TAG_RESPONSE)
6478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			<< TestLog::EndSampleInfo;
6488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		for (size_t sampleNdx = 0; sampleNdx < samples.size(); sampleNdx++)
6508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		{
6518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			const Sample& sample = samples[sampleNdx];
6528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			log << TestLog::Sample << sample.workload << sample.order << sample.testTime << TestLog::EndSample;
6548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		}
6558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
6568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	else
6578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
6588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		log << TestLog::SampleInfo
6598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			<< TestLog::ValueInfo("Workload",	"Workload",			"",				QP_SAMPLE_VALUE_TAG_PREDICTOR)
6608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			<< TestLog::ValueInfo("Order",		"Order of sample",	"",				QP_SAMPLE_VALUE_TAG_PREDICTOR)
6618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			<< TestLog::ValueInfo("TestTime",	"Test render time",	"us",			QP_SAMPLE_VALUE_TAG_RESPONSE)
6628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			<< TestLog::ValueInfo("NullTime",	"Read pixels time",	"us",			QP_SAMPLE_VALUE_TAG_RESPONSE)
6638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			<< TestLog::ValueInfo("BaseTime",	"Base render time",	"us",			QP_SAMPLE_VALUE_TAG_RESPONSE)
6648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			<< TestLog::EndSampleInfo;
6658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		for (size_t sampleNdx = 0; sampleNdx < samples.size(); sampleNdx++)
6678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		{
6688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			const Sample& sample = samples[sampleNdx];
6698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			log << TestLog::Sample << sample.workload << sample.order << sample.testTime << sample.nullTime << sample.baseTime << TestLog::EndSample;
6718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		}
6728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
6738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	log << TestLog::EndSampleList;
6758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
6768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryvoid BaseCase::logGeometry (const tcu::ConstPixelBufferAccess& sample, const glu::ShaderProgram& occluderProg, const glu::ShaderProgram& occludedProg)
6788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
6798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	TestLog& log = m_testCtx.getLog();
6808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	log << TestLog::Section("Geometry", "Geometry");
6828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	log << TestLog::Message << "Occluding geometry is green with shade dependent on depth (rgb == 0, depth, 0)" << TestLog::EndMessage;
6838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	log << TestLog::Message << "Occluded geometry is red with shade dependent on depth (rgb == depth, 0, 0)" << TestLog::EndMessage;
6848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	log << TestLog::Message << "Primitive edges are a lighter shade of red/green" << TestLog::EndMessage;
6858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	log << TestLog::Image("Test Geometry", "Test Geometry",  sample);
6878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	log << TestLog::EndSection;
6888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	log << TestLog::Section("Occluder", "Occluder");
6908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	log << occluderProg;
6918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	log << TestLog::EndSection;
6928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	log << TestLog::Section("Occluded", "Occluded");
6948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	log << occludedProg;
6958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	log << TestLog::EndSection;
6968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
6978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
6988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryvoid BaseCase::render (const RenderData& data) const
6998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
7008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const glw::Functions& gl = m_renderCtx.getFunctions();
7018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.useProgram(data.m_program.getProgram());
7038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.bindVertexArray(*data.m_vao);
7058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.drawArrays(GL_TRIANGLES, 0, data.m_numVertices);
7068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.bindVertexArray(0);
7078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
7088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryvoid BaseCase::render (const RenderData& data, int instances) const
7108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
7118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const glw::Functions& gl = m_renderCtx.getFunctions();
7128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.useProgram(data.m_program.getProgram());
7148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.bindVertexArray(*data.m_vao);
7168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.drawArraysInstanced(GL_TRIANGLES, 0, data.m_numVertices, instances);
7178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.bindVertexArray(0);
7188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
7198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry// Render occluder once, then repeatedly render occluded geometry. Sample with multiple repetition counts & establish time per call with linear regression
7218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryclass RenderCountCase : public BaseCase
7228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
7238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrypublic:
7248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry					RenderCountCase		(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc);
7258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry					~RenderCountCase	(void) {}
7268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryprotected:
7288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	virtual void	logAnalysis			(const vector<Sample>& samples);
7298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryprivate:
7318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	virtual int		calibrate			(void) const;
7328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	virtual Sample	renderSample		(const RenderData& occluder, const RenderData& occluded, int callcount) const;
7338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry};
7348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko PoyryRenderCountCase::RenderCountCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
7368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	: BaseCase	(testCtx, renderCtx, name, desc)
7378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
7388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
7398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryvoid RenderCountCase::logAnalysis (const vector<Sample>& samples)
7418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
7428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	using namespace gls;
7438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	TestLog&		log			= m_testCtx.getLog();
7458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	int				maxWorkload	= 0;
7468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	vector<Vec2>	testSamples	(samples.size());
7478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	for (size_t ndx = 0; ndx < samples.size(); ndx++)
7498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
7508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		const Sample& sample = samples[ndx];
7518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		testSamples[ndx] = Vec2((float)sample.workload, (float)sample.testTime);
7538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		maxWorkload = de::max(maxWorkload, sample.workload);
7558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
7568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
7588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		const float							confidence	= 0.60f;
7598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		const LineParametersWithConfidence	testParam	= theilSenSiegelLinearRegression(testSamples, confidence);
7608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		const float							usPerCall	= testParam.coefficient;
7618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		const float							pxPerCall	= RENDER_SIZE*RENDER_SIZE;
7628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		const float							pxPerUs		= pxPerCall/usPerCall;
7638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		const float							mpxPerS		= pxPerUs;
7648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		log << TestLog::Section("Linear Regression", "Linear Regression");
7668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		log << TestLog::Message << "Offset & coefficient presented as [confidence interval min, estimate, confidence interval max]. Reported confidence interval for this test is " << confidence << TestLog::EndMessage;
7678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		log << TestLog::Message << "Render time for scene with depth test was\n\t"
7688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			<< "[" << testParam.offsetConfidenceLower << ", " << testParam.offset <<  ", " << testParam.offsetConfidenceUpper << "]us +"
7698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			<< "[" << testParam.coefficientConfidenceLower << ", " << testParam.coefficient << ", " << testParam.coefficientConfidenceUpper << "]"
7708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			<< "us/workload" << TestLog::EndMessage;
7718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		log << TestLog::EndSection;
7728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		log << TestLog::Section("Result", "Result");
7748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		if (testParam.coefficientConfidenceLower < 0.0f)
7768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		{
7778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			log << TestLog::Message << "Coefficient confidence bounds include values below 0.0, the operation likely has neglible per-pixel cost" << TestLog::EndMessage;
7788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			m_results.addResult(QP_TEST_RESULT_PASS, "Pass");
7798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		}
7808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		else if (testParam.coefficientConfidenceLower < testParam.coefficientConfidenceUpper*0.25)
7818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		{
7828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			log << TestLog::Message << "Coefficient confidence range is extremely large, cannot give reliable result" << TestLog::EndMessage;
7838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			m_results.addResult(QP_TEST_RESULT_PASS, "Result confidence extremely low");
7848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		}
7858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		else
7868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		{
7878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			log << TestLog::Message << "Culled hidden pixels @ " << mpxPerS << "Mpx/s" << TestLog::EndMessage;
7888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			m_results.addResult(QP_TEST_RESULT_PASS, de::floatToString(mpxPerS, 2));
7898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		}
7908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		log << TestLog::EndSection;
7928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
7938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
7948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
7958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko PoyrySample RenderCountCase::renderSample (const RenderData& occluder, const RenderData& occluded, int callcount) const
7968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
7978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const glw::Functions&	gl		= m_renderCtx.getFunctions();
7988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	Sample					sample;
7998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	deUint64				now		= 0;
8008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	deUint64				prev	= 0;
8018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	deUint8					buffer[4];
8028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	// Stabilize
8048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
8058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
8068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		gl.enable(GL_DEPTH_TEST);
8078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
8088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
8098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	prev = deGetMicroseconds();
8118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
8138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.enable(GL_DEPTH_TEST);
8148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	render(occluder);
8168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	render(occluded, callcount);
8178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
8198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	now = deGetMicroseconds();
8218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	sample.testTime = now - prev;
8238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	sample.baseTime = 0;
8248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	sample.nullTime = 0;
8258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	sample.workload = callcount;
8268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	return sample;
8288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
8298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryint RenderCountCase::calibrate (void) const
8318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
8328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	using namespace gls;
8338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const glw::Functions&	gl					= m_renderCtx.getFunctions();
8358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	TestLog&				log					= m_testCtx.getLog();
8368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const RenderData		occluderGeometry	(genOccluderGeometry(), m_renderCtx, log);
8388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const RenderData		occludedGeometry	(genOccludedGeometry(), m_renderCtx, log);
8398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	TheilSenCalibrator		calibrator			(CalibratorParameters(20, // Initial workload
8418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry																	  10, // Max iteration frames
8428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry																	  20.0f, // Iteration shortcut threshold ms
8438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry																	  20, // Max iterations
8448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry																	  33.0f, // Target frame time
8458852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry																	  40.0f, // Frame time cap
8468852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry																	  1000.0f // Target measurement duration
8478852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry																	  ));
8488852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8498852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	while (true)
8508852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
8518852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		switch(calibrator.getState())
8528852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		{
8538852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			case TheilSenCalibrator::STATE_FINISHED:
8548852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				logCalibrationInfo(m_testCtx.getLog(), calibrator);
8558852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				return calibrator.getCallCount();
8568852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8578852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			case TheilSenCalibrator::STATE_MEASURE:
8588852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			{
8598852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				deUint8	buffer[4];
8608852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				deInt64 now;
8618852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				deInt64 prev;
8628852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8638852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				prev = deGetMicroseconds();
8648852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8658852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
8668852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				gl.disable(GL_DEPTH_TEST);
8678852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8688852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				render(occluderGeometry);
8698852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				render(occludedGeometry, calibrator.getCallCount());
8708852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8718852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
8728852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8738852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				now = deGetMicroseconds();
8748852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8758852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				calibrator.recordIteration(now - prev);
8768852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				break;
8778852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			}
8788852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8798852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			case TheilSenCalibrator::STATE_RECOMPUTE_PARAMS:
8808852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				calibrator.recomputeParameters();
8818852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				break;
8828852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			default:
8838852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				DE_ASSERT(false);
8848852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				return 1;
8858852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		}
8868852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	}
8878852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
8888852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8898852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry// Compares time/workload gradients of same geometry with and without depth testing
8908852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryclass RelativeChangeCase : public BaseCase
8918852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
8928852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyrypublic:
8938852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry					RelativeChangeCase	(TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc);
8948852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	virtual			~RelativeChangeCase	(void) {}
8958852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8968852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryprotected:
8978852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	Sample			renderSample		(const RenderData& occluder, const RenderData& occluded, int workload) const;
8988852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
8998852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	virtual void	logAnalysis			(const vector<Sample>& samples);
9008852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
9018852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryprivate:
9028852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	int				calibrate			(void) const;
9038852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry};
9048852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
9058852c82a1ffa4760985c17cc6875d5d521daf343Jarkko PoyryRelativeChangeCase::RelativeChangeCase (TestContext& testCtx, const RenderContext& renderCtx, const char* name, const char* desc)
9068852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	: BaseCase		(testCtx, renderCtx, name, desc)
9078852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
9088852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry}
9098852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
9108852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyryint RelativeChangeCase::calibrate (void) const
9118852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry{
9128852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	using namespace gls;
9138852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
9148852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const glw::Functions&	gl		= m_renderCtx.getFunctions();
9158852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	TestLog&				log		= m_testCtx.getLog();
9168852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
9178852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	const RenderData		geom	(genOccludedGeometry(), m_renderCtx, log);
9188852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
9198852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	TheilSenCalibrator calibrator(CalibratorParameters( 20, // Initial workload
9208852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry														10, // Max iteration frames
9218852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry														20.0f, // Iteration shortcut threshold ms
9228852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry														20, // Max iterations
9238852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry														10.0f, // Target frame time
9248852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry														15.0f, // Frame time cap
9258852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry														1000.0f // Target measurement duration
9268852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry														));
9278852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
9288852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	while (true)
9298852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry	{
9308852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		switch(calibrator.getState())
9318852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry		{
9328852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			case TheilSenCalibrator::STATE_FINISHED:
9338852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				logCalibrationInfo(m_testCtx.getLog(), calibrator);
9348852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				return calibrator.getCallCount();
9358852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
9368852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			case TheilSenCalibrator::STATE_MEASURE:
9378852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry			{
9388852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				deUint8			buffer[4];
9398852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				const GLuint	program	= geom.m_program.getProgram();
9408852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
9418852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				gl.useProgram(program);
9428852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				gl.uniform1i(gl.getUniformLocation(program, "u_iterations"), calibrator.getCallCount());
9438852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry
9448852c82a1ffa4760985c17cc6875d5d521daf343Jarkko Poyry				const deInt64 prev = deGetMicroseconds();
945