1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker * drawElements Quality Program OpenGL ES Utilities
3*35238bceSAndroid Build Coastguard Worker * ------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker *
5*35238bceSAndroid Build Coastguard Worker * Copyright 2015 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 .test file utilities.
22*35238bceSAndroid Build Coastguard Worker *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker
24*35238bceSAndroid Build Coastguard Worker #include "gluShaderLibrary.hpp"
25*35238bceSAndroid Build Coastguard Worker
26*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "tcuResource.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "tcuTestLog.hpp"
29*35238bceSAndroid Build Coastguard Worker
30*35238bceSAndroid Build Coastguard Worker #include "deStringUtil.hpp"
31*35238bceSAndroid Build Coastguard Worker #include "deUniquePtr.hpp"
32*35238bceSAndroid Build Coastguard Worker #include "deFilePath.hpp"
33*35238bceSAndroid Build Coastguard Worker
34*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
35*35238bceSAndroid Build Coastguard Worker
36*35238bceSAndroid Build Coastguard Worker #include <sstream>
37*35238bceSAndroid Build Coastguard Worker #include <map>
38*35238bceSAndroid Build Coastguard Worker #include <cstdlib>
39*35238bceSAndroid Build Coastguard Worker
40*35238bceSAndroid Build Coastguard Worker #if 0
41*35238bceSAndroid Build Coastguard Worker #define PARSE_DBG(X) printf X
42*35238bceSAndroid Build Coastguard Worker #else
43*35238bceSAndroid Build Coastguard Worker #define PARSE_DBG(X) DE_NULL_STATEMENT
44*35238bceSAndroid Build Coastguard Worker #endif
45*35238bceSAndroid Build Coastguard Worker
46*35238bceSAndroid Build Coastguard Worker namespace glu
47*35238bceSAndroid Build Coastguard Worker {
48*35238bceSAndroid Build Coastguard Worker namespace sl
49*35238bceSAndroid Build Coastguard Worker {
50*35238bceSAndroid Build Coastguard Worker
51*35238bceSAndroid Build Coastguard Worker using namespace tcu;
52*35238bceSAndroid Build Coastguard Worker
53*35238bceSAndroid Build Coastguard Worker using de::UniquePtr;
54*35238bceSAndroid Build Coastguard Worker using std::map;
55*35238bceSAndroid Build Coastguard Worker using std::ostringstream;
56*35238bceSAndroid Build Coastguard Worker using std::pair;
57*35238bceSAndroid Build Coastguard Worker using std::string;
58*35238bceSAndroid Build Coastguard Worker using std::vector;
59*35238bceSAndroid Build Coastguard Worker
60*35238bceSAndroid Build Coastguard Worker // Specification
61*35238bceSAndroid Build Coastguard Worker
isValid(const ValueBlock & block)62*35238bceSAndroid Build Coastguard Worker bool isValid(const ValueBlock &block)
63*35238bceSAndroid Build Coastguard Worker {
64*35238bceSAndroid Build Coastguard Worker for (size_t storageNdx = 0; storageNdx < 3; ++storageNdx)
65*35238bceSAndroid Build Coastguard Worker {
66*35238bceSAndroid Build Coastguard Worker const vector<Value> &values = storageNdx == 0 ? block.inputs : storageNdx == 1 ? block.outputs : block.uniforms;
67*35238bceSAndroid Build Coastguard Worker const size_t refArrayLen =
68*35238bceSAndroid Build Coastguard Worker values.empty() ? 0 : (values[0].elements.size() / (size_t)values[0].type.getScalarSize());
69*35238bceSAndroid Build Coastguard Worker
70*35238bceSAndroid Build Coastguard Worker for (size_t valNdx = 0; valNdx < values.size(); ++valNdx)
71*35238bceSAndroid Build Coastguard Worker {
72*35238bceSAndroid Build Coastguard Worker const Value &value = values[valNdx];
73*35238bceSAndroid Build Coastguard Worker
74*35238bceSAndroid Build Coastguard Worker if (!value.type.isBasicType())
75*35238bceSAndroid Build Coastguard Worker {
76*35238bceSAndroid Build Coastguard Worker print("ERROR: Value '%s' is of unsupported type!\n", value.name.c_str());
77*35238bceSAndroid Build Coastguard Worker return false;
78*35238bceSAndroid Build Coastguard Worker }
79*35238bceSAndroid Build Coastguard Worker
80*35238bceSAndroid Build Coastguard Worker if (value.elements.size() != refArrayLen * (size_t)value.type.getScalarSize())
81*35238bceSAndroid Build Coastguard Worker {
82*35238bceSAndroid Build Coastguard Worker print("ERROR: Value '%s' has invalid number of scalars!\n", value.name.c_str());
83*35238bceSAndroid Build Coastguard Worker return false;
84*35238bceSAndroid Build Coastguard Worker }
85*35238bceSAndroid Build Coastguard Worker }
86*35238bceSAndroid Build Coastguard Worker }
87*35238bceSAndroid Build Coastguard Worker
88*35238bceSAndroid Build Coastguard Worker return true;
89*35238bceSAndroid Build Coastguard Worker }
90*35238bceSAndroid Build Coastguard Worker
isValid(const ShaderCaseSpecification & spec)91*35238bceSAndroid Build Coastguard Worker bool isValid(const ShaderCaseSpecification &spec)
92*35238bceSAndroid Build Coastguard Worker {
93*35238bceSAndroid Build Coastguard Worker const uint32_t vtxFragMask = (1u << SHADERTYPE_VERTEX) | (1u << SHADERTYPE_FRAGMENT);
94*35238bceSAndroid Build Coastguard Worker const uint32_t tessCtrlEvalMask =
95*35238bceSAndroid Build Coastguard Worker (1u << SHADERTYPE_TESSELLATION_CONTROL) | (1u << SHADERTYPE_TESSELLATION_EVALUATION);
96*35238bceSAndroid Build Coastguard Worker const uint32_t supportedStageMask = vtxFragMask | tessCtrlEvalMask | (1u << SHADERTYPE_GEOMETRY);
97*35238bceSAndroid Build Coastguard Worker const bool isSeparable = !spec.programs.empty() && spec.programs[0].sources.separable;
98*35238bceSAndroid Build Coastguard Worker
99*35238bceSAndroid Build Coastguard Worker if (spec.programs.empty())
100*35238bceSAndroid Build Coastguard Worker {
101*35238bceSAndroid Build Coastguard Worker print("ERROR: No programs specified!\n");
102*35238bceSAndroid Build Coastguard Worker return false;
103*35238bceSAndroid Build Coastguard Worker }
104*35238bceSAndroid Build Coastguard Worker
105*35238bceSAndroid Build Coastguard Worker if (isCapabilityRequired(CAPABILITY_FULL_GLSL_ES_100_SUPPORT, spec))
106*35238bceSAndroid Build Coastguard Worker {
107*35238bceSAndroid Build Coastguard Worker if (spec.targetVersion != GLSL_VERSION_100_ES)
108*35238bceSAndroid Build Coastguard Worker {
109*35238bceSAndroid Build Coastguard Worker print("ERROR: Full GLSL ES 1.00 support requested for other GLSL version!\n");
110*35238bceSAndroid Build Coastguard Worker return false;
111*35238bceSAndroid Build Coastguard Worker }
112*35238bceSAndroid Build Coastguard Worker
113*35238bceSAndroid Build Coastguard Worker if (spec.expectResult != EXPECT_PASS && spec.expectResult != EXPECT_VALIDATION_FAIL &&
114*35238bceSAndroid Build Coastguard Worker spec.expectResult != EXPECT_BUILD_SUCCESSFUL)
115*35238bceSAndroid Build Coastguard Worker {
116*35238bceSAndroid Build Coastguard Worker print("ERROR: Full GLSL ES 1.00 support doesn't make sense when expecting compile/link failure!\n");
117*35238bceSAndroid Build Coastguard Worker return false;
118*35238bceSAndroid Build Coastguard Worker }
119*35238bceSAndroid Build Coastguard Worker }
120*35238bceSAndroid Build Coastguard Worker
121*35238bceSAndroid Build Coastguard Worker if (!de::inBounds(spec.caseType, (CaseType)0, CASETYPE_LAST))
122*35238bceSAndroid Build Coastguard Worker {
123*35238bceSAndroid Build Coastguard Worker print("ERROR: Invalid case type!\n");
124*35238bceSAndroid Build Coastguard Worker return false;
125*35238bceSAndroid Build Coastguard Worker }
126*35238bceSAndroid Build Coastguard Worker
127*35238bceSAndroid Build Coastguard Worker if (!de::inBounds(spec.expectResult, (ExpectResult)0, EXPECT_LAST))
128*35238bceSAndroid Build Coastguard Worker {
129*35238bceSAndroid Build Coastguard Worker print("ERROR: Invalid expected result!\n");
130*35238bceSAndroid Build Coastguard Worker return false;
131*35238bceSAndroid Build Coastguard Worker }
132*35238bceSAndroid Build Coastguard Worker
133*35238bceSAndroid Build Coastguard Worker if (!isValid(spec.values))
134*35238bceSAndroid Build Coastguard Worker return false;
135*35238bceSAndroid Build Coastguard Worker
136*35238bceSAndroid Build Coastguard Worker if (!spec.values.inputs.empty() && !spec.values.outputs.empty() &&
137*35238bceSAndroid Build Coastguard Worker spec.values.inputs[0].elements.size() / spec.values.inputs[0].type.getScalarSize() !=
138*35238bceSAndroid Build Coastguard Worker spec.values.outputs[0].elements.size() / spec.values.outputs[0].type.getScalarSize())
139*35238bceSAndroid Build Coastguard Worker {
140*35238bceSAndroid Build Coastguard Worker print("ERROR: Number of input and output elements don't match!\n");
141*35238bceSAndroid Build Coastguard Worker return false;
142*35238bceSAndroid Build Coastguard Worker }
143*35238bceSAndroid Build Coastguard Worker
144*35238bceSAndroid Build Coastguard Worker if (isSeparable)
145*35238bceSAndroid Build Coastguard Worker {
146*35238bceSAndroid Build Coastguard Worker uint32_t usedStageMask = 0u;
147*35238bceSAndroid Build Coastguard Worker
148*35238bceSAndroid Build Coastguard Worker if (spec.caseType != CASETYPE_COMPLETE)
149*35238bceSAndroid Build Coastguard Worker {
150*35238bceSAndroid Build Coastguard Worker print("ERROR: Separable shaders supported only for complete cases!\n");
151*35238bceSAndroid Build Coastguard Worker return false;
152*35238bceSAndroid Build Coastguard Worker }
153*35238bceSAndroid Build Coastguard Worker
154*35238bceSAndroid Build Coastguard Worker for (size_t progNdx = 0; progNdx < spec.programs.size(); ++progNdx)
155*35238bceSAndroid Build Coastguard Worker {
156*35238bceSAndroid Build Coastguard Worker for (int shaderStageNdx = 0; shaderStageNdx < SHADERTYPE_LAST; ++shaderStageNdx)
157*35238bceSAndroid Build Coastguard Worker {
158*35238bceSAndroid Build Coastguard Worker const uint32_t curStageMask = (1u << shaderStageNdx);
159*35238bceSAndroid Build Coastguard Worker
160*35238bceSAndroid Build Coastguard Worker if (supportedStageMask & curStageMask)
161*35238bceSAndroid Build Coastguard Worker {
162*35238bceSAndroid Build Coastguard Worker const bool hasShader = !spec.programs[progNdx].sources.sources[shaderStageNdx].empty();
163*35238bceSAndroid Build Coastguard Worker const bool isEnabled = (spec.programs[progNdx].activeStages & curStageMask) != 0;
164*35238bceSAndroid Build Coastguard Worker
165*35238bceSAndroid Build Coastguard Worker if (hasShader != isEnabled)
166*35238bceSAndroid Build Coastguard Worker {
167*35238bceSAndroid Build Coastguard Worker print("ERROR: Inconsistent source/enable for shader stage %s!\n",
168*35238bceSAndroid Build Coastguard Worker getShaderTypeName((ShaderType)shaderStageNdx));
169*35238bceSAndroid Build Coastguard Worker return false;
170*35238bceSAndroid Build Coastguard Worker }
171*35238bceSAndroid Build Coastguard Worker
172*35238bceSAndroid Build Coastguard Worker if (hasShader && (usedStageMask & curStageMask) != 0)
173*35238bceSAndroid Build Coastguard Worker {
174*35238bceSAndroid Build Coastguard Worker print("ERROR: Stage %s enabled on multiple programs!\n",
175*35238bceSAndroid Build Coastguard Worker getShaderTypeName((ShaderType)shaderStageNdx));
176*35238bceSAndroid Build Coastguard Worker return false;
177*35238bceSAndroid Build Coastguard Worker }
178*35238bceSAndroid Build Coastguard Worker
179*35238bceSAndroid Build Coastguard Worker if (isEnabled)
180*35238bceSAndroid Build Coastguard Worker usedStageMask |= curStageMask;
181*35238bceSAndroid Build Coastguard Worker }
182*35238bceSAndroid Build Coastguard Worker else if (!spec.programs[progNdx].sources.sources[shaderStageNdx].empty())
183*35238bceSAndroid Build Coastguard Worker {
184*35238bceSAndroid Build Coastguard Worker print("ERROR: Source specified for unsupported shader stage %s!\n",
185*35238bceSAndroid Build Coastguard Worker getShaderTypeName((ShaderType)shaderStageNdx));
186*35238bceSAndroid Build Coastguard Worker return false;
187*35238bceSAndroid Build Coastguard Worker }
188*35238bceSAndroid Build Coastguard Worker }
189*35238bceSAndroid Build Coastguard Worker }
190*35238bceSAndroid Build Coastguard Worker
191*35238bceSAndroid Build Coastguard Worker if ((usedStageMask & vtxFragMask) != vtxFragMask)
192*35238bceSAndroid Build Coastguard Worker {
193*35238bceSAndroid Build Coastguard Worker print("ERROR: Vertex and fragment shaders are mandatory!\n");
194*35238bceSAndroid Build Coastguard Worker return false;
195*35238bceSAndroid Build Coastguard Worker }
196*35238bceSAndroid Build Coastguard Worker
197*35238bceSAndroid Build Coastguard Worker if ((usedStageMask & tessCtrlEvalMask) != 0 && (usedStageMask & tessCtrlEvalMask) != tessCtrlEvalMask)
198*35238bceSAndroid Build Coastguard Worker {
199*35238bceSAndroid Build Coastguard Worker print("ERROR: Both tessellation control and eval shaders must be either enabled or disabled!\n");
200*35238bceSAndroid Build Coastguard Worker return false;
201*35238bceSAndroid Build Coastguard Worker }
202*35238bceSAndroid Build Coastguard Worker }
203*35238bceSAndroid Build Coastguard Worker else
204*35238bceSAndroid Build Coastguard Worker {
205*35238bceSAndroid Build Coastguard Worker const bool hasVertex = !spec.programs[0].sources.sources[SHADERTYPE_VERTEX].empty();
206*35238bceSAndroid Build Coastguard Worker const bool hasFragment = !spec.programs[0].sources.sources[SHADERTYPE_FRAGMENT].empty();
207*35238bceSAndroid Build Coastguard Worker
208*35238bceSAndroid Build Coastguard Worker if (spec.programs.size() != 1)
209*35238bceSAndroid Build Coastguard Worker {
210*35238bceSAndroid Build Coastguard Worker print("ERROR: Only cases using separable programs can have multiple programs!\n");
211*35238bceSAndroid Build Coastguard Worker return false;
212*35238bceSAndroid Build Coastguard Worker }
213*35238bceSAndroid Build Coastguard Worker
214*35238bceSAndroid Build Coastguard Worker if (spec.caseType == CASETYPE_VERTEX_ONLY && (!hasVertex || hasFragment))
215*35238bceSAndroid Build Coastguard Worker {
216*35238bceSAndroid Build Coastguard Worker print("ERROR: Vertex-only case must have only vertex shader!\n");
217*35238bceSAndroid Build Coastguard Worker return false;
218*35238bceSAndroid Build Coastguard Worker }
219*35238bceSAndroid Build Coastguard Worker
220*35238bceSAndroid Build Coastguard Worker if (spec.caseType == CASETYPE_FRAGMENT_ONLY && (hasVertex || !hasFragment))
221*35238bceSAndroid Build Coastguard Worker {
222*35238bceSAndroid Build Coastguard Worker print("ERROR: Fragment-only case must have only fragment shader!\n");
223*35238bceSAndroid Build Coastguard Worker return false;
224*35238bceSAndroid Build Coastguard Worker }
225*35238bceSAndroid Build Coastguard Worker
226*35238bceSAndroid Build Coastguard Worker if (spec.caseType == CASETYPE_COMPLETE && (!hasVertex || !hasFragment))
227*35238bceSAndroid Build Coastguard Worker {
228*35238bceSAndroid Build Coastguard Worker print("ERROR: Complete case must have at least vertex and fragment shaders\n");
229*35238bceSAndroid Build Coastguard Worker return false;
230*35238bceSAndroid Build Coastguard Worker }
231*35238bceSAndroid Build Coastguard Worker }
232*35238bceSAndroid Build Coastguard Worker
233*35238bceSAndroid Build Coastguard Worker return true;
234*35238bceSAndroid Build Coastguard Worker }
235*35238bceSAndroid Build Coastguard Worker
isCapabilityRequired(CapabilityFlag capabilityFlag,const ShaderCaseSpecification & spec)236*35238bceSAndroid Build Coastguard Worker bool isCapabilityRequired(CapabilityFlag capabilityFlag, const ShaderCaseSpecification &spec)
237*35238bceSAndroid Build Coastguard Worker {
238*35238bceSAndroid Build Coastguard Worker std::vector<RequiredCapability>::const_iterator currRequirement = spec.requiredCaps.begin();
239*35238bceSAndroid Build Coastguard Worker while (currRequirement != spec.requiredCaps.end())
240*35238bceSAndroid Build Coastguard Worker {
241*35238bceSAndroid Build Coastguard Worker if ((currRequirement->type == CAPABILITY_FLAG) && (currRequirement->flagName == capabilityFlag))
242*35238bceSAndroid Build Coastguard Worker return true;
243*35238bceSAndroid Build Coastguard Worker ++currRequirement;
244*35238bceSAndroid Build Coastguard Worker }
245*35238bceSAndroid Build Coastguard Worker
246*35238bceSAndroid Build Coastguard Worker return false;
247*35238bceSAndroid Build Coastguard Worker }
248*35238bceSAndroid Build Coastguard Worker
249*35238bceSAndroid Build Coastguard Worker // Parser
250*35238bceSAndroid Build Coastguard Worker
251*35238bceSAndroid Build Coastguard Worker static const glu::GLSLVersion DEFAULT_GLSL_VERSION = glu::GLSL_VERSION_100_ES;
252*35238bceSAndroid Build Coastguard Worker
isWhitespace(char c)253*35238bceSAndroid Build Coastguard Worker DE_INLINE bool isWhitespace(char c)
254*35238bceSAndroid Build Coastguard Worker {
255*35238bceSAndroid Build Coastguard Worker return (c == ' ') || (c == '\t') || (c == '\r') || (c == '\n');
256*35238bceSAndroid Build Coastguard Worker }
257*35238bceSAndroid Build Coastguard Worker
isEOL(char c)258*35238bceSAndroid Build Coastguard Worker DE_INLINE bool isEOL(char c)
259*35238bceSAndroid Build Coastguard Worker {
260*35238bceSAndroid Build Coastguard Worker return (c == '\r') || (c == '\n');
261*35238bceSAndroid Build Coastguard Worker }
262*35238bceSAndroid Build Coastguard Worker
isNumeric(char c)263*35238bceSAndroid Build Coastguard Worker DE_INLINE bool isNumeric(char c)
264*35238bceSAndroid Build Coastguard Worker {
265*35238bceSAndroid Build Coastguard Worker return deInRange32(c, '0', '9');
266*35238bceSAndroid Build Coastguard Worker }
267*35238bceSAndroid Build Coastguard Worker
isAlpha(char c)268*35238bceSAndroid Build Coastguard Worker DE_INLINE bool isAlpha(char c)
269*35238bceSAndroid Build Coastguard Worker {
270*35238bceSAndroid Build Coastguard Worker return deInRange32(c, 'a', 'z') || deInRange32(c, 'A', 'Z');
271*35238bceSAndroid Build Coastguard Worker }
272*35238bceSAndroid Build Coastguard Worker
isCaseNameChar(char c)273*35238bceSAndroid Build Coastguard Worker DE_INLINE bool isCaseNameChar(char c)
274*35238bceSAndroid Build Coastguard Worker {
275*35238bceSAndroid Build Coastguard Worker return deInRange32(c, 'a', 'z') || deInRange32(c, 'A', 'Z') || deInRange32(c, '0', '9') || (c == '_') ||
276*35238bceSAndroid Build Coastguard Worker (c == '-') || (c == '.');
277*35238bceSAndroid Build Coastguard Worker }
278*35238bceSAndroid Build Coastguard Worker
279*35238bceSAndroid Build Coastguard Worker class ShaderParser
280*35238bceSAndroid Build Coastguard Worker {
281*35238bceSAndroid Build Coastguard Worker public:
282*35238bceSAndroid Build Coastguard Worker ShaderParser(const tcu::Archive &archive, const std::string &filename, ShaderCaseFactory *caseFactory);
283*35238bceSAndroid Build Coastguard Worker ~ShaderParser(void);
284*35238bceSAndroid Build Coastguard Worker
285*35238bceSAndroid Build Coastguard Worker vector<tcu::TestNode *> parse(void);
286*35238bceSAndroid Build Coastguard Worker
287*35238bceSAndroid Build Coastguard Worker private:
288*35238bceSAndroid Build Coastguard Worker enum Token
289*35238bceSAndroid Build Coastguard Worker {
290*35238bceSAndroid Build Coastguard Worker TOKEN_INVALID = 0,
291*35238bceSAndroid Build Coastguard Worker TOKEN_EOF,
292*35238bceSAndroid Build Coastguard Worker TOKEN_STRING,
293*35238bceSAndroid Build Coastguard Worker TOKEN_SHADER_SOURCE,
294*35238bceSAndroid Build Coastguard Worker
295*35238bceSAndroid Build Coastguard Worker TOKEN_INT_LITERAL,
296*35238bceSAndroid Build Coastguard Worker TOKEN_FLOAT_LITERAL,
297*35238bceSAndroid Build Coastguard Worker
298*35238bceSAndroid Build Coastguard Worker // identifiers
299*35238bceSAndroid Build Coastguard Worker TOKEN_IDENTIFIER,
300*35238bceSAndroid Build Coastguard Worker TOKEN_TRUE,
301*35238bceSAndroid Build Coastguard Worker TOKEN_FALSE,
302*35238bceSAndroid Build Coastguard Worker TOKEN_DESC,
303*35238bceSAndroid Build Coastguard Worker TOKEN_EXPECT,
304*35238bceSAndroid Build Coastguard Worker TOKEN_GROUP,
305*35238bceSAndroid Build Coastguard Worker TOKEN_CASE,
306*35238bceSAndroid Build Coastguard Worker TOKEN_END,
307*35238bceSAndroid Build Coastguard Worker TOKEN_OUTPUT_COLOR,
308*35238bceSAndroid Build Coastguard Worker TOKEN_FORMAT,
309*35238bceSAndroid Build Coastguard Worker TOKEN_VALUES,
310*35238bceSAndroid Build Coastguard Worker TOKEN_BOTH,
311*35238bceSAndroid Build Coastguard Worker TOKEN_VERTEX,
312*35238bceSAndroid Build Coastguard Worker TOKEN_FRAGMENT,
313*35238bceSAndroid Build Coastguard Worker TOKEN_UNIFORM,
314*35238bceSAndroid Build Coastguard Worker TOKEN_INPUT,
315*35238bceSAndroid Build Coastguard Worker TOKEN_OUTPUT,
316*35238bceSAndroid Build Coastguard Worker TOKEN_FLOAT,
317*35238bceSAndroid Build Coastguard Worker TOKEN_FLOAT_VEC2,
318*35238bceSAndroid Build Coastguard Worker TOKEN_FLOAT_VEC3,
319*35238bceSAndroid Build Coastguard Worker TOKEN_FLOAT_VEC4,
320*35238bceSAndroid Build Coastguard Worker TOKEN_FLOAT_MAT2,
321*35238bceSAndroid Build Coastguard Worker TOKEN_FLOAT_MAT2X3,
322*35238bceSAndroid Build Coastguard Worker TOKEN_FLOAT_MAT2X4,
323*35238bceSAndroid Build Coastguard Worker TOKEN_FLOAT_MAT3X2,
324*35238bceSAndroid Build Coastguard Worker TOKEN_FLOAT_MAT3,
325*35238bceSAndroid Build Coastguard Worker TOKEN_FLOAT_MAT3X4,
326*35238bceSAndroid Build Coastguard Worker TOKEN_FLOAT_MAT4X2,
327*35238bceSAndroid Build Coastguard Worker TOKEN_FLOAT_MAT4X3,
328*35238bceSAndroid Build Coastguard Worker TOKEN_FLOAT_MAT4,
329*35238bceSAndroid Build Coastguard Worker TOKEN_INT,
330*35238bceSAndroid Build Coastguard Worker TOKEN_INT_VEC2,
331*35238bceSAndroid Build Coastguard Worker TOKEN_INT_VEC3,
332*35238bceSAndroid Build Coastguard Worker TOKEN_INT_VEC4,
333*35238bceSAndroid Build Coastguard Worker TOKEN_UINT,
334*35238bceSAndroid Build Coastguard Worker TOKEN_UINT_VEC2,
335*35238bceSAndroid Build Coastguard Worker TOKEN_UINT_VEC3,
336*35238bceSAndroid Build Coastguard Worker TOKEN_UINT_VEC4,
337*35238bceSAndroid Build Coastguard Worker TOKEN_BOOL,
338*35238bceSAndroid Build Coastguard Worker TOKEN_BOOL_VEC2,
339*35238bceSAndroid Build Coastguard Worker TOKEN_BOOL_VEC3,
340*35238bceSAndroid Build Coastguard Worker TOKEN_BOOL_VEC4,
341*35238bceSAndroid Build Coastguard Worker TOKEN_VERSION,
342*35238bceSAndroid Build Coastguard Worker TOKEN_TESSELLATION_CONTROL,
343*35238bceSAndroid Build Coastguard Worker TOKEN_TESSELLATION_EVALUATION,
344*35238bceSAndroid Build Coastguard Worker TOKEN_GEOMETRY,
345*35238bceSAndroid Build Coastguard Worker TOKEN_REQUIRE,
346*35238bceSAndroid Build Coastguard Worker TOKEN_IN,
347*35238bceSAndroid Build Coastguard Worker TOKEN_IMPORT,
348*35238bceSAndroid Build Coastguard Worker TOKEN_PIPELINE_PROGRAM,
349*35238bceSAndroid Build Coastguard Worker TOKEN_ACTIVE_STAGES,
350*35238bceSAndroid Build Coastguard Worker
351*35238bceSAndroid Build Coastguard Worker // symbols
352*35238bceSAndroid Build Coastguard Worker TOKEN_ASSIGN,
353*35238bceSAndroid Build Coastguard Worker TOKEN_PLUS,
354*35238bceSAndroid Build Coastguard Worker TOKEN_MINUS,
355*35238bceSAndroid Build Coastguard Worker TOKEN_COMMA,
356*35238bceSAndroid Build Coastguard Worker TOKEN_VERTICAL_BAR,
357*35238bceSAndroid Build Coastguard Worker TOKEN_SEMI_COLON,
358*35238bceSAndroid Build Coastguard Worker TOKEN_LEFT_PAREN,
359*35238bceSAndroid Build Coastguard Worker TOKEN_RIGHT_PAREN,
360*35238bceSAndroid Build Coastguard Worker TOKEN_LEFT_BRACKET,
361*35238bceSAndroid Build Coastguard Worker TOKEN_RIGHT_BRACKET,
362*35238bceSAndroid Build Coastguard Worker TOKEN_LEFT_BRACE,
363*35238bceSAndroid Build Coastguard Worker TOKEN_RIGHT_BRACE,
364*35238bceSAndroid Build Coastguard Worker TOKEN_GREATER,
365*35238bceSAndroid Build Coastguard Worker
366*35238bceSAndroid Build Coastguard Worker TOKEN_LAST
367*35238bceSAndroid Build Coastguard Worker };
368*35238bceSAndroid Build Coastguard Worker
369*35238bceSAndroid Build Coastguard Worker void parseError(const std::string &errorStr);
370*35238bceSAndroid Build Coastguard Worker float parseFloatLiteral(const char *str);
371*35238bceSAndroid Build Coastguard Worker int parseIntLiteral(const char *str);
372*35238bceSAndroid Build Coastguard Worker string parseStringLiteral(const char *str);
373*35238bceSAndroid Build Coastguard Worker string parseShaderSource(const char *str);
374*35238bceSAndroid Build Coastguard Worker void advanceToken(void);
375*35238bceSAndroid Build Coastguard Worker void advanceToken(Token assumed);
376*35238bceSAndroid Build Coastguard Worker void assumeToken(Token token);
377*35238bceSAndroid Build Coastguard Worker DataType mapDataTypeToken(Token token);
378*35238bceSAndroid Build Coastguard Worker const char *getTokenName(Token token);
379*35238bceSAndroid Build Coastguard Worker uint32_t getShaderStageLiteralFlag(void);
380*35238bceSAndroid Build Coastguard Worker uint32_t getGLEnumFromName(const std::string &enumName);
381*35238bceSAndroid Build Coastguard Worker
382*35238bceSAndroid Build Coastguard Worker void parseValueElement(DataType dataType, Value &result);
383*35238bceSAndroid Build Coastguard Worker void parseValue(ValueBlock &valueBlock);
384*35238bceSAndroid Build Coastguard Worker void parseValueBlock(ValueBlock &valueBlock);
385*35238bceSAndroid Build Coastguard Worker uint32_t parseShaderStageList(void);
386*35238bceSAndroid Build Coastguard Worker void parseRequirement(vector<RequiredCapability> &requiredCaps, vector<RequiredExtension> &requiredExts);
387*35238bceSAndroid Build Coastguard Worker void parseExpectResult(ExpectResult &expectResult);
388*35238bceSAndroid Build Coastguard Worker void parseFormat(DataType &format);
389*35238bceSAndroid Build Coastguard Worker void parseGLSLVersion(glu::GLSLVersion &version);
390*35238bceSAndroid Build Coastguard Worker void parsePipelineProgram(ProgramSpecification &program);
391*35238bceSAndroid Build Coastguard Worker void parseShaderCase(vector<tcu::TestNode *> &shaderNodeList);
392*35238bceSAndroid Build Coastguard Worker void parseShaderGroup(vector<tcu::TestNode *> &shaderNodeList);
393*35238bceSAndroid Build Coastguard Worker void parseImport(vector<tcu::TestNode *> &shaderNodeList);
394*35238bceSAndroid Build Coastguard Worker
395*35238bceSAndroid Build Coastguard Worker const tcu::Archive &m_archive;
396*35238bceSAndroid Build Coastguard Worker const string m_filename;
397*35238bceSAndroid Build Coastguard Worker ShaderCaseFactory *const m_caseFactory;
398*35238bceSAndroid Build Coastguard Worker
399*35238bceSAndroid Build Coastguard Worker UniquePtr<tcu::Resource> m_resource;
400*35238bceSAndroid Build Coastguard Worker vector<char> m_input;
401*35238bceSAndroid Build Coastguard Worker
402*35238bceSAndroid Build Coastguard Worker const char *m_curPtr;
403*35238bceSAndroid Build Coastguard Worker Token m_curToken;
404*35238bceSAndroid Build Coastguard Worker std::string m_curTokenStr;
405*35238bceSAndroid Build Coastguard Worker };
406*35238bceSAndroid Build Coastguard Worker
ShaderParser(const tcu::Archive & archive,const string & filename,ShaderCaseFactory * caseFactroy)407*35238bceSAndroid Build Coastguard Worker ShaderParser::ShaderParser(const tcu::Archive &archive, const string &filename, ShaderCaseFactory *caseFactroy)
408*35238bceSAndroid Build Coastguard Worker : m_archive(archive)
409*35238bceSAndroid Build Coastguard Worker , m_filename(filename)
410*35238bceSAndroid Build Coastguard Worker , m_caseFactory(caseFactroy)
411*35238bceSAndroid Build Coastguard Worker , m_resource(archive.getResource(m_filename.c_str()))
412*35238bceSAndroid Build Coastguard Worker , m_curPtr(DE_NULL)
413*35238bceSAndroid Build Coastguard Worker , m_curToken(TOKEN_LAST)
414*35238bceSAndroid Build Coastguard Worker {
415*35238bceSAndroid Build Coastguard Worker }
416*35238bceSAndroid Build Coastguard Worker
~ShaderParser(void)417*35238bceSAndroid Build Coastguard Worker ShaderParser::~ShaderParser(void)
418*35238bceSAndroid Build Coastguard Worker {
419*35238bceSAndroid Build Coastguard Worker }
420*35238bceSAndroid Build Coastguard Worker
parseError(const std::string & errorStr)421*35238bceSAndroid Build Coastguard Worker void ShaderParser::parseError(const std::string &errorStr)
422*35238bceSAndroid Build Coastguard Worker {
423*35238bceSAndroid Build Coastguard Worker string atStr = string(m_curPtr, 80);
424*35238bceSAndroid Build Coastguard Worker throw tcu::InternalError((string("Parser error: ") + errorStr + " near '" + atStr + " ...'").c_str(), DE_NULL,
425*35238bceSAndroid Build Coastguard Worker __FILE__, __LINE__);
426*35238bceSAndroid Build Coastguard Worker }
427*35238bceSAndroid Build Coastguard Worker
parseFloatLiteral(const char * str)428*35238bceSAndroid Build Coastguard Worker float ShaderParser::parseFloatLiteral(const char *str)
429*35238bceSAndroid Build Coastguard Worker {
430*35238bceSAndroid Build Coastguard Worker return (float)atof(str);
431*35238bceSAndroid Build Coastguard Worker }
432*35238bceSAndroid Build Coastguard Worker
parseIntLiteral(const char * str)433*35238bceSAndroid Build Coastguard Worker int ShaderParser::parseIntLiteral(const char *str)
434*35238bceSAndroid Build Coastguard Worker {
435*35238bceSAndroid Build Coastguard Worker return atoi(str);
436*35238bceSAndroid Build Coastguard Worker }
437*35238bceSAndroid Build Coastguard Worker
parseStringLiteral(const char * str)438*35238bceSAndroid Build Coastguard Worker string ShaderParser::parseStringLiteral(const char *str)
439*35238bceSAndroid Build Coastguard Worker {
440*35238bceSAndroid Build Coastguard Worker const char *p = str;
441*35238bceSAndroid Build Coastguard Worker char endChar = *p++;
442*35238bceSAndroid Build Coastguard Worker ostringstream o;
443*35238bceSAndroid Build Coastguard Worker
444*35238bceSAndroid Build Coastguard Worker while (*p != endChar && *p)
445*35238bceSAndroid Build Coastguard Worker {
446*35238bceSAndroid Build Coastguard Worker if (*p == '\\')
447*35238bceSAndroid Build Coastguard Worker {
448*35238bceSAndroid Build Coastguard Worker switch (p[1])
449*35238bceSAndroid Build Coastguard Worker {
450*35238bceSAndroid Build Coastguard Worker case 0:
451*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
452*35238bceSAndroid Build Coastguard Worker break;
453*35238bceSAndroid Build Coastguard Worker case 'n':
454*35238bceSAndroid Build Coastguard Worker o << '\n';
455*35238bceSAndroid Build Coastguard Worker break;
456*35238bceSAndroid Build Coastguard Worker case 't':
457*35238bceSAndroid Build Coastguard Worker o << '\t';
458*35238bceSAndroid Build Coastguard Worker break;
459*35238bceSAndroid Build Coastguard Worker default:
460*35238bceSAndroid Build Coastguard Worker o << p[1];
461*35238bceSAndroid Build Coastguard Worker break;
462*35238bceSAndroid Build Coastguard Worker }
463*35238bceSAndroid Build Coastguard Worker
464*35238bceSAndroid Build Coastguard Worker p += 2;
465*35238bceSAndroid Build Coastguard Worker }
466*35238bceSAndroid Build Coastguard Worker else
467*35238bceSAndroid Build Coastguard Worker o << *p++;
468*35238bceSAndroid Build Coastguard Worker }
469*35238bceSAndroid Build Coastguard Worker
470*35238bceSAndroid Build Coastguard Worker return o.str();
471*35238bceSAndroid Build Coastguard Worker }
472*35238bceSAndroid Build Coastguard Worker
removeExtraIndentation(const string & source)473*35238bceSAndroid Build Coastguard Worker static string removeExtraIndentation(const string &source)
474*35238bceSAndroid Build Coastguard Worker {
475*35238bceSAndroid Build Coastguard Worker // Detect indentation from first line.
476*35238bceSAndroid Build Coastguard Worker int numIndentChars = 0;
477*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < (int)source.length() && isWhitespace(source[ndx]); ndx++)
478*35238bceSAndroid Build Coastguard Worker numIndentChars += source[ndx] == '\t' ? 4 : 1;
479*35238bceSAndroid Build Coastguard Worker
480*35238bceSAndroid Build Coastguard Worker // Process all lines and remove preceding indentation.
481*35238bceSAndroid Build Coastguard Worker ostringstream processed;
482*35238bceSAndroid Build Coastguard Worker {
483*35238bceSAndroid Build Coastguard Worker bool atLineStart = true;
484*35238bceSAndroid Build Coastguard Worker int indentCharsOmitted = 0;
485*35238bceSAndroid Build Coastguard Worker
486*35238bceSAndroid Build Coastguard Worker for (int pos = 0; pos < (int)source.length(); pos++)
487*35238bceSAndroid Build Coastguard Worker {
488*35238bceSAndroid Build Coastguard Worker char c = source[pos];
489*35238bceSAndroid Build Coastguard Worker
490*35238bceSAndroid Build Coastguard Worker if (atLineStart && indentCharsOmitted < numIndentChars && (c == ' ' || c == '\t'))
491*35238bceSAndroid Build Coastguard Worker {
492*35238bceSAndroid Build Coastguard Worker indentCharsOmitted += c == '\t' ? 4 : 1;
493*35238bceSAndroid Build Coastguard Worker }
494*35238bceSAndroid Build Coastguard Worker else if (isEOL(c))
495*35238bceSAndroid Build Coastguard Worker {
496*35238bceSAndroid Build Coastguard Worker if (source[pos] == '\r' && source[pos + 1] == '\n')
497*35238bceSAndroid Build Coastguard Worker {
498*35238bceSAndroid Build Coastguard Worker pos += 1;
499*35238bceSAndroid Build Coastguard Worker processed << '\n';
500*35238bceSAndroid Build Coastguard Worker }
501*35238bceSAndroid Build Coastguard Worker else
502*35238bceSAndroid Build Coastguard Worker processed << c;
503*35238bceSAndroid Build Coastguard Worker
504*35238bceSAndroid Build Coastguard Worker atLineStart = true;
505*35238bceSAndroid Build Coastguard Worker indentCharsOmitted = 0;
506*35238bceSAndroid Build Coastguard Worker }
507*35238bceSAndroid Build Coastguard Worker else
508*35238bceSAndroid Build Coastguard Worker {
509*35238bceSAndroid Build Coastguard Worker processed << c;
510*35238bceSAndroid Build Coastguard Worker atLineStart = false;
511*35238bceSAndroid Build Coastguard Worker }
512*35238bceSAndroid Build Coastguard Worker }
513*35238bceSAndroid Build Coastguard Worker }
514*35238bceSAndroid Build Coastguard Worker
515*35238bceSAndroid Build Coastguard Worker return processed.str();
516*35238bceSAndroid Build Coastguard Worker }
517*35238bceSAndroid Build Coastguard Worker
parseShaderSource(const char * str)518*35238bceSAndroid Build Coastguard Worker string ShaderParser::parseShaderSource(const char *str)
519*35238bceSAndroid Build Coastguard Worker {
520*35238bceSAndroid Build Coastguard Worker const char *p = str + 2;
521*35238bceSAndroid Build Coastguard Worker ostringstream o;
522*35238bceSAndroid Build Coastguard Worker
523*35238bceSAndroid Build Coastguard Worker // Eat first empty line from beginning.
524*35238bceSAndroid Build Coastguard Worker while (*p == ' ')
525*35238bceSAndroid Build Coastguard Worker p++;
526*35238bceSAndroid Build Coastguard Worker if (*p == '\r')
527*35238bceSAndroid Build Coastguard Worker p++;
528*35238bceSAndroid Build Coastguard Worker if (*p == '\n')
529*35238bceSAndroid Build Coastguard Worker p++;
530*35238bceSAndroid Build Coastguard Worker
531*35238bceSAndroid Build Coastguard Worker while ((p[0] != '"') || (p[1] != '"'))
532*35238bceSAndroid Build Coastguard Worker {
533*35238bceSAndroid Build Coastguard Worker if (*p == '\\')
534*35238bceSAndroid Build Coastguard Worker {
535*35238bceSAndroid Build Coastguard Worker switch (p[1])
536*35238bceSAndroid Build Coastguard Worker {
537*35238bceSAndroid Build Coastguard Worker case 0:
538*35238bceSAndroid Build Coastguard Worker DE_ASSERT(false);
539*35238bceSAndroid Build Coastguard Worker break;
540*35238bceSAndroid Build Coastguard Worker case 'n':
541*35238bceSAndroid Build Coastguard Worker o << '\n';
542*35238bceSAndroid Build Coastguard Worker break;
543*35238bceSAndroid Build Coastguard Worker case 't':
544*35238bceSAndroid Build Coastguard Worker o << '\t';
545*35238bceSAndroid Build Coastguard Worker break;
546*35238bceSAndroid Build Coastguard Worker default:
547*35238bceSAndroid Build Coastguard Worker o << p[1];
548*35238bceSAndroid Build Coastguard Worker break;
549*35238bceSAndroid Build Coastguard Worker }
550*35238bceSAndroid Build Coastguard Worker
551*35238bceSAndroid Build Coastguard Worker p += 2;
552*35238bceSAndroid Build Coastguard Worker }
553*35238bceSAndroid Build Coastguard Worker else
554*35238bceSAndroid Build Coastguard Worker o << *p++;
555*35238bceSAndroid Build Coastguard Worker }
556*35238bceSAndroid Build Coastguard Worker
557*35238bceSAndroid Build Coastguard Worker return removeExtraIndentation(o.str());
558*35238bceSAndroid Build Coastguard Worker }
559*35238bceSAndroid Build Coastguard Worker
advanceToken(void)560*35238bceSAndroid Build Coastguard Worker void ShaderParser::advanceToken(void)
561*35238bceSAndroid Build Coastguard Worker {
562*35238bceSAndroid Build Coastguard Worker // Skip old token.
563*35238bceSAndroid Build Coastguard Worker m_curPtr += m_curTokenStr.length();
564*35238bceSAndroid Build Coastguard Worker
565*35238bceSAndroid Build Coastguard Worker // Reset token (for safety).
566*35238bceSAndroid Build Coastguard Worker m_curToken = TOKEN_INVALID;
567*35238bceSAndroid Build Coastguard Worker m_curTokenStr = "";
568*35238bceSAndroid Build Coastguard Worker
569*35238bceSAndroid Build Coastguard Worker // Eat whitespace & comments while they last.
570*35238bceSAndroid Build Coastguard Worker for (;;)
571*35238bceSAndroid Build Coastguard Worker {
572*35238bceSAndroid Build Coastguard Worker while (isWhitespace(*m_curPtr))
573*35238bceSAndroid Build Coastguard Worker m_curPtr++;
574*35238bceSAndroid Build Coastguard Worker
575*35238bceSAndroid Build Coastguard Worker // Check for EOL comment.
576*35238bceSAndroid Build Coastguard Worker if (*m_curPtr == '#')
577*35238bceSAndroid Build Coastguard Worker {
578*35238bceSAndroid Build Coastguard Worker while (*m_curPtr && !isEOL(*m_curPtr))
579*35238bceSAndroid Build Coastguard Worker m_curPtr++;
580*35238bceSAndroid Build Coastguard Worker }
581*35238bceSAndroid Build Coastguard Worker else
582*35238bceSAndroid Build Coastguard Worker break;
583*35238bceSAndroid Build Coastguard Worker }
584*35238bceSAndroid Build Coastguard Worker
585*35238bceSAndroid Build Coastguard Worker if (!*m_curPtr)
586*35238bceSAndroid Build Coastguard Worker {
587*35238bceSAndroid Build Coastguard Worker m_curToken = TOKEN_EOF;
588*35238bceSAndroid Build Coastguard Worker m_curTokenStr = "<EOF>";
589*35238bceSAndroid Build Coastguard Worker }
590*35238bceSAndroid Build Coastguard Worker else if (isAlpha(*m_curPtr))
591*35238bceSAndroid Build Coastguard Worker {
592*35238bceSAndroid Build Coastguard Worker struct Named
593*35238bceSAndroid Build Coastguard Worker {
594*35238bceSAndroid Build Coastguard Worker const char *str;
595*35238bceSAndroid Build Coastguard Worker Token token;
596*35238bceSAndroid Build Coastguard Worker };
597*35238bceSAndroid Build Coastguard Worker
598*35238bceSAndroid Build Coastguard Worker static const Named s_named[] = {
599*35238bceSAndroid Build Coastguard Worker {"true", TOKEN_TRUE},
600*35238bceSAndroid Build Coastguard Worker {"false", TOKEN_FALSE},
601*35238bceSAndroid Build Coastguard Worker {"desc", TOKEN_DESC},
602*35238bceSAndroid Build Coastguard Worker {"expect", TOKEN_EXPECT},
603*35238bceSAndroid Build Coastguard Worker {"group", TOKEN_GROUP},
604*35238bceSAndroid Build Coastguard Worker {"case", TOKEN_CASE},
605*35238bceSAndroid Build Coastguard Worker {"end", TOKEN_END},
606*35238bceSAndroid Build Coastguard Worker {"output_color", TOKEN_OUTPUT_COLOR},
607*35238bceSAndroid Build Coastguard Worker {"format", TOKEN_FORMAT},
608*35238bceSAndroid Build Coastguard Worker {"values", TOKEN_VALUES},
609*35238bceSAndroid Build Coastguard Worker {"both", TOKEN_BOTH},
610*35238bceSAndroid Build Coastguard Worker {"vertex", TOKEN_VERTEX},
611*35238bceSAndroid Build Coastguard Worker {"fragment", TOKEN_FRAGMENT},
612*35238bceSAndroid Build Coastguard Worker {"uniform", TOKEN_UNIFORM},
613*35238bceSAndroid Build Coastguard Worker {"input", TOKEN_INPUT},
614*35238bceSAndroid Build Coastguard Worker {"output", TOKEN_OUTPUT},
615*35238bceSAndroid Build Coastguard Worker {"float", TOKEN_FLOAT},
616*35238bceSAndroid Build Coastguard Worker {"vec2", TOKEN_FLOAT_VEC2},
617*35238bceSAndroid Build Coastguard Worker {"vec3", TOKEN_FLOAT_VEC3},
618*35238bceSAndroid Build Coastguard Worker {"vec4", TOKEN_FLOAT_VEC4},
619*35238bceSAndroid Build Coastguard Worker {"mat2", TOKEN_FLOAT_MAT2},
620*35238bceSAndroid Build Coastguard Worker {"mat2x3", TOKEN_FLOAT_MAT2X3},
621*35238bceSAndroid Build Coastguard Worker {"mat2x4", TOKEN_FLOAT_MAT2X4},
622*35238bceSAndroid Build Coastguard Worker {"mat3x2", TOKEN_FLOAT_MAT3X2},
623*35238bceSAndroid Build Coastguard Worker {"mat3", TOKEN_FLOAT_MAT3},
624*35238bceSAndroid Build Coastguard Worker {"mat3x4", TOKEN_FLOAT_MAT3X4},
625*35238bceSAndroid Build Coastguard Worker {"mat4x2", TOKEN_FLOAT_MAT4X2},
626*35238bceSAndroid Build Coastguard Worker {"mat4x3", TOKEN_FLOAT_MAT4X3},
627*35238bceSAndroid Build Coastguard Worker {"mat4", TOKEN_FLOAT_MAT4},
628*35238bceSAndroid Build Coastguard Worker {"int", TOKEN_INT},
629*35238bceSAndroid Build Coastguard Worker {"ivec2", TOKEN_INT_VEC2},
630*35238bceSAndroid Build Coastguard Worker {"ivec3", TOKEN_INT_VEC3},
631*35238bceSAndroid Build Coastguard Worker {"ivec4", TOKEN_INT_VEC4},
632*35238bceSAndroid Build Coastguard Worker {"uint", TOKEN_UINT},
633*35238bceSAndroid Build Coastguard Worker {"uvec2", TOKEN_UINT_VEC2},
634*35238bceSAndroid Build Coastguard Worker {"uvec3", TOKEN_UINT_VEC3},
635*35238bceSAndroid Build Coastguard Worker {"uvec4", TOKEN_UINT_VEC4},
636*35238bceSAndroid Build Coastguard Worker {"bool", TOKEN_BOOL},
637*35238bceSAndroid Build Coastguard Worker {"bvec2", TOKEN_BOOL_VEC2},
638*35238bceSAndroid Build Coastguard Worker {"bvec3", TOKEN_BOOL_VEC3},
639*35238bceSAndroid Build Coastguard Worker {"bvec4", TOKEN_BOOL_VEC4},
640*35238bceSAndroid Build Coastguard Worker {"version", TOKEN_VERSION},
641*35238bceSAndroid Build Coastguard Worker {"tessellation_control", TOKEN_TESSELLATION_CONTROL},
642*35238bceSAndroid Build Coastguard Worker {"tessellation_evaluation", TOKEN_TESSELLATION_EVALUATION},
643*35238bceSAndroid Build Coastguard Worker {"geometry", TOKEN_GEOMETRY},
644*35238bceSAndroid Build Coastguard Worker {"require", TOKEN_REQUIRE},
645*35238bceSAndroid Build Coastguard Worker {"in", TOKEN_IN},
646*35238bceSAndroid Build Coastguard Worker {"import", TOKEN_IMPORT},
647*35238bceSAndroid Build Coastguard Worker {"pipeline_program", TOKEN_PIPELINE_PROGRAM},
648*35238bceSAndroid Build Coastguard Worker {"active_stages", TOKEN_ACTIVE_STAGES},
649*35238bceSAndroid Build Coastguard Worker };
650*35238bceSAndroid Build Coastguard Worker
651*35238bceSAndroid Build Coastguard Worker const char *end = m_curPtr + 1;
652*35238bceSAndroid Build Coastguard Worker while (isCaseNameChar(*end))
653*35238bceSAndroid Build Coastguard Worker end++;
654*35238bceSAndroid Build Coastguard Worker m_curTokenStr = string(m_curPtr, end - m_curPtr);
655*35238bceSAndroid Build Coastguard Worker
656*35238bceSAndroid Build Coastguard Worker m_curToken = TOKEN_IDENTIFIER;
657*35238bceSAndroid Build Coastguard Worker
658*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_named); ndx++)
659*35238bceSAndroid Build Coastguard Worker {
660*35238bceSAndroid Build Coastguard Worker if (m_curTokenStr == s_named[ndx].str)
661*35238bceSAndroid Build Coastguard Worker {
662*35238bceSAndroid Build Coastguard Worker m_curToken = s_named[ndx].token;
663*35238bceSAndroid Build Coastguard Worker break;
664*35238bceSAndroid Build Coastguard Worker }
665*35238bceSAndroid Build Coastguard Worker }
666*35238bceSAndroid Build Coastguard Worker }
667*35238bceSAndroid Build Coastguard Worker else if (isNumeric(*m_curPtr))
668*35238bceSAndroid Build Coastguard Worker {
669*35238bceSAndroid Build Coastguard Worker /* \todo [2010-03-31 petri] Hex? */
670*35238bceSAndroid Build Coastguard Worker const char *p = m_curPtr;
671*35238bceSAndroid Build Coastguard Worker while (isNumeric(*p))
672*35238bceSAndroid Build Coastguard Worker p++;
673*35238bceSAndroid Build Coastguard Worker if (*p == '.')
674*35238bceSAndroid Build Coastguard Worker {
675*35238bceSAndroid Build Coastguard Worker p++;
676*35238bceSAndroid Build Coastguard Worker while (isNumeric(*p))
677*35238bceSAndroid Build Coastguard Worker p++;
678*35238bceSAndroid Build Coastguard Worker
679*35238bceSAndroid Build Coastguard Worker if (*p == 'e' || *p == 'E')
680*35238bceSAndroid Build Coastguard Worker {
681*35238bceSAndroid Build Coastguard Worker p++;
682*35238bceSAndroid Build Coastguard Worker if (*p == '+' || *p == '-')
683*35238bceSAndroid Build Coastguard Worker p++;
684*35238bceSAndroid Build Coastguard Worker DE_ASSERT(isNumeric(*p));
685*35238bceSAndroid Build Coastguard Worker while (isNumeric(*p))
686*35238bceSAndroid Build Coastguard Worker p++;
687*35238bceSAndroid Build Coastguard Worker }
688*35238bceSAndroid Build Coastguard Worker
689*35238bceSAndroid Build Coastguard Worker m_curToken = TOKEN_FLOAT_LITERAL;
690*35238bceSAndroid Build Coastguard Worker m_curTokenStr = string(m_curPtr, p - m_curPtr);
691*35238bceSAndroid Build Coastguard Worker }
692*35238bceSAndroid Build Coastguard Worker else
693*35238bceSAndroid Build Coastguard Worker {
694*35238bceSAndroid Build Coastguard Worker m_curToken = TOKEN_INT_LITERAL;
695*35238bceSAndroid Build Coastguard Worker m_curTokenStr = string(m_curPtr, p - m_curPtr);
696*35238bceSAndroid Build Coastguard Worker }
697*35238bceSAndroid Build Coastguard Worker }
698*35238bceSAndroid Build Coastguard Worker else if (*m_curPtr == '"' && m_curPtr[1] == '"')
699*35238bceSAndroid Build Coastguard Worker {
700*35238bceSAndroid Build Coastguard Worker const char *p = m_curPtr + 2;
701*35238bceSAndroid Build Coastguard Worker
702*35238bceSAndroid Build Coastguard Worker while ((p[0] != '"') || (p[1] != '"'))
703*35238bceSAndroid Build Coastguard Worker {
704*35238bceSAndroid Build Coastguard Worker DE_ASSERT(*p);
705*35238bceSAndroid Build Coastguard Worker if (*p == '\\')
706*35238bceSAndroid Build Coastguard Worker {
707*35238bceSAndroid Build Coastguard Worker DE_ASSERT(p[1] != 0);
708*35238bceSAndroid Build Coastguard Worker p += 2;
709*35238bceSAndroid Build Coastguard Worker }
710*35238bceSAndroid Build Coastguard Worker else
711*35238bceSAndroid Build Coastguard Worker p++;
712*35238bceSAndroid Build Coastguard Worker }
713*35238bceSAndroid Build Coastguard Worker p += 2;
714*35238bceSAndroid Build Coastguard Worker
715*35238bceSAndroid Build Coastguard Worker m_curToken = TOKEN_SHADER_SOURCE;
716*35238bceSAndroid Build Coastguard Worker m_curTokenStr = string(m_curPtr, (int)(p - m_curPtr));
717*35238bceSAndroid Build Coastguard Worker }
718*35238bceSAndroid Build Coastguard Worker else if (*m_curPtr == '"' || *m_curPtr == '\'')
719*35238bceSAndroid Build Coastguard Worker {
720*35238bceSAndroid Build Coastguard Worker char endChar = *m_curPtr;
721*35238bceSAndroid Build Coastguard Worker const char *p = m_curPtr + 1;
722*35238bceSAndroid Build Coastguard Worker
723*35238bceSAndroid Build Coastguard Worker while (*p != endChar)
724*35238bceSAndroid Build Coastguard Worker {
725*35238bceSAndroid Build Coastguard Worker DE_ASSERT(*p);
726*35238bceSAndroid Build Coastguard Worker if (*p == '\\')
727*35238bceSAndroid Build Coastguard Worker {
728*35238bceSAndroid Build Coastguard Worker DE_ASSERT(p[1] != 0);
729*35238bceSAndroid Build Coastguard Worker p += 2;
730*35238bceSAndroid Build Coastguard Worker }
731*35238bceSAndroid Build Coastguard Worker else
732*35238bceSAndroid Build Coastguard Worker p++;
733*35238bceSAndroid Build Coastguard Worker }
734*35238bceSAndroid Build Coastguard Worker p++;
735*35238bceSAndroid Build Coastguard Worker
736*35238bceSAndroid Build Coastguard Worker m_curToken = TOKEN_STRING;
737*35238bceSAndroid Build Coastguard Worker m_curTokenStr = string(m_curPtr, (int)(p - m_curPtr));
738*35238bceSAndroid Build Coastguard Worker }
739*35238bceSAndroid Build Coastguard Worker else
740*35238bceSAndroid Build Coastguard Worker {
741*35238bceSAndroid Build Coastguard Worker struct SimpleToken
742*35238bceSAndroid Build Coastguard Worker {
743*35238bceSAndroid Build Coastguard Worker const char *str;
744*35238bceSAndroid Build Coastguard Worker Token token;
745*35238bceSAndroid Build Coastguard Worker };
746*35238bceSAndroid Build Coastguard Worker
747*35238bceSAndroid Build Coastguard Worker static const SimpleToken s_simple[] = {
748*35238bceSAndroid Build Coastguard Worker {"=", TOKEN_ASSIGN}, {"+", TOKEN_PLUS}, {"-", TOKEN_MINUS}, {",", TOKEN_COMMA},
749*35238bceSAndroid Build Coastguard Worker {"|", TOKEN_VERTICAL_BAR}, {";", TOKEN_SEMI_COLON}, {"(", TOKEN_LEFT_PAREN}, {")", TOKEN_RIGHT_PAREN},
750*35238bceSAndroid Build Coastguard Worker {"[", TOKEN_LEFT_BRACKET}, {"]", TOKEN_RIGHT_BRACKET}, {"{", TOKEN_LEFT_BRACE}, {"}", TOKEN_RIGHT_BRACE},
751*35238bceSAndroid Build Coastguard Worker {">", TOKEN_GREATER},
752*35238bceSAndroid Build Coastguard Worker };
753*35238bceSAndroid Build Coastguard Worker
754*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_simple); ndx++)
755*35238bceSAndroid Build Coastguard Worker {
756*35238bceSAndroid Build Coastguard Worker if (strncmp(s_simple[ndx].str, m_curPtr, strlen(s_simple[ndx].str)) == 0)
757*35238bceSAndroid Build Coastguard Worker {
758*35238bceSAndroid Build Coastguard Worker m_curToken = s_simple[ndx].token;
759*35238bceSAndroid Build Coastguard Worker m_curTokenStr = s_simple[ndx].str;
760*35238bceSAndroid Build Coastguard Worker return;
761*35238bceSAndroid Build Coastguard Worker }
762*35238bceSAndroid Build Coastguard Worker }
763*35238bceSAndroid Build Coastguard Worker
764*35238bceSAndroid Build Coastguard Worker // Otherwise invalid token.
765*35238bceSAndroid Build Coastguard Worker m_curToken = TOKEN_INVALID;
766*35238bceSAndroid Build Coastguard Worker m_curTokenStr = *m_curPtr;
767*35238bceSAndroid Build Coastguard Worker }
768*35238bceSAndroid Build Coastguard Worker }
769*35238bceSAndroid Build Coastguard Worker
advanceToken(Token assumed)770*35238bceSAndroid Build Coastguard Worker void ShaderParser::advanceToken(Token assumed)
771*35238bceSAndroid Build Coastguard Worker {
772*35238bceSAndroid Build Coastguard Worker assumeToken(assumed);
773*35238bceSAndroid Build Coastguard Worker advanceToken();
774*35238bceSAndroid Build Coastguard Worker }
775*35238bceSAndroid Build Coastguard Worker
assumeToken(Token token)776*35238bceSAndroid Build Coastguard Worker void ShaderParser::assumeToken(Token token)
777*35238bceSAndroid Build Coastguard Worker {
778*35238bceSAndroid Build Coastguard Worker if (m_curToken != token)
779*35238bceSAndroid Build Coastguard Worker parseError(
780*35238bceSAndroid Build Coastguard Worker (string("unexpected token '") + m_curTokenStr + "', expecting '" + getTokenName(token) + "'").c_str());
781*35238bceSAndroid Build Coastguard Worker DE_TEST_ASSERT(m_curToken == token);
782*35238bceSAndroid Build Coastguard Worker }
783*35238bceSAndroid Build Coastguard Worker
mapDataTypeToken(Token token)784*35238bceSAndroid Build Coastguard Worker DataType ShaderParser::mapDataTypeToken(Token token)
785*35238bceSAndroid Build Coastguard Worker {
786*35238bceSAndroid Build Coastguard Worker switch (token)
787*35238bceSAndroid Build Coastguard Worker {
788*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT:
789*35238bceSAndroid Build Coastguard Worker return TYPE_FLOAT;
790*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_VEC2:
791*35238bceSAndroid Build Coastguard Worker return TYPE_FLOAT_VEC2;
792*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_VEC3:
793*35238bceSAndroid Build Coastguard Worker return TYPE_FLOAT_VEC3;
794*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_VEC4:
795*35238bceSAndroid Build Coastguard Worker return TYPE_FLOAT_VEC4;
796*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_MAT2:
797*35238bceSAndroid Build Coastguard Worker return TYPE_FLOAT_MAT2;
798*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_MAT2X3:
799*35238bceSAndroid Build Coastguard Worker return TYPE_FLOAT_MAT2X3;
800*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_MAT2X4:
801*35238bceSAndroid Build Coastguard Worker return TYPE_FLOAT_MAT2X4;
802*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_MAT3X2:
803*35238bceSAndroid Build Coastguard Worker return TYPE_FLOAT_MAT3X2;
804*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_MAT3:
805*35238bceSAndroid Build Coastguard Worker return TYPE_FLOAT_MAT3;
806*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_MAT3X4:
807*35238bceSAndroid Build Coastguard Worker return TYPE_FLOAT_MAT3X4;
808*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_MAT4X2:
809*35238bceSAndroid Build Coastguard Worker return TYPE_FLOAT_MAT4X2;
810*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_MAT4X3:
811*35238bceSAndroid Build Coastguard Worker return TYPE_FLOAT_MAT4X3;
812*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_MAT4:
813*35238bceSAndroid Build Coastguard Worker return TYPE_FLOAT_MAT4;
814*35238bceSAndroid Build Coastguard Worker case TOKEN_INT:
815*35238bceSAndroid Build Coastguard Worker return TYPE_INT;
816*35238bceSAndroid Build Coastguard Worker case TOKEN_INT_VEC2:
817*35238bceSAndroid Build Coastguard Worker return TYPE_INT_VEC2;
818*35238bceSAndroid Build Coastguard Worker case TOKEN_INT_VEC3:
819*35238bceSAndroid Build Coastguard Worker return TYPE_INT_VEC3;
820*35238bceSAndroid Build Coastguard Worker case TOKEN_INT_VEC4:
821*35238bceSAndroid Build Coastguard Worker return TYPE_INT_VEC4;
822*35238bceSAndroid Build Coastguard Worker case TOKEN_UINT:
823*35238bceSAndroid Build Coastguard Worker return TYPE_UINT;
824*35238bceSAndroid Build Coastguard Worker case TOKEN_UINT_VEC2:
825*35238bceSAndroid Build Coastguard Worker return TYPE_UINT_VEC2;
826*35238bceSAndroid Build Coastguard Worker case TOKEN_UINT_VEC3:
827*35238bceSAndroid Build Coastguard Worker return TYPE_UINT_VEC3;
828*35238bceSAndroid Build Coastguard Worker case TOKEN_UINT_VEC4:
829*35238bceSAndroid Build Coastguard Worker return TYPE_UINT_VEC4;
830*35238bceSAndroid Build Coastguard Worker case TOKEN_BOOL:
831*35238bceSAndroid Build Coastguard Worker return TYPE_BOOL;
832*35238bceSAndroid Build Coastguard Worker case TOKEN_BOOL_VEC2:
833*35238bceSAndroid Build Coastguard Worker return TYPE_BOOL_VEC2;
834*35238bceSAndroid Build Coastguard Worker case TOKEN_BOOL_VEC3:
835*35238bceSAndroid Build Coastguard Worker return TYPE_BOOL_VEC3;
836*35238bceSAndroid Build Coastguard Worker case TOKEN_BOOL_VEC4:
837*35238bceSAndroid Build Coastguard Worker return TYPE_BOOL_VEC4;
838*35238bceSAndroid Build Coastguard Worker default:
839*35238bceSAndroid Build Coastguard Worker return TYPE_INVALID;
840*35238bceSAndroid Build Coastguard Worker }
841*35238bceSAndroid Build Coastguard Worker }
842*35238bceSAndroid Build Coastguard Worker
getTokenName(Token token)843*35238bceSAndroid Build Coastguard Worker const char *ShaderParser::getTokenName(Token token)
844*35238bceSAndroid Build Coastguard Worker {
845*35238bceSAndroid Build Coastguard Worker switch (token)
846*35238bceSAndroid Build Coastguard Worker {
847*35238bceSAndroid Build Coastguard Worker case TOKEN_INVALID:
848*35238bceSAndroid Build Coastguard Worker return "<invalid>";
849*35238bceSAndroid Build Coastguard Worker case TOKEN_EOF:
850*35238bceSAndroid Build Coastguard Worker return "<eof>";
851*35238bceSAndroid Build Coastguard Worker case TOKEN_STRING:
852*35238bceSAndroid Build Coastguard Worker return "<string>";
853*35238bceSAndroid Build Coastguard Worker case TOKEN_SHADER_SOURCE:
854*35238bceSAndroid Build Coastguard Worker return "source";
855*35238bceSAndroid Build Coastguard Worker
856*35238bceSAndroid Build Coastguard Worker case TOKEN_INT_LITERAL:
857*35238bceSAndroid Build Coastguard Worker return "<int>";
858*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_LITERAL:
859*35238bceSAndroid Build Coastguard Worker return "<float>";
860*35238bceSAndroid Build Coastguard Worker
861*35238bceSAndroid Build Coastguard Worker // identifiers
862*35238bceSAndroid Build Coastguard Worker case TOKEN_IDENTIFIER:
863*35238bceSAndroid Build Coastguard Worker return "<identifier>";
864*35238bceSAndroid Build Coastguard Worker case TOKEN_TRUE:
865*35238bceSAndroid Build Coastguard Worker return "true";
866*35238bceSAndroid Build Coastguard Worker case TOKEN_FALSE:
867*35238bceSAndroid Build Coastguard Worker return "false";
868*35238bceSAndroid Build Coastguard Worker case TOKEN_DESC:
869*35238bceSAndroid Build Coastguard Worker return "desc";
870*35238bceSAndroid Build Coastguard Worker case TOKEN_EXPECT:
871*35238bceSAndroid Build Coastguard Worker return "expect";
872*35238bceSAndroid Build Coastguard Worker case TOKEN_GROUP:
873*35238bceSAndroid Build Coastguard Worker return "group";
874*35238bceSAndroid Build Coastguard Worker case TOKEN_CASE:
875*35238bceSAndroid Build Coastguard Worker return "case";
876*35238bceSAndroid Build Coastguard Worker case TOKEN_END:
877*35238bceSAndroid Build Coastguard Worker return "end";
878*35238bceSAndroid Build Coastguard Worker case TOKEN_VALUES:
879*35238bceSAndroid Build Coastguard Worker return "values";
880*35238bceSAndroid Build Coastguard Worker case TOKEN_BOTH:
881*35238bceSAndroid Build Coastguard Worker return "both";
882*35238bceSAndroid Build Coastguard Worker case TOKEN_VERTEX:
883*35238bceSAndroid Build Coastguard Worker return "vertex";
884*35238bceSAndroid Build Coastguard Worker case TOKEN_FRAGMENT:
885*35238bceSAndroid Build Coastguard Worker return "fragment";
886*35238bceSAndroid Build Coastguard Worker case TOKEN_TESSELLATION_CONTROL:
887*35238bceSAndroid Build Coastguard Worker return "tessellation_control";
888*35238bceSAndroid Build Coastguard Worker case TOKEN_TESSELLATION_EVALUATION:
889*35238bceSAndroid Build Coastguard Worker return "tessellation_evaluation";
890*35238bceSAndroid Build Coastguard Worker case TOKEN_GEOMETRY:
891*35238bceSAndroid Build Coastguard Worker return "geometry";
892*35238bceSAndroid Build Coastguard Worker case TOKEN_REQUIRE:
893*35238bceSAndroid Build Coastguard Worker return "require";
894*35238bceSAndroid Build Coastguard Worker case TOKEN_UNIFORM:
895*35238bceSAndroid Build Coastguard Worker return "uniform";
896*35238bceSAndroid Build Coastguard Worker case TOKEN_INPUT:
897*35238bceSAndroid Build Coastguard Worker return "input";
898*35238bceSAndroid Build Coastguard Worker case TOKEN_OUTPUT:
899*35238bceSAndroid Build Coastguard Worker return "output";
900*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT:
901*35238bceSAndroid Build Coastguard Worker return "float";
902*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_VEC2:
903*35238bceSAndroid Build Coastguard Worker return "vec2";
904*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_VEC3:
905*35238bceSAndroid Build Coastguard Worker return "vec3";
906*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_VEC4:
907*35238bceSAndroid Build Coastguard Worker return "vec4";
908*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_MAT2:
909*35238bceSAndroid Build Coastguard Worker return "mat2";
910*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_MAT2X3:
911*35238bceSAndroid Build Coastguard Worker return "mat2x3";
912*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_MAT2X4:
913*35238bceSAndroid Build Coastguard Worker return "mat2x4";
914*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_MAT3X2:
915*35238bceSAndroid Build Coastguard Worker return "mat3x2";
916*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_MAT3:
917*35238bceSAndroid Build Coastguard Worker return "mat3";
918*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_MAT3X4:
919*35238bceSAndroid Build Coastguard Worker return "mat3x4";
920*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_MAT4X2:
921*35238bceSAndroid Build Coastguard Worker return "mat4x2";
922*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_MAT4X3:
923*35238bceSAndroid Build Coastguard Worker return "mat4x3";
924*35238bceSAndroid Build Coastguard Worker case TOKEN_FLOAT_MAT4:
925*35238bceSAndroid Build Coastguard Worker return "mat4";
926*35238bceSAndroid Build Coastguard Worker case TOKEN_INT:
927*35238bceSAndroid Build Coastguard Worker return "int";
928*35238bceSAndroid Build Coastguard Worker case TOKEN_INT_VEC2:
929*35238bceSAndroid Build Coastguard Worker return "ivec2";
930*35238bceSAndroid Build Coastguard Worker case TOKEN_INT_VEC3:
931*35238bceSAndroid Build Coastguard Worker return "ivec3";
932*35238bceSAndroid Build Coastguard Worker case TOKEN_INT_VEC4:
933*35238bceSAndroid Build Coastguard Worker return "ivec4";
934*35238bceSAndroid Build Coastguard Worker case TOKEN_UINT:
935*35238bceSAndroid Build Coastguard Worker return "uint";
936*35238bceSAndroid Build Coastguard Worker case TOKEN_UINT_VEC2:
937*35238bceSAndroid Build Coastguard Worker return "uvec2";
938*35238bceSAndroid Build Coastguard Worker case TOKEN_UINT_VEC3:
939*35238bceSAndroid Build Coastguard Worker return "uvec3";
940*35238bceSAndroid Build Coastguard Worker case TOKEN_UINT_VEC4:
941*35238bceSAndroid Build Coastguard Worker return "uvec4";
942*35238bceSAndroid Build Coastguard Worker case TOKEN_BOOL:
943*35238bceSAndroid Build Coastguard Worker return "bool";
944*35238bceSAndroid Build Coastguard Worker case TOKEN_BOOL_VEC2:
945*35238bceSAndroid Build Coastguard Worker return "bvec2";
946*35238bceSAndroid Build Coastguard Worker case TOKEN_BOOL_VEC3:
947*35238bceSAndroid Build Coastguard Worker return "bvec3";
948*35238bceSAndroid Build Coastguard Worker case TOKEN_BOOL_VEC4:
949*35238bceSAndroid Build Coastguard Worker return "bvec4";
950*35238bceSAndroid Build Coastguard Worker case TOKEN_IN:
951*35238bceSAndroid Build Coastguard Worker return "in";
952*35238bceSAndroid Build Coastguard Worker case TOKEN_IMPORT:
953*35238bceSAndroid Build Coastguard Worker return "import";
954*35238bceSAndroid Build Coastguard Worker case TOKEN_PIPELINE_PROGRAM:
955*35238bceSAndroid Build Coastguard Worker return "pipeline_program";
956*35238bceSAndroid Build Coastguard Worker case TOKEN_ACTIVE_STAGES:
957*35238bceSAndroid Build Coastguard Worker return "active_stages";
958*35238bceSAndroid Build Coastguard Worker
959*35238bceSAndroid Build Coastguard Worker case TOKEN_ASSIGN:
960*35238bceSAndroid Build Coastguard Worker return "=";
961*35238bceSAndroid Build Coastguard Worker case TOKEN_PLUS:
962*35238bceSAndroid Build Coastguard Worker return "+";
963*35238bceSAndroid Build Coastguard Worker case TOKEN_MINUS:
964*35238bceSAndroid Build Coastguard Worker return "-";
965*35238bceSAndroid Build Coastguard Worker case TOKEN_COMMA:
966*35238bceSAndroid Build Coastguard Worker return ",";
967*35238bceSAndroid Build Coastguard Worker case TOKEN_VERTICAL_BAR:
968*35238bceSAndroid Build Coastguard Worker return "|";
969*35238bceSAndroid Build Coastguard Worker case TOKEN_SEMI_COLON:
970*35238bceSAndroid Build Coastguard Worker return ";";
971*35238bceSAndroid Build Coastguard Worker case TOKEN_LEFT_PAREN:
972*35238bceSAndroid Build Coastguard Worker return "(";
973*35238bceSAndroid Build Coastguard Worker case TOKEN_RIGHT_PAREN:
974*35238bceSAndroid Build Coastguard Worker return ")";
975*35238bceSAndroid Build Coastguard Worker case TOKEN_LEFT_BRACKET:
976*35238bceSAndroid Build Coastguard Worker return "[";
977*35238bceSAndroid Build Coastguard Worker case TOKEN_RIGHT_BRACKET:
978*35238bceSAndroid Build Coastguard Worker return "]";
979*35238bceSAndroid Build Coastguard Worker case TOKEN_LEFT_BRACE:
980*35238bceSAndroid Build Coastguard Worker return "{";
981*35238bceSAndroid Build Coastguard Worker case TOKEN_RIGHT_BRACE:
982*35238bceSAndroid Build Coastguard Worker return "}";
983*35238bceSAndroid Build Coastguard Worker case TOKEN_GREATER:
984*35238bceSAndroid Build Coastguard Worker return ">";
985*35238bceSAndroid Build Coastguard Worker
986*35238bceSAndroid Build Coastguard Worker default:
987*35238bceSAndroid Build Coastguard Worker return "<unknown>";
988*35238bceSAndroid Build Coastguard Worker }
989*35238bceSAndroid Build Coastguard Worker }
990*35238bceSAndroid Build Coastguard Worker
getShaderStageLiteralFlag(void)991*35238bceSAndroid Build Coastguard Worker uint32_t ShaderParser::getShaderStageLiteralFlag(void)
992*35238bceSAndroid Build Coastguard Worker {
993*35238bceSAndroid Build Coastguard Worker switch (m_curToken)
994*35238bceSAndroid Build Coastguard Worker {
995*35238bceSAndroid Build Coastguard Worker case TOKEN_VERTEX:
996*35238bceSAndroid Build Coastguard Worker return (1 << glu::SHADERTYPE_VERTEX);
997*35238bceSAndroid Build Coastguard Worker case TOKEN_FRAGMENT:
998*35238bceSAndroid Build Coastguard Worker return (1 << glu::SHADERTYPE_FRAGMENT);
999*35238bceSAndroid Build Coastguard Worker case TOKEN_GEOMETRY:
1000*35238bceSAndroid Build Coastguard Worker return (1 << glu::SHADERTYPE_GEOMETRY);
1001*35238bceSAndroid Build Coastguard Worker case TOKEN_TESSELLATION_CONTROL:
1002*35238bceSAndroid Build Coastguard Worker return (1 << glu::SHADERTYPE_TESSELLATION_CONTROL);
1003*35238bceSAndroid Build Coastguard Worker case TOKEN_TESSELLATION_EVALUATION:
1004*35238bceSAndroid Build Coastguard Worker return (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION);
1005*35238bceSAndroid Build Coastguard Worker
1006*35238bceSAndroid Build Coastguard Worker default:
1007*35238bceSAndroid Build Coastguard Worker parseError(std::string() + "invalid shader stage name, got " + m_curTokenStr);
1008*35238bceSAndroid Build Coastguard Worker return 0;
1009*35238bceSAndroid Build Coastguard Worker }
1010*35238bceSAndroid Build Coastguard Worker }
1011*35238bceSAndroid Build Coastguard Worker
getGLEnumFromName(const std::string & enumName)1012*35238bceSAndroid Build Coastguard Worker uint32_t ShaderParser::getGLEnumFromName(const std::string &enumName)
1013*35238bceSAndroid Build Coastguard Worker {
1014*35238bceSAndroid Build Coastguard Worker static const struct
1015*35238bceSAndroid Build Coastguard Worker {
1016*35238bceSAndroid Build Coastguard Worker const char *name;
1017*35238bceSAndroid Build Coastguard Worker uint32_t value;
1018*35238bceSAndroid Build Coastguard Worker } names[] = {
1019*35238bceSAndroid Build Coastguard Worker {"GL_MAX_VERTEX_IMAGE_UNIFORMS", GL_MAX_VERTEX_IMAGE_UNIFORMS},
1020*35238bceSAndroid Build Coastguard Worker {"GL_MAX_VERTEX_ATOMIC_COUNTERS", GL_MAX_VERTEX_ATOMIC_COUNTERS},
1021*35238bceSAndroid Build Coastguard Worker {"GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS", GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS},
1022*35238bceSAndroid Build Coastguard Worker {"GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS", GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS},
1023*35238bceSAndroid Build Coastguard Worker };
1024*35238bceSAndroid Build Coastguard Worker
1025*35238bceSAndroid Build Coastguard Worker for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(names); ++ndx)
1026*35238bceSAndroid Build Coastguard Worker if (names[ndx].name == enumName)
1027*35238bceSAndroid Build Coastguard Worker return names[ndx].value;
1028*35238bceSAndroid Build Coastguard Worker
1029*35238bceSAndroid Build Coastguard Worker parseError(std::string() + "unknown enum name, got " + enumName);
1030*35238bceSAndroid Build Coastguard Worker return 0;
1031*35238bceSAndroid Build Coastguard Worker }
1032*35238bceSAndroid Build Coastguard Worker
parseValueElement(DataType expectedDataType,Value & result)1033*35238bceSAndroid Build Coastguard Worker void ShaderParser::parseValueElement(DataType expectedDataType, Value &result)
1034*35238bceSAndroid Build Coastguard Worker {
1035*35238bceSAndroid Build Coastguard Worker DataType scalarType = getDataTypeScalarType(expectedDataType);
1036*35238bceSAndroid Build Coastguard Worker int scalarSize = getDataTypeScalarSize(expectedDataType);
1037*35238bceSAndroid Build Coastguard Worker
1038*35238bceSAndroid Build Coastguard Worker /* \todo [2010-04-19 petri] Support arrays. */
1039*35238bceSAndroid Build Coastguard Worker Value::Element elems[16];
1040*35238bceSAndroid Build Coastguard Worker
1041*35238bceSAndroid Build Coastguard Worker if (scalarSize > 1)
1042*35238bceSAndroid Build Coastguard Worker {
1043*35238bceSAndroid Build Coastguard Worker DE_ASSERT(mapDataTypeToken(m_curToken) == expectedDataType);
1044*35238bceSAndroid Build Coastguard Worker advanceToken(); // data type (float, vec2, etc.)
1045*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_LEFT_PAREN);
1046*35238bceSAndroid Build Coastguard Worker }
1047*35238bceSAndroid Build Coastguard Worker
1048*35238bceSAndroid Build Coastguard Worker for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++)
1049*35238bceSAndroid Build Coastguard Worker {
1050*35238bceSAndroid Build Coastguard Worker if (scalarType == TYPE_FLOAT)
1051*35238bceSAndroid Build Coastguard Worker {
1052*35238bceSAndroid Build Coastguard Worker float signMult = 1.0f;
1053*35238bceSAndroid Build Coastguard Worker if (m_curToken == TOKEN_MINUS)
1054*35238bceSAndroid Build Coastguard Worker {
1055*35238bceSAndroid Build Coastguard Worker signMult = -1.0f;
1056*35238bceSAndroid Build Coastguard Worker advanceToken();
1057*35238bceSAndroid Build Coastguard Worker }
1058*35238bceSAndroid Build Coastguard Worker
1059*35238bceSAndroid Build Coastguard Worker assumeToken(TOKEN_FLOAT_LITERAL);
1060*35238bceSAndroid Build Coastguard Worker elems[scalarNdx].float32 = signMult * parseFloatLiteral(m_curTokenStr.c_str());
1061*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_FLOAT_LITERAL);
1062*35238bceSAndroid Build Coastguard Worker }
1063*35238bceSAndroid Build Coastguard Worker else if (scalarType == TYPE_INT || scalarType == TYPE_UINT)
1064*35238bceSAndroid Build Coastguard Worker {
1065*35238bceSAndroid Build Coastguard Worker int signMult = 1;
1066*35238bceSAndroid Build Coastguard Worker if (m_curToken == TOKEN_MINUS)
1067*35238bceSAndroid Build Coastguard Worker {
1068*35238bceSAndroid Build Coastguard Worker signMult = -1;
1069*35238bceSAndroid Build Coastguard Worker advanceToken();
1070*35238bceSAndroid Build Coastguard Worker }
1071*35238bceSAndroid Build Coastguard Worker
1072*35238bceSAndroid Build Coastguard Worker assumeToken(TOKEN_INT_LITERAL);
1073*35238bceSAndroid Build Coastguard Worker elems[scalarNdx].int32 = signMult * parseIntLiteral(m_curTokenStr.c_str());
1074*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_INT_LITERAL);
1075*35238bceSAndroid Build Coastguard Worker }
1076*35238bceSAndroid Build Coastguard Worker else
1077*35238bceSAndroid Build Coastguard Worker {
1078*35238bceSAndroid Build Coastguard Worker DE_ASSERT(scalarType == TYPE_BOOL);
1079*35238bceSAndroid Build Coastguard Worker elems[scalarNdx].bool32 = (m_curToken == TOKEN_TRUE);
1080*35238bceSAndroid Build Coastguard Worker if (m_curToken != TOKEN_TRUE && m_curToken != TOKEN_FALSE)
1081*35238bceSAndroid Build Coastguard Worker parseError(string("unexpected token, expecting bool: " + m_curTokenStr));
1082*35238bceSAndroid Build Coastguard Worker advanceToken(); // true/false
1083*35238bceSAndroid Build Coastguard Worker }
1084*35238bceSAndroid Build Coastguard Worker
1085*35238bceSAndroid Build Coastguard Worker if (scalarNdx != (scalarSize - 1))
1086*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_COMMA);
1087*35238bceSAndroid Build Coastguard Worker }
1088*35238bceSAndroid Build Coastguard Worker
1089*35238bceSAndroid Build Coastguard Worker if (scalarSize > 1)
1090*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_RIGHT_PAREN);
1091*35238bceSAndroid Build Coastguard Worker
1092*35238bceSAndroid Build Coastguard Worker // Store results.
1093*35238bceSAndroid Build Coastguard Worker for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++)
1094*35238bceSAndroid Build Coastguard Worker result.elements.push_back(elems[scalarNdx]);
1095*35238bceSAndroid Build Coastguard Worker }
1096*35238bceSAndroid Build Coastguard Worker
parseValue(ValueBlock & valueBlock)1097*35238bceSAndroid Build Coastguard Worker void ShaderParser::parseValue(ValueBlock &valueBlock)
1098*35238bceSAndroid Build Coastguard Worker {
1099*35238bceSAndroid Build Coastguard Worker PARSE_DBG((" parseValue()\n"));
1100*35238bceSAndroid Build Coastguard Worker
1101*35238bceSAndroid Build Coastguard Worker // Parsed results.
1102*35238bceSAndroid Build Coastguard Worker vector<Value> *dstBlock = DE_NULL;
1103*35238bceSAndroid Build Coastguard Worker DataType basicType = TYPE_LAST;
1104*35238bceSAndroid Build Coastguard Worker std::string valueName;
1105*35238bceSAndroid Build Coastguard Worker
1106*35238bceSAndroid Build Coastguard Worker // Parse storage.
1107*35238bceSAndroid Build Coastguard Worker if (m_curToken == TOKEN_UNIFORM)
1108*35238bceSAndroid Build Coastguard Worker dstBlock = &valueBlock.uniforms;
1109*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_INPUT)
1110*35238bceSAndroid Build Coastguard Worker dstBlock = &valueBlock.inputs;
1111*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_OUTPUT)
1112*35238bceSAndroid Build Coastguard Worker dstBlock = &valueBlock.outputs;
1113*35238bceSAndroid Build Coastguard Worker else
1114*35238bceSAndroid Build Coastguard Worker parseError(string("unexpected token encountered when parsing value classifier"));
1115*35238bceSAndroid Build Coastguard Worker advanceToken();
1116*35238bceSAndroid Build Coastguard Worker
1117*35238bceSAndroid Build Coastguard Worker // Parse data type.
1118*35238bceSAndroid Build Coastguard Worker basicType = mapDataTypeToken(m_curToken);
1119*35238bceSAndroid Build Coastguard Worker if (basicType == TYPE_INVALID)
1120*35238bceSAndroid Build Coastguard Worker parseError(string("unexpected token when parsing value data type: " + m_curTokenStr));
1121*35238bceSAndroid Build Coastguard Worker advanceToken();
1122*35238bceSAndroid Build Coastguard Worker
1123*35238bceSAndroid Build Coastguard Worker // Parse value name.
1124*35238bceSAndroid Build Coastguard Worker if (m_curToken == TOKEN_IDENTIFIER || m_curToken == TOKEN_STRING)
1125*35238bceSAndroid Build Coastguard Worker {
1126*35238bceSAndroid Build Coastguard Worker if (m_curToken == TOKEN_IDENTIFIER)
1127*35238bceSAndroid Build Coastguard Worker valueName = m_curTokenStr;
1128*35238bceSAndroid Build Coastguard Worker else
1129*35238bceSAndroid Build Coastguard Worker valueName = parseStringLiteral(m_curTokenStr.c_str());
1130*35238bceSAndroid Build Coastguard Worker }
1131*35238bceSAndroid Build Coastguard Worker else
1132*35238bceSAndroid Build Coastguard Worker parseError(string("unexpected token when parsing value name: " + m_curTokenStr));
1133*35238bceSAndroid Build Coastguard Worker advanceToken();
1134*35238bceSAndroid Build Coastguard Worker
1135*35238bceSAndroid Build Coastguard Worker // Parse assignment operator.
1136*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_ASSIGN);
1137*35238bceSAndroid Build Coastguard Worker
1138*35238bceSAndroid Build Coastguard Worker {
1139*35238bceSAndroid Build Coastguard Worker Value value;
1140*35238bceSAndroid Build Coastguard Worker value.name = valueName;
1141*35238bceSAndroid Build Coastguard Worker value.type = VarType(basicType, PRECISION_LAST);
1142*35238bceSAndroid Build Coastguard Worker dstBlock->push_back(value);
1143*35238bceSAndroid Build Coastguard Worker }
1144*35238bceSAndroid Build Coastguard Worker
1145*35238bceSAndroid Build Coastguard Worker // Parse actual value.
1146*35238bceSAndroid Build Coastguard Worker if (m_curToken == TOKEN_LEFT_BRACKET) // value list
1147*35238bceSAndroid Build Coastguard Worker {
1148*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_LEFT_BRACKET);
1149*35238bceSAndroid Build Coastguard Worker
1150*35238bceSAndroid Build Coastguard Worker for (;;)
1151*35238bceSAndroid Build Coastguard Worker {
1152*35238bceSAndroid Build Coastguard Worker parseValueElement(basicType, dstBlock->back());
1153*35238bceSAndroid Build Coastguard Worker
1154*35238bceSAndroid Build Coastguard Worker if (m_curToken == TOKEN_RIGHT_BRACKET)
1155*35238bceSAndroid Build Coastguard Worker break;
1156*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_VERTICAL_BAR)
1157*35238bceSAndroid Build Coastguard Worker {
1158*35238bceSAndroid Build Coastguard Worker advanceToken();
1159*35238bceSAndroid Build Coastguard Worker continue;
1160*35238bceSAndroid Build Coastguard Worker }
1161*35238bceSAndroid Build Coastguard Worker else
1162*35238bceSAndroid Build Coastguard Worker parseError(string("unexpected token in value element array: " + m_curTokenStr));
1163*35238bceSAndroid Build Coastguard Worker }
1164*35238bceSAndroid Build Coastguard Worker
1165*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_RIGHT_BRACKET);
1166*35238bceSAndroid Build Coastguard Worker }
1167*35238bceSAndroid Build Coastguard Worker else // single elements
1168*35238bceSAndroid Build Coastguard Worker {
1169*35238bceSAndroid Build Coastguard Worker parseValueElement(basicType, dstBlock->back());
1170*35238bceSAndroid Build Coastguard Worker }
1171*35238bceSAndroid Build Coastguard Worker
1172*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_SEMI_COLON); // end of declaration
1173*35238bceSAndroid Build Coastguard Worker }
1174*35238bceSAndroid Build Coastguard Worker
parseValueBlock(ValueBlock & valueBlock)1175*35238bceSAndroid Build Coastguard Worker void ShaderParser::parseValueBlock(ValueBlock &valueBlock)
1176*35238bceSAndroid Build Coastguard Worker {
1177*35238bceSAndroid Build Coastguard Worker PARSE_DBG((" parseValueBlock()\n"));
1178*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_VALUES);
1179*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_LEFT_BRACE);
1180*35238bceSAndroid Build Coastguard Worker
1181*35238bceSAndroid Build Coastguard Worker for (;;)
1182*35238bceSAndroid Build Coastguard Worker {
1183*35238bceSAndroid Build Coastguard Worker if (m_curToken == TOKEN_UNIFORM || m_curToken == TOKEN_INPUT || m_curToken == TOKEN_OUTPUT)
1184*35238bceSAndroid Build Coastguard Worker parseValue(valueBlock);
1185*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_RIGHT_BRACE)
1186*35238bceSAndroid Build Coastguard Worker break;
1187*35238bceSAndroid Build Coastguard Worker else
1188*35238bceSAndroid Build Coastguard Worker parseError(string("unexpected token when parsing a value block: " + m_curTokenStr));
1189*35238bceSAndroid Build Coastguard Worker }
1190*35238bceSAndroid Build Coastguard Worker
1191*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_RIGHT_BRACE);
1192*35238bceSAndroid Build Coastguard Worker }
1193*35238bceSAndroid Build Coastguard Worker
parseShaderStageList(void)1194*35238bceSAndroid Build Coastguard Worker uint32_t ShaderParser::parseShaderStageList(void)
1195*35238bceSAndroid Build Coastguard Worker {
1196*35238bceSAndroid Build Coastguard Worker uint32_t mask = 0;
1197*35238bceSAndroid Build Coastguard Worker
1198*35238bceSAndroid Build Coastguard Worker assumeToken(TOKEN_LEFT_BRACE);
1199*35238bceSAndroid Build Coastguard Worker
1200*35238bceSAndroid Build Coastguard Worker // don't allow 0-sized lists
1201*35238bceSAndroid Build Coastguard Worker advanceToken();
1202*35238bceSAndroid Build Coastguard Worker mask |= getShaderStageLiteralFlag();
1203*35238bceSAndroid Build Coastguard Worker advanceToken();
1204*35238bceSAndroid Build Coastguard Worker
1205*35238bceSAndroid Build Coastguard Worker for (;;)
1206*35238bceSAndroid Build Coastguard Worker {
1207*35238bceSAndroid Build Coastguard Worker if (m_curToken == TOKEN_RIGHT_BRACE)
1208*35238bceSAndroid Build Coastguard Worker break;
1209*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_COMMA)
1210*35238bceSAndroid Build Coastguard Worker {
1211*35238bceSAndroid Build Coastguard Worker uint32_t stageFlag;
1212*35238bceSAndroid Build Coastguard Worker advanceToken();
1213*35238bceSAndroid Build Coastguard Worker
1214*35238bceSAndroid Build Coastguard Worker stageFlag = getShaderStageLiteralFlag();
1215*35238bceSAndroid Build Coastguard Worker if (stageFlag & mask)
1216*35238bceSAndroid Build Coastguard Worker parseError(string("stage already set in the shader stage set: " + m_curTokenStr));
1217*35238bceSAndroid Build Coastguard Worker
1218*35238bceSAndroid Build Coastguard Worker mask |= stageFlag;
1219*35238bceSAndroid Build Coastguard Worker advanceToken();
1220*35238bceSAndroid Build Coastguard Worker }
1221*35238bceSAndroid Build Coastguard Worker else
1222*35238bceSAndroid Build Coastguard Worker parseError(string("invalid shader stage set token: " + m_curTokenStr));
1223*35238bceSAndroid Build Coastguard Worker }
1224*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_RIGHT_BRACE);
1225*35238bceSAndroid Build Coastguard Worker
1226*35238bceSAndroid Build Coastguard Worker return mask;
1227*35238bceSAndroid Build Coastguard Worker }
1228*35238bceSAndroid Build Coastguard Worker
parseRequirement(vector<RequiredCapability> & requiredCaps,vector<RequiredExtension> & requiredExts)1229*35238bceSAndroid Build Coastguard Worker void ShaderParser::parseRequirement(vector<RequiredCapability> &requiredCaps, vector<RequiredExtension> &requiredExts)
1230*35238bceSAndroid Build Coastguard Worker {
1231*35238bceSAndroid Build Coastguard Worker PARSE_DBG((" parseRequirement()\n"));
1232*35238bceSAndroid Build Coastguard Worker
1233*35238bceSAndroid Build Coastguard Worker advanceToken();
1234*35238bceSAndroid Build Coastguard Worker assumeToken(TOKEN_IDENTIFIER);
1235*35238bceSAndroid Build Coastguard Worker
1236*35238bceSAndroid Build Coastguard Worker if (m_curTokenStr == "extension")
1237*35238bceSAndroid Build Coastguard Worker {
1238*35238bceSAndroid Build Coastguard Worker std::vector<std::string> anyExtensionStringList;
1239*35238bceSAndroid Build Coastguard Worker uint32_t affectedCasesFlags = -1; // by default all stages
1240*35238bceSAndroid Build Coastguard Worker
1241*35238bceSAndroid Build Coastguard Worker advanceToken();
1242*35238bceSAndroid Build Coastguard Worker assumeToken(TOKEN_LEFT_BRACE);
1243*35238bceSAndroid Build Coastguard Worker
1244*35238bceSAndroid Build Coastguard Worker advanceToken();
1245*35238bceSAndroid Build Coastguard Worker assumeToken(TOKEN_STRING);
1246*35238bceSAndroid Build Coastguard Worker
1247*35238bceSAndroid Build Coastguard Worker anyExtensionStringList.push_back(parseStringLiteral(m_curTokenStr.c_str()));
1248*35238bceSAndroid Build Coastguard Worker advanceToken();
1249*35238bceSAndroid Build Coastguard Worker
1250*35238bceSAndroid Build Coastguard Worker for (;;)
1251*35238bceSAndroid Build Coastguard Worker {
1252*35238bceSAndroid Build Coastguard Worker if (m_curToken == TOKEN_RIGHT_BRACE)
1253*35238bceSAndroid Build Coastguard Worker break;
1254*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_VERTICAL_BAR)
1255*35238bceSAndroid Build Coastguard Worker {
1256*35238bceSAndroid Build Coastguard Worker advanceToken();
1257*35238bceSAndroid Build Coastguard Worker assumeToken(TOKEN_STRING);
1258*35238bceSAndroid Build Coastguard Worker
1259*35238bceSAndroid Build Coastguard Worker anyExtensionStringList.push_back(parseStringLiteral(m_curTokenStr.c_str()));
1260*35238bceSAndroid Build Coastguard Worker advanceToken();
1261*35238bceSAndroid Build Coastguard Worker }
1262*35238bceSAndroid Build Coastguard Worker else
1263*35238bceSAndroid Build Coastguard Worker parseError(string("invalid extension list token: " + m_curTokenStr));
1264*35238bceSAndroid Build Coastguard Worker }
1265*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_RIGHT_BRACE);
1266*35238bceSAndroid Build Coastguard Worker
1267*35238bceSAndroid Build Coastguard Worker if (m_curToken == TOKEN_IN)
1268*35238bceSAndroid Build Coastguard Worker {
1269*35238bceSAndroid Build Coastguard Worker advanceToken();
1270*35238bceSAndroid Build Coastguard Worker affectedCasesFlags = parseShaderStageList();
1271*35238bceSAndroid Build Coastguard Worker }
1272*35238bceSAndroid Build Coastguard Worker
1273*35238bceSAndroid Build Coastguard Worker requiredExts.push_back(RequiredExtension(anyExtensionStringList, affectedCasesFlags));
1274*35238bceSAndroid Build Coastguard Worker }
1275*35238bceSAndroid Build Coastguard Worker else if (m_curTokenStr == "limit")
1276*35238bceSAndroid Build Coastguard Worker {
1277*35238bceSAndroid Build Coastguard Worker uint32_t limitEnum;
1278*35238bceSAndroid Build Coastguard Worker int limitValue;
1279*35238bceSAndroid Build Coastguard Worker
1280*35238bceSAndroid Build Coastguard Worker advanceToken();
1281*35238bceSAndroid Build Coastguard Worker
1282*35238bceSAndroid Build Coastguard Worker assumeToken(TOKEN_STRING);
1283*35238bceSAndroid Build Coastguard Worker limitEnum = getGLEnumFromName(parseStringLiteral(m_curTokenStr.c_str()));
1284*35238bceSAndroid Build Coastguard Worker advanceToken();
1285*35238bceSAndroid Build Coastguard Worker
1286*35238bceSAndroid Build Coastguard Worker assumeToken(TOKEN_GREATER);
1287*35238bceSAndroid Build Coastguard Worker advanceToken();
1288*35238bceSAndroid Build Coastguard Worker
1289*35238bceSAndroid Build Coastguard Worker assumeToken(TOKEN_INT_LITERAL);
1290*35238bceSAndroid Build Coastguard Worker limitValue = parseIntLiteral(m_curTokenStr.c_str());
1291*35238bceSAndroid Build Coastguard Worker advanceToken();
1292*35238bceSAndroid Build Coastguard Worker
1293*35238bceSAndroid Build Coastguard Worker requiredCaps.push_back(RequiredCapability(limitEnum, limitValue));
1294*35238bceSAndroid Build Coastguard Worker }
1295*35238bceSAndroid Build Coastguard Worker else if (m_curTokenStr == "full_glsl_es_100_support")
1296*35238bceSAndroid Build Coastguard Worker {
1297*35238bceSAndroid Build Coastguard Worker advanceToken();
1298*35238bceSAndroid Build Coastguard Worker
1299*35238bceSAndroid Build Coastguard Worker requiredCaps.push_back(RequiredCapability(CAPABILITY_FULL_GLSL_ES_100_SUPPORT));
1300*35238bceSAndroid Build Coastguard Worker }
1301*35238bceSAndroid Build Coastguard Worker else if (m_curTokenStr == "only_glsl_es_100_support")
1302*35238bceSAndroid Build Coastguard Worker {
1303*35238bceSAndroid Build Coastguard Worker advanceToken();
1304*35238bceSAndroid Build Coastguard Worker
1305*35238bceSAndroid Build Coastguard Worker requiredCaps.push_back(RequiredCapability(CAPABILITY_ONLY_GLSL_ES_100_SUPPORT));
1306*35238bceSAndroid Build Coastguard Worker }
1307*35238bceSAndroid Build Coastguard Worker else if (m_curTokenStr == "exactly_one_draw_buffer")
1308*35238bceSAndroid Build Coastguard Worker {
1309*35238bceSAndroid Build Coastguard Worker advanceToken();
1310*35238bceSAndroid Build Coastguard Worker
1311*35238bceSAndroid Build Coastguard Worker requiredCaps.push_back(RequiredCapability(CAPABILITY_EXACTLY_ONE_DRAW_BUFFER));
1312*35238bceSAndroid Build Coastguard Worker }
1313*35238bceSAndroid Build Coastguard Worker else
1314*35238bceSAndroid Build Coastguard Worker parseError(string("invalid requirement value: " + m_curTokenStr));
1315*35238bceSAndroid Build Coastguard Worker }
1316*35238bceSAndroid Build Coastguard Worker
parseExpectResult(ExpectResult & expectResult)1317*35238bceSAndroid Build Coastguard Worker void ShaderParser::parseExpectResult(ExpectResult &expectResult)
1318*35238bceSAndroid Build Coastguard Worker {
1319*35238bceSAndroid Build Coastguard Worker assumeToken(TOKEN_IDENTIFIER);
1320*35238bceSAndroid Build Coastguard Worker
1321*35238bceSAndroid Build Coastguard Worker if (m_curTokenStr == "pass")
1322*35238bceSAndroid Build Coastguard Worker expectResult = EXPECT_PASS;
1323*35238bceSAndroid Build Coastguard Worker else if (m_curTokenStr == "compile_fail")
1324*35238bceSAndroid Build Coastguard Worker expectResult = EXPECT_COMPILE_FAIL;
1325*35238bceSAndroid Build Coastguard Worker else if (m_curTokenStr == "link_fail")
1326*35238bceSAndroid Build Coastguard Worker expectResult = EXPECT_LINK_FAIL;
1327*35238bceSAndroid Build Coastguard Worker else if (m_curTokenStr == "compile_or_link_fail")
1328*35238bceSAndroid Build Coastguard Worker expectResult = EXPECT_COMPILE_LINK_FAIL;
1329*35238bceSAndroid Build Coastguard Worker else if (m_curTokenStr == "validation_fail")
1330*35238bceSAndroid Build Coastguard Worker expectResult = EXPECT_VALIDATION_FAIL;
1331*35238bceSAndroid Build Coastguard Worker else if (m_curTokenStr == "build_successful")
1332*35238bceSAndroid Build Coastguard Worker expectResult = EXPECT_BUILD_SUCCESSFUL;
1333*35238bceSAndroid Build Coastguard Worker else
1334*35238bceSAndroid Build Coastguard Worker parseError(string("invalid expected result value: " + m_curTokenStr));
1335*35238bceSAndroid Build Coastguard Worker
1336*35238bceSAndroid Build Coastguard Worker advanceToken();
1337*35238bceSAndroid Build Coastguard Worker }
1338*35238bceSAndroid Build Coastguard Worker
parseFormat(DataType & format)1339*35238bceSAndroid Build Coastguard Worker void ShaderParser::parseFormat(DataType &format)
1340*35238bceSAndroid Build Coastguard Worker {
1341*35238bceSAndroid Build Coastguard Worker format = mapDataTypeToken(m_curToken);
1342*35238bceSAndroid Build Coastguard Worker advanceToken();
1343*35238bceSAndroid Build Coastguard Worker }
1344*35238bceSAndroid Build Coastguard Worker
parseGLSLVersion(glu::GLSLVersion & version)1345*35238bceSAndroid Build Coastguard Worker void ShaderParser::parseGLSLVersion(glu::GLSLVersion &version)
1346*35238bceSAndroid Build Coastguard Worker {
1347*35238bceSAndroid Build Coastguard Worker int versionNum = 0;
1348*35238bceSAndroid Build Coastguard Worker std::string postfix = "";
1349*35238bceSAndroid Build Coastguard Worker
1350*35238bceSAndroid Build Coastguard Worker assumeToken(TOKEN_INT_LITERAL);
1351*35238bceSAndroid Build Coastguard Worker versionNum = parseIntLiteral(m_curTokenStr.c_str());
1352*35238bceSAndroid Build Coastguard Worker advanceToken();
1353*35238bceSAndroid Build Coastguard Worker
1354*35238bceSAndroid Build Coastguard Worker if (m_curToken == TOKEN_IDENTIFIER)
1355*35238bceSAndroid Build Coastguard Worker {
1356*35238bceSAndroid Build Coastguard Worker postfix = m_curTokenStr;
1357*35238bceSAndroid Build Coastguard Worker advanceToken();
1358*35238bceSAndroid Build Coastguard Worker }
1359*35238bceSAndroid Build Coastguard Worker
1360*35238bceSAndroid Build Coastguard Worker DE_STATIC_ASSERT(glu::GLSL_VERSION_LAST == 15);
1361*35238bceSAndroid Build Coastguard Worker
1362*35238bceSAndroid Build Coastguard Worker if (versionNum == 100 && postfix == "es")
1363*35238bceSAndroid Build Coastguard Worker version = glu::GLSL_VERSION_100_ES;
1364*35238bceSAndroid Build Coastguard Worker else if (versionNum == 300 && postfix == "es")
1365*35238bceSAndroid Build Coastguard Worker version = glu::GLSL_VERSION_300_ES;
1366*35238bceSAndroid Build Coastguard Worker else if (versionNum == 310 && postfix == "es")
1367*35238bceSAndroid Build Coastguard Worker version = glu::GLSL_VERSION_310_ES;
1368*35238bceSAndroid Build Coastguard Worker else if (versionNum == 320 && postfix == "es")
1369*35238bceSAndroid Build Coastguard Worker version = glu::GLSL_VERSION_320_ES;
1370*35238bceSAndroid Build Coastguard Worker else if (versionNum == 130)
1371*35238bceSAndroid Build Coastguard Worker version = glu::GLSL_VERSION_130;
1372*35238bceSAndroid Build Coastguard Worker else if (versionNum == 140)
1373*35238bceSAndroid Build Coastguard Worker version = glu::GLSL_VERSION_140;
1374*35238bceSAndroid Build Coastguard Worker else if (versionNum == 150)
1375*35238bceSAndroid Build Coastguard Worker version = glu::GLSL_VERSION_150;
1376*35238bceSAndroid Build Coastguard Worker else if (versionNum == 330)
1377*35238bceSAndroid Build Coastguard Worker version = glu::GLSL_VERSION_330;
1378*35238bceSAndroid Build Coastguard Worker else if (versionNum == 400)
1379*35238bceSAndroid Build Coastguard Worker version = glu::GLSL_VERSION_400;
1380*35238bceSAndroid Build Coastguard Worker else if (versionNum == 410)
1381*35238bceSAndroid Build Coastguard Worker version = glu::GLSL_VERSION_410;
1382*35238bceSAndroid Build Coastguard Worker else if (versionNum == 420)
1383*35238bceSAndroid Build Coastguard Worker version = glu::GLSL_VERSION_420;
1384*35238bceSAndroid Build Coastguard Worker else if (versionNum == 430)
1385*35238bceSAndroid Build Coastguard Worker version = glu::GLSL_VERSION_430;
1386*35238bceSAndroid Build Coastguard Worker else if (versionNum == 440)
1387*35238bceSAndroid Build Coastguard Worker version = glu::GLSL_VERSION_440;
1388*35238bceSAndroid Build Coastguard Worker else if (versionNum == 450)
1389*35238bceSAndroid Build Coastguard Worker version = glu::GLSL_VERSION_450;
1390*35238bceSAndroid Build Coastguard Worker else if (versionNum == 460)
1391*35238bceSAndroid Build Coastguard Worker version = glu::GLSL_VERSION_460;
1392*35238bceSAndroid Build Coastguard Worker else
1393*35238bceSAndroid Build Coastguard Worker parseError("Unknown GLSL version");
1394*35238bceSAndroid Build Coastguard Worker }
1395*35238bceSAndroid Build Coastguard Worker
parsePipelineProgram(ProgramSpecification & program)1396*35238bceSAndroid Build Coastguard Worker void ShaderParser::parsePipelineProgram(ProgramSpecification &program)
1397*35238bceSAndroid Build Coastguard Worker {
1398*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_PIPELINE_PROGRAM);
1399*35238bceSAndroid Build Coastguard Worker
1400*35238bceSAndroid Build Coastguard Worker for (;;)
1401*35238bceSAndroid Build Coastguard Worker {
1402*35238bceSAndroid Build Coastguard Worker if (m_curToken == TOKEN_END)
1403*35238bceSAndroid Build Coastguard Worker break;
1404*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_ACTIVE_STAGES)
1405*35238bceSAndroid Build Coastguard Worker {
1406*35238bceSAndroid Build Coastguard Worker advanceToken();
1407*35238bceSAndroid Build Coastguard Worker program.activeStages = parseShaderStageList();
1408*35238bceSAndroid Build Coastguard Worker }
1409*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_REQUIRE)
1410*35238bceSAndroid Build Coastguard Worker {
1411*35238bceSAndroid Build Coastguard Worker vector<RequiredCapability> unusedCaps;
1412*35238bceSAndroid Build Coastguard Worker size_t size = program.requiredExtensions.size();
1413*35238bceSAndroid Build Coastguard Worker parseRequirement(unusedCaps, program.requiredExtensions);
1414*35238bceSAndroid Build Coastguard Worker
1415*35238bceSAndroid Build Coastguard Worker if (size == program.requiredExtensions.size())
1416*35238bceSAndroid Build Coastguard Worker parseError("only extension requirements are allowed inside pipeline program");
1417*35238bceSAndroid Build Coastguard Worker }
1418*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_VERTEX || m_curToken == TOKEN_FRAGMENT ||
1419*35238bceSAndroid Build Coastguard Worker m_curToken == TOKEN_TESSELLATION_CONTROL || m_curToken == TOKEN_TESSELLATION_EVALUATION ||
1420*35238bceSAndroid Build Coastguard Worker m_curToken == TOKEN_GEOMETRY)
1421*35238bceSAndroid Build Coastguard Worker {
1422*35238bceSAndroid Build Coastguard Worker const Token token = m_curToken;
1423*35238bceSAndroid Build Coastguard Worker string source;
1424*35238bceSAndroid Build Coastguard Worker
1425*35238bceSAndroid Build Coastguard Worker advanceToken();
1426*35238bceSAndroid Build Coastguard Worker assumeToken(TOKEN_SHADER_SOURCE);
1427*35238bceSAndroid Build Coastguard Worker source = parseShaderSource(m_curTokenStr.c_str());
1428*35238bceSAndroid Build Coastguard Worker advanceToken();
1429*35238bceSAndroid Build Coastguard Worker
1430*35238bceSAndroid Build Coastguard Worker switch (token)
1431*35238bceSAndroid Build Coastguard Worker {
1432*35238bceSAndroid Build Coastguard Worker case TOKEN_VERTEX:
1433*35238bceSAndroid Build Coastguard Worker program.sources.sources[SHADERTYPE_VERTEX].push_back(source);
1434*35238bceSAndroid Build Coastguard Worker break;
1435*35238bceSAndroid Build Coastguard Worker case TOKEN_FRAGMENT:
1436*35238bceSAndroid Build Coastguard Worker program.sources.sources[SHADERTYPE_FRAGMENT].push_back(source);
1437*35238bceSAndroid Build Coastguard Worker break;
1438*35238bceSAndroid Build Coastguard Worker case TOKEN_TESSELLATION_CONTROL:
1439*35238bceSAndroid Build Coastguard Worker program.sources.sources[SHADERTYPE_TESSELLATION_CONTROL].push_back(source);
1440*35238bceSAndroid Build Coastguard Worker break;
1441*35238bceSAndroid Build Coastguard Worker case TOKEN_TESSELLATION_EVALUATION:
1442*35238bceSAndroid Build Coastguard Worker program.sources.sources[SHADERTYPE_TESSELLATION_EVALUATION].push_back(source);
1443*35238bceSAndroid Build Coastguard Worker break;
1444*35238bceSAndroid Build Coastguard Worker case TOKEN_GEOMETRY:
1445*35238bceSAndroid Build Coastguard Worker program.sources.sources[SHADERTYPE_GEOMETRY].push_back(source);
1446*35238bceSAndroid Build Coastguard Worker break;
1447*35238bceSAndroid Build Coastguard Worker default:
1448*35238bceSAndroid Build Coastguard Worker DE_FATAL("Unreachable");
1449*35238bceSAndroid Build Coastguard Worker }
1450*35238bceSAndroid Build Coastguard Worker }
1451*35238bceSAndroid Build Coastguard Worker else
1452*35238bceSAndroid Build Coastguard Worker parseError(string("invalid pipeline program value: " + m_curTokenStr));
1453*35238bceSAndroid Build Coastguard Worker }
1454*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_END);
1455*35238bceSAndroid Build Coastguard Worker
1456*35238bceSAndroid Build Coastguard Worker if (program.activeStages == 0)
1457*35238bceSAndroid Build Coastguard Worker parseError("program pipeline object must have active stages");
1458*35238bceSAndroid Build Coastguard Worker }
1459*35238bceSAndroid Build Coastguard Worker
parseShaderCase(vector<tcu::TestNode * > & shaderNodeList)1460*35238bceSAndroid Build Coastguard Worker void ShaderParser::parseShaderCase(vector<tcu::TestNode *> &shaderNodeList)
1461*35238bceSAndroid Build Coastguard Worker {
1462*35238bceSAndroid Build Coastguard Worker // Parse 'case'.
1463*35238bceSAndroid Build Coastguard Worker PARSE_DBG((" parseShaderCase()\n"));
1464*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_CASE);
1465*35238bceSAndroid Build Coastguard Worker
1466*35238bceSAndroid Build Coastguard Worker // Parse case name.
1467*35238bceSAndroid Build Coastguard Worker string caseName = m_curTokenStr;
1468*35238bceSAndroid Build Coastguard Worker advanceToken(); // \note [pyry] All token types are allowed here.
1469*35238bceSAndroid Build Coastguard Worker
1470*35238bceSAndroid Build Coastguard Worker // \todo [pyry] Optimize by parsing most stuff directly to ShaderCaseSpecification
1471*35238bceSAndroid Build Coastguard Worker
1472*35238bceSAndroid Build Coastguard Worker // Setup case.
1473*35238bceSAndroid Build Coastguard Worker GLSLVersion version = DEFAULT_GLSL_VERSION;
1474*35238bceSAndroid Build Coastguard Worker ExpectResult expectResult = EXPECT_PASS;
1475*35238bceSAndroid Build Coastguard Worker OutputType outputType = OUTPUT_RESULT;
1476*35238bceSAndroid Build Coastguard Worker DataType format = TYPE_LAST;
1477*35238bceSAndroid Build Coastguard Worker string description;
1478*35238bceSAndroid Build Coastguard Worker string bothSource;
1479*35238bceSAndroid Build Coastguard Worker vector<string> vertexSources;
1480*35238bceSAndroid Build Coastguard Worker vector<string> fragmentSources;
1481*35238bceSAndroid Build Coastguard Worker vector<string> tessellationCtrlSources;
1482*35238bceSAndroid Build Coastguard Worker vector<string> tessellationEvalSources;
1483*35238bceSAndroid Build Coastguard Worker vector<string> geometrySources;
1484*35238bceSAndroid Build Coastguard Worker ValueBlock valueBlock;
1485*35238bceSAndroid Build Coastguard Worker bool valueBlockSeen = false;
1486*35238bceSAndroid Build Coastguard Worker vector<RequiredCapability> requiredCaps;
1487*35238bceSAndroid Build Coastguard Worker vector<RequiredExtension> requiredExts;
1488*35238bceSAndroid Build Coastguard Worker vector<ProgramSpecification> pipelinePrograms;
1489*35238bceSAndroid Build Coastguard Worker
1490*35238bceSAndroid Build Coastguard Worker for (;;)
1491*35238bceSAndroid Build Coastguard Worker {
1492*35238bceSAndroid Build Coastguard Worker if (m_curToken == TOKEN_END)
1493*35238bceSAndroid Build Coastguard Worker break;
1494*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_DESC)
1495*35238bceSAndroid Build Coastguard Worker {
1496*35238bceSAndroid Build Coastguard Worker advanceToken();
1497*35238bceSAndroid Build Coastguard Worker assumeToken(TOKEN_STRING);
1498*35238bceSAndroid Build Coastguard Worker description = parseStringLiteral(m_curTokenStr.c_str());
1499*35238bceSAndroid Build Coastguard Worker advanceToken();
1500*35238bceSAndroid Build Coastguard Worker }
1501*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_EXPECT)
1502*35238bceSAndroid Build Coastguard Worker {
1503*35238bceSAndroid Build Coastguard Worker advanceToken();
1504*35238bceSAndroid Build Coastguard Worker parseExpectResult(expectResult);
1505*35238bceSAndroid Build Coastguard Worker }
1506*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_OUTPUT_COLOR)
1507*35238bceSAndroid Build Coastguard Worker {
1508*35238bceSAndroid Build Coastguard Worker outputType = OUTPUT_COLOR;
1509*35238bceSAndroid Build Coastguard Worker advanceToken();
1510*35238bceSAndroid Build Coastguard Worker parseFormat(format);
1511*35238bceSAndroid Build Coastguard Worker }
1512*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_VALUES)
1513*35238bceSAndroid Build Coastguard Worker {
1514*35238bceSAndroid Build Coastguard Worker if (valueBlockSeen)
1515*35238bceSAndroid Build Coastguard Worker parseError("multiple value blocks");
1516*35238bceSAndroid Build Coastguard Worker parseValueBlock(valueBlock);
1517*35238bceSAndroid Build Coastguard Worker valueBlockSeen = true;
1518*35238bceSAndroid Build Coastguard Worker }
1519*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_BOTH || m_curToken == TOKEN_VERTEX || m_curToken == TOKEN_FRAGMENT ||
1520*35238bceSAndroid Build Coastguard Worker m_curToken == TOKEN_TESSELLATION_CONTROL || m_curToken == TOKEN_TESSELLATION_EVALUATION ||
1521*35238bceSAndroid Build Coastguard Worker m_curToken == TOKEN_GEOMETRY)
1522*35238bceSAndroid Build Coastguard Worker {
1523*35238bceSAndroid Build Coastguard Worker const Token token = m_curToken;
1524*35238bceSAndroid Build Coastguard Worker string source;
1525*35238bceSAndroid Build Coastguard Worker
1526*35238bceSAndroid Build Coastguard Worker advanceToken();
1527*35238bceSAndroid Build Coastguard Worker assumeToken(TOKEN_SHADER_SOURCE);
1528*35238bceSAndroid Build Coastguard Worker source = parseShaderSource(m_curTokenStr.c_str());
1529*35238bceSAndroid Build Coastguard Worker advanceToken();
1530*35238bceSAndroid Build Coastguard Worker
1531*35238bceSAndroid Build Coastguard Worker switch (token)
1532*35238bceSAndroid Build Coastguard Worker {
1533*35238bceSAndroid Build Coastguard Worker case TOKEN_VERTEX:
1534*35238bceSAndroid Build Coastguard Worker vertexSources.push_back(source);
1535*35238bceSAndroid Build Coastguard Worker break;
1536*35238bceSAndroid Build Coastguard Worker case TOKEN_FRAGMENT:
1537*35238bceSAndroid Build Coastguard Worker fragmentSources.push_back(source);
1538*35238bceSAndroid Build Coastguard Worker break;
1539*35238bceSAndroid Build Coastguard Worker case TOKEN_TESSELLATION_CONTROL:
1540*35238bceSAndroid Build Coastguard Worker tessellationCtrlSources.push_back(source);
1541*35238bceSAndroid Build Coastguard Worker break;
1542*35238bceSAndroid Build Coastguard Worker case TOKEN_TESSELLATION_EVALUATION:
1543*35238bceSAndroid Build Coastguard Worker tessellationEvalSources.push_back(source);
1544*35238bceSAndroid Build Coastguard Worker break;
1545*35238bceSAndroid Build Coastguard Worker case TOKEN_GEOMETRY:
1546*35238bceSAndroid Build Coastguard Worker geometrySources.push_back(source);
1547*35238bceSAndroid Build Coastguard Worker break;
1548*35238bceSAndroid Build Coastguard Worker case TOKEN_BOTH:
1549*35238bceSAndroid Build Coastguard Worker {
1550*35238bceSAndroid Build Coastguard Worker if (!bothSource.empty())
1551*35238bceSAndroid Build Coastguard Worker parseError("multiple 'both' blocks");
1552*35238bceSAndroid Build Coastguard Worker bothSource = source;
1553*35238bceSAndroid Build Coastguard Worker break;
1554*35238bceSAndroid Build Coastguard Worker }
1555*35238bceSAndroid Build Coastguard Worker
1556*35238bceSAndroid Build Coastguard Worker default:
1557*35238bceSAndroid Build Coastguard Worker DE_FATAL("Unreachable");
1558*35238bceSAndroid Build Coastguard Worker }
1559*35238bceSAndroid Build Coastguard Worker }
1560*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_VERSION)
1561*35238bceSAndroid Build Coastguard Worker {
1562*35238bceSAndroid Build Coastguard Worker advanceToken();
1563*35238bceSAndroid Build Coastguard Worker parseGLSLVersion(version);
1564*35238bceSAndroid Build Coastguard Worker }
1565*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_REQUIRE)
1566*35238bceSAndroid Build Coastguard Worker {
1567*35238bceSAndroid Build Coastguard Worker parseRequirement(requiredCaps, requiredExts);
1568*35238bceSAndroid Build Coastguard Worker }
1569*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_PIPELINE_PROGRAM)
1570*35238bceSAndroid Build Coastguard Worker {
1571*35238bceSAndroid Build Coastguard Worker ProgramSpecification pipelineProgram;
1572*35238bceSAndroid Build Coastguard Worker parsePipelineProgram(pipelineProgram);
1573*35238bceSAndroid Build Coastguard Worker pipelineProgram.sources.separable = true;
1574*35238bceSAndroid Build Coastguard Worker pipelinePrograms.push_back(pipelineProgram);
1575*35238bceSAndroid Build Coastguard Worker }
1576*35238bceSAndroid Build Coastguard Worker else
1577*35238bceSAndroid Build Coastguard Worker parseError(string("unexpected token while parsing shader case: " + m_curTokenStr));
1578*35238bceSAndroid Build Coastguard Worker }
1579*35238bceSAndroid Build Coastguard Worker
1580*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_END); // case end
1581*35238bceSAndroid Build Coastguard Worker
1582*35238bceSAndroid Build Coastguard Worker if (!bothSource.empty())
1583*35238bceSAndroid Build Coastguard Worker {
1584*35238bceSAndroid Build Coastguard Worker if (!vertexSources.empty() || !fragmentSources.empty() || !tessellationCtrlSources.empty() ||
1585*35238bceSAndroid Build Coastguard Worker !tessellationEvalSources.empty() || !geometrySources.empty() || !pipelinePrograms.empty())
1586*35238bceSAndroid Build Coastguard Worker {
1587*35238bceSAndroid Build Coastguard Worker parseError("'both' cannot be mixed with other shader stages");
1588*35238bceSAndroid Build Coastguard Worker }
1589*35238bceSAndroid Build Coastguard Worker
1590*35238bceSAndroid Build Coastguard Worker // vertex
1591*35238bceSAndroid Build Coastguard Worker {
1592*35238bceSAndroid Build Coastguard Worker ShaderCaseSpecification spec;
1593*35238bceSAndroid Build Coastguard Worker spec.caseType = CASETYPE_VERTEX_ONLY;
1594*35238bceSAndroid Build Coastguard Worker spec.expectResult = expectResult;
1595*35238bceSAndroid Build Coastguard Worker spec.targetVersion = version;
1596*35238bceSAndroid Build Coastguard Worker spec.requiredCaps = requiredCaps;
1597*35238bceSAndroid Build Coastguard Worker spec.values = valueBlock;
1598*35238bceSAndroid Build Coastguard Worker
1599*35238bceSAndroid Build Coastguard Worker spec.programs.resize(1);
1600*35238bceSAndroid Build Coastguard Worker spec.programs[0].sources << VertexSource(bothSource);
1601*35238bceSAndroid Build Coastguard Worker spec.programs[0].requiredExtensions = requiredExts;
1602*35238bceSAndroid Build Coastguard Worker
1603*35238bceSAndroid Build Coastguard Worker shaderNodeList.push_back(
1604*35238bceSAndroid Build Coastguard Worker m_caseFactory->createCase(caseName + "_vertex", description, ShaderCaseSpecification(spec)));
1605*35238bceSAndroid Build Coastguard Worker }
1606*35238bceSAndroid Build Coastguard Worker
1607*35238bceSAndroid Build Coastguard Worker // fragment
1608*35238bceSAndroid Build Coastguard Worker {
1609*35238bceSAndroid Build Coastguard Worker ShaderCaseSpecification spec;
1610*35238bceSAndroid Build Coastguard Worker spec.caseType = CASETYPE_FRAGMENT_ONLY;
1611*35238bceSAndroid Build Coastguard Worker spec.expectResult = expectResult;
1612*35238bceSAndroid Build Coastguard Worker spec.targetVersion = version;
1613*35238bceSAndroid Build Coastguard Worker spec.requiredCaps = requiredCaps;
1614*35238bceSAndroid Build Coastguard Worker spec.values = valueBlock;
1615*35238bceSAndroid Build Coastguard Worker
1616*35238bceSAndroid Build Coastguard Worker spec.programs.resize(1);
1617*35238bceSAndroid Build Coastguard Worker spec.programs[0].sources << FragmentSource(bothSource);
1618*35238bceSAndroid Build Coastguard Worker spec.programs[0].requiredExtensions = requiredExts;
1619*35238bceSAndroid Build Coastguard Worker
1620*35238bceSAndroid Build Coastguard Worker shaderNodeList.push_back(
1621*35238bceSAndroid Build Coastguard Worker m_caseFactory->createCase(caseName + "_fragment", description, ShaderCaseSpecification(spec)));
1622*35238bceSAndroid Build Coastguard Worker }
1623*35238bceSAndroid Build Coastguard Worker }
1624*35238bceSAndroid Build Coastguard Worker else if (pipelinePrograms.empty())
1625*35238bceSAndroid Build Coastguard Worker {
1626*35238bceSAndroid Build Coastguard Worker ShaderCaseSpecification spec;
1627*35238bceSAndroid Build Coastguard Worker spec.caseType = CASETYPE_COMPLETE;
1628*35238bceSAndroid Build Coastguard Worker spec.expectResult = expectResult;
1629*35238bceSAndroid Build Coastguard Worker spec.outputType = outputType;
1630*35238bceSAndroid Build Coastguard Worker spec.outputFormat = format;
1631*35238bceSAndroid Build Coastguard Worker spec.targetVersion = version;
1632*35238bceSAndroid Build Coastguard Worker spec.requiredCaps = requiredCaps;
1633*35238bceSAndroid Build Coastguard Worker spec.values = valueBlock;
1634*35238bceSAndroid Build Coastguard Worker
1635*35238bceSAndroid Build Coastguard Worker spec.programs.resize(1);
1636*35238bceSAndroid Build Coastguard Worker spec.programs[0].sources.sources[SHADERTYPE_VERTEX].swap(vertexSources);
1637*35238bceSAndroid Build Coastguard Worker spec.programs[0].sources.sources[SHADERTYPE_FRAGMENT].swap(fragmentSources);
1638*35238bceSAndroid Build Coastguard Worker spec.programs[0].sources.sources[SHADERTYPE_TESSELLATION_CONTROL].swap(tessellationCtrlSources);
1639*35238bceSAndroid Build Coastguard Worker spec.programs[0].sources.sources[SHADERTYPE_TESSELLATION_EVALUATION].swap(tessellationEvalSources);
1640*35238bceSAndroid Build Coastguard Worker spec.programs[0].sources.sources[SHADERTYPE_GEOMETRY].swap(geometrySources);
1641*35238bceSAndroid Build Coastguard Worker spec.programs[0].requiredExtensions.swap(requiredExts);
1642*35238bceSAndroid Build Coastguard Worker
1643*35238bceSAndroid Build Coastguard Worker shaderNodeList.push_back(m_caseFactory->createCase(caseName, description, ShaderCaseSpecification(spec)));
1644*35238bceSAndroid Build Coastguard Worker }
1645*35238bceSAndroid Build Coastguard Worker else
1646*35238bceSAndroid Build Coastguard Worker {
1647*35238bceSAndroid Build Coastguard Worker if (!vertexSources.empty() || !fragmentSources.empty() || !tessellationCtrlSources.empty() ||
1648*35238bceSAndroid Build Coastguard Worker !tessellationEvalSources.empty() || !geometrySources.empty())
1649*35238bceSAndroid Build Coastguard Worker {
1650*35238bceSAndroid Build Coastguard Worker parseError("pipeline programs cannot be mixed with complete programs");
1651*35238bceSAndroid Build Coastguard Worker }
1652*35238bceSAndroid Build Coastguard Worker
1653*35238bceSAndroid Build Coastguard Worker if (!requiredExts.empty())
1654*35238bceSAndroid Build Coastguard Worker parseError("global extension requirements cannot be mixed with pipeline programs");
1655*35238bceSAndroid Build Coastguard Worker
1656*35238bceSAndroid Build Coastguard Worker // Pipeline case, multiple programs
1657*35238bceSAndroid Build Coastguard Worker {
1658*35238bceSAndroid Build Coastguard Worker ShaderCaseSpecification spec;
1659*35238bceSAndroid Build Coastguard Worker spec.caseType = CASETYPE_COMPLETE;
1660*35238bceSAndroid Build Coastguard Worker spec.expectResult = expectResult;
1661*35238bceSAndroid Build Coastguard Worker spec.targetVersion = version;
1662*35238bceSAndroid Build Coastguard Worker spec.requiredCaps = requiredCaps;
1663*35238bceSAndroid Build Coastguard Worker spec.values = valueBlock;
1664*35238bceSAndroid Build Coastguard Worker
1665*35238bceSAndroid Build Coastguard Worker spec.programs.swap(pipelinePrograms);
1666*35238bceSAndroid Build Coastguard Worker
1667*35238bceSAndroid Build Coastguard Worker shaderNodeList.push_back(m_caseFactory->createCase(caseName, description, ShaderCaseSpecification(spec)));
1668*35238bceSAndroid Build Coastguard Worker }
1669*35238bceSAndroid Build Coastguard Worker }
1670*35238bceSAndroid Build Coastguard Worker }
1671*35238bceSAndroid Build Coastguard Worker
parseShaderGroup(vector<tcu::TestNode * > & shaderNodeList)1672*35238bceSAndroid Build Coastguard Worker void ShaderParser::parseShaderGroup(vector<tcu::TestNode *> &shaderNodeList)
1673*35238bceSAndroid Build Coastguard Worker {
1674*35238bceSAndroid Build Coastguard Worker // Parse 'case'.
1675*35238bceSAndroid Build Coastguard Worker PARSE_DBG((" parseShaderGroup()\n"));
1676*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_GROUP);
1677*35238bceSAndroid Build Coastguard Worker
1678*35238bceSAndroid Build Coastguard Worker // Parse case name.
1679*35238bceSAndroid Build Coastguard Worker string name = m_curTokenStr;
1680*35238bceSAndroid Build Coastguard Worker advanceToken(); // \note [pyry] We don't want to check token type here (for instance to allow "uniform") group.
1681*35238bceSAndroid Build Coastguard Worker
1682*35238bceSAndroid Build Coastguard Worker // Parse description.
1683*35238bceSAndroid Build Coastguard Worker assumeToken(TOKEN_STRING);
1684*35238bceSAndroid Build Coastguard Worker string description = parseStringLiteral(m_curTokenStr.c_str());
1685*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_STRING);
1686*35238bceSAndroid Build Coastguard Worker
1687*35238bceSAndroid Build Coastguard Worker std::vector<tcu::TestNode *> children;
1688*35238bceSAndroid Build Coastguard Worker
1689*35238bceSAndroid Build Coastguard Worker // Parse group children.
1690*35238bceSAndroid Build Coastguard Worker for (;;)
1691*35238bceSAndroid Build Coastguard Worker {
1692*35238bceSAndroid Build Coastguard Worker if (m_curToken == TOKEN_END)
1693*35238bceSAndroid Build Coastguard Worker break;
1694*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_GROUP)
1695*35238bceSAndroid Build Coastguard Worker parseShaderGroup(children);
1696*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_CASE)
1697*35238bceSAndroid Build Coastguard Worker parseShaderCase(children);
1698*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_IMPORT)
1699*35238bceSAndroid Build Coastguard Worker parseImport(children);
1700*35238bceSAndroid Build Coastguard Worker else
1701*35238bceSAndroid Build Coastguard Worker parseError(string("unexpected token while parsing shader group: " + m_curTokenStr));
1702*35238bceSAndroid Build Coastguard Worker }
1703*35238bceSAndroid Build Coastguard Worker
1704*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_END); // group end
1705*35238bceSAndroid Build Coastguard Worker
1706*35238bceSAndroid Build Coastguard Worker // Create group node.
1707*35238bceSAndroid Build Coastguard Worker tcu::TestCaseGroup *groupNode = m_caseFactory->createGroup(name, description, children);
1708*35238bceSAndroid Build Coastguard Worker shaderNodeList.push_back(groupNode);
1709*35238bceSAndroid Build Coastguard Worker }
1710*35238bceSAndroid Build Coastguard Worker
parseImport(vector<tcu::TestNode * > & shaderNodeList)1711*35238bceSAndroid Build Coastguard Worker void ShaderParser::parseImport(vector<tcu::TestNode *> &shaderNodeList)
1712*35238bceSAndroid Build Coastguard Worker {
1713*35238bceSAndroid Build Coastguard Worker std::string importFileName;
1714*35238bceSAndroid Build Coastguard Worker
1715*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_IMPORT);
1716*35238bceSAndroid Build Coastguard Worker
1717*35238bceSAndroid Build Coastguard Worker assumeToken(TOKEN_STRING);
1718*35238bceSAndroid Build Coastguard Worker importFileName = parseStringLiteral(m_curTokenStr.c_str());
1719*35238bceSAndroid Build Coastguard Worker advanceToken(TOKEN_STRING);
1720*35238bceSAndroid Build Coastguard Worker
1721*35238bceSAndroid Build Coastguard Worker {
1722*35238bceSAndroid Build Coastguard Worker ShaderParser subParser(m_archive,
1723*35238bceSAndroid Build Coastguard Worker de::FilePath::join(de::FilePath(m_filename).getDirName(), importFileName).getPath(),
1724*35238bceSAndroid Build Coastguard Worker m_caseFactory);
1725*35238bceSAndroid Build Coastguard Worker const vector<tcu::TestNode *> importedCases = subParser.parse();
1726*35238bceSAndroid Build Coastguard Worker
1727*35238bceSAndroid Build Coastguard Worker // \todo [2015-08-03 pyry] Not exception safe
1728*35238bceSAndroid Build Coastguard Worker shaderNodeList.insert(shaderNodeList.end(), importedCases.begin(), importedCases.end());
1729*35238bceSAndroid Build Coastguard Worker }
1730*35238bceSAndroid Build Coastguard Worker }
1731*35238bceSAndroid Build Coastguard Worker
parse(void)1732*35238bceSAndroid Build Coastguard Worker vector<tcu::TestNode *> ShaderParser::parse(void)
1733*35238bceSAndroid Build Coastguard Worker {
1734*35238bceSAndroid Build Coastguard Worker const int dataLen = m_resource->getSize();
1735*35238bceSAndroid Build Coastguard Worker
1736*35238bceSAndroid Build Coastguard Worker m_input.resize(dataLen + 1);
1737*35238bceSAndroid Build Coastguard Worker m_resource->setPosition(0);
1738*35238bceSAndroid Build Coastguard Worker m_resource->read((uint8_t *)&m_input[0], dataLen);
1739*35238bceSAndroid Build Coastguard Worker m_input[dataLen] = '\0';
1740*35238bceSAndroid Build Coastguard Worker
1741*35238bceSAndroid Build Coastguard Worker // Initialize parser.
1742*35238bceSAndroid Build Coastguard Worker m_curPtr = &m_input[0];
1743*35238bceSAndroid Build Coastguard Worker m_curToken = TOKEN_INVALID;
1744*35238bceSAndroid Build Coastguard Worker m_curTokenStr = "";
1745*35238bceSAndroid Build Coastguard Worker advanceToken();
1746*35238bceSAndroid Build Coastguard Worker
1747*35238bceSAndroid Build Coastguard Worker vector<tcu::TestNode *> nodeList;
1748*35238bceSAndroid Build Coastguard Worker
1749*35238bceSAndroid Build Coastguard Worker // Parse all cases.
1750*35238bceSAndroid Build Coastguard Worker PARSE_DBG(("parse()\n"));
1751*35238bceSAndroid Build Coastguard Worker for (;;)
1752*35238bceSAndroid Build Coastguard Worker {
1753*35238bceSAndroid Build Coastguard Worker if (m_curToken == TOKEN_CASE)
1754*35238bceSAndroid Build Coastguard Worker parseShaderCase(nodeList);
1755*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_GROUP)
1756*35238bceSAndroid Build Coastguard Worker parseShaderGroup(nodeList);
1757*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_IMPORT)
1758*35238bceSAndroid Build Coastguard Worker parseImport(nodeList);
1759*35238bceSAndroid Build Coastguard Worker else if (m_curToken == TOKEN_EOF)
1760*35238bceSAndroid Build Coastguard Worker break;
1761*35238bceSAndroid Build Coastguard Worker else
1762*35238bceSAndroid Build Coastguard Worker parseError(string("invalid token encountered at main level: '") + m_curTokenStr + "'");
1763*35238bceSAndroid Build Coastguard Worker }
1764*35238bceSAndroid Build Coastguard Worker
1765*35238bceSAndroid Build Coastguard Worker assumeToken(TOKEN_EOF);
1766*35238bceSAndroid Build Coastguard Worker // printf(" parsed %d test cases.\n", caseList.size());
1767*35238bceSAndroid Build Coastguard Worker return nodeList;
1768*35238bceSAndroid Build Coastguard Worker }
1769*35238bceSAndroid Build Coastguard Worker
parseFile(const tcu::Archive & archive,const std::string & filename,ShaderCaseFactory * caseFactory)1770*35238bceSAndroid Build Coastguard Worker std::vector<tcu::TestNode *> parseFile(const tcu::Archive &archive, const std::string &filename,
1771*35238bceSAndroid Build Coastguard Worker ShaderCaseFactory *caseFactory)
1772*35238bceSAndroid Build Coastguard Worker {
1773*35238bceSAndroid Build Coastguard Worker sl::ShaderParser parser(archive, filename, caseFactory);
1774*35238bceSAndroid Build Coastguard Worker
1775*35238bceSAndroid Build Coastguard Worker return parser.parse();
1776*35238bceSAndroid Build Coastguard Worker }
1777*35238bceSAndroid Build Coastguard Worker
1778*35238bceSAndroid Build Coastguard Worker // Execution utilities
1779*35238bceSAndroid Build Coastguard Worker
dumpValue(tcu::TestLog & log,const Value & val,const char * storageName,int arrayNdx)1780*35238bceSAndroid Build Coastguard Worker static void dumpValue(tcu::TestLog &log, const Value &val, const char *storageName, int arrayNdx)
1781*35238bceSAndroid Build Coastguard Worker {
1782*35238bceSAndroid Build Coastguard Worker const char *const valueName = val.name.c_str();
1783*35238bceSAndroid Build Coastguard Worker const DataType dataType = val.type.getBasicType();
1784*35238bceSAndroid Build Coastguard Worker int scalarSize = getDataTypeScalarSize(dataType);
1785*35238bceSAndroid Build Coastguard Worker ostringstream result;
1786*35238bceSAndroid Build Coastguard Worker
1787*35238bceSAndroid Build Coastguard Worker result << " " << storageName << " ";
1788*35238bceSAndroid Build Coastguard Worker
1789*35238bceSAndroid Build Coastguard Worker result << getDataTypeName(dataType) << " " << valueName << ":";
1790*35238bceSAndroid Build Coastguard Worker
1791*35238bceSAndroid Build Coastguard Worker if (isDataTypeScalar(dataType))
1792*35238bceSAndroid Build Coastguard Worker result << " ";
1793*35238bceSAndroid Build Coastguard Worker if (isDataTypeVector(dataType))
1794*35238bceSAndroid Build Coastguard Worker result << " [ ";
1795*35238bceSAndroid Build Coastguard Worker else if (isDataTypeMatrix(dataType))
1796*35238bceSAndroid Build Coastguard Worker result << "\n";
1797*35238bceSAndroid Build Coastguard Worker
1798*35238bceSAndroid Build Coastguard Worker if (isDataTypeScalarOrVector(dataType))
1799*35238bceSAndroid Build Coastguard Worker {
1800*35238bceSAndroid Build Coastguard Worker for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++)
1801*35238bceSAndroid Build Coastguard Worker {
1802*35238bceSAndroid Build Coastguard Worker int elemNdx = arrayNdx;
1803*35238bceSAndroid Build Coastguard Worker const Value::Element &e = val.elements[elemNdx * scalarSize + scalarNdx];
1804*35238bceSAndroid Build Coastguard Worker result << ((scalarNdx != 0) ? ", " : "");
1805*35238bceSAndroid Build Coastguard Worker
1806*35238bceSAndroid Build Coastguard Worker if (isDataTypeFloatOrVec(dataType))
1807*35238bceSAndroid Build Coastguard Worker result << e.float32;
1808*35238bceSAndroid Build Coastguard Worker else if (isDataTypeIntOrIVec(dataType))
1809*35238bceSAndroid Build Coastguard Worker result << e.int32;
1810*35238bceSAndroid Build Coastguard Worker else if (isDataTypeUintOrUVec(dataType))
1811*35238bceSAndroid Build Coastguard Worker result << (uint32_t)e.int32;
1812*35238bceSAndroid Build Coastguard Worker else if (isDataTypeBoolOrBVec(dataType))
1813*35238bceSAndroid Build Coastguard Worker result << (e.bool32 ? "true" : "false");
1814*35238bceSAndroid Build Coastguard Worker }
1815*35238bceSAndroid Build Coastguard Worker }
1816*35238bceSAndroid Build Coastguard Worker else if (isDataTypeMatrix(dataType))
1817*35238bceSAndroid Build Coastguard Worker {
1818*35238bceSAndroid Build Coastguard Worker int numRows = getDataTypeMatrixNumRows(dataType);
1819*35238bceSAndroid Build Coastguard Worker int numCols = getDataTypeMatrixNumColumns(dataType);
1820*35238bceSAndroid Build Coastguard Worker for (int rowNdx = 0; rowNdx < numRows; rowNdx++)
1821*35238bceSAndroid Build Coastguard Worker {
1822*35238bceSAndroid Build Coastguard Worker result << " [ ";
1823*35238bceSAndroid Build Coastguard Worker for (int colNdx = 0; colNdx < numCols; colNdx++)
1824*35238bceSAndroid Build Coastguard Worker {
1825*35238bceSAndroid Build Coastguard Worker int elemNdx = arrayNdx;
1826*35238bceSAndroid Build Coastguard Worker float v = val.elements[elemNdx * scalarSize + rowNdx * numCols + colNdx].float32;
1827*35238bceSAndroid Build Coastguard Worker result << ((colNdx == 0) ? "" : ", ") << v;
1828*35238bceSAndroid Build Coastguard Worker }
1829*35238bceSAndroid Build Coastguard Worker result << " ]\n";
1830*35238bceSAndroid Build Coastguard Worker }
1831*35238bceSAndroid Build Coastguard Worker }
1832*35238bceSAndroid Build Coastguard Worker
1833*35238bceSAndroid Build Coastguard Worker if (isDataTypeScalar(dataType))
1834*35238bceSAndroid Build Coastguard Worker result << "\n";
1835*35238bceSAndroid Build Coastguard Worker else if (isDataTypeVector(dataType))
1836*35238bceSAndroid Build Coastguard Worker result << " ]\n";
1837*35238bceSAndroid Build Coastguard Worker
1838*35238bceSAndroid Build Coastguard Worker log << TestLog::Message << result.str() << TestLog::EndMessage;
1839*35238bceSAndroid Build Coastguard Worker }
1840*35238bceSAndroid Build Coastguard Worker
dumpValues(tcu::TestLog & log,const vector<Value> & values,const char * storageName,int arrayNdx)1841*35238bceSAndroid Build Coastguard Worker static void dumpValues(tcu::TestLog &log, const vector<Value> &values, const char *storageName, int arrayNdx)
1842*35238bceSAndroid Build Coastguard Worker {
1843*35238bceSAndroid Build Coastguard Worker for (size_t valNdx = 0; valNdx < values.size(); valNdx++)
1844*35238bceSAndroid Build Coastguard Worker dumpValue(log, values[valNdx], storageName, arrayNdx);
1845*35238bceSAndroid Build Coastguard Worker }
1846*35238bceSAndroid Build Coastguard Worker
dumpValues(tcu::TestLog & log,const ValueBlock & values,int arrayNdx)1847*35238bceSAndroid Build Coastguard Worker void dumpValues(tcu::TestLog &log, const ValueBlock &values, int arrayNdx)
1848*35238bceSAndroid Build Coastguard Worker {
1849*35238bceSAndroid Build Coastguard Worker dumpValues(log, values.inputs, "input", arrayNdx);
1850*35238bceSAndroid Build Coastguard Worker dumpValues(log, values.outputs, "expected", arrayNdx);
1851*35238bceSAndroid Build Coastguard Worker dumpValues(log, values.uniforms, "uniform", arrayNdx);
1852*35238bceSAndroid Build Coastguard Worker }
1853*35238bceSAndroid Build Coastguard Worker
generateExtensionStatements(std::ostringstream & buf,const std::vector<RequiredExtension> & extensions,glu::ShaderType type)1854*35238bceSAndroid Build Coastguard Worker static void generateExtensionStatements(std::ostringstream &buf, const std::vector<RequiredExtension> &extensions,
1855*35238bceSAndroid Build Coastguard Worker glu::ShaderType type)
1856*35238bceSAndroid Build Coastguard Worker {
1857*35238bceSAndroid Build Coastguard Worker for (size_t ndx = 0; ndx < extensions.size(); ++ndx)
1858*35238bceSAndroid Build Coastguard Worker {
1859*35238bceSAndroid Build Coastguard Worker DE_ASSERT(extensions[ndx].effectiveStages != 0u && extensions[ndx].alternatives.size() == 1);
1860*35238bceSAndroid Build Coastguard Worker
1861*35238bceSAndroid Build Coastguard Worker if ((extensions[ndx].effectiveStages & (1u << (uint32_t)type)) != 0)
1862*35238bceSAndroid Build Coastguard Worker buf << "#extension " << extensions[ndx].alternatives[0] << " : require\n";
1863*35238bceSAndroid Build Coastguard Worker }
1864*35238bceSAndroid Build Coastguard Worker }
1865*35238bceSAndroid Build Coastguard Worker
1866*35238bceSAndroid Build Coastguard Worker // Injects #extension XXX : require lines after the last preprocessor directive in the shader code. Does not support line continuations
injectExtensionRequirements(const std::string & baseCode,const std::vector<RequiredExtension> & extensions,glu::ShaderType shaderType)1867*35238bceSAndroid Build Coastguard Worker std::string injectExtensionRequirements(const std::string &baseCode, const std::vector<RequiredExtension> &extensions,
1868*35238bceSAndroid Build Coastguard Worker glu::ShaderType shaderType)
1869*35238bceSAndroid Build Coastguard Worker {
1870*35238bceSAndroid Build Coastguard Worker std::istringstream baseCodeBuf(baseCode);
1871*35238bceSAndroid Build Coastguard Worker std::ostringstream resultBuf;
1872*35238bceSAndroid Build Coastguard Worker std::string line;
1873*35238bceSAndroid Build Coastguard Worker bool firstNonPreprocessorLine = true;
1874*35238bceSAndroid Build Coastguard Worker std::ostringstream extStr;
1875*35238bceSAndroid Build Coastguard Worker
1876*35238bceSAndroid Build Coastguard Worker generateExtensionStatements(extStr, extensions, shaderType);
1877*35238bceSAndroid Build Coastguard Worker
1878*35238bceSAndroid Build Coastguard Worker // skip if no requirements
1879*35238bceSAndroid Build Coastguard Worker if (extStr.str().empty())
1880*35238bceSAndroid Build Coastguard Worker return baseCode;
1881*35238bceSAndroid Build Coastguard Worker
1882*35238bceSAndroid Build Coastguard Worker while (std::getline(baseCodeBuf, line))
1883*35238bceSAndroid Build Coastguard Worker {
1884*35238bceSAndroid Build Coastguard Worker // begins with '#'?
1885*35238bceSAndroid Build Coastguard Worker const std::string::size_type firstNonWhitespace = line.find_first_not_of("\t ");
1886*35238bceSAndroid Build Coastguard Worker const bool isPreprocessorDirective =
1887*35238bceSAndroid Build Coastguard Worker (firstNonWhitespace != std::string::npos && line.at(firstNonWhitespace) == '#');
1888*35238bceSAndroid Build Coastguard Worker
1889*35238bceSAndroid Build Coastguard Worker // Inject #extensions
1890*35238bceSAndroid Build Coastguard Worker if (!isPreprocessorDirective && firstNonPreprocessorLine)
1891*35238bceSAndroid Build Coastguard Worker {
1892*35238bceSAndroid Build Coastguard Worker firstNonPreprocessorLine = false;
1893*35238bceSAndroid Build Coastguard Worker resultBuf << extStr.str();
1894*35238bceSAndroid Build Coastguard Worker }
1895*35238bceSAndroid Build Coastguard Worker
1896*35238bceSAndroid Build Coastguard Worker resultBuf << line << "\n";
1897*35238bceSAndroid Build Coastguard Worker }
1898*35238bceSAndroid Build Coastguard Worker
1899*35238bceSAndroid Build Coastguard Worker return resultBuf.str();
1900*35238bceSAndroid Build Coastguard Worker }
1901*35238bceSAndroid Build Coastguard Worker
genCompareFunctions(ostringstream & stream,const ValueBlock & valueBlock,bool useFloatTypes)1902*35238bceSAndroid Build Coastguard Worker void genCompareFunctions(ostringstream &stream, const ValueBlock &valueBlock, bool useFloatTypes)
1903*35238bceSAndroid Build Coastguard Worker {
1904*35238bceSAndroid Build Coastguard Worker bool cmpTypeFound[TYPE_LAST];
1905*35238bceSAndroid Build Coastguard Worker for (int i = 0; i < TYPE_LAST; i++)
1906*35238bceSAndroid Build Coastguard Worker cmpTypeFound[i] = false;
1907*35238bceSAndroid Build Coastguard Worker
1908*35238bceSAndroid Build Coastguard Worker for (size_t valueNdx = 0; valueNdx < valueBlock.outputs.size(); valueNdx++)
1909*35238bceSAndroid Build Coastguard Worker {
1910*35238bceSAndroid Build Coastguard Worker const Value &val = valueBlock.outputs[valueNdx];
1911*35238bceSAndroid Build Coastguard Worker cmpTypeFound[(size_t)val.type.getBasicType()] = true;
1912*35238bceSAndroid Build Coastguard Worker }
1913*35238bceSAndroid Build Coastguard Worker
1914*35238bceSAndroid Build Coastguard Worker if (useFloatTypes)
1915*35238bceSAndroid Build Coastguard Worker {
1916*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_BOOL])
1917*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (float a, bool b) { return ((a > 0.5) == b); }\n";
1918*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_BOOL_VEC2])
1919*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (vec2 a, bvec2 b) { return (greaterThan(a, vec2(0.5)) == b); }\n";
1920*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_BOOL_VEC3])
1921*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (vec3 a, bvec3 b) { return (greaterThan(a, vec3(0.5)) == b); }\n";
1922*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_BOOL_VEC4])
1923*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (vec4 a, bvec4 b) { return (greaterThan(a, vec4(0.5)) == b); }\n";
1924*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_INT])
1925*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (float a, int b) { float atemp = a+0.5; return (float(b) <= atemp && atemp <= "
1926*35238bceSAndroid Build Coastguard Worker "float(b+1)); }\n";
1927*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_INT_VEC2])
1928*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (vec2 a, ivec2 b) { return (ivec2(floor(a + 0.5)) == b); }\n";
1929*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_INT_VEC3])
1930*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (vec3 a, ivec3 b) { return (ivec3(floor(a + 0.5)) == b); }\n";
1931*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_INT_VEC4])
1932*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (vec4 a, ivec4 b) { return (ivec4(floor(a + 0.5)) == b); }\n";
1933*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_UINT])
1934*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (float a, uint b) { float atemp = a+0.5; return (float(b) <= atemp && atemp <= "
1935*35238bceSAndroid Build Coastguard Worker "float(b+1u)); }\n";
1936*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_UINT_VEC2])
1937*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (vec2 a, uvec2 b) { return (uvec2(floor(a + 0.5)) == b); }\n";
1938*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_UINT_VEC3])
1939*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (vec3 a, uvec3 b) { return (uvec3(floor(a + 0.5)) == b); }\n";
1940*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_UINT_VEC4])
1941*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (vec4 a, uvec4 b) { return (uvec4(floor(a + 0.5)) == b); }\n";
1942*35238bceSAndroid Build Coastguard Worker }
1943*35238bceSAndroid Build Coastguard Worker else
1944*35238bceSAndroid Build Coastguard Worker {
1945*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_BOOL])
1946*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (bool a, bool b) { return (a == b); }\n";
1947*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_BOOL_VEC2])
1948*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (bvec2 a, bvec2 b) { return (a == b); }\n";
1949*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_BOOL_VEC3])
1950*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (bvec3 a, bvec3 b) { return (a == b); }\n";
1951*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_BOOL_VEC4])
1952*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (bvec4 a, bvec4 b) { return (a == b); }\n";
1953*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_INT])
1954*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (int a, int b) { return (a == b); }\n";
1955*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_INT_VEC2])
1956*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (ivec2 a, ivec2 b) { return (a == b); }\n";
1957*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_INT_VEC3])
1958*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (ivec3 a, ivec3 b) { return (a == b); }\n";
1959*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_INT_VEC4])
1960*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (ivec4 a, ivec4 b) { return (a == b); }\n";
1961*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_UINT])
1962*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (uint a, uint b) { return (a == b); }\n";
1963*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_UINT_VEC2])
1964*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (uvec2 a, uvec2 b) { return (a == b); }\n";
1965*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_UINT_VEC3])
1966*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (uvec3 a, uvec3 b) { return (a == b); }\n";
1967*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_UINT_VEC4])
1968*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (uvec4 a, uvec4 b) { return (a == b); }\n";
1969*35238bceSAndroid Build Coastguard Worker }
1970*35238bceSAndroid Build Coastguard Worker
1971*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_FLOAT])
1972*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (float a, float b, float eps) { return (abs(a-b) <= (eps*abs(b) + eps)); }\n";
1973*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_FLOAT_VEC2])
1974*35238bceSAndroid Build Coastguard Worker stream
1975*35238bceSAndroid Build Coastguard Worker << "bool isOk (vec2 a, vec2 b, float eps) { return all(lessThanEqual(abs(a-b), (eps*abs(b) + eps))); }\n";
1976*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_FLOAT_VEC3])
1977*35238bceSAndroid Build Coastguard Worker stream
1978*35238bceSAndroid Build Coastguard Worker << "bool isOk (vec3 a, vec3 b, float eps) { return all(lessThanEqual(abs(a-b), (eps*abs(b) + eps))); }\n";
1979*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_FLOAT_VEC4])
1980*35238bceSAndroid Build Coastguard Worker stream
1981*35238bceSAndroid Build Coastguard Worker << "bool isOk (vec4 a, vec4 b, float eps) { return all(lessThanEqual(abs(a-b), (eps*abs(b) + eps))); }\n";
1982*35238bceSAndroid Build Coastguard Worker
1983*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_FLOAT_MAT2])
1984*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (mat2 a, mat2 b, float eps) { vec2 diff = max(abs(a[0]-b[0]), abs(a[1]-b[1])); return "
1985*35238bceSAndroid Build Coastguard Worker "all(lessThanEqual(diff, vec2(eps))); }\n";
1986*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_FLOAT_MAT2X3])
1987*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (mat2x3 a, mat2x3 b, float eps) { vec3 diff = max(abs(a[0]-b[0]), abs(a[1]-b[1])); return "
1988*35238bceSAndroid Build Coastguard Worker "all(lessThanEqual(diff, vec3(eps))); }\n";
1989*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_FLOAT_MAT2X4])
1990*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (mat2x4 a, mat2x4 b, float eps) { vec4 diff = max(abs(a[0]-b[0]), abs(a[1]-b[1])); return "
1991*35238bceSAndroid Build Coastguard Worker "all(lessThanEqual(diff, vec4(eps))); }\n";
1992*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_FLOAT_MAT3X2])
1993*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (mat3x2 a, mat3x2 b, float eps) { vec2 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), "
1994*35238bceSAndroid Build Coastguard Worker "abs(a[2]-b[2])); return all(lessThanEqual(diff, vec2(eps))); }\n";
1995*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_FLOAT_MAT3])
1996*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (mat3 a, mat3 b, float eps) { vec3 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), "
1997*35238bceSAndroid Build Coastguard Worker "abs(a[2]-b[2])); return all(lessThanEqual(diff, vec3(eps))); }\n";
1998*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_FLOAT_MAT3X4])
1999*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (mat3x4 a, mat3x4 b, float eps) { vec4 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), "
2000*35238bceSAndroid Build Coastguard Worker "abs(a[2]-b[2])); return all(lessThanEqual(diff, vec4(eps))); }\n";
2001*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_FLOAT_MAT4X2])
2002*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (mat4x2 a, mat4x2 b, float eps) { vec2 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), "
2003*35238bceSAndroid Build Coastguard Worker "max(abs(a[2]-b[2]), abs(a[3]-b[3]))); return all(lessThanEqual(diff, vec2(eps))); }\n";
2004*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_FLOAT_MAT4X3])
2005*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (mat4x3 a, mat4x3 b, float eps) { vec3 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), "
2006*35238bceSAndroid Build Coastguard Worker "max(abs(a[2]-b[2]), abs(a[3]-b[3]))); return all(lessThanEqual(diff, vec3(eps))); }\n";
2007*35238bceSAndroid Build Coastguard Worker if (cmpTypeFound[TYPE_FLOAT_MAT4])
2008*35238bceSAndroid Build Coastguard Worker stream << "bool isOk (mat4 a, mat4 b, float eps) { vec4 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), "
2009*35238bceSAndroid Build Coastguard Worker "max(abs(a[2]-b[2]), abs(a[3]-b[3]))); return all(lessThanEqual(diff, vec4(eps))); }\n";
2010*35238bceSAndroid Build Coastguard Worker }
2011*35238bceSAndroid Build Coastguard Worker
2012*35238bceSAndroid Build Coastguard Worker } // namespace sl
2013*35238bceSAndroid Build Coastguard Worker } // namespace glu
2014