blob: 4afa73de7c2706f0c87c653becd42620eb9bfdd4 [file] [log] [blame]
alokp@chromium.org07620a52010-09-23 17:53:56 +00001//
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +00002// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
alokp@chromium.org07620a52010-09-23 17:53:56 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
zmo@google.com32e97312011-08-24 01:03:11 +00007#include "compiler/BuiltInFunctionEmulator.h"
Jamie Madilleb1a0102013-07-08 13:31:38 -04008#include "compiler/DetectCallDepth.h"
zmo@google.com0c6bb7a2011-08-17 19:39:58 +00009#include "compiler/ForLoopUnroll.h"
alokp@chromium.org07620a52010-09-23 17:53:56 +000010#include "compiler/Initialize.h"
Zhenyao Moac44cd22013-09-23 14:57:09 -040011#include "compiler/InitializeGLPosition.h"
alokp@chromium.org8b851c62012-06-15 16:25:11 +000012#include "compiler/InitializeParseContext.h"
zmo@google.comb9f64aa2012-01-20 00:35:15 +000013#include "compiler/MapLongVariableNames.h"
alokp@chromium.org07620a52010-09-23 17:53:56 +000014#include "compiler/ParseHelper.h"
maxvujovic@gmail.com430f5e02012-06-08 17:47:59 +000015#include "compiler/RenameFunction.h"
alokp@chromium.org07620a52010-09-23 17:53:56 +000016#include "compiler/ShHandle.h"
alokp@chromium.orgb59a7782010-11-24 18:38:33 +000017#include "compiler/ValidateLimitations.h"
Jamie Madill05a80ce2013-06-20 11:55:49 -040018#include "compiler/ValidateOutputs.h"
gman@chromium.org8d804792012-10-17 21:33:48 +000019#include "compiler/VariablePacker.h"
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +000020#include "compiler/depgraph/DependencyGraph.h"
21#include "compiler/depgraph/DependencyGraphOutput.h"
22#include "compiler/timing/RestrictFragmentShaderTiming.h"
23#include "compiler/timing/RestrictVertexShaderTiming.h"
shannon.woods@transgaming.comda1ed362013-01-25 21:54:57 +000024#include "third_party/compiler/ArrayBoundsClamper.h"
alokp@chromium.org07620a52010-09-23 17:53:56 +000025
maxvujovic@gmail.com430f5e02012-06-08 17:47:59 +000026bool isWebGLBasedSpec(ShShaderSpec spec)
27{
28 return spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC;
29}
30
alokp@chromium.orgbafcbaa2010-11-23 19:07:43 +000031namespace {
alokp@chromium.orgbafcbaa2010-11-23 19:07:43 +000032class TScopedPoolAllocator {
33public:
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -040034 TScopedPoolAllocator(TPoolAllocator* allocator) : mAllocator(allocator) {
35 mAllocator->push();
alokp@chromium.orgbafcbaa2010-11-23 19:07:43 +000036 SetGlobalPoolAllocator(mAllocator);
37 }
38 ~TScopedPoolAllocator() {
39 SetGlobalPoolAllocator(NULL);
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -040040 mAllocator->pop();
alokp@chromium.orgbafcbaa2010-11-23 19:07:43 +000041 }
42
43private:
44 TPoolAllocator* mAllocator;
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -040045};
46
47class TScopedSymbolTableLevel {
48public:
49 TScopedSymbolTableLevel(TSymbolTable* table) : mTable(table) {
50 ASSERT(mTable->atBuiltInLevel());
51 mTable->push();
52 }
53 ~TScopedSymbolTableLevel() {
54 while (!mTable->atBuiltInLevel())
55 mTable->pop();
56 }
57
58private:
59 TSymbolTable* mTable;
alokp@chromium.orgbafcbaa2010-11-23 19:07:43 +000060};
61} // namespace
62
63TShHandleBase::TShHandleBase() {
64 allocator.push();
65 SetGlobalPoolAllocator(&allocator);
66}
67
68TShHandleBase::~TShHandleBase() {
69 SetGlobalPoolAllocator(NULL);
70 allocator.popAll();
71}
72
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000073TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
74 : shaderType(type),
zmo@google.comf420c422011-09-12 18:27:59 +000075 shaderSpec(spec),
Jamie Madilleb1a0102013-07-08 13:31:38 -040076 maxUniformVectors(0),
77 maxExpressionComplexity(0),
78 maxCallStackDepth(0),
shannon.woods%transgaming.com@gtempaccount.comcbb6b6a2013-04-13 03:27:47 +000079 fragmentPrecisionHigh(false),
shannon.woods@transgaming.com1d432bb2013-01-25 21:57:28 +000080 clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC),
zmo@google.com9996b8e2012-01-19 01:43:55 +000081 builtInFunctionEmulator(type)
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000082{
zmo@google.comb9f64aa2012-01-20 00:35:15 +000083 longNameMap = LongNameMap::GetInstance();
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000084}
85
86TCompiler::~TCompiler()
87{
zmo@google.comb9f64aa2012-01-20 00:35:15 +000088 ASSERT(longNameMap);
89 longNameMap->Release();
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000090}
91
92bool TCompiler::Init(const ShBuiltInResources& resources)
alokp@chromium.org07620a52010-09-23 17:53:56 +000093{
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +000094 shaderVersion = 100;
gman@chromium.org8d804792012-10-17 21:33:48 +000095 maxUniformVectors = (shaderType == SH_VERTEX_SHADER) ?
96 resources.MaxVertexUniformVectors :
97 resources.MaxFragmentUniformVectors;
Jamie Madilleb1a0102013-07-08 13:31:38 -040098 maxExpressionComplexity = resources.MaxExpressionComplexity;
99 maxCallStackDepth = resources.MaxCallStackDepth;
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400100
101 SetGlobalPoolAllocator(&allocator);
alokp@chromium.orgbafcbaa2010-11-23 19:07:43 +0000102
alokp@chromium.org07620a52010-09-23 17:53:56 +0000103 // Generate built-in symbol table.
104 if (!InitBuiltInSymbolTable(resources))
105 return false;
alokp@chromium.org07620a52010-09-23 17:53:56 +0000106 InitExtensionBehavior(resources, extensionBehavior);
shannon.woods%transgaming.com@gtempaccount.comcbb6b6a2013-04-13 03:27:47 +0000107 fragmentPrecisionHigh = resources.FragmentPrecisionHigh == 1;
alokp@chromium.orgbafcbaa2010-11-23 19:07:43 +0000108
shannon.woods@transgaming.com1d432bb2013-01-25 21:57:28 +0000109 arrayBoundsClamper.SetClampingStrategy(resources.ArrayIndexClampingStrategy);
110 clampingStrategy = resources.ArrayIndexClampingStrategy;
111
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000112 hashFunction = resources.HashFunction;
113
alokp@chromium.org07620a52010-09-23 17:53:56 +0000114 return true;
115}
116
117bool TCompiler::compile(const char* const shaderStrings[],
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000118 size_t numStrings,
alokp@chromium.org07620a52010-09-23 17:53:56 +0000119 int compileOptions)
120{
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400121 TScopedPoolAllocator scopedAlloc(&allocator);
alokp@chromium.org07620a52010-09-23 17:53:56 +0000122 clearResults();
123
124 if (numStrings == 0)
125 return true;
126
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000127 // If compiling for WebGL, validate loop and indexing as well.
maxvujovic@gmail.com430f5e02012-06-08 17:47:59 +0000128 if (isWebGLBasedSpec(shaderSpec))
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000129 compileOptions |= SH_VALIDATE_LOOP_INDEXING;
alokp@chromium.org1f299542010-11-12 15:50:23 +0000130
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000131 // First string is path of source file if flag is set. The actual source follows.
132 const char* sourcePath = NULL;
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000133 size_t firstSource = 0;
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000134 if (compileOptions & SH_SOURCE_PATH)
135 {
136 sourcePath = shaderStrings[0];
137 ++firstSource;
138 }
139
alokp@chromium.org07620a52010-09-23 17:53:56 +0000140 TIntermediate intermediate(infoSink);
141 TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
zmo@google.comdc4b4f82011-06-17 00:42:53 +0000142 shaderType, shaderSpec, compileOptions, true,
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000143 sourcePath, infoSink);
shannon.woods%transgaming.com@gtempaccount.comcbb6b6a2013-04-13 03:27:47 +0000144 parseContext.fragmentPrecisionHigh = fragmentPrecisionHigh;
Alok Priyadarshi8156b6b2013-09-23 14:56:58 -0400145 SetGlobalParseContext(&parseContext);
alokp@chromium.org07620a52010-09-23 17:53:56 +0000146
147 // We preserve symbols at the built-in level from compile-to-compile.
148 // Start pushing the user-defined symbols at global level.
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400149 TScopedSymbolTableLevel scopedSymbolLevel(&symbolTable);
alokp@chromium.org07620a52010-09-23 17:53:56 +0000150
151 // Parse shader.
152 bool success =
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000153 (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) &&
alokp@chromium.org07620a52010-09-23 17:53:56 +0000154 (parseContext.treeRoot != NULL);
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +0000155
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +0000156 shaderVersion = parseContext.getShaderVersion();
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +0000157
alokp@chromium.org07620a52010-09-23 17:53:56 +0000158 if (success) {
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000159 TIntermNode* root = parseContext.treeRoot;
160 success = intermediate.postProcess(root);
161
zmo@google.comb1762df2011-07-30 02:04:23 +0000162 if (success)
Jamie Madilleb1a0102013-07-08 13:31:38 -0400163 success = detectCallDepth(root, infoSink, (compileOptions & SH_LIMIT_CALL_STACK_DEPTH) != 0);
zmo@google.comb1762df2011-07-30 02:04:23 +0000164
Jamie Madill05a80ce2013-06-20 11:55:49 -0400165 if (success && shaderVersion == 300 && shaderType == SH_FRAGMENT_SHADER)
166 success = validateOutputs(root);
167
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000168 if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
169 success = validateLimitations(root);
alokp@chromium.org07620a52010-09-23 17:53:56 +0000170
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000171 if (success && (compileOptions & SH_TIMING_RESTRICTIONS))
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000172 success = enforceTimingRestrictions(root, (compileOptions & SH_DEPENDENCY_GRAPH) != 0);
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000173
maxvujovic@gmail.com430f5e02012-06-08 17:47:59 +0000174 if (success && shaderSpec == SH_CSS_SHADERS_SPEC)
175 rewriteCSSShader(root);
176
zmo@google.com0c6bb7a2011-08-17 19:39:58 +0000177 // Unroll for-loop markup needs to happen after validateLimitations pass.
178 if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX))
179 ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(root);
180
zmo@google.com32e97312011-08-24 01:03:11 +0000181 // Built-in function emulation needs to happen after validateLimitations pass.
182 if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS))
183 builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root);
184
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000185 // Clamping uniform array bounds needs to happen after validateLimitations pass.
186 if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS))
187 arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root);
188
Jamie Madilleb1a0102013-07-08 13:31:38 -0400189 // Disallow expressions deemed too complex.
190 if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY))
191 success = limitExpressionComplexity(root);
192
zmo@google.comfd747b82011-04-23 01:30:07 +0000193 // Call mapLongVariableNames() before collectAttribsUniforms() so in
194 // collectAttribsUniforms() we already have the mapped symbol names and
195 // we could composite mapped and original variable names.
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000196 // Also, if we hash all the names, then no need to do this for long names.
197 if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES) && hashFunction == NULL)
zmo@google.comfd747b82011-04-23 01:30:07 +0000198 mapLongVariableNames(root);
199
Zhenyao Moac44cd22013-09-23 14:57:09 -0400200 if (success && shaderType == SH_VERTEX_SHADER && (compileOptions & SH_INIT_GL_POSITION)) {
201 InitializeGLPosition initGLPosition;
202 root->traverse(&initGLPosition);
203 }
204
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400205 if (success && (compileOptions & SH_VARIABLES)) {
206 collectVariables(root);
gman@chromium.org8d804792012-10-17 21:33:48 +0000207 if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) {
208 success = enforcePackingRestrictions();
209 if (!success) {
Jamie Madill075edd82013-07-08 13:30:19 -0400210 infoSink.info.prefix(EPrefixError);
211 infoSink.info << "too many uniforms";
gman@chromium.org8d804792012-10-17 21:33:48 +0000212 }
213 }
214 }
zmo@google.comfd747b82011-04-23 01:30:07 +0000215
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000216 if (success && (compileOptions & SH_INTERMEDIATE_TREE))
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000217 intermediate.outputTree(root);
alokp@chromium.org07620a52010-09-23 17:53:56 +0000218
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000219 if (success && (compileOptions & SH_OBJECT_CODE))
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000220 translate(root);
alokp@chromium.org07620a52010-09-23 17:53:56 +0000221 }
222
223 // Cleanup memory.
224 intermediate.remove(parseContext.treeRoot);
alokp@chromium.org07620a52010-09-23 17:53:56 +0000225
226 return success;
227}
228
Nicolas Capens49a88872013-06-20 09:54:03 -0400229bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000230{
shannon.woods%transgaming.com@gtempaccount.com18b4c4b2013-04-13 03:31:40 +0000231 compileResources = resources;
shannonwoods@chromium.org2ac0be92013-05-30 00:02:27 +0000232
Nicolas Capens49a88872013-06-20 09:54:03 -0400233 assert(symbolTable.isEmpty());
234 symbolTable.push(); // COMMON_BUILTINS
235 symbolTable.push(); // ESSL1_BUILTINS
236 symbolTable.push(); // ESSL3_BUILTINS
shannonwoods@chromium.org2ac0be92013-05-30 00:02:27 +0000237
Nicolas Capens49a88872013-06-20 09:54:03 -0400238 TPublicType integer;
239 integer.type = EbtInt;
240 integer.primarySize = 1;
241 integer.secondarySize = 1;
242 integer.array = false;
243
244 TPublicType floatingPoint;
245 floatingPoint.type = EbtFloat;
246 floatingPoint.primarySize = 1;
247 floatingPoint.secondarySize = 1;
248 floatingPoint.array = false;
249
Zhenyao Moa5a1dfc2013-09-23 14:57:03 -0400250 TPublicType sampler;
251 sampler.primarySize = 1;
252 sampler.secondarySize = 1;
253 sampler.array = false;
254
Nicolas Capens49a88872013-06-20 09:54:03 -0400255 switch(shaderType)
256 {
257 case SH_FRAGMENT_SHADER:
258 symbolTable.setDefaultPrecision(integer, EbpMedium);
259 break;
260 case SH_VERTEX_SHADER:
261 symbolTable.setDefaultPrecision(integer, EbpHigh);
262 symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
263 break;
264 default: assert(false && "Language not supported");
265 }
Zhenyao Moa5a1dfc2013-09-23 14:57:03 -0400266 // We set defaults for all the sampler types, even those that are
267 // only available if an extension exists.
268 for (int samplerType = EbtGuardSamplerBegin + 1;
269 samplerType < EbtGuardSamplerEnd; ++samplerType) {
270 sampler.type = static_cast<TBasicType>(samplerType);
271 symbolTable.setDefaultPrecision(sampler, EbpLow);
272 }
Nicolas Capens49a88872013-06-20 09:54:03 -0400273
Jamie Madill1b452142013-07-12 14:51:11 -0400274 InsertBuiltInFunctions(shaderType, shaderSpec, resources, symbolTable);
Nicolas Capens49a88872013-06-20 09:54:03 -0400275
276 IdentifyBuiltIns(shaderType, shaderSpec, resources, symbolTable);
277
278 return true;
alokp@chromium.org07620a52010-09-23 17:53:56 +0000279}
280
281void TCompiler::clearResults()
282{
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000283 arrayBoundsClamper.Cleanup();
alokp@chromium.org07620a52010-09-23 17:53:56 +0000284 infoSink.info.erase();
285 infoSink.obj.erase();
286 infoSink.debug.erase();
287
288 attribs.clear();
289 uniforms.clear();
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400290 varyings.clear();
zmo@google.coma3b4ab42011-09-16 00:53:26 +0000291
292 builtInFunctionEmulator.Cleanup();
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000293
294 nameMap.clear();
alokp@chromium.org07620a52010-09-23 17:53:56 +0000295}
296
Jamie Madilleb1a0102013-07-08 13:31:38 -0400297bool TCompiler::detectCallDepth(TIntermNode* root, TInfoSink& infoSink, bool limitCallStackDepth)
zmo@google.comb1762df2011-07-30 02:04:23 +0000298{
Jamie Madilleb1a0102013-07-08 13:31:38 -0400299 DetectCallDepth detect(infoSink, limitCallStackDepth, maxCallStackDepth);
zmo@google.comb1762df2011-07-30 02:04:23 +0000300 root->traverse(&detect);
Jamie Madilleb1a0102013-07-08 13:31:38 -0400301 switch (detect.detectCallDepth()) {
302 case DetectCallDepth::kErrorNone:
zmo@google.comb1762df2011-07-30 02:04:23 +0000303 return true;
Jamie Madilleb1a0102013-07-08 13:31:38 -0400304 case DetectCallDepth::kErrorMissingMain:
Jamie Madill075edd82013-07-08 13:30:19 -0400305 infoSink.info.prefix(EPrefixError);
306 infoSink.info << "Missing main()";
zmo@google.comb1762df2011-07-30 02:04:23 +0000307 return false;
Jamie Madilleb1a0102013-07-08 13:31:38 -0400308 case DetectCallDepth::kErrorRecursion:
Jamie Madill075edd82013-07-08 13:30:19 -0400309 infoSink.info.prefix(EPrefixError);
310 infoSink.info << "Function recursion detected";
zmo@google.comb1762df2011-07-30 02:04:23 +0000311 return false;
Jamie Madilleb1a0102013-07-08 13:31:38 -0400312 case DetectCallDepth::kErrorMaxDepthExceeded:
313 infoSink.info.prefix(EPrefixError);
314 infoSink.info << "Function call stack too deep";
315 return false;
zmo@google.comb1762df2011-07-30 02:04:23 +0000316 default:
317 UNREACHABLE();
318 return false;
319 }
320}
321
Jamie Madill05a80ce2013-06-20 11:55:49 -0400322bool TCompiler::validateOutputs(TIntermNode* root)
323{
324 ValidateOutputs validateOutputs(infoSink.info, compileResources.MaxDrawBuffers);
325 root->traverse(&validateOutputs);
326 return (validateOutputs.numErrors() == 0);
327}
328
maxvujovic@gmail.com430f5e02012-06-08 17:47:59 +0000329void TCompiler::rewriteCSSShader(TIntermNode* root)
330{
331 RenameFunction renamer("main(", "css_main(");
332 root->traverse(&renamer);
333}
334
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000335bool TCompiler::validateLimitations(TIntermNode* root) {
336 ValidateLimitations validate(shaderType, infoSink.info);
337 root->traverse(&validate);
338 return validate.numErrors() == 0;
339}
340
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000341bool TCompiler::enforceTimingRestrictions(TIntermNode* root, bool outputGraph)
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000342{
343 if (shaderSpec != SH_WEBGL_SPEC) {
344 infoSink.info << "Timing restrictions must be enforced under the WebGL spec.";
345 return false;
346 }
347
348 if (shaderType == SH_FRAGMENT_SHADER) {
349 TDependencyGraph graph(root);
350
351 // Output any errors first.
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000352 bool success = enforceFragmentShaderTimingRestrictions(graph);
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000353
354 // Then, output the dependency graph.
355 if (outputGraph) {
356 TDependencyGraphOutput output(infoSink.info);
357 output.outputAllSpanningTrees(graph);
358 }
359
360 return success;
361 }
362 else {
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000363 return enforceVertexShaderTimingRestrictions(root);
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000364 }
365}
366
Jamie Madilleb1a0102013-07-08 13:31:38 -0400367bool TCompiler::limitExpressionComplexity(TIntermNode* root)
368{
369 TIntermTraverser traverser;
370 root->traverse(&traverser);
371 TDependencyGraph graph(root);
372
373 for (TFunctionCallVector::const_iterator iter = graph.beginUserDefinedFunctionCalls();
374 iter != graph.endUserDefinedFunctionCalls();
375 ++iter)
376 {
377 TGraphFunctionCall* samplerSymbol = *iter;
378 TDependencyGraphTraverser graphTraverser;
379 samplerSymbol->traverse(&graphTraverser);
380 }
381
382 if (traverser.getMaxDepth() > maxExpressionComplexity) {
383 infoSink.info << "Expression too complex.";
384 return false;
385 }
386 return true;
387}
388
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000389bool TCompiler::enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph)
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000390{
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000391 RestrictFragmentShaderTiming restrictor(infoSink.info);
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000392 restrictor.enforceRestrictions(graph);
393 return restrictor.numErrors() == 0;
394}
395
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000396bool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root)
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000397{
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000398 RestrictVertexShaderTiming restrictor(infoSink.info);
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000399 restrictor.enforceRestrictions(root);
400 return restrictor.numErrors() == 0;
401}
402
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400403void TCompiler::collectVariables(TIntermNode* root)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000404{
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400405 CollectVariables collect(attribs, uniforms, varyings, hashFunction);
alokp@chromium.org07620a52010-09-23 17:53:56 +0000406 root->traverse(&collect);
407}
zmo@google.comfd747b82011-04-23 01:30:07 +0000408
gman@chromium.org8d804792012-10-17 21:33:48 +0000409bool TCompiler::enforcePackingRestrictions()
410{
411 VariablePacker packer;
412 return packer.CheckVariablesWithinPackingLimits(maxUniformVectors, uniforms);
413}
414
zmo@google.comfd747b82011-04-23 01:30:07 +0000415void TCompiler::mapLongVariableNames(TIntermNode* root)
416{
zmo@google.comb9f64aa2012-01-20 00:35:15 +0000417 ASSERT(longNameMap);
418 MapLongVariableNames map(longNameMap);
zmo@google.com9996b8e2012-01-19 01:43:55 +0000419 root->traverse(&map);
zmo@google.comfd747b82011-04-23 01:30:07 +0000420}
421
422int TCompiler::getMappedNameMaxLength() const
423{
kbr@chromium.org22152112011-10-26 01:18:28 +0000424 return MAX_SHORTENED_IDENTIFIER_SIZE + 1;
zmo@google.comfd747b82011-04-23 01:30:07 +0000425}
zmo@google.com5601ea02011-06-10 18:23:25 +0000426
427const TExtensionBehavior& TCompiler::getExtensionBehavior() const
428{
429 return extensionBehavior;
430}
zmo@google.com32e97312011-08-24 01:03:11 +0000431
shannon.woods%transgaming.com@gtempaccount.com18b4c4b2013-04-13 03:31:40 +0000432const ShBuiltInResources& TCompiler::getResources() const
433{
434 return compileResources;
435}
436
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000437const ArrayBoundsClamper& TCompiler::getArrayBoundsClamper() const
438{
439 return arrayBoundsClamper;
440}
441
shannon.woods@transgaming.com1d432bb2013-01-25 21:57:28 +0000442ShArrayIndexClampingStrategy TCompiler::getArrayIndexClampingStrategy() const
443{
444 return clampingStrategy;
445}
446
447const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
448{
449 return builtInFunctionEmulator;
450}