blob: 37b5ab2226192f9a0d0e4d0c9f607d5b093f98e9 [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"
alokp@chromium.org8b851c62012-06-15 16:25:11 +000011#include "compiler/InitializeParseContext.h"
zmo@google.comb9f64aa2012-01-20 00:35:15 +000012#include "compiler/MapLongVariableNames.h"
alokp@chromium.org07620a52010-09-23 17:53:56 +000013#include "compiler/ParseHelper.h"
maxvujovic@gmail.com430f5e02012-06-08 17:47:59 +000014#include "compiler/RenameFunction.h"
alokp@chromium.org07620a52010-09-23 17:53:56 +000015#include "compiler/ShHandle.h"
alokp@chromium.orgb59a7782010-11-24 18:38:33 +000016#include "compiler/ValidateLimitations.h"
Jamie Madill05a80ce2013-06-20 11:55:49 -040017#include "compiler/ValidateOutputs.h"
gman@chromium.org8d804792012-10-17 21:33:48 +000018#include "compiler/VariablePacker.h"
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +000019#include "compiler/depgraph/DependencyGraph.h"
20#include "compiler/depgraph/DependencyGraphOutput.h"
21#include "compiler/timing/RestrictFragmentShaderTiming.h"
22#include "compiler/timing/RestrictVertexShaderTiming.h"
shannon.woods@transgaming.comda1ed362013-01-25 21:54:57 +000023#include "third_party/compiler/ArrayBoundsClamper.h"
alokp@chromium.org07620a52010-09-23 17:53:56 +000024
maxvujovic@gmail.com430f5e02012-06-08 17:47:59 +000025bool isWebGLBasedSpec(ShShaderSpec spec)
26{
27 return spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC;
28}
29
alokp@chromium.orgbafcbaa2010-11-23 19:07:43 +000030namespace {
alokp@chromium.orgbafcbaa2010-11-23 19:07:43 +000031class TScopedPoolAllocator {
32public:
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -040033 TScopedPoolAllocator(TPoolAllocator* allocator) : mAllocator(allocator) {
34 mAllocator->push();
alokp@chromium.orgbafcbaa2010-11-23 19:07:43 +000035 SetGlobalPoolAllocator(mAllocator);
36 }
37 ~TScopedPoolAllocator() {
38 SetGlobalPoolAllocator(NULL);
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -040039 mAllocator->pop();
alokp@chromium.orgbafcbaa2010-11-23 19:07:43 +000040 }
41
42private:
43 TPoolAllocator* mAllocator;
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -040044};
45
46class TScopedSymbolTableLevel {
47public:
48 TScopedSymbolTableLevel(TSymbolTable* table) : mTable(table) {
49 ASSERT(mTable->atBuiltInLevel());
50 mTable->push();
51 }
52 ~TScopedSymbolTableLevel() {
53 while (!mTable->atBuiltInLevel())
54 mTable->pop();
55 }
56
57private:
58 TSymbolTable* mTable;
alokp@chromium.orgbafcbaa2010-11-23 19:07:43 +000059};
60} // namespace
61
62TShHandleBase::TShHandleBase() {
63 allocator.push();
64 SetGlobalPoolAllocator(&allocator);
65}
66
67TShHandleBase::~TShHandleBase() {
68 SetGlobalPoolAllocator(NULL);
69 allocator.popAll();
70}
71
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000072TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
73 : shaderType(type),
zmo@google.comf420c422011-09-12 18:27:59 +000074 shaderSpec(spec),
Jamie Madilleb1a0102013-07-08 13:31:38 -040075 maxUniformVectors(0),
76 maxExpressionComplexity(0),
77 maxCallStackDepth(0),
shannon.woods%transgaming.com@gtempaccount.comcbb6b6a2013-04-13 03:27:47 +000078 fragmentPrecisionHigh(false),
shannon.woods@transgaming.com1d432bb2013-01-25 21:57:28 +000079 clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC),
zmo@google.com9996b8e2012-01-19 01:43:55 +000080 builtInFunctionEmulator(type)
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000081{
zmo@google.comb9f64aa2012-01-20 00:35:15 +000082 longNameMap = LongNameMap::GetInstance();
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000083}
84
85TCompiler::~TCompiler()
86{
zmo@google.comb9f64aa2012-01-20 00:35:15 +000087 ASSERT(longNameMap);
88 longNameMap->Release();
alokp@chromium.org4888ceb2010-10-01 21:13:12 +000089}
90
91bool TCompiler::Init(const ShBuiltInResources& resources)
alokp@chromium.org07620a52010-09-23 17:53:56 +000092{
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +000093 shaderVersion = 100;
gman@chromium.org8d804792012-10-17 21:33:48 +000094 maxUniformVectors = (shaderType == SH_VERTEX_SHADER) ?
95 resources.MaxVertexUniformVectors :
96 resources.MaxFragmentUniformVectors;
Jamie Madilleb1a0102013-07-08 13:31:38 -040097 maxExpressionComplexity = resources.MaxExpressionComplexity;
98 maxCallStackDepth = resources.MaxCallStackDepth;
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -040099
100 SetGlobalPoolAllocator(&allocator);
alokp@chromium.orgbafcbaa2010-11-23 19:07:43 +0000101
alokp@chromium.org07620a52010-09-23 17:53:56 +0000102 // Generate built-in symbol table.
103 if (!InitBuiltInSymbolTable(resources))
104 return false;
alokp@chromium.org07620a52010-09-23 17:53:56 +0000105 InitExtensionBehavior(resources, extensionBehavior);
shannon.woods%transgaming.com@gtempaccount.comcbb6b6a2013-04-13 03:27:47 +0000106 fragmentPrecisionHigh = resources.FragmentPrecisionHigh == 1;
alokp@chromium.orgbafcbaa2010-11-23 19:07:43 +0000107
shannon.woods@transgaming.com1d432bb2013-01-25 21:57:28 +0000108 arrayBoundsClamper.SetClampingStrategy(resources.ArrayIndexClampingStrategy);
109 clampingStrategy = resources.ArrayIndexClampingStrategy;
110
daniel@transgaming.comc23f4612012-11-28 19:42:57 +0000111 hashFunction = resources.HashFunction;
112
alokp@chromium.org07620a52010-09-23 17:53:56 +0000113 return true;
114}
115
116bool TCompiler::compile(const char* const shaderStrings[],
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000117 size_t numStrings,
alokp@chromium.org07620a52010-09-23 17:53:56 +0000118 int compileOptions)
119{
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400120 TScopedPoolAllocator scopedAlloc(&allocator);
alokp@chromium.org07620a52010-09-23 17:53:56 +0000121 clearResults();
122
123 if (numStrings == 0)
124 return true;
125
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000126 // If compiling for WebGL, validate loop and indexing as well.
maxvujovic@gmail.com430f5e02012-06-08 17:47:59 +0000127 if (isWebGLBasedSpec(shaderSpec))
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000128 compileOptions |= SH_VALIDATE_LOOP_INDEXING;
alokp@chromium.org1f299542010-11-12 15:50:23 +0000129
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000130 // First string is path of source file if flag is set. The actual source follows.
131 const char* sourcePath = NULL;
shannon.woods@transgaming.comd64b3da2013-02-28 23:19:26 +0000132 size_t firstSource = 0;
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000133 if (compileOptions & SH_SOURCE_PATH)
134 {
135 sourcePath = shaderStrings[0];
136 ++firstSource;
137 }
138
alokp@chromium.org07620a52010-09-23 17:53:56 +0000139 TIntermediate intermediate(infoSink);
140 TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
zmo@google.comdc4b4f82011-06-17 00:42:53 +0000141 shaderType, shaderSpec, compileOptions, true,
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000142 sourcePath, infoSink);
shannon.woods%transgaming.com@gtempaccount.comcbb6b6a2013-04-13 03:27:47 +0000143 parseContext.fragmentPrecisionHigh = fragmentPrecisionHigh;
Alok Priyadarshi8156b6b2013-09-23 14:56:58 -0400144 SetGlobalParseContext(&parseContext);
alokp@chromium.org07620a52010-09-23 17:53:56 +0000145
146 // We preserve symbols at the built-in level from compile-to-compile.
147 // Start pushing the user-defined symbols at global level.
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400148 TScopedSymbolTableLevel scopedSymbolLevel(&symbolTable);
alokp@chromium.org07620a52010-09-23 17:53:56 +0000149
150 // Parse shader.
151 bool success =
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000152 (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) &&
alokp@chromium.org07620a52010-09-23 17:53:56 +0000153 (parseContext.treeRoot != NULL);
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +0000154
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +0000155 shaderVersion = parseContext.getShaderVersion();
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +0000156
alokp@chromium.org07620a52010-09-23 17:53:56 +0000157 if (success) {
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000158 TIntermNode* root = parseContext.treeRoot;
159 success = intermediate.postProcess(root);
160
zmo@google.comb1762df2011-07-30 02:04:23 +0000161 if (success)
Jamie Madilleb1a0102013-07-08 13:31:38 -0400162 success = detectCallDepth(root, infoSink, (compileOptions & SH_LIMIT_CALL_STACK_DEPTH) != 0);
zmo@google.comb1762df2011-07-30 02:04:23 +0000163
Jamie Madill05a80ce2013-06-20 11:55:49 -0400164 if (success && shaderVersion == 300 && shaderType == SH_FRAGMENT_SHADER)
165 success = validateOutputs(root);
166
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000167 if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
168 success = validateLimitations(root);
alokp@chromium.org07620a52010-09-23 17:53:56 +0000169
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000170 if (success && (compileOptions & SH_TIMING_RESTRICTIONS))
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000171 success = enforceTimingRestrictions(root, (compileOptions & SH_DEPENDENCY_GRAPH) != 0);
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000172
maxvujovic@gmail.com430f5e02012-06-08 17:47:59 +0000173 if (success && shaderSpec == SH_CSS_SHADERS_SPEC)
174 rewriteCSSShader(root);
175
zmo@google.com0c6bb7a2011-08-17 19:39:58 +0000176 // Unroll for-loop markup needs to happen after validateLimitations pass.
177 if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX))
178 ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(root);
179
zmo@google.com32e97312011-08-24 01:03:11 +0000180 // Built-in function emulation needs to happen after validateLimitations pass.
181 if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS))
182 builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root);
183
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000184 // Clamping uniform array bounds needs to happen after validateLimitations pass.
185 if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS))
186 arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root);
187
Jamie Madilleb1a0102013-07-08 13:31:38 -0400188 // Disallow expressions deemed too complex.
189 if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY))
190 success = limitExpressionComplexity(root);
191
zmo@google.comfd747b82011-04-23 01:30:07 +0000192 // Call mapLongVariableNames() before collectAttribsUniforms() so in
193 // collectAttribsUniforms() we already have the mapped symbol names and
194 // we could composite mapped and original variable names.
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000195 // Also, if we hash all the names, then no need to do this for long names.
196 if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES) && hashFunction == NULL)
zmo@google.comfd747b82011-04-23 01:30:07 +0000197 mapLongVariableNames(root);
198
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400199 if (success && (compileOptions & SH_VARIABLES)) {
200 collectVariables(root);
gman@chromium.org8d804792012-10-17 21:33:48 +0000201 if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) {
202 success = enforcePackingRestrictions();
203 if (!success) {
Jamie Madill075edd82013-07-08 13:30:19 -0400204 infoSink.info.prefix(EPrefixError);
205 infoSink.info << "too many uniforms";
gman@chromium.org8d804792012-10-17 21:33:48 +0000206 }
207 }
208 }
zmo@google.comfd747b82011-04-23 01:30:07 +0000209
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000210 if (success && (compileOptions & SH_INTERMEDIATE_TREE))
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000211 intermediate.outputTree(root);
alokp@chromium.org07620a52010-09-23 17:53:56 +0000212
alokp@chromium.org4888ceb2010-10-01 21:13:12 +0000213 if (success && (compileOptions & SH_OBJECT_CODE))
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000214 translate(root);
alokp@chromium.org07620a52010-09-23 17:53:56 +0000215 }
216
217 // Cleanup memory.
218 intermediate.remove(parseContext.treeRoot);
alokp@chromium.org07620a52010-09-23 17:53:56 +0000219
220 return success;
221}
222
Nicolas Capens49a88872013-06-20 09:54:03 -0400223bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000224{
shannon.woods%transgaming.com@gtempaccount.com18b4c4b2013-04-13 03:31:40 +0000225 compileResources = resources;
shannonwoods@chromium.org2ac0be92013-05-30 00:02:27 +0000226
Nicolas Capens49a88872013-06-20 09:54:03 -0400227 assert(symbolTable.isEmpty());
228 symbolTable.push(); // COMMON_BUILTINS
229 symbolTable.push(); // ESSL1_BUILTINS
230 symbolTable.push(); // ESSL3_BUILTINS
shannonwoods@chromium.org2ac0be92013-05-30 00:02:27 +0000231
Nicolas Capens49a88872013-06-20 09:54:03 -0400232 TPublicType integer;
233 integer.type = EbtInt;
234 integer.primarySize = 1;
235 integer.secondarySize = 1;
236 integer.array = false;
237
238 TPublicType floatingPoint;
239 floatingPoint.type = EbtFloat;
240 floatingPoint.primarySize = 1;
241 floatingPoint.secondarySize = 1;
242 floatingPoint.array = false;
243
244 switch(shaderType)
245 {
246 case SH_FRAGMENT_SHADER:
247 symbolTable.setDefaultPrecision(integer, EbpMedium);
248 break;
249 case SH_VERTEX_SHADER:
250 symbolTable.setDefaultPrecision(integer, EbpHigh);
251 symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
252 break;
253 default: assert(false && "Language not supported");
254 }
255
Jamie Madill1b452142013-07-12 14:51:11 -0400256 InsertBuiltInFunctions(shaderType, shaderSpec, resources, symbolTable);
Nicolas Capens49a88872013-06-20 09:54:03 -0400257
258 IdentifyBuiltIns(shaderType, shaderSpec, resources, symbolTable);
259
260 return true;
alokp@chromium.org07620a52010-09-23 17:53:56 +0000261}
262
263void TCompiler::clearResults()
264{
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000265 arrayBoundsClamper.Cleanup();
alokp@chromium.org07620a52010-09-23 17:53:56 +0000266 infoSink.info.erase();
267 infoSink.obj.erase();
268 infoSink.debug.erase();
269
270 attribs.clear();
271 uniforms.clear();
zmo@google.coma3b4ab42011-09-16 00:53:26 +0000272
273 builtInFunctionEmulator.Cleanup();
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000274
275 nameMap.clear();
alokp@chromium.org07620a52010-09-23 17:53:56 +0000276}
277
Jamie Madilleb1a0102013-07-08 13:31:38 -0400278bool TCompiler::detectCallDepth(TIntermNode* root, TInfoSink& infoSink, bool limitCallStackDepth)
zmo@google.comb1762df2011-07-30 02:04:23 +0000279{
Jamie Madilleb1a0102013-07-08 13:31:38 -0400280 DetectCallDepth detect(infoSink, limitCallStackDepth, maxCallStackDepth);
zmo@google.comb1762df2011-07-30 02:04:23 +0000281 root->traverse(&detect);
Jamie Madilleb1a0102013-07-08 13:31:38 -0400282 switch (detect.detectCallDepth()) {
283 case DetectCallDepth::kErrorNone:
zmo@google.comb1762df2011-07-30 02:04:23 +0000284 return true;
Jamie Madilleb1a0102013-07-08 13:31:38 -0400285 case DetectCallDepth::kErrorMissingMain:
Jamie Madill075edd82013-07-08 13:30:19 -0400286 infoSink.info.prefix(EPrefixError);
287 infoSink.info << "Missing main()";
zmo@google.comb1762df2011-07-30 02:04:23 +0000288 return false;
Jamie Madilleb1a0102013-07-08 13:31:38 -0400289 case DetectCallDepth::kErrorRecursion:
Jamie Madill075edd82013-07-08 13:30:19 -0400290 infoSink.info.prefix(EPrefixError);
291 infoSink.info << "Function recursion detected";
zmo@google.comb1762df2011-07-30 02:04:23 +0000292 return false;
Jamie Madilleb1a0102013-07-08 13:31:38 -0400293 case DetectCallDepth::kErrorMaxDepthExceeded:
294 infoSink.info.prefix(EPrefixError);
295 infoSink.info << "Function call stack too deep";
296 return false;
zmo@google.comb1762df2011-07-30 02:04:23 +0000297 default:
298 UNREACHABLE();
299 return false;
300 }
301}
302
Jamie Madill05a80ce2013-06-20 11:55:49 -0400303bool TCompiler::validateOutputs(TIntermNode* root)
304{
305 ValidateOutputs validateOutputs(infoSink.info, compileResources.MaxDrawBuffers);
306 root->traverse(&validateOutputs);
307 return (validateOutputs.numErrors() == 0);
308}
309
maxvujovic@gmail.com430f5e02012-06-08 17:47:59 +0000310void TCompiler::rewriteCSSShader(TIntermNode* root)
311{
312 RenameFunction renamer("main(", "css_main(");
313 root->traverse(&renamer);
314}
315
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000316bool TCompiler::validateLimitations(TIntermNode* root) {
317 ValidateLimitations validate(shaderType, infoSink.info);
318 root->traverse(&validate);
319 return validate.numErrors() == 0;
320}
321
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000322bool TCompiler::enforceTimingRestrictions(TIntermNode* root, bool outputGraph)
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000323{
324 if (shaderSpec != SH_WEBGL_SPEC) {
325 infoSink.info << "Timing restrictions must be enforced under the WebGL spec.";
326 return false;
327 }
328
329 if (shaderType == SH_FRAGMENT_SHADER) {
330 TDependencyGraph graph(root);
331
332 // Output any errors first.
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000333 bool success = enforceFragmentShaderTimingRestrictions(graph);
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000334
335 // Then, output the dependency graph.
336 if (outputGraph) {
337 TDependencyGraphOutput output(infoSink.info);
338 output.outputAllSpanningTrees(graph);
339 }
340
341 return success;
342 }
343 else {
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000344 return enforceVertexShaderTimingRestrictions(root);
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000345 }
346}
347
Jamie Madilleb1a0102013-07-08 13:31:38 -0400348bool TCompiler::limitExpressionComplexity(TIntermNode* root)
349{
350 TIntermTraverser traverser;
351 root->traverse(&traverser);
352 TDependencyGraph graph(root);
353
354 for (TFunctionCallVector::const_iterator iter = graph.beginUserDefinedFunctionCalls();
355 iter != graph.endUserDefinedFunctionCalls();
356 ++iter)
357 {
358 TGraphFunctionCall* samplerSymbol = *iter;
359 TDependencyGraphTraverser graphTraverser;
360 samplerSymbol->traverse(&graphTraverser);
361 }
362
363 if (traverser.getMaxDepth() > maxExpressionComplexity) {
364 infoSink.info << "Expression too complex.";
365 return false;
366 }
367 return true;
368}
369
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000370bool TCompiler::enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph)
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000371{
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000372 RestrictFragmentShaderTiming restrictor(infoSink.info);
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000373 restrictor.enforceRestrictions(graph);
374 return restrictor.numErrors() == 0;
375}
376
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000377bool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root)
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000378{
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000379 RestrictVertexShaderTiming restrictor(infoSink.info);
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000380 restrictor.enforceRestrictions(root);
381 return restrictor.numErrors() == 0;
382}
383
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400384void TCompiler::collectVariables(TIntermNode* root)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000385{
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400386 CollectVariables collect(attribs, uniforms, varyings, hashFunction);
alokp@chromium.org07620a52010-09-23 17:53:56 +0000387 root->traverse(&collect);
388}
zmo@google.comfd747b82011-04-23 01:30:07 +0000389
gman@chromium.org8d804792012-10-17 21:33:48 +0000390bool TCompiler::enforcePackingRestrictions()
391{
392 VariablePacker packer;
393 return packer.CheckVariablesWithinPackingLimits(maxUniformVectors, uniforms);
394}
395
zmo@google.comfd747b82011-04-23 01:30:07 +0000396void TCompiler::mapLongVariableNames(TIntermNode* root)
397{
zmo@google.comb9f64aa2012-01-20 00:35:15 +0000398 ASSERT(longNameMap);
399 MapLongVariableNames map(longNameMap);
zmo@google.com9996b8e2012-01-19 01:43:55 +0000400 root->traverse(&map);
zmo@google.comfd747b82011-04-23 01:30:07 +0000401}
402
403int TCompiler::getMappedNameMaxLength() const
404{
kbr@chromium.org22152112011-10-26 01:18:28 +0000405 return MAX_SHORTENED_IDENTIFIER_SIZE + 1;
zmo@google.comfd747b82011-04-23 01:30:07 +0000406}
zmo@google.com5601ea02011-06-10 18:23:25 +0000407
408const TExtensionBehavior& TCompiler::getExtensionBehavior() const
409{
410 return extensionBehavior;
411}
zmo@google.com32e97312011-08-24 01:03:11 +0000412
shannon.woods%transgaming.com@gtempaccount.com18b4c4b2013-04-13 03:31:40 +0000413const ShBuiltInResources& TCompiler::getResources() const
414{
415 return compileResources;
416}
417
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000418const ArrayBoundsClamper& TCompiler::getArrayBoundsClamper() const
419{
420 return arrayBoundsClamper;
421}
422
shannon.woods@transgaming.com1d432bb2013-01-25 21:57:28 +0000423ShArrayIndexClampingStrategy TCompiler::getArrayIndexClampingStrategy() const
424{
425 return clampingStrategy;
426}
427
428const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
429{
430 return builtInFunctionEmulator;
431}