xref: /aosp_15_r20/external/deqp/framework/randomshaders/rsgShaderGenerator.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program Random Shader Generator
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 Shader generator.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "rsgShaderGenerator.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "rsgFunctionGenerator.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "rsgToken.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "rsgPrettyPrinter.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "rsgUtils.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "deString.h"
30*35238bceSAndroid Build Coastguard Worker 
31*35238bceSAndroid Build Coastguard Worker #include <iterator>
32*35238bceSAndroid Build Coastguard Worker 
33*35238bceSAndroid Build Coastguard Worker using std::string;
34*35238bceSAndroid Build Coastguard Worker using std::vector;
35*35238bceSAndroid Build Coastguard Worker 
36*35238bceSAndroid Build Coastguard Worker namespace rsg
37*35238bceSAndroid Build Coastguard Worker {
38*35238bceSAndroid Build Coastguard Worker 
ShaderGenerator(GeneratorState & state)39*35238bceSAndroid Build Coastguard Worker ShaderGenerator::ShaderGenerator(GeneratorState &state) : m_state(state), m_varManager(state.getNameAllocator())
40*35238bceSAndroid Build Coastguard Worker {
41*35238bceSAndroid Build Coastguard Worker     state.setVariableManager(m_varManager);
42*35238bceSAndroid Build Coastguard Worker }
43*35238bceSAndroid Build Coastguard Worker 
~ShaderGenerator(void)44*35238bceSAndroid Build Coastguard Worker ShaderGenerator::~ShaderGenerator(void)
45*35238bceSAndroid Build Coastguard Worker {
46*35238bceSAndroid Build Coastguard Worker }
47*35238bceSAndroid Build Coastguard Worker 
48*35238bceSAndroid Build Coastguard Worker namespace
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker 
getFragColorName(const GeneratorState & state)51*35238bceSAndroid Build Coastguard Worker const char *getFragColorName(const GeneratorState &state)
52*35238bceSAndroid Build Coastguard Worker {
53*35238bceSAndroid Build Coastguard Worker     switch (state.getProgramParameters().version)
54*35238bceSAndroid Build Coastguard Worker     {
55*35238bceSAndroid Build Coastguard Worker     case VERSION_100:
56*35238bceSAndroid Build Coastguard Worker         return "gl_FragColor";
57*35238bceSAndroid Build Coastguard Worker     case VERSION_300:
58*35238bceSAndroid Build Coastguard Worker         return "dEQP_FragColor";
59*35238bceSAndroid Build Coastguard Worker     default:
60*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(false);
61*35238bceSAndroid Build Coastguard Worker         return DE_NULL;
62*35238bceSAndroid Build Coastguard Worker     }
63*35238bceSAndroid Build Coastguard Worker }
64*35238bceSAndroid Build Coastguard Worker 
createAssignment(BlockStatement & block,const Variable * dstVar,const Variable * srcVar)65*35238bceSAndroid Build Coastguard Worker void createAssignment(BlockStatement &block, const Variable *dstVar, const Variable *srcVar)
66*35238bceSAndroid Build Coastguard Worker {
67*35238bceSAndroid Build Coastguard Worker     VariableRead *varRead = new VariableRead(srcVar);
68*35238bceSAndroid Build Coastguard Worker     try
69*35238bceSAndroid Build Coastguard Worker     {
70*35238bceSAndroid Build Coastguard Worker         block.addChild(new AssignStatement(dstVar, varRead));
71*35238bceSAndroid Build Coastguard Worker     }
72*35238bceSAndroid Build Coastguard Worker     catch (const std::exception &)
73*35238bceSAndroid Build Coastguard Worker     {
74*35238bceSAndroid Build Coastguard Worker         delete varRead;
75*35238bceSAndroid Build Coastguard Worker         throw;
76*35238bceSAndroid Build Coastguard Worker     }
77*35238bceSAndroid Build Coastguard Worker }
78*35238bceSAndroid Build Coastguard Worker 
findByName(VariableManager & varManager,const char * name)79*35238bceSAndroid Build Coastguard Worker const ValueEntry *findByName(VariableManager &varManager, const char *name)
80*35238bceSAndroid Build Coastguard Worker {
81*35238bceSAndroid Build Coastguard Worker     AnyEntry::Iterator iter = varManager.getBegin<AnyEntry>();
82*35238bceSAndroid Build Coastguard Worker     AnyEntry::Iterator end  = varManager.getEnd<AnyEntry>();
83*35238bceSAndroid Build Coastguard Worker     for (; iter != end; iter++)
84*35238bceSAndroid Build Coastguard Worker     {
85*35238bceSAndroid Build Coastguard Worker         const ValueEntry *entry = *iter;
86*35238bceSAndroid Build Coastguard Worker         if (deStringEqual(entry->getVariable()->getName(), name))
87*35238bceSAndroid Build Coastguard Worker             return entry;
88*35238bceSAndroid Build Coastguard Worker     }
89*35238bceSAndroid Build Coastguard Worker     return DE_NULL;
90*35238bceSAndroid Build Coastguard Worker }
91*35238bceSAndroid Build Coastguard Worker 
genVertexPassthrough(GeneratorState & state,Shader & shader)92*35238bceSAndroid Build Coastguard Worker void genVertexPassthrough(GeneratorState &state, Shader &shader)
93*35238bceSAndroid Build Coastguard Worker {
94*35238bceSAndroid Build Coastguard Worker     // Create copies from shader inputs to outputs
95*35238bceSAndroid Build Coastguard Worker     vector<const ValueEntry *> entries;
96*35238bceSAndroid Build Coastguard Worker     std::copy(state.getVariableManager().getBegin<AnyEntry>(), state.getVariableManager().getEnd<AnyEntry>(),
97*35238bceSAndroid Build Coastguard Worker               std::inserter(entries, entries.begin()));
98*35238bceSAndroid Build Coastguard Worker 
99*35238bceSAndroid Build Coastguard Worker     for (vector<const ValueEntry *>::const_iterator i = entries.begin(); i != entries.end(); i++)
100*35238bceSAndroid Build Coastguard Worker     {
101*35238bceSAndroid Build Coastguard Worker         const ValueEntry *entry = *i;
102*35238bceSAndroid Build Coastguard Worker         const Variable *outVar  = entry->getVariable();
103*35238bceSAndroid Build Coastguard Worker         std::string inVarName;
104*35238bceSAndroid Build Coastguard Worker 
105*35238bceSAndroid Build Coastguard Worker         if (outVar->getStorage() != Variable::STORAGE_SHADER_OUT)
106*35238bceSAndroid Build Coastguard Worker             continue;
107*35238bceSAndroid Build Coastguard Worker 
108*35238bceSAndroid Build Coastguard Worker         // Name: a_[name], remove v_ -prefix if such exists
109*35238bceSAndroid Build Coastguard Worker         inVarName = "a_";
110*35238bceSAndroid Build Coastguard Worker         if (deStringBeginsWith(outVar->getName(), "v_"))
111*35238bceSAndroid Build Coastguard Worker             inVarName += (outVar->getName() + 2);
112*35238bceSAndroid Build Coastguard Worker         else
113*35238bceSAndroid Build Coastguard Worker             inVarName += outVar->getName();
114*35238bceSAndroid Build Coastguard Worker 
115*35238bceSAndroid Build Coastguard Worker         Variable *inVar =
116*35238bceSAndroid Build Coastguard Worker             state.getVariableManager().allocate(outVar->getType(), Variable::STORAGE_SHADER_IN, inVarName.c_str());
117*35238bceSAndroid Build Coastguard Worker 
118*35238bceSAndroid Build Coastguard Worker         // Update value range. This will be stored into shader input info.
119*35238bceSAndroid Build Coastguard Worker         state.getVariableManager().setValue(inVar, entry->getValueRange());
120*35238bceSAndroid Build Coastguard Worker 
121*35238bceSAndroid Build Coastguard Worker         // Add assignment from input to output into main() body
122*35238bceSAndroid Build Coastguard Worker         createAssignment(shader.getMain().getBody(), entry->getVariable(), inVar);
123*35238bceSAndroid Build Coastguard Worker     }
124*35238bceSAndroid Build Coastguard Worker }
125*35238bceSAndroid Build Coastguard Worker 
genFragmentPassthrough(GeneratorState & state,Shader & shader)126*35238bceSAndroid Build Coastguard Worker void genFragmentPassthrough(GeneratorState &state, Shader &shader)
127*35238bceSAndroid Build Coastguard Worker {
128*35238bceSAndroid Build Coastguard Worker     // Add simple gl_FragColor = v_color; assignment
129*35238bceSAndroid Build Coastguard Worker     const ValueEntry *fragColorEntry = findByName(state.getVariableManager(), getFragColorName(state));
130*35238bceSAndroid Build Coastguard Worker     TCU_CHECK(fragColorEntry);
131*35238bceSAndroid Build Coastguard Worker 
132*35238bceSAndroid Build Coastguard Worker     Variable *inColorVariable = state.getVariableManager().allocate(fragColorEntry->getVariable()->getType(),
133*35238bceSAndroid Build Coastguard Worker                                                                     Variable::STORAGE_SHADER_IN, "v_color");
134*35238bceSAndroid Build Coastguard Worker 
135*35238bceSAndroid Build Coastguard Worker     state.getVariableManager().setValue(inColorVariable, fragColorEntry->getValueRange());
136*35238bceSAndroid Build Coastguard Worker     createAssignment(shader.getMain().getBody(), fragColorEntry->getVariable(), inColorVariable);
137*35238bceSAndroid Build Coastguard Worker }
138*35238bceSAndroid Build Coastguard Worker 
139*35238bceSAndroid Build Coastguard Worker // Sets undefined (-inf..inf) components to some meaningful values. Used for sanitizing final shader input value ranges.
fillUndefinedComponents(ValueRangeAccess valueRange)140*35238bceSAndroid Build Coastguard Worker void fillUndefinedComponents(ValueRangeAccess valueRange)
141*35238bceSAndroid Build Coastguard Worker {
142*35238bceSAndroid Build Coastguard Worker     VariableType::Type baseType = valueRange.getType().getBaseType();
143*35238bceSAndroid Build Coastguard Worker     TCU_CHECK(baseType == VariableType::TYPE_FLOAT || baseType == VariableType::TYPE_INT ||
144*35238bceSAndroid Build Coastguard Worker               baseType == VariableType::TYPE_BOOL);
145*35238bceSAndroid Build Coastguard Worker 
146*35238bceSAndroid Build Coastguard Worker     for (int elemNdx = 0; elemNdx < valueRange.getType().getNumElements(); elemNdx++)
147*35238bceSAndroid Build Coastguard Worker     {
148*35238bceSAndroid Build Coastguard Worker         if (isUndefinedValueRange(valueRange.component(elemNdx)))
149*35238bceSAndroid Build Coastguard Worker         {
150*35238bceSAndroid Build Coastguard Worker             ValueAccess min = valueRange.component(elemNdx).getMin();
151*35238bceSAndroid Build Coastguard Worker             ValueAccess max = valueRange.component(elemNdx).getMax();
152*35238bceSAndroid Build Coastguard Worker 
153*35238bceSAndroid Build Coastguard Worker             switch (baseType)
154*35238bceSAndroid Build Coastguard Worker             {
155*35238bceSAndroid Build Coastguard Worker             case VariableType::TYPE_FLOAT:
156*35238bceSAndroid Build Coastguard Worker                 min = 0.0f;
157*35238bceSAndroid Build Coastguard Worker                 max = 1.0f;
158*35238bceSAndroid Build Coastguard Worker                 break;
159*35238bceSAndroid Build Coastguard Worker             case VariableType::TYPE_INT:
160*35238bceSAndroid Build Coastguard Worker                 min = 0;
161*35238bceSAndroid Build Coastguard Worker                 max = 1;
162*35238bceSAndroid Build Coastguard Worker                 break;
163*35238bceSAndroid Build Coastguard Worker             case VariableType::TYPE_BOOL:
164*35238bceSAndroid Build Coastguard Worker                 min = false;
165*35238bceSAndroid Build Coastguard Worker                 max = true;
166*35238bceSAndroid Build Coastguard Worker                 break;
167*35238bceSAndroid Build Coastguard Worker             default:
168*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(false);
169*35238bceSAndroid Build Coastguard Worker             }
170*35238bceSAndroid Build Coastguard Worker         }
171*35238bceSAndroid Build Coastguard Worker     }
172*35238bceSAndroid Build Coastguard Worker }
173*35238bceSAndroid Build Coastguard Worker 
fillUndefinedShaderInputs(vector<ShaderInput * > & inputs)174*35238bceSAndroid Build Coastguard Worker void fillUndefinedShaderInputs(vector<ShaderInput *> &inputs)
175*35238bceSAndroid Build Coastguard Worker {
176*35238bceSAndroid Build Coastguard Worker     for (vector<ShaderInput *>::iterator i = inputs.begin(); i != inputs.end(); i++)
177*35238bceSAndroid Build Coastguard Worker     {
178*35238bceSAndroid Build Coastguard Worker         if (!(*i)->getVariable()->getType().isSampler()) // Samplers are assigned at program-level.
179*35238bceSAndroid Build Coastguard Worker             fillUndefinedComponents((*i)->getValueRange());
180*35238bceSAndroid Build Coastguard Worker     }
181*35238bceSAndroid Build Coastguard Worker }
182*35238bceSAndroid Build Coastguard Worker 
183*35238bceSAndroid Build Coastguard Worker } // namespace
184*35238bceSAndroid Build Coastguard Worker 
generate(const ShaderParameters & shaderParams,Shader & shader,const vector<ShaderInput * > & outputs)185*35238bceSAndroid Build Coastguard Worker void ShaderGenerator::generate(const ShaderParameters &shaderParams, Shader &shader,
186*35238bceSAndroid Build Coastguard Worker                                const vector<ShaderInput *> &outputs)
187*35238bceSAndroid Build Coastguard Worker {
188*35238bceSAndroid Build Coastguard Worker     // Global scopes
189*35238bceSAndroid Build Coastguard Worker     VariableScope &globalVariableScope = shader.getGlobalScope();
190*35238bceSAndroid Build Coastguard Worker     ValueScope globalValueScope;
191*35238bceSAndroid Build Coastguard Worker 
192*35238bceSAndroid Build Coastguard Worker     // Init state
193*35238bceSAndroid Build Coastguard Worker     m_state.setShader(shaderParams, shader);
194*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(m_state.getExpressionFlags() == 0);
195*35238bceSAndroid Build Coastguard Worker 
196*35238bceSAndroid Build Coastguard Worker     // Reserve some scalars for gl_Position & dEQP_Position
197*35238bceSAndroid Build Coastguard Worker     ReservedScalars reservedScalars;
198*35238bceSAndroid Build Coastguard Worker     if (shader.getType() == Shader::TYPE_VERTEX)
199*35238bceSAndroid Build Coastguard Worker         m_state.getVariableManager().reserve(reservedScalars, 4 * 2);
200*35238bceSAndroid Build Coastguard Worker 
201*35238bceSAndroid Build Coastguard Worker     // Push global scopes
202*35238bceSAndroid Build Coastguard Worker     m_varManager.pushVariableScope(globalVariableScope);
203*35238bceSAndroid Build Coastguard Worker     m_varManager.pushValueScope(globalValueScope);
204*35238bceSAndroid Build Coastguard Worker 
205*35238bceSAndroid Build Coastguard Worker     // Init shader outputs.
206*35238bceSAndroid Build Coastguard Worker     {
207*35238bceSAndroid Build Coastguard Worker         for (vector<ShaderInput *>::const_iterator i = outputs.begin(); i != outputs.end(); i++)
208*35238bceSAndroid Build Coastguard Worker         {
209*35238bceSAndroid Build Coastguard Worker             const ShaderInput *input = *i;
210*35238bceSAndroid Build Coastguard Worker             Variable *variable       = m_state.getVariableManager().allocate(
211*35238bceSAndroid Build Coastguard Worker                 input->getVariable()->getType(), Variable::STORAGE_SHADER_OUT, input->getVariable()->getName());
212*35238bceSAndroid Build Coastguard Worker 
213*35238bceSAndroid Build Coastguard Worker             m_state.getVariableManager().setValue(variable, input->getValueRange());
214*35238bceSAndroid Build Coastguard Worker         }
215*35238bceSAndroid Build Coastguard Worker 
216*35238bceSAndroid Build Coastguard Worker         if (shader.getType() == Shader::TYPE_FRAGMENT)
217*35238bceSAndroid Build Coastguard Worker         {
218*35238bceSAndroid Build Coastguard Worker             // gl_FragColor
219*35238bceSAndroid Build Coastguard Worker             // \todo [2011-11-22 pyry] Multiple outputs from fragment shader!
220*35238bceSAndroid Build Coastguard Worker             Variable *fragColorVar = m_state.getVariableManager().allocate(
221*35238bceSAndroid Build Coastguard Worker                 VariableType(VariableType::TYPE_FLOAT, 4), Variable::STORAGE_SHADER_OUT, getFragColorName(m_state));
222*35238bceSAndroid Build Coastguard Worker             ValueRange valueRange(fragColorVar->getType());
223*35238bceSAndroid Build Coastguard Worker 
224*35238bceSAndroid Build Coastguard Worker             valueRange.getMin() = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
225*35238bceSAndroid Build Coastguard Worker             valueRange.getMax() = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);
226*35238bceSAndroid Build Coastguard Worker 
227*35238bceSAndroid Build Coastguard Worker             fragColorVar->setLayoutLocation(0); // Bind color output to location 0 (applies to GLSL ES 3.0 onwards).
228*35238bceSAndroid Build Coastguard Worker 
229*35238bceSAndroid Build Coastguard Worker             m_state.getVariableManager().setValue(fragColorVar, valueRange.asAccess());
230*35238bceSAndroid Build Coastguard Worker         }
231*35238bceSAndroid Build Coastguard Worker     }
232*35238bceSAndroid Build Coastguard Worker 
233*35238bceSAndroid Build Coastguard Worker     // Construct shader code.
234*35238bceSAndroid Build Coastguard Worker     {
235*35238bceSAndroid Build Coastguard Worker         Function &main = shader.getMain();
236*35238bceSAndroid Build Coastguard Worker         main.setReturnType(VariableType(VariableType::TYPE_VOID));
237*35238bceSAndroid Build Coastguard Worker 
238*35238bceSAndroid Build Coastguard Worker         if (shaderParams.randomize)
239*35238bceSAndroid Build Coastguard Worker         {
240*35238bceSAndroid Build Coastguard Worker             FunctionGenerator funcGen(m_state, main);
241*35238bceSAndroid Build Coastguard Worker 
242*35238bceSAndroid Build Coastguard Worker             // Mandate assignment into to all shader outputs in main()
243*35238bceSAndroid Build Coastguard Worker             const vector<Variable *> &liveVars = globalVariableScope.getLiveVariables();
244*35238bceSAndroid Build Coastguard Worker             for (vector<Variable *>::const_iterator i = liveVars.begin(); i != liveVars.end(); i++)
245*35238bceSAndroid Build Coastguard Worker             {
246*35238bceSAndroid Build Coastguard Worker                 Variable *variable = *i;
247*35238bceSAndroid Build Coastguard Worker                 if (variable->getStorage() == Variable::STORAGE_SHADER_OUT)
248*35238bceSAndroid Build Coastguard Worker                     funcGen.requireAssignment(variable);
249*35238bceSAndroid Build Coastguard Worker             }
250*35238bceSAndroid Build Coastguard Worker 
251*35238bceSAndroid Build Coastguard Worker             funcGen.generate();
252*35238bceSAndroid Build Coastguard Worker         }
253*35238bceSAndroid Build Coastguard Worker         else
254*35238bceSAndroid Build Coastguard Worker         {
255*35238bceSAndroid Build Coastguard Worker             if (shader.getType() == Shader::TYPE_VERTEX)
256*35238bceSAndroid Build Coastguard Worker                 genVertexPassthrough(m_state, shader);
257*35238bceSAndroid Build Coastguard Worker             else
258*35238bceSAndroid Build Coastguard Worker             {
259*35238bceSAndroid Build Coastguard Worker                 DE_ASSERT(shader.getType() == Shader::TYPE_FRAGMENT);
260*35238bceSAndroid Build Coastguard Worker                 genFragmentPassthrough(m_state, shader);
261*35238bceSAndroid Build Coastguard Worker             }
262*35238bceSAndroid Build Coastguard Worker         }
263*35238bceSAndroid Build Coastguard Worker 
264*35238bceSAndroid Build Coastguard Worker         if (shader.getType() == Shader::TYPE_VERTEX)
265*35238bceSAndroid Build Coastguard Worker         {
266*35238bceSAndroid Build Coastguard Worker             // Add gl_Position = dEQP_Position;
267*35238bceSAndroid Build Coastguard Worker             m_state.getVariableManager().release(reservedScalars);
268*35238bceSAndroid Build Coastguard Worker 
269*35238bceSAndroid Build Coastguard Worker             Variable *glPosVariable = m_state.getVariableManager().allocate(
270*35238bceSAndroid Build Coastguard Worker                 VariableType(VariableType::TYPE_FLOAT, 4), Variable::STORAGE_SHADER_OUT, "gl_Position");
271*35238bceSAndroid Build Coastguard Worker             Variable *qpPosVariable = m_state.getVariableManager().allocate(
272*35238bceSAndroid Build Coastguard Worker                 VariableType(VariableType::TYPE_FLOAT, 4), Variable::STORAGE_SHADER_IN, "dEQP_Position");
273*35238bceSAndroid Build Coastguard Worker 
274*35238bceSAndroid Build Coastguard Worker             ValueRange valueRange(glPosVariable->getType());
275*35238bceSAndroid Build Coastguard Worker 
276*35238bceSAndroid Build Coastguard Worker             valueRange.getMin() = tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f);
277*35238bceSAndroid Build Coastguard Worker             valueRange.getMax() = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
278*35238bceSAndroid Build Coastguard Worker 
279*35238bceSAndroid Build Coastguard Worker             m_state.getVariableManager().setValue(
280*35238bceSAndroid Build Coastguard Worker                 qpPosVariable,
281*35238bceSAndroid Build Coastguard Worker                 valueRange
282*35238bceSAndroid Build Coastguard Worker                     .asAccess()); // \todo [2011-05-24 pyry] No expression should be able to use gl_Position or dEQP_Position..
283*35238bceSAndroid Build Coastguard Worker 
284*35238bceSAndroid Build Coastguard Worker             createAssignment(main.getBody(), glPosVariable, qpPosVariable);
285*35238bceSAndroid Build Coastguard Worker         }
286*35238bceSAndroid Build Coastguard Worker     }
287*35238bceSAndroid Build Coastguard Worker 
288*35238bceSAndroid Build Coastguard Worker     // Declare live global variables.
289*35238bceSAndroid Build Coastguard Worker     {
290*35238bceSAndroid Build Coastguard Worker         vector<Variable *> liveVariables;
291*35238bceSAndroid Build Coastguard Worker         std::copy(globalVariableScope.getLiveVariables().begin(), globalVariableScope.getLiveVariables().end(),
292*35238bceSAndroid Build Coastguard Worker                   std::inserter(liveVariables, liveVariables.begin()));
293*35238bceSAndroid Build Coastguard Worker 
294*35238bceSAndroid Build Coastguard Worker         vector<Variable *> createDeclarationStatementVars;
295*35238bceSAndroid Build Coastguard Worker 
296*35238bceSAndroid Build Coastguard Worker         for (vector<Variable *>::iterator i = liveVariables.begin(); i != liveVariables.end(); i++)
297*35238bceSAndroid Build Coastguard Worker         {
298*35238bceSAndroid Build Coastguard Worker             Variable *variable = *i;
299*35238bceSAndroid Build Coastguard Worker             const char *name   = variable->getName();
300*35238bceSAndroid Build Coastguard Worker             bool declare       = !deStringBeginsWith(name, "gl_"); // Do not declare built-in types.
301*35238bceSAndroid Build Coastguard Worker 
302*35238bceSAndroid Build Coastguard Worker             // Create input entries (store value range) if necessary
303*35238bceSAndroid Build Coastguard Worker             vector<ShaderInput *> &inputs   = shader.getInputs();
304*35238bceSAndroid Build Coastguard Worker             vector<ShaderInput *> &uniforms = shader.getUniforms();
305*35238bceSAndroid Build Coastguard Worker 
306*35238bceSAndroid Build Coastguard Worker             switch (variable->getStorage())
307*35238bceSAndroid Build Coastguard Worker             {
308*35238bceSAndroid Build Coastguard Worker             case Variable::STORAGE_SHADER_IN:
309*35238bceSAndroid Build Coastguard Worker             {
310*35238bceSAndroid Build Coastguard Worker                 const ValueEntry *value = m_state.getVariableManager().getValue(variable);
311*35238bceSAndroid Build Coastguard Worker 
312*35238bceSAndroid Build Coastguard Worker                 inputs.reserve(inputs.size() + 1);
313*35238bceSAndroid Build Coastguard Worker                 inputs.push_back(new ShaderInput(variable, value->getValueRange()));
314*35238bceSAndroid Build Coastguard Worker                 break;
315*35238bceSAndroid Build Coastguard Worker             }
316*35238bceSAndroid Build Coastguard Worker 
317*35238bceSAndroid Build Coastguard Worker             case Variable::STORAGE_UNIFORM:
318*35238bceSAndroid Build Coastguard Worker             {
319*35238bceSAndroid Build Coastguard Worker                 const ValueEntry *value = m_state.getVariableManager().getValue(variable);
320*35238bceSAndroid Build Coastguard Worker 
321*35238bceSAndroid Build Coastguard Worker                 uniforms.reserve(uniforms.size() + 1);
322*35238bceSAndroid Build Coastguard Worker                 uniforms.push_back(new ShaderInput(variable, value->getValueRange()));
323*35238bceSAndroid Build Coastguard Worker                 break;
324*35238bceSAndroid Build Coastguard Worker             }
325*35238bceSAndroid Build Coastguard Worker 
326*35238bceSAndroid Build Coastguard Worker             default:
327*35238bceSAndroid Build Coastguard Worker                 break;
328*35238bceSAndroid Build Coastguard Worker             }
329*35238bceSAndroid Build Coastguard Worker 
330*35238bceSAndroid Build Coastguard Worker             if (declare)
331*35238bceSAndroid Build Coastguard Worker                 createDeclarationStatementVars.push_back(variable);
332*35238bceSAndroid Build Coastguard Worker             else
333*35238bceSAndroid Build Coastguard Worker             {
334*35238bceSAndroid Build Coastguard Worker                 // Just move to global scope without declaration statement.
335*35238bceSAndroid Build Coastguard Worker                 m_state.getVariableManager().declareVariable(variable);
336*35238bceSAndroid Build Coastguard Worker             }
337*35238bceSAndroid Build Coastguard Worker         }
338*35238bceSAndroid Build Coastguard Worker 
339*35238bceSAndroid Build Coastguard Worker         // All global initializers must be constant expressions, no variable allocation is allowed
340*35238bceSAndroid Build Coastguard Worker         DE_ASSERT(m_state.getExpressionFlags() == 0);
341*35238bceSAndroid Build Coastguard Worker         m_state.pushExpressionFlags(CONST_EXPR | NO_VAR_ALLOCATION);
342*35238bceSAndroid Build Coastguard Worker 
343*35238bceSAndroid Build Coastguard Worker         // Create declaration statements
344*35238bceSAndroid Build Coastguard Worker         for (vector<Variable *>::iterator i = createDeclarationStatementVars.begin();
345*35238bceSAndroid Build Coastguard Worker              i != createDeclarationStatementVars.end(); i++)
346*35238bceSAndroid Build Coastguard Worker         {
347*35238bceSAndroid Build Coastguard Worker             shader.getGlobalStatements().reserve(shader.getGlobalStatements().size());
348*35238bceSAndroid Build Coastguard Worker             shader.getGlobalStatements().push_back(new DeclarationStatement(m_state, *i));
349*35238bceSAndroid Build Coastguard Worker         }
350*35238bceSAndroid Build Coastguard Worker 
351*35238bceSAndroid Build Coastguard Worker         m_state.popExpressionFlags();
352*35238bceSAndroid Build Coastguard Worker     }
353*35238bceSAndroid Build Coastguard Worker 
354*35238bceSAndroid Build Coastguard Worker     // Pop global scopes
355*35238bceSAndroid Build Coastguard Worker     m_varManager.popVariableScope();
356*35238bceSAndroid Build Coastguard Worker     m_varManager.popValueScope();
357*35238bceSAndroid Build Coastguard Worker 
358*35238bceSAndroid Build Coastguard Worker     // Fill undefined (unused) components in inputs with unused values
359*35238bceSAndroid Build Coastguard Worker     fillUndefinedShaderInputs(shader.getInputs());
360*35238bceSAndroid Build Coastguard Worker     fillUndefinedShaderInputs(shader.getUniforms());
361*35238bceSAndroid Build Coastguard Worker 
362*35238bceSAndroid Build Coastguard Worker     // Tokenize shader and write source
363*35238bceSAndroid Build Coastguard Worker     {
364*35238bceSAndroid Build Coastguard Worker         TokenStream tokenStr;
365*35238bceSAndroid Build Coastguard Worker         shader.tokenize(m_state, tokenStr);
366*35238bceSAndroid Build Coastguard Worker 
367*35238bceSAndroid Build Coastguard Worker         std::ostringstream str;
368*35238bceSAndroid Build Coastguard Worker         PrettyPrinter printer(str);
369*35238bceSAndroid Build Coastguard Worker 
370*35238bceSAndroid Build Coastguard Worker         // Append #version if necessary.
371*35238bceSAndroid Build Coastguard Worker         if (m_state.getProgramParameters().version == VERSION_300)
372*35238bceSAndroid Build Coastguard Worker             str << "#version 300 es\n";
373*35238bceSAndroid Build Coastguard Worker 
374*35238bceSAndroid Build Coastguard Worker         printer.append(tokenStr);
375*35238bceSAndroid Build Coastguard Worker         shader.setSource(str.str().c_str());
376*35238bceSAndroid Build Coastguard Worker     }
377*35238bceSAndroid Build Coastguard Worker }
378*35238bceSAndroid Build Coastguard Worker 
379*35238bceSAndroid Build Coastguard Worker } // namespace rsg
380