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