blob: 0a91f9b2cd1a5bf0382f72a7a86be4cbb2e355c1 [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
Zhenyao Moa5a1dfc2013-09-23 14:57:03 -0400244 TPublicType sampler;
245 sampler.primarySize = 1;
246 sampler.secondarySize = 1;
247 sampler.array = false;
248
Nicolas Capens49a88872013-06-20 09:54:03 -0400249 switch(shaderType)
250 {
251 case SH_FRAGMENT_SHADER:
252 symbolTable.setDefaultPrecision(integer, EbpMedium);
253 break;
254 case SH_VERTEX_SHADER:
255 symbolTable.setDefaultPrecision(integer, EbpHigh);
256 symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
257 break;
258 default: assert(false && "Language not supported");
259 }
Zhenyao Moa5a1dfc2013-09-23 14:57:03 -0400260 // We set defaults for all the sampler types, even those that are
261 // only available if an extension exists.
262 for (int samplerType = EbtGuardSamplerBegin + 1;
263 samplerType < EbtGuardSamplerEnd; ++samplerType) {
264 sampler.type = static_cast<TBasicType>(samplerType);
265 symbolTable.setDefaultPrecision(sampler, EbpLow);
266 }
Nicolas Capens49a88872013-06-20 09:54:03 -0400267
Jamie Madill1b452142013-07-12 14:51:11 -0400268 InsertBuiltInFunctions(shaderType, shaderSpec, resources, symbolTable);
Nicolas Capens49a88872013-06-20 09:54:03 -0400269
270 IdentifyBuiltIns(shaderType, shaderSpec, resources, symbolTable);
271
272 return true;
alokp@chromium.org07620a52010-09-23 17:53:56 +0000273}
274
275void TCompiler::clearResults()
276{
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000277 arrayBoundsClamper.Cleanup();
alokp@chromium.org07620a52010-09-23 17:53:56 +0000278 infoSink.info.erase();
279 infoSink.obj.erase();
280 infoSink.debug.erase();
281
282 attribs.clear();
283 uniforms.clear();
Zhenyao Mod2d340b2013-09-23 14:57:05 -0400284 varyings.clear();
zmo@google.coma3b4ab42011-09-16 00:53:26 +0000285
286 builtInFunctionEmulator.Cleanup();
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000287
288 nameMap.clear();
alokp@chromium.org07620a52010-09-23 17:53:56 +0000289}
290
Jamie Madilleb1a0102013-07-08 13:31:38 -0400291bool TCompiler::detectCallDepth(TIntermNode* root, TInfoSink& infoSink, bool limitCallStackDepth)
zmo@google.comb1762df2011-07-30 02:04:23 +0000292{
Jamie Madilleb1a0102013-07-08 13:31:38 -0400293 DetectCallDepth detect(infoSink, limitCallStackDepth, maxCallStackDepth);
zmo@google.comb1762df2011-07-30 02:04:23 +0000294 root->traverse(&detect);
Jamie Madilleb1a0102013-07-08 13:31:38 -0400295 switch (detect.detectCallDepth()) {
296 case DetectCallDepth::kErrorNone:
zmo@google.comb1762df2011-07-30 02:04:23 +0000297 return true;
Jamie Madilleb1a0102013-07-08 13:31:38 -0400298 case DetectCallDepth::kErrorMissingMain:
Jamie Madill075edd82013-07-08 13:30:19 -0400299 infoSink.info.prefix(EPrefixError);
300 infoSink.info << "Missing main()";
zmo@google.comb1762df2011-07-30 02:04:23 +0000301 return false;
Jamie Madilleb1a0102013-07-08 13:31:38 -0400302 case DetectCallDepth::kErrorRecursion:
Jamie Madill075edd82013-07-08 13:30:19 -0400303 infoSink.info.prefix(EPrefixError);
304 infoSink.info << "Function recursion detected";
zmo@google.comb1762df2011-07-30 02:04:23 +0000305 return false;
Jamie Madilleb1a0102013-07-08 13:31:38 -0400306 case DetectCallDepth::kErrorMaxDepthExceeded:
307 infoSink.info.prefix(EPrefixError);
308 infoSink.info << "Function call stack too deep";
309 return false;
zmo@google.comb1762df2011-07-30 02:04:23 +0000310 default:
311 UNREACHABLE();
312 return false;
313 }
314}
315
Jamie Madill05a80ce2013-06-20 11:55:49 -0400316bool TCompiler::validateOutputs(TIntermNode* root)
317{
318 ValidateOutputs validateOutputs(infoSink.info, compileResources.MaxDrawBuffers);
319 root->traverse(&validateOutputs);
320 return (validateOutputs.numErrors() == 0);
321}
322
maxvujovic@gmail.com430f5e02012-06-08 17:47:59 +0000323void TCompiler::rewriteCSSShader(TIntermNode* root)
324{
325 RenameFunction renamer("main(", "css_main(");
326 root->traverse(&renamer);
327}
328
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000329bool TCompiler::validateLimitations(TIntermNode* root) {
330 ValidateLimitations validate(shaderType, infoSink.info);
331 root->traverse(&validate);
332 return validate.numErrors() == 0;
333}
334
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000335bool TCompiler::enforceTimingRestrictions(TIntermNode* root, bool outputGraph)
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000336{
337 if (shaderSpec != SH_WEBGL_SPEC) {
338 infoSink.info << "Timing restrictions must be enforced under the WebGL spec.";
339 return false;
340 }
341
342 if (shaderType == SH_FRAGMENT_SHADER) {
343 TDependencyGraph graph(root);
344
345 // Output any errors first.
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000346 bool success = enforceFragmentShaderTimingRestrictions(graph);
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000347
348 // Then, output the dependency graph.
349 if (outputGraph) {
350 TDependencyGraphOutput output(infoSink.info);
351 output.outputAllSpanningTrees(graph);
352 }
353
354 return success;
355 }
356 else {
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000357 return enforceVertexShaderTimingRestrictions(root);
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000358 }
359}
360
Jamie Madilleb1a0102013-07-08 13:31:38 -0400361bool TCompiler::limitExpressionComplexity(TIntermNode* root)
362{
363 TIntermTraverser traverser;
364 root->traverse(&traverser);
365 TDependencyGraph graph(root);
366
367 for (TFunctionCallVector::const_iterator iter = graph.beginUserDefinedFunctionCalls();
368 iter != graph.endUserDefinedFunctionCalls();
369 ++iter)
370 {
371 TGraphFunctionCall* samplerSymbol = *iter;
372 TDependencyGraphTraverser graphTraverser;
373 samplerSymbol->traverse(&graphTraverser);
374 }
375
376 if (traverser.getMaxDepth() > maxExpressionComplexity) {
377 infoSink.info << "Expression too complex.";
378 return false;
379 }
380 return true;
381}
382
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000383bool TCompiler::enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph)
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000384{
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000385 RestrictFragmentShaderTiming restrictor(infoSink.info);
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000386 restrictor.enforceRestrictions(graph);
387 return restrictor.numErrors() == 0;
388}
389
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000390bool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root)
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000391{
maxvujovic@gmail.com77222c92012-06-04 21:06:05 +0000392 RestrictVertexShaderTiming restrictor(infoSink.info);
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000393 restrictor.enforceRestrictions(root);
394 return restrictor.numErrors() == 0;
395}
396
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400397void TCompiler::collectVariables(TIntermNode* root)
alokp@chromium.org07620a52010-09-23 17:53:56 +0000398{
Zhenyao Mo74da9f22013-09-23 14:57:01 -0400399 CollectVariables collect(attribs, uniforms, varyings, hashFunction);
alokp@chromium.org07620a52010-09-23 17:53:56 +0000400 root->traverse(&collect);
401}
zmo@google.comfd747b82011-04-23 01:30:07 +0000402
gman@chromium.org8d804792012-10-17 21:33:48 +0000403bool TCompiler::enforcePackingRestrictions()
404{
405 VariablePacker packer;
406 return packer.CheckVariablesWithinPackingLimits(maxUniformVectors, uniforms);
407}
408
zmo@google.comfd747b82011-04-23 01:30:07 +0000409void TCompiler::mapLongVariableNames(TIntermNode* root)
410{
zmo@google.comb9f64aa2012-01-20 00:35:15 +0000411 ASSERT(longNameMap);
412 MapLongVariableNames map(longNameMap);
zmo@google.com9996b8e2012-01-19 01:43:55 +0000413 root->traverse(&map);
zmo@google.comfd747b82011-04-23 01:30:07 +0000414}
415
416int TCompiler::getMappedNameMaxLength() const
417{
kbr@chromium.org22152112011-10-26 01:18:28 +0000418 return MAX_SHORTENED_IDENTIFIER_SIZE + 1;
zmo@google.comfd747b82011-04-23 01:30:07 +0000419}
zmo@google.com5601ea02011-06-10 18:23:25 +0000420
421const TExtensionBehavior& TCompiler::getExtensionBehavior() const
422{
423 return extensionBehavior;
424}
zmo@google.com32e97312011-08-24 01:03:11 +0000425
shannon.woods%transgaming.com@gtempaccount.com18b4c4b2013-04-13 03:31:40 +0000426const ShBuiltInResources& TCompiler::getResources() const
427{
428 return compileResources;
429}
430
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000431const ArrayBoundsClamper& TCompiler::getArrayBoundsClamper() const
432{
433 return arrayBoundsClamper;
434}
435
shannon.woods@transgaming.com1d432bb2013-01-25 21:57:28 +0000436ShArrayIndexClampingStrategy TCompiler::getArrayIndexClampingStrategy() const
437{
438 return clampingStrategy;
439}
440
441const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
442{
443 return builtInFunctionEmulator;
444}