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