xref: /aosp_15_r20/external/deqp/modules/gles3/stress/es3sLongShaderTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 3.0 Module
3*35238bceSAndroid Build Coastguard Worker  * -------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Long shader compilation stress tests
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es3sLongShaderTests.hpp"
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker #include "deRandom.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "deString.h"
29*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
30*35238bceSAndroid Build Coastguard Worker #include "gluRenderContext.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "glwFunctions.hpp"
33*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
34*35238bceSAndroid Build Coastguard Worker 
35*35238bceSAndroid Build Coastguard Worker #include <string>
36*35238bceSAndroid Build Coastguard Worker #include <set>
37*35238bceSAndroid Build Coastguard Worker #include <map>
38*35238bceSAndroid Build Coastguard Worker #include <cmath>
39*35238bceSAndroid Build Coastguard Worker 
40*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
41*35238bceSAndroid Build Coastguard Worker 
42*35238bceSAndroid Build Coastguard Worker namespace deqp
43*35238bceSAndroid Build Coastguard Worker {
44*35238bceSAndroid Build Coastguard Worker namespace gles3
45*35238bceSAndroid Build Coastguard Worker {
46*35238bceSAndroid Build Coastguard Worker namespace Stress
47*35238bceSAndroid Build Coastguard Worker {
48*35238bceSAndroid Build Coastguard Worker 
49*35238bceSAndroid Build Coastguard Worker namespace
50*35238bceSAndroid Build Coastguard Worker {
51*35238bceSAndroid Build Coastguard Worker 
52*35238bceSAndroid Build Coastguard Worker enum LongShaderCaseFlags
53*35238bceSAndroid Build Coastguard Worker {
54*35238bceSAndroid Build Coastguard Worker     CASE_REQUIRE_LINK_STATUS_OK = 1
55*35238bceSAndroid Build Coastguard Worker };
56*35238bceSAndroid Build Coastguard Worker 
getConstVertShaderSource(void)57*35238bceSAndroid Build Coastguard Worker const char *getConstVertShaderSource(void)
58*35238bceSAndroid Build Coastguard Worker {
59*35238bceSAndroid Build Coastguard Worker     const char *const src = "#version 300 es\n"
60*35238bceSAndroid Build Coastguard Worker                             "void main ()\n"
61*35238bceSAndroid Build Coastguard Worker                             "{\n"
62*35238bceSAndroid Build Coastguard Worker                             "    gl_Position = vec4(0.0);\n"
63*35238bceSAndroid Build Coastguard Worker                             "}\n";
64*35238bceSAndroid Build Coastguard Worker 
65*35238bceSAndroid Build Coastguard Worker     return src;
66*35238bceSAndroid Build Coastguard Worker }
67*35238bceSAndroid Build Coastguard Worker 
getConstFragShaderSource(void)68*35238bceSAndroid Build Coastguard Worker const char *getConstFragShaderSource(void)
69*35238bceSAndroid Build Coastguard Worker {
70*35238bceSAndroid Build Coastguard Worker     const char *const src = "#version 300 es\n"
71*35238bceSAndroid Build Coastguard Worker                             "layout(location = 0) out mediump vec4 o_fragColor;\n"
72*35238bceSAndroid Build Coastguard Worker                             "void main ()\n"
73*35238bceSAndroid Build Coastguard Worker                             "{\n"
74*35238bceSAndroid Build Coastguard Worker                             "    o_fragColor = vec4(0.0);\n"
75*35238bceSAndroid Build Coastguard Worker                             "}\n";
76*35238bceSAndroid Build Coastguard Worker 
77*35238bceSAndroid Build Coastguard Worker     return src;
78*35238bceSAndroid Build Coastguard Worker }
79*35238bceSAndroid Build Coastguard Worker 
getConstShaderSource(const glu::ShaderType shaderType)80*35238bceSAndroid Build Coastguard Worker const char *getConstShaderSource(const glu::ShaderType shaderType)
81*35238bceSAndroid Build Coastguard Worker {
82*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(shaderType == glu::SHADERTYPE_VERTEX || shaderType == glu::SHADERTYPE_FRAGMENT);
83*35238bceSAndroid Build Coastguard Worker 
84*35238bceSAndroid Build Coastguard Worker     if (shaderType == glu::SHADERTYPE_VERTEX)
85*35238bceSAndroid Build Coastguard Worker         return getConstVertShaderSource();
86*35238bceSAndroid Build Coastguard Worker     else
87*35238bceSAndroid Build Coastguard Worker         return getConstFragShaderSource();
88*35238bceSAndroid Build Coastguard Worker }
89*35238bceSAndroid Build Coastguard Worker 
90*35238bceSAndroid Build Coastguard Worker typedef std::set<std::string> ShaderScope;
91*35238bceSAndroid Build Coastguard Worker 
92*35238bceSAndroid Build Coastguard Worker const char variableNamePrefixChars[] = "abcdefghijklmnopqrstuvwxyz";
93*35238bceSAndroid Build Coastguard Worker 
94*35238bceSAndroid Build Coastguard Worker class NameGenerator
95*35238bceSAndroid Build Coastguard Worker {
96*35238bceSAndroid Build Coastguard Worker public:
NameGenerator(void)97*35238bceSAndroid Build Coastguard Worker     NameGenerator(void) : m_scopeIndices(1, 0), m_currentScopeDepth(1), m_variableIndex(0)
98*35238bceSAndroid Build Coastguard Worker     {
99*35238bceSAndroid Build Coastguard Worker     }
100*35238bceSAndroid Build Coastguard Worker 
beginScope(void)101*35238bceSAndroid Build Coastguard Worker     void beginScope(void)
102*35238bceSAndroid Build Coastguard Worker     {
103*35238bceSAndroid Build Coastguard Worker         m_currentScopeDepth++;
104*35238bceSAndroid Build Coastguard Worker 
105*35238bceSAndroid Build Coastguard Worker         if (m_scopeIndices.size() < (size_t)m_currentScopeDepth)
106*35238bceSAndroid Build Coastguard Worker             m_scopeIndices.push_back(0);
107*35238bceSAndroid Build Coastguard Worker         else
108*35238bceSAndroid Build Coastguard Worker             m_scopeIndices[m_currentScopeDepth - 1]++;
109*35238bceSAndroid Build Coastguard Worker 
110*35238bceSAndroid Build Coastguard Worker         m_variableIndex = 0;
111*35238bceSAndroid Build Coastguard Worker     }
112*35238bceSAndroid Build Coastguard Worker 
endScope(void)113*35238bceSAndroid Build Coastguard Worker     void endScope(void)
114*35238bceSAndroid Build Coastguard Worker     {
115*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_currentScopeDepth > 1);
116*35238bceSAndroid Build Coastguard Worker 
117*35238bceSAndroid Build Coastguard Worker         m_currentScopeDepth--;
118*35238bceSAndroid Build Coastguard Worker     }
119*35238bceSAndroid Build Coastguard Worker 
makePrefix(void)120*35238bceSAndroid Build Coastguard Worker     std::string makePrefix(void)
121*35238bceSAndroid Build Coastguard Worker     {
122*35238bceSAndroid Build Coastguard Worker         std::string prefix;
123*35238bceSAndroid Build Coastguard Worker 
124*35238bceSAndroid Build Coastguard Worker         for (int ndx = 0; ndx < m_currentScopeDepth; ndx++)
125*35238bceSAndroid Build Coastguard Worker         {
126*35238bceSAndroid Build Coastguard Worker             const int scopeIndex = m_scopeIndices[m_currentScopeDepth - 1];
127*35238bceSAndroid Build Coastguard Worker 
128*35238bceSAndroid Build Coastguard Worker             DE_ASSERT(scopeIndex < DE_LENGTH_OF_ARRAY(variableNamePrefixChars));
129*35238bceSAndroid Build Coastguard Worker 
130*35238bceSAndroid Build Coastguard Worker             prefix += variableNamePrefixChars[scopeIndex];
131*35238bceSAndroid Build Coastguard Worker         }
132*35238bceSAndroid Build Coastguard Worker 
133*35238bceSAndroid Build Coastguard Worker         return prefix;
134*35238bceSAndroid Build Coastguard Worker     }
135*35238bceSAndroid Build Coastguard Worker 
next(void)136*35238bceSAndroid Build Coastguard Worker     std::string next(void)
137*35238bceSAndroid Build Coastguard Worker     {
138*35238bceSAndroid Build Coastguard Worker         m_variableIndex++;
139*35238bceSAndroid Build Coastguard Worker 
140*35238bceSAndroid Build Coastguard Worker         return makePrefix() + de::toString(m_variableIndex);
141*35238bceSAndroid Build Coastguard Worker     }
142*35238bceSAndroid Build Coastguard Worker 
makeNames(ShaderScope & scope,const uint32_t count)143*35238bceSAndroid Build Coastguard Worker     void makeNames(ShaderScope &scope, const uint32_t count)
144*35238bceSAndroid Build Coastguard Worker     {
145*35238bceSAndroid Build Coastguard Worker         for (uint32_t ndx = 0; ndx < count; ndx++)
146*35238bceSAndroid Build Coastguard Worker             scope.insert(next());
147*35238bceSAndroid Build Coastguard Worker     }
148*35238bceSAndroid Build Coastguard Worker 
149*35238bceSAndroid Build Coastguard Worker private:
150*35238bceSAndroid Build Coastguard Worker     std::vector<int> m_scopeIndices;
151*35238bceSAndroid Build Coastguard Worker     int m_currentScopeDepth;
152*35238bceSAndroid Build Coastguard Worker     int m_variableIndex;
153*35238bceSAndroid Build Coastguard Worker };
154*35238bceSAndroid Build Coastguard Worker 
155*35238bceSAndroid Build Coastguard Worker struct LongShaderSpec
156*35238bceSAndroid Build Coastguard Worker {
157*35238bceSAndroid Build Coastguard Worker     glu::ShaderType shaderType;
158*35238bceSAndroid Build Coastguard Worker     uint32_t opsTotal;
159*35238bceSAndroid Build Coastguard Worker 
160*35238bceSAndroid Build Coastguard Worker     uint32_t variablesPerBlock;
161*35238bceSAndroid Build Coastguard Worker     uint32_t opsPerExpression;
162*35238bceSAndroid Build Coastguard Worker 
LongShaderSpecdeqp::gles3::Stress::__anond87001f10111::LongShaderSpec163*35238bceSAndroid Build Coastguard Worker     LongShaderSpec(const glu::ShaderType shaderTypeInit, const uint32_t opsTotalInit)
164*35238bceSAndroid Build Coastguard Worker         : shaderType(shaderTypeInit)
165*35238bceSAndroid Build Coastguard Worker         , opsTotal(opsTotalInit)
166*35238bceSAndroid Build Coastguard Worker         , variablesPerBlock(deMaxu32(10, (uint32_t)std::floor(std::sqrt((double)opsTotal))))
167*35238bceSAndroid Build Coastguard Worker         , opsPerExpression(deMinu32(10, variablesPerBlock / 2))
168*35238bceSAndroid Build Coastguard Worker     {
169*35238bceSAndroid Build Coastguard Worker     }
170*35238bceSAndroid Build Coastguard Worker };
171*35238bceSAndroid Build Coastguard Worker 
172*35238bceSAndroid Build Coastguard Worker // Generator for long test shaders
173*35238bceSAndroid Build Coastguard Worker 
174*35238bceSAndroid Build Coastguard Worker class LongShaderGenerator
175*35238bceSAndroid Build Coastguard Worker {
176*35238bceSAndroid Build Coastguard Worker public:
177*35238bceSAndroid Build Coastguard Worker     LongShaderGenerator(de::Random &rnd, const LongShaderSpec &spec);
178*35238bceSAndroid Build Coastguard Worker 
179*35238bceSAndroid Build Coastguard Worker     glu::ShaderSource getSource(void);
180*35238bceSAndroid Build Coastguard Worker 
181*35238bceSAndroid Build Coastguard Worker private:
182*35238bceSAndroid Build Coastguard Worker     de::Random m_rnd;
183*35238bceSAndroid Build Coastguard Worker     const LongShaderSpec m_spec;
184*35238bceSAndroid Build Coastguard Worker 
185*35238bceSAndroid Build Coastguard Worker     NameGenerator m_nameGen;
186*35238bceSAndroid Build Coastguard Worker 
187*35238bceSAndroid Build Coastguard Worker     std::vector<std::string> m_varNames;
188*35238bceSAndroid Build Coastguard Worker     std::vector<ShaderScope> m_scopes;
189*35238bceSAndroid Build Coastguard Worker 
190*35238bceSAndroid Build Coastguard Worker     std::string m_source;
191*35238bceSAndroid Build Coastguard Worker 
192*35238bceSAndroid Build Coastguard Worker     void generateSource(void);
193*35238bceSAndroid Build Coastguard Worker 
194*35238bceSAndroid Build Coastguard Worker     std::string getRandomVariableName(void);
195*35238bceSAndroid Build Coastguard Worker     std::string getShaderOutputName(void);
196*35238bceSAndroid Build Coastguard Worker     std::string makeExpression(const std::vector<std::string> &varNames, const int numOps);
197*35238bceSAndroid Build Coastguard Worker 
198*35238bceSAndroid Build Coastguard Worker     void addIndent(void);
199*35238bceSAndroid Build Coastguard Worker     void addLine(const std::string &text);
200*35238bceSAndroid Build Coastguard Worker 
201*35238bceSAndroid Build Coastguard Worker     void beginBlock(void);
202*35238bceSAndroid Build Coastguard Worker     void endBlock(void);
203*35238bceSAndroid Build Coastguard Worker };
204*35238bceSAndroid Build Coastguard Worker 
LongShaderGenerator(de::Random & rnd,const LongShaderSpec & spec)205*35238bceSAndroid Build Coastguard Worker LongShaderGenerator::LongShaderGenerator(de::Random &rnd, const LongShaderSpec &spec) : m_rnd(rnd), m_spec(spec)
206*35238bceSAndroid Build Coastguard Worker {
207*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_spec.shaderType == glu::SHADERTYPE_VERTEX || m_spec.shaderType == glu::SHADERTYPE_FRAGMENT);
208*35238bceSAndroid Build Coastguard Worker }
209*35238bceSAndroid Build Coastguard Worker 
getSource(void)210*35238bceSAndroid Build Coastguard Worker glu::ShaderSource LongShaderGenerator::getSource(void)
211*35238bceSAndroid Build Coastguard Worker {
212*35238bceSAndroid Build Coastguard Worker     if (m_source.empty())
213*35238bceSAndroid Build Coastguard Worker         generateSource();
214*35238bceSAndroid Build Coastguard Worker 
215*35238bceSAndroid Build Coastguard Worker     return glu::ShaderSource(m_spec.shaderType, m_source);
216*35238bceSAndroid Build Coastguard Worker }
217*35238bceSAndroid Build Coastguard Worker 
generateSource(void)218*35238bceSAndroid Build Coastguard Worker void LongShaderGenerator::generateSource(void)
219*35238bceSAndroid Build Coastguard Worker {
220*35238bceSAndroid Build Coastguard Worker     uint32_t currentOpsTotal = 0;
221*35238bceSAndroid Build Coastguard Worker 
222*35238bceSAndroid Build Coastguard Worker     m_source.clear();
223*35238bceSAndroid Build Coastguard Worker 
224*35238bceSAndroid Build Coastguard Worker     addLine("#version 300 es");
225*35238bceSAndroid Build Coastguard Worker 
226*35238bceSAndroid Build Coastguard Worker     if (m_spec.shaderType == glu::SHADERTYPE_FRAGMENT)
227*35238bceSAndroid Build Coastguard Worker         addLine("layout(location = 0) out mediump vec4 o_fragColor;");
228*35238bceSAndroid Build Coastguard Worker 
229*35238bceSAndroid Build Coastguard Worker     addLine("void main (void)");
230*35238bceSAndroid Build Coastguard Worker     beginBlock();
231*35238bceSAndroid Build Coastguard Worker 
232*35238bceSAndroid Build Coastguard Worker     while (currentOpsTotal < m_spec.opsTotal)
233*35238bceSAndroid Build Coastguard Worker     {
234*35238bceSAndroid Build Coastguard Worker         const bool isLast    = (m_spec.opsTotal <= (currentOpsTotal + m_spec.opsPerExpression));
235*35238bceSAndroid Build Coastguard Worker         const int numOps     = isLast ? (m_spec.opsTotal - currentOpsTotal) : m_spec.opsPerExpression;
236*35238bceSAndroid Build Coastguard Worker         const size_t numVars = numOps + 1;
237*35238bceSAndroid Build Coastguard Worker 
238*35238bceSAndroid Build Coastguard Worker         const std::string outName = isLast ? getShaderOutputName() : getRandomVariableName();
239*35238bceSAndroid Build Coastguard Worker         std::vector<std::string> inNames(numVars);
240*35238bceSAndroid Build Coastguard Worker 
241*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(numVars < m_varNames.size());
242*35238bceSAndroid Build Coastguard Worker         m_rnd.choose(m_varNames.begin(), m_varNames.end(), inNames.begin(), (int)numVars);
243*35238bceSAndroid Build Coastguard Worker 
244*35238bceSAndroid Build Coastguard Worker         {
245*35238bceSAndroid Build Coastguard Worker             std::string expr = makeExpression(inNames, numOps);
246*35238bceSAndroid Build Coastguard Worker 
247*35238bceSAndroid Build Coastguard Worker             if (isLast)
248*35238bceSAndroid Build Coastguard Worker                 addLine(outName + " = vec4(" + expr + ");");
249*35238bceSAndroid Build Coastguard Worker             else
250*35238bceSAndroid Build Coastguard Worker                 addLine(outName + " = " + expr + ";");
251*35238bceSAndroid Build Coastguard Worker         }
252*35238bceSAndroid Build Coastguard Worker 
253*35238bceSAndroid Build Coastguard Worker         currentOpsTotal += numOps;
254*35238bceSAndroid Build Coastguard Worker     }
255*35238bceSAndroid Build Coastguard Worker 
256*35238bceSAndroid Build Coastguard Worker     while (!m_scopes.empty())
257*35238bceSAndroid Build Coastguard Worker         endBlock();
258*35238bceSAndroid Build Coastguard Worker }
259*35238bceSAndroid Build Coastguard Worker 
getRandomVariableName(void)260*35238bceSAndroid Build Coastguard Worker std::string LongShaderGenerator::getRandomVariableName(void)
261*35238bceSAndroid Build Coastguard Worker {
262*35238bceSAndroid Build Coastguard Worker     return m_rnd.choose<std::string>(m_varNames.begin(), m_varNames.end());
263*35238bceSAndroid Build Coastguard Worker }
264*35238bceSAndroid Build Coastguard Worker 
getShaderOutputName(void)265*35238bceSAndroid Build Coastguard Worker std::string LongShaderGenerator::getShaderOutputName(void)
266*35238bceSAndroid Build Coastguard Worker {
267*35238bceSAndroid Build Coastguard Worker     return (m_spec.shaderType == glu::SHADERTYPE_VERTEX) ? "gl_Position" : "o_fragColor";
268*35238bceSAndroid Build Coastguard Worker }
269*35238bceSAndroid Build Coastguard Worker 
makeExpression(const std::vector<std::string> & varNames,const int numOps)270*35238bceSAndroid Build Coastguard Worker std::string LongShaderGenerator::makeExpression(const std::vector<std::string> &varNames, const int numOps)
271*35238bceSAndroid Build Coastguard Worker {
272*35238bceSAndroid Build Coastguard Worker     const std::string operators = "+-*/";
273*35238bceSAndroid Build Coastguard Worker     std::string expr;
274*35238bceSAndroid Build Coastguard Worker 
275*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(varNames.size() > (size_t)numOps);
276*35238bceSAndroid Build Coastguard Worker 
277*35238bceSAndroid Build Coastguard Worker     expr = varNames[0];
278*35238bceSAndroid Build Coastguard Worker 
279*35238bceSAndroid Build Coastguard Worker     for (int ndx = 1; ndx <= numOps; ndx++)
280*35238bceSAndroid Build Coastguard Worker     {
281*35238bceSAndroid Build Coastguard Worker         const std::string op      = std::string("") + m_rnd.choose<char>(operators.begin(), operators.end());
282*35238bceSAndroid Build Coastguard Worker         const std::string varName = varNames[ndx];
283*35238bceSAndroid Build Coastguard Worker 
284*35238bceSAndroid Build Coastguard Worker         expr += " " + op + " " + varName;
285*35238bceSAndroid Build Coastguard Worker     }
286*35238bceSAndroid Build Coastguard Worker 
287*35238bceSAndroid Build Coastguard Worker     return expr;
288*35238bceSAndroid Build Coastguard Worker }
289*35238bceSAndroid Build Coastguard Worker 
addIndent(void)290*35238bceSAndroid Build Coastguard Worker void LongShaderGenerator::addIndent(void)
291*35238bceSAndroid Build Coastguard Worker {
292*35238bceSAndroid Build Coastguard Worker     m_source += std::string(m_scopes.size(), '\t');
293*35238bceSAndroid Build Coastguard Worker }
294*35238bceSAndroid Build Coastguard Worker 
addLine(const std::string & text)295*35238bceSAndroid Build Coastguard Worker void LongShaderGenerator::addLine(const std::string &text)
296*35238bceSAndroid Build Coastguard Worker {
297*35238bceSAndroid Build Coastguard Worker     addIndent();
298*35238bceSAndroid Build Coastguard Worker     m_source += text + "\n";
299*35238bceSAndroid Build Coastguard Worker }
300*35238bceSAndroid Build Coastguard Worker 
beginBlock(void)301*35238bceSAndroid Build Coastguard Worker void LongShaderGenerator::beginBlock(void)
302*35238bceSAndroid Build Coastguard Worker {
303*35238bceSAndroid Build Coastguard Worker     ShaderScope scope;
304*35238bceSAndroid Build Coastguard Worker 
305*35238bceSAndroid Build Coastguard Worker     addLine("{");
306*35238bceSAndroid Build Coastguard Worker 
307*35238bceSAndroid Build Coastguard Worker     m_nameGen.beginScope();
308*35238bceSAndroid Build Coastguard Worker     m_nameGen.makeNames(scope, m_spec.variablesPerBlock);
309*35238bceSAndroid Build Coastguard Worker 
310*35238bceSAndroid Build Coastguard Worker     m_scopes.push_back(scope);
311*35238bceSAndroid Build Coastguard Worker 
312*35238bceSAndroid Build Coastguard Worker     for (ShaderScope::const_iterator nameIter = scope.begin(); nameIter != scope.end(); nameIter++)
313*35238bceSAndroid Build Coastguard Worker     {
314*35238bceSAndroid Build Coastguard Worker         const std::string varName = *nameIter;
315*35238bceSAndroid Build Coastguard Worker         const float varValue      = m_rnd.getFloat();
316*35238bceSAndroid Build Coastguard Worker 
317*35238bceSAndroid Build Coastguard Worker         addLine("mediump float " + varName + " = " + de::floatToString(varValue, 5) + "f;");
318*35238bceSAndroid Build Coastguard Worker         m_varNames.push_back(varName);
319*35238bceSAndroid Build Coastguard Worker     }
320*35238bceSAndroid Build Coastguard Worker }
321*35238bceSAndroid Build Coastguard Worker 
endBlock(void)322*35238bceSAndroid Build Coastguard Worker void LongShaderGenerator::endBlock(void)
323*35238bceSAndroid Build Coastguard Worker {
324*35238bceSAndroid Build Coastguard Worker     ShaderScope &scope = *(m_scopes.end() - 1);
325*35238bceSAndroid Build Coastguard Worker 
326*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(!m_scopes.empty());
327*35238bceSAndroid Build Coastguard Worker 
328*35238bceSAndroid Build Coastguard Worker     m_varNames.erase((m_varNames.begin() + (m_varNames.size() - scope.size())), m_varNames.end());
329*35238bceSAndroid Build Coastguard Worker 
330*35238bceSAndroid Build Coastguard Worker     m_nameGen.endScope();
331*35238bceSAndroid Build Coastguard Worker     m_scopes.pop_back();
332*35238bceSAndroid Build Coastguard Worker 
333*35238bceSAndroid Build Coastguard Worker     addLine("}");
334*35238bceSAndroid Build Coastguard Worker }
335*35238bceSAndroid Build Coastguard Worker 
336*35238bceSAndroid Build Coastguard Worker } // namespace
337*35238bceSAndroid Build Coastguard Worker 
338*35238bceSAndroid Build Coastguard Worker // Stress test case for compilation of large shaders
339*35238bceSAndroid Build Coastguard Worker 
340*35238bceSAndroid Build Coastguard Worker class LongShaderCompileStressCase : public TestCase
341*35238bceSAndroid Build Coastguard Worker {
342*35238bceSAndroid Build Coastguard Worker public:
343*35238bceSAndroid Build Coastguard Worker     LongShaderCompileStressCase(Context &context, const char *name, const char *desc, const LongShaderSpec &caseSpec,
344*35238bceSAndroid Build Coastguard Worker                                 const uint32_t flags);
345*35238bceSAndroid Build Coastguard Worker     virtual ~LongShaderCompileStressCase(void);
346*35238bceSAndroid Build Coastguard Worker 
347*35238bceSAndroid Build Coastguard Worker     void init(void);
348*35238bceSAndroid Build Coastguard Worker 
349*35238bceSAndroid Build Coastguard Worker     IterateResult iterate(void);
350*35238bceSAndroid Build Coastguard Worker 
351*35238bceSAndroid Build Coastguard Worker     void verify(const glu::ShaderProgram &program);
352*35238bceSAndroid Build Coastguard Worker 
353*35238bceSAndroid Build Coastguard Worker private:
354*35238bceSAndroid Build Coastguard Worker     const glu::ShaderType m_shaderType;
355*35238bceSAndroid Build Coastguard Worker     const uint32_t m_flags;
356*35238bceSAndroid Build Coastguard Worker     de::Random m_rnd;
357*35238bceSAndroid Build Coastguard Worker     LongShaderGenerator m_gen;
358*35238bceSAndroid Build Coastguard Worker };
359*35238bceSAndroid Build Coastguard Worker 
LongShaderCompileStressCase(Context & context,const char * name,const char * desc,const LongShaderSpec & caseSpec,const uint32_t flags)360*35238bceSAndroid Build Coastguard Worker LongShaderCompileStressCase::LongShaderCompileStressCase(Context &context, const char *name, const char *desc,
361*35238bceSAndroid Build Coastguard Worker                                                          const LongShaderSpec &caseSpec, const uint32_t flags)
362*35238bceSAndroid Build Coastguard Worker     : TestCase(context, name, desc)
363*35238bceSAndroid Build Coastguard Worker     , m_shaderType(caseSpec.shaderType)
364*35238bceSAndroid Build Coastguard Worker     , m_flags(flags)
365*35238bceSAndroid Build Coastguard Worker     , m_rnd(deStringHash(name) ^ 0xac9c91d)
366*35238bceSAndroid Build Coastguard Worker     , m_gen(m_rnd, caseSpec)
367*35238bceSAndroid Build Coastguard Worker {
368*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_shaderType == glu::SHADERTYPE_VERTEX || m_shaderType == glu::SHADERTYPE_FRAGMENT);
369*35238bceSAndroid Build Coastguard Worker }
370*35238bceSAndroid Build Coastguard Worker 
~LongShaderCompileStressCase(void)371*35238bceSAndroid Build Coastguard Worker LongShaderCompileStressCase::~LongShaderCompileStressCase(void)
372*35238bceSAndroid Build Coastguard Worker {
373*35238bceSAndroid Build Coastguard Worker }
374*35238bceSAndroid Build Coastguard Worker 
init(void)375*35238bceSAndroid Build Coastguard Worker void LongShaderCompileStressCase::init(void)
376*35238bceSAndroid Build Coastguard Worker {
377*35238bceSAndroid Build Coastguard Worker     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
378*35238bceSAndroid Build Coastguard Worker }
379*35238bceSAndroid Build Coastguard Worker 
iterate(void)380*35238bceSAndroid Build Coastguard Worker tcu::TestCase::IterateResult LongShaderCompileStressCase::iterate(void)
381*35238bceSAndroid Build Coastguard Worker {
382*35238bceSAndroid Build Coastguard Worker     tcu::TestLog &log = m_testCtx.getLog();
383*35238bceSAndroid Build Coastguard Worker     const glu::ShaderType otherShader =
384*35238bceSAndroid Build Coastguard Worker         (m_shaderType == glu::SHADERTYPE_VERTEX) ? glu::SHADERTYPE_FRAGMENT : glu::SHADERTYPE_VERTEX;
385*35238bceSAndroid Build Coastguard Worker     glu::ProgramSources sources;
386*35238bceSAndroid Build Coastguard Worker 
387*35238bceSAndroid Build Coastguard Worker     sources << m_gen.getSource();
388*35238bceSAndroid Build Coastguard Worker     sources << glu::ShaderSource(otherShader, getConstShaderSource(otherShader));
389*35238bceSAndroid Build Coastguard Worker 
390*35238bceSAndroid Build Coastguard Worker     {
391*35238bceSAndroid Build Coastguard Worker         glu::ShaderProgram program(m_context.getRenderContext(), sources);
392*35238bceSAndroid Build Coastguard Worker 
393*35238bceSAndroid Build Coastguard Worker         verify(program);
394*35238bceSAndroid Build Coastguard Worker 
395*35238bceSAndroid Build Coastguard Worker         log << program;
396*35238bceSAndroid Build Coastguard Worker     }
397*35238bceSAndroid Build Coastguard Worker 
398*35238bceSAndroid Build Coastguard Worker     return STOP;
399*35238bceSAndroid Build Coastguard Worker }
400*35238bceSAndroid Build Coastguard Worker 
verify(const glu::ShaderProgram & program)401*35238bceSAndroid Build Coastguard Worker void LongShaderCompileStressCase::verify(const glu::ShaderProgram &program)
402*35238bceSAndroid Build Coastguard Worker {
403*35238bceSAndroid Build Coastguard Worker     tcu::TestLog &log           = m_testCtx.getLog();
404*35238bceSAndroid Build Coastguard Worker     const glw::Functions &gl    = m_context.getRenderContext().getFunctions();
405*35238bceSAndroid Build Coastguard Worker     const bool isStrict         = (m_flags & CASE_REQUIRE_LINK_STATUS_OK) != 0;
406*35238bceSAndroid Build Coastguard Worker     const glw::GLenum errorCode = gl.getError();
407*35238bceSAndroid Build Coastguard Worker 
408*35238bceSAndroid Build Coastguard Worker     if (isStrict && !program.isOk())
409*35238bceSAndroid Build Coastguard Worker     {
410*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Fail, expected program to compile and link successfully." << TestLog::EndMessage;
411*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Linking failed");
412*35238bceSAndroid Build Coastguard Worker     }
413*35238bceSAndroid Build Coastguard Worker 
414*35238bceSAndroid Build Coastguard Worker     if (program.isOk() && (errorCode != GL_NO_ERROR))
415*35238bceSAndroid Build Coastguard Worker     {
416*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Fail, program status OK but a GL error was received (" << errorCode << ")."
417*35238bceSAndroid Build Coastguard Worker             << TestLog::EndMessage;
418*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Conflicting status");
419*35238bceSAndroid Build Coastguard Worker     }
420*35238bceSAndroid Build Coastguard Worker     else if ((errorCode != GL_NO_ERROR) && (errorCode != GL_OUT_OF_MEMORY))
421*35238bceSAndroid Build Coastguard Worker     {
422*35238bceSAndroid Build Coastguard Worker         log << TestLog::Message << "Fail, expected GL_NO_ERROR or GL_OUT_OF_MEMORY, received " << errorCode << "."
423*35238bceSAndroid Build Coastguard Worker             << TestLog::EndMessage;
424*35238bceSAndroid Build Coastguard Worker         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Unexpected GL error");
425*35238bceSAndroid Build Coastguard Worker     }
426*35238bceSAndroid Build Coastguard Worker }
427*35238bceSAndroid Build Coastguard Worker 
LongShaderTests(Context & testCtx)428*35238bceSAndroid Build Coastguard Worker LongShaderTests::LongShaderTests(Context &testCtx)
429*35238bceSAndroid Build Coastguard Worker     : TestCaseGroup(testCtx, "long_shaders", "Long shader compilation stress tests")
430*35238bceSAndroid Build Coastguard Worker {
431*35238bceSAndroid Build Coastguard Worker }
432*35238bceSAndroid Build Coastguard Worker 
~LongShaderTests(void)433*35238bceSAndroid Build Coastguard Worker LongShaderTests::~LongShaderTests(void)
434*35238bceSAndroid Build Coastguard Worker {
435*35238bceSAndroid Build Coastguard Worker }
436*35238bceSAndroid Build Coastguard Worker 
init(void)437*35238bceSAndroid Build Coastguard Worker void LongShaderTests::init(void)
438*35238bceSAndroid Build Coastguard Worker {
439*35238bceSAndroid Build Coastguard Worker     const uint32_t requireLinkOkMaxOps = 1000;
440*35238bceSAndroid Build Coastguard Worker 
441*35238bceSAndroid Build Coastguard Worker     const uint32_t caseOpCounts[] = {100, 1000, 10000, 100000};
442*35238bceSAndroid Build Coastguard Worker 
443*35238bceSAndroid Build Coastguard Worker     for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(caseOpCounts); caseNdx++)
444*35238bceSAndroid Build Coastguard Worker     {
445*35238bceSAndroid Build Coastguard Worker         for (int shaderTypeInt = 0; shaderTypeInt < 2; shaderTypeInt++)
446*35238bceSAndroid Build Coastguard Worker         {
447*35238bceSAndroid Build Coastguard Worker             const glu::ShaderType shaderType = (shaderTypeInt == 0) ? glu::SHADERTYPE_VERTEX : glu::SHADERTYPE_FRAGMENT;
448*35238bceSAndroid Build Coastguard Worker             const uint32_t opCount           = caseOpCounts[caseNdx];
449*35238bceSAndroid Build Coastguard Worker             const uint32_t flags             = (opCount <= requireLinkOkMaxOps) ? CASE_REQUIRE_LINK_STATUS_OK : 0;
450*35238bceSAndroid Build Coastguard Worker 
451*35238bceSAndroid Build Coastguard Worker             const std::string name = de::toString(opCount) + "_operations_" + glu::getShaderTypeName(shaderType);
452*35238bceSAndroid Build Coastguard Worker             const std::string desc = std::string("Compile ") + glu::getShaderTypeName(shaderType) + " shader with " +
453*35238bceSAndroid Build Coastguard Worker                                      de::toString(opCount) + " operations";
454*35238bceSAndroid Build Coastguard Worker 
455*35238bceSAndroid Build Coastguard Worker             LongShaderSpec caseSpec(shaderType, opCount);
456*35238bceSAndroid Build Coastguard Worker 
457*35238bceSAndroid Build Coastguard Worker             addChild(new LongShaderCompileStressCase(m_context, name.c_str(), desc.c_str(), caseSpec, flags));
458*35238bceSAndroid Build Coastguard Worker         }
459*35238bceSAndroid Build Coastguard Worker     }
460*35238bceSAndroid Build Coastguard Worker }
461*35238bceSAndroid Build Coastguard Worker 
462*35238bceSAndroid Build Coastguard Worker } // namespace Stress
463*35238bceSAndroid Build Coastguard Worker } // namespace gles3
464*35238bceSAndroid Build Coastguard Worker } // namespace deqp
465