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