xref: /aosp_15_r20/external/deqp/modules/gles2/performance/es2pShaderOptimizationTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 2.0 Module
3*35238bceSAndroid Build Coastguard Worker  * -------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Optimized vs unoptimized shader performance tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es2pShaderOptimizationTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "glsShaderPerformanceMeasurer.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuVector.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "deSharedPtr.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "deMath.h"
34*35238bceSAndroid Build Coastguard Worker 
35*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
36*35238bceSAndroid Build Coastguard Worker 
37*35238bceSAndroid Build Coastguard Worker #include <vector>
38*35238bceSAndroid Build Coastguard Worker #include <string>
39*35238bceSAndroid Build Coastguard Worker #include <map>
40*35238bceSAndroid Build Coastguard Worker 
41*35238bceSAndroid Build Coastguard Worker using de::SharedPtr;
42*35238bceSAndroid Build Coastguard Worker using de::toString;
43*35238bceSAndroid Build Coastguard Worker using glu::ShaderProgram;
44*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
45*35238bceSAndroid Build Coastguard Worker using tcu::Vec4;
46*35238bceSAndroid Build Coastguard Worker 
47*35238bceSAndroid Build Coastguard Worker using std::string;
48*35238bceSAndroid Build Coastguard Worker using std::vector;
49*35238bceSAndroid Build Coastguard Worker 
50*35238bceSAndroid Build Coastguard Worker namespace deqp
51*35238bceSAndroid Build Coastguard Worker {
52*35238bceSAndroid Build Coastguard Worker 
53*35238bceSAndroid Build Coastguard Worker using gls::ShaderPerformanceMeasurer;
54*35238bceSAndroid Build Coastguard Worker 
55*35238bceSAndroid Build Coastguard Worker namespace gles2
56*35238bceSAndroid Build Coastguard Worker {
57*35238bceSAndroid Build Coastguard Worker namespace Performance
58*35238bceSAndroid Build Coastguard Worker {
59*35238bceSAndroid Build Coastguard Worker 
singleMap(const string & key,const string & value)60*35238bceSAndroid Build Coastguard Worker static inline std::map<string, string> singleMap(const string &key, const string &value)
61*35238bceSAndroid Build Coastguard Worker {
62*35238bceSAndroid Build Coastguard Worker     std::map<string, string> res;
63*35238bceSAndroid Build Coastguard Worker     res[key] = value;
64*35238bceSAndroid Build Coastguard Worker     return res;
65*35238bceSAndroid Build Coastguard Worker }
66*35238bceSAndroid Build Coastguard Worker 
repeat(const string & str,int numRepeats,const string & delim="")67*35238bceSAndroid Build Coastguard Worker static inline string repeat(const string &str, int numRepeats, const string &delim = "")
68*35238bceSAndroid Build Coastguard Worker {
69*35238bceSAndroid Build Coastguard Worker     string result = str;
70*35238bceSAndroid Build Coastguard Worker     for (int i = 1; i < numRepeats; i++)
71*35238bceSAndroid Build Coastguard Worker         result += delim + str;
72*35238bceSAndroid Build Coastguard Worker     return result;
73*35238bceSAndroid Build Coastguard Worker }
74*35238bceSAndroid Build Coastguard Worker 
repeatIndexedTemplate(const string & strTempl,int numRepeats,const string & delim="",int ndxStart=0)75*35238bceSAndroid Build Coastguard Worker static inline string repeatIndexedTemplate(const string &strTempl, int numRepeats, const string &delim = "",
76*35238bceSAndroid Build Coastguard Worker                                            int ndxStart = 0)
77*35238bceSAndroid Build Coastguard Worker {
78*35238bceSAndroid Build Coastguard Worker     const tcu::StringTemplate templ(strTempl);
79*35238bceSAndroid Build Coastguard Worker     string result;
80*35238bceSAndroid Build Coastguard Worker     std::map<string, string> params;
81*35238bceSAndroid Build Coastguard Worker 
82*35238bceSAndroid Build Coastguard Worker     for (int i = 0; i < numRepeats; i++)
83*35238bceSAndroid Build Coastguard Worker     {
84*35238bceSAndroid Build Coastguard Worker         params["PREV_NDX"] = toString(i + ndxStart - 1);
85*35238bceSAndroid Build Coastguard Worker         params["NDX"]      = toString(i + ndxStart);
86*35238bceSAndroid Build Coastguard Worker 
87*35238bceSAndroid Build Coastguard Worker         result += (i > 0 ? delim : "") + templ.specialize(params);
88*35238bceSAndroid Build Coastguard Worker     }
89*35238bceSAndroid Build Coastguard Worker 
90*35238bceSAndroid Build Coastguard Worker     return result;
91*35238bceSAndroid Build Coastguard Worker }
92*35238bceSAndroid Build Coastguard Worker 
93*35238bceSAndroid Build Coastguard Worker namespace
94*35238bceSAndroid Build Coastguard Worker {
95*35238bceSAndroid Build Coastguard Worker 
96*35238bceSAndroid Build Coastguard Worker enum CaseShaderType
97*35238bceSAndroid Build Coastguard Worker {
98*35238bceSAndroid Build Coastguard Worker     CASESHADERTYPE_VERTEX = 0,
99*35238bceSAndroid Build Coastguard Worker     CASESHADERTYPE_FRAGMENT,
100*35238bceSAndroid Build Coastguard Worker 
101*35238bceSAndroid Build Coastguard Worker     CASESHADERTYPE_LAST
102*35238bceSAndroid Build Coastguard Worker };
103*35238bceSAndroid Build Coastguard Worker 
getShaderPrecision(CaseShaderType shaderType)104*35238bceSAndroid Build Coastguard Worker static inline string getShaderPrecision(CaseShaderType shaderType)
105*35238bceSAndroid Build Coastguard Worker {
106*35238bceSAndroid Build Coastguard Worker     switch (shaderType)
107*35238bceSAndroid Build Coastguard Worker     {
108*35238bceSAndroid Build Coastguard Worker     case CASESHADERTYPE_VERTEX:
109*35238bceSAndroid Build Coastguard Worker         return "highp";
110*35238bceSAndroid Build Coastguard Worker     case CASESHADERTYPE_FRAGMENT:
111*35238bceSAndroid Build Coastguard Worker         return "mediump";
112*35238bceSAndroid Build Coastguard Worker     default:
113*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
114*35238bceSAndroid Build Coastguard Worker         return "";
115*35238bceSAndroid Build Coastguard Worker     }
116*35238bceSAndroid Build Coastguard Worker }
117*35238bceSAndroid Build Coastguard Worker 
118*35238bceSAndroid Build Coastguard Worker struct ProgramData
119*35238bceSAndroid Build Coastguard Worker {
120*35238bceSAndroid Build Coastguard Worker     glu::ProgramSources sources;
121*35238bceSAndroid Build Coastguard Worker     vector<gls::AttribSpec>
122*35238bceSAndroid Build Coastguard Worker         attributes; //!< \note Shouldn't contain a_position; that one is set by gls::ShaderPerformanceMeasurer.
123*35238bceSAndroid Build Coastguard Worker 
ProgramDatadeqp::gles2::Performance::__anon9fd9d6310111::ProgramData124*35238bceSAndroid Build Coastguard Worker     ProgramData(void)
125*35238bceSAndroid Build Coastguard Worker     {
126*35238bceSAndroid Build Coastguard Worker     }
ProgramDatadeqp::gles2::Performance::__anon9fd9d6310111::ProgramData127*35238bceSAndroid Build Coastguard Worker     ProgramData(const glu::ProgramSources &sources_,
128*35238bceSAndroid Build Coastguard Worker                 const vector<gls::AttribSpec> &attributes_ = vector<gls::AttribSpec>())
129*35238bceSAndroid Build Coastguard Worker         : sources(sources_)
130*35238bceSAndroid Build Coastguard Worker         , attributes(attributes_)
131*35238bceSAndroid Build Coastguard Worker     {
132*35238bceSAndroid Build Coastguard Worker     }
ProgramDatadeqp::gles2::Performance::__anon9fd9d6310111::ProgramData133*35238bceSAndroid Build Coastguard Worker     ProgramData(const glu::ProgramSources &sources_, const gls::AttribSpec &attribute)
134*35238bceSAndroid Build Coastguard Worker         : sources(sources_)
135*35238bceSAndroid Build Coastguard Worker         , attributes(1, attribute)
136*35238bceSAndroid Build Coastguard Worker     {
137*35238bceSAndroid Build Coastguard Worker     }
138*35238bceSAndroid Build Coastguard Worker };
139*35238bceSAndroid Build Coastguard Worker 
140*35238bceSAndroid Build Coastguard Worker //! Shader boilerplate helper; most cases have similar basic shader structure.
defaultProgramData(CaseShaderType shaderType,const string & funcDefs,const string & mainStatements)141*35238bceSAndroid Build Coastguard Worker static inline ProgramData defaultProgramData(CaseShaderType shaderType, const string &funcDefs,
142*35238bceSAndroid Build Coastguard Worker                                              const string &mainStatements)
143*35238bceSAndroid Build Coastguard Worker {
144*35238bceSAndroid Build Coastguard Worker     const bool isVertexCase   = shaderType == CASESHADERTYPE_VERTEX;
145*35238bceSAndroid Build Coastguard Worker     const bool isFragmentCase = shaderType == CASESHADERTYPE_FRAGMENT;
146*35238bceSAndroid Build Coastguard Worker     const string vtxPrec      = getShaderPrecision(CASESHADERTYPE_VERTEX);
147*35238bceSAndroid Build Coastguard Worker     const string fragPrec     = getShaderPrecision(CASESHADERTYPE_FRAGMENT);
148*35238bceSAndroid Build Coastguard Worker 
149*35238bceSAndroid Build Coastguard Worker     return ProgramData(glu::ProgramSources()
150*35238bceSAndroid Build Coastguard Worker                            << glu::VertexSource("attribute " + vtxPrec +
151*35238bceSAndroid Build Coastguard Worker                                                 " vec4 a_position;\n"
152*35238bceSAndroid Build Coastguard Worker                                                 "attribute " +
153*35238bceSAndroid Build Coastguard Worker                                                 vtxPrec +
154*35238bceSAndroid Build Coastguard Worker                                                 " vec4 a_value;\n"
155*35238bceSAndroid Build Coastguard Worker                                                 "varying " +
156*35238bceSAndroid Build Coastguard Worker                                                 fragPrec + " vec4 v_value;\n" + (isVertexCase ? funcDefs : "") +
157*35238bceSAndroid Build Coastguard Worker                                                 "void main (void)\n"
158*35238bceSAndroid Build Coastguard Worker                                                 "{\n"
159*35238bceSAndroid Build Coastguard Worker                                                 "    gl_Position = a_position;\n"
160*35238bceSAndroid Build Coastguard Worker                                                 "    " +
161*35238bceSAndroid Build Coastguard Worker                                                 vtxPrec + " vec4 value = a_value;\n" +
162*35238bceSAndroid Build Coastguard Worker                                                 (isVertexCase ? mainStatements : "") +
163*35238bceSAndroid Build Coastguard Worker                                                 "    v_value = value;\n"
164*35238bceSAndroid Build Coastguard Worker                                                 "}\n")
165*35238bceSAndroid Build Coastguard Worker 
166*35238bceSAndroid Build Coastguard Worker                            << glu::FragmentSource(
167*35238bceSAndroid Build Coastguard Worker                                   "varying " + fragPrec + " vec4 v_value;\n" + (isFragmentCase ? funcDefs : "") +
168*35238bceSAndroid Build Coastguard Worker                                   "void main (void)\n"
169*35238bceSAndroid Build Coastguard Worker                                   "{\n"
170*35238bceSAndroid Build Coastguard Worker                                   "    " +
171*35238bceSAndroid Build Coastguard Worker                                   fragPrec + " vec4 value = v_value;\n" + (isFragmentCase ? mainStatements : "") +
172*35238bceSAndroid Build Coastguard Worker                                   "    gl_FragColor = value;\n"
173*35238bceSAndroid Build Coastguard Worker                                   "}\n"),
174*35238bceSAndroid Build Coastguard Worker                        gls::AttribSpec("a_value", Vec4(1.0f, 0.0f, 0.0f, 0.0f), Vec4(0.0f, 1.0f, 0.0f, 0.0f),
175*35238bceSAndroid Build Coastguard Worker                                        Vec4(0.0f, 0.0f, 1.0f, 0.0f), Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
176*35238bceSAndroid Build Coastguard Worker }
177*35238bceSAndroid Build Coastguard Worker 
defaultProgramData(CaseShaderType shaderType,const string & mainStatements)178*35238bceSAndroid Build Coastguard Worker static inline ProgramData defaultProgramData(CaseShaderType shaderType, const string &mainStatements)
179*35238bceSAndroid Build Coastguard Worker {
180*35238bceSAndroid Build Coastguard Worker     return defaultProgramData(shaderType, "", mainStatements);
181*35238bceSAndroid Build Coastguard Worker }
182*35238bceSAndroid Build Coastguard Worker 
183*35238bceSAndroid Build Coastguard Worker class ShaderOptimizationCase : public TestCase
184*35238bceSAndroid Build Coastguard Worker {
185*35238bceSAndroid Build Coastguard Worker public:
ShaderOptimizationCase(Context & context,const char * name,const char * description,CaseShaderType caseShaderType)186*35238bceSAndroid Build Coastguard Worker     ShaderOptimizationCase(Context &context, const char *name, const char *description, CaseShaderType caseShaderType)
187*35238bceSAndroid Build Coastguard Worker         : TestCase(context, tcu::NODETYPE_PERFORMANCE, name, description)
188*35238bceSAndroid Build Coastguard Worker         , m_caseShaderType(caseShaderType)
189*35238bceSAndroid Build Coastguard Worker         , m_state(STATE_LAST)
190*35238bceSAndroid Build Coastguard Worker         , m_measurer(context.getRenderContext(), caseShaderType == CASESHADERTYPE_VERTEX   ? gls::CASETYPE_VERTEX :
191*35238bceSAndroid Build Coastguard Worker                                                  caseShaderType == CASESHADERTYPE_FRAGMENT ? gls::CASETYPE_FRAGMENT :
192*35238bceSAndroid Build Coastguard Worker                                                                                              gls::CASETYPE_LAST)
193*35238bceSAndroid Build Coastguard Worker         , m_unoptimizedResult(-1.0f, -1.0f)
194*35238bceSAndroid Build Coastguard Worker         , m_optimizedResult(-1.0f, -1.0f)
195*35238bceSAndroid Build Coastguard Worker     {
196*35238bceSAndroid Build Coastguard Worker     }
197*35238bceSAndroid Build Coastguard Worker 
~ShaderOptimizationCase(void)198*35238bceSAndroid Build Coastguard Worker     virtual ~ShaderOptimizationCase(void)
199*35238bceSAndroid Build Coastguard Worker     {
200*35238bceSAndroid Build Coastguard Worker     }
201*35238bceSAndroid Build Coastguard Worker 
202*35238bceSAndroid Build Coastguard Worker     void init(void);
203*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
204*35238bceSAndroid Build Coastguard Worker 
205*35238bceSAndroid Build Coastguard Worker protected:
206*35238bceSAndroid Build Coastguard Worker     virtual ProgramData generateProgramData(bool optimized) const = 0;
207*35238bceSAndroid Build Coastguard Worker 
208*35238bceSAndroid Build Coastguard Worker     const CaseShaderType m_caseShaderType;
209*35238bceSAndroid Build Coastguard Worker 
210*35238bceSAndroid Build Coastguard Worker private:
211*35238bceSAndroid Build Coastguard Worker     enum State
212*35238bceSAndroid Build Coastguard Worker     {
213*35238bceSAndroid Build Coastguard Worker         STATE_INIT_UNOPTIMIZED = 0,
214*35238bceSAndroid Build Coastguard Worker         STATE_MEASURE_UNOPTIMIZED,
215*35238bceSAndroid Build Coastguard Worker         STATE_INIT_OPTIMIZED,
216*35238bceSAndroid Build Coastguard Worker         STATE_MEASURE_OPTIMIZED,
217*35238bceSAndroid Build Coastguard Worker         STATE_FINISHED,
218*35238bceSAndroid Build Coastguard Worker 
219*35238bceSAndroid Build Coastguard Worker         STATE_LAST
220*35238bceSAndroid Build Coastguard Worker     };
221*35238bceSAndroid Build Coastguard Worker 
programData(bool optimized)222*35238bceSAndroid Build Coastguard Worker     ProgramData &programData(bool optimized)
223*35238bceSAndroid Build Coastguard Worker     {
224*35238bceSAndroid Build Coastguard Worker         return optimized ? m_optimizedData : m_unoptimizedData;
225*35238bceSAndroid Build Coastguard Worker     }
program(bool optimized)226*35238bceSAndroid Build Coastguard Worker     SharedPtr<const ShaderProgram> &program(bool optimized)
227*35238bceSAndroid Build Coastguard Worker     {
228*35238bceSAndroid Build Coastguard Worker         return optimized ? m_optimizedProgram : m_unoptimizedProgram;
229*35238bceSAndroid Build Coastguard Worker     }
result(bool optimized)230*35238bceSAndroid Build Coastguard Worker     ShaderPerformanceMeasurer::Result &result(bool optimized)
231*35238bceSAndroid Build Coastguard Worker     {
232*35238bceSAndroid Build Coastguard Worker         return optimized ? m_optimizedResult : m_unoptimizedResult;
233*35238bceSAndroid Build Coastguard Worker     }
234*35238bceSAndroid Build Coastguard Worker 
235*35238bceSAndroid Build Coastguard Worker     State m_state;
236*35238bceSAndroid Build Coastguard Worker     ShaderPerformanceMeasurer m_measurer;
237*35238bceSAndroid Build Coastguard Worker 
238*35238bceSAndroid Build Coastguard Worker     ProgramData m_unoptimizedData;
239*35238bceSAndroid Build Coastguard Worker     ProgramData m_optimizedData;
240*35238bceSAndroid Build Coastguard Worker     SharedPtr<const ShaderProgram> m_unoptimizedProgram;
241*35238bceSAndroid Build Coastguard Worker     SharedPtr<const ShaderProgram> m_optimizedProgram;
242*35238bceSAndroid Build Coastguard Worker     ShaderPerformanceMeasurer::Result m_unoptimizedResult;
243*35238bceSAndroid Build Coastguard Worker     ShaderPerformanceMeasurer::Result m_optimizedResult;
244*35238bceSAndroid Build Coastguard Worker };
245*35238bceSAndroid Build Coastguard Worker 
init(void)246*35238bceSAndroid Build Coastguard Worker void ShaderOptimizationCase::init(void)
247*35238bceSAndroid Build Coastguard Worker {
248*35238bceSAndroid Build Coastguard Worker     const glu::RenderContext &renderCtx = m_context.getRenderContext();
249*35238bceSAndroid Build Coastguard Worker     TestLog &log                        = m_testCtx.getLog();
250*35238bceSAndroid Build Coastguard Worker 
251*35238bceSAndroid Build Coastguard Worker     m_measurer.logParameters(log);
252*35238bceSAndroid Build Coastguard Worker 
253*35238bceSAndroid Build Coastguard Worker     for (int ndx = 0; ndx < 2; ndx++)
254*35238bceSAndroid Build Coastguard Worker     {
255*35238bceSAndroid Build Coastguard Worker         const bool optimized = ndx == 1;
256*35238bceSAndroid Build Coastguard Worker 
257*35238bceSAndroid Build Coastguard Worker         programData(optimized) = generateProgramData(optimized);
258*35238bceSAndroid Build Coastguard Worker 
259*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < (int)programData(optimized).attributes.size(); i++)
260*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(programData(optimized).attributes[i].name !=
261*35238bceSAndroid Build Coastguard Worker                       "a_position"); // \note Position attribute is set by m_measurer.
262*35238bceSAndroid Build Coastguard Worker 
263*35238bceSAndroid Build Coastguard Worker         program(optimized) =
264*35238bceSAndroid Build Coastguard Worker             SharedPtr<const ShaderProgram>(new ShaderProgram(renderCtx, programData(optimized).sources));
265*35238bceSAndroid Build Coastguard Worker 
266*35238bceSAndroid Build Coastguard Worker         {
267*35238bceSAndroid Build Coastguard Worker             const tcu::ScopedLogSection section(log, optimized ? "OptimizedProgram" : "UnoptimizedProgram",
268*35238bceSAndroid Build Coastguard Worker                                                 optimized ? "Hand-optimized program" : "Unoptimized program");
269*35238bceSAndroid Build Coastguard Worker             log << *program(optimized);
270*35238bceSAndroid Build Coastguard Worker         }
271*35238bceSAndroid Build Coastguard Worker 
272*35238bceSAndroid Build Coastguard Worker         if (!program(optimized)->isOk())
273*35238bceSAndroid Build Coastguard Worker             TCU_FAIL("Shader compilation failed");
274*35238bceSAndroid Build Coastguard Worker     }
275*35238bceSAndroid Build Coastguard Worker 
276*35238bceSAndroid Build Coastguard Worker     m_state = STATE_INIT_UNOPTIMIZED;
277*35238bceSAndroid Build Coastguard Worker }
278*35238bceSAndroid Build Coastguard Worker 
iterate(void)279*35238bceSAndroid Build Coastguard Worker ShaderOptimizationCase::IterateResult ShaderOptimizationCase::iterate(void)
280*35238bceSAndroid Build Coastguard Worker {
281*35238bceSAndroid Build Coastguard Worker     TestLog &log = m_testCtx.getLog();
282*35238bceSAndroid Build Coastguard Worker 
283*35238bceSAndroid Build Coastguard Worker     if (m_state == STATE_INIT_UNOPTIMIZED || m_state == STATE_INIT_OPTIMIZED)
284*35238bceSAndroid Build Coastguard Worker     {
285*35238bceSAndroid Build Coastguard Worker         const bool optimized = m_state == STATE_INIT_OPTIMIZED;
286*35238bceSAndroid Build Coastguard Worker         m_measurer.init(program(optimized)->getProgram(), programData(optimized).attributes, 1);
287*35238bceSAndroid Build Coastguard Worker         m_state = optimized ? STATE_MEASURE_OPTIMIZED : STATE_MEASURE_UNOPTIMIZED;
288*35238bceSAndroid Build Coastguard Worker 
289*35238bceSAndroid Build Coastguard Worker         return CONTINUE;
290*35238bceSAndroid Build Coastguard Worker     }
291*35238bceSAndroid Build Coastguard Worker     else if (m_state == STATE_MEASURE_UNOPTIMIZED || m_state == STATE_MEASURE_OPTIMIZED)
292*35238bceSAndroid Build Coastguard Worker     {
293*35238bceSAndroid Build Coastguard Worker         m_measurer.iterate();
294*35238bceSAndroid Build Coastguard Worker 
295*35238bceSAndroid Build Coastguard Worker         if (m_measurer.isFinished())
296*35238bceSAndroid Build Coastguard Worker         {
297*35238bceSAndroid Build Coastguard Worker             const bool optimized = m_state == STATE_MEASURE_OPTIMIZED;
298*35238bceSAndroid Build Coastguard Worker             const tcu::ScopedLogSection section(log, optimized ? "OptimizedResult" : "UnoptimizedResult",
299*35238bceSAndroid Build Coastguard Worker                                                 optimized ? "Measurement results for hand-optimized program" :
300*35238bceSAndroid Build Coastguard Worker                                                             "Measurement result for unoptimized program");
301*35238bceSAndroid Build Coastguard Worker             m_measurer.logMeasurementInfo(log);
302*35238bceSAndroid Build Coastguard Worker             result(optimized) = m_measurer.getResult();
303*35238bceSAndroid Build Coastguard Worker             m_measurer.deinit();
304*35238bceSAndroid Build Coastguard Worker             m_state = optimized ? STATE_FINISHED : STATE_INIT_OPTIMIZED;
305*35238bceSAndroid Build Coastguard Worker         }
306*35238bceSAndroid Build Coastguard Worker 
307*35238bceSAndroid Build Coastguard Worker         return CONTINUE;
308*35238bceSAndroid Build Coastguard Worker     }
309*35238bceSAndroid Build Coastguard Worker     else
310*35238bceSAndroid Build Coastguard Worker     {
311*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_state == STATE_FINISHED);
312*35238bceSAndroid Build Coastguard Worker 
313*35238bceSAndroid Build Coastguard Worker         const float unoptimizedRelevantResult = m_caseShaderType == CASESHADERTYPE_VERTEX ?
314*35238bceSAndroid Build Coastguard Worker                                                     m_unoptimizedResult.megaVertPerSec :
315*35238bceSAndroid Build Coastguard Worker                                                     m_unoptimizedResult.megaFragPerSec;
316*35238bceSAndroid Build Coastguard Worker         const float optimizedRelevantResult   = m_caseShaderType == CASESHADERTYPE_VERTEX ?
317*35238bceSAndroid Build Coastguard Worker                                                     m_optimizedResult.megaVertPerSec :
318*35238bceSAndroid Build Coastguard Worker                                                     m_optimizedResult.megaFragPerSec;
319*35238bceSAndroid Build Coastguard Worker         const char *const relevantResultName  = m_caseShaderType == CASESHADERTYPE_VERTEX ? "vertex" : "fragment";
320*35238bceSAndroid Build Coastguard Worker         const float ratio                     = unoptimizedRelevantResult / optimizedRelevantResult;
321*35238bceSAndroid Build Coastguard Worker         const int handOptimizationGain        = (int)deFloatRound(100.0f / ratio) - 100;
322*35238bceSAndroid Build Coastguard Worker 
323*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Unoptimized / optimized " << relevantResultName << " performance ratio: " << ratio
324*35238bceSAndroid Build Coastguard Worker             << TestLog::EndMessage;
325*35238bceSAndroid Build Coastguard Worker 
326*35238bceSAndroid Build Coastguard Worker         if (handOptimizationGain >= 0)
327*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "Note: " << handOptimizationGain
328*35238bceSAndroid Build Coastguard Worker                 << "% performance gain was achieved with hand-optimized version" << TestLog::EndMessage;
329*35238bceSAndroid Build Coastguard Worker         else
330*35238bceSAndroid Build Coastguard Worker             log << TestLog::Message << "Note: hand-optimization degraded performance by " << -handOptimizationGain
331*35238bceSAndroid Build Coastguard Worker                 << "%" << TestLog::EndMessage;
332*35238bceSAndroid Build Coastguard Worker 
333*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::floatToString(ratio, 2).c_str());
334*35238bceSAndroid Build Coastguard Worker 
335*35238bceSAndroid Build Coastguard Worker         return STOP;
336*35238bceSAndroid Build Coastguard Worker     }
337*35238bceSAndroid Build Coastguard Worker }
338*35238bceSAndroid Build Coastguard Worker 
339*35238bceSAndroid Build Coastguard Worker class LoopUnrollCase : public ShaderOptimizationCase
340*35238bceSAndroid Build Coastguard Worker {
341*35238bceSAndroid Build Coastguard Worker public:
342*35238bceSAndroid Build Coastguard Worker     enum CaseType
343*35238bceSAndroid Build Coastguard Worker     {
344*35238bceSAndroid Build Coastguard Worker         CASETYPE_INDEPENDENT = 0,
345*35238bceSAndroid Build Coastguard Worker         CASETYPE_DEPENDENT,
346*35238bceSAndroid Build Coastguard Worker 
347*35238bceSAndroid Build Coastguard Worker         CASETYPE_LAST
348*35238bceSAndroid Build Coastguard Worker     };
349*35238bceSAndroid Build Coastguard Worker 
LoopUnrollCase(Context & context,const char * name,const char * description,CaseShaderType caseShaderType,CaseType caseType,int numRepetitions)350*35238bceSAndroid Build Coastguard Worker     LoopUnrollCase(Context &context, const char *name, const char *description, CaseShaderType caseShaderType,
351*35238bceSAndroid Build Coastguard Worker                    CaseType caseType, int numRepetitions)
352*35238bceSAndroid Build Coastguard Worker         : ShaderOptimizationCase(context, name, description, caseShaderType)
353*35238bceSAndroid Build Coastguard Worker         , m_numRepetitions(numRepetitions)
354*35238bceSAndroid Build Coastguard Worker         , m_caseType(caseType)
355*35238bceSAndroid Build Coastguard Worker     {
356*35238bceSAndroid Build Coastguard Worker     }
357*35238bceSAndroid Build Coastguard Worker 
358*35238bceSAndroid Build Coastguard Worker protected:
generateProgramData(bool optimized) const359*35238bceSAndroid Build Coastguard Worker     ProgramData generateProgramData(bool optimized) const
360*35238bceSAndroid Build Coastguard Worker     {
361*35238bceSAndroid Build Coastguard Worker         const string repetition =
362*35238bceSAndroid Build Coastguard Worker             optimized ? repeatIndexedTemplate("\t" + expressionTemplate(m_caseType) + ";\n", m_numRepetitions) :
363*35238bceSAndroid Build Coastguard Worker                         loop(m_numRepetitions, expressionTemplate(m_caseType));
364*35238bceSAndroid Build Coastguard Worker 
365*35238bceSAndroid Build Coastguard Worker         return defaultProgramData(m_caseShaderType, "\t" + getShaderPrecision(m_caseShaderType) +
366*35238bceSAndroid Build Coastguard Worker                                                         " vec4 valueOrig = value;\n" + repetition);
367*35238bceSAndroid Build Coastguard Worker     }
368*35238bceSAndroid Build Coastguard Worker 
369*35238bceSAndroid Build Coastguard Worker private:
370*35238bceSAndroid Build Coastguard Worker     const int m_numRepetitions;
371*35238bceSAndroid Build Coastguard Worker     const CaseType m_caseType;
372*35238bceSAndroid Build Coastguard Worker 
expressionTemplate(CaseType caseType)373*35238bceSAndroid Build Coastguard Worker     static inline string expressionTemplate(CaseType caseType)
374*35238bceSAndroid Build Coastguard Worker     {
375*35238bceSAndroid Build Coastguard Worker         switch (caseType)
376*35238bceSAndroid Build Coastguard Worker         {
377*35238bceSAndroid Build Coastguard Worker         case CASETYPE_INDEPENDENT:
378*35238bceSAndroid Build Coastguard Worker             return "value += sin(float(${NDX}+1)*valueOrig)";
379*35238bceSAndroid Build Coastguard Worker         case CASETYPE_DEPENDENT:
380*35238bceSAndroid Build Coastguard Worker             return "value = sin(value)";
381*35238bceSAndroid Build Coastguard Worker         default:
382*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(false);
383*35238bceSAndroid Build Coastguard Worker             return "";
384*35238bceSAndroid Build Coastguard Worker         }
385*35238bceSAndroid Build Coastguard Worker     }
386*35238bceSAndroid Build Coastguard Worker 
loop(int iterations,const string & innerExpr)387*35238bceSAndroid Build Coastguard Worker     static inline string loop(int iterations, const string &innerExpr)
388*35238bceSAndroid Build Coastguard Worker     {
389*35238bceSAndroid Build Coastguard Worker         return "\tfor (int i = 0; i < " + toString(iterations) + "; i++)\n\t\t" +
390*35238bceSAndroid Build Coastguard Worker                tcu::StringTemplate(innerExpr).specialize(singleMap("NDX", "i")) + ";\n";
391*35238bceSAndroid Build Coastguard Worker     }
392*35238bceSAndroid Build Coastguard Worker };
393*35238bceSAndroid Build Coastguard Worker 
394*35238bceSAndroid Build Coastguard Worker class LoopInvariantCodeMotionCase : public ShaderOptimizationCase
395*35238bceSAndroid Build Coastguard Worker {
396*35238bceSAndroid Build Coastguard Worker public:
LoopInvariantCodeMotionCase(Context & context,const char * name,const char * description,CaseShaderType caseShaderType,int numLoopIterations)397*35238bceSAndroid Build Coastguard Worker     LoopInvariantCodeMotionCase(Context &context, const char *name, const char *description,
398*35238bceSAndroid Build Coastguard Worker                                 CaseShaderType caseShaderType, int numLoopIterations)
399*35238bceSAndroid Build Coastguard Worker         : ShaderOptimizationCase(context, name, description, caseShaderType)
400*35238bceSAndroid Build Coastguard Worker         , m_numLoopIterations(numLoopIterations)
401*35238bceSAndroid Build Coastguard Worker     {
402*35238bceSAndroid Build Coastguard Worker     }
403*35238bceSAndroid Build Coastguard Worker 
404*35238bceSAndroid Build Coastguard Worker protected:
generateProgramData(bool optimized) const405*35238bceSAndroid Build Coastguard Worker     ProgramData generateProgramData(bool optimized) const
406*35238bceSAndroid Build Coastguard Worker     {
407*35238bceSAndroid Build Coastguard Worker         float scale = 0.0f;
408*35238bceSAndroid Build Coastguard Worker         for (int i = 0; i < m_numLoopIterations; i++)
409*35238bceSAndroid Build Coastguard Worker             scale += 3.2f * (float)i + 4.6f;
410*35238bceSAndroid Build Coastguard Worker         scale = 1.0f / scale;
411*35238bceSAndroid Build Coastguard Worker 
412*35238bceSAndroid Build Coastguard Worker         const string precision  = getShaderPrecision(m_caseShaderType);
413*35238bceSAndroid Build Coastguard Worker         const string statements = optimized ? "    " + precision +
414*35238bceSAndroid Build Coastguard Worker                                                   " vec4 valueOrig = value;\n"
415*35238bceSAndroid Build Coastguard Worker                                                   "    " +
416*35238bceSAndroid Build Coastguard Worker                                                   precision +
417*35238bceSAndroid Build Coastguard Worker                                                   " vec4 y = sin(cos(sin(valueOrig)));\n"
418*35238bceSAndroid Build Coastguard Worker                                                   "    for (int i = 0; i < " +
419*35238bceSAndroid Build Coastguard Worker                                                   toString(m_numLoopIterations) +
420*35238bceSAndroid Build Coastguard Worker                                                   "; i++)\n"
421*35238bceSAndroid Build Coastguard Worker                                                   "    {\n"
422*35238bceSAndroid Build Coastguard Worker                                                   "        " +
423*35238bceSAndroid Build Coastguard Worker                                                   precision +
424*35238bceSAndroid Build Coastguard Worker                                                   " float x = 3.2*float(i) + 4.6;\n"
425*35238bceSAndroid Build Coastguard Worker                                                   "        value += x*y;\n"
426*35238bceSAndroid Build Coastguard Worker                                                   "    }\n"
427*35238bceSAndroid Build Coastguard Worker                                                   "    value *= " +
428*35238bceSAndroid Build Coastguard Worker                                                   toString(scale) + ";\n"
429*35238bceSAndroid Build Coastguard Worker 
430*35238bceSAndroid Build Coastguard Worker                                               :
431*35238bceSAndroid Build Coastguard Worker                                               "    " + precision +
432*35238bceSAndroid Build Coastguard Worker                                                   " vec4 valueOrig = value;\n"
433*35238bceSAndroid Build Coastguard Worker                                                   "    for (int i = 0; i < " +
434*35238bceSAndroid Build Coastguard Worker                                                   toString(m_numLoopIterations) +
435*35238bceSAndroid Build Coastguard Worker                                                   "; i++)\n"
436*35238bceSAndroid Build Coastguard Worker                                                   "    {\n"
437*35238bceSAndroid Build Coastguard Worker                                                   "        " +
438*35238bceSAndroid Build Coastguard Worker                                                   precision +
439*35238bceSAndroid Build Coastguard Worker                                                   " float x = 3.2*float(i) + 4.6;\n"
440*35238bceSAndroid Build Coastguard Worker                                                   "        " +
441*35238bceSAndroid Build Coastguard Worker                                                   precision +
442*35238bceSAndroid Build Coastguard Worker                                                   " vec4 y = sin(cos(sin(valueOrig)));\n"
443*35238bceSAndroid Build Coastguard Worker                                                   "        value += x*y;\n"
444*35238bceSAndroid Build Coastguard Worker                                                   "    }\n"
445*35238bceSAndroid Build Coastguard Worker                                                   "    value *= " +
446*35238bceSAndroid Build Coastguard Worker                                                   toString(scale) + ";\n";
447*35238bceSAndroid Build Coastguard Worker 
448*35238bceSAndroid Build Coastguard Worker         return defaultProgramData(m_caseShaderType, statements);
449*35238bceSAndroid Build Coastguard Worker     }
450*35238bceSAndroid Build Coastguard Worker 
451*35238bceSAndroid Build Coastguard Worker private:
452*35238bceSAndroid Build Coastguard Worker     const int m_numLoopIterations;
453*35238bceSAndroid Build Coastguard Worker };
454*35238bceSAndroid Build Coastguard Worker 
455*35238bceSAndroid Build Coastguard Worker class FunctionInliningCase : public ShaderOptimizationCase
456*35238bceSAndroid Build Coastguard Worker {
457*35238bceSAndroid Build Coastguard Worker public:
FunctionInliningCase(Context & context,const char * name,const char * description,CaseShaderType caseShaderType,int callNestingDepth)458*35238bceSAndroid Build Coastguard Worker     FunctionInliningCase(Context &context, const char *name, const char *description, CaseShaderType caseShaderType,
459*35238bceSAndroid Build Coastguard Worker                          int callNestingDepth)
460*35238bceSAndroid Build Coastguard Worker         : ShaderOptimizationCase(context, name, description, caseShaderType)
461*35238bceSAndroid Build Coastguard Worker         , m_callNestingDepth(callNestingDepth)
462*35238bceSAndroid Build Coastguard Worker     {
463*35238bceSAndroid Build Coastguard Worker     }
464*35238bceSAndroid Build Coastguard Worker 
465*35238bceSAndroid Build Coastguard Worker protected:
generateProgramData(bool optimized) const466*35238bceSAndroid Build Coastguard Worker     ProgramData generateProgramData(bool optimized) const
467*35238bceSAndroid Build Coastguard Worker     {
468*35238bceSAndroid Build Coastguard Worker         const string precision     = getShaderPrecision(m_caseShaderType);
469*35238bceSAndroid Build Coastguard Worker         const string expression    = "value*vec4(0.8, 0.7, 0.6, 0.9)";
470*35238bceSAndroid Build Coastguard Worker         const string maybeFuncDefs = optimized ? "" : funcDefinitions(m_callNestingDepth, precision, expression);
471*35238bceSAndroid Build Coastguard Worker         const string mainValueStatement =
472*35238bceSAndroid Build Coastguard Worker             (optimized ? "\tvalue = " + expression : "\tvalue = func" + toString(m_callNestingDepth - 1) + "(value)") +
473*35238bceSAndroid Build Coastguard Worker             ";\n";
474*35238bceSAndroid Build Coastguard Worker 
475*35238bceSAndroid Build Coastguard Worker         return defaultProgramData(m_caseShaderType, maybeFuncDefs, mainValueStatement);
476*35238bceSAndroid Build Coastguard Worker     }
477*35238bceSAndroid Build Coastguard Worker 
478*35238bceSAndroid Build Coastguard Worker private:
479*35238bceSAndroid Build Coastguard Worker     const int m_callNestingDepth;
480*35238bceSAndroid Build Coastguard Worker 
funcDefinitions(int callNestingDepth,const string & precision,const string & expression)481*35238bceSAndroid Build Coastguard Worker     static inline string funcDefinitions(int callNestingDepth, const string &precision, const string &expression)
482*35238bceSAndroid Build Coastguard Worker     {
483*35238bceSAndroid Build Coastguard Worker         string result = precision + " vec4 func0 (" + precision + " vec4 value) { return " + expression + "; }\n";
484*35238bceSAndroid Build Coastguard Worker 
485*35238bceSAndroid Build Coastguard Worker         for (int i = 1; i < callNestingDepth; i++)
486*35238bceSAndroid Build Coastguard Worker             result += precision + " vec4 func" + toString(i) + " (" + precision + " vec4 v) { return func" +
487*35238bceSAndroid Build Coastguard Worker                       toString(i - 1) + "(v); }\n";
488*35238bceSAndroid Build Coastguard Worker 
489*35238bceSAndroid Build Coastguard Worker         return result;
490*35238bceSAndroid Build Coastguard Worker     }
491*35238bceSAndroid Build Coastguard Worker };
492*35238bceSAndroid Build Coastguard Worker 
493*35238bceSAndroid Build Coastguard Worker class ConstantPropagationCase : public ShaderOptimizationCase
494*35238bceSAndroid Build Coastguard Worker {
495*35238bceSAndroid Build Coastguard Worker public:
496*35238bceSAndroid Build Coastguard Worker     enum CaseType
497*35238bceSAndroid Build Coastguard Worker     {
498*35238bceSAndroid Build Coastguard Worker         CASETYPE_BUILT_IN_FUNCTIONS = 0,
499*35238bceSAndroid Build Coastguard Worker         CASETYPE_ARRAY,
500*35238bceSAndroid Build Coastguard Worker         CASETYPE_STRUCT,
501*35238bceSAndroid Build Coastguard Worker 
502*35238bceSAndroid Build Coastguard Worker         CASETYPE_LAST
503*35238bceSAndroid Build Coastguard Worker     };
504*35238bceSAndroid Build Coastguard Worker 
ConstantPropagationCase(Context & context,const char * name,const char * description,CaseShaderType caseShaderType,CaseType caseType,bool useConstantExpressionsOnly)505*35238bceSAndroid Build Coastguard Worker     ConstantPropagationCase(Context &context, const char *name, const char *description, CaseShaderType caseShaderType,
506*35238bceSAndroid Build Coastguard Worker                             CaseType caseType, bool useConstantExpressionsOnly)
507*35238bceSAndroid Build Coastguard Worker         : ShaderOptimizationCase(context, name, description, caseShaderType)
508*35238bceSAndroid Build Coastguard Worker         , m_caseType(caseType)
509*35238bceSAndroid Build Coastguard Worker         , m_useConstantExpressionsOnly(useConstantExpressionsOnly)
510*35238bceSAndroid Build Coastguard Worker     {
511*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(
512*35238bceSAndroid Build Coastguard Worker             !(m_caseType == CASETYPE_ARRAY &&
513*35238bceSAndroid Build Coastguard Worker               m_useConstantExpressionsOnly)); // \note Would need array constructors, which GLSL ES 1 doesn't have.
514*35238bceSAndroid Build Coastguard Worker     }
515*35238bceSAndroid Build Coastguard Worker 
516*35238bceSAndroid Build Coastguard Worker protected:
generateProgramData(bool optimized) const517*35238bceSAndroid Build Coastguard Worker     ProgramData generateProgramData(bool optimized) const
518*35238bceSAndroid Build Coastguard Worker     {
519*35238bceSAndroid Build Coastguard Worker         const bool isVertexCase = m_caseShaderType == CASESHADERTYPE_VERTEX;
520*35238bceSAndroid Build Coastguard Worker         const string precision  = getShaderPrecision(m_caseShaderType);
521*35238bceSAndroid Build Coastguard Worker         const string statements =
522*35238bceSAndroid Build Coastguard Worker             m_caseType == CASETYPE_BUILT_IN_FUNCTIONS ?
523*35238bceSAndroid Build Coastguard Worker                 builtinFunctionsCaseStatements(optimized, m_useConstantExpressionsOnly, precision, isVertexCase) :
524*35238bceSAndroid Build Coastguard Worker             m_caseType == CASETYPE_ARRAY ?
525*35238bceSAndroid Build Coastguard Worker                 arrayCaseStatements(optimized, precision, isVertexCase) :
526*35238bceSAndroid Build Coastguard Worker             m_caseType == CASETYPE_STRUCT ?
527*35238bceSAndroid Build Coastguard Worker                 structCaseStatements(optimized, m_useConstantExpressionsOnly, precision, isVertexCase) :
528*35238bceSAndroid Build Coastguard Worker                 deFatalStr("Invalid CaseType");
529*35238bceSAndroid Build Coastguard Worker 
530*35238bceSAndroid Build Coastguard Worker         return defaultProgramData(m_caseShaderType, statements);
531*35238bceSAndroid Build Coastguard Worker     }
532*35238bceSAndroid Build Coastguard Worker 
533*35238bceSAndroid Build Coastguard Worker private:
534*35238bceSAndroid Build Coastguard Worker     const CaseType m_caseType;
535*35238bceSAndroid Build Coastguard Worker     const bool m_useConstantExpressionsOnly;
536*35238bceSAndroid Build Coastguard Worker 
builtinFunctionsCaseStatements(bool optimized,bool constantExpressionsOnly,const string & precision,bool useHeavierWorkload)537*35238bceSAndroid Build Coastguard Worker     static inline string builtinFunctionsCaseStatements(bool optimized, bool constantExpressionsOnly,
538*35238bceSAndroid Build Coastguard Worker                                                         const string &precision, bool useHeavierWorkload)
539*35238bceSAndroid Build Coastguard Worker     {
540*35238bceSAndroid Build Coastguard Worker         const string constMaybe = constantExpressionsOnly ? "const " : "";
541*35238bceSAndroid Build Coastguard Worker         const int numSinRows    = useHeavierWorkload ? 12 : 1;
542*35238bceSAndroid Build Coastguard Worker 
543*35238bceSAndroid Build Coastguard Worker         return optimized ? "    value = vec4(0.4, 0.5, 0.6, 0.7) * value; // NOTE: factor doesn't necessarily match "
544*35238bceSAndroid Build Coastguard Worker                            "the one in unoptimized shader, but shouldn't make a difference performance-wise\n"
545*35238bceSAndroid Build Coastguard Worker 
546*35238bceSAndroid Build Coastguard Worker                            :
547*35238bceSAndroid Build Coastguard Worker                            "    " + constMaybe + precision +
548*35238bceSAndroid Build Coastguard Worker                                " vec4 a = vec4(sin(0.7), cos(0.2), sin(0.9), abs(-0.5));\n"
549*35238bceSAndroid Build Coastguard Worker                                "    " +
550*35238bceSAndroid Build Coastguard Worker                                constMaybe + precision +
551*35238bceSAndroid Build Coastguard Worker                                " vec4 b = cos(a) + fract(3.0*a.xzzw);\n"
552*35238bceSAndroid Build Coastguard Worker                                "    " +
553*35238bceSAndroid Build Coastguard Worker                                constMaybe +
554*35238bceSAndroid Build Coastguard Worker                                "bvec4 c = bvec4(true, false, true, true);\n"
555*35238bceSAndroid Build Coastguard Worker                                "    " +
556*35238bceSAndroid Build Coastguard Worker                                constMaybe + precision +
557*35238bceSAndroid Build Coastguard Worker                                " vec4 d = exp(b + vec4(c));\n"
558*35238bceSAndroid Build Coastguard Worker                                "    " +
559*35238bceSAndroid Build Coastguard Worker                                constMaybe + precision + " vec4 e0 = inversesqrt(mix(d+a, d+b, a));\n" +
560*35238bceSAndroid Build Coastguard Worker                                repeatIndexedTemplate("    " + constMaybe + precision +
561*35238bceSAndroid Build Coastguard Worker                                                          " vec4 e${NDX} = sin(sin(sin(sin(e${PREV_NDX}))));\n",
562*35238bceSAndroid Build Coastguard Worker                                                      numSinRows, "", 1) +
563*35238bceSAndroid Build Coastguard Worker                                "    " + constMaybe + precision + " vec4 f = abs(e" + toString(numSinRows) + ");\n" +
564*35238bceSAndroid Build Coastguard Worker                                "    value = f*value;\n";
565*35238bceSAndroid Build Coastguard Worker     }
566*35238bceSAndroid Build Coastguard Worker 
arrayCaseStatements(bool optimized,const string & precision,bool useHeavierWorkload)567*35238bceSAndroid Build Coastguard Worker     static inline string arrayCaseStatements(bool optimized, const string &precision, bool useHeavierWorkload)
568*35238bceSAndroid Build Coastguard Worker     {
569*35238bceSAndroid Build Coastguard Worker         const int numSinRows = useHeavierWorkload ? 12 : 1;
570*35238bceSAndroid Build Coastguard Worker 
571*35238bceSAndroid Build Coastguard Worker         return optimized ?
572*35238bceSAndroid Build Coastguard Worker                    "    value = vec4(0.4, 0.5, 0.6, 0.7) * value; // NOTE: factor doesn't necessarily match the one in "
573*35238bceSAndroid Build Coastguard Worker                    "unoptimized shader, but shouldn't make a difference performance-wise\n"
574*35238bceSAndroid Build Coastguard Worker 
575*35238bceSAndroid Build Coastguard Worker                    :
576*35238bceSAndroid Build Coastguard Worker                    "    const int arrLen = 4;\n"
577*35238bceSAndroid Build Coastguard Worker                    "    " +
578*35238bceSAndroid Build Coastguard Worker                        precision +
579*35238bceSAndroid Build Coastguard Worker                        " vec4 arr[arrLen];\n"
580*35238bceSAndroid Build Coastguard Worker                        "    arr[0] = vec4(0.1, 0.5, 0.9, 1.3);\n"
581*35238bceSAndroid Build Coastguard Worker                        "    arr[1] = vec4(0.2, 0.6, 1.0, 1.4);\n"
582*35238bceSAndroid Build Coastguard Worker                        "    arr[2] = vec4(0.3, 0.7, 1.1, 1.5);\n"
583*35238bceSAndroid Build Coastguard Worker                        "    arr[3] = vec4(0.4, 0.8, 1.2, 1.6);\n"
584*35238bceSAndroid Build Coastguard Worker                        "    " +
585*35238bceSAndroid Build Coastguard Worker                        precision +
586*35238bceSAndroid Build Coastguard Worker                        " vec4 a = (arr[0] + arr[1] + arr[2] + arr[3]) * 0.25;\n"
587*35238bceSAndroid Build Coastguard Worker                        "    " +
588*35238bceSAndroid Build Coastguard Worker                        precision + " vec4 b0 = cos(sin(a));\n" +
589*35238bceSAndroid Build Coastguard Worker                        repeatIndexedTemplate("    " + precision + " vec4 b${NDX} = sin(sin(sin(sin(b${PREV_NDX}))));\n",
590*35238bceSAndroid Build Coastguard Worker                                              numSinRows, "", 1) +
591*35238bceSAndroid Build Coastguard Worker                        "    " + precision + " vec4 c = abs(b" + toString(numSinRows) + ");\n" +
592*35238bceSAndroid Build Coastguard Worker                        "    value = c*value;\n";
593*35238bceSAndroid Build Coastguard Worker     }
594*35238bceSAndroid Build Coastguard Worker 
structCaseStatements(bool optimized,bool constantExpressionsOnly,const string & precision,bool useHeavierWorkload)595*35238bceSAndroid Build Coastguard Worker     static inline string structCaseStatements(bool optimized, bool constantExpressionsOnly, const string &precision,
596*35238bceSAndroid Build Coastguard Worker                                               bool useHeavierWorkload)
597*35238bceSAndroid Build Coastguard Worker     {
598*35238bceSAndroid Build Coastguard Worker         const string constMaybe = constantExpressionsOnly ? "const " : "";
599*35238bceSAndroid Build Coastguard Worker         const int numSinRows    = useHeavierWorkload ? 12 : 1;
600*35238bceSAndroid Build Coastguard Worker 
601*35238bceSAndroid Build Coastguard Worker         return optimized ? "    value = vec4(0.4, 0.5, 0.6, 0.7) * value; // NOTE: factor doesn't necessarily match "
602*35238bceSAndroid Build Coastguard Worker                            "the one in unoptimized shader, but shouldn't make a difference performance-wise\n"
603*35238bceSAndroid Build Coastguard Worker 
604*35238bceSAndroid Build Coastguard Worker                            :
605*35238bceSAndroid Build Coastguard Worker                            "    struct S\n"
606*35238bceSAndroid Build Coastguard Worker                            "    {\n"
607*35238bceSAndroid Build Coastguard Worker                            "        " +
608*35238bceSAndroid Build Coastguard Worker                                precision +
609*35238bceSAndroid Build Coastguard Worker                                " vec4 a;\n"
610*35238bceSAndroid Build Coastguard Worker                                "        " +
611*35238bceSAndroid Build Coastguard Worker                                precision +
612*35238bceSAndroid Build Coastguard Worker                                " vec4 b;\n"
613*35238bceSAndroid Build Coastguard Worker                                "        " +
614*35238bceSAndroid Build Coastguard Worker                                precision +
615*35238bceSAndroid Build Coastguard Worker                                " vec4 c;\n"
616*35238bceSAndroid Build Coastguard Worker                                "        " +
617*35238bceSAndroid Build Coastguard Worker                                precision +
618*35238bceSAndroid Build Coastguard Worker                                " vec4 d;\n"
619*35238bceSAndroid Build Coastguard Worker                                "    };\n"
620*35238bceSAndroid Build Coastguard Worker                                "\n"
621*35238bceSAndroid Build Coastguard Worker                                "    " +
622*35238bceSAndroid Build Coastguard Worker                                constMaybe +
623*35238bceSAndroid Build Coastguard Worker                                "S s =\n"
624*35238bceSAndroid Build Coastguard Worker                                "        S(vec4(0.1, 0.5, 0.9, 1.3),\n"
625*35238bceSAndroid Build Coastguard Worker                                "          vec4(0.2, 0.6, 1.0, 1.4),\n"
626*35238bceSAndroid Build Coastguard Worker                                "          vec4(0.3, 0.7, 1.1, 1.5),\n"
627*35238bceSAndroid Build Coastguard Worker                                "          vec4(0.4, 0.8, 1.2, 1.6));\n"
628*35238bceSAndroid Build Coastguard Worker                                "    " +
629*35238bceSAndroid Build Coastguard Worker                                constMaybe + precision +
630*35238bceSAndroid Build Coastguard Worker                                " vec4 a = (s.a + s.b + s.c + s.d) * 0.25;\n"
631*35238bceSAndroid Build Coastguard Worker                                "    " +
632*35238bceSAndroid Build Coastguard Worker                                constMaybe + precision + " vec4 b0 = cos(sin(a));\n" +
633*35238bceSAndroid Build Coastguard Worker                                repeatIndexedTemplate("    " + constMaybe + precision +
634*35238bceSAndroid Build Coastguard Worker                                                          " vec4 b${NDX} = sin(sin(sin(sin(b${PREV_NDX}))));\n",
635*35238bceSAndroid Build Coastguard Worker                                                      numSinRows, "", 1) +
636*35238bceSAndroid Build Coastguard Worker                                "    " + constMaybe + precision + " vec4 c = abs(b" + toString(numSinRows) + ");\n" +
637*35238bceSAndroid Build Coastguard Worker                                "    value = c*value;\n";
638*35238bceSAndroid Build Coastguard Worker     }
639*35238bceSAndroid Build Coastguard Worker };
640*35238bceSAndroid Build Coastguard Worker 
641*35238bceSAndroid Build Coastguard Worker class CommonSubexpressionCase : public ShaderOptimizationCase
642*35238bceSAndroid Build Coastguard Worker {
643*35238bceSAndroid Build Coastguard Worker public:
644*35238bceSAndroid Build Coastguard Worker     enum CaseType
645*35238bceSAndroid Build Coastguard Worker     {
646*35238bceSAndroid Build Coastguard Worker         CASETYPE_SINGLE_STATEMENT = 0,
647*35238bceSAndroid Build Coastguard Worker         CASETYPE_MULTIPLE_STATEMENTS,
648*35238bceSAndroid Build Coastguard Worker         CASETYPE_STATIC_BRANCH,
649*35238bceSAndroid Build Coastguard Worker         CASETYPE_LOOP,
650*35238bceSAndroid Build Coastguard Worker 
651*35238bceSAndroid Build Coastguard Worker         CASETYPE_LAST
652*35238bceSAndroid Build Coastguard Worker     };
653*35238bceSAndroid Build Coastguard Worker 
CommonSubexpressionCase(Context & context,const char * name,const char * description,CaseShaderType caseShaderType,CaseType caseType)654*35238bceSAndroid Build Coastguard Worker     CommonSubexpressionCase(Context &context, const char *name, const char *description, CaseShaderType caseShaderType,
655*35238bceSAndroid Build Coastguard Worker                             CaseType caseType)
656*35238bceSAndroid Build Coastguard Worker         : ShaderOptimizationCase(context, name, description, caseShaderType)
657*35238bceSAndroid Build Coastguard Worker         , m_caseType(caseType)
658*35238bceSAndroid Build Coastguard Worker     {
659*35238bceSAndroid Build Coastguard Worker     }
660*35238bceSAndroid Build Coastguard Worker 
661*35238bceSAndroid Build Coastguard Worker protected:
generateProgramData(bool optimized) const662*35238bceSAndroid Build Coastguard Worker     ProgramData generateProgramData(bool optimized) const
663*35238bceSAndroid Build Coastguard Worker     {
664*35238bceSAndroid Build Coastguard Worker         const bool isVertexCase = m_caseShaderType == CASESHADERTYPE_VERTEX;
665*35238bceSAndroid Build Coastguard Worker         const string precision  = getShaderPrecision(m_caseShaderType);
666*35238bceSAndroid Build Coastguard Worker         const string statements = m_caseType == CASETYPE_SINGLE_STATEMENT ?
667*35238bceSAndroid Build Coastguard Worker                                       singleStatementCaseStatements(optimized, precision, isVertexCase) :
668*35238bceSAndroid Build Coastguard Worker                                   m_caseType == CASETYPE_MULTIPLE_STATEMENTS ?
669*35238bceSAndroid Build Coastguard Worker                                       multipleStatementsCaseStatements(optimized, precision, isVertexCase) :
670*35238bceSAndroid Build Coastguard Worker                                   m_caseType == CASETYPE_STATIC_BRANCH ?
671*35238bceSAndroid Build Coastguard Worker                                       staticBranchCaseStatements(optimized, precision, isVertexCase) :
672*35238bceSAndroid Build Coastguard Worker                                   m_caseType == CASETYPE_LOOP ? loopCaseStatements(optimized, precision, isVertexCase) :
673*35238bceSAndroid Build Coastguard Worker                                                                 deFatalStr("Invalid CaseType");
674*35238bceSAndroid Build Coastguard Worker 
675*35238bceSAndroid Build Coastguard Worker         return defaultProgramData(m_caseShaderType, statements);
676*35238bceSAndroid Build Coastguard Worker     }
677*35238bceSAndroid Build Coastguard Worker 
678*35238bceSAndroid Build Coastguard Worker private:
679*35238bceSAndroid Build Coastguard Worker     const CaseType m_caseType;
680*35238bceSAndroid Build Coastguard Worker 
singleStatementCaseStatements(bool optimized,const string & precision,bool useHeavierWorkload)681*35238bceSAndroid Build Coastguard Worker     static inline string singleStatementCaseStatements(bool optimized, const string &precision, bool useHeavierWorkload)
682*35238bceSAndroid Build Coastguard Worker     {
683*35238bceSAndroid Build Coastguard Worker         const int numTopLevelRepeats = useHeavierWorkload ? 4 : 1;
684*35238bceSAndroid Build Coastguard Worker 
685*35238bceSAndroid Build Coastguard Worker         return optimized ? "    " + precision +
686*35238bceSAndroid Build Coastguard Worker                                " vec4 s = sin(value);\n"
687*35238bceSAndroid Build Coastguard Worker                                "    " +
688*35238bceSAndroid Build Coastguard Worker                                precision +
689*35238bceSAndroid Build Coastguard Worker                                " vec4 cs = cos(s);\n"
690*35238bceSAndroid Build Coastguard Worker                                "    " +
691*35238bceSAndroid Build Coastguard Worker                                precision +
692*35238bceSAndroid Build Coastguard Worker                                " vec4 d = fract(s + cs) + sqrt(s + exp(cs));\n"
693*35238bceSAndroid Build Coastguard Worker                                "    value = " +
694*35238bceSAndroid Build Coastguard Worker                                repeat("d", numTopLevelRepeats, "+") + ";\n"
695*35238bceSAndroid Build Coastguard Worker 
696*35238bceSAndroid Build Coastguard Worker                            :
697*35238bceSAndroid Build Coastguard Worker                            "    value = " +
698*35238bceSAndroid Build Coastguard Worker                                repeat("fract(sin(value) + cos(sin(value))) + sqrt(sin(value) + exp(cos(sin(value))))",
699*35238bceSAndroid Build Coastguard Worker                                       numTopLevelRepeats, "\n\t      + ") +
700*35238bceSAndroid Build Coastguard Worker                                ";\n";
701*35238bceSAndroid Build Coastguard Worker     }
702*35238bceSAndroid Build Coastguard Worker 
multipleStatementsCaseStatements(bool optimized,const string & precision,bool useHeavierWorkload)703*35238bceSAndroid Build Coastguard Worker     static inline string multipleStatementsCaseStatements(bool optimized, const string &precision,
704*35238bceSAndroid Build Coastguard Worker                                                           bool useHeavierWorkload)
705*35238bceSAndroid Build Coastguard Worker     {
706*35238bceSAndroid Build Coastguard Worker         const int numTopLevelRepeats = useHeavierWorkload ? 4 : 2;
707*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(numTopLevelRepeats >= 2);
708*35238bceSAndroid Build Coastguard Worker 
709*35238bceSAndroid Build Coastguard Worker         return optimized ? "    " + precision +
710*35238bceSAndroid Build Coastguard Worker                                " vec4 a = sin(value) + cos(exp(value));\n"
711*35238bceSAndroid Build Coastguard Worker                                "    " +
712*35238bceSAndroid Build Coastguard Worker                                precision +
713*35238bceSAndroid Build Coastguard Worker                                " vec4 b = cos(cos(a));\n"
714*35238bceSAndroid Build Coastguard Worker                                "    a = fract(exp(sqrt(b)));\n"
715*35238bceSAndroid Build Coastguard Worker                                "\n" +
716*35238bceSAndroid Build Coastguard Worker                                repeat("\tvalue += a*b;\n", numTopLevelRepeats)
717*35238bceSAndroid Build Coastguard Worker 
718*35238bceSAndroid Build Coastguard Worker                            :
719*35238bceSAndroid Build Coastguard Worker                            repeatIndexedTemplate("    " + precision +
720*35238bceSAndroid Build Coastguard Worker                                                      " vec4 a${NDX} = sin(value) + cos(exp(value));\n"
721*35238bceSAndroid Build Coastguard Worker                                                      "    " +
722*35238bceSAndroid Build Coastguard Worker                                                      precision +
723*35238bceSAndroid Build Coastguard Worker                                                      " vec4 b${NDX} = cos(cos(a${NDX}));\n"
724*35238bceSAndroid Build Coastguard Worker                                                      "    a${NDX} = fract(exp(sqrt(b${NDX})));\n"
725*35238bceSAndroid Build Coastguard Worker                                                      "\n",
726*35238bceSAndroid Build Coastguard Worker                                                  numTopLevelRepeats) +
727*35238bceSAndroid Build Coastguard Worker 
728*35238bceSAndroid Build Coastguard Worker                                repeatIndexedTemplate("    value += a${NDX}*b${NDX};\n", numTopLevelRepeats);
729*35238bceSAndroid Build Coastguard Worker     }
730*35238bceSAndroid Build Coastguard Worker 
staticBranchCaseStatements(bool optimized,const string & precision,bool useHeavierWorkload)731*35238bceSAndroid Build Coastguard Worker     static inline string staticBranchCaseStatements(bool optimized, const string &precision, bool useHeavierWorkload)
732*35238bceSAndroid Build Coastguard Worker     {
733*35238bceSAndroid Build Coastguard Worker         const int numTopLevelRepeats = useHeavierWorkload ? 4 : 2;
734*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(numTopLevelRepeats >= 2);
735*35238bceSAndroid Build Coastguard Worker 
736*35238bceSAndroid Build Coastguard Worker         if (optimized)
737*35238bceSAndroid Build Coastguard Worker         {
738*35238bceSAndroid Build Coastguard Worker             return "    " + precision +
739*35238bceSAndroid Build Coastguard Worker                    " vec4 a = sin(value) + cos(exp(value));\n"
740*35238bceSAndroid Build Coastguard Worker                    "    " +
741*35238bceSAndroid Build Coastguard Worker                    precision +
742*35238bceSAndroid Build Coastguard Worker                    " vec4 b = cos(a);\n"
743*35238bceSAndroid Build Coastguard Worker                    "    b = cos(b);\n"
744*35238bceSAndroid Build Coastguard Worker                    "    a = fract(exp(sqrt(b)));\n"
745*35238bceSAndroid Build Coastguard Worker                    "\n" +
746*35238bceSAndroid Build Coastguard Worker                    repeat("    value += a*b;\n", numTopLevelRepeats);
747*35238bceSAndroid Build Coastguard Worker         }
748*35238bceSAndroid Build Coastguard Worker         else
749*35238bceSAndroid Build Coastguard Worker         {
750*35238bceSAndroid Build Coastguard Worker             string result;
751*35238bceSAndroid Build Coastguard Worker 
752*35238bceSAndroid Build Coastguard Worker             for (int i = 0; i < numTopLevelRepeats; i++)
753*35238bceSAndroid Build Coastguard Worker             {
754*35238bceSAndroid Build Coastguard Worker                 result += "    " + precision + " vec4 a" + toString(i) +
755*35238bceSAndroid Build Coastguard Worker                           " = sin(value) + cos(exp(value));\n"
756*35238bceSAndroid Build Coastguard Worker                           "    " +
757*35238bceSAndroid Build Coastguard Worker                           precision + " vec4 b" + toString(i) + " = cos(a" + toString(i) + ");\n";
758*35238bceSAndroid Build Coastguard Worker 
759*35238bceSAndroid Build Coastguard Worker                 if (i % 3 == 0)
760*35238bceSAndroid Build Coastguard Worker                     result += "    if (1 < 2)\n"
761*35238bceSAndroid Build Coastguard Worker                               "        b" +
762*35238bceSAndroid Build Coastguard Worker                               toString(i) + " = cos(b" + toString(i) + ");\n";
763*35238bceSAndroid Build Coastguard Worker                 else if (i % 3 == 1)
764*35238bceSAndroid Build Coastguard Worker                     result += "    b" + toString(i) + " = cos(b" + toString(i) + ");\n";
765*35238bceSAndroid Build Coastguard Worker                 else if (i % 3 == 2)
766*35238bceSAndroid Build Coastguard Worker                     result += "    if (2 < 1);\n"
767*35238bceSAndroid Build Coastguard Worker                               "    else\n"
768*35238bceSAndroid Build Coastguard Worker                               "        b" +
769*35238bceSAndroid Build Coastguard Worker                               toString(i) + " = cos(b" + toString(i) + ");\n";
770*35238bceSAndroid Build Coastguard Worker                 else
771*35238bceSAndroid Build Coastguard Worker                     DE_ASSERT(false);
772*35238bceSAndroid Build Coastguard Worker 
773*35238bceSAndroid Build Coastguard Worker                 result += "    a" + toString(i) + " = fract(exp(sqrt(b" + toString(i) + ")));\n\n";
774*35238bceSAndroid Build Coastguard Worker             }
775*35238bceSAndroid Build Coastguard Worker 
776*35238bceSAndroid Build Coastguard Worker             result += repeatIndexedTemplate("    value += a${NDX}*b${NDX};\n", numTopLevelRepeats);
777*35238bceSAndroid Build Coastguard Worker 
778*35238bceSAndroid Build Coastguard Worker             return result;
779*35238bceSAndroid Build Coastguard Worker         }
780*35238bceSAndroid Build Coastguard Worker     }
781*35238bceSAndroid Build Coastguard Worker 
loopCaseStatements(bool optimized,const string & precision,bool useHeavierWorkload)782*35238bceSAndroid Build Coastguard Worker     static inline string loopCaseStatements(bool optimized, const string &precision, bool useHeavierWorkload)
783*35238bceSAndroid Build Coastguard Worker     {
784*35238bceSAndroid Build Coastguard Worker         const int numLoopIterations = useHeavierWorkload ? 32 : 4;
785*35238bceSAndroid Build Coastguard Worker 
786*35238bceSAndroid Build Coastguard Worker         return optimized ? "    " + precision +
787*35238bceSAndroid Build Coastguard Worker                                " vec4 acc = value;\n"
788*35238bceSAndroid Build Coastguard Worker                                "    for (int i = 0; i < " +
789*35238bceSAndroid Build Coastguard Worker                                toString(numLoopIterations) +
790*35238bceSAndroid Build Coastguard Worker                                "; i++)\n"
791*35238bceSAndroid Build Coastguard Worker                                "        acc = sin(acc);\n"
792*35238bceSAndroid Build Coastguard Worker                                "\n"
793*35238bceSAndroid Build Coastguard Worker                                "    value += acc;\n"
794*35238bceSAndroid Build Coastguard Worker                                "    value += acc;\n"
795*35238bceSAndroid Build Coastguard Worker 
796*35238bceSAndroid Build Coastguard Worker                            :
797*35238bceSAndroid Build Coastguard Worker                            "    " + precision +
798*35238bceSAndroid Build Coastguard Worker                                " vec4 acc0 = value;\n"
799*35238bceSAndroid Build Coastguard Worker                                "    for (int i = 0; i < " +
800*35238bceSAndroid Build Coastguard Worker                                toString(numLoopIterations) +
801*35238bceSAndroid Build Coastguard Worker                                "; i++)\n"
802*35238bceSAndroid Build Coastguard Worker                                "        acc0 = sin(acc0);\n"
803*35238bceSAndroid Build Coastguard Worker                                "\n"
804*35238bceSAndroid Build Coastguard Worker                                "    " +
805*35238bceSAndroid Build Coastguard Worker                                precision +
806*35238bceSAndroid Build Coastguard Worker                                " vec4 acc1 = value;\n"
807*35238bceSAndroid Build Coastguard Worker                                "    for (int i = 0; i < " +
808*35238bceSAndroid Build Coastguard Worker                                toString(numLoopIterations) +
809*35238bceSAndroid Build Coastguard Worker                                "; i++)\n"
810*35238bceSAndroid Build Coastguard Worker                                "        acc1 = sin(acc1);\n"
811*35238bceSAndroid Build Coastguard Worker                                "\n"
812*35238bceSAndroid Build Coastguard Worker                                "    value += acc0;\n"
813*35238bceSAndroid Build Coastguard Worker                                "    value += acc1;\n";
814*35238bceSAndroid Build Coastguard Worker     }
815*35238bceSAndroid Build Coastguard Worker };
816*35238bceSAndroid Build Coastguard Worker 
817*35238bceSAndroid Build Coastguard Worker class DeadCodeEliminationCase : public ShaderOptimizationCase
818*35238bceSAndroid Build Coastguard Worker {
819*35238bceSAndroid Build Coastguard Worker public:
820*35238bceSAndroid Build Coastguard Worker     enum CaseType
821*35238bceSAndroid Build Coastguard Worker     {
822*35238bceSAndroid Build Coastguard Worker         CASETYPE_DEAD_BRANCH_SIMPLE = 0,
823*35238bceSAndroid Build Coastguard Worker         CASETYPE_DEAD_BRANCH_COMPLEX,
824*35238bceSAndroid Build Coastguard Worker         CASETYPE_DEAD_BRANCH_COMPLEX_NO_CONST,
825*35238bceSAndroid Build Coastguard Worker         CASETYPE_DEAD_BRANCH_FUNC_CALL,
826*35238bceSAndroid Build Coastguard Worker         CASETYPE_UNUSED_VALUE_BASIC,
827*35238bceSAndroid Build Coastguard Worker         CASETYPE_UNUSED_VALUE_LOOP,
828*35238bceSAndroid Build Coastguard Worker         CASETYPE_UNUSED_VALUE_DEAD_BRANCH,
829*35238bceSAndroid Build Coastguard Worker         CASETYPE_UNUSED_VALUE_AFTER_RETURN,
830*35238bceSAndroid Build Coastguard Worker         CASETYPE_UNUSED_VALUE_MUL_ZERO,
831*35238bceSAndroid Build Coastguard Worker 
832*35238bceSAndroid Build Coastguard Worker         CASETYPE_LAST
833*35238bceSAndroid Build Coastguard Worker     };
834*35238bceSAndroid Build Coastguard Worker 
DeadCodeEliminationCase(Context & context,const char * name,const char * description,CaseShaderType caseShaderType,CaseType caseType)835*35238bceSAndroid Build Coastguard Worker     DeadCodeEliminationCase(Context &context, const char *name, const char *description, CaseShaderType caseShaderType,
836*35238bceSAndroid Build Coastguard Worker                             CaseType caseType)
837*35238bceSAndroid Build Coastguard Worker         : ShaderOptimizationCase(context, name, description, caseShaderType)
838*35238bceSAndroid Build Coastguard Worker         , m_caseType(caseType)
839*35238bceSAndroid Build Coastguard Worker     {
840*35238bceSAndroid Build Coastguard Worker     }
841*35238bceSAndroid Build Coastguard Worker 
842*35238bceSAndroid Build Coastguard Worker protected:
generateProgramData(bool optimized) const843*35238bceSAndroid Build Coastguard Worker     ProgramData generateProgramData(bool optimized) const
844*35238bceSAndroid Build Coastguard Worker     {
845*35238bceSAndroid Build Coastguard Worker         const bool isVertexCase = m_caseShaderType == CASESHADERTYPE_VERTEX;
846*35238bceSAndroid Build Coastguard Worker         const string precision  = getShaderPrecision(m_caseShaderType);
847*35238bceSAndroid Build Coastguard Worker         const string funcDefs   = m_caseType == CASETYPE_DEAD_BRANCH_FUNC_CALL ?
848*35238bceSAndroid Build Coastguard Worker                                       deadBranchFuncCallCaseFuncDefs(optimized, precision) :
849*35238bceSAndroid Build Coastguard Worker                                   m_caseType == CASETYPE_UNUSED_VALUE_AFTER_RETURN ?
850*35238bceSAndroid Build Coastguard Worker                                       unusedValueAfterReturnCaseFuncDefs(optimized, precision, isVertexCase) :
851*35238bceSAndroid Build Coastguard Worker                                       "";
852*35238bceSAndroid Build Coastguard Worker 
853*35238bceSAndroid Build Coastguard Worker         const string statements = m_caseType == CASETYPE_DEAD_BRANCH_SIMPLE ?
854*35238bceSAndroid Build Coastguard Worker                                       deadBranchSimpleCaseStatements(optimized, isVertexCase) :
855*35238bceSAndroid Build Coastguard Worker                                   m_caseType == CASETYPE_DEAD_BRANCH_COMPLEX ?
856*35238bceSAndroid Build Coastguard Worker                                       deadBranchComplexCaseStatements(optimized, precision, true, isVertexCase) :
857*35238bceSAndroid Build Coastguard Worker                                   m_caseType == CASETYPE_DEAD_BRANCH_COMPLEX_NO_CONST ?
858*35238bceSAndroid Build Coastguard Worker                                       deadBranchComplexCaseStatements(optimized, precision, false, isVertexCase) :
859*35238bceSAndroid Build Coastguard Worker                                   m_caseType == CASETYPE_DEAD_BRANCH_FUNC_CALL ?
860*35238bceSAndroid Build Coastguard Worker                                       deadBranchFuncCallCaseStatements(optimized, isVertexCase) :
861*35238bceSAndroid Build Coastguard Worker                                   m_caseType == CASETYPE_UNUSED_VALUE_BASIC ?
862*35238bceSAndroid Build Coastguard Worker                                       unusedValueBasicCaseStatements(optimized, precision, isVertexCase) :
863*35238bceSAndroid Build Coastguard Worker                                   m_caseType == CASETYPE_UNUSED_VALUE_LOOP ?
864*35238bceSAndroid Build Coastguard Worker                                       unusedValueLoopCaseStatements(optimized, precision, isVertexCase) :
865*35238bceSAndroid Build Coastguard Worker                                   m_caseType == CASETYPE_UNUSED_VALUE_DEAD_BRANCH ?
866*35238bceSAndroid Build Coastguard Worker                                       unusedValueDeadBranchCaseStatements(optimized, precision, isVertexCase) :
867*35238bceSAndroid Build Coastguard Worker                                   m_caseType == CASETYPE_UNUSED_VALUE_AFTER_RETURN ?
868*35238bceSAndroid Build Coastguard Worker                                       unusedValueAfterReturnCaseStatements() :
869*35238bceSAndroid Build Coastguard Worker                                   m_caseType == CASETYPE_UNUSED_VALUE_MUL_ZERO ?
870*35238bceSAndroid Build Coastguard Worker                                       unusedValueMulZeroCaseStatements(optimized, precision, isVertexCase) :
871*35238bceSAndroid Build Coastguard Worker                                       deFatalStr("Invalid CaseType");
872*35238bceSAndroid Build Coastguard Worker 
873*35238bceSAndroid Build Coastguard Worker         return defaultProgramData(m_caseShaderType, funcDefs, statements);
874*35238bceSAndroid Build Coastguard Worker     }
875*35238bceSAndroid Build Coastguard Worker 
876*35238bceSAndroid Build Coastguard Worker private:
877*35238bceSAndroid Build Coastguard Worker     const CaseType m_caseType;
878*35238bceSAndroid Build Coastguard Worker 
deadBranchSimpleCaseStatements(bool optimized,bool useHeavierWorkload)879*35238bceSAndroid Build Coastguard Worker     static inline string deadBranchSimpleCaseStatements(bool optimized, bool useHeavierWorkload)
880*35238bceSAndroid Build Coastguard Worker     {
881*35238bceSAndroid Build Coastguard Worker         const int numLoopIterations = useHeavierWorkload ? 16 : 4;
882*35238bceSAndroid Build Coastguard Worker 
883*35238bceSAndroid Build Coastguard Worker         return optimized ? "    value = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
884*35238bceSAndroid Build Coastguard Worker 
885*35238bceSAndroid Build Coastguard Worker                            :
886*35238bceSAndroid Build Coastguard Worker                            "    value = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
887*35238bceSAndroid Build Coastguard Worker                            "    if (2 < 1)\n"
888*35238bceSAndroid Build Coastguard Worker                            "    {\n"
889*35238bceSAndroid Build Coastguard Worker                            "        value = cos(exp(sin(value))*log(sqrt(value)));\n"
890*35238bceSAndroid Build Coastguard Worker                            "        for (int i = 0; i < " +
891*35238bceSAndroid Build Coastguard Worker                                toString(numLoopIterations) +
892*35238bceSAndroid Build Coastguard Worker                                "; i++)\n"
893*35238bceSAndroid Build Coastguard Worker                                "            value = sin(value);\n"
894*35238bceSAndroid Build Coastguard Worker                                "    }\n";
895*35238bceSAndroid Build Coastguard Worker     }
896*35238bceSAndroid Build Coastguard Worker 
deadBranchComplexCaseStatements(bool optimized,const string & precision,bool useConst,bool useHeavierWorkload)897*35238bceSAndroid Build Coastguard Worker     static inline string deadBranchComplexCaseStatements(bool optimized, const string &precision, bool useConst,
898*35238bceSAndroid Build Coastguard Worker                                                          bool useHeavierWorkload)
899*35238bceSAndroid Build Coastguard Worker     {
900*35238bceSAndroid Build Coastguard Worker         const string constMaybe     = useConst ? "const " : "";
901*35238bceSAndroid Build Coastguard Worker         const int numLoopIterations = useHeavierWorkload ? 16 : 4;
902*35238bceSAndroid Build Coastguard Worker 
903*35238bceSAndroid Build Coastguard Worker         return optimized ? "    value = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
904*35238bceSAndroid Build Coastguard Worker 
905*35238bceSAndroid Build Coastguard Worker                            :
906*35238bceSAndroid Build Coastguard Worker                            "    value = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
907*35238bceSAndroid Build Coastguard Worker                            "    " +
908*35238bceSAndroid Build Coastguard Worker                                constMaybe + precision +
909*35238bceSAndroid Build Coastguard Worker                                " vec4 a = vec4(sin(0.7), cos(0.2), sin(0.9), abs(-0.5));\n"
910*35238bceSAndroid Build Coastguard Worker                                "    " +
911*35238bceSAndroid Build Coastguard Worker                                constMaybe + precision +
912*35238bceSAndroid Build Coastguard Worker                                " vec4 b = cos(a) + fract(3.0*a.xzzw);\n"
913*35238bceSAndroid Build Coastguard Worker                                "    " +
914*35238bceSAndroid Build Coastguard Worker                                constMaybe +
915*35238bceSAndroid Build Coastguard Worker                                "bvec4 c = bvec4(true, false, true, true);\n"
916*35238bceSAndroid Build Coastguard Worker                                "    " +
917*35238bceSAndroid Build Coastguard Worker                                constMaybe + precision +
918*35238bceSAndroid Build Coastguard Worker                                " vec4 d = exp(b + vec4(c));\n"
919*35238bceSAndroid Build Coastguard Worker                                "    " +
920*35238bceSAndroid Build Coastguard Worker                                constMaybe + precision +
921*35238bceSAndroid Build Coastguard Worker                                " vec4 e = 1.8*abs(sin(sin(inversesqrt(mix(d+a, d+b, a)))));\n"
922*35238bceSAndroid Build Coastguard Worker                                "    if (e.x > 1.0)\n"
923*35238bceSAndroid Build Coastguard Worker                                "    {\n"
924*35238bceSAndroid Build Coastguard Worker                                "        value = cos(exp(sin(value))*log(sqrt(value)));\n"
925*35238bceSAndroid Build Coastguard Worker                                "        for (int i = 0; i < " +
926*35238bceSAndroid Build Coastguard Worker                                toString(numLoopIterations) +
927*35238bceSAndroid Build Coastguard Worker                                "; i++)\n"
928*35238bceSAndroid Build Coastguard Worker                                "            value = sin(value);\n"
929*35238bceSAndroid Build Coastguard Worker                                "    }\n";
930*35238bceSAndroid Build Coastguard Worker     }
931*35238bceSAndroid Build Coastguard Worker 
deadBranchFuncCallCaseFuncDefs(bool optimized,const string & precision)932*35238bceSAndroid Build Coastguard Worker     static inline string deadBranchFuncCallCaseFuncDefs(bool optimized, const string &precision)
933*35238bceSAndroid Build Coastguard Worker     {
934*35238bceSAndroid Build Coastguard Worker         return optimized ? "" : precision + " float func (" + precision + " float x) { return 2.0*x; }\n";
935*35238bceSAndroid Build Coastguard Worker     }
936*35238bceSAndroid Build Coastguard Worker 
deadBranchFuncCallCaseStatements(bool optimized,bool useHeavierWorkload)937*35238bceSAndroid Build Coastguard Worker     static inline string deadBranchFuncCallCaseStatements(bool optimized, bool useHeavierWorkload)
938*35238bceSAndroid Build Coastguard Worker     {
939*35238bceSAndroid Build Coastguard Worker         const int numLoopIterations = useHeavierWorkload ? 16 : 4;
940*35238bceSAndroid Build Coastguard Worker 
941*35238bceSAndroid Build Coastguard Worker         return optimized ? "    value = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
942*35238bceSAndroid Build Coastguard Worker 
943*35238bceSAndroid Build Coastguard Worker                            :
944*35238bceSAndroid Build Coastguard Worker                            "    value = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
945*35238bceSAndroid Build Coastguard Worker                            "    if (func(0.3) > 1.0)\n"
946*35238bceSAndroid Build Coastguard Worker                            "    {\n"
947*35238bceSAndroid Build Coastguard Worker                            "        value = cos(exp(sin(value))*log(sqrt(value)));\n"
948*35238bceSAndroid Build Coastguard Worker                            "        for (int i = 0; i < " +
949*35238bceSAndroid Build Coastguard Worker                                toString(numLoopIterations) +
950*35238bceSAndroid Build Coastguard Worker                                "; i++)\n"
951*35238bceSAndroid Build Coastguard Worker                                "            value = sin(value);\n"
952*35238bceSAndroid Build Coastguard Worker                                "    }\n";
953*35238bceSAndroid Build Coastguard Worker     }
954*35238bceSAndroid Build Coastguard Worker 
unusedValueBasicCaseStatements(bool optimized,const string & precision,bool useHeavierWorkload)955*35238bceSAndroid Build Coastguard Worker     static inline string unusedValueBasicCaseStatements(bool optimized, const string &precision,
956*35238bceSAndroid Build Coastguard Worker                                                         bool useHeavierWorkload)
957*35238bceSAndroid Build Coastguard Worker     {
958*35238bceSAndroid Build Coastguard Worker         const int numSinRows = useHeavierWorkload ? 12 : 1;
959*35238bceSAndroid Build Coastguard Worker 
960*35238bceSAndroid Build Coastguard Worker         return optimized ? "    " + precision +
961*35238bceSAndroid Build Coastguard Worker                                " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
962*35238bceSAndroid Build Coastguard Worker                                "    value = used;\n"
963*35238bceSAndroid Build Coastguard Worker 
964*35238bceSAndroid Build Coastguard Worker                            :
965*35238bceSAndroid Build Coastguard Worker                            "    " + precision +
966*35238bceSAndroid Build Coastguard Worker                                " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
967*35238bceSAndroid Build Coastguard Worker                                "    " +
968*35238bceSAndroid Build Coastguard Worker                                precision + " vec4 unused = cos(exp(sin(value))*log(sqrt(value))) + used;\n" +
969*35238bceSAndroid Build Coastguard Worker                                repeat("    unused = sin(sin(sin(sin(unused))));\n", numSinRows) + "    value = used;\n";
970*35238bceSAndroid Build Coastguard Worker     }
971*35238bceSAndroid Build Coastguard Worker 
unusedValueLoopCaseStatements(bool optimized,const string & precision,bool useHeavierWorkload)972*35238bceSAndroid Build Coastguard Worker     static inline string unusedValueLoopCaseStatements(bool optimized, const string &precision, bool useHeavierWorkload)
973*35238bceSAndroid Build Coastguard Worker     {
974*35238bceSAndroid Build Coastguard Worker         const int numLoopIterations = useHeavierWorkload ? 16 : 4;
975*35238bceSAndroid Build Coastguard Worker 
976*35238bceSAndroid Build Coastguard Worker         return optimized ? "    " + precision +
977*35238bceSAndroid Build Coastguard Worker                                " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
978*35238bceSAndroid Build Coastguard Worker                                "    value = used;\n"
979*35238bceSAndroid Build Coastguard Worker 
980*35238bceSAndroid Build Coastguard Worker                            :
981*35238bceSAndroid Build Coastguard Worker                            "    " + precision +
982*35238bceSAndroid Build Coastguard Worker                                " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
983*35238bceSAndroid Build Coastguard Worker                                "    " +
984*35238bceSAndroid Build Coastguard Worker                                precision +
985*35238bceSAndroid Build Coastguard Worker                                " vec4 unused = cos(exp(sin(value))*log(sqrt(value)));\n"
986*35238bceSAndroid Build Coastguard Worker                                "    for (int i = 0; i < " +
987*35238bceSAndroid Build Coastguard Worker                                toString(numLoopIterations) +
988*35238bceSAndroid Build Coastguard Worker                                "; i++)\n"
989*35238bceSAndroid Build Coastguard Worker                                "        unused = sin(unused + used);\n"
990*35238bceSAndroid Build Coastguard Worker                                "    value = used;\n";
991*35238bceSAndroid Build Coastguard Worker     }
992*35238bceSAndroid Build Coastguard Worker 
unusedValueAfterReturnCaseFuncDefs(bool optimized,const string & precision,bool useHeavierWorkload)993*35238bceSAndroid Build Coastguard Worker     static inline string unusedValueAfterReturnCaseFuncDefs(bool optimized, const string &precision,
994*35238bceSAndroid Build Coastguard Worker                                                             bool useHeavierWorkload)
995*35238bceSAndroid Build Coastguard Worker     {
996*35238bceSAndroid Build Coastguard Worker         const int numSinRows = useHeavierWorkload ? 12 : 1;
997*35238bceSAndroid Build Coastguard Worker 
998*35238bceSAndroid Build Coastguard Worker         return optimized ? precision + " vec4 func (" + precision +
999*35238bceSAndroid Build Coastguard Worker                                " vec4 v)\n"
1000*35238bceSAndroid Build Coastguard Worker                                "{\n"
1001*35238bceSAndroid Build Coastguard Worker                                "    " +
1002*35238bceSAndroid Build Coastguard Worker                                precision +
1003*35238bceSAndroid Build Coastguard Worker                                " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * v;\n"
1004*35238bceSAndroid Build Coastguard Worker                                "    return used;\n"
1005*35238bceSAndroid Build Coastguard Worker                                "}\n"
1006*35238bceSAndroid Build Coastguard Worker 
1007*35238bceSAndroid Build Coastguard Worker                            :
1008*35238bceSAndroid Build Coastguard Worker                            precision + " vec4 func (" + precision +
1009*35238bceSAndroid Build Coastguard Worker                                " vec4 v)\n"
1010*35238bceSAndroid Build Coastguard Worker                                "{\n"
1011*35238bceSAndroid Build Coastguard Worker                                "    " +
1012*35238bceSAndroid Build Coastguard Worker                                precision +
1013*35238bceSAndroid Build Coastguard Worker                                " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * v;\n"
1014*35238bceSAndroid Build Coastguard Worker                                "    " +
1015*35238bceSAndroid Build Coastguard Worker                                precision + " vec4 unused = cos(exp(sin(v))*log(sqrt(v)));\n" +
1016*35238bceSAndroid Build Coastguard Worker                                repeat("    unused = sin(sin(sin(sin(unused))));\n", numSinRows) +
1017*35238bceSAndroid Build Coastguard Worker                                "    return used;\n"
1018*35238bceSAndroid Build Coastguard Worker                                "    used = used*unused;"
1019*35238bceSAndroid Build Coastguard Worker                                "    return used;\n"
1020*35238bceSAndroid Build Coastguard Worker                                "}\n";
1021*35238bceSAndroid Build Coastguard Worker     }
1022*35238bceSAndroid Build Coastguard Worker 
unusedValueAfterReturnCaseStatements(void)1023*35238bceSAndroid Build Coastguard Worker     static inline string unusedValueAfterReturnCaseStatements(void)
1024*35238bceSAndroid Build Coastguard Worker     {
1025*35238bceSAndroid Build Coastguard Worker         return "    value = func(value);\n";
1026*35238bceSAndroid Build Coastguard Worker     }
1027*35238bceSAndroid Build Coastguard Worker 
unusedValueDeadBranchCaseStatements(bool optimized,const string & precision,bool useHeavierWorkload)1028*35238bceSAndroid Build Coastguard Worker     static inline string unusedValueDeadBranchCaseStatements(bool optimized, const string &precision,
1029*35238bceSAndroid Build Coastguard Worker                                                              bool useHeavierWorkload)
1030*35238bceSAndroid Build Coastguard Worker     {
1031*35238bceSAndroid Build Coastguard Worker         const int numSinRows = useHeavierWorkload ? 12 : 1;
1032*35238bceSAndroid Build Coastguard Worker 
1033*35238bceSAndroid Build Coastguard Worker         return optimized ? "    " + precision +
1034*35238bceSAndroid Build Coastguard Worker                                " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
1035*35238bceSAndroid Build Coastguard Worker                                "    value = used;\n"
1036*35238bceSAndroid Build Coastguard Worker 
1037*35238bceSAndroid Build Coastguard Worker                            :
1038*35238bceSAndroid Build Coastguard Worker                            "    " + precision +
1039*35238bceSAndroid Build Coastguard Worker                                " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
1040*35238bceSAndroid Build Coastguard Worker                                "    " +
1041*35238bceSAndroid Build Coastguard Worker                                precision + " vec4 unused = cos(exp(sin(value))*log(sqrt(value)));\n" +
1042*35238bceSAndroid Build Coastguard Worker                                repeat("    unused = sin(sin(sin(sin(unused))));\n", numSinRows) +
1043*35238bceSAndroid Build Coastguard Worker                                "    if (2 < 1)\n"
1044*35238bceSAndroid Build Coastguard Worker                                "        used = used*unused;\n"
1045*35238bceSAndroid Build Coastguard Worker                                "    value = used;\n";
1046*35238bceSAndroid Build Coastguard Worker     }
1047*35238bceSAndroid Build Coastguard Worker 
unusedValueMulZeroCaseStatements(bool optimized,const string & precision,bool useHeavierWorkload)1048*35238bceSAndroid Build Coastguard Worker     static inline string unusedValueMulZeroCaseStatements(bool optimized, const string &precision,
1049*35238bceSAndroid Build Coastguard Worker                                                           bool useHeavierWorkload)
1050*35238bceSAndroid Build Coastguard Worker     {
1051*35238bceSAndroid Build Coastguard Worker         const int numSinRows = useHeavierWorkload ? 12 : 1;
1052*35238bceSAndroid Build Coastguard Worker 
1053*35238bceSAndroid Build Coastguard Worker         return optimized ? "    " + precision +
1054*35238bceSAndroid Build Coastguard Worker                                " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
1055*35238bceSAndroid Build Coastguard Worker                                "    value = used;\n"
1056*35238bceSAndroid Build Coastguard Worker 
1057*35238bceSAndroid Build Coastguard Worker                            :
1058*35238bceSAndroid Build Coastguard Worker                            "    " + precision +
1059*35238bceSAndroid Build Coastguard Worker                                " vec4 used = vec4(0.6, 0.7, 0.8, 0.9) * value;\n"
1060*35238bceSAndroid Build Coastguard Worker                                "    " +
1061*35238bceSAndroid Build Coastguard Worker                                precision + " vec4 unused = cos(exp(sin(value))*log(sqrt(value)));\n" +
1062*35238bceSAndroid Build Coastguard Worker                                repeat("    unused = sin(sin(sin(sin(unused))));\n", numSinRows) +
1063*35238bceSAndroid Build Coastguard Worker                                "    value = used + unused*float(1-1);\n";
1064*35238bceSAndroid Build Coastguard Worker     }
1065*35238bceSAndroid Build Coastguard Worker };
1066*35238bceSAndroid Build Coastguard Worker 
1067*35238bceSAndroid Build Coastguard Worker } // namespace
1068*35238bceSAndroid Build Coastguard Worker 
ShaderOptimizationTests(Context & context)1069*35238bceSAndroid Build Coastguard Worker ShaderOptimizationTests::ShaderOptimizationTests(Context &context)
1070*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(context, "optimization", "Shader Optimization Performance Tests")
1071*35238bceSAndroid Build Coastguard Worker {
1072*35238bceSAndroid Build Coastguard Worker }
1073*35238bceSAndroid Build Coastguard Worker 
~ShaderOptimizationTests(void)1074*35238bceSAndroid Build Coastguard Worker ShaderOptimizationTests::~ShaderOptimizationTests(void)
1075*35238bceSAndroid Build Coastguard Worker {
1076*35238bceSAndroid Build Coastguard Worker }
1077*35238bceSAndroid Build Coastguard Worker 
init(void)1078*35238bceSAndroid Build Coastguard Worker void ShaderOptimizationTests::init(void)
1079*35238bceSAndroid Build Coastguard Worker {
1080*35238bceSAndroid Build Coastguard Worker     TestCaseGroup *const unrollGroup = new TestCaseGroup(m_context, "loop_unrolling", "Loop Unrolling Cases");
1081*35238bceSAndroid Build Coastguard Worker     TestCaseGroup *const loopInvariantCodeMotionGroup =
1082*35238bceSAndroid Build Coastguard Worker         new TestCaseGroup(m_context, "loop_invariant_code_motion", "Loop-Invariant Code Motion Cases");
1083*35238bceSAndroid Build Coastguard Worker     TestCaseGroup *const inlineGroup = new TestCaseGroup(m_context, "function_inlining", "Function Inlining Cases");
1084*35238bceSAndroid Build Coastguard Worker     TestCaseGroup *const constantPropagationGroup =
1085*35238bceSAndroid Build Coastguard Worker         new TestCaseGroup(m_context, "constant_propagation", "Constant Propagation Cases");
1086*35238bceSAndroid Build Coastguard Worker     TestCaseGroup *const commonSubexpressionGroup =
1087*35238bceSAndroid Build Coastguard Worker         new TestCaseGroup(m_context, "common_subexpression_elimination", "Common Subexpression Elimination Cases");
1088*35238bceSAndroid Build Coastguard Worker     TestCaseGroup *const deadCodeEliminationGroup =
1089*35238bceSAndroid Build Coastguard Worker         new TestCaseGroup(m_context, "dead_code_elimination", "Dead Code Elimination Cases");
1090*35238bceSAndroid Build Coastguard Worker     addChild(unrollGroup);
1091*35238bceSAndroid Build Coastguard Worker     addChild(loopInvariantCodeMotionGroup);
1092*35238bceSAndroid Build Coastguard Worker     addChild(inlineGroup);
1093*35238bceSAndroid Build Coastguard Worker     addChild(constantPropagationGroup);
1094*35238bceSAndroid Build Coastguard Worker     addChild(commonSubexpressionGroup);
1095*35238bceSAndroid Build Coastguard Worker     addChild(deadCodeEliminationGroup);
1096*35238bceSAndroid Build Coastguard Worker 
1097*35238bceSAndroid Build Coastguard Worker     for (int caseShaderTypeI = 0; caseShaderTypeI < CASESHADERTYPE_LAST; caseShaderTypeI++)
1098*35238bceSAndroid Build Coastguard Worker     {
1099*35238bceSAndroid Build Coastguard Worker         const CaseShaderType caseShaderType    = (CaseShaderType)caseShaderTypeI;
1100*35238bceSAndroid Build Coastguard Worker         const char *const caseShaderTypeSuffix = caseShaderType == CASESHADERTYPE_VERTEX   ? "_vertex" :
1101*35238bceSAndroid Build Coastguard Worker                                                  caseShaderType == CASESHADERTYPE_FRAGMENT ? "_fragment" :
1102*35238bceSAndroid Build Coastguard Worker                                                                                              DE_NULL;
1103*35238bceSAndroid Build Coastguard Worker 
1104*35238bceSAndroid Build Coastguard Worker         // Loop unrolling cases.
1105*35238bceSAndroid Build Coastguard Worker 
1106*35238bceSAndroid Build Coastguard Worker         {
1107*35238bceSAndroid Build Coastguard Worker             static const int loopIterationCounts[] = {4, 8, 32};
1108*35238bceSAndroid Build Coastguard Worker 
1109*35238bceSAndroid Build Coastguard Worker             for (int caseTypeI = 0; caseTypeI < LoopUnrollCase::CASETYPE_LAST; caseTypeI++)
1110*35238bceSAndroid Build Coastguard Worker             {
1111*35238bceSAndroid Build Coastguard Worker                 const LoopUnrollCase::CaseType caseType = (LoopUnrollCase::CaseType)caseTypeI;
1112*35238bceSAndroid Build Coastguard Worker                 const string caseTypeName               = caseType == LoopUnrollCase::CASETYPE_INDEPENDENT ?
1113*35238bceSAndroid Build Coastguard Worker                                                               "independent_iterations" :
1114*35238bceSAndroid Build Coastguard Worker                                                           caseType == LoopUnrollCase::CASETYPE_DEPENDENT ? "dependent_iterations" :
1115*35238bceSAndroid Build Coastguard Worker                                                                                                            DE_NULL;
1116*35238bceSAndroid Build Coastguard Worker                 const string caseTypeDesc =
1117*35238bceSAndroid Build Coastguard Worker                     caseType == LoopUnrollCase::CASETYPE_INDEPENDENT ? "loop iterations don't depend on each other" :
1118*35238bceSAndroid Build Coastguard Worker                     caseType == LoopUnrollCase::CASETYPE_DEPENDENT   ? "loop iterations depend on each other" :
1119*35238bceSAndroid Build Coastguard Worker                                                                        DE_NULL;
1120*35238bceSAndroid Build Coastguard Worker 
1121*35238bceSAndroid Build Coastguard Worker                 for (int loopIterNdx = 0; loopIterNdx < DE_LENGTH_OF_ARRAY(loopIterationCounts); loopIterNdx++)
1122*35238bceSAndroid Build Coastguard Worker                 {
1123*35238bceSAndroid Build Coastguard Worker                     const int loopIterations = loopIterationCounts[loopIterNdx];
1124*35238bceSAndroid Build Coastguard Worker                     const string name        = caseTypeName + "_" + toString(loopIterations) + caseShaderTypeSuffix;
1125*35238bceSAndroid Build Coastguard Worker                     const string description = toString(loopIterations) + " iterations; " + caseTypeDesc;
1126*35238bceSAndroid Build Coastguard Worker 
1127*35238bceSAndroid Build Coastguard Worker                     unrollGroup->addChild(new LoopUnrollCase(m_context, name.c_str(), description.c_str(),
1128*35238bceSAndroid Build Coastguard Worker                                                              caseShaderType, caseType, loopIterations));
1129*35238bceSAndroid Build Coastguard Worker                 }
1130*35238bceSAndroid Build Coastguard Worker             }
1131*35238bceSAndroid Build Coastguard Worker         }
1132*35238bceSAndroid Build Coastguard Worker 
1133*35238bceSAndroid Build Coastguard Worker         // Loop-invariant code motion cases.
1134*35238bceSAndroid Build Coastguard Worker 
1135*35238bceSAndroid Build Coastguard Worker         {
1136*35238bceSAndroid Build Coastguard Worker             static const int loopIterationCounts[] = {4, 8, 32};
1137*35238bceSAndroid Build Coastguard Worker 
1138*35238bceSAndroid Build Coastguard Worker             for (int loopIterNdx = 0; loopIterNdx < DE_LENGTH_OF_ARRAY(loopIterationCounts); loopIterNdx++)
1139*35238bceSAndroid Build Coastguard Worker             {
1140*35238bceSAndroid Build Coastguard Worker                 const int loopIterations = loopIterationCounts[loopIterNdx];
1141*35238bceSAndroid Build Coastguard Worker                 const string name        = toString(loopIterations) + "_iterations" + caseShaderTypeSuffix;
1142*35238bceSAndroid Build Coastguard Worker 
1143*35238bceSAndroid Build Coastguard Worker                 loopInvariantCodeMotionGroup->addChild(
1144*35238bceSAndroid Build Coastguard Worker                     new LoopInvariantCodeMotionCase(m_context, name.c_str(), "", caseShaderType, loopIterations));
1145*35238bceSAndroid Build Coastguard Worker             }
1146*35238bceSAndroid Build Coastguard Worker         }
1147*35238bceSAndroid Build Coastguard Worker 
1148*35238bceSAndroid Build Coastguard Worker         // Function inlining cases.
1149*35238bceSAndroid Build Coastguard Worker 
1150*35238bceSAndroid Build Coastguard Worker         {
1151*35238bceSAndroid Build Coastguard Worker             static const int callNestingDepths[] = {4, 8, 32};
1152*35238bceSAndroid Build Coastguard Worker 
1153*35238bceSAndroid Build Coastguard Worker             for (int nestDepthNdx = 0; nestDepthNdx < DE_LENGTH_OF_ARRAY(callNestingDepths); nestDepthNdx++)
1154*35238bceSAndroid Build Coastguard Worker             {
1155*35238bceSAndroid Build Coastguard Worker                 const int nestingDepth = callNestingDepths[nestDepthNdx];
1156*35238bceSAndroid Build Coastguard Worker                 const string name      = toString(nestingDepth) + "_nested" + caseShaderTypeSuffix;
1157*35238bceSAndroid Build Coastguard Worker 
1158*35238bceSAndroid Build Coastguard Worker                 inlineGroup->addChild(
1159*35238bceSAndroid Build Coastguard Worker                     new FunctionInliningCase(m_context, name.c_str(), "", caseShaderType, nestingDepth));
1160*35238bceSAndroid Build Coastguard Worker             }
1161*35238bceSAndroid Build Coastguard Worker         }
1162*35238bceSAndroid Build Coastguard Worker 
1163*35238bceSAndroid Build Coastguard Worker         // Constant propagation cases.
1164*35238bceSAndroid Build Coastguard Worker 
1165*35238bceSAndroid Build Coastguard Worker         for (int caseTypeI = 0; caseTypeI < ConstantPropagationCase::CASETYPE_LAST; caseTypeI++)
1166*35238bceSAndroid Build Coastguard Worker         {
1167*35238bceSAndroid Build Coastguard Worker             const ConstantPropagationCase::CaseType caseType = (ConstantPropagationCase::CaseType)caseTypeI;
1168*35238bceSAndroid Build Coastguard Worker             const string caseTypeName = caseType == ConstantPropagationCase::CASETYPE_BUILT_IN_FUNCTIONS ?
1169*35238bceSAndroid Build Coastguard Worker                                             "built_in_functions" :
1170*35238bceSAndroid Build Coastguard Worker                                         caseType == ConstantPropagationCase::CASETYPE_ARRAY  ? "array" :
1171*35238bceSAndroid Build Coastguard Worker                                         caseType == ConstantPropagationCase::CASETYPE_STRUCT ? "struct" :
1172*35238bceSAndroid Build Coastguard Worker                                                                                                DE_NULL;
1173*35238bceSAndroid Build Coastguard Worker 
1174*35238bceSAndroid Build Coastguard Worker             for (int constantExpressionsOnlyI = 0; constantExpressionsOnlyI <= 1; constantExpressionsOnlyI++)
1175*35238bceSAndroid Build Coastguard Worker             {
1176*35238bceSAndroid Build Coastguard Worker                 const bool constantExpressionsOnly = constantExpressionsOnlyI != 0;
1177*35238bceSAndroid Build Coastguard Worker                 const string name = caseTypeName + (constantExpressionsOnly ? "" : "_no_const") + caseShaderTypeSuffix;
1178*35238bceSAndroid Build Coastguard Worker 
1179*35238bceSAndroid Build Coastguard Worker                 if (caseType == ConstantPropagationCase::CASETYPE_ARRAY &&
1180*35238bceSAndroid Build Coastguard Worker                     constantExpressionsOnly) // \note See ConstantPropagationCase's constructor for explanation.
1181*35238bceSAndroid Build Coastguard Worker                     continue;
1182*35238bceSAndroid Build Coastguard Worker 
1183*35238bceSAndroid Build Coastguard Worker                 constantPropagationGroup->addChild(new ConstantPropagationCase(
1184*35238bceSAndroid Build Coastguard Worker                     m_context, name.c_str(), "", caseShaderType, caseType, constantExpressionsOnly));
1185*35238bceSAndroid Build Coastguard Worker             }
1186*35238bceSAndroid Build Coastguard Worker         }
1187*35238bceSAndroid Build Coastguard Worker 
1188*35238bceSAndroid Build Coastguard Worker         // Common subexpression cases.
1189*35238bceSAndroid Build Coastguard Worker 
1190*35238bceSAndroid Build Coastguard Worker         for (int caseTypeI = 0; caseTypeI < CommonSubexpressionCase::CASETYPE_LAST; caseTypeI++)
1191*35238bceSAndroid Build Coastguard Worker         {
1192*35238bceSAndroid Build Coastguard Worker             const CommonSubexpressionCase::CaseType caseType = (CommonSubexpressionCase::CaseType)caseTypeI;
1193*35238bceSAndroid Build Coastguard Worker 
1194*35238bceSAndroid Build Coastguard Worker             const string caseTypeName =
1195*35238bceSAndroid Build Coastguard Worker                 caseType == CommonSubexpressionCase::CASETYPE_SINGLE_STATEMENT    ? "single_statement" :
1196*35238bceSAndroid Build Coastguard Worker                 caseType == CommonSubexpressionCase::CASETYPE_MULTIPLE_STATEMENTS ? "multiple_statements" :
1197*35238bceSAndroid Build Coastguard Worker                 caseType == CommonSubexpressionCase::CASETYPE_STATIC_BRANCH       ? "static_branch" :
1198*35238bceSAndroid Build Coastguard Worker                 caseType == CommonSubexpressionCase::CASETYPE_LOOP                ? "loop" :
1199*35238bceSAndroid Build Coastguard Worker                                                                                     DE_NULL;
1200*35238bceSAndroid Build Coastguard Worker 
1201*35238bceSAndroid Build Coastguard Worker             const string description = caseType == CommonSubexpressionCase::CASETYPE_SINGLE_STATEMENT ?
1202*35238bceSAndroid Build Coastguard Worker                                            "A single statement containing multiple uses of same subexpression" :
1203*35238bceSAndroid Build Coastguard Worker                                        caseType == CommonSubexpressionCase::CASETYPE_MULTIPLE_STATEMENTS ?
1204*35238bceSAndroid Build Coastguard Worker                                            "Multiple statements performing same computations" :
1205*35238bceSAndroid Build Coastguard Worker                                        caseType == CommonSubexpressionCase::CASETYPE_STATIC_BRANCH ?
1206*35238bceSAndroid Build Coastguard Worker                                            "Multiple statements including a static conditional" :
1207*35238bceSAndroid Build Coastguard Worker                                        caseType == CommonSubexpressionCase::CASETYPE_LOOP ?
1208*35238bceSAndroid Build Coastguard Worker                                            "Multiple loops performing the same computations" :
1209*35238bceSAndroid Build Coastguard Worker                                            DE_NULL;
1210*35238bceSAndroid Build Coastguard Worker 
1211*35238bceSAndroid Build Coastguard Worker             commonSubexpressionGroup->addChild(
1212*35238bceSAndroid Build Coastguard Worker                 new CommonSubexpressionCase(m_context, (caseTypeName + caseShaderTypeSuffix).c_str(),
1213*35238bceSAndroid Build Coastguard Worker                                             description.c_str(), caseShaderType, caseType));
1214*35238bceSAndroid Build Coastguard Worker         }
1215*35238bceSAndroid Build Coastguard Worker 
1216*35238bceSAndroid Build Coastguard Worker         // Dead code elimination cases.
1217*35238bceSAndroid Build Coastguard Worker 
1218*35238bceSAndroid Build Coastguard Worker         for (int caseTypeI = 0; caseTypeI < DeadCodeEliminationCase::CASETYPE_LAST; caseTypeI++)
1219*35238bceSAndroid Build Coastguard Worker         {
1220*35238bceSAndroid Build Coastguard Worker             const DeadCodeEliminationCase::CaseType caseType = (DeadCodeEliminationCase::CaseType)caseTypeI;
1221*35238bceSAndroid Build Coastguard Worker             const char *const caseTypeName =
1222*35238bceSAndroid Build Coastguard Worker                 caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_SIMPLE  ? "dead_branch_simple" :
1223*35238bceSAndroid Build Coastguard Worker                 caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_COMPLEX ? "dead_branch_complex" :
1224*35238bceSAndroid Build Coastguard Worker                 caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_COMPLEX_NO_CONST ?
1225*35238bceSAndroid Build Coastguard Worker                                                                                     "dead_branch_complex_no_const" :
1226*35238bceSAndroid Build Coastguard Worker                 caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_FUNC_CALL     ? "dead_branch_func_call" :
1227*35238bceSAndroid Build Coastguard Worker                 caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_BASIC        ? "unused_value_basic" :
1228*35238bceSAndroid Build Coastguard Worker                 caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_LOOP         ? "unused_value_loop" :
1229*35238bceSAndroid Build Coastguard Worker                 caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_DEAD_BRANCH  ? "unused_value_dead_branch" :
1230*35238bceSAndroid Build Coastguard Worker                 caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_AFTER_RETURN ? "unused_value_after_return" :
1231*35238bceSAndroid Build Coastguard Worker                 caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_MUL_ZERO     ? "unused_value_mul_zero" :
1232*35238bceSAndroid Build Coastguard Worker                                                                                           DE_NULL;
1233*35238bceSAndroid Build Coastguard Worker 
1234*35238bceSAndroid Build Coastguard Worker             const char *const caseTypeDescription =
1235*35238bceSAndroid Build Coastguard Worker                 caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_SIMPLE ?
1236*35238bceSAndroid Build Coastguard Worker                     "Do computation inside a branch that is never taken (condition is simple false constant "
1237*35238bceSAndroid Build Coastguard Worker                     "expression)" :
1238*35238bceSAndroid Build Coastguard Worker                 caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_COMPLEX ?
1239*35238bceSAndroid Build Coastguard Worker                     "Do computation inside a branch that is never taken (condition is complex false constant "
1240*35238bceSAndroid Build Coastguard Worker                     "expression)" :
1241*35238bceSAndroid Build Coastguard Worker                 caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_COMPLEX_NO_CONST ?
1242*35238bceSAndroid Build Coastguard Worker                     "Do computation inside a branch that is never taken (condition is complex false expression, not "
1243*35238bceSAndroid Build Coastguard Worker                     "constant expression but still compile-time computable)" :
1244*35238bceSAndroid Build Coastguard Worker                 caseType == DeadCodeEliminationCase::CASETYPE_DEAD_BRANCH_FUNC_CALL ?
1245*35238bceSAndroid Build Coastguard Worker                     "Do computation inside a branch that is never taken (condition is compile-time computable false "
1246*35238bceSAndroid Build Coastguard Worker                     "expression containing function call to a simple inlineable function)" :
1247*35238bceSAndroid Build Coastguard Worker                 caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_BASIC ?
1248*35238bceSAndroid Build Coastguard Worker                     "Compute a value that is never used even statically" :
1249*35238bceSAndroid Build Coastguard Worker                 caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_LOOP ?
1250*35238bceSAndroid Build Coastguard Worker                     "Compute a value, using a loop, that is never used even statically" :
1251*35238bceSAndroid Build Coastguard Worker                 caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_DEAD_BRANCH ?
1252*35238bceSAndroid Build Coastguard Worker                     "Compute a value that is used only inside a statically dead branch" :
1253*35238bceSAndroid Build Coastguard Worker                 caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_AFTER_RETURN ?
1254*35238bceSAndroid Build Coastguard Worker                     "Compute a value that is used only after a return statement" :
1255*35238bceSAndroid Build Coastguard Worker                 caseType == DeadCodeEliminationCase::CASETYPE_UNUSED_VALUE_MUL_ZERO ?
1256*35238bceSAndroid Build Coastguard Worker                     "Compute a value that is used but multiplied by a zero constant expression" :
1257*35238bceSAndroid Build Coastguard Worker                     DE_NULL;
1258*35238bceSAndroid Build Coastguard Worker 
1259*35238bceSAndroid Build Coastguard Worker             deadCodeEliminationGroup->addChild(
1260*35238bceSAndroid Build Coastguard Worker                 new DeadCodeEliminationCase(m_context, (string() + caseTypeName + caseShaderTypeSuffix).c_str(),
1261*35238bceSAndroid Build Coastguard Worker                                             caseTypeDescription, caseShaderType, caseType));
1262*35238bceSAndroid Build Coastguard Worker         }
1263*35238bceSAndroid Build Coastguard Worker     }
1264*35238bceSAndroid Build Coastguard Worker }
1265*35238bceSAndroid Build Coastguard Worker 
1266*35238bceSAndroid Build Coastguard Worker } // namespace Performance
1267*35238bceSAndroid Build Coastguard Worker } // namespace gles2
1268*35238bceSAndroid Build Coastguard Worker } // namespace deqp
1269