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