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 Optimized vs unoptimized shader performance tests.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "es2pShaderOptimizationTests.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glsShaderPerformanceMeasurer.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluRenderContext.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "gluShaderProgram.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuTestLog.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuVector.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuStringTemplate.hpp"
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deSharedPtr.hpp"
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deStringUtil.hpp"
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deMath.h"
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwFunctions.hpp"
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector>
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string>
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <map>
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::ShaderProgram;
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::TestLog;
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::Vec4;
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::SharedPtr;
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::toString;
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::vector;
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace deqp
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing gls::ShaderPerformanceMeasurer;
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace gles2
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace Performance
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline std::map<string, string> singleMap (const string& key, const string& value)
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::map<string, string> res;
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	res[key] = value;
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return res;
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline string repeat (const string& str, int numRepeats, const string& delim = "")
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string result = str;
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 1; i < numRepeats; i++)
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result += delim + str;
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline string repeatIndexedTemplate (const string& strTempl, int numRepeats, const string& delim = "", int ndxStart = 0)
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const tcu::StringTemplate	templ(strTempl);
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	string						result;
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::map<string, string>	params;
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numRepeats; i++)
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params["PREV_NDX"]	= toString(i + ndxStart - 1);
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		params["NDX"]		= toString(i + ndxStart);
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		result += (i > 0 ? delim : "") + templ.specialize(params);
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return result;
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryenum CaseShaderType
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASESHADERTYPE_VERTEX = 0,
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASESHADERTYPE_FRAGMENT,
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CASESHADERTYPE_LAST
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline string getShaderPrecision (CaseShaderType shaderType)
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (shaderType)
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASESHADERTYPE_VERTEX:		return "highp";
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case CASESHADERTYPE_FRAGMENT:	return "mediump";
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(false);
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return DE_NULL;
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct ProgramData
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::ProgramSources			sources;
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	vector<gls::AttribSpec>		attributes; //!< \note Shouldn't contain a_position; that one is set by gls::ShaderPerformanceMeasurer.
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramData (void) {}
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramData (const glu::ProgramSources& sources_, const vector<gls::AttribSpec>& attributes_ = vector<gls::AttribSpec>())	: sources(sources_), attributes(attributes_)	{}
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramData (const glu::ProgramSources& sources_, const gls::AttribSpec& attribute)											: sources(sources_), attributes(1, attribute)	{}
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Shader boilerplate helper; most cases have similar basic shader structure.
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline ProgramData defaultProgramData (CaseShaderType shaderType, const string& funcDefs, const string& mainStatements)
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		isVertexCase	= shaderType == CASESHADERTYPE_VERTEX;
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		isFragmentCase	= shaderType == CASESHADERTYPE_FRAGMENT;
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const string	vtxPrec			= getShaderPrecision(CASESHADERTYPE_VERTEX);
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const string	fragPrec		= getShaderPrecision(CASESHADERTYPE_FRAGMENT);
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return ProgramData(glu::ProgramSources() << glu::VertexSource(		"attribute " + vtxPrec + " vec4 a_position;\n"
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		"attribute " + vtxPrec + " vec4 a_value;\n"
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		"varying " + fragPrec + " vec4 v_value;\n"
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		+ (isVertexCase ? funcDefs : "") +
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		"void main (void)\n"
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		"{\n"
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		"	gl_Position = a_position;\n"
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		"	" + vtxPrec + " vec4 value = a_value;\n"
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		+ (isVertexCase ? mainStatements : "") +
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		"	v_value = value;\n"
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		"}\n")
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											 << glu::FragmentSource(	"varying " + fragPrec + " vec4 v_value;\n"
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		+ (isFragmentCase ? funcDefs : "") +
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		"void main (void)\n"
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		"{\n"
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		"	" + fragPrec + " vec4 value = v_value;\n"
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		+ (isFragmentCase ? mainStatements : "") +
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		"	gl_FragColor = value;\n"
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		"}\n"),
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					  gls::AttribSpec("a_value",
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  Vec4(1.0f, 0.0f, 0.0f, 0.0f),
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  Vec4(0.0f, 1.0f, 0.0f, 0.0f),
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  Vec4(0.0f, 0.0f, 1.0f, 0.0f),
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									  Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline ProgramData defaultProgramData (CaseShaderType shaderType, const string& mainStatements)
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return defaultProgramData(shaderType, "", mainStatements);
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ShaderOptimizationCase : public TestCase
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderOptimizationCase (Context& context, const char* name, const char* description, CaseShaderType caseShaderType)
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: TestCase				(context, tcu::NODETYPE_PERFORMANCE, name, description)
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_caseShaderType		(caseShaderType)
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_state				(STATE_LAST)
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_measurer			(context.getRenderContext(), caseShaderType == CASESHADERTYPE_VERTEX	? gls::CASETYPE_VERTEX
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														   : caseShaderType == CASESHADERTYPE_FRAGMENT	? gls::CASETYPE_FRAGMENT
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														   : gls::CASETYPE_LAST)
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_unoptimizedResult	(-1.0f, -1.0f)
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_optimizedResult		(-1.0f, -1.0f)
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ~ShaderOptimizationCase (void) {}
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void			init		(void);
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	IterateResult	iterate		(void);
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ProgramData		generateProgramData (bool optimized) const = 0;
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CaseShaderType	m_caseShaderType;
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum State
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		STATE_INIT_UNOPTIMIZED = 0,
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		STATE_MEASURE_UNOPTIMIZED,
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		STATE_INIT_OPTIMIZED,
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		STATE_MEASURE_OPTIMIZED,
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		STATE_FINISHED,
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		STATE_LAST
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramData&						programData		(bool optimized) { return optimized ? m_optimizedData		: m_unoptimizedData;		}
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SharedPtr<const ShaderProgram>&		program			(bool optimized) { return optimized ? m_optimizedProgram	: m_unoptimizedProgram;		}
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderPerformanceMeasurer::Result&	result			(bool optimized) { return optimized ? m_optimizedResult		: m_unoptimizedResult;		}
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	State								m_state;
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderPerformanceMeasurer			m_measurer;
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramData							m_unoptimizedData;
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramData							m_optimizedData;
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SharedPtr<const ShaderProgram>		m_unoptimizedProgram;
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	SharedPtr<const ShaderProgram>		m_optimizedProgram;
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderPerformanceMeasurer::Result	m_unoptimizedResult;
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ShaderPerformanceMeasurer::Result	m_optimizedResult;
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderOptimizationCase::init (void)
2183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const glu::RenderContext&	renderCtx	= m_context.getRenderContext();
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog&					log			= m_testCtx.getLog();
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_measurer.logParameters(log);
2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int ndx = 0; ndx < 2; ndx++)
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool optimized = ndx == 1;
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		programData(optimized) = generateProgramData(optimized);
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < (int)programData(optimized).attributes.size(); i++)
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			DE_ASSERT(programData(optimized).attributes[i].name != "a_position"); // \note Position attribute is set by m_measurer.
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		program(optimized) = SharedPtr<const ShaderProgram>(new ShaderProgram(renderCtx, programData(optimized).sources));
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::ScopedLogSection section(log, optimized ? "OptimizedProgram"			: "UnoptimizedProgram",
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 optimized ? "Hand-optimized program"	: "Unoptimized program");
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << *program(optimized);
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!program(optimized)->isOk())
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_FAIL("Shader compilation failed");
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_state = STATE_INIT_UNOPTIMIZED;
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2483c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderOptimizationCase::IterateResult ShaderOptimizationCase::iterate (void)
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestLog& log = m_testCtx.getLog();
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_state == STATE_INIT_UNOPTIMIZED || m_state == STATE_INIT_OPTIMIZED)
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool optimized = m_state == STATE_INIT_OPTIMIZED;
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_measurer.init(program(optimized)->getProgram(), programData(optimized).attributes, 1);
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_state = optimized ? STATE_MEASURE_OPTIMIZED : STATE_MEASURE_UNOPTIMIZED;
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CONTINUE;
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else if (m_state == STATE_MEASURE_UNOPTIMIZED || m_state == STATE_MEASURE_OPTIMIZED)
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_measurer.iterate();
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (m_measurer.isFinished())
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const bool						optimized	= m_state == STATE_MEASURE_OPTIMIZED;
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const tcu::ScopedLogSection		section		(log, optimized ? "OptimizedResult"									: "UnoptimizedResult",
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															  optimized ? "Measurement results for hand-optimized program"	: "Measurement result for unoptimized program");
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_measurer.logMeasurementInfo(log);
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result(optimized) = m_measurer.getResult();
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_measurer.deinit();
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			m_state = optimized ? STATE_FINISHED : STATE_INIT_OPTIMIZED;
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return CONTINUE;
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	else
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(m_state == STATE_FINISHED);
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float			unoptimizedRelevantResult	= m_caseShaderType == CASESHADERTYPE_VERTEX ? m_unoptimizedResult.megaVertPerSec	: m_unoptimizedResult.megaFragPerSec;
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float			optimizedRelevantResult		= m_caseShaderType == CASESHADERTYPE_VERTEX ? m_optimizedResult.megaVertPerSec		: m_optimizedResult.megaFragPerSec;
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* const	relevantResultName			= m_caseShaderType == CASESHADERTYPE_VERTEX ? "vertex"								: "fragment";
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const float			ratio						= unoptimizedRelevantResult / optimizedRelevantResult;
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int			handOptimizationGain		= (int)deFloatRound(100.0f/ratio) - 100;
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		log << TestLog::Message << "Unoptimized / optimized " << relevantResultName << " performance ratio: " << ratio << TestLog::EndMessage;
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (handOptimizationGain >= 0)
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Note: " << handOptimizationGain << "% performance gain was achieved with hand-optimized version" << TestLog::EndMessage;
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			log << TestLog::Message << "Note: hand-optimization degraded performance by " << -handOptimizationGain << "%" << TestLog::EndMessage;
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(ratio, 2).c_str());
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return STOP;
2973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass LoopUnrollCase : public ShaderOptimizationCase
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum CaseType
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_INDEPENDENT = 0,
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_DEPENDENT,
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_LAST
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LoopUnrollCase (Context& context, const char* name, const char* description, CaseShaderType caseShaderType, CaseType caseType, int numRepetitions)
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ShaderOptimizationCase	(context, name, description, caseShaderType)
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_numRepetitions			(numRepetitions)
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_caseType				(caseType)
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramData generateProgramData (bool optimized) const
3203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string repetition = optimized ? repeatIndexedTemplate("\t" + expressionTemplate(m_caseType) + ";\n", m_numRepetitions)
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry											: loop(m_numRepetitions, expressionTemplate(m_caseType));
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return defaultProgramData(m_caseShaderType, "\t" + getShaderPrecision(m_caseShaderType) + " vec4 valueOrig = value;\n" + repetition);
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int		m_numRepetitions;
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CaseType	m_caseType;
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string expressionTemplate (CaseType caseType)
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		switch (caseType)
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
3353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case CASETYPE_INDEPENDENT:	return "value += sin(float(${NDX}+1)*valueOrig)";
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			case CASETYPE_DEPENDENT:	return "value = sin(value)";
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			default:
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				DE_ASSERT(false);
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				return DE_NULL;
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string loop (int iterations, const string& innerExpr)
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return "\tfor (int i = 0; i < " + toString(iterations) + "; i++)\n\t\t" + tcu::StringTemplate(innerExpr).specialize(singleMap("NDX", "i")) + ";\n";
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass LoopInvariantCodeMotionCase : public ShaderOptimizationCase
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	LoopInvariantCodeMotionCase (Context& context, const char* name, const char* description, CaseShaderType caseShaderType, int numLoopIterations)
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ShaderOptimizationCase	(context, name, description, caseShaderType)
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_numLoopIterations		(numLoopIterations)
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramData generateProgramData (bool optimized) const
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		float scale = 0.0f;
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 0; i < m_numLoopIterations; i++)
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			scale += 3.2f*(float)i + 4.6f;
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		scale = 1.0f / scale;
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string precision		= getShaderPrecision(m_caseShaderType);
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string statements		= optimized ?	"	" + precision + " vec4 valueOrig = value;\n"
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"	" + precision + " vec4 y = sin(cos(sin(valueOrig)));\n"
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"	for (int i = 0; i < " + toString(m_numLoopIterations) + "; i++)\n"
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"	{\n"
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"		" + precision + " float x = 3.2*float(i) + 4.6;\n"
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"		value += x*y;\n"
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"	}\n"
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"	value *= " + toString(scale) + ";\n"
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												:	"	" + precision + " vec4 valueOrig = value;\n"
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"	for (int i = 0; i < " + toString(m_numLoopIterations) + "; i++)\n"
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"	{\n"
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"		" + precision + " float x = 3.2*float(i) + 4.6;\n"
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"		" + precision + " vec4 y = sin(cos(sin(valueOrig)));\n"
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"		value += x*y;\n"
3823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"	}\n"
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"	value *= " + toString(scale) + ";\n";
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return defaultProgramData(m_caseShaderType, statements);
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int m_numLoopIterations;
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FunctionInliningCase : public ShaderOptimizationCase
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FunctionInliningCase (Context& context, const char* name, const char* description, CaseShaderType caseShaderType, int callNestingDepth)
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ShaderOptimizationCase	(context, name, description, caseShaderType)
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_callNestingDepth		(callNestingDepth)
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramData generateProgramData (bool optimized) const
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string precision				= getShaderPrecision(m_caseShaderType);
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string expression				= "value*vec4(0.8, 0.7, 0.6, 0.9)";
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string maybeFuncDefs			= optimized ? "" : funcDefinitions(m_callNestingDepth, precision, expression);
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string mainValueStatement		= (optimized ? "\tvalue = " + expression : "\tvalue = func" + toString(m_callNestingDepth-1) + "(value)") + ";\n";
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return defaultProgramData(m_caseShaderType, maybeFuncDefs, mainValueStatement);
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int m_callNestingDepth;
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string funcDefinitions (int callNestingDepth, const string& precision, const string& expression)
4163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		string result = precision + " vec4 func0 (" + precision + " vec4 value) { return " + expression + "; }\n";
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int i = 1; i < callNestingDepth; i++)
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result += precision + " vec4 func" + toString(i) + " (" + precision + " vec4 v) { return func" + toString(i-1) + "(v); }\n";
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return result;
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass ConstantPropagationCase : public ShaderOptimizationCase
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum CaseType
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_BUILT_IN_FUNCTIONS = 0,
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_ARRAY,
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_STRUCT,
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_LAST
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ConstantPropagationCase (Context& context, const char* name, const char* description, CaseShaderType caseShaderType, CaseType caseType, bool useConstantExpressionsOnly)
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ShaderOptimizationCase			(context, name, description, caseShaderType)
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_caseType						(caseType)
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_useConstantExpressionsOnly		(useConstantExpressionsOnly)
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(!(m_caseType == CASETYPE_ARRAY && m_useConstantExpressionsOnly)); // \note Would need array constructors, which GLSL ES 1 doesn't have.
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramData generateProgramData (bool optimized) const
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool		isVertexCase	= m_caseShaderType == CASESHADERTYPE_VERTEX;
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string	precision		= getShaderPrecision(m_caseShaderType);
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string	statements		= m_caseType == CASETYPE_BUILT_IN_FUNCTIONS		? builtinFunctionsCaseStatements	(optimized, m_useConstantExpressionsOnly, precision, isVertexCase)
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: m_caseType == CASETYPE_ARRAY					? arrayCaseStatements				(optimized, precision, isVertexCase)
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: m_caseType == CASETYPE_STRUCT					? structCaseStatements				(optimized, m_useConstantExpressionsOnly, precision, isVertexCase)
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: DE_NULL;
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return defaultProgramData(m_caseShaderType, statements);
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CaseType	m_caseType;
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const bool		m_useConstantExpressionsOnly;
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string builtinFunctionsCaseStatements (bool optimized, bool constantExpressionsOnly, const string& precision, bool useHeavierWorkload)
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string	constMaybe = constantExpressionsOnly ? "const " : "";
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		numSinRows = useHeavierWorkload ? 12 : 1;
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return optimized ?	"	value = vec4(0.4, 0.5, 0.6, 0.7) * value; // NOTE: factor doesn't necessarily match the one in unoptimized shader, but shouldn't make a difference performance-wise\n"
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 :	"	" + constMaybe + precision + " vec4 a = vec4(sin(0.7), cos(0.2), sin(0.9), abs(-0.5));\n"
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + constMaybe + precision + " vec4 b = cos(a) + fract(3.0*a.xzzw);\n"
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + constMaybe + "bvec4 c = bvec4(true, false, true, true);\n"
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + constMaybe + precision + " vec4 d = exp(b + vec4(c));\n"
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + constMaybe + precision + " vec4 e0 = inversesqrt(mix(d+a, d+b, a));\n"
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							+ repeatIndexedTemplate("	" + constMaybe + precision + " vec4 e${NDX} = sin(sin(sin(sin(e${PREV_NDX}))));\n", numSinRows, "", 1) +
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + constMaybe + precision + " vec4 f = abs(e" + toString(numSinRows) + ");\n" +
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	value = f*value;\n";
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string arrayCaseStatements (bool optimized, const string& precision, bool useHeavierWorkload)
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int numSinRows = useHeavierWorkload ? 12 : 1;
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return optimized ?	"	value = vec4(0.4, 0.5, 0.6, 0.7) * value; // NOTE: factor doesn't necessarily match the one in unoptimized shader, but shouldn't make a difference performance-wise\n"
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 :	"	const int arrLen = 4;\n"
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + precision + " vec4 arr[arrLen];\n"
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	arr[0] = vec4(0.1, 0.5, 0.9, 1.3);\n"
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	arr[1] = vec4(0.2, 0.6, 1.0, 1.4);\n"
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	arr[2] = vec4(0.3, 0.7, 1.1, 1.5);\n"
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	arr[3] = vec4(0.4, 0.8, 1.2, 1.6);\n"
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + precision + " vec4 a = (arr[0] + arr[1] + arr[2] + arr[3]) * 0.25;\n"
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + precision + " vec4 b0 = cos(sin(a));\n"
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							+ repeatIndexedTemplate("	" + precision + " vec4 b${NDX} = sin(sin(sin(sin(b${PREV_NDX}))));\n", numSinRows, "", 1) +
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + precision + " vec4 c = abs(b" + toString(numSinRows) + ");\n" +
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	value = c*value;\n";
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string structCaseStatements (bool optimized, bool constantExpressionsOnly, const string& precision, bool useHeavierWorkload)
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string	constMaybe = constantExpressionsOnly ? "const " : "";
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		numSinRows = useHeavierWorkload ? 12 : 1;
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return optimized ?	"	value = vec4(0.4, 0.5, 0.6, 0.7) * value; // NOTE: factor doesn't necessarily match the one in unoptimized shader, but shouldn't make a difference performance-wise\n"
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 :	"	struct S\n"
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	{\n"
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		" + precision + " vec4 a;\n"
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		" + precision + " vec4 b;\n"
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		" + precision + " vec4 c;\n"
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		" + precision + " vec4 d;\n"
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	};\n"
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"\n"
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + constMaybe + "S s =\n"
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		S(vec4(0.1, 0.5, 0.9, 1.3),\n"
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		  vec4(0.2, 0.6, 1.0, 1.4),\n"
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		  vec4(0.3, 0.7, 1.1, 1.5),\n"
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		  vec4(0.4, 0.8, 1.2, 1.6));\n"
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + constMaybe + precision + " vec4 a = (s.a + s.b + s.c + s.d) * 0.25;\n"
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + constMaybe + precision + " vec4 b0 = cos(sin(a));\n"
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							+ repeatIndexedTemplate("	" + constMaybe + precision + " vec4 b${NDX} = sin(sin(sin(sin(b${PREV_NDX}))));\n", numSinRows, "", 1) +
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + constMaybe + precision + " vec4 c = abs(b" + toString(numSinRows) + ");\n" +
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	value = c*value;\n";
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CommonSubexpressionCase : public ShaderOptimizationCase
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum CaseType
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_SINGLE_STATEMENT = 0,
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_MULTIPLE_STATEMENTS,
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_STATIC_BRANCH,
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_LOOP,
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_LAST
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	CommonSubexpressionCase (Context& context, const char* name, const char* description, CaseShaderType caseShaderType, CaseType caseType)
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ShaderOptimizationCase	(context, name, description, caseShaderType)
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_caseType				(caseType)
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramData generateProgramData (bool optimized) const
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool		isVertexCase	= m_caseShaderType == CASESHADERTYPE_VERTEX;
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string	precision		= getShaderPrecision(m_caseShaderType);
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string	statements		= m_caseType == CASETYPE_SINGLE_STATEMENT		? singleStatementCaseStatements		(optimized, precision, isVertexCase)
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: m_caseType == CASETYPE_MULTIPLE_STATEMENTS	? multipleStatementsCaseStatements	(optimized, precision, isVertexCase)
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: m_caseType == CASETYPE_STATIC_BRANCH			? staticBranchCaseStatements		(optimized, precision, isVertexCase)
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: m_caseType == CASETYPE_LOOP					? loopCaseStatements				(optimized, precision, isVertexCase)
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: DE_NULL;
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return defaultProgramData(m_caseShaderType, statements);
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CaseType m_caseType;
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string singleStatementCaseStatements (bool optimized, const string& precision, bool useHeavierWorkload)
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int numTopLevelRepeats = useHeavierWorkload ? 4 : 1;
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return optimized ?	"	" + precision + " vec4 s = sin(value);\n"
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + precision + " vec4 cs = cos(s);\n"
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + precision + " vec4 d = fract(s + cs) + sqrt(s + exp(cs));\n"
5703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	value = " + repeat("d", numTopLevelRepeats, "+") + ";\n"
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 :	"	value = " + repeat("fract(sin(value) + cos(sin(value))) + sqrt(sin(value) + exp(cos(sin(value))))", numTopLevelRepeats, "\n\t      + ") + ";\n";
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string multipleStatementsCaseStatements (bool optimized, const string& precision, bool useHeavierWorkload)
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int numTopLevelRepeats = useHeavierWorkload ? 4 : 2;
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(numTopLevelRepeats >= 2);
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return optimized ?	"	" + precision + " vec4 a = sin(value) + cos(exp(value));\n"
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + precision + " vec4 b = cos(cos(a));\n"
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	a = fract(exp(sqrt(b)));\n"
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"\n"
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							+ repeat("\tvalue += a*b;\n", numTopLevelRepeats)
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 :	repeatIndexedTemplate(	"	" + precision + " vec4 a${NDX} = sin(value) + cos(exp(value));\n"
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"	" + precision + " vec4 b${NDX} = cos(cos(a${NDX}));\n"
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"	a${NDX} = fract(exp(sqrt(b${NDX})));\n"
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													"\n",
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													numTopLevelRepeats) +
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							repeatIndexedTemplate(	"	value += a${NDX}*b${NDX};\n", numTopLevelRepeats);
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string staticBranchCaseStatements (bool optimized, const string& precision, bool useHeavierWorkload)
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int numTopLevelRepeats = useHeavierWorkload ? 4 : 2;
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		DE_ASSERT(numTopLevelRepeats >= 2);
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (optimized)
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return "	" + precision + " vec4 a = sin(value) + cos(exp(value));\n"
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   "	" + precision + " vec4 b = cos(a);\n"
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   "	b = cos(b);\n"
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   "	a = fract(exp(sqrt(b)));\n"
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   "\n"
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   + repeat("	value += a*b;\n", numTopLevelRepeats);
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			string result;
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int i = 0; i < numTopLevelRepeats; i++)
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
6153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				result +=	"	" + precision + " vec4 a" + toString(i) + " = sin(value) + cos(exp(value));\n"
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + precision + " vec4 b" + toString(i) + " = cos(a" + toString(i) + ");\n";
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (i % 3 == 0)
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result +=	"	if (1 < 2)\n"
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								"		b" + toString(i) + " = cos(b" + toString(i) + ");\n";
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else if (i % 3 == 1)
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result +=	"	b" + toString(i) + " = cos(b" + toString(i) + ");\n";
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else if (i % 3 == 2)
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					result +=	"	if (2 < 1);\n"
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								"	else\n"
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								"		b" + toString(i) + " = cos(b" + toString(i) + ");\n";
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				else
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					DE_ASSERT(false);
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				result +=	"	a" + toString(i) + " = fract(exp(sqrt(b" + toString(i) + ")));\n\n";
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			result += repeatIndexedTemplate("	value += a${NDX}*b${NDX};\n", numTopLevelRepeats);
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return result;
6363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string loopCaseStatements (bool optimized, const string& precision, bool useHeavierWorkload)
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int numLoopIterations = useHeavierWorkload ? 32 : 4;
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return optimized ?	"	" + precision + " vec4 acc = value;\n"
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	for (int i = 0; i < " + toString(numLoopIterations) + "; i++)\n"
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		acc = sin(acc);\n"
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"\n"
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	value += acc;\n"
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	value += acc;\n"
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 :	"	" + precision + " vec4 acc0 = value;\n"
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	for (int i = 0; i < " + toString(numLoopIterations) + "; i++)\n"
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		acc0 = sin(acc0);\n"
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"\n"
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + precision + " vec4 acc1 = value;\n"
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	for (int i = 0; i < " + toString(numLoopIterations) + "; i++)\n"
6563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		acc1 = sin(acc1);\n"
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"\n"
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	value += acc0;\n"
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	value += acc1;\n";
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass DeadCodeEliminationCase : public ShaderOptimizationCase
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum CaseType
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_DEAD_BRANCH_SIMPLE = 0,
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_DEAD_BRANCH_COMPLEX,
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_DEAD_BRANCH_COMPLEX_NO_CONST,
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_DEAD_BRANCH_FUNC_CALL,
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_UNUSED_VALUE_BASIC,
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_UNUSED_VALUE_LOOP,
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_UNUSED_VALUE_DEAD_BRANCH,
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_UNUSED_VALUE_AFTER_RETURN,
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_UNUSED_VALUE_MUL_ZERO,
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		CASETYPE_LAST
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DeadCodeEliminationCase (Context& context, const char* name, const char* description, CaseShaderType caseShaderType, CaseType caseType)
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		: ShaderOptimizationCase	(context, name, description, caseShaderType)
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		, m_caseType				(caseType)
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
6883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ProgramData generateProgramData (bool optimized) const
6893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const bool		isVertexCase	= m_caseShaderType == CASESHADERTYPE_VERTEX;
6913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string	precision		= getShaderPrecision(m_caseShaderType);
6923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string	funcDefs		= m_caseType == CASETYPE_DEAD_BRANCH_FUNC_CALL		? deadBranchFuncCallCaseFuncDefs		(optimized, precision)
6933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: m_caseType == CASETYPE_UNUSED_VALUE_AFTER_RETURN	? unusedValueAfterReturnCaseFuncDefs	(optimized, precision, isVertexCase)
6943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: "";
6953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string	statements		= m_caseType == CASETYPE_DEAD_BRANCH_SIMPLE				? deadBranchSimpleCaseStatements			(optimized, isVertexCase)
6973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: m_caseType == CASETYPE_DEAD_BRANCH_COMPLEX			? deadBranchComplexCaseStatements			(optimized, precision, true,	isVertexCase)
6983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: m_caseType == CASETYPE_DEAD_BRANCH_COMPLEX_NO_CONST	? deadBranchComplexCaseStatements			(optimized, precision, false,	isVertexCase)
6993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: m_caseType == CASETYPE_DEAD_BRANCH_FUNC_CALL			? deadBranchFuncCallCaseStatements			(optimized, isVertexCase)
7003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: m_caseType == CASETYPE_UNUSED_VALUE_BASIC				? unusedValueBasicCaseStatements			(optimized, precision, isVertexCase)
7013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: m_caseType == CASETYPE_UNUSED_VALUE_LOOP				? unusedValueLoopCaseStatements				(optimized, precision, isVertexCase)
7023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: m_caseType == CASETYPE_UNUSED_VALUE_DEAD_BRANCH		? unusedValueDeadBranchCaseStatements		(optimized, precision, isVertexCase)
7033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: m_caseType == CASETYPE_UNUSED_VALUE_AFTER_RETURN		? unusedValueAfterReturnCaseStatements		()
7043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: m_caseType == CASETYPE_UNUSED_VALUE_MUL_ZERO			? unusedValueMulZeroCaseStatements			(optimized, precision, isVertexCase)
7053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										: DE_NULL;
7063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return defaultProgramData(m_caseShaderType, funcDefs, statements);
7083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
7113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const CaseType m_caseType;
7123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string deadBranchSimpleCaseStatements (bool optimized, bool useHeavierWorkload)
7143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int numLoopIterations = useHeavierWorkload ? 16 : 4;
7163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return optimized ?	"	value = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
7183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 :	"	value = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
7203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	if (2 < 1)\n"
7213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	{\n"
7223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		value = cos(exp(sin(value))*log(sqrt(value)));\n"
7233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		for (int i = 0; i < " + toString(numLoopIterations) + "; i++)\n"
7243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"			value = sin(value);\n"
7253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	}\n";
7263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string deadBranchComplexCaseStatements (bool optimized, const string& precision, bool useConst, bool useHeavierWorkload)
7293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const string	constMaybe			= useConst ? "const " : "";
7313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int		numLoopIterations	= useHeavierWorkload ? 16 : 4;
7323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return optimized ?	"	value = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
7343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 :	"	value = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
7363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + constMaybe + precision + " vec4 a = vec4(sin(0.7), cos(0.2), sin(0.9), abs(-0.5));\n"
7373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + constMaybe + precision + " vec4 b = cos(a) + fract(3.0*a.xzzw);\n"
7383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + constMaybe + "bvec4 c = bvec4(true, false, true, true);\n"
7393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + constMaybe + precision + " vec4 d = exp(b + vec4(c));\n"
7403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + constMaybe + precision + " vec4 e = 1.8*abs(sin(sin(inversesqrt(mix(d+a, d+b, a)))));\n"
7413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	if (e.x > 1.0)\n"
7423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	{\n"
7433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		value = cos(exp(sin(value))*log(sqrt(value)));\n"
7443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		for (int i = 0; i < " + toString(numLoopIterations) + "; i++)\n"
7453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"			value = sin(value);\n"
7463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	}\n";
7473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string deadBranchFuncCallCaseFuncDefs (bool optimized, const string& precision)
7503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return optimized ? "" : precision + " float func (" + precision + " float x) { return 2.0*x; }\n";
7523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string deadBranchFuncCallCaseStatements (bool optimized, bool useHeavierWorkload)
7553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int numLoopIterations = useHeavierWorkload ? 16 : 4;
7573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return optimized ?	"	value = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
7593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 :	"	value = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
7613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	if (func(0.3) > 1.0)\n"
7623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	{\n"
7633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		value = cos(exp(sin(value))*log(sqrt(value)));\n"
7643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		for (int i = 0; i < " + toString(numLoopIterations) + "; i++)\n"
7653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"			value = sin(value);\n"
7663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	}\n";
7673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string unusedValueBasicCaseStatements (bool optimized, const string& precision, bool useHeavierWorkload)
7703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int numSinRows = useHeavierWorkload ? 12 : 1;
7723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return optimized ?	"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
7743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	value = used;\n"
7753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 :	"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
7773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + precision + " vec4 unused = cos(exp(sin(value))*log(sqrt(value))) + used;\n"
7783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							+ repeat("	unused = sin(sin(sin(sin(unused))));\n", numSinRows) +
7793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	value = used;\n";
7803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string unusedValueLoopCaseStatements (bool optimized, const string& precision, bool useHeavierWorkload)
7833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int numLoopIterations = useHeavierWorkload ? 16 : 4;
7853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return optimized ?	"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
7873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	value = used;\n"
7883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 :	"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
7903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + precision + " vec4 unused = cos(exp(sin(value))*log(sqrt(value)));\n"
7913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	for (int i = 0; i < " + toString(numLoopIterations) + "; i++)\n"
7923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		unused = sin(unused + used);\n"
7933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	value = used;\n";
7943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
7953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
7963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string unusedValueAfterReturnCaseFuncDefs (bool optimized, const string& precision, bool useHeavierWorkload)
7973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
7983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int numSinRows = useHeavierWorkload ? 12 : 1;
7993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return optimized ?	precision + " vec4 func (" + precision + " vec4 v)\n"
8013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"{\n"
8023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * v;\n"
8033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	return used;\n"
8043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"}\n"
8053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 :	precision + " vec4 func (" + precision + " vec4 v)\n"
8073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"{\n"
8083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * v;\n"
8093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + precision + " vec4 unused = cos(exp(sin(v))*log(sqrt(v)));\n"
8103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							+ repeat("	unused = sin(sin(sin(sin(unused))));\n", numSinRows) +
8113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	return used;\n"
8123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	used = used*unused;"
8133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	return used;\n"
8143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"}\n";
8153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string unusedValueAfterReturnCaseStatements (void)
8183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return "	value = func(value);\n";
8203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string unusedValueDeadBranchCaseStatements (bool optimized, const string& precision, bool useHeavierWorkload)
8233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int numSinRows = useHeavierWorkload ? 12 : 1;
8253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return optimized ?	"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
8273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	value = used;\n"
8283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 :	"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
8303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + precision + " vec4 unused = cos(exp(sin(value))*log(sqrt(value)));\n"
8313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							+ repeat("	unused = sin(sin(sin(sin(unused))));\n", numSinRows) +
8323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	if (2 < 1)\n"
8333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"		used = used*unused;\n"
8343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	value = used;\n";
8353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static inline string unusedValueMulZeroCaseStatements (bool optimized, const string& precision, bool useHeavierWorkload)
8383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int numSinRows = useHeavierWorkload ? 12 : 1;
8403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return optimized ?	"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
8423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	value = used;\n"
8433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 :	"	" + precision + " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
8453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	" + precision + " vec4 unused = cos(exp(sin(value))*log(sqrt(value)));\n"
8463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							+ repeat("	unused = sin(sin(sin(sin(unused))));\n", numSinRows) +
8473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							"	value = used + unused*float(1-1);\n";
8483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
8493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
8503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // anonymous
8523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8533c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderOptimizationTests::ShaderOptimizationTests (Context& context)
8543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: TestCaseGroup(context, "optimization", "Shader Optimization Performance Tests")
8553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8583c827367444ee418f129b2c238299f49d3264554Jarkko PoyryShaderOptimizationTests::~ShaderOptimizationTests (void)
8593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
8613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8623c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid ShaderOptimizationTests::init (void)
8633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
8643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* const unrollGroup					= new TestCaseGroup(m_context, "loop_unrolling",					"Loop Unrolling Cases");
8653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* const loopInvariantCodeMotionGroup	= new TestCaseGroup(m_context, "loop_invariant_code_motion",		"Loop-Invariant Code Motion Cases");
8663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* const inlineGroup					= new TestCaseGroup(m_context, "function_inlining",					"Function Inlining Cases");
8673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* const constantPropagationGroup		= new TestCaseGroup(m_context, "constant_propagation",				"Constant Propagation Cases");
8683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* const commonSubexpressionGroup		= new TestCaseGroup(m_context, "common_subexpression_elimination",	"Common Subexpression Elimination Cases");
8693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TestCaseGroup* const deadCodeEliminationGroup		= new TestCaseGroup(m_context, "dead_code_elimination",				"Dead Code Elimination Cases");
8703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(unrollGroup);
8713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(loopInvariantCodeMotionGroup);
8723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(inlineGroup);
8733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(constantPropagationGroup);
8743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(commonSubexpressionGroup);
8753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	addChild(deadCodeEliminationGroup);
8763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int caseShaderTypeI = 0; caseShaderTypeI < CASESHADERTYPE_LAST; caseShaderTypeI++)
8783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
8793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const CaseShaderType	caseShaderType			= (CaseShaderType)caseShaderTypeI;
8803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* const		caseShaderTypeSuffix	= caseShaderType == CASESHADERTYPE_VERTEX		? "_vertex"
8813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														: caseShaderType == CASESHADERTYPE_FRAGMENT		? "_fragment"
8823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry														: DE_NULL;
8833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Loop unrolling cases.
8853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
8873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			static const int loopIterationCounts[] = { 4, 8, 32 };
8883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int caseTypeI = 0; caseTypeI < LoopUnrollCase::CASETYPE_LAST; caseTypeI++)
8903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
8913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const LoopUnrollCase::CaseType	caseType		= (LoopUnrollCase::CaseType)caseTypeI;
8923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string					caseTypeName	= caseType == LoopUnrollCase::CASETYPE_INDEPENDENT	? "independent_iterations"
8933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																: caseType == LoopUnrollCase::CASETYPE_DEPENDENT	? "dependent_iterations"
8943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																: DE_NULL;
8953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string					caseTypeDesc	= caseType == LoopUnrollCase::CASETYPE_INDEPENDENT	? "loop iterations don't depend on each other"
8963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																: caseType == LoopUnrollCase::CASETYPE_DEPENDENT	? "loop iterations depend on each other"
8973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																: DE_NULL;
8983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
8993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				for (int loopIterNdx = 0; loopIterNdx < DE_LENGTH_OF_ARRAY(loopIterationCounts); loopIterNdx++)
9003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				{
9013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const int			loopIterations	= loopIterationCounts[loopIterNdx];
9023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const string		name			= caseTypeName + "_" + toString(loopIterations) + caseShaderTypeSuffix;
9033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					const string		description		= toString(loopIterations) + " iterations; " + caseTypeDesc;
9043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					unrollGroup->addChild(new LoopUnrollCase(m_context, name.c_str(), description.c_str(), caseShaderType, caseType, loopIterations));
9063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				}
9073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Loop-invariant code motion cases.
9113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			static const int loopIterationCounts[] = { 4, 8, 32 };
9143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int loopIterNdx = 0; loopIterNdx < DE_LENGTH_OF_ARRAY(loopIterationCounts); loopIterNdx++)
9163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		loopIterations	= loopIterationCounts[loopIterNdx];
9183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string	name			= toString(loopIterations) + "_iterations" + caseShaderTypeSuffix;
9193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				loopInvariantCodeMotionGroup->addChild(new LoopInvariantCodeMotionCase(m_context, name.c_str(), "", caseShaderType, loopIterations));
9213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Function inlining cases.
9253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			static const int callNestingDepths[] = { 4, 8, 32 };
9283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int nestDepthNdx = 0; nestDepthNdx < DE_LENGTH_OF_ARRAY(callNestingDepths); nestDepthNdx++)
9303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const int		nestingDepth	= callNestingDepths[nestDepthNdx];
9323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string	name			= toString(nestingDepth) + "_nested" + caseShaderTypeSuffix;
9333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				inlineGroup->addChild(new FunctionInliningCase(m_context, name.c_str(), "", caseShaderType, nestingDepth));
9353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Constant propagation cases.
9393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int caseTypeI = 0; caseTypeI < ConstantPropagationCase::CASETYPE_LAST; caseTypeI++)
9413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const ConstantPropagationCase::CaseType		caseType		= (ConstantPropagationCase::CaseType)caseTypeI;
9433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string								caseTypeName	= caseType == ConstantPropagationCase::CASETYPE_BUILT_IN_FUNCTIONS		? "built_in_functions"
9443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		: caseType == ConstantPropagationCase::CASETYPE_ARRAY					? "array"
9453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		: caseType == ConstantPropagationCase::CASETYPE_STRUCT					? "struct"
9463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		: DE_NULL;
9473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			for (int constantExpressionsOnlyI = 0; constantExpressionsOnlyI <= 1; constantExpressionsOnlyI++)
9493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			{
9503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const bool		constantExpressionsOnly		= constantExpressionsOnlyI != 0;
9513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				const string	name						= caseTypeName + (constantExpressionsOnly ? "" : "_no_const") + caseShaderTypeSuffix;
9523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				if (caseType == ConstantPropagationCase::CASETYPE_ARRAY && constantExpressionsOnly) // \note See ConstantPropagationCase's constructor for explanation.
9543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					continue;
9553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				constantPropagationGroup->addChild(new ConstantPropagationCase(m_context, name.c_str(), "", caseShaderType, caseType, constantExpressionsOnly));
9573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			}
9583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Common subexpression cases.
9613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int caseTypeI = 0; caseTypeI < CommonSubexpressionCase::CASETYPE_LAST; caseTypeI++)
9633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const CommonSubexpressionCase::CaseType		caseType		= (CommonSubexpressionCase::CaseType)caseTypeI;
9653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string								caseTypeName	= caseType == CommonSubexpressionCase::CASETYPE_SINGLE_STATEMENT		? "single_statement"
9673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		: caseType == CommonSubexpressionCase::CASETYPE_MULTIPLE_STATEMENTS		? "multiple_statements"
9683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		: caseType == CommonSubexpressionCase::CASETYPE_STATIC_BRANCH			? "static_branch"
9693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		: caseType == CommonSubexpressionCase::CASETYPE_LOOP					? "loop"
9703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		: DE_NULL;
9713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const string								description		= caseType == CommonSubexpressionCase::CASETYPE_SINGLE_STATEMENT		? "A single statement containing multiple uses of same subexpression"
9733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		: caseType == CommonSubexpressionCase::CASETYPE_MULTIPLE_STATEMENTS		? "Multiple statements performing same computations"
9743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		: caseType == CommonSubexpressionCase::CASETYPE_STATIC_BRANCH			? "Multiple statements including a static conditional"
9753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		: caseType == CommonSubexpressionCase::CASETYPE_LOOP					? "Multiple loops performing the same computations"
9763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																		: DE_NULL;
9773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			commonSubexpressionGroup->addChild(new CommonSubexpressionCase(m_context, (caseTypeName + caseShaderTypeSuffix).c_str(), description.c_str(), caseShaderType, caseType));
9793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
9803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// Dead code elimination cases.
9823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		for (int caseTypeI = 0; caseTypeI < DeadCodeEliminationCase::CASETYPE_LAST; caseTypeI++)
9843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
9853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const DeadCodeEliminationCase::CaseType		caseType				= (DeadCodeEliminationCase::CaseType)caseTypeI;
9863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char* const							caseTypeName			= caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_SIMPLE				? "dead_branch_simple"
9873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				: caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_COMPLEX				? "dead_branch_complex"
9883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				: caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_COMPLEX_NO_CONST	? "dead_branch_complex_no_const"
9893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				: caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_FUNC_CALL			? "dead_branch_func_call"
9903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_BASIC				? "unused_value_basic"
9913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_LOOP				? "unused_value_loop"
9923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_DEAD_BRANCH		? "unused_value_dead_branch"
9933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_AFTER_RETURN		? "unused_value_after_return"
9943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_MUL_ZERO			? "unused_value_mul_zero"
9953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				: DE_NULL;
9963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
9973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			const char* const							caseTypeDescription		= caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_SIMPLE				? "Do computation inside a branch that is never taken (condition is simple false constant expression)"
9983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				: caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_COMPLEX				? "Do computation inside a branch that is never taken (condition is complex false constant expression)"
9993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				: caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_COMPLEX_NO_CONST	? "Do computation inside a branch that is never taken (condition is complex false expression, not constant expression but still compile-time computable)"
10003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				: caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_FUNC_CALL			? "Do computation inside a branch that is never taken (condition is compile-time computable false expression containing function call to a simple inlineable function)"
10013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_BASIC				? "Compute a value that is never used even statically"
10023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_LOOP				? "Compute a value, using a loop, that is never used even statically"
10033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_DEAD_BRANCH		? "Compute a value that is used only inside a statically dead branch"
10043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_AFTER_RETURN		? "Compute a value that is used only after a return statement"
10053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				: caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_MUL_ZERO			? "Compute a value that is used but multiplied by a zero constant expression"
10063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry																				: DE_NULL;
10073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			deadCodeEliminationGroup->addChild(new DeadCodeEliminationCase(m_context, (string() + caseTypeName + caseShaderTypeSuffix).c_str(), caseTypeDescription, caseShaderType, caseType));
10093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
10103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
10113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
10123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
10133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // Performance
10143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // gles2
10153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // deqp
1016