13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program OpenGL ES 2.0 Module
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * -------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Shader compilation performance tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es2pShaderCompilationCases.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVector.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuMatrix.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTextureUtil.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuPlatform.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuCommandLine.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuCPUWarmup.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuStringTemplate.hpp"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluTexture.hpp"
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluPixelTransfer.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp"
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deRandom.hpp"
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deClock.h"
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h"
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwEnums.hpp"
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <map>
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <algorithm>
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <limits>
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <iomanip>
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec3;
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec4;
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Mat3;
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Mat4;
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing namespace glw; // GL types
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles2
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Performance
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const bool	WARMUP_CPU_AT_BEGINNING_OF_CASE					= false;
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const bool	WARMUP_CPU_BEFORE_EACH_MEASUREMENT				= true;
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int	MAX_VIEWPORT_WIDTH								= 64;
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int	MAX_VIEWPORT_HEIGHT								= 64;
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int	DEFAULT_MINIMUM_MEASUREMENT_COUNT				= 15;
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const float	RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD	= 0.05f;
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Texture size for the light shader and texture lookup shader cases.
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int	TEXTURE_WIDTH									= 64;
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const int	TEXTURE_HEIGHT									= 64;
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyryinline string toStringWithPadding (T value, int minLength)
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::ostringstream s;
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	s << std::setfill('0') << std::setw(minLength) << value;
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return s.str();
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Add some whitespace and comments to str. They should depend on uniqueNumber.
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string strWithWhiteSpaceAndComments (const string& str, deUint32 uniqueNumber)
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string res("");
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Find the first newline.
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int firstLineEndNdx = 0;
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	while (firstLineEndNdx < (int)str.size() && str[firstLineEndNdx] != '\n')
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res += str[firstLineEndNdx];
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		firstLineEndNdx++;
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	res += '\n';
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(firstLineEndNdx < (int)str.size());
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Add the whitespaces and comments just after the first line.
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	de::Random		rnd		(uniqueNumber);
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				numWS	= rnd.getInt(10, 20);
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numWS; i++)
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res += " \t\n"[rnd.getInt(0, 2)];
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	res += "/* unique comment " + de::toString(uniqueNumber) + " */\n";
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	res += "// unique comment " + de::toString(uniqueNumber) + "\n";
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numWS; i++)
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res += " \t\n"[rnd.getInt(0, 2)];
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Add the rest of the string.
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	res.append(&str.c_str()[firstLineEndNdx + 1]);
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res;
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Helper for computing relative magnitudes while avoiding division by zero.
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float hackySafeRelativeResult (float x, float y)
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note A possible case is that x is standard deviation, and y is average
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 (or similarly for median or some such). So, if y is 0, that
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 probably means that x is also 0(ish) (because in practice we're
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 dealing with non-negative values, in which case an average of 0
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 implies that the samples are all 0 - note that the same isn't
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 strictly true for things like median) so a relative result of 0
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	//		 wouldn't be that far from the truth.
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return y == 0.0f ? 0.0f : x/y;
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float vectorFloatAverage (const vector<T>& v)
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!v.empty());
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float result = 0.0f;
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)v.size(); i++)
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result += (float)v[i];
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result / (float)v.size();
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float vectorFloatMedian (const vector<T>& v)
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!v.empty());
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<T> temp = v;
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::sort(temp.begin(), temp.end());
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return temp.size() % 2 == 0
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   ? 0.5f * ((float)temp[temp.size()/2-1] + (float)temp[temp.size()/2])
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		   : (float)temp[temp.size()/2];
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float vectorFloatMinimum (const vector<T>& v)
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!v.empty());
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (float)*std::min_element(v.begin(), v.end());
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float vectorFloatMaximum (const vector<T>& v)
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!v.empty());
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return (float)*std::max_element(v.begin(), v.end());
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float vectorFloatStandardDeviation (const vector<T>& v)
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float average	= vectorFloatAverage(v);
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float result	= 0.0f;
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)v.size(); i++)
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float d = (float)v[i] - average;
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result += d*d;
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return deFloatSqrt(result/(float)v.size());
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float vectorFloatRelativeStandardDeviation (const vector<T>& v)
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return hackySafeRelativeResult(vectorFloatStandardDeviation(v), vectorFloatAverage(v));
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float vectorFloatMedianAbsoluteDeviation (const vector<T>& v)
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	float			median				= vectorFloatMedian(v);
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<float>	absoluteDeviations	(v.size());
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < (int)v.size(); i++)
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		absoluteDeviations[i] = deFloatAbs((float)v[i] - median);
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return vectorFloatMedian(absoluteDeviations);
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float vectorFloatRelativeMedianAbsoluteDeviation (const vector<T>& v)
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return hackySafeRelativeResult(vectorFloatMedianAbsoluteDeviation(v), vectorFloatMedian(v));
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float vectorFloatMaximumMinusMinimum (const vector<T>& v)
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return vectorFloatMaximum(v) - vectorFloatMinimum(v);
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float vectorFloatRelativeMaximumMinusMinimum (const vector<T>& v)
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return hackySafeRelativeResult(vectorFloatMaximumMinusMinimum(v), vectorFloatMaximum(v));
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<T> vectorLowestPercentage (const vector<T>& v, float factor)
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(0.0f < factor && factor <= 1.0f);
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			targetSize	= (int)(deFloatCeil(factor*(float)v.size()));
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<T>	temp		= v;
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::sort(temp.begin(), temp.end());
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	while ((int)temp.size() > targetSize)
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		temp.pop_back();
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return temp;
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <typename T>
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic float vectorFloatFirstQuartile (const vector<T>& v)
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return vectorFloatMedian(vectorLowestPercentage(v, 0.5f));
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Helper function for combining 4 tcu::Vec4's into one tcu::Vector<float, 16>.
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic tcu::Vector<float, 16> combineVec4ToVec16 (const Vec4& a0, const Vec4& a1, const Vec4& a2, const Vec4& a3)
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Vector<float, 16> result;
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int vecNdx = 0; vecNdx < 4; vecNdx++)
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const Vec4& srcVec = vecNdx == 0 ? a0 : vecNdx == 1 ? a1 : vecNdx == 2 ? a2 : a3;
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < 4; i++)
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result[vecNdx*4 + i] = srcVec[i];
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Helper function for extending an n-sized (n <= 16) vector to a 16-sized vector (padded with zeros).
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size>
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic tcu::Vector<float, 16> vecTo16 (const tcu::Vector<float, Size>& vec)
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(Size <= 16);
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Vector<float, 16> res(0.0f);
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < Size; i++)
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res[i] = vec[i];
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res;
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Helper function for extending an n-sized (n <= 16) array to a 16-sized vector (padded with zeros).
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate <int Size>
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic tcu::Vector<float, 16> arrTo16 (const tcu::Array<float, Size>& arr)
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_STATIC_ASSERT(Size <= 16);
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::Vector<float, 16> res(0.0f);
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for(int i = 0; i < Size; i++)
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		res[i] = arr[i];
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res;
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string getShaderInfoLog (const glw::Functions& gl, deUint32 shader)
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string			result;
288059a70e68d787977450b0c6a5f61c034b5e45dcaMika Isojärvi	int				infoLogLen = 0;
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<char>	infoLogBuf;
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLen);
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	infoLogBuf.resize(infoLogLen + 1);
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getShaderInfoLog(shader, infoLogLen + 1, DE_NULL, &infoLogBuf[0]);
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result = &infoLogBuf[0];
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string getProgramInfoLog (const glw::Functions& gl, deUint32 program)
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string			result;
302059a70e68d787977450b0c6a5f61c034b5e45dcaMika Isojärvi	int				infoLogLen = 0;
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<char>	infoLogBuf;
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLen);
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	infoLogBuf.resize(infoLogLen + 1);
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getProgramInfoLog(program, infoLogLen + 1, DE_NULL, &infoLogBuf[0]);
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result = &infoLogBuf[0];
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum LightType
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LIGHT_DIRECTIONAL = 0,
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LIGHT_POINT,
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LIGHT_LAST,
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum LoopType
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOP_TYPE_STATIC = 0,
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOP_TYPE_UNIFORM,
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOP_TYPE_DYNAMIC,
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LOOP_LAST
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// For texture lookup cases: which texture lookups are inside a conditional statement.
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum ConditionalUsage
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CONDITIONAL_USAGE_NONE = 0,		// No conditional statements.
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CONDITIONAL_USAGE_FIRST_HALF,	// First numLookUps/2 lookups are inside a conditional statement.
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CONDITIONAL_USAGE_EVERY_OTHER,	// First, third etc. lookups are inside conditional statements.
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CONDITIONAL_USAGE_LAST
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum ConditionalType
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CONDITIONAL_TYPE_STATIC = 0,
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CONDITIONAL_TYPE_UNIFORM,
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CONDITIONAL_TYPE_DYNAMIC,
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CONDITIONAL_TYPE_LAST
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// For the invalid shader compilation tests; what kind of invalidity a shader shall contain.
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum ShaderValidity
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SHADER_VALIDITY_VALID = 0,
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SHADER_VALIDITY_INVALID_CHAR,
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SHADER_VALIDITY_SEMANTIC_ERROR,
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SHADER_VALIDITY_LAST
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderCompilerCase : public TestCase
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct AttribSpec
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string					name;
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vector<float, 16>	value;
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		AttribSpec (const string& n, const tcu::Vector<float, 16>& v) : name(n), value(v) {}
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct UniformSpec
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		enum Type
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_FLOAT = 0,
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_VEC2,
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_VEC3,
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_VEC4,
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_MAT3,
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_MAT4,
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_TEXTURE_UNIT,
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TYPE_LAST
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		};
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string					name;
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Type					type;
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::Vector<float, 16>	value;
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformSpec (const string& n, Type t, float v)							: name(n), type(t), value(v) {}
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		UniformSpec (const string& n, Type t, const tcu::Vector<float, 16>& v)	: name(n), type(t), value(v) {}
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								ShaderCompilerCase		(Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments);
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								~ShaderCompilerCase		(void);
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						init					(void);
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult				iterate					(void);
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct ProgramContext
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string					vertShaderSource;
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string					fragShaderSource;
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<AttribSpec>		vertexAttributes;
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<UniformSpec>		uniforms;
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					getSpecializationID		(int measurementNdx) const;		// Return an ID that depends on the case ID, current measurement index and time; used to specialize attribute names etc. (avoid shader caching).
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ProgramContext		generateShaderData		(int measurementNdx) const = 0;	// Generate shader sources and inputs. Attribute etc. names depend on above name specialization.
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct Measurement
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note All times in microseconds. 32-bit integers would probably suffice (would need over an hour of test case runtime to overflow), but better safe than sorry.
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt64 sourceSetTime;
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt64 vertexCompileTime;
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt64 fragmentCompileTime;
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt64 programLinkTime;
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt64 firstInputSetTime;
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt64 firstDrawTime;
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt64 secondInputSetTime;
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt64 secondDrawTime;
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt64 firstPhase				(void) const { return sourceSetTime + vertexCompileTime + fragmentCompileTime + programLinkTime + firstInputSetTime + firstDrawTime; }
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt64 secondPhase				(void) const { return secondInputSetTime + secondDrawTime; }
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt64 totalTimeWithoutDraw	(void) const { return firstPhase() - de::min(secondPhase(), firstInputSetTime + firstDrawTime); }
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Measurement (deInt64 sourceSetTime_,
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 deInt64 vertexCompileTime_,
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 deInt64 fragmentCompileTime_,
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 deInt64 programLinkTime_,
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 deInt64 firstInputSetTime_,
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 deInt64 firstDrawTime_,
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 deInt64 secondInputSetTime_,
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 deInt64 secondDrawTime_)
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: sourceSetTime			(sourceSetTime_)
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, vertexCompileTime		(vertexCompileTime_)
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, fragmentCompileTime	(fragmentCompileTime_)
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, programLinkTime		(programLinkTime_)
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, firstInputSetTime		(firstInputSetTime_)
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, firstDrawTime			(firstDrawTime_)
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, secondInputSetTime	(secondInputSetTime_)
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, secondDrawTime		(secondDrawTime_)
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct ShadersAndProgram
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 vertShader;
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 fragShader;
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 program;
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct Logs
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string vert;
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string frag;
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string link;
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct BuildInfo
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool vertCompileSuccess;
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool fragCompileSuccess;
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool linkSuccess;
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Logs logs;
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShadersAndProgram			createShadersAndProgram		(void) const;
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						setShaderSources			(deUint32 vertShader, deUint32 fragShader, const ProgramContext&) const;
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						compileShader				(deUint32 shader) const;
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						linkAndUseProgram			(deUint32 program) const;
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						setShaderInputs				(deUint32 program, const ProgramContext&) const;							// Set attribute pointers and uniforms.
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						draw						(void) const;																// Clear, draw and finish.
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						cleanup						(const ShadersAndProgram&, const ProgramContext&, bool linkSuccess) const;	// Do GL deinitializations.
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Logs						getLogs						(const ShadersAndProgram&) const;
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						logProgramData				(const BuildInfo&, const ProgramContext&) const;
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						goodEnoughMeasurements		(const vector<Measurement>& measurements) const;
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_viewportWidth;
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_viewportHeight;
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						m_avoidCache;				// If true, avoid caching between measurements as well (and not only between test cases).
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						m_addWhitespaceAndComments;	// If true, add random whitespace and comments to the source (good caching should ignore those).
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_startHash;				// A hash from case id and time, at the time of construction.
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_minimumMeasurementCount;
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_maximumMeasurementCount;
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderCompilerLightCase : public ShaderCompilerCase
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							ShaderCompilerLightCase		(Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, bool isVertexCase, int numLights, LightType lightType);
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~ShaderCompilerLightCase	(void);
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					init						(void);
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					deinit						(void);
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext			generateShaderData			(int measurementNdx) const;
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_numLights;
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					m_isVertexCase;
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LightType				m_lightType;
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::Texture2D*			m_texture;
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderCompilerTextureCase : public ShaderCompilerCase
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									ShaderCompilerTextureCase	(Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, int numLookups, ConditionalUsage conditionalUsage, ConditionalType conditionalType);
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									~ShaderCompilerTextureCase	(void);
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							init						(void);
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void							deinit						(void);
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext					generateShaderData			(int measurementNdx) const;
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int								m_numLookups;
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<glu::Texture2D*>			m_textures;
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConditionalUsage				m_conditionalUsage;
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConditionalType					m_conditionalType;
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderCompilerLoopCase : public ShaderCompilerCase
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ShaderCompilerLoopCase	(Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, bool isVertexCase, LoopType type, int numLoopIterations, int nestingDepth);
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~ShaderCompilerLoopCase	(void);
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext		generateShaderData		(int measurementNdx) const;
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_numLoopIterations;
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_nestingDepth;
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				m_isVertexCase;
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LoopType			m_type;
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderCompilerOperCase : public ShaderCompilerCase
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ShaderCompilerOperCase	(Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, bool isVertexCase, const char* oper, int numOperations);
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~ShaderCompilerOperCase	(void);
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext		generateShaderData		(int measurementNdx) const;
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string				m_oper;
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_numOperations;
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				m_isVertexCase;
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderCompilerMandelbrotCase : public ShaderCompilerCase
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						ShaderCompilerMandelbrotCase	(Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, int numFractalIterations);
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~ShaderCompilerMandelbrotCase	(void);
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext		generateShaderData				(int measurementNdx) const;
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_numFractalIterations;
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InvalidShaderCompilerCase : public TestCase
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Similar to the ShaderValidity enum, but doesn't have a VALID type.
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum InvalidityType
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		INVALIDITY_INVALID_CHAR = 0,
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		INVALIDITY_SEMANTIC_ERROR,
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		INVALIDITY_LAST
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						InvalidShaderCompilerCase	(Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType);
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~InvalidShaderCompilerCase	(void);
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult		iterate						(void);
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct ProgramContext
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string vertShaderSource;
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string fragShaderSource;
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32				getSpecializationID		(int measurementNdx) const;			// Return an ID that depends on the case ID, current measurement index and time; used to specialize attribute names etc. (avoid shader caching).
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ProgramContext	generateShaderSources	(int measurementNdx) const = 0;		// Generate shader sources. Attribute etc. names depend on above name specialization.
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	InvalidityType			m_invalidityType;
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct Measurement
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note All times in microseconds. 32-bit integers would probably suffice (would need over an hour of test case runtime to overflow), but better safe than sorry.
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt64 sourceSetTime;
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt64 vertexCompileTime;
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt64 fragmentCompileTime;
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deInt64 totalTime (void) const { return sourceSetTime + vertexCompileTime + fragmentCompileTime; }
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Measurement (deInt64 sourceSetTime_,
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 deInt64 vertexCompileTime_,
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 deInt64 fragmentCompileTime_)
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			: sourceSetTime			(sourceSetTime_)
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, vertexCompileTime		(vertexCompileTime_)
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			, fragmentCompileTime	(fragmentCompileTime_)
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct Shaders
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 vertShader;
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 fragShader;
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct Logs
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string vert;
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string frag;
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	struct BuildInfo
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool vertCompileSuccess;
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		bool fragCompileSuccess;
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Logs logs;
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Shaders						createShaders			(void) const;
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						setShaderSources		(const Shaders&, const ProgramContext&) const;
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						compileShader			(deUint32 shader) const;
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						cleanup					(const Shaders&) const;
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Logs						getLogs					(const Shaders&) const;
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void						logProgramData			(const BuildInfo&, const ProgramContext&) const;
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool						goodEnoughMeasurements	(const vector<Measurement>& measurements) const;
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32					m_startHash; // A hash from case id and time, at the time of construction.
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_minimumMeasurementCount;
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int							m_maximumMeasurementCount;
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InvalidShaderCompilerLightCase : public InvalidShaderCompilerCase
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							InvalidShaderCompilerLightCase	(Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, bool isVertexCase, int numLights, LightType lightType);
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~InvalidShaderCompilerLightCase	(void);
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext			generateShaderSources			(int measurementNdx) const;
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					m_isVertexCase;
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_numLights;
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LightType				m_lightType;
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InvalidShaderCompilerTextureCase : public InvalidShaderCompilerCase
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							InvalidShaderCompilerTextureCase	(Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, int numLookups, ConditionalUsage conditionalUsage, ConditionalType conditionalType);
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~InvalidShaderCompilerTextureCase	(void);
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext			generateShaderSources				(int measurementNdx) const;
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_numLookups;
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConditionalUsage		m_conditionalUsage;
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConditionalType			m_conditionalType;
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InvalidShaderCompilerLoopCase : public InvalidShaderCompilerCase
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						InvalidShaderCompilerLoopCase	(Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, bool , LoopType type, int numLoopIterations, int nestingDepth);
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~InvalidShaderCompilerLoopCase	(void);
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext		generateShaderSources			(int measurementNdx) const;
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				m_isVertexCase;
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_numLoopIterations;
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_nestingDepth;
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LoopType			m_type;
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InvalidShaderCompilerOperCase : public InvalidShaderCompilerCase
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						InvalidShaderCompilerOperCase	(Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, bool isVertexCase, const char* oper, int numOperations);
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~InvalidShaderCompilerOperCase	(void);
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext		generateShaderSources			(int measurementNdx) const;
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool				m_isVertexCase;
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string				m_oper;
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_numOperations;
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass InvalidShaderCompilerMandelbrotCase : public InvalidShaderCompilerCase
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						InvalidShaderCompilerMandelbrotCase		(Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, int numFractalIterations);
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						~InvalidShaderCompilerMandelbrotCase	(void);
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext		generateShaderSources					(int measurementNdx) const;
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int					m_numFractalIterations;
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string getNameSpecialization (deUint32 id)
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return "_" + toStringWithPadding(id, 10);
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Substitute StringTemplate parameters for attribute/uniform/varying name and constant expression specialization as well as possible shader compilation error causes.
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string specializeShaderSource (const string& shaderSourceTemplate, deUint32 cacheAvoidanceID, ShaderValidity validity)
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::map<string, string> params;
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params["NAME_SPEC"]			= getNameSpecialization(cacheAvoidanceID);
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params["FLOAT01"]			= de::floatToString((float)cacheAvoidanceID / (float)(std::numeric_limits<deUint32>::max()), 6);
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params["SEMANTIC_ERROR"]	= validity != SHADER_VALIDITY_SEMANTIC_ERROR	? "" : "\tmediump float invalid = sin(1.0, 2.0);\n";
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	params["INVALID_CHAR"]		= validity != SHADER_VALIDITY_INVALID_CHAR		? "" : "@\n"; // \note Some implementations crash when the invalid character is the last character in the source, so use newline.
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return tcu::StringTemplate(shaderSourceTemplate).specialize(params);
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Function for generating the vertex shader of a (directional or point) light case.
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string lightVertexTemplate (int numLights, bool isVertexCase, LightType lightType)
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string resultTemplate;
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"attribute highp vec4 a_position${NAME_SPEC};\n"
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"attribute mediump vec3 a_normal${NAME_SPEC};\n"
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"attribute mediump vec4 a_texCoord0${NAME_SPEC};\n"
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform mediump vec3 u_material_ambientColor${NAME_SPEC};\n"
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform mediump vec4 u_material_diffuseColor${NAME_SPEC};\n"
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform mediump vec3 u_material_emissiveColor${NAME_SPEC};\n"
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform mediump vec3 u_material_specularColor${NAME_SPEC};\n"
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform mediump float u_material_shininess${NAME_SPEC};\n";
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int lightNdx = 0; lightNdx < numLights; lightNdx++)
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string ndxStr = de::toString(lightNdx);
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform mediump vec3 u_light" + ndxStr + "_color${NAME_SPEC};\n"
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform mediump vec3 u_light" + ndxStr + "_direction${NAME_SPEC};\n";
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (lightType == LIGHT_POINT)
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultTemplate +=
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"uniform mediump vec4 u_light" + ndxStr + "_position${NAME_SPEC};\n"
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"uniform mediump float u_light" + ndxStr + "_constantAttenuation${NAME_SPEC};\n"
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"uniform mediump float u_light" + ndxStr + "_linearAttenuation${NAME_SPEC};\n"
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"uniform mediump float u_light" + ndxStr + "_quadraticAttenuation${NAME_SPEC};\n";
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform highp mat4 u_mvpMatrix${NAME_SPEC};\n"
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform highp mat4 u_modelViewMatrix${NAME_SPEC};\n"
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform mediump mat3 u_normalMatrix${NAME_SPEC};\n"
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform mediump mat4 u_texCoordMatrix0${NAME_SPEC};\n"
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"varying mediump vec4 v_color${NAME_SPEC};\n"
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"varying mediump vec2 v_texCoord0${NAME_SPEC};\n";
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!isVertexCase)
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate += "varying mediump vec3 v_eyeNormal${NAME_SPEC};\n";
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (lightType == LIGHT_POINT)
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultTemplate +=
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"varying mediump vec3 v_directionToLight${NAME_SPEC}[" + de::toString(numLights) + "];\n"
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"varying mediump float v_distanceToLight${NAME_SPEC}[" + de::toString(numLights) + "];\n";
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"mediump vec3 direction (mediump vec4 from, mediump vec4 to)\n"
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	return vec3(to.xyz * from.w - from.xyz * to.w);\n"
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n"
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"mediump vec3 computeLighting (\n"
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	mediump vec3 directionToLight,\n"
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	mediump vec3 halfVector,\n"
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	mediump vec3 normal,\n"
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	mediump vec3 lightColor,\n"
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	mediump vec3 diffuseColor,\n"
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	mediump vec3 specularColor,\n"
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	mediump float shininess)\n"
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	mediump float normalDotDirection  = max(dot(normal, directionToLight), 0.0);\n"
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	mediump vec3  color               = normalDotDirection * diffuseColor * lightColor;\n"
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	if (normalDotDirection != 0.0)\n"
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"		color += pow(max(dot(normal, halfVector), 0.0), shininess) * specularColor * lightColor;\n"
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	return color;\n"
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n"
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n";
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (lightType == LIGHT_POINT)
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"mediump float computeDistanceAttenuation (mediump float distToLight, mediump float constAtt, mediump float linearAtt, mediump float quadraticAtt)\n"
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	return 1.0 / (constAtt + linearAtt * distToLight + quadraticAtt * distToLight * distToLight);\n"
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n"
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n";
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main (void)\n"
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	highp vec4 position = a_position${NAME_SPEC};\n"
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	highp vec3 normal = a_normal${NAME_SPEC};\n"
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_Position = u_mvpMatrix${NAME_SPEC} * position * (0.95 + 0.05*${FLOAT01});\n"
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	v_texCoord0${NAME_SPEC} = (u_texCoordMatrix0${NAME_SPEC} * a_texCoord0${NAME_SPEC}).xy;\n"
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	mediump vec4 color = vec4(u_material_emissiveColor${NAME_SPEC}, u_material_diffuseColor${NAME_SPEC}.a);\n"
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	highp vec4 eyePosition = u_modelViewMatrix${NAME_SPEC} * position;\n"
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	mediump vec3 eyeNormal = normalize(u_normalMatrix${NAME_SPEC} * normal);\n";
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!isVertexCase)
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate += "\tv_eyeNormal${NAME_SPEC} = eyeNormal;\n";
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate += "\n";
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int lightNdx = 0; lightNdx < numLights; lightNdx++)
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string ndxStr = de::toString(lightNdx);
8583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	/* Light " + ndxStr + " */\n";
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (lightType == LIGHT_POINT)
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultTemplate +=
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	mediump float distanceToLight" + ndxStr + " = distance(eyePosition, u_light" + ndxStr + "_position${NAME_SPEC});\n"
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	mediump vec3 directionToLight" + ndxStr + " = normalize(direction(eyePosition, u_light" + ndxStr + "_position${NAME_SPEC}));\n";
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isVertexCase)
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				resultTemplate +=
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"	mediump vec3 halfVector" + ndxStr + " = normalize(directionToLight" + ndxStr + " + vec3(0.0, 0.0, 1.0));\n"
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"	color.rgb += computeLighting(directionToLight" + ndxStr + ", halfVector" + ndxStr + ", eyeNormal, u_light" + ndxStr + "_color${NAME_SPEC}, u_material_diffuseColor${NAME_SPEC}.rgb, "
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"u_material_specularColor${NAME_SPEC}, u_material_shininess${NAME_SPEC}) * computeDistanceAttenuation(distanceToLight" + ndxStr + ", u_light" + ndxStr + "_constantAttenuation${NAME_SPEC}, "
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"u_light" + ndxStr + "_linearAttenuation${NAME_SPEC}, u_light" + ndxStr + "_quadraticAttenuation${NAME_SPEC});\n";
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				resultTemplate +=
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"	v_directionToLight${NAME_SPEC}[" + ndxStr + "] = directionToLight" + ndxStr + ";\n"
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"	v_distanceToLight${NAME_SPEC}[" + ndxStr + "]  = distanceToLight" + ndxStr + ";\n";
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (lightType == LIGHT_DIRECTIONAL)
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (isVertexCase)
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				resultTemplate +=
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"	mediump vec3 directionToLight" + ndxStr + " = -u_light" + ndxStr + "_direction${NAME_SPEC};\n"
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"	mediump vec3 halfVector" + ndxStr + " = normalize(directionToLight" + ndxStr + " + vec3(0.0, 0.0, 1.0));\n"
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"	color.rgb += computeLighting(directionToLight" + ndxStr + ", halfVector" + ndxStr + ", eyeNormal, u_light" + ndxStr + "_color${NAME_SPEC}, u_material_diffuseColor${NAME_SPEC}.rgb, u_material_specularColor${NAME_SPEC}, u_material_shininess${NAME_SPEC});\n";
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(DE_FALSE);
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate += "\n";
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	v_color${NAME_SPEC} = color;\n"
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${SEMANTIC_ERROR}"
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n"
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${INVALID_CHAR}";
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return resultTemplate;
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Function for generating the fragment shader of a (directional or point) light case.
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string lightFragmentTemplate (int numLights, bool isVertexCase, LightType lightType)
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string resultTemplate;
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!isVertexCase)
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform mediump vec3 u_material_ambientColor${NAME_SPEC};\n"
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform mediump vec4 u_material_diffuseColor${NAME_SPEC};\n"
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform mediump vec3 u_material_emissiveColor${NAME_SPEC};\n"
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform mediump vec3 u_material_specularColor${NAME_SPEC};\n"
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform mediump float u_material_shininess${NAME_SPEC};\n";
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int lightNdx = 0; lightNdx < numLights; lightNdx++)
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string ndxStr = de::toString(lightNdx);
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultTemplate +=
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"uniform mediump vec3 u_light" + ndxStr + "_color${NAME_SPEC};\n"
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"uniform mediump vec3 u_light" + ndxStr + "_direction${NAME_SPEC};\n";
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (lightType == LIGHT_POINT)
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				resultTemplate +=
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"uniform mediump vec4 u_light" + ndxStr + "_position${NAME_SPEC};\n"
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"uniform mediump float u_light" + ndxStr + "_constantAttenuation${NAME_SPEC};\n"
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"uniform mediump float u_light" + ndxStr + "_linearAttenuation${NAME_SPEC};\n"
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"uniform mediump float u_light" + ndxStr + "_quadraticAttenuation${NAME_SPEC};\n";
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform sampler2D u_sampler0${NAME_SPEC};\n"
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"varying mediump vec4 v_color${NAME_SPEC};\n"
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"varying mediump vec2 v_texCoord0${NAME_SPEC};\n";
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!isVertexCase)
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"varying mediump vec3 v_eyeNormal${NAME_SPEC};\n";
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (lightType == LIGHT_POINT)
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultTemplate +=
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"varying mediump vec3 v_directionToLight${NAME_SPEC}[" + de::toString(numLights) + "];\n"
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"varying mediump float v_distanceToLight${NAME_SPEC}[" + de::toString(numLights) + "];\n";
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"mediump vec3 direction (mediump vec4 from, mediump vec4 to)\n"
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	return vec3(to.xyz * from.w - from.xyz * to.w);\n"
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n"
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n";
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"mediump vec3 computeLighting (\n"
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump vec3 directionToLight,\n"
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump vec3 halfVector,\n"
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump vec3 normal,\n"
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump vec3 lightColor,\n"
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump vec3 diffuseColor,\n"
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump vec3 specularColor,\n"
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump float shininess)\n"
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump float normalDotDirection  = max(dot(normal, directionToLight), 0.0);\n"
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump vec3  color               = normalDotDirection * diffuseColor * lightColor;\n"
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	if (normalDotDirection != 0.0)\n"
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"		color += pow(max(dot(normal, halfVector), 0.0), shininess) * specularColor * lightColor;\n"
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	return color;\n"
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"}\n"
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n";
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (lightType == LIGHT_POINT)
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultTemplate +=
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"mediump float computeDistanceAttenuation (mediump float distToLight, mediump float constAtt, mediump float linearAtt, mediump float quadraticAtt)\n"
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"{\n"
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	return 1.0 / (constAtt + linearAtt * distToLight + quadraticAtt * distToLight * distToLight);\n"
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"}\n"
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"\n";
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main (void)\n"
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	mediump vec2 texCoord0 = v_texCoord0${NAME_SPEC}.xy;\n"
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	mediump vec4 color = v_color${NAME_SPEC};\n";
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!isVertexCase)
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump vec3 eyeNormal = normalize(v_eyeNormal${NAME_SPEC});\n"
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n";
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int lightNdx = 0; lightNdx < numLights; lightNdx++)
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string ndxStr = de::toString(lightNdx);
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultTemplate +=
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	/* Light " + ndxStr + " */\n";
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (lightType == LIGHT_POINT)
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				resultTemplate +=
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"	mediump vec3 directionToLight" + ndxStr + " = normalize(v_directionToLight${NAME_SPEC}[" + ndxStr + "]);\n"
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"	mediump float distanceToLight" + ndxStr + " = v_distanceToLight${NAME_SPEC}[" + ndxStr + "];\n"
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"	mediump vec3 halfVector" + ndxStr + " = normalize(directionToLight" + ndxStr + " + vec3(0.0, 0.0, 1.0));\n"
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"	color.rgb += computeLighting(directionToLight" + ndxStr + ", halfVector" + ndxStr + ", eyeNormal, u_light" + ndxStr + "_color${NAME_SPEC}, u_material_diffuseColor${NAME_SPEC}.rgb, "
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"u_material_specularColor${NAME_SPEC}, u_material_shininess${NAME_SPEC}) * computeDistanceAttenuation(distanceToLight" + ndxStr + ", u_light" + ndxStr + "_constantAttenuation${NAME_SPEC}, "
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"u_light" + ndxStr + "_linearAttenuation${NAME_SPEC}, u_light" + ndxStr + "_quadraticAttenuation${NAME_SPEC});\n"
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"\n";
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else if (lightType == LIGHT_DIRECTIONAL)
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				resultTemplate +=
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"	mediump vec3 directionToLight" + ndxStr + " = -u_light" + ndxStr + "_direction${NAME_SPEC};\n"
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"	mediump vec3 halfVector" + ndxStr + " = normalize(directionToLight" + ndxStr + " + vec3(0.0, 0.0, 1.0));\n"
10163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"	color.rgb += computeLighting(directionToLight" + ndxStr + ", halfVector" + ndxStr + ", eyeNormal, u_light" + ndxStr + "_color${NAME_SPEC}, u_material_diffuseColor${NAME_SPEC}.rgb, u_material_specularColor${NAME_SPEC}, u_material_shininess${NAME_SPEC});\n"
10173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"\n";
10183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			else
10193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(DE_FALSE);
10203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
10243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	color *= texture2D(u_sampler0${NAME_SPEC}, texCoord0);\n"
10253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_FragColor = color + ${FLOAT01};\n"
10263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${SEMANTIC_ERROR}"
10273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n"
10283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${INVALID_CHAR}";
10293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return resultTemplate;
10313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Function for generating the shader attributes of a (directional or point) light case.
10343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<ShaderCompilerCase::AttribSpec> lightShaderAttributes (const string& nameSpecialization)
10353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<ShaderCompilerCase::AttribSpec> result;
10373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::AttribSpec("a_position" + nameSpecialization,
10393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													combineVec4ToVec16(Vec4(-1.0f, -1.0f,  0.0f,  1.0f),
10403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4(-1.0f,  1.0f,  0.0f,  1.0f),
10413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4( 1.0f, -1.0f,  0.0f,  1.0f),
10423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4( 1.0f,  1.0f,  0.0f,  1.0f))));
10433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::AttribSpec("a_normal" + nameSpecialization,
10453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													combineVec4ToVec16(Vec4(0.0f, 0.0f, -1.0f, 0.0f),
10463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4(0.0f, 0.0f, -1.0f, 0.0f),
10473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4(0.0f, 0.0f, -1.0f, 0.0f),
10483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4(0.0f, 0.0f, -1.0f, 0.0f))));
10493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::AttribSpec("a_texCoord0" + nameSpecialization,
10513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													combineVec4ToVec16(Vec4(0.0f, 0.0f, 0.0f, 0.0f),
10523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4(1.0f, 0.0f, 0.0f, 0.0f),
10533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4(0.0f, 1.0f, 0.0f, 0.0f),
10543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4(1.0f, 1.0f, 0.0f, 0.0f))));
10553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
10573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Function for generating the shader uniforms of a (directional or point) light case.
10603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<ShaderCompilerCase::UniformSpec> lightShaderUniforms (const string& nameSpecialization, int numLights, LightType lightType)
10613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
10623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<ShaderCompilerCase::UniformSpec> result;
10633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::UniformSpec("u_material_ambientColor" + nameSpecialization,
10653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 ShaderCompilerCase::UniformSpec::TYPE_VEC3,
10663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 vecTo16(Vec3(0.5f, 0.7f, 0.9f))));
10673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::UniformSpec("u_material_diffuseColor" + nameSpecialization,
10693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 ShaderCompilerCase:: UniformSpec::TYPE_VEC4,
10703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 vecTo16(Vec4(0.3f, 0.4f, 0.5f, 1.0f))));
10713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::UniformSpec("u_material_emissiveColor" + nameSpecialization,
10733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 ShaderCompilerCase::UniformSpec::TYPE_VEC3,
10743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 vecTo16(Vec3(0.7f, 0.2f, 0.2f))));
10753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::UniformSpec("u_material_specularColor" + nameSpecialization,
10773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 ShaderCompilerCase::UniformSpec::TYPE_VEC3,
10783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 vecTo16(Vec3(0.2f, 0.6f, 1.0f))));
10793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::UniformSpec("u_material_shininess" + nameSpecialization,
10813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 ShaderCompilerCase::UniformSpec::TYPE_FLOAT,
10823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 0.8f));
10833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int lightNdx = 0; lightNdx < numLights; lightNdx++)
10853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
10863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string ndxStr = de::toString(lightNdx);
10873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.push_back(ShaderCompilerCase::UniformSpec("u_light" + ndxStr + "_color" + nameSpecialization,
10893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 ShaderCompilerCase::UniformSpec::TYPE_VEC3,
10903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 vecTo16(Vec3(0.8f, 0.6f, 0.3f))));
10913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.push_back(ShaderCompilerCase::UniformSpec("u_light" + ndxStr + "_direction" + nameSpecialization,
10933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 ShaderCompilerCase::UniformSpec::TYPE_VEC3,
10943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 vecTo16(Vec3(0.2f, 0.3f, 0.4f))));
10953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (lightType == LIGHT_POINT)
10973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
10983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.push_back(ShaderCompilerCase::UniformSpec("u_light" + ndxStr + "_position" + nameSpecialization,
10993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 ShaderCompilerCase::UniformSpec::TYPE_VEC4,
11003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 vecTo16(Vec4(1.0f, 0.6f, 0.3f, 0.2f))));
11013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.push_back(ShaderCompilerCase::UniformSpec("u_light" + ndxStr + "_constantAttenuation" + nameSpecialization,
11033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 ShaderCompilerCase::UniformSpec::TYPE_FLOAT,
11043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 0.6f));
11053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.push_back(ShaderCompilerCase::UniformSpec("u_light" + ndxStr + "_linearAttenuation" + nameSpecialization,
11073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 ShaderCompilerCase::UniformSpec::TYPE_FLOAT,
11083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 0.5f));
11093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result.push_back(ShaderCompilerCase::UniformSpec("u_light" + ndxStr + "_quadraticAttenuation" + nameSpecialization,
11113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 ShaderCompilerCase::UniformSpec::TYPE_FLOAT,
11123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 0.4f));
11133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::UniformSpec("u_mvpMatrix" + nameSpecialization,
11173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 ShaderCompilerCase::UniformSpec::TYPE_MAT4,
11183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 arrTo16(Mat4(1.0f).getColumnMajorData())));
11193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::UniformSpec("u_modelViewMatrix" + nameSpecialization,
11213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 ShaderCompilerCase::UniformSpec::TYPE_MAT4,
11223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 arrTo16(Mat4(1.0f).getColumnMajorData())));
11233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::UniformSpec("u_normalMatrix" + nameSpecialization,
11253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 ShaderCompilerCase::UniformSpec::TYPE_MAT3,
11263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 arrTo16(Mat3(1.0f).getColumnMajorData())));
11273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::UniformSpec("u_texCoordMatrix0" + nameSpecialization,
11293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 ShaderCompilerCase::UniformSpec::TYPE_MAT4,
11303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 arrTo16(Mat4(1.0f).getColumnMajorData())));
11313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::UniformSpec("u_sampler0" + nameSpecialization,
11333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 ShaderCompilerCase::UniformSpec::TYPE_TEXTURE_UNIT,
11343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 0.0f));
11353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
11373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
11383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Function for generating a vertex shader with a for loop.
11403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string loopVertexTemplate (LoopType type, bool isVertexCase, int numLoopIterations, int nestingDepth)
11413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
11423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string resultTemplate;
11433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string loopBound		= type == LOOP_TYPE_STATIC	? de::toString(numLoopIterations)
11443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							: type == LOOP_TYPE_UNIFORM	? "int(u_loopBound${NAME_SPEC})"
11453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							: type == LOOP_TYPE_DYNAMIC	? "int(a_loopBound${NAME_SPEC})"
11463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							: "";
11473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!loopBound.empty());
11493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
11513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"attribute highp vec4 a_position${NAME_SPEC};\n";
11523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type == LOOP_TYPE_DYNAMIC)
11543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
11553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"attribute mediump float a_loopBound${NAME_SPEC};\n";
11563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
11583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"attribute mediump vec4 a_value${NAME_SPEC};\n"
11593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"varying mediump vec4 v_value${NAME_SPEC};\n";
11603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (isVertexCase)
11623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (type == LOOP_TYPE_UNIFORM)
11643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultTemplate += "uniform mediump float u_loopBound${NAME_SPEC};\n";
11653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
11673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
11683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main()\n"
11693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
11703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_Position = a_position${NAME_SPEC} * (0.95 + 0.05*${FLOAT01});\n"
11713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump vec4 value = a_value${NAME_SPEC};\n";
11723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < nestingDepth; i++)
11743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
11753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string iterName = "i" + de::toString(i);
11763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultTemplate += string(i + 1, '\t') + "for (int " + iterName + " = 0; " + iterName + " < " + loopBound + "; " + iterName + "++)\n";
11773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
11783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate += string(nestingDepth + 1, '\t') + "value *= a_value${NAME_SPEC};\n";
11803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
11823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	v_value${NAME_SPEC} = value;\n";
11833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
11843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
11853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
11863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (type == LOOP_TYPE_DYNAMIC)
11873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultTemplate +=
11883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"varying mediump float v_loopBound${NAME_SPEC};\n";
11893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
11913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
11923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main()\n"
11933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
11943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_Position = a_position${NAME_SPEC} * (0.95 + 0.05*${FLOAT01});\n"
11953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	v_value${NAME_SPEC} = a_value${NAME_SPEC};\n";
11963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
11973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (type == LOOP_TYPE_DYNAMIC)
11983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultTemplate +=
11993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"	v_loopBound${NAME_SPEC} = a_loopBound${NAME_SPEC};\n";
12003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
12033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${SEMANTIC_ERROR}"
12043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n"
12053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${INVALID_CHAR}";
12063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return resultTemplate;
12083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Function for generating a fragment shader with a for loop.
12113c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string loopFragmentTemplate (LoopType type, bool isVertexCase, int numLoopIterations, int nestingDepth)
12123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string resultTemplate;
12143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string loopBound		= type == LOOP_TYPE_STATIC	? de::toString(numLoopIterations)
12153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							: type == LOOP_TYPE_UNIFORM	? "int(u_loopBound${NAME_SPEC})"
12163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							: type == LOOP_TYPE_DYNAMIC	? "int(v_loopBound${NAME_SPEC})"
12173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							: "";
12183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(!loopBound.empty());
12203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
12223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"varying mediump vec4 v_value${NAME_SPEC};\n";
12233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!isVertexCase)
12253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
12263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (type == LOOP_TYPE_DYNAMIC)
12273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultTemplate +=
12283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"varying mediump float v_loopBound${NAME_SPEC};\n";
12293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (type == LOOP_TYPE_UNIFORM)
12303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultTemplate +=
12313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				"uniform mediump float u_loopBound${NAME_SPEC};\n";
12323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
12343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
12353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main()\n"
12363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
12373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	mediump vec4 value = v_value${NAME_SPEC};\n";
12383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < nestingDepth; i++)
12403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
12413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string iterName = "i" + de::toString(i);
12423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultTemplate += string(i + 1, '\t') + "for (int " + iterName + " = 0; " + iterName + " < " + loopBound + "; " + iterName + "++)\n";
12433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
12443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate += string(nestingDepth + 1, '\t') + "value *= v_value${NAME_SPEC};\n";
12463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
12483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_FragColor = value + ${FLOAT01};\n";
12493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
12503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
12513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
12523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"\n"
12533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"void main()\n"
12543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"{\n"
12553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	gl_FragColor = v_value${NAME_SPEC} + ${FLOAT01};\n";
12563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
12583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${SEMANTIC_ERROR}"
12593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n"
12603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${INVALID_CHAR}";
12613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return resultTemplate;
12633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Function for generating the shader attributes for a loop case.
12663c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<ShaderCompilerCase::AttribSpec> loopShaderAttributes (const string& nameSpecialization, LoopType type, int numLoopIterations)
12673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<ShaderCompilerCase::AttribSpec> result;
12693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::AttribSpec("a_position" + nameSpecialization,
12713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													combineVec4ToVec16(Vec4(-1.0f, -1.0f,  0.0f,  1.0f),
12723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4(-1.0f,  1.0f,  0.0f,  1.0f),
12733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4( 1.0f, -1.0f,  0.0f,  1.0f),
12743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4( 1.0f,  1.0f,  0.0f,  1.0f))));
12753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::AttribSpec("a_value" + nameSpecialization,
12773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													combineVec4ToVec16(Vec4( 1.0f,  1.0f,  1.0f,  1.0f),
12783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4( 1.0f,  1.0f,  1.0f,  1.0f),
12793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4( 1.0f,  1.0f,  1.0f,  1.0f),
12803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4( 1.0f,  1.0f,  1.0f,  1.0f))));
12813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type == LOOP_TYPE_DYNAMIC)
12833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.push_back(ShaderCompilerCase::AttribSpec("a_loopBound" + nameSpecialization,
12843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														combineVec4ToVec16(Vec4((float)numLoopIterations, 0.0f, 0.0f, 0.0f),
12853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		   Vec4((float)numLoopIterations, 0.0f, 0.0f, 0.0f),
12863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		   Vec4((float)numLoopIterations, 0.0f, 0.0f, 0.0f),
12873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		   Vec4((float)numLoopIterations, 0.0f, 0.0f, 0.0f))));
12883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
12903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
12913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<ShaderCompilerCase::UniformSpec> loopShaderUniforms (const string& nameSpecialization, LoopType type, int numLoopIterations)
12933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
12943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<ShaderCompilerCase::UniformSpec> result;
12953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
12963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (type == LOOP_TYPE_UNIFORM)
12973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.push_back(ShaderCompilerCase::UniformSpec("u_loopBound" + nameSpecialization,
12983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 ShaderCompilerCase::UniformSpec::TYPE_FLOAT,
12993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 (float)numLoopIterations));
13003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
13023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Function for generating the shader attributes for a case with only one attribute value in addition to the position attribute.
13053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<ShaderCompilerCase::AttribSpec> singleValueShaderAttributes (const string& nameSpecialization)
13063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<ShaderCompilerCase::AttribSpec> result;
13083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::AttribSpec("a_position" + nameSpecialization,
13103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													combineVec4ToVec16(Vec4(-1.0f, -1.0f,  0.0f,  1.0f),
13113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4(-1.0f,  1.0f,  0.0f,  1.0f),
13123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4( 1.0f, -1.0f,  0.0f,  1.0f),
13133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4( 1.0f,  1.0f,  0.0f,  1.0f))));
13143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::AttribSpec("a_value" + nameSpecialization,
13163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													combineVec4ToVec16(Vec4( 1.0f,  1.0f,  1.0f,  1.0f),
13173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4( 1.0f,  1.0f,  1.0f,  1.0f),
13183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4( 1.0f,  1.0f,  1.0f,  1.0f),
13193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4( 1.0f,  1.0f,  1.0f,  1.0f))));
13203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
13223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Function for generating a vertex shader with a binary operation chain.
13253c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string binaryOpVertexTemplate (int numOperations, const char* op)
13263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string resultTemplate;
13283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
13303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"attribute highp vec4 a_position${NAME_SPEC};\n"
13313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"attribute mediump vec4 a_value${NAME_SPEC};\n"
13323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"varying mediump vec4 v_value${NAME_SPEC};\n"
13333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
13343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main()\n"
13353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
13363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_Position = a_position${NAME_SPEC} * (0.95 + 0.05*${FLOAT01});\n"
13373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	mediump vec4 value = ";
13383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numOperations; i++)
13403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate += string(i > 0 ? op : "") + "a_value${NAME_SPEC}";
13413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
13433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		";\n"
13443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	v_value${NAME_SPEC} = value;\n"
13453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${SEMANTIC_ERROR}"
13463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n"
13473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${INVALID_CHAR}";
13483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return resultTemplate;
13503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Function for generating a fragment shader with a binary operation chain.
13533c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string binaryOpFragmentTemplate (int numOperations, const char* op)
13543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string resultTemplate;
13563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
13583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"varying mediump vec4 v_value${NAME_SPEC};\n"
13593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
13603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main()\n"
13613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
13623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	mediump vec4 value = ";
13633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numOperations; i++)
13653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate += string(i > 0 ? op : "") + "v_value${NAME_SPEC}";
13663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
13683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		";\n"
13693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_FragColor = value + ${FLOAT01};\n"
13703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${SEMANTIC_ERROR}"
13713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n"
13723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${INVALID_CHAR}";
13733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return resultTemplate;
13753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Function for generating a vertex that takes one attribute in addition to position and just passes it to the fragment shader as a varying.
13783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string singleVaryingVertexTemplate (void)
13793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* resultTemplate =
13813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"attribute highp vec4 a_position${NAME_SPEC};\n"
13823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"attribute mediump vec4 a_value${NAME_SPEC};\n"
13833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"varying mediump vec4 v_value${NAME_SPEC};\n"
13843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
13853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main()\n"
13863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
13873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_Position = a_position${NAME_SPEC} * (0.95 + 0.05*${FLOAT01});\n"
13883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	v_value${NAME_SPEC} = a_value${NAME_SPEC};\n"
13893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${SEMANTIC_ERROR}"
13903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n"
13913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${INVALID_CHAR}";
13923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return resultTemplate;
13943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
13953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
13963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Function for generating a fragment shader that takes a single varying and uses it as the color.
13973c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string singleVaryingFragmentTemplate (void)
13983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
13993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* resultTemplate =
14003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"varying mediump vec4 v_value${NAME_SPEC};\n"
14013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
14023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main()\n"
14033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
14043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_FragColor = v_value${NAME_SPEC} + ${FLOAT01};\n"
14053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${SEMANTIC_ERROR}"
14063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n"
14073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${INVALID_CHAR}";
14083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return resultTemplate;
14103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Function for generating the vertex shader of a texture lookup case.
14133c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string textureLookupVertexTemplate (ConditionalUsage conditionalUsage, ConditionalType conditionalType)
14143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string	resultTemplate;
14163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool	conditionVaryingNeeded = conditionalUsage != CONDITIONAL_USAGE_NONE && conditionalType == CONDITIONAL_TYPE_DYNAMIC;
14173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
14193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"attribute highp vec4 a_position${NAME_SPEC};\n"
14203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"attribute mediump vec2 a_coords${NAME_SPEC};\n"
14213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"varying mediump vec2 v_coords${NAME_SPEC};\n";
14223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (conditionVaryingNeeded)
14243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
14253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"attribute mediump float a_condition${NAME_SPEC};\n"
14263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"varying mediump float v_condition${NAME_SPEC};\n";
14273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
14293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
14303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main()\n"
14313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
14323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_Position = a_position${NAME_SPEC} * (0.95 + 0.05*${FLOAT01});\n"
14333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	v_coords${NAME_SPEC} = a_coords${NAME_SPEC};\n";
14343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (conditionVaryingNeeded)
14363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
14373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	v_condition${NAME_SPEC} = a_condition${NAME_SPEC};\n";
14383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
14403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${SEMANTIC_ERROR}"
14413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n"
14423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${INVALID_CHAR}";
14433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return resultTemplate;
14453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
14463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Function for generating the fragment shader of a texture lookup case.
14483c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string textureLookupFragmentTemplate (int numLookups, ConditionalUsage conditionalUsage, ConditionalType conditionalType)
14493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
14503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string resultTemplate;
14513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
14533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"varying mediump vec2 v_coords${NAME_SPEC};\n";
14543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (conditionalUsage != CONDITIONAL_USAGE_NONE && conditionalType == CONDITIONAL_TYPE_DYNAMIC)
14563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
14573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"varying mediump float v_condition${NAME_SPEC};\n";
14583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numLookups; i++)
14603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
14613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform sampler2D u_sampler" + de::toString(i) + "${NAME_SPEC};\n";
14623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (conditionalUsage != CONDITIONAL_USAGE_NONE && conditionalType == CONDITIONAL_TYPE_UNIFORM)
14643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
14653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"uniform mediump float u_condition${NAME_SPEC};\n";
14663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
14683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
14693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main()\n"
14703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
14713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	mediump vec4 color = vec4(0.0);\n";
14723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* conditionalTerm = conditionalType == CONDITIONAL_TYPE_STATIC	? "1.0 > 0.0"
14743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								: conditionalType == CONDITIONAL_TYPE_UNIFORM	? "u_condition${NAME_SPEC} > 0.0"
14753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								: conditionalType == CONDITIONAL_TYPE_DYNAMIC	? "v_condition${NAME_SPEC} > 0.0"
14763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								: DE_NULL;
14773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(conditionalTerm != DE_NULL);
14793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (conditionalUsage == CONDITIONAL_USAGE_FIRST_HALF)
14813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate += string("") +
14823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	if (" + conditionalTerm + ")\n"
14833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	{\n";
14843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
14853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numLookups; i++)
14863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
14873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (conditionalUsage == CONDITIONAL_USAGE_FIRST_HALF)
14883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (i < (numLookups + 1) / 2)
14903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				resultTemplate += "\t";
14913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else if (conditionalUsage == CONDITIONAL_USAGE_EVERY_OTHER)
14933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
14943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (i % 2 == 0)
14953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				resultTemplate += string("") +
14963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"	if (" + conditionalTerm + ")\n"
14973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					"\t";
14983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
14993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		resultTemplate +=
15013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			"	color += texture2D(u_sampler" + de::toString(i) + "${NAME_SPEC}, v_coords${NAME_SPEC});\n";
15023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (conditionalUsage == CONDITIONAL_USAGE_FIRST_HALF && i == (numLookups - 1) / 2)
15043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			resultTemplate += "\t}\n";
15053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
15063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	resultTemplate +=
15083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_FragColor = color/" + de::toString(numLookups) + ".0 + ${FLOAT01};\n" +
15093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${SEMANTIC_ERROR}"
15103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n"
15113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${INVALID_CHAR}";
15123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return resultTemplate;
15143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Function for generating the shader attributes of a texture lookup case.
15173c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<ShaderCompilerCase::AttribSpec> textureLookupShaderAttributes (const string& nameSpecialization, ConditionalUsage conditionalUsage, ConditionalType conditionalType)
15183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<ShaderCompilerCase::AttribSpec> result;
15203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::AttribSpec("a_position" + nameSpecialization,
15223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													combineVec4ToVec16(Vec4(-1.0f, -1.0f,  0.0f,  1.0f),
15233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4(-1.0f,  1.0f,  0.0f,  1.0f),
15243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4( 1.0f, -1.0f,  0.0f,  1.0f),
15253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4( 1.0f,  1.0f,  0.0f,  1.0f))));
15263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::AttribSpec("a_coords" + nameSpecialization,
15283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													combineVec4ToVec16(Vec4(0.0f, 0.0f, 0.0f, 0.0f),
15293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4(0.0f, 1.0f, 0.0f, 0.0f),
15303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4(1.0f, 0.0f, 0.0f, 0.0f),
15313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4(1.0f, 1.0f, 0.0f, 0.0f))));
15323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (conditionalUsage != CONDITIONAL_USAGE_NONE && conditionalType == CONDITIONAL_TYPE_DYNAMIC)
15343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.push_back(ShaderCompilerCase::AttribSpec("a_condition" + nameSpecialization,
15353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														combineVec4ToVec16(Vec4(1.0f), Vec4(1.0f), Vec4(1.0f), Vec4(1.0f))));
15363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
15383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// Function for generating the shader uniforms of a texture lookup case.
15413c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<ShaderCompilerCase::UniformSpec> textureLookupShaderUniforms (const string& nameSpecialization, int numLookups, ConditionalUsage conditionalUsage, ConditionalType conditionalType)
15423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<ShaderCompilerCase::UniformSpec> result;
15443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numLookups; i++)
15463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.push_back(ShaderCompilerCase::UniformSpec("u_sampler" + de::toString(i) + nameSpecialization,
15473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 ShaderCompilerCase::UniformSpec::TYPE_TEXTURE_UNIT,
15483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 (float)i));
15493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (conditionalUsage != CONDITIONAL_USAGE_NONE && conditionalType == CONDITIONAL_TYPE_UNIFORM)
15513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.push_back(ShaderCompilerCase::UniformSpec("u_condition" + nameSpecialization,
15523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 ShaderCompilerCase::UniformSpec::TYPE_FLOAT,
15533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														 1.0f));
15543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
15563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15583c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string mandelbrotVertexTemplate (void)
15593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* resultTemplate =
15613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"uniform highp mat4 u_mvp${NAME_SPEC};\n"
15623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
15633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"attribute highp vec4 a_vertex${NAME_SPEC};\n"
15643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"attribute highp vec4 a_coord${NAME_SPEC};\n"
15653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
15663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"varying mediump vec2 v_coord${NAME_SPEC};\n"
15673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
15683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main(void)\n"
15693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
15703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_Position = u_mvp${NAME_SPEC} * a_vertex${NAME_SPEC} * (0.95 + 0.05*${FLOAT01});\n"
15713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
15723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	float xMin = -2.0;\n"
15733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	float xMax = +0.5;\n"
15743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	float yMin = -1.5;\n"
15753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	float yMax = +1.5;\n"
15763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
15773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	v_coord${NAME_SPEC}.x = a_coord${NAME_SPEC}.x * (xMax - xMin) + xMin;\n"
15783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	v_coord${NAME_SPEC}.y = a_coord${NAME_SPEC}.y * (yMax - yMin) + yMin;\n"
15793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${SEMANTIC_ERROR}"
15803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n"
15813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${INVALID_CHAR}";
15823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return resultTemplate;
15843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
15853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
15863c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic string mandelbrotFragmentTemplate (int numFractalIterations)
15873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
15883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string resultTemplate =
15893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"varying mediump vec2 v_coord${NAME_SPEC};\n"
15903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
15913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"precision mediump float;\n"
15923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
15933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"#define NUM_ITERS " + de::toString(numFractalIterations) + "\n"
15943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
15953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"void main (void)\n"
15963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"{\n"
15973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	vec2 coords = v_coord${NAME_SPEC};\n"
15983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	float u_limit = 2.0 * 2.0;\n"
15993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	vec2 tmp = vec2(0, 0);\n"
16003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	int iter;\n"
16013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
16023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	for (iter = 0; iter < NUM_ITERS; iter++)\n"
16033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	{\n"
16043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"		tmp = vec2((tmp.x + tmp.y) * (tmp.x - tmp.y), 2.0 * (tmp.x * tmp.y)) + coords;\n"
16053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
16063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"		if (dot(tmp, tmp) > u_limit)\n"
16073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"			break;\n"
16083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	}\n"
16093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
16103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	vec3 color = vec3(float(iter) * (1.0 / float(NUM_ITERS)));\n"
16113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"\n"
16123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"	gl_FragColor = vec4(color, 1.0) + ${FLOAT01};\n"
16133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${SEMANTIC_ERROR}"
16143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"}\n"
16153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		"${INVALID_CHAR}";
16163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return resultTemplate;
16183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16203c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<ShaderCompilerCase::AttribSpec> mandelbrotShaderAttributes (const string& nameSpecialization)
16213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<ShaderCompilerCase::AttribSpec> result;
16233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::AttribSpec("a_vertex" + nameSpecialization,
16253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													combineVec4ToVec16(Vec4(-1.0f, -1.0f,  0.0f,  1.0f),
16263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4(-1.0f,  1.0f,  0.0f,  1.0f),
16273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4( 1.0f, -1.0f,  0.0f,  1.0f),
16283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4( 1.0f,  1.0f,  0.0f,  1.0f))));
16293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::AttribSpec("a_coord" + nameSpecialization,
16313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													combineVec4ToVec16(Vec4(0.0f, 0.0f, 0.0f, 1.0f),
16323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4(0.0f, 1.0f, 0.0f, 1.0f),
16333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4(1.0f, 0.0f, 0.0f, 1.0f),
16343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																	   Vec4(1.0f, 1.0f, 0.0f, 1.0f))));
16353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
16373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16393c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic vector<ShaderCompilerCase::UniformSpec> mandelbrotShaderUniforms (const string& nameSpecialization)
16403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<ShaderCompilerCase::UniformSpec> result;
16423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.push_back(ShaderCompilerCase::UniformSpec("u_mvp" + nameSpecialization,
16443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 ShaderCompilerCase::UniformSpec::TYPE_MAT4,
16453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 arrTo16(Mat4(1.0f).getColumnMajorData())));
16463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
16483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16503c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerCase::ShaderCompilerCase (Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments)
16513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase								(context, tcu::NODETYPE_PERFORMANCE, name, description)
16523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_viewportWidth						(0)
16533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_viewportHeight						(0)
16543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_avoidCache							(avoidCache)
16553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_addWhitespaceAndComments			(addWhitespaceAndComments)
16563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_startHash							((deUint32)(deUint64Hash(deGetTime()) ^ deUint64Hash(deGetMicroseconds()) ^ deInt32Hash(caseID)))
16573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int cmdLineIterCount = context.getTestContext().getCommandLine().getTestIterationCount();
16593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_minimumMeasurementCount = cmdLineIterCount > 0 ? cmdLineIterCount : DEFAULT_MINIMUM_MEASUREMENT_COUNT;
16603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_maximumMeasurementCount = m_minimumMeasurementCount*3;
16613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16633c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerCase::~ShaderCompilerCase (void)
16643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16673c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 ShaderCompilerCase::getSpecializationID (int measurementNdx) const
16683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_avoidCache)
16703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return m_startHash ^ (deUint32)deInt32Hash((deInt32)measurementNdx);
16713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
16723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return m_startHash;
16733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16753c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderCompilerCase::init (void)
16763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&		gl				= m_context.getRenderContext().getFunctions();
16783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::RenderTarget&	renderTarget	= m_context.getRenderContext().getRenderTarget();
16793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_viewportWidth		= deMin32(MAX_VIEWPORT_WIDTH, renderTarget.getWidth());
16813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_viewportHeight	= deMin32(MAX_VIEWPORT_HEIGHT, renderTarget.getHeight());
16823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.viewport(0, 0, m_viewportWidth, m_viewportHeight);
16843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
16853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16863c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerCase::ShadersAndProgram ShaderCompilerCase::createShadersAndProgram (void) const
16873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
16883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl = m_context.getRenderContext().getFunctions();
16893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShadersAndProgram		result;
16903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.vertShader	= gl.createShader(GL_VERTEX_SHADER);
16923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.fragShader	= gl.createShader(GL_FRAGMENT_SHADER);
16933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.program		= gl.createProgram();
16943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.attachShader(result.program, result.vertShader);
16963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.attachShader(result.program, result.fragShader);
16973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
16983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
16993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderCompilerCase::setShaderSources (deUint32 vertShader, deUint32 fragShader, const ProgramContext& progCtx) const
17023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
17043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* vertShaderSourceCStr = progCtx.vertShaderSource.c_str();
17053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* fragShaderSourceCStr = progCtx.fragShaderSource.c_str();
17063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.shaderSource(vertShader, 1, &vertShaderSourceCStr, DE_NULL);
17073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.shaderSource(fragShader, 1, &fragShaderSourceCStr, DE_NULL);
17083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ShaderCompilerCase::compileShader (deUint32 shader) const
17113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1713059a70e68d787977450b0c6a5f61c034b5e45dcaMika Isojärvi	GLint status = 0;
17143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.compileShader(shader);
17153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getShaderiv(shader, GL_COMPILE_STATUS, &status);
17163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return status != 0;
17173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17193c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ShaderCompilerCase::linkAndUseProgram (deUint32 program) const
17203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1722059a70e68d787977450b0c6a5f61c034b5e45dcaMika Isojärvi	GLint linkStatus = 0;
17233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.linkProgram(program);
17253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getProgramiv(program, GL_LINK_STATUS, &linkStatus);
17263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (linkStatus != 0)
17283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.useProgram(program);
17293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return linkStatus != 0;
17313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderCompilerCase::setShaderInputs (deUint32 program, const ProgramContext& progCtx) const
17343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
17363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup attributes.
17383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int attribNdx = 0; attribNdx < (int)progCtx.vertexAttributes.size(); attribNdx++)
17403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int location = gl.getAttribLocation(program, progCtx.vertexAttributes[attribNdx].name.c_str());
17423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (location >= 0)
17433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.enableVertexAttribArray(location);
17453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			gl.vertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE, 0, progCtx.vertexAttributes[attribNdx].value.getPtr());
17463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup uniforms.
17503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int uniformNdx = 0; uniformNdx < (int)progCtx.uniforms.size(); uniformNdx++)
17523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		int location = gl.getUniformLocation(program, progCtx.uniforms[uniformNdx].name.c_str());
17543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (location >= 0)
17553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
17563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const float* floatPtr = progCtx.uniforms[uniformNdx].value.getPtr();
17573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			switch (progCtx.uniforms[uniformNdx].type)
17593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
17603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case UniformSpec::TYPE_FLOAT:			gl.uniform1fv(location, 1, floatPtr);								break;
17613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case UniformSpec::TYPE_VEC2:			gl.uniform2fv(location, 1, floatPtr);								break;
17623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case UniformSpec::TYPE_VEC3:			gl.uniform3fv(location, 1, floatPtr);								break;
17633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case UniformSpec::TYPE_VEC4:			gl.uniform4fv(location, 1, floatPtr);								break;
17643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case UniformSpec::TYPE_MAT3:			gl.uniformMatrix3fv(location, 1, GL_FALSE, floatPtr);				break;
17653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case UniformSpec::TYPE_MAT4:			gl.uniformMatrix4fv(location, 1, GL_FALSE, floatPtr);				break;
17663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				case UniformSpec::TYPE_TEXTURE_UNIT:	gl.uniform1i(location, (GLint)deRoundFloatToInt32(*floatPtr));		break;
17673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				default:
17683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(DE_FALSE);
17693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
17703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
17713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
17723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderCompilerCase::draw (void) const
17753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
17773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static const deUint8 indices[] =
17793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		0, 1, 2,
17813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		2, 1, 3
17823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
17833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
17853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.drawElements(GL_TRIANGLES, DE_LENGTH_OF_ARRAY(indices), GL_UNSIGNED_BYTE, indices);
17863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note Read one pixel to force compilation.
17883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32 pixel;
17893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
17903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
17913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderCompilerCase::cleanup (const ShadersAndProgram& shadersAndProgram, const ProgramContext& progCtx, bool linkSuccess) const
17933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
17943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
17953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
17963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (linkSuccess)
17973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
17983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int attribNdx = 0; attribNdx < (int)progCtx.vertexAttributes.size(); attribNdx++)
17993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int location = gl.getAttribLocation(shadersAndProgram.program, progCtx.vertexAttributes[attribNdx].name.c_str());
18013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (location >= 0)
18023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				gl.disableVertexAttribArray(location);
18033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.useProgram(0);
18073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.detachShader(shadersAndProgram.program, shadersAndProgram.vertShader);
18083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.detachShader(shadersAndProgram.program, shadersAndProgram.fragShader);
18093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.deleteShader(shadersAndProgram.vertShader);
18103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.deleteShader(shadersAndProgram.fragShader);
18113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.deleteProgram(shadersAndProgram.program);
18123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18143c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderCompilerCase::logProgramData (const BuildInfo& buildInfo, const ProgramContext& progCtx) const
18153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << TestLog::ShaderProgram(buildInfo.linkSuccess, buildInfo.logs.link)
18173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   << TestLog::Shader(QP_SHADER_TYPE_VERTEX,	progCtx.vertShaderSource, buildInfo.vertCompileSuccess, buildInfo.logs.vert)
18183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   << TestLog::Shader(QP_SHADER_TYPE_FRAGMENT,	progCtx.fragShaderSource, buildInfo.fragCompileSuccess, buildInfo.logs.frag)
18193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   << TestLog::EndShaderProgram;
18203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18223c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerCase::Logs ShaderCompilerCase::getLogs (const ShadersAndProgram& shadersAndProgram) const
18233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl = m_context.getRenderContext().getFunctions();
18253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Logs					result;
18263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.vert = getShaderInfoLog(gl, shadersAndProgram.vertShader);
18283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.frag = getShaderInfoLog(gl, shadersAndProgram.fragShader);
18293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.link = getProgramInfoLog(gl, shadersAndProgram.program);
18303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
18323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18343c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool ShaderCompilerCase::goodEnoughMeasurements (const vector<Measurement>& measurements) const
18353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((int)measurements.size() < m_minimumMeasurementCount)
18373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
18383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
18393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((int)measurements.size() >= m_maximumMeasurementCount)
18413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
18423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
18433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vector<deInt64> totalTimesWithoutDraw;
18453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)measurements.size(); i++)
18463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				totalTimesWithoutDraw.push_back(measurements[i].totalTimeWithoutDraw());
18473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return vectorFloatRelativeMedianAbsoluteDeviation(vectorLowestPercentage(totalTimesWithoutDraw, 0.5f)) < RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD;
18483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
18513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18523c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerCase::IterateResult ShaderCompilerCase::iterate (void)
18533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
18543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Before actual measurements, compile and draw with a dummy shader to avoid possible initial slowdowns in the actual test.
18553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		specID = getSpecializationID(0);
18573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ProgramContext	progCtx;
18583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		progCtx.vertShaderSource = specializeShaderSource(singleVaryingVertexTemplate(), specID, SHADER_VALIDITY_VALID);
18593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		progCtx.fragShaderSource = specializeShaderSource(singleVaryingFragmentTemplate(), specID, SHADER_VALIDITY_VALID);
18603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		progCtx.vertexAttributes = singleValueShaderAttributes(getNameSpecialization(specID));
18613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ShadersAndProgram shadersAndProgram = createShadersAndProgram();
18633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		setShaderSources(shadersAndProgram.vertShader, shadersAndProgram.fragShader, progCtx);
18643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BuildInfo buildInfo;
18663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buildInfo.vertCompileSuccess	= compileShader(shadersAndProgram.vertShader);
18673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buildInfo.fragCompileSuccess	= compileShader(shadersAndProgram.fragShader);
18683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buildInfo.linkSuccess			= linkAndUseProgram(shadersAndProgram.program);
18693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!(buildInfo.vertCompileSuccess && buildInfo.fragCompileSuccess && buildInfo.linkSuccess))
18703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
18713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buildInfo.logs = getLogs(shadersAndProgram);
18723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			logProgramData(buildInfo, progCtx);
18733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			cleanup(shadersAndProgram, progCtx, buildInfo.linkSuccess);
18743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compilation failed");
18753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return STOP;
18763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
18773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		setShaderInputs(shadersAndProgram.program, progCtx);
18783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		draw();
18793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		cleanup(shadersAndProgram, progCtx, buildInfo.linkSuccess);
18803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
18813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Measurement>		measurements;
18833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note These are logged after measurements are done.
18843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext			latestProgramContext;
18853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	BuildInfo				latestBuildInfo;
18863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (WARMUP_CPU_AT_BEGINNING_OF_CASE)
18883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::warmupCPU();
18893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Actual test measurements.
18913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	while (!goodEnoughMeasurements(measurements))
18923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
18933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Create shaders, compile & link, set shader inputs and draw. Time measurement is done at relevant points.
18943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note Setting inputs and drawing are done twice in order to find out the time for actual compiling.
18953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
18963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note Shader data (sources and inputs) are generated and GL shader and program objects are created before any time measurements.
18973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ProgramContext		progCtx				= generateShaderData((int)measurements.size());
18983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ShadersAndProgram	shadersAndProgram	= createShadersAndProgram();
18993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BuildInfo			buildInfo;
19003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_addWhitespaceAndComments)
19023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const deUint32 hash = m_startHash ^ (deUint32)deInt32Hash((deInt32)measurements.size());
19043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			progCtx.vertShaderSource = strWithWhiteSpaceAndComments(progCtx.vertShaderSource, hash);
19053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			progCtx.fragShaderSource = strWithWhiteSpaceAndComments(progCtx.fragShaderSource, hash);
19063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (WARMUP_CPU_BEFORE_EACH_MEASUREMENT)
19093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::warmupCPU();
19103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note Do NOT do anything too hefty between the first and last deGetMicroseconds() here (other than the gl calls); it would disturb the measurement.
19123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint64 startTime = deGetMicroseconds();
19143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		setShaderSources(shadersAndProgram.vertShader, shadersAndProgram.fragShader, progCtx);
19163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint64 shaderSourceSetEndTime = deGetMicroseconds();
19173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buildInfo.vertCompileSuccess = compileShader(shadersAndProgram.vertShader);
19193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint64 vertexShaderCompileEndTime = deGetMicroseconds();
19203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buildInfo.fragCompileSuccess = compileShader(shadersAndProgram.fragShader);
19223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint64 fragmentShaderCompileEndTime = deGetMicroseconds();
19233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buildInfo.linkSuccess = linkAndUseProgram(shadersAndProgram.program);
19253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint64 programLinkEndTime = deGetMicroseconds();
19263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Check compilation and linking status here, after all compilation and linking gl calls are made.
19283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!(buildInfo.vertCompileSuccess && buildInfo.fragCompileSuccess && buildInfo.linkSuccess))
19293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
19303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buildInfo.logs = getLogs(shadersAndProgram);
19313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			logProgramData(buildInfo, progCtx);
19323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			cleanup(shadersAndProgram, progCtx, buildInfo.linkSuccess);
19333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compilation failed");
19343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return STOP;
19353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
19363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		setShaderInputs(shadersAndProgram.program, progCtx);
19383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint64 firstShaderInputSetEndTime = deGetMicroseconds();
19393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Draw for the first time.
19413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		draw();
19423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint64 firstDrawEndTime = deGetMicroseconds();
19433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Set inputs and draw again.
19453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		setShaderInputs(shadersAndProgram.program, progCtx);
19473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint64 secondShaderInputSetEndTime = deGetMicroseconds();
19483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		draw();
19503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint64 secondDrawEndTime = deGetMicroseconds();
19513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// De-initializations (detach shaders etc.).
19533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buildInfo.logs = getLogs(shadersAndProgram);
19553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		cleanup(shadersAndProgram, progCtx, buildInfo.linkSuccess);
19563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Output measurement log later (after last measurement).
19583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		measurements.push_back(Measurement((deInt64)(shaderSourceSetEndTime			- startTime),
19603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										   (deInt64)(vertexShaderCompileEndTime		- shaderSourceSetEndTime),
19613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										   (deInt64)(fragmentShaderCompileEndTime	- vertexShaderCompileEndTime),
19623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										   (deInt64)(programLinkEndTime				- fragmentShaderCompileEndTime),
19633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										   (deInt64)(firstShaderInputSetEndTime		- programLinkEndTime),
19643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										   (deInt64)(firstDrawEndTime				- firstShaderInputSetEndTime),
19653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										   (deInt64)(secondShaderInputSetEndTime	- firstDrawEndTime),
19663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										   (deInt64)(secondDrawEndTime				- secondShaderInputSetEndTime)));
19673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		latestBuildInfo			= buildInfo;
19693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		latestProgramContext	= progCtx;
19703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.touchWatchdog(); // \note Measurements may take a while in a bad case.
19723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
19733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// End of test case, log information about measurements.
19753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
19763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog& log = m_testCtx.getLog();
19773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deInt64> sourceSetTimes;
19793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deInt64> vertexCompileTimes;
19803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deInt64> fragmentCompileTimes;
19813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deInt64> programLinkTimes;
19823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deInt64> firstInputSetTimes;
19833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deInt64> firstDrawTimes;
19843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deInt64> secondInputTimes;
19853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deInt64> secondDrawTimes;
19863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deInt64> firstPhaseTimes;
19873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deInt64> secondPhaseTimes;
19883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deInt64> totalTimesWithoutDraw;
19893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deInt64> specializationTimes;
19903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!m_avoidCache)
19923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Note: Testing cache hits, so the medians and averages exclude the first iteration." << TestLog::EndMessage;
19933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Note: \"Specialization time\" means first draw time minus second draw time." << TestLog::EndMessage
19953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< TestLog::Message << "Note: \"Compilation time\" means the time up to (and including) linking, plus specialization time." << TestLog::EndMessage;
19963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Section("IterationMeasurements", "Iteration measurements of compilation and linking times");
19983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
19993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT((int)measurements.size() > (m_avoidCache ? 0 : 1));
20003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < (int)measurements.size(); ndx++)
20023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const Measurement& curMeas = measurements[ndx];
20043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Subtract time of second phase (second input setup and draw) from first (from start to end of first draw).
20063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// \note Cap if second phase seems unreasonably high (higher than first input set and draw).
20073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deInt64 timeWithoutDraw		= curMeas.totalTimeWithoutDraw();
20083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Specialization time = first draw - second draw time. Again, cap at 0 if second draw was longer than first draw.
20103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deInt64 specializationTime	= de::max<deInt64>(0, curMeas.firstDrawTime - curMeas.secondDrawTime);
20113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (ndx > 0 || m_avoidCache) // \note When allowing cache hits, don't account for the first measurement when calculating median or average.
20133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
20143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				sourceSetTimes.push_back		(curMeas.sourceSetTime);
20153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				vertexCompileTimes.push_back	(curMeas.vertexCompileTime);
20163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				fragmentCompileTimes.push_back	(curMeas.fragmentCompileTime);
20173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				programLinkTimes.push_back		(curMeas.programLinkTime);
20183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				firstInputSetTimes.push_back	(curMeas.firstInputSetTime);
20193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				firstDrawTimes.push_back		(curMeas.firstDrawTime);
20203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				firstPhaseTimes.push_back		(curMeas.firstPhase());
20213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				secondDrawTimes.push_back		(curMeas.secondDrawTime);
20223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				secondInputTimes.push_back		(curMeas.secondInputSetTime);
20233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				secondPhaseTimes.push_back		(curMeas.secondPhase());
20243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				totalTimesWithoutDraw.push_back	(timeWithoutDraw);
20253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				specializationTimes.push_back	(specializationTime);
20263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
20273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Log this measurement.
20293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Float("Measurement" + de::toString(ndx) + "CompilationTime",
20303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								  "Measurement " + de::toString(ndx) + " compilation time",
203134ecfcfbd748c67160b41ac08cfd57abf9df479aJarkko Pöyry								  "ms", QP_KEY_TAG_TIME, (float)timeWithoutDraw / 1000.0f)
20323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				<< TestLog::Float("Measurement" + de::toString(ndx) + "SpecializationTime",
20333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								  "Measurement " + de::toString(ndx) + " specialization time",
203434ecfcfbd748c67160b41ac08cfd57abf9df479aJarkko Pöyry								  "ms", QP_KEY_TAG_TIME, (float)specializationTime / 1000.0f);
20353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Log some statistics.
20383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int entireRangeOrLowestHalf = 0; entireRangeOrLowestHalf < 2; entireRangeOrLowestHalf++)
20403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool				isEntireRange				= entireRangeOrLowestHalf == 0;
20423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string				statNamePrefix				= isEntireRange ? "" : "LowestHalf";
20433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vector<deInt64>		rangeTotalTimes				= isEntireRange ? totalTimesWithoutDraw	: vectorLowestPercentage(totalTimesWithoutDraw,	0.5f);
20443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vector<deInt64>		rangeSpecializationTimes	= isEntireRange ? specializationTimes	: vectorLowestPercentage(specializationTimes,	0.5f);
20453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define LOG_COMPILE_SPECIALIZE_TIME_STAT(NAME, DESC, FUNC)																													\
20473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Float(statNamePrefix + "CompilationTime" + (NAME), (DESC) + string(" of compilation time"), "ms", QP_KEY_TAG_TIME, (FUNC)(rangeTotalTimes)/1000.0f)		\
20483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< TestLog::Float(statNamePrefix + "SpecializationTime" + (NAME), (DESC) + string(" of specialization time"), "ms", QP_KEY_TAG_TIME, (FUNC)(rangeSpecializationTimes)/1000.0f)
20493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define LOG_COMPILE_SPECIALIZE_RELATIVE_STAT(NAME, DESC, FUNC)																										\
20513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	log << TestLog::Float(statNamePrefix + "CompilationTime" + (NAME), (DESC) + string(" of compilation time"), "", QP_KEY_TAG_NONE, (FUNC)(rangeTotalTimes))		\
20523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		<< TestLog::Float(statNamePrefix + "SpecializationTime" + (NAME), (DESC) + string(" of specialization time"), "", QP_KEY_TAG_NONE, (FUNC)(rangeSpecializationTimes))
20533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "\nStatistics computed from "
20553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<< (isEntireRange ? "all" : "only the lowest 50%")
20563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<< " of the above measurements:"
20573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<< TestLog::EndMessage;
20583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_COMPILE_SPECIALIZE_TIME_STAT		("Median",							"Median",								vectorFloatMedian);
20603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_COMPILE_SPECIALIZE_TIME_STAT		("Average",							"Average",								vectorFloatAverage);
20613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_COMPILE_SPECIALIZE_TIME_STAT		("Minimum",							"Minimum",								vectorFloatMinimum);
20623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_COMPILE_SPECIALIZE_TIME_STAT		("Maximum",							"Maximum",								vectorFloatMaximum);
20633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_COMPILE_SPECIALIZE_TIME_STAT		("MedianAbsoluteDeviation",			"Median absolute deviation",			vectorFloatMedianAbsoluteDeviation);
20643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_COMPILE_SPECIALIZE_RELATIVE_STAT	("RelativeMedianAbsoluteDeviation",	"Relative median absolute deviation",	vectorFloatRelativeMedianAbsoluteDeviation);
20653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_COMPILE_SPECIALIZE_TIME_STAT		("StandardDeviation",				"Standard deviation",					vectorFloatStandardDeviation);
20663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_COMPILE_SPECIALIZE_RELATIVE_STAT	("RelativeStandardDeviation",		"Relative standard deviation",			vectorFloatRelativeStandardDeviation);
20673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_COMPILE_SPECIALIZE_TIME_STAT		("MaxMinusMin",						"Max-min",								vectorFloatMaximumMinusMinimum);
20683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_COMPILE_SPECIALIZE_RELATIVE_STAT	("RelativeMaxMinusMin",				"Relative max-min",						vectorFloatRelativeMaximumMinusMinimum);
20693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef LOG_COMPILE_SPECIALIZE_RELATIVE_STAT
20713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef LOG_COMPILE_SPECIALIZE_TIME_STAT
20723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isEntireRange && vectorFloatRelativeMedianAbsoluteDeviation(rangeTotalTimes) > RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD)
20743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "\nWARNING: couldn't achieve relative median absolute deviation under threshold value "
20753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										<< RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD
20763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										<< " for compilation time of the lowest 50% of measurements" << TestLog::EndMessage;
20773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
20783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::EndSection; // End section IterationMeasurements
20803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int medianOrAverage = 0; medianOrAverage < 2; medianOrAverage++)
20823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
20833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			typedef float (*VecFunc)(const vector<deInt64>&);
20843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool	isMedian						= medianOrAverage == 0;
20863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string	singular						= isMedian ? "Median" : "Average";
20873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string	plural							= singular + "s";
20883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			VecFunc	func							= isMedian ? (VecFunc) vectorFloatMedian<deInt64> : (VecFunc) vectorFloatAverage<deInt64>;
20893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Section(plural + "PerPhase", plural + " per phase");
20913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int entireRangeOrLowestHalf = 0; entireRangeOrLowestHalf < 2; entireRangeOrLowestHalf++)
20933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
20943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bool	isEntireRange	= entireRangeOrLowestHalf == 0;
20953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string	statNamePrefix	= isEntireRange ? "" : "LowestHalf";
20963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	rangeSizeRatio	= isEntireRange ? 1.0f : 0.5f;
20973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
20983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define LOG_TIME(NAME, DESC, DATA) log << TestLog::Float(statNamePrefix + (NAME) + singular, singular + " of " + (DESC), "ms", QP_KEY_TAG_TIME, func(vectorLowestPercentage((DATA), rangeSizeRatio))/1000.0f);
20993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << (isEntireRange ? "For all measurements:" : "\nFor only the lowest 50% of the measurements:") << TestLog::EndMessage;
21013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				LOG_TIME("ShaderSourceSetTime",			"shader source set time",			sourceSetTimes);
21023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				LOG_TIME("VertexShaderCompileTime",		"vertex shader compile time",		vertexCompileTimes);
21033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				LOG_TIME("FragmentShaderCompileTime",	"fragment shader compile time",		fragmentCompileTimes);
21043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				LOG_TIME("ProgramLinkTime",				"program link time",				programLinkTimes);
21053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				LOG_TIME("FirstShaderInputSetTime",		"first shader input set time",		firstInputSetTimes);
21063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				LOG_TIME("FirstDrawTime",				"first draw time",					firstDrawTimes);
21073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				LOG_TIME("SecondShaderInputSetTime",	"second shader input set time",		secondInputTimes);
21083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				LOG_TIME("SecondDrawTime",				"second draw time",					secondDrawTimes);
21093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef LOG_TIME
21113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
21123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::EndSection;
21143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Set result.
21173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Note: test result is the first quartile (i.e. median of the lowest half of measurements) of compilation times" << TestLog::EndMessage;
21203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float result = vectorFloatFirstQuartile(totalTimesWithoutDraw) / 1000.0f;
21213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(result, 2).c_str());
21223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Log shaders.
21253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_avoidCache || m_addWhitespaceAndComments)
21273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
21283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string msg = "Note: the following shaders are the ones from the last iteration; ";
21293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_avoidCache)
21313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				msg += "variables' names and some constant expressions";
21323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (m_addWhitespaceAndComments)
21333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				msg += string(m_avoidCache ? " as well as " : "") + "whitespace and comments";
21343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			msg += " differ between iterations.";
21363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << msg.c_str() << TestLog::EndMessage;
21383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
21393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		logProgramData(latestBuildInfo, latestProgramContext);
21413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
21433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
21443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerLightCase::ShaderCompilerLightCase (Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, bool isVertexCase, int numLights, LightType lightType)
21473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ShaderCompilerCase	(context, name, description, caseID, avoidCache, addWhitespaceAndComments)
21483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLights			(numLights)
21493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_isVertexCase		(isVertexCase)
21503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_lightType			(lightType)
21513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_texture				(DE_NULL)
21523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21553c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerLightCase::~ShaderCompilerLightCase (void)
21563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderCompilerLightCase::deinit();
21583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderCompilerLightCase::deinit (void)
21613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	delete m_texture;
21633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = DE_NULL;
21643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21663c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderCompilerLightCase::init (void)
21673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
21693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup texture.
21713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_texture == DE_NULL);
21733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture = new glu::Texture2D(m_context.getRenderContext(), GL_RGB, GL_UNSIGNED_BYTE, TEXTURE_WIDTH, TEXTURE_HEIGHT);
21753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
21773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture->getRefTexture().allocLevel(0);
21793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0), fmtInfo.valueMin, fmtInfo.valueMax);
21803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.activeTexture(GL_TEXTURE0);
21823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
21833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
21843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
21853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
21863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
21873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_texture->upload();
21883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderCompilerCase::init();
21903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
21913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21923c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerCase::ProgramContext ShaderCompilerLightCase::generateShaderData (int measurementNdx) const
21933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
21943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32		specID		= getSpecializationID(measurementNdx);
21953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string			nameSpec	= getNameSpecialization(specID);
21963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext	result;
21973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
21983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.vertShaderSource		= specializeShaderSource(lightVertexTemplate(m_numLights, m_isVertexCase, m_lightType), specID, SHADER_VALIDITY_VALID);
21993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.fragShaderSource		= specializeShaderSource(lightFragmentTemplate(m_numLights, m_isVertexCase, m_lightType), specID, SHADER_VALIDITY_VALID);
22003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.vertexAttributes		= lightShaderAttributes(nameSpec);
22013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.uniforms				= lightShaderUniforms(nameSpec, m_numLights, m_lightType);
22023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
22043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22063c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerTextureCase::ShaderCompilerTextureCase (Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, int numLookups, ConditionalUsage conditionalUsage, ConditionalType conditionalType)
22073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ShaderCompilerCase	(context, name, description, caseID, avoidCache, addWhitespaceAndComments)
22083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLookups			(numLookups)
22093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_conditionalUsage	(conditionalUsage)
22103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_conditionalType		(conditionalType)
22113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22143c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerTextureCase::~ShaderCompilerTextureCase (void)
22153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderCompilerTextureCase::deinit();
22173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22193c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderCompilerTextureCase::deinit (void)
22203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
22223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		delete *i;
22233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures.clear();
22243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderCompilerTextureCase::init (void)
22273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
22293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Setup texture.
22313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(m_textures.empty());
22333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_textures.reserve(m_numLookups);
22353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < m_numLookups; i++)
22373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
22383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glu::Texture2D*			tex		= new glu::Texture2D(m_context.getRenderContext(), GL_RGB, GL_UNSIGNED_BYTE, TEXTURE_WIDTH, TEXTURE_HEIGHT);
22393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::TextureFormatInfo	fmtInfo	= tcu::getTextureFormatInfo(tex->getRefTexture().getFormat());
22403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tex->getRefTexture().allocLevel(0);
22423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::fillWithComponentGradients(tex->getRefTexture().getLevel(0), fmtInfo.valueMin, fmtInfo.valueMax);
22433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.activeTexture(GL_TEXTURE0 + i);
22453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.bindTexture(GL_TEXTURE_2D, tex->getGLTexture());
22463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
22473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
22483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
22493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
22503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tex->upload();
22513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_textures.push_back(tex);
22533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
22543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderCompilerCase::init();
22563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerCase::ProgramContext ShaderCompilerTextureCase::generateShaderData (int measurementNdx) const
22593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32		specID		= getSpecializationID(measurementNdx);
22613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string			nameSpec	= getNameSpecialization(specID);
22623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext	result;
22633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.vertShaderSource		= specializeShaderSource(textureLookupVertexTemplate(m_conditionalUsage, m_conditionalType), specID, SHADER_VALIDITY_VALID);
22653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.fragShaderSource		= specializeShaderSource(textureLookupFragmentTemplate(m_numLookups, m_conditionalUsage, m_conditionalType), specID, SHADER_VALIDITY_VALID);
22663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.vertexAttributes		= textureLookupShaderAttributes(nameSpec, m_conditionalUsage, m_conditionalType);
22673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.uniforms				= textureLookupShaderUniforms(nameSpec, m_numLookups, m_conditionalUsage, m_conditionalType);
22683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
22703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22723c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerLoopCase::ShaderCompilerLoopCase (Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, bool isVertexCase, LoopType type, int numLoopIterations, int nestingDepth)
22733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ShaderCompilerCase	(context, name, description, caseID, avoidCache, addWhitespaceAndComments)
22743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLoopIterations	(numLoopIterations)
22753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_nestingDepth		(nestingDepth)
22763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_isVertexCase		(isVertexCase)
22773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_type				(type)
22783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22813c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerLoopCase::~ShaderCompilerLoopCase (void)
22823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22853c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerCase::ProgramContext ShaderCompilerLoopCase::generateShaderData (int measurementNdx) const
22863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
22873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32		specID		= getSpecializationID(measurementNdx);
22883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string			nameSpec	= getNameSpecialization(specID);
22893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext	result;
22903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.vertShaderSource		= specializeShaderSource(loopVertexTemplate(m_type, m_isVertexCase, m_numLoopIterations, m_nestingDepth), specID, SHADER_VALIDITY_VALID);
22923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.fragShaderSource		= specializeShaderSource(loopFragmentTemplate(m_type, m_isVertexCase, m_numLoopIterations, m_nestingDepth), specID, SHADER_VALIDITY_VALID);
22933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.vertexAttributes		= loopShaderAttributes(nameSpec, m_type, m_numLoopIterations);
22953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.uniforms				= loopShaderUniforms(nameSpec, m_type, m_numLoopIterations);
22963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
22973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
22983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
22993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23003c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerOperCase::ShaderCompilerOperCase (Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, bool isVertexCase, const char* oper, int numOperations)
23013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ShaderCompilerCase	(context, name, description, caseID, avoidCache, addWhitespaceAndComments)
23023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_oper				(oper)
23033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numOperations		(numOperations)
23043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_isVertexCase		(isVertexCase)
23053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23083c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerOperCase::~ShaderCompilerOperCase (void)
23093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23123c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerCase::ProgramContext ShaderCompilerOperCase::generateShaderData (int measurementNdx) const
23133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32		specID		= getSpecializationID(measurementNdx);
23153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string			nameSpec	= getNameSpecialization(specID);
23163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext	result;
23173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_isVertexCase)
23193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.vertShaderSource = specializeShaderSource(binaryOpVertexTemplate(m_numOperations, m_oper.c_str()), specID, SHADER_VALIDITY_VALID);
23213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.fragShaderSource = specializeShaderSource(singleVaryingFragmentTemplate(), specID, SHADER_VALIDITY_VALID);
23223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
23243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
23253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.vertShaderSource = specializeShaderSource(singleVaryingVertexTemplate(), specID, SHADER_VALIDITY_VALID);
23263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.fragShaderSource = specializeShaderSource(binaryOpFragmentTemplate(m_numOperations, m_oper.c_str()), specID, SHADER_VALIDITY_VALID);
23273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
23283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.vertexAttributes = singleValueShaderAttributes(nameSpec);
23303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.uniforms.clear(); // No uniforms used.
23323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
23343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerMandelbrotCase::ShaderCompilerMandelbrotCase (Context& context, const char* name, const char* description, int caseID, bool avoidCache, bool addWhitespaceAndComments, int numFractalIterations)
23373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: ShaderCompilerCase		(context, name, description, caseID, avoidCache, addWhitespaceAndComments)
23383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numFractalIterations	(numFractalIterations)
23393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23423c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerMandelbrotCase::~ShaderCompilerMandelbrotCase (void)
23433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23463c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderCompilerCase::ProgramContext ShaderCompilerMandelbrotCase::generateShaderData (int measurementNdx) const
23473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32		specID		= getSpecializationID(measurementNdx);
23493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string			nameSpec	= getNameSpecialization(specID);
23503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext	result;
23513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.vertShaderSource = specializeShaderSource(mandelbrotVertexTemplate(), specID, SHADER_VALIDITY_VALID);
23533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.fragShaderSource = specializeShaderSource(mandelbrotFragmentTemplate(m_numFractalIterations), specID, SHADER_VALIDITY_VALID);
23543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.vertexAttributes = mandelbrotShaderAttributes(nameSpec);
23563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.uniforms = mandelbrotShaderUniforms(nameSpec);
23573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
23593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23613c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerCase::InvalidShaderCompilerCase (Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType)
23623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCase						(context, tcu::NODETYPE_PERFORMANCE, name, description)
23633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_invalidityType				(invalidityType)
23643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_startHash					((deUint32)(deUint64Hash(deGetTime()) ^ deUint64Hash(deGetMicroseconds()) ^ deInt32Hash(caseID)))
23653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int cmdLineIterCount = context.getTestContext().getCommandLine().getTestIterationCount();
23673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_minimumMeasurementCount = cmdLineIterCount > 0 ? cmdLineIterCount : DEFAULT_MINIMUM_MEASUREMENT_COUNT;
23683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_maximumMeasurementCount = 3*m_minimumMeasurementCount;
23693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23713c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerCase::~InvalidShaderCompilerCase (void)
23723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23753c827367444ee418f129b2c238299f49d3264554Jarkko PoyrydeUint32 InvalidShaderCompilerCase::getSpecializationID (int measurementNdx) const
23763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_startHash ^ (deUint32)deInt32Hash((deInt32)measurementNdx);
23783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23803c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerCase::Shaders InvalidShaderCompilerCase::createShaders (void) const
23813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl = m_context.getRenderContext().getFunctions();
23833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Shaders					result;
23843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.vertShader = gl.createShader(GL_VERTEX_SHADER);
23863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.fragShader = gl.createShader(GL_FRAGMENT_SHADER);
23873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
23893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
23913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InvalidShaderCompilerCase::setShaderSources (const Shaders& shaders, const ProgramContext& progCtx) const
23923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
23933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
23943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* vertShaderSourceCStr = progCtx.vertShaderSource.c_str();
23953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const char* fragShaderSourceCStr = progCtx.fragShaderSource.c_str();
23963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.shaderSource(shaders.vertShader, 1, &vertShaderSourceCStr, DE_NULL);
23973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.shaderSource(shaders.fragShader, 1, &fragShaderSourceCStr, DE_NULL);
23983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
23993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24003c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool InvalidShaderCompilerCase::compileShader (deUint32 shader) const
24013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
24033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLint status;
24043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.compileShader(shader);
24053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.getShaderiv(shader, GL_COMPILE_STATUS, &status);
24063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return status != 0;
24073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24093c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InvalidShaderCompilerCase::logProgramData (const BuildInfo& buildInfo, const ProgramContext& progCtx) const
24103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_testCtx.getLog() << TestLog::ShaderProgram(false, "(No linking done)")
24123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   << TestLog::Shader(QP_SHADER_TYPE_VERTEX,	progCtx.vertShaderSource, buildInfo.vertCompileSuccess, buildInfo.logs.vert)
24133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   << TestLog::Shader(QP_SHADER_TYPE_FRAGMENT,	progCtx.fragShaderSource, buildInfo.fragCompileSuccess, buildInfo.logs.frag)
24143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					   << TestLog::EndShaderProgram;
24153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24173c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerCase::Logs InvalidShaderCompilerCase::getLogs (const Shaders& shaders) const
24183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions&	gl = m_context.getRenderContext().getFunctions();
24203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Logs					result;
24213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.vert = getShaderInfoLog(gl, shaders.vertShader);
24233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.frag = getShaderInfoLog(gl, shaders.fragShader);
24243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
24263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24283c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid InvalidShaderCompilerCase::cleanup (const Shaders& shaders) const
24293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
24313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.deleteShader(shaders.vertShader);
24333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	gl.deleteShader(shaders.fragShader);
24343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24363c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool InvalidShaderCompilerCase::goodEnoughMeasurements (const vector<Measurement>& measurements) const
24373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((int)measurements.size() < m_minimumMeasurementCount)
24393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return false;
24403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
24413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((int)measurements.size() >= m_maximumMeasurementCount)
24433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return true;
24443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
24453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vector<deInt64> totalTimes;
24473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < (int)measurements.size(); i++)
24483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				totalTimes.push_back(measurements[i].totalTime());
24493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return vectorFloatRelativeMedianAbsoluteDeviation(vectorLowestPercentage(totalTimes, 0.5f)) < RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD;
24503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
24533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24543c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerCase::IterateResult InvalidShaderCompilerCase::iterate (void)
24553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
24563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderValidity shaderValidity = m_invalidityType == INVALIDITY_INVALID_CHAR		? SHADER_VALIDITY_INVALID_CHAR
24573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								  : m_invalidityType == INVALIDITY_SEMANTIC_ERROR	? SHADER_VALIDITY_SEMANTIC_ERROR
24583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								  : SHADER_VALIDITY_LAST;
24593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(shaderValidity != SHADER_VALIDITY_LAST);
24613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Before actual measurements, compile a dummy shader to avoid possible initial slowdowns in the actual test.
24633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32		specID = getSpecializationID(0);
24653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ProgramContext	progCtx;
24663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		progCtx.vertShaderSource = specializeShaderSource(singleVaryingVertexTemplate(), specID, shaderValidity);
24673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		progCtx.fragShaderSource = specializeShaderSource(singleVaryingFragmentTemplate(), specID, shaderValidity);
24683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Shaders shaders = createShaders();
24703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		setShaderSources(shaders, progCtx);
24713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BuildInfo buildInfo;
24733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buildInfo.vertCompileSuccess = compileShader(shaders.vertShader);
24743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buildInfo.fragCompileSuccess = compileShader(shaders.fragShader);
24753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (buildInfo.vertCompileSuccess || buildInfo.fragCompileSuccess)
24763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
24773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			buildInfo.logs = getLogs(shaders);
24783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			logProgramData(buildInfo, progCtx);
24793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			cleanup(shaders);
24803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compilation of a shader erroneously succeeded");
24813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return STOP;
24823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
24833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		cleanup(shaders);
24843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
24853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<Measurement>		measurements;
24873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// \note These are logged after measurements are done.
24883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext			latestProgramContext;
24893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	BuildInfo				latestBuildInfo;
24903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (WARMUP_CPU_AT_BEGINNING_OF_CASE)
24923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::warmupCPU();
24933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Actual test measurements.
24953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	while (!goodEnoughMeasurements(measurements))
24963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
24973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Create shader and compile. Measure time.
24983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
24993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note Shader sources are generated and GL shader objects are created before any time measurements.
25003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ProgramContext	progCtx		= generateShaderSources((int)measurements.size());
25013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		Shaders			shaders		= createShaders();
25023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		BuildInfo		buildInfo;
25033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (WARMUP_CPU_BEFORE_EACH_MEASUREMENT)
25053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			tcu::warmupCPU();
25063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note Do NOT do anything too hefty between the first and last deGetMicroseconds() here (other than the gl calls); it would disturb the measurement.
25083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint64 startTime = deGetMicroseconds();
25103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		setShaderSources(shaders, progCtx);
25123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint64 shaderSourceSetEndTime = deGetMicroseconds();
25133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buildInfo.vertCompileSuccess = compileShader(shaders.vertShader);
25153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint64 vertexShaderCompileEndTime = deGetMicroseconds();
25163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buildInfo.fragCompileSuccess = compileShader(shaders.fragShader);
25183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint64 fragmentShaderCompileEndTime = deGetMicroseconds();
25193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		buildInfo.logs = getLogs(shaders);
25213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Both shader compilations should have failed.
25233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (buildInfo.vertCompileSuccess || buildInfo.fragCompileSuccess)
25243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			logProgramData(buildInfo, progCtx);
25263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			cleanup(shaders);
25273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Compilation of a shader erroneously succeeded");
25283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return STOP;
25293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// De-initializations (delete shaders).
25323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		cleanup(shaders);
25343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Output measurement log later (after last measurement).
25363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		measurements.push_back(Measurement((deInt64)(shaderSourceSetEndTime			- startTime),
25383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										   (deInt64)(vertexShaderCompileEndTime		- shaderSourceSetEndTime),
25393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										   (deInt64)(fragmentShaderCompileEndTime	- vertexShaderCompileEndTime)));
25403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		latestBuildInfo			= buildInfo;
25423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		latestProgramContext	= progCtx;
25433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.touchWatchdog(); // \note Measurements may take a while in a bad case.
25453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
25463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// End of test case, log information about measurements.
25483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
25493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestLog& log = m_testCtx.getLog();
25503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deInt64> sourceSetTimes;
25523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deInt64> vertexCompileTimes;
25533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deInt64> fragmentCompileTimes;
25543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		vector<deInt64> totalTimes;
25553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Section("IterationMeasurements", "Iteration measurements of compilation times");
25573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int ndx = 0; ndx < (int)measurements.size(); ndx++)
25593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			sourceSetTimes.push_back		(measurements[ndx].sourceSetTime);
25613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vertexCompileTimes.push_back	(measurements[ndx].vertexCompileTime);
25623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			fragmentCompileTimes.push_back	(measurements[ndx].fragmentCompileTime);
25633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			totalTimes.push_back			(measurements[ndx].totalTime());
25643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Log this measurement.
25663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Float("Measurement" + de::toString(ndx) + "Time",
25673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								  "Measurement " + de::toString(ndx) + " time",
256834ecfcfbd748c67160b41ac08cfd57abf9df479aJarkko Pöyry								  "ms", QP_KEY_TAG_TIME, (float)measurements[ndx].totalTime()/1000.0f);
25693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
25703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Log some statistics.
25723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int entireRangeOrLowestHalf = 0; entireRangeOrLowestHalf < 2; entireRangeOrLowestHalf++)
25743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
25753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool				isEntireRange	= entireRangeOrLowestHalf == 0;
25763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string				statNamePrefix	= isEntireRange ? "" : "LowestHalf";
25773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			vector<deInt64>		rangeTimes		= isEntireRange ? totalTimes : vectorLowestPercentage(totalTimes, 0.5f);
25783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "\nStatistics computed from "
25803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<< (isEntireRange ? "all" : "only the lowest 50%")
25813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<< " of the above measurements:"
25823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									<< TestLog::EndMessage;
25833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define LOG_TIME_STAT(NAME, DESC, FUNC)			log << TestLog::Float(statNamePrefix + "TotalTime" + (NAME), (DESC) + string(" of total time"), "ms",	QP_KEY_TAG_TIME, (FUNC)(rangeTimes)/1000.0f)
25853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define LOG_RELATIVE_STAT(NAME, DESC, FUNC)		log << TestLog::Float(statNamePrefix + "TotalTime" + (NAME), (DESC) + string(" of total time"), "",		QP_KEY_TAG_NONE, (FUNC)(rangeTimes))
25863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_TIME_STAT		("Median",							"Median",								vectorFloatMedian);
25883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_TIME_STAT		("Average",							"Average",								vectorFloatAverage);
25893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_TIME_STAT		("Minimum",							"Minimum",								vectorFloatMinimum);
25903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_TIME_STAT		("Maximum",							"Maximum",								vectorFloatMaximum);
25913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_TIME_STAT		("MedianAbsoluteDeviation",			"Median absolute deviation",			vectorFloatMedianAbsoluteDeviation);
25923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_RELATIVE_STAT	("RelativeMedianAbsoluteDeviation",	"Relative median absolute deviation",	vectorFloatRelativeMedianAbsoluteDeviation);
25933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_TIME_STAT		("StandardDeviation",				"Standard deviation",					vectorFloatStandardDeviation);
25943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_RELATIVE_STAT	("RelativeStandardDeviation",		"Relative standard deviation",			vectorFloatRelativeStandardDeviation);
25953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_TIME_STAT		("MaxMinusMin",						"Max-min",								vectorFloatMaximumMinusMinimum);
25963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			LOG_RELATIVE_STAT	("RelativeMaxMinusMin",				"Relative max-min",						vectorFloatRelativeMaximumMinusMinimum);
25973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
25983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef LOG_TIME_STAT
25993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef LOG_RELATIVE_STAT
26003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			if (!isEntireRange && vectorFloatRelativeMedianAbsoluteDeviation(rangeTimes) > RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD)
26023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << "\nWARNING: couldn't achieve relative median absolute deviation under threshold value " << RELATIVE_MEDIAN_ABSOLUTE_DEVIATION_THRESHOLD << TestLog::EndMessage;
26033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::EndSection; // End section IterationMeasurements
26063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int medianOrAverage = 0; medianOrAverage < 2; medianOrAverage++)
26083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			typedef float (*VecFunc)(const vector<deInt64>&);
26103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool	isMedian						= medianOrAverage == 0;
26123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string	singular						= isMedian ? "Median" : "Average";
26133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string	plural							= singular + "s";
26143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			VecFunc func							= isMedian ? (VecFunc) vectorFloatMedian<deInt64> : (VecFunc) vectorFloatAverage<deInt64>;
26153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Section(plural + "PerPhase", plural + " per phase");
26173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int entireRangeOrLowestHalf = 0; entireRangeOrLowestHalf < 2; entireRangeOrLowestHalf++)
26193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
26203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bool	isEntireRange	= entireRangeOrLowestHalf == 0;
26213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string	statNamePrefix	= isEntireRange ? "" : "LowestHalf";
26223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				float	rangeSizeRatio	= isEntireRange ? 1.0f : 0.5f;
26233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define LOG_TIME(NAME, DESC, DATA) log << TestLog::Float(statNamePrefix + (NAME) + singular, singular + " of " + (DESC), "ms", QP_KEY_TAG_TIME, func(vectorLowestPercentage((DATA), rangeSizeRatio))/1000.0f);
26253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				log << TestLog::Message << (isEntireRange ? "For all measurements:" : "\nFor only the lowest 50% of the measurements:") << TestLog::EndMessage;
26273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				LOG_TIME("ShaderSourceSetTime",			"shader source set time",			sourceSetTimes);
26283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				LOG_TIME("VertexShaderCompileTime",		"vertex shader compile time",		vertexCompileTimes);
26293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				LOG_TIME("FragmentShaderCompileTime",	"fragment shader compile time",		fragmentCompileTimes);
26303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#undef LOG_TIME
26323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
26333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::EndSection;
26353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Set result.
26383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
26403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Note: test result is the first quartile (i.e. median of the lowest half of measurements) of total times" << TestLog::EndMessage;
26413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			float result = vectorFloatFirstQuartile(totalTimes) / 1000.0f;
26423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(result, 2).c_str());
26433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
26443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Log shaders.
26463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Note: the following shaders are the ones from the last iteration; variables' names and some constant expressions differ between iterations." << TestLog::EndMessage;
26483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		logProgramData(latestBuildInfo, latestProgramContext);
26503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
26523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
26533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26553c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerLightCase::InvalidShaderCompilerLightCase (Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, bool isVertexCase, int numLights, LightType lightType)
26563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: InvalidShaderCompilerCase	(context, name, description, caseID, invalidityType)
26573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_isVertexCase			(isVertexCase)
26583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLights				(numLights)
26593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_lightType				(lightType)
26603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26633c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerLightCase::~InvalidShaderCompilerLightCase (void)
26643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26673c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerCase::ProgramContext InvalidShaderCompilerLightCase::generateShaderSources (int measurementNdx) const
26683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32		specID			= getSpecializationID(measurementNdx);
26703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext	result;
26713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderValidity	shaderValidity	= m_invalidityType == INVALIDITY_INVALID_CHAR	? SHADER_VALIDITY_INVALID_CHAR
26723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									: m_invalidityType == INVALIDITY_SEMANTIC_ERROR	? SHADER_VALIDITY_SEMANTIC_ERROR
26733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									: SHADER_VALIDITY_LAST;
26743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(shaderValidity != SHADER_VALIDITY_LAST);
26763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.vertShaderSource = specializeShaderSource(lightVertexTemplate(m_numLights, m_isVertexCase, m_lightType), specID, shaderValidity);
26783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.fragShaderSource = specializeShaderSource(lightFragmentTemplate(m_numLights, m_isVertexCase, m_lightType), specID, shaderValidity);
26793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
26813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26833c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerTextureCase::InvalidShaderCompilerTextureCase (Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, int numLookups, ConditionalUsage conditionalUsage, ConditionalType conditionalType)
26843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: InvalidShaderCompilerCase	(context, name, description, caseID, invalidityType)
26853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLookups				(numLookups)
26863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_conditionalUsage		(conditionalUsage)
26873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_conditionalType			(conditionalType)
26883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26913c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerTextureCase::~InvalidShaderCompilerTextureCase (void)
26923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
26943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
26953c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerCase::ProgramContext InvalidShaderCompilerTextureCase::generateShaderSources (int measurementNdx) const
26963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
26973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32		specID			= getSpecializationID(measurementNdx);
26983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext	result;
26993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderValidity	shaderValidity	= m_invalidityType == INVALIDITY_INVALID_CHAR	? SHADER_VALIDITY_INVALID_CHAR
27003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									: m_invalidityType == INVALIDITY_SEMANTIC_ERROR	? SHADER_VALIDITY_SEMANTIC_ERROR
27013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									: SHADER_VALIDITY_LAST;
27023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(shaderValidity != SHADER_VALIDITY_LAST);
27043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.vertShaderSource = specializeShaderSource(textureLookupVertexTemplate(m_conditionalUsage, m_conditionalType), specID, shaderValidity);
27063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.fragShaderSource = specializeShaderSource(textureLookupFragmentTemplate(m_numLookups, m_conditionalUsage, m_conditionalType), specID, shaderValidity);
27073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
27093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27113c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerLoopCase::InvalidShaderCompilerLoopCase (Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, bool isVertexCase, LoopType type, int numLoopIterations, int nestingDepth)
27123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: InvalidShaderCompilerCase	(context, name, description, caseID, invalidityType)
27133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_isVertexCase			(isVertexCase)
27143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numLoopIterations		(numLoopIterations)
27153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_nestingDepth			(nestingDepth)
27163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_type					(type)
27173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27203c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerLoopCase::~InvalidShaderCompilerLoopCase (void)
27213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27243c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerCase::ProgramContext InvalidShaderCompilerLoopCase::generateShaderSources (int measurementNdx) const
27253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32		specID			= getSpecializationID(measurementNdx);
27273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext	result;
27283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderValidity	shaderValidity	= m_invalidityType == INVALIDITY_INVALID_CHAR	? SHADER_VALIDITY_INVALID_CHAR
27293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									: m_invalidityType == INVALIDITY_SEMANTIC_ERROR	? SHADER_VALIDITY_SEMANTIC_ERROR
27303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									: SHADER_VALIDITY_LAST;
27313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(shaderValidity != SHADER_VALIDITY_LAST);
27333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.vertShaderSource = specializeShaderSource(loopVertexTemplate(m_type, m_isVertexCase, m_numLoopIterations, m_nestingDepth), specID, shaderValidity);
27353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.fragShaderSource = specializeShaderSource(loopFragmentTemplate(m_type, m_isVertexCase, m_numLoopIterations, m_nestingDepth), specID, shaderValidity);
27363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
27383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27403c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerOperCase::InvalidShaderCompilerOperCase (Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, bool isVertexCase, const char* oper, int numOperations)
27413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: InvalidShaderCompilerCase	(context, name, description, caseID, invalidityType)
27423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_isVertexCase			(isVertexCase)
27433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_oper					(oper)
27443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numOperations			(numOperations)
27453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerOperCase::~InvalidShaderCompilerOperCase (void)
27493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27523c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerCase::ProgramContext InvalidShaderCompilerOperCase::generateShaderSources (int measurementNdx) const
27533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32		specID			= getSpecializationID(measurementNdx);
27553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext	result;
27563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderValidity	shaderValidity	= m_invalidityType == INVALIDITY_INVALID_CHAR	? SHADER_VALIDITY_INVALID_CHAR
27573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									: m_invalidityType == INVALIDITY_SEMANTIC_ERROR	? SHADER_VALIDITY_SEMANTIC_ERROR
27583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									: SHADER_VALIDITY_LAST;
27593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(shaderValidity != SHADER_VALIDITY_LAST);
27613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_isVertexCase)
27633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.vertShaderSource = specializeShaderSource(binaryOpVertexTemplate(m_numOperations, m_oper.c_str()), specID, shaderValidity);
27653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.fragShaderSource = specializeShaderSource(singleVaryingFragmentTemplate(), specID, shaderValidity);
27663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
27683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
27693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.vertShaderSource = specializeShaderSource(singleVaryingVertexTemplate(), specID, shaderValidity);
27703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result.fragShaderSource = specializeShaderSource(binaryOpFragmentTemplate(m_numOperations, m_oper.c_str()), specID, shaderValidity);
27713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
27723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
27743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27763c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerMandelbrotCase::InvalidShaderCompilerMandelbrotCase (Context& context, const char* name, const char* description, int caseID, InvalidityType invalidityType, int numFractalIterations)
27773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: InvalidShaderCompilerCase	(context, name, description, caseID, invalidityType)
27783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_numFractalIterations	(numFractalIterations)
27793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27823c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerMandelbrotCase::~InvalidShaderCompilerMandelbrotCase (void)
27833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
27853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27863c827367444ee418f129b2c238299f49d3264554Jarkko PoyryInvalidShaderCompilerCase::ProgramContext InvalidShaderCompilerMandelbrotCase::generateShaderSources (int measurementNdx) const
27873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
27883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint32		specID			= getSpecializationID(measurementNdx);
27893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramContext	result;
27903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderValidity	shaderValidity	= m_invalidityType == INVALIDITY_INVALID_CHAR	? SHADER_VALIDITY_INVALID_CHAR
27913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									: m_invalidityType == INVALIDITY_SEMANTIC_ERROR	? SHADER_VALIDITY_SEMANTIC_ERROR
27923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									: SHADER_VALIDITY_LAST;
27933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_ASSERT(shaderValidity != SHADER_VALIDITY_LAST);
27953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.vertShaderSource = specializeShaderSource(mandelbrotVertexTemplate(), specID, shaderValidity);
27973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	result.fragShaderSource = specializeShaderSource(mandelbrotFragmentTemplate(m_numFractalIterations), specID, shaderValidity);
27983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
27993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
28003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
28013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28023c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid addShaderCompilationPerformanceCases (TestCaseGroup& parentGroup)
28033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
28043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Context&	context		= parentGroup.getContext();
28053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			caseID		= 0; // Increment this after adding each case. Used for avoiding cache hits between cases.
28063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* validGroup			= new TestCaseGroup(context, "valid_shader",	"Valid Shader Compiler Cases");
28083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* invalidGroup			= new TestCaseGroup(context, "invalid_shader",	"Invalid Shader Compiler Cases");
28093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* cacheGroup			= new TestCaseGroup(context, "cache",			"Allow shader caching");
28103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	parentGroup.addChild(validGroup);
28113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	parentGroup.addChild(invalidGroup);
28123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	parentGroup.addChild(cacheGroup);
28133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* invalidCharGroup		= new TestCaseGroup(context, "invalid_char",	"Invalid Character Shader Compiler Cases");
28153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* semanticErrorGroup	= new TestCaseGroup(context, "semantic_error",	"Semantic Error Shader Compiler Cases");
28163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	invalidGroup->addChild(invalidCharGroup);
28173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	invalidGroup->addChild(semanticErrorGroup);
28183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Lighting shader compilation cases.
28203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
28223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const int lightCounts[] = { 1, 2, 4, 8 };
28233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* validLightingGroup			= new TestCaseGroup(context, "lighting", "Shader Compiler Lighting Cases");
28253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* invalidCharLightingGroup		= new TestCaseGroup(context, "lighting", "Invalid Character Shader Compiler Lighting Cases");
28263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* semanticErrorLightingGroup	= new TestCaseGroup(context, "lighting", "Semantic Error Shader Compiler Lighting Cases");
28273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* cacheLightingGroup			= new TestCaseGroup(context, "lighting", "Shader Compiler Lighting Cache Cases");
28283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		validGroup->addChild(validLightingGroup);
28293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		invalidCharGroup->addChild(invalidCharLightingGroup);
28303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		semanticErrorGroup->addChild(semanticErrorLightingGroup);
28313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		cacheGroup->addChild(cacheLightingGroup);
28323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int lightType = 0; lightType < (int)LIGHT_LAST; lightType++)
28343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
28353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char* lightTypeName = lightType == (int)LIGHT_DIRECTIONAL	? "directional"
28363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  : lightType == (int)LIGHT_POINT		? "point"
28373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  : DE_NULL;
28383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(lightTypeName != DE_NULL);
28403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int isFrag = 0; isFrag <= 1; isFrag++)
28423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
28433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bool		isVertex	= isFrag == 0;
28443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*	vertFragStr	= isVertex ? "vertex" : "fragment";
28453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int lightCountNdx = 0; lightCountNdx < DE_LENGTH_OF_ARRAY(lightCounts); lightCountNdx++)
28473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
28483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					int numLights = lightCounts[lightCountNdx];
28493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					string caseName = string("") + lightTypeName + "_" + de::toString(numLights) + "_lights_" + vertFragStr;
28513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					// Valid shader case, no-cache and cache versions.
28533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					validLightingGroup->addChild(new ShaderCompilerLightCase(context, caseName.c_str(), "", caseID++, true  /* avoid cache */, false, isVertex, numLights, (LightType)lightType));
28553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					cacheLightingGroup->addChild(new ShaderCompilerLightCase(context, caseName.c_str(), "", caseID++, false /* allow cache */, false, isVertex, numLights, (LightType)lightType));
28563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					// Invalid shader cases.
28583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int invalidityType = 0; invalidityType < (int)InvalidShaderCompilerCase::INVALIDITY_LAST; invalidityType++)
28603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
28613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						TestCaseGroup* curInvalidGroup	= invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_INVALID_CHAR		? invalidCharLightingGroup
28623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														: invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_SEMANTIC_ERROR	? semanticErrorLightingGroup
28633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														: DE_NULL;
28643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(curInvalidGroup != DE_NULL);
28663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						curInvalidGroup->addChild(new InvalidShaderCompilerLightCase(context, caseName.c_str(), "", caseID++, (InvalidShaderCompilerCase::InvalidityType)invalidityType, isVertex, numLights, (LightType)lightType));
28683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
28693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
28703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
28713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
28723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
28733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Texture lookup shader compilation cases.
28753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
28773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const int texLookupCounts[] = { 1, 2, 4, 8 };
28783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* validTexGroup			= new TestCaseGroup(context, "texture", "Shader Compiler Texture Lookup Cases");
28803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* invalidCharTexGroup		= new TestCaseGroup(context, "texture", "Invalid Character Shader Compiler Texture Lookup Cases");
28813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* semanticErrorTexGroup	= new TestCaseGroup(context, "texture", "Semantic Error Shader Compiler Texture Lookup Cases");
28823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* cacheTexGroup			= new TestCaseGroup(context, "texture", "Shader Compiler Texture Lookup Cache Cases");
28833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		validGroup->addChild(validTexGroup);
28843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		invalidCharGroup->addChild(invalidCharTexGroup);
28853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		semanticErrorGroup->addChild(semanticErrorTexGroup);
28863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		cacheGroup->addChild(cacheTexGroup);
28873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int conditionalUsage = 0; conditionalUsage < (int)CONDITIONAL_USAGE_LAST; conditionalUsage++)
28893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
28903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char* conditionalUsageName = conditionalUsage == (int)CONDITIONAL_USAGE_NONE			? "no_conditionals"
28913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 : conditionalUsage == (int)CONDITIONAL_USAGE_FIRST_HALF	? "first_half"
28923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 : conditionalUsage == (int)CONDITIONAL_USAGE_EVERY_OTHER	? "every_other"
28933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 : DE_NULL;
28943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(conditionalUsageName != DE_NULL);
28963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int lastConditionalType = conditionalUsage == (int)CONDITIONAL_USAGE_NONE ? 1 : (int)CONDITIONAL_TYPE_LAST;
28983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
28993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int conditionalType = 0; conditionalType < lastConditionalType; conditionalType++)
29003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char* conditionalTypeName = conditionalType == (int)CONDITIONAL_TYPE_STATIC	? "static_conditionals"
29023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												: conditionalType == (int)CONDITIONAL_TYPE_UNIFORM	? "uniform_conditionals"
29033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												: conditionalType == (int)CONDITIONAL_TYPE_DYNAMIC	? "dynamic_conditionals"
29043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												: DE_NULL;
29053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(conditionalTypeName != DE_NULL);
29073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int lookupCountNdx = 0; lookupCountNdx < DE_LENGTH_OF_ARRAY(texLookupCounts); lookupCountNdx++)
29093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
29103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					int numLookups = texLookupCounts[lookupCountNdx];
29113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					string caseName = de::toString(numLookups) + "_lookups_" + conditionalUsageName + (conditionalUsage == (int)CONDITIONAL_USAGE_NONE ? "" : string("_") + conditionalTypeName);
29133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					// Valid shader case, no-cache and cache versions.
29153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					validTexGroup->addChild(new ShaderCompilerTextureCase(context, caseName.c_str(), "", caseID++, true  /* avoid cache */, false, numLookups, (ConditionalUsage)conditionalUsage, (ConditionalType)conditionalType));
29173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					cacheTexGroup->addChild(new ShaderCompilerTextureCase(context, caseName.c_str(), "", caseID++, false /* allow cache */, false, numLookups, (ConditionalUsage)conditionalUsage, (ConditionalType)conditionalType));
29183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					// Invalid shader cases.
29203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int invalidityType = 0; invalidityType < (int)InvalidShaderCompilerCase::INVALIDITY_LAST; invalidityType++)
29223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
29233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						TestCaseGroup* curInvalidGroup	= invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_INVALID_CHAR		? invalidCharTexGroup
29243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														: invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_SEMANTIC_ERROR	? semanticErrorTexGroup
29253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														: DE_NULL;
29263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						DE_ASSERT(curInvalidGroup != DE_NULL);
29283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						curInvalidGroup->addChild(new InvalidShaderCompilerTextureCase(context, caseName.c_str(), "", caseID++, (InvalidShaderCompilerCase::InvalidityType)invalidityType, numLookups, (ConditionalUsage)conditionalUsage, (ConditionalType)conditionalType));
29303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
29313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
29323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
29333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
29343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
29353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Loop shader compilation cases.
29373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
29393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const int loopIterCounts[]		= { 10, 100, 1000 };
29403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const int maxLoopNestingDepth	= 3;
29413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const int maxTotalLoopIterations	= 2000; // If <loop iteration count> ** <loop nesting depth> (where ** is exponentiation) exceeds this, don't generate the case.
29423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* validLoopGroup			= new TestCaseGroup(context, "loop", "Shader Compiler Loop Cases");
29443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* invalidCharLoopGroup		= new TestCaseGroup(context, "loop", "Invalid Character Shader Compiler Loop Cases");
29453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* semanticErrorLoopGroup	= new TestCaseGroup(context, "loop", "Semantic Error Shader Compiler Loop Cases");
29463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* cacheLoopGroup			= new TestCaseGroup(context, "loop", "Shader Compiler Loop Cache Cases");
29473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		validGroup->addChild(validLoopGroup);
29483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		invalidCharGroup->addChild(invalidCharLoopGroup);
29493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		semanticErrorGroup->addChild(semanticErrorLoopGroup);
29503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		cacheGroup->addChild(cacheLoopGroup);
29513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int loopType = 0; loopType < (int)LOOP_LAST; loopType++)
29533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
29543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char* loopTypeName = loopType == (int)LOOP_TYPE_STATIC	? "static"
29553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 : loopType == (int)LOOP_TYPE_UNIFORM	? "uniform"
29563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 : loopType == (int)LOOP_TYPE_DYNAMIC	? "dynamic"
29573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 : DE_NULL;
29583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(loopTypeName != DE_NULL);
29603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* validLoopTypeGroup			= new TestCaseGroup(context, loopTypeName, "");
29623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* invalidCharLoopTypeGroup		= new TestCaseGroup(context, loopTypeName, "");
29633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* semanticErrorLoopTypeGroup	= new TestCaseGroup(context, loopTypeName, "");
29643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TestCaseGroup* cacheLoopTypeGroup			= new TestCaseGroup(context, loopTypeName, "");
29653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			validLoopGroup->addChild(validLoopTypeGroup);
29663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			invalidCharLoopGroup->addChild(invalidCharLoopTypeGroup);
29673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			semanticErrorLoopGroup->addChild(semanticErrorLoopTypeGroup);
29683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			cacheLoopGroup->addChild(cacheLoopTypeGroup);
29693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int isFrag = 0; isFrag <= 1; isFrag++)
29713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
29723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				bool		isVertex	= isFrag == 0;
29733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const char*	vertFragStr	= isVertex ? "vertex" : "fragment";
29743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// \note Non-static loop cases with different iteration counts have identical shaders, so only make one of each.
29763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int loopIterCountMaxNdx = loopType != (int)LOOP_TYPE_STATIC ? 1 : DE_LENGTH_OF_ARRAY(loopIterCounts);
29773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int nestingDepth = 1; nestingDepth <= maxLoopNestingDepth; nestingDepth++)
29793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
29803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					for (int loopIterCountNdx = 0; loopIterCountNdx < loopIterCountMaxNdx; loopIterCountNdx++)
29813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					{
29823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						int numIterations = loopIterCounts[loopIterCountNdx];
29833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						if (deFloatPow((float)numIterations, (float)nestingDepth) > (float)maxTotalLoopIterations)
29853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							continue; // Don't generate too heavy tasks.
29863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						string validCaseName = de::toString(numIterations) + "_iterations_" + de::toString(nestingDepth) + "_levels_" + vertFragStr;
29883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						// Valid shader case, no-cache and cache versions.
29903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						validLoopTypeGroup->addChild(new ShaderCompilerLoopCase(context, validCaseName.c_str(), "", caseID++, true  /* avoid cache */, false, isVertex, (LoopType)loopType, numIterations, nestingDepth));
29923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						cacheLoopTypeGroup->addChild(new ShaderCompilerLoopCase(context, validCaseName.c_str(), "", caseID++, false /* allow cache */, false, isVertex, (LoopType)loopType, numIterations, nestingDepth));
29933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						// Invalid shader cases.
29953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
29963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						for (int invalidityType = 0; invalidityType < (int)InvalidShaderCompilerCase::INVALIDITY_LAST; invalidityType++)
29973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						{
29983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							TestCaseGroup* curInvalidGroup	= invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_INVALID_CHAR		? invalidCharLoopTypeGroup
29993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															: invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_SEMANTIC_ERROR	? semanticErrorLoopTypeGroup
30003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															: DE_NULL;
30013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							DE_ASSERT(curInvalidGroup != DE_NULL);
30033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							string invalidCaseName = de::toString(nestingDepth) + "_levels_" + vertFragStr;
30053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							if (loopType == (int)LOOP_TYPE_STATIC)
30073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								invalidCaseName = de::toString(numIterations) + "_iterations_" + invalidCaseName; // \note For invalid, non-static loop cases the iteration count means nothing (since no uniforms or attributes are set).
30083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							curInvalidGroup->addChild(new InvalidShaderCompilerLoopCase(context, invalidCaseName.c_str(), "", caseID++, (InvalidShaderCompilerCase::InvalidityType)invalidityType, isVertex, (LoopType)loopType, numIterations, nestingDepth));
30103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						}
30113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					}
30123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
30133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
30143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
30153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
30163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Multiplication shader compilation cases.
30183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
30203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const int multiplicationCounts[] = { 10, 100, 1000 };
30213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* validMulGroup			= new TestCaseGroup(context, "multiplication", "Shader Compiler Multiplication Cases");
30233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* invalidCharMulGroup		= new TestCaseGroup(context, "multiplication", "Invalid Character Shader Compiler Multiplication Cases");
30243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* semanticErrorMulGroup	= new TestCaseGroup(context, "multiplication", "Semantic Error Shader Compiler Multiplication Cases");
30253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* cacheMulGroup			= new TestCaseGroup(context, "multiplication", "Shader Compiler Multiplication Cache Cases");
30263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		validGroup->addChild(validMulGroup);
30273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		invalidCharGroup->addChild(invalidCharMulGroup);
30283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		semanticErrorGroup->addChild(semanticErrorMulGroup);
30293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		cacheGroup->addChild(cacheMulGroup);
30303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int isFrag = 0; isFrag <= 1; isFrag++)
30323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
30333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool		isVertex	= isFrag == 0;
30343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char*	vertFragStr	= isVertex ? "vertex" : "fragment";
30353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int operCountNdx = 0; operCountNdx < DE_LENGTH_OF_ARRAY(multiplicationCounts); operCountNdx++)
30373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
30383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				int numOpers = multiplicationCounts[operCountNdx];
30393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				string caseName = de::toString(numOpers) + "_operations_" + vertFragStr;
30413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Valid shader case, no-cache and cache versions.
30433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				validMulGroup->addChild(new ShaderCompilerOperCase(context, caseName.c_str(), "", caseID++, true  /* avoid cache */, false, isVertex, "*", numOpers));
30453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				cacheMulGroup->addChild(new ShaderCompilerOperCase(context, caseName.c_str(), "", caseID++, false /* allow cache */, false, isVertex, "*", numOpers));
30463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				// Invalid shader cases.
30483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int invalidityType = 0; invalidityType < (int)InvalidShaderCompilerCase::INVALIDITY_LAST; invalidityType++)
30503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
30513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					TestCaseGroup* curInvalidGroup	= invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_INVALID_CHAR		? invalidCharMulGroup
30523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_SEMANTIC_ERROR	? semanticErrorMulGroup
30533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													: DE_NULL;
30543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(curInvalidGroup != DE_NULL);
30563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					curInvalidGroup->addChild(new InvalidShaderCompilerOperCase(context, caseName.c_str(), "", caseID++, (InvalidShaderCompilerCase::InvalidityType)invalidityType, isVertex, "*", numOpers));
30583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
30593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
30603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
30613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
30623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Mandelbrot shader compilation cases.
30643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
30663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		static const int mandelbrotIterationCounts[] = { 32, 64, 128 };
30673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* validMandelbrotGroup			= new TestCaseGroup(context, "mandelbrot", "Shader Compiler Mandelbrot Fractal Cases");
30693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* invalidCharMandelbrotGroup	= new TestCaseGroup(context, "mandelbrot", "Invalid Character Shader Compiler Mandelbrot Fractal Cases");
30703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* semanticErrorMandelbrotGroup	= new TestCaseGroup(context, "mandelbrot", "Semantic Error Shader Compiler Mandelbrot Fractal Cases");
30713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* cacheMandelbrotGroup			= new TestCaseGroup(context, "mandelbrot", "Shader Compiler Mandelbrot Fractal Cache Cases");
30723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		validGroup->addChild(validMandelbrotGroup);
30733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		invalidCharGroup->addChild(invalidCharMandelbrotGroup);
30743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		semanticErrorGroup->addChild(semanticErrorMandelbrotGroup);
30753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		cacheGroup->addChild(cacheMandelbrotGroup);
30763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int iterCountNdx = 0; iterCountNdx < DE_LENGTH_OF_ARRAY(mandelbrotIterationCounts); iterCountNdx++)
30783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
30793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			int		numFractalIterations	= mandelbrotIterationCounts[iterCountNdx];
30803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string	caseName				= de::toString(numFractalIterations) + "_iterations";
30813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Valid shader case, no-cache and cache versions.
30833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			validMandelbrotGroup->addChild(new ShaderCompilerMandelbrotCase(context, caseName.c_str(), "", caseID++, true  /* avoid cache */, false, numFractalIterations));
30853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			cacheMandelbrotGroup->addChild(new ShaderCompilerMandelbrotCase(context, caseName.c_str(), "", caseID++, false /* allow cache */, false, numFractalIterations));
30863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// Invalid shader cases.
30883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int invalidityType = 0; invalidityType < (int)InvalidShaderCompilerCase::INVALIDITY_LAST; invalidityType++)
30903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
30913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				TestCaseGroup* curInvalidGroup	= invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_INVALID_CHAR		? invalidCharMandelbrotGroup
30923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												: invalidityType == (int)InvalidShaderCompilerCase::INVALIDITY_SEMANTIC_ERROR	? semanticErrorMandelbrotGroup
30933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												: DE_NULL;
30943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(curInvalidGroup != DE_NULL);
30963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
30973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				curInvalidGroup->addChild(new InvalidShaderCompilerMandelbrotCase(context, caseName.c_str(), "", caseID++, (InvalidShaderCompilerCase::InvalidityType)invalidityType, numFractalIterations));
30983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
30993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
31003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
31013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Cases testing cache behaviour when whitespace and comments are added.
31033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
31053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TestCaseGroup* whitespaceCommentCacheGroup = new TestCaseGroup(context, "cache_whitespace_comment", "Cases testing the effect of whitespace and comments on caching");
31063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		parentGroup.addChild(whitespaceCommentCacheGroup);
31073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// \note Add just a small subset of the cases that were added above for the main performance tests.
31093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Cases with both vertex and fragment variants.
31113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int isFrag = 0; isFrag <= 1; isFrag++)
31123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
31133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			bool	isVertex		= isFrag == 0;
31143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string	vtxFragSuffix	= isVertex ? "_vertex" : "_fragment";
31153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string	dirLightName	= "directional_2_lights" + vtxFragSuffix;
31163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string	loopName		= "static_loop_100_iterations" + vtxFragSuffix;
31173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string	multCase		= "multiplication_100_operations" + vtxFragSuffix;
31183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			whitespaceCommentCacheGroup->addChild(new ShaderCompilerLightCase(context, dirLightName.c_str(), "", caseID++, false, true, isVertex, 2, LIGHT_DIRECTIONAL));
31203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			whitespaceCommentCacheGroup->addChild(new ShaderCompilerLoopCase(context, loopName.c_str(), "", caseID++, false, true, isVertex, LOOP_TYPE_STATIC, 100, 1));
31213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			whitespaceCommentCacheGroup->addChild(new ShaderCompilerOperCase(context, multCase.c_str(), "", caseID++, false, true, isVertex, "*", 100));
31223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
31233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Cases that don't have vertex and fragment variants.
31253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		whitespaceCommentCacheGroup->addChild(new ShaderCompilerTextureCase(context, "texture_4_lookups", "", caseID++, false, true, 4, CONDITIONAL_USAGE_NONE, CONDITIONAL_TYPE_STATIC));
31263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		whitespaceCommentCacheGroup->addChild(new ShaderCompilerMandelbrotCase(context, "mandelbrot_32_operations", "", caseID++, false, true, 32));
31273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
31283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
31293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
31303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Performance
31313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles2
31323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
3133