107620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org//
288f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
307620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org// Use of this source code is governed by a BSD-style license that can be
407620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org// found in the LICENSE file.
507620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org//
607620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
717732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/BuiltInFunctionEmulator.h"
817732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/DetectCallDepth.h"
917732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/ForLoopUnroll.h"
1017732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/Initialize.h"
1117732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/InitializeParseContext.h"
124a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo#include "compiler/translator/InitializeVariables.h"
136b9cb25980022d0c792d858bc6f6500c00a6c29dJamie Madill#include "compiler/translator/ParseContext.h"
1417732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/RenameFunction.h"
1517732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/ShHandle.h"
167cab38b594213c7c80f70871b72d40d30e878035Zhenyao Mo#include "compiler/translator/UnfoldShortCircuitAST.h"
1717732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/ValidateLimitations.h"
1817732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/ValidateOutputs.h"
1917732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/VariablePacker.h"
2017732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/depgraph/DependencyGraph.h"
2117732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/depgraph/DependencyGraphOutput.h"
2217732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/timing/RestrictFragmentShaderTiming.h"
2317732823f9c21bdba9cc51ffaceb545ce3857a8cGeoff Lang#include "compiler/translator/timing/RestrictVertexShaderTiming.h"
24da1ed36a3ba807337ec1d5a2009238c00ce4caabshannon.woods@transgaming.com#include "third_party/compiler/ArrayBoundsClamper.h"
2507620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
265508f39d0cffc9a68565bbff2e6f61332a509cdfJamie Madillbool IsWebGLBasedSpec(ShShaderSpec spec)
27430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com{
28430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com     return spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC;
29430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com}
30430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com
317faf1a14deb3cdfc9f9137de95f9fc1552b603bdZhenyao Mosize_t GetGlobalMaxTokenSize(ShShaderSpec spec)
3288f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill{
3388f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill    // WebGL defines a max token legnth of 256, while ES2 leaves max token
3488f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill    // size undefined. ES3 defines a max size of 1024 characters.
357faf1a14deb3cdfc9f9137de95f9fc1552b603bdZhenyao Mo    if (IsWebGLBasedSpec(spec))
3688f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill    {
3788f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill        return 256;
3888f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill    }
3988f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill    else
4088f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill    {
4188f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill        return 1024;
4288f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill    }
4388f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill}
4488f6e946b97ee15fe199e3fa151174c0bfeaa895Jamie Madill
45bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.orgnamespace {
464a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Moclass TScopedPoolAllocator
474a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo{
484a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo  public:
494a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    TScopedPoolAllocator(TPoolAllocator* allocator) : mAllocator(allocator)
504a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
51bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi        mAllocator->push();
52bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org        SetGlobalPoolAllocator(mAllocator);
53bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org    }
544a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    ~TScopedPoolAllocator()
554a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
56bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org        SetGlobalPoolAllocator(NULL);
57bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi        mAllocator->pop();
58bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org    }
59bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org
604a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo  private:
61bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org    TPoolAllocator* mAllocator;
62bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi};
63bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi
644a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Moclass TScopedSymbolTableLevel
654a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo{
664a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo  public:
674a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    TScopedSymbolTableLevel(TSymbolTable* table) : mTable(table)
684a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
69bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi        ASSERT(mTable->atBuiltInLevel());
70bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi        mTable->push();
71bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi    }
724a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    ~TScopedSymbolTableLevel()
734a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
74bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi        while (!mTable->atBuiltInLevel())
75bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi            mTable->pop();
76bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi    }
77bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi
784a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo  private:
79bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi    TSymbolTable* mTable;
80bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org};
81bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org}  // namespace
82bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org
834a667fe96e55df4713532e3830dd215ac7696f53Zhenyao MoTShHandleBase::TShHandleBase()
844a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo{
85bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org    allocator.push();
86bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org    SetGlobalPoolAllocator(&allocator);
87bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org}
88bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org
894a667fe96e55df4713532e3830dd215ac7696f53Zhenyao MoTShHandleBase::~TShHandleBase()
904a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo{
91bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org    SetGlobalPoolAllocator(NULL);
92bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org    allocator.popAll();
93bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org}
94bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org
9568fe74aabbb4d8ae08aadcf22705f0d85a16e0b5Jamie MadillTCompiler::TCompiler(ShShaderType type, ShShaderSpec spec, ShShaderOutput output)
964888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.org    : shaderType(type),
97f420c42442136e63c8c475446e01da1f6bcf5d32zmo@google.com      shaderSpec(spec),
9868fe74aabbb4d8ae08aadcf22705f0d85a16e0b5Jamie Madill      outputType(output),
99eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill      maxUniformVectors(0),
100eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill      maxExpressionComplexity(0),
101eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill      maxCallStackDepth(0),
102cbb6b6a0416552b5e3fa8589194288532558ccb8shannon.woods%transgaming.com@gtempaccount.com      fragmentPrecisionHigh(false),
1031d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.com      clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC),
1049996b8e6b16c43f8002eea64266b595f05a3a2d1zmo@google.com      builtInFunctionEmulator(type)
1054888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.org{
1064888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.org}
1074888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.org
1084888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.orgTCompiler::~TCompiler()
1094888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.org{
1104888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.org}
1114888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.org
1124888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.orgbool TCompiler::Init(const ShBuiltInResources& resources)
11307620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org{
1140bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com    shaderVersion = 100;
1158d8047995445882c73091578b889226323f38053gman@chromium.org    maxUniformVectors = (shaderType == SH_VERTEX_SHADER) ?
1168d8047995445882c73091578b889226323f38053gman@chromium.org        resources.MaxVertexUniformVectors :
1178d8047995445882c73091578b889226323f38053gman@chromium.org        resources.MaxFragmentUniformVectors;
118eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill    maxExpressionComplexity = resources.MaxExpressionComplexity;
119eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill    maxCallStackDepth = resources.MaxCallStackDepth;
120bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi
121bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi    SetGlobalPoolAllocator(&allocator);
122bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org
12307620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    // Generate built-in symbol table.
12407620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    if (!InitBuiltInSymbolTable(resources))
12507620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org        return false;
12607620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    InitExtensionBehavior(resources, extensionBehavior);
127cbb6b6a0416552b5e3fa8589194288532558ccb8shannon.woods%transgaming.com@gtempaccount.com    fragmentPrecisionHigh = resources.FragmentPrecisionHigh == 1;
128bafcbaa3a31cc9175b757a60d6377bce01d3be9balokp@chromium.org
1291d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.com    arrayBoundsClamper.SetClampingStrategy(resources.ArrayIndexClampingStrategy);
1301d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.com    clampingStrategy = resources.ArrayIndexClampingStrategy;
1311d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.com
132c23f4611be61bccdbfe2a5c43f63c4d98537ef9fdaniel@transgaming.com    hashFunction = resources.HashFunction;
133c23f4611be61bccdbfe2a5c43f63c4d98537ef9fdaniel@transgaming.com
13407620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    return true;
13507620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org}
13607620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
13707620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.orgbool TCompiler::compile(const char* const shaderStrings[],
138d64b3dab06c30da1e5dd9ba12667ff86388540e2shannon.woods@transgaming.com                        size_t numStrings,
13907620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org                        int compileOptions)
14007620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org{
141bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi    TScopedPoolAllocator scopedAlloc(&allocator);
14207620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    clearResults();
14307620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
14407620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    if (numStrings == 0)
14507620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org        return true;
14607620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
147b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org    // If compiling for WebGL, validate loop and indexing as well.
1485508f39d0cffc9a68565bbff2e6f61332a509cdfJamie Madill    if (IsWebGLBasedSpec(shaderSpec))
149b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org        compileOptions |= SH_VALIDATE_LOOP_INDEXING;
1501f29954dc7d433d6a69c4ec7bd07b7153f8d4b99alokp@chromium.org
1510f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org    // First string is path of source file if flag is set. The actual source follows.
1520f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org    const char* sourcePath = NULL;
153d64b3dab06c30da1e5dd9ba12667ff86388540e2shannon.woods@transgaming.com    size_t firstSource = 0;
1540f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org    if (compileOptions & SH_SOURCE_PATH)
1550f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org    {
1560f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org        sourcePath = shaderStrings[0];
1570f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org        ++firstSource;
1580f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org    }
1590f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org
16007620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    TIntermediate intermediate(infoSink);
16107620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
162dc4b4f85516fec32b746d1841c1df00865d96214zmo@google.com                               shaderType, shaderSpec, compileOptions, true,
1630f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org                               sourcePath, infoSink);
164cbb6b6a0416552b5e3fa8589194288532558ccb8shannon.woods%transgaming.com@gtempaccount.com    parseContext.fragmentPrecisionHigh = fragmentPrecisionHigh;
1658156b6be065905c22db8f5dc3ab0fb715b0e1b52Alok Priyadarshi    SetGlobalParseContext(&parseContext);
16607620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
16707620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    // We preserve symbols at the built-in level from compile-to-compile.
16807620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    // Start pushing the user-defined symbols at global level.
169bc3f1ac66061610b80500c9b3d91321ab332be44Alok Priyadarshi    TScopedSymbolTableLevel scopedSymbolLevel(&symbolTable);
17007620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
17107620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    // Parse shader.
17207620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    bool success =
1730f4cefe9462e53627f02f10b34d76f8665c72521apatrick@chromium.org        (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) &&
17407620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org        (parseContext.treeRoot != NULL);
1750bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com
1765524db0c05c8df6002489a077b18dd6fd5746448shannon.woods%transgaming.com@gtempaccount.com    shaderVersion = parseContext.getShaderVersion();
1770bbed38f417d490604909de5928d725fb39c5e3cshannon.woods%transgaming.com@gtempaccount.com
1784a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    if (success)
1794a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
180b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org        TIntermNode* root = parseContext.treeRoot;
181b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org        success = intermediate.postProcess(root);
182b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org
1836654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill        // Disallow expressions deemed too complex.
1846654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill        if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY))
1856654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill            success = limitExpressionComplexity(root);
1866654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill
187b1762df486cad22cb5b07100f6765065f9bdc546zmo@google.com        if (success)
188eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill            success = detectCallDepth(root, infoSink, (compileOptions & SH_LIMIT_CALL_STACK_DEPTH) != 0);
189b1762df486cad22cb5b07100f6765065f9bdc546zmo@google.com
19005a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madill        if (success && shaderVersion == 300 && shaderType == SH_FRAGMENT_SHADER)
19105a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madill            success = validateOutputs(root);
19205a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madill
193b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org        if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
194b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org            success = validateLimitations(root);
19507620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
19666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        if (success && (compileOptions & SH_TIMING_RESTRICTIONS))
19777222c9715408518c21a7f359b8f0f9af8c4bfddmaxvujovic@gmail.com            success = enforceTimingRestrictions(root, (compileOptions & SH_DEPENDENCY_GRAPH) != 0);
19866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
199430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com        if (success && shaderSpec == SH_CSS_SHADERS_SPEC)
200430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com            rewriteCSSShader(root);
201430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com
2020c6bb7a653f52baa3dab4492a3599ddcacf076edzmo@google.com        // Unroll for-loop markup needs to happen after validateLimitations pass.
2030c6bb7a653f52baa3dab4492a3599ddcacf076edzmo@google.com        if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX))
2043cdfcce86b38ef31a0afd71855887193a7924468Zhenyao Mo        {
2053cdfcce86b38ef31a0afd71855887193a7924468Zhenyao Mo            ForLoopUnrollMarker marker(ForLoopUnrollMarker::kIntegerIndex);
206550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo            root->traverse(&marker);
207550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo        }
208550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo        if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX))
2093cdfcce86b38ef31a0afd71855887193a7924468Zhenyao Mo        {
2103cdfcce86b38ef31a0afd71855887193a7924468Zhenyao Mo            ForLoopUnrollMarker marker(ForLoopUnrollMarker::kSamplerArrayIndex);
211550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo            root->traverse(&marker);
212550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo            if (marker.samplerArrayIndexIsFloatLoopIndex())
213550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo            {
214550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo                infoSink.info.prefix(EPrefixError);
215550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo                infoSink.info << "sampler array index is float loop index";
216550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo                success = false;
217550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo            }
218550c600b99d7ee2463e5878d0a9f66ea24c1414aZhenyao Mo        }
2190c6bb7a653f52baa3dab4492a3599ddcacf076edzmo@google.com
22032e97315e2a55557ad7c372239e0823a81243221zmo@google.com        // Built-in function emulation needs to happen after validateLimitations pass.
22132e97315e2a55557ad7c372239e0823a81243221zmo@google.com        if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS))
22232e97315e2a55557ad7c372239e0823a81243221zmo@google.com            builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root);
22332e97315e2a55557ad7c372239e0823a81243221zmo@google.com
2244167cc910276be723901f187dec45d04275abb7edaniel@transgaming.com        // Clamping uniform array bounds needs to happen after validateLimitations pass.
2254167cc910276be723901f187dec45d04275abb7edaniel@transgaming.com        if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS))
2264167cc910276be723901f187dec45d04275abb7edaniel@transgaming.com            arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root);
2274167cc910276be723901f187dec45d04275abb7edaniel@transgaming.com
2284a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        if (success && shaderType == SH_VERTEX_SHADER && (compileOptions & SH_INIT_GL_POSITION))
2294a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            initializeGLPosition(root);
230ac44cd2b072916b83f079bbfda66636491279d2eZhenyao Mo
2314a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT))
2324a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        {
2337cab38b594213c7c80f70871b72d40d30e878035Zhenyao Mo            UnfoldShortCircuitAST unfoldShortCircuit;
2347cab38b594213c7c80f70871b72d40d30e878035Zhenyao Mo            root->traverse(&unfoldShortCircuit);
2357cab38b594213c7c80f70871b72d40d30e878035Zhenyao Mo            unfoldShortCircuit.updateTree();
2367cab38b594213c7c80f70871b72d40d30e878035Zhenyao Mo        }
2377cab38b594213c7c80f70871b72d40d30e878035Zhenyao Mo
2384a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        if (success && (compileOptions & SH_VARIABLES))
2394a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        {
24074da9f2f24093e828b30071cebc09f99088fc13cZhenyao Mo            collectVariables(root);
2414a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS)
2424a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            {
2438d8047995445882c73091578b889226323f38053gman@chromium.org                success = enforcePackingRestrictions();
2444a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo                if (!success)
2454a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo                {
246075edd84dd682b91279132317d34b09e8028ae6fJamie Madill                    infoSink.info.prefix(EPrefixError);
247075edd84dd682b91279132317d34b09e8028ae6fJamie Madill                    infoSink.info << "too many uniforms";
2488d8047995445882c73091578b889226323f38053gman@chromium.org                }
2498d8047995445882c73091578b889226323f38053gman@chromium.org            }
2504a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            if (success && shaderType == SH_VERTEX_SHADER &&
2514a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo                (compileOptions & SH_INIT_VARYINGS_WITHOUT_STATIC_USE))
2524a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo                initializeVaryingsWithoutStaticUse(root);
2538d8047995445882c73091578b889226323f38053gman@chromium.org        }
254fd747b861195a03df634a722a9cf3505dcd41253zmo@google.com
2554888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.org        if (success && (compileOptions & SH_INTERMEDIATE_TREE))
256b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org            intermediate.outputTree(root);
25707620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
2584888ceb6681c3668d3afcbdafdbe2b7efdaa3d04alokp@chromium.org        if (success && (compileOptions & SH_OBJECT_CODE))
259b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org            translate(root);
26007620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    }
26107620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
26207620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    // Cleanup memory.
26307620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    intermediate.remove(parseContext.treeRoot);
2647faf1a14deb3cdfc9f9137de95f9fc1552b603bdZhenyao Mo    SetGlobalParseContext(NULL);
26507620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    return success;
26607620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org}
26707620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
26849a8887b73345356e147702be9eeb5b40236953cNicolas Capensbool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources)
26907620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org{
27018b4c4b56a1a31e1b1c9fccf01f1ffd46504ead9shannon.woods%transgaming.com@gtempaccount.com    compileResources = resources;
2712d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods    setResourceString();
2722ac0be9df9be957eb8fe504a88fa2e10c8ae9dc9shannonwoods@chromium.org
27349a8887b73345356e147702be9eeb5b40236953cNicolas Capens    assert(symbolTable.isEmpty());
27449a8887b73345356e147702be9eeb5b40236953cNicolas Capens    symbolTable.push();   // COMMON_BUILTINS
27549a8887b73345356e147702be9eeb5b40236953cNicolas Capens    symbolTable.push();   // ESSL1_BUILTINS
27649a8887b73345356e147702be9eeb5b40236953cNicolas Capens    symbolTable.push();   // ESSL3_BUILTINS
27749a8887b73345356e147702be9eeb5b40236953cNicolas Capens
27849a8887b73345356e147702be9eeb5b40236953cNicolas Capens    TPublicType integer;
27949a8887b73345356e147702be9eeb5b40236953cNicolas Capens    integer.type = EbtInt;
28049a8887b73345356e147702be9eeb5b40236953cNicolas Capens    integer.primarySize = 1;
28149a8887b73345356e147702be9eeb5b40236953cNicolas Capens    integer.secondarySize = 1;
28249a8887b73345356e147702be9eeb5b40236953cNicolas Capens    integer.array = false;
28349a8887b73345356e147702be9eeb5b40236953cNicolas Capens
28449a8887b73345356e147702be9eeb5b40236953cNicolas Capens    TPublicType floatingPoint;
28549a8887b73345356e147702be9eeb5b40236953cNicolas Capens    floatingPoint.type = EbtFloat;
28649a8887b73345356e147702be9eeb5b40236953cNicolas Capens    floatingPoint.primarySize = 1;
28749a8887b73345356e147702be9eeb5b40236953cNicolas Capens    floatingPoint.secondarySize = 1;
28849a8887b73345356e147702be9eeb5b40236953cNicolas Capens    floatingPoint.array = false;
28949a8887b73345356e147702be9eeb5b40236953cNicolas Capens
290a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo    TPublicType sampler;
291a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo    sampler.primarySize = 1;
292a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo    sampler.secondarySize = 1;
293a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo    sampler.array = false;
294a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo
29549a8887b73345356e147702be9eeb5b40236953cNicolas Capens    switch(shaderType)
29649a8887b73345356e147702be9eeb5b40236953cNicolas Capens    {
29749a8887b73345356e147702be9eeb5b40236953cNicolas Capens      case SH_FRAGMENT_SHADER:
29849a8887b73345356e147702be9eeb5b40236953cNicolas Capens        symbolTable.setDefaultPrecision(integer, EbpMedium);
29949a8887b73345356e147702be9eeb5b40236953cNicolas Capens        break;
30049a8887b73345356e147702be9eeb5b40236953cNicolas Capens      case SH_VERTEX_SHADER:
30149a8887b73345356e147702be9eeb5b40236953cNicolas Capens        symbolTable.setDefaultPrecision(integer, EbpHigh);
30249a8887b73345356e147702be9eeb5b40236953cNicolas Capens        symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
30349a8887b73345356e147702be9eeb5b40236953cNicolas Capens        break;
3044a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo      default:
3054a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        assert(false && "Language not supported");
30649a8887b73345356e147702be9eeb5b40236953cNicolas Capens    }
307a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo    // We set defaults for all the sampler types, even those that are
308a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo    // only available if an extension exists.
309a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo    for (int samplerType = EbtGuardSamplerBegin + 1;
3104a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo         samplerType < EbtGuardSamplerEnd; ++samplerType)
3114a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
312a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo        sampler.type = static_cast<TBasicType>(samplerType);
313a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo        symbolTable.setDefaultPrecision(sampler, EbpLow);
314a5a1dfc6ec47c5e5aef6d871a48eef25a44dc407Zhenyao Mo    }
31549a8887b73345356e147702be9eeb5b40236953cNicolas Capens
3161b45214aef6439fdeb6291e9d9fd1da61dec618cJamie Madill    InsertBuiltInFunctions(shaderType, shaderSpec, resources, symbolTable);
3172ac0be9df9be957eb8fe504a88fa2e10c8ae9dc9shannonwoods@chromium.org
31849a8887b73345356e147702be9eeb5b40236953cNicolas Capens    IdentifyBuiltIns(shaderType, shaderSpec, resources, symbolTable);
31949a8887b73345356e147702be9eeb5b40236953cNicolas Capens
32049a8887b73345356e147702be9eeb5b40236953cNicolas Capens    return true;
32107620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org}
32207620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
3232d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woodsvoid TCompiler::setResourceString()
3242d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods{
3252d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods    std::ostringstream strstream;
3262d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods    strstream << ":MaxVertexAttribs:" << compileResources.MaxVertexAttribs
3272d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxVertexUniformVectors:" << compileResources.MaxVertexUniformVectors
3282d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxVaryingVectors:" << compileResources.MaxVaryingVectors
3292d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxVertexTextureImageUnits:" << compileResources.MaxVertexTextureImageUnits
3302d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxCombinedTextureImageUnits:" << compileResources.MaxCombinedTextureImageUnits
3312d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxTextureImageUnits:" << compileResources.MaxTextureImageUnits
3322d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxFragmentUniformVectors:" << compileResources.MaxFragmentUniformVectors
3332d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxDrawBuffers:" << compileResources.MaxDrawBuffers
3342d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":OES_standard_derivatives:" << compileResources.OES_standard_derivatives
3352d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":OES_EGL_image_external:" << compileResources.OES_EGL_image_external
3362d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":ARB_texture_rectangle:" << compileResources.ARB_texture_rectangle
3372d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":EXT_draw_buffers:" << compileResources.EXT_draw_buffers
3382d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":FragmentPrecisionHigh:" << compileResources.FragmentPrecisionHigh
3392d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxExpressionComplexity:" << compileResources.MaxExpressionComplexity
3402d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxCallStackDepth:" << compileResources.MaxCallStackDepth
3412d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":EXT_frag_depth:" << compileResources.EXT_frag_depth
3422d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":EXT_shader_texture_lod:" << compileResources.EXT_shader_texture_lod
3432d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxVertexOutputVectors:" << compileResources.MaxVertexOutputVectors
3442d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxFragmentInputVectors:" << compileResources.MaxFragmentInputVectors
3452d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MinProgramTexelOffset:" << compileResources.MinProgramTexelOffset
3462d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods              << ":MaxProgramTexelOffset:" << compileResources.MaxProgramTexelOffset;
3472d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods
3482d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods    builtInResourcesString = strstream.str();
3492d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods}
3502d76e5f66595e1cef04f4ad678deda0d0e4643d7Shannon Woods
35107620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.orgvoid TCompiler::clearResults()
35207620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org{
3534167cc910276be723901f187dec45d04275abb7edaniel@transgaming.com    arrayBoundsClamper.Cleanup();
35407620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    infoSink.info.erase();
35507620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    infoSink.obj.erase();
35607620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    infoSink.debug.erase();
35707620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
35807620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    attribs.clear();
35907620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    uniforms.clear();
360d2d340b0da87296b1ec04799ef4c811966bfb7aeZhenyao Mo    varyings.clear();
361a3b4ab4c2beb1c020e474007ded4bed4a2383601zmo@google.com
362a3b4ab4c2beb1c020e474007ded4bed4a2383601zmo@google.com    builtInFunctionEmulator.Cleanup();
3630aa3b5a2b216c9033e7bb59f6dde3acf46cf2260daniel@transgaming.com
3640aa3b5a2b216c9033e7bb59f6dde3acf46cf2260daniel@transgaming.com    nameMap.clear();
36507620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org}
36607620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org
367eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madillbool TCompiler::detectCallDepth(TIntermNode* root, TInfoSink& infoSink, bool limitCallStackDepth)
368b1762df486cad22cb5b07100f6765065f9bdc546zmo@google.com{
369eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill    DetectCallDepth detect(infoSink, limitCallStackDepth, maxCallStackDepth);
370b1762df486cad22cb5b07100f6765065f9bdc546zmo@google.com    root->traverse(&detect);
3714a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    switch (detect.detectCallDepth())
3724a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
3734a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo      case DetectCallDepth::kErrorNone:
3744a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        return true;
3754a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo      case DetectCallDepth::kErrorMissingMain:
3764a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        infoSink.info.prefix(EPrefixError);
3774a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        infoSink.info << "Missing main()";
3784a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        return false;
3794a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo      case DetectCallDepth::kErrorRecursion:
3804a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        infoSink.info.prefix(EPrefixError);
3814a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        infoSink.info << "Function recursion detected";
3824a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        return false;
3834a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo      case DetectCallDepth::kErrorMaxDepthExceeded:
3844a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        infoSink.info.prefix(EPrefixError);
3854a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        infoSink.info << "Function call stack too deep";
3864a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        return false;
3874a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo      default:
3884a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        UNREACHABLE();
3894a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        return false;
390b1762df486cad22cb5b07100f6765065f9bdc546zmo@google.com    }
391b1762df486cad22cb5b07100f6765065f9bdc546zmo@google.com}
392b1762df486cad22cb5b07100f6765065f9bdc546zmo@google.com
39305a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madillbool TCompiler::validateOutputs(TIntermNode* root)
39405a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madill{
39505a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madill    ValidateOutputs validateOutputs(infoSink.info, compileResources.MaxDrawBuffers);
39605a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madill    root->traverse(&validateOutputs);
39705a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madill    return (validateOutputs.numErrors() == 0);
39805a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madill}
39905a80cebc3ce8ca07ae10e2970863e3cc603c756Jamie Madill
400430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.comvoid TCompiler::rewriteCSSShader(TIntermNode* root)
401430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com{
402430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com    RenameFunction renamer("main(", "css_main(");
403430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com    root->traverse(&renamer);
404430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com}
405430f5e0c75ade69935befb55d2592635f70255cemaxvujovic@gmail.com
4064a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mobool TCompiler::validateLimitations(TIntermNode* root)
4074a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo{
408b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org    ValidateLimitations validate(shaderType, infoSink.info);
409b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org    root->traverse(&validate);
410b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org    return validate.numErrors() == 0;
411b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org}
412b59a778cfe7e36dca41c2cc44198da511f447be8alokp@chromium.org
41377222c9715408518c21a7f359b8f0f9af8c4bfddmaxvujovic@gmail.combool TCompiler::enforceTimingRestrictions(TIntermNode* root, bool outputGraph)
41466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
4154a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    if (shaderSpec != SH_WEBGL_SPEC)
4164a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
41766ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        infoSink.info << "Timing restrictions must be enforced under the WebGL spec.";
41866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        return false;
41966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
42066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
4214a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    if (shaderType == SH_FRAGMENT_SHADER)
4224a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
42366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        TDependencyGraph graph(root);
42466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
42566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        // Output any errors first.
42677222c9715408518c21a7f359b8f0f9af8c4bfddmaxvujovic@gmail.com        bool success = enforceFragmentShaderTimingRestrictions(graph);
4275508f39d0cffc9a68565bbff2e6f61332a509cdfJamie Madill
42866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        // Then, output the dependency graph.
4294a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        if (outputGraph)
4304a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        {
43166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            TDependencyGraphOutput output(infoSink.info);
43266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com            output.outputAllSpanningTrees(graph);
43366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        }
4345508f39d0cffc9a68565bbff2e6f61332a509cdfJamie Madill
43566ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com        return success;
43666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
4374a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    else
4384a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
43977222c9715408518c21a7f359b8f0f9af8c4bfddmaxvujovic@gmail.com        return enforceVertexShaderTimingRestrictions(root);
44066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    }
44166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
44266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
443eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madillbool TCompiler::limitExpressionComplexity(TIntermNode* root)
444eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill{
4456654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill    TMaxDepthTraverser traverser(maxExpressionComplexity+1);
446eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill    root->traverse(&traverser);
4476654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill
4486654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill    if (traverser.getMaxDepth() > maxExpressionComplexity)
4496654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill    {
4506654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill        infoSink.info << "Expression too complex.";
4516654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill        return false;
4526654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill    }
4536654bc93f1ca30c2a5d7403f56c94d668c650ca0Jamie Madill
454eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill    TDependencyGraph graph(root);
455eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill
456eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill    for (TFunctionCallVector::const_iterator iter = graph.beginUserDefinedFunctionCalls();
457eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill         iter != graph.endUserDefinedFunctionCalls();
458eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill         ++iter)
459eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill    {
460eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill        TGraphFunctionCall* samplerSymbol = *iter;
461eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill        TDependencyGraphTraverser graphTraverser;
462eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill        samplerSymbol->traverse(&graphTraverser);
463eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill    }
464eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill
465eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill    return true;
466eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill}
467eb1a010f0f996b3742fd34b92ffaf9014c943528Jamie Madill
46877222c9715408518c21a7f359b8f0f9af8c4bfddmaxvujovic@gmail.combool TCompiler::enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph)
46966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
47077222c9715408518c21a7f359b8f0f9af8c4bfddmaxvujovic@gmail.com    RestrictFragmentShaderTiming restrictor(infoSink.info);
47166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    restrictor.enforceRestrictions(graph);
47266ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    return restrictor.numErrors() == 0;
47366ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
47466ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
47577222c9715408518c21a7f359b8f0f9af8c4bfddmaxvujovic@gmail.combool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root)
47666ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com{
47777222c9715408518c21a7f359b8f0f9af8c4bfddmaxvujovic@gmail.com    RestrictVertexShaderTiming restrictor(infoSink.info);
47866ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    restrictor.enforceRestrictions(root);
47966ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com    return restrictor.numErrors() == 0;
48066ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com}
48166ebd0143ea40a9beb83eab5d86e24f52825b3famaxvujovic@gmail.com
48274da9f2f24093e828b30071cebc09f99088fc13cZhenyao Movoid TCompiler::collectVariables(TIntermNode* root)
48307620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org{
48474da9f2f24093e828b30071cebc09f99088fc13cZhenyao Mo    CollectVariables collect(attribs, uniforms, varyings, hashFunction);
48507620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org    root->traverse(&collect);
48607620a585ae04ba6a86f0c04a27b3cabd10cc6b8alokp@chromium.org}
487fd747b861195a03df634a722a9cf3505dcd41253zmo@google.com
4888d8047995445882c73091578b889226323f38053gman@chromium.orgbool TCompiler::enforcePackingRestrictions()
4898d8047995445882c73091578b889226323f38053gman@chromium.org{
4908d8047995445882c73091578b889226323f38053gman@chromium.org    VariablePacker packer;
4918d8047995445882c73091578b889226323f38053gman@chromium.org    return packer.CheckVariablesWithinPackingLimits(maxUniformVectors, uniforms);
4928d8047995445882c73091578b889226323f38053gman@chromium.org}
4938d8047995445882c73091578b889226323f38053gman@chromium.org
4944a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Movoid TCompiler::initializeGLPosition(TIntermNode* root)
4954a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo{
4964a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    InitializeVariables::InitVariableInfoList variables;
4974a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    InitializeVariables::InitVariableInfo var(
4984a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        "gl_Position", TType(EbtFloat, EbpUndefined, EvqPosition, 4));
4994a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    variables.push_back(var);
5004a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    InitializeVariables initializer(variables);
5014a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    root->traverse(&initializer);
5024a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo}
5034a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo
5044a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Movoid TCompiler::initializeVaryingsWithoutStaticUse(TIntermNode* root)
5054a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo{
5064a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    InitializeVariables::InitVariableInfoList variables;
5074a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    for (size_t ii = 0; ii < varyings.size(); ++ii)
5084a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    {
5094a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        const TVariableInfo& varying = varyings[ii];
5104a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        if (varying.staticUse)
5114a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            continue;
51266e5dda735b70e6d9b81614beef6d64dd180e580Zhenyao Mo        unsigned char primarySize = 1, secondarySize = 1;
5134a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        switch (varying.type)
5144a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        {
5154a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo          case SH_FLOAT:
5164a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            break;
5174a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo          case SH_FLOAT_VEC2:
51866e5dda735b70e6d9b81614beef6d64dd180e580Zhenyao Mo            primarySize = 2;
5194a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            break;
5204a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo          case SH_FLOAT_VEC3:
52166e5dda735b70e6d9b81614beef6d64dd180e580Zhenyao Mo            primarySize = 3;
5224a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            break;
5234a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo          case SH_FLOAT_VEC4:
52466e5dda735b70e6d9b81614beef6d64dd180e580Zhenyao Mo            primarySize = 4;
5254a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            break;
5264a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo          case SH_FLOAT_MAT2:
52766e5dda735b70e6d9b81614beef6d64dd180e580Zhenyao Mo            primarySize = 2;
52866e5dda735b70e6d9b81614beef6d64dd180e580Zhenyao Mo            secondarySize = 2;
5294a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            break;
5304a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo          case SH_FLOAT_MAT3:
53166e5dda735b70e6d9b81614beef6d64dd180e580Zhenyao Mo            primarySize = 3;
53266e5dda735b70e6d9b81614beef6d64dd180e580Zhenyao Mo            secondarySize = 3;
5334a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            break;
5344a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo          case SH_FLOAT_MAT4:
53566e5dda735b70e6d9b81614beef6d64dd180e580Zhenyao Mo            primarySize = 4;
53666e5dda735b70e6d9b81614beef6d64dd180e580Zhenyao Mo            secondarySize = 4;
5374a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            break;
5384a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo          default:
5394a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            ASSERT(false);
5404a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        }
54166e5dda735b70e6d9b81614beef6d64dd180e580Zhenyao Mo        TType type(EbtFloat, EbpUndefined, EvqVaryingOut, primarySize, secondarySize, varying.isArray);
5424a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        TString name = varying.name.c_str();
5434a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        if (varying.isArray)
5444a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        {
5454a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            type.setArraySize(varying.size);
5464a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo            name = name.substr(0, name.find_first_of('['));
5474a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        }
5484a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo
5494a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        InitializeVariables::InitVariableInfo var(name, type);
5504a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo        variables.push_back(var);
5514a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    }
5524a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    InitializeVariables initializer(variables);
5534a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo    root->traverse(&initializer);
5544a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo}
5554a667fe96e55df4713532e3830dd215ac7696f53Zhenyao Mo
5565601ea0d66442518d4745bb02b7619485b9d305bzmo@google.comconst TExtensionBehavior& TCompiler::getExtensionBehavior() const
5575601ea0d66442518d4745bb02b7619485b9d305bzmo@google.com{
5585601ea0d66442518d4745bb02b7619485b9d305bzmo@google.com    return extensionBehavior;
5595601ea0d66442518d4745bb02b7619485b9d305bzmo@google.com}
56032e97315e2a55557ad7c372239e0823a81243221zmo@google.com
56118b4c4b56a1a31e1b1c9fccf01f1ffd46504ead9shannon.woods%transgaming.com@gtempaccount.comconst ShBuiltInResources& TCompiler::getResources() const
56218b4c4b56a1a31e1b1c9fccf01f1ffd46504ead9shannon.woods%transgaming.com@gtempaccount.com{
56318b4c4b56a1a31e1b1c9fccf01f1ffd46504ead9shannon.woods%transgaming.com@gtempaccount.com    return compileResources;
56418b4c4b56a1a31e1b1c9fccf01f1ffd46504ead9shannon.woods%transgaming.com@gtempaccount.com}
56518b4c4b56a1a31e1b1c9fccf01f1ffd46504ead9shannon.woods%transgaming.com@gtempaccount.com
5661d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.comconst ArrayBoundsClamper& TCompiler::getArrayBoundsClamper() const
56732e97315e2a55557ad7c372239e0823a81243221zmo@google.com{
5681d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.com    return arrayBoundsClamper;
56932e97315e2a55557ad7c372239e0823a81243221zmo@google.com}
5704167cc910276be723901f187dec45d04275abb7edaniel@transgaming.com
5711d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.comShArrayIndexClampingStrategy TCompiler::getArrayIndexClampingStrategy() const
5724167cc910276be723901f187dec45d04275abb7edaniel@transgaming.com{
5731d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.com    return clampingStrategy;
5744167cc910276be723901f187dec45d04275abb7edaniel@transgaming.com}
5754167cc910276be723901f187dec45d04275abb7edaniel@transgaming.com
5761d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.comconst BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
5771d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.com{
5781d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.com    return builtInFunctionEmulator;
5791d432bb570bd175c3cdc51629a386e324e98b95bshannon.woods@transgaming.com}
580