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