summaryrefslogtreecommitdiff
path: root/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp')
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp452
1 files changed, 0 insertions, 452 deletions
diff --git a/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp b/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp
deleted file mode 100644
index c2b4ef602..000000000
--- a/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp
+++ /dev/null
@@ -1,452 +0,0 @@
-//
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#include "compiler/BuiltInFunctionEmulator.h"
-#include "compiler/DetectCallDepth.h"
-#include "compiler/ForLoopUnroll.h"
-#include "compiler/Initialize.h"
-#include "compiler/InitializeGLPosition.h"
-#include "compiler/InitializeParseContext.h"
-#include "compiler/MapLongVariableNames.h"
-#include "compiler/ParseContext.h"
-#include "compiler/RenameFunction.h"
-#include "compiler/ShHandle.h"
-#include "compiler/UnfoldShortCircuitAST.h"
-#include "compiler/ValidateLimitations.h"
-#include "compiler/VariablePacker.h"
-#include "compiler/depgraph/DependencyGraph.h"
-#include "compiler/depgraph/DependencyGraphOutput.h"
-#include "compiler/timing/RestrictFragmentShaderTiming.h"
-#include "compiler/timing/RestrictVertexShaderTiming.h"
-#include "third_party/compiler/ArrayBoundsClamper.h"
-
-bool isWebGLBasedSpec(ShShaderSpec spec)
-{
- return spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC;
-}
-
-namespace {
-class TScopedPoolAllocator {
-public:
- TScopedPoolAllocator(TPoolAllocator* allocator) : mAllocator(allocator) {
- mAllocator->push();
- SetGlobalPoolAllocator(mAllocator);
- }
- ~TScopedPoolAllocator() {
- SetGlobalPoolAllocator(NULL);
- mAllocator->pop();
- }
-
-private:
- TPoolAllocator* mAllocator;
-};
-
-class TScopedSymbolTableLevel {
-public:
- TScopedSymbolTableLevel(TSymbolTable* table) : mTable(table) {
- ASSERT(mTable->atBuiltInLevel());
- mTable->push();
- }
- ~TScopedSymbolTableLevel() {
- while (!mTable->atBuiltInLevel())
- mTable->pop();
- }
-
-private:
- TSymbolTable* mTable;
-};
-} // namespace
-
-TShHandleBase::TShHandleBase() {
- allocator.push();
- SetGlobalPoolAllocator(&allocator);
-}
-
-TShHandleBase::~TShHandleBase() {
- SetGlobalPoolAllocator(NULL);
- allocator.popAll();
-}
-
-TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
- : shaderType(type),
- shaderSpec(spec),
- maxUniformVectors(0),
- maxVaryingVectors(0),
- maxExpressionComplexity(0),
- maxCallStackDepth(0),
- fragmentPrecisionHigh(false),
- clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC),
- builtInFunctionEmulator(type)
-{
- longNameMap = LongNameMap::GetInstance();
-}
-
-TCompiler::~TCompiler()
-{
- ASSERT(longNameMap);
- longNameMap->Release();
-}
-
-bool TCompiler::Init(const ShBuiltInResources& resources)
-{
- maxUniformVectors = (shaderType == SH_VERTEX_SHADER) ?
- resources.MaxVertexUniformVectors :
- resources.MaxFragmentUniformVectors;
- maxVaryingVectors = resources.MaxVaryingVectors;
- maxExpressionComplexity = resources.MaxExpressionComplexity;
- maxCallStackDepth = resources.MaxCallStackDepth;
-
- SetGlobalPoolAllocator(&allocator);
-
- // Generate built-in symbol table.
- if (!InitBuiltInSymbolTable(resources))
- return false;
- InitExtensionBehavior(resources, extensionBehavior);
- fragmentPrecisionHigh = resources.FragmentPrecisionHigh == 1;
-
- arrayBoundsClamper.SetClampingStrategy(resources.ArrayIndexClampingStrategy);
- clampingStrategy = resources.ArrayIndexClampingStrategy;
-
- hashFunction = resources.HashFunction;
-
- return true;
-}
-
-bool TCompiler::compile(const char* const shaderStrings[],
- size_t numStrings,
- int compileOptions)
-{
- TScopedPoolAllocator scopedAlloc(&allocator);
- clearResults();
-
- if (numStrings == 0)
- return true;
-
- // If compiling for WebGL, validate loop and indexing as well.
- if (isWebGLBasedSpec(shaderSpec))
- compileOptions |= SH_VALIDATE_LOOP_INDEXING;
-
- // First string is path of source file if flag is set. The actual source follows.
- const char* sourcePath = NULL;
- size_t firstSource = 0;
- if (compileOptions & SH_SOURCE_PATH)
- {
- sourcePath = shaderStrings[0];
- ++firstSource;
- }
-
- TIntermediate intermediate(infoSink);
- TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
- shaderType, shaderSpec, compileOptions, true,
- sourcePath, infoSink);
- parseContext.fragmentPrecisionHigh = fragmentPrecisionHigh;
- SetGlobalParseContext(&parseContext);
-
- // We preserve symbols at the built-in level from compile-to-compile.
- // Start pushing the user-defined symbols at global level.
- TScopedSymbolTableLevel scopedSymbolLevel(&symbolTable);
-
- // Parse shader.
- bool success =
- (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) &&
- (parseContext.treeRoot != NULL);
- if (success) {
- TIntermNode* root = parseContext.treeRoot;
- success = intermediate.postProcess(root);
-
- if (success)
- success = detectCallDepth(root, infoSink, (compileOptions & SH_LIMIT_CALL_STACK_DEPTH) != 0);
-
- if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
- success = validateLimitations(root);
-
- if (success && (compileOptions & SH_TIMING_RESTRICTIONS))
- success = enforceTimingRestrictions(root, (compileOptions & SH_DEPENDENCY_GRAPH) != 0);
-
- if (success && shaderSpec == SH_CSS_SHADERS_SPEC)
- rewriteCSSShader(root);
-
- // Unroll for-loop markup needs to happen after validateLimitations pass.
- if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX))
- ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(root);
-
- // Built-in function emulation needs to happen after validateLimitations pass.
- if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS))
- builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root);
-
- // Clamping uniform array bounds needs to happen after validateLimitations pass.
- if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS))
- arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root);
-
- // Disallow expressions deemed too complex.
- if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY))
- success = limitExpressionComplexity(root);
-
- // Call mapLongVariableNames() before collectAttribsUniforms() so in
- // collectAttribsUniforms() we already have the mapped symbol names and
- // we could composite mapped and original variable names.
- // Also, if we hash all the names, then no need to do this for long names.
- if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES) && hashFunction == NULL)
- mapLongVariableNames(root);
-
- if (success && shaderType == SH_VERTEX_SHADER && (compileOptions & SH_INIT_GL_POSITION)) {
- InitializeGLPosition initGLPosition;
- root->traverse(&initGLPosition);
- }
-
- if (success && (compileOptions & SH_UNFOLD_SHORT_CIRCUIT)) {
- UnfoldShortCircuitAST unfoldShortCircuit;
- root->traverse(&unfoldShortCircuit);
- unfoldShortCircuit.updateTree();
- }
-
- if (success && (compileOptions & SH_VARIABLES)) {
- collectVariables(root);
- if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS)
- success = enforcePackingRestrictions();
- }
-
- if (success && (compileOptions & SH_INTERMEDIATE_TREE))
- intermediate.outputTree(root);
-
- if (success && (compileOptions & SH_OBJECT_CODE))
- translate(root);
- }
-
- // Cleanup memory.
- intermediate.remove(parseContext.treeRoot);
-
- return success;
-}
-
-bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources)
-{
- compileResources = resources;
-
- assert(symbolTable.isEmpty());
- symbolTable.push();
-
- TPublicType integer;
- integer.type = EbtInt;
- integer.size = 1;
- integer.matrix = false;
- integer.array = false;
-
- TPublicType floatingPoint;
- floatingPoint.type = EbtFloat;
- floatingPoint.size = 1;
- floatingPoint.matrix = false;
- floatingPoint.array = false;
-
- TPublicType sampler;
- sampler.size = 1;
- sampler.matrix = false;
- sampler.array = false;
-
- switch(shaderType)
- {
- case SH_FRAGMENT_SHADER:
- symbolTable.setDefaultPrecision(integer, EbpMedium);
- break;
- case SH_VERTEX_SHADER:
- symbolTable.setDefaultPrecision(integer, EbpHigh);
- symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
- break;
- default: assert(false && "Language not supported");
- }
- // We set defaults for all the sampler types, even those that are
- // only available if an extension exists.
- for (int samplerType = EbtGuardSamplerBegin + 1;
- samplerType < EbtGuardSamplerEnd; ++samplerType) {
- sampler.type = static_cast<TBasicType>(samplerType);
- symbolTable.setDefaultPrecision(sampler, EbpLow);
- }
-
- InsertBuiltInFunctions(shaderType, shaderSpec, resources, symbolTable);
-
- IdentifyBuiltIns(shaderType, shaderSpec, resources, symbolTable);
-
- return true;
-}
-
-void TCompiler::clearResults()
-{
- arrayBoundsClamper.Cleanup();
- infoSink.info.erase();
- infoSink.obj.erase();
- infoSink.debug.erase();
-
- attribs.clear();
- uniforms.clear();
- varyings.clear();
-
- builtInFunctionEmulator.Cleanup();
-
- nameMap.clear();
-}
-
-bool TCompiler::detectCallDepth(TIntermNode* root, TInfoSink& infoSink, bool limitCallStackDepth)
-{
- DetectCallDepth detect(infoSink, limitCallStackDepth, maxCallStackDepth);
- root->traverse(&detect);
- switch (detect.detectCallDepth()) {
- case DetectCallDepth::kErrorNone:
- return true;
- case DetectCallDepth::kErrorMissingMain:
- infoSink.info.prefix(EPrefixError);
- infoSink.info << "Missing main()";
- return false;
- case DetectCallDepth::kErrorRecursion:
- infoSink.info.prefix(EPrefixError);
- infoSink.info << "Function recursion detected";
- return false;
- case DetectCallDepth::kErrorMaxDepthExceeded:
- infoSink.info.prefix(EPrefixError);
- infoSink.info << "Function call stack too deep";
- return false;
- default:
- UNREACHABLE();
- return false;
- }
-}
-
-void TCompiler::rewriteCSSShader(TIntermNode* root)
-{
- RenameFunction renamer("main(", "css_main(");
- root->traverse(&renamer);
-}
-
-bool TCompiler::validateLimitations(TIntermNode* root) {
- ValidateLimitations validate(shaderType, infoSink.info);
- root->traverse(&validate);
- return validate.numErrors() == 0;
-}
-
-bool TCompiler::enforceTimingRestrictions(TIntermNode* root, bool outputGraph)
-{
- if (shaderSpec != SH_WEBGL_SPEC) {
- infoSink.info << "Timing restrictions must be enforced under the WebGL spec.";
- return false;
- }
-
- if (shaderType == SH_FRAGMENT_SHADER) {
- TDependencyGraph graph(root);
-
- // Output any errors first.
- bool success = enforceFragmentShaderTimingRestrictions(graph);
-
- // Then, output the dependency graph.
- if (outputGraph) {
- TDependencyGraphOutput output(infoSink.info);
- output.outputAllSpanningTrees(graph);
- }
-
- return success;
- }
- else {
- return enforceVertexShaderTimingRestrictions(root);
- }
-}
-
-bool TCompiler::limitExpressionComplexity(TIntermNode* root)
-{
- TIntermTraverser traverser;
- root->traverse(&traverser);
- TDependencyGraph graph(root);
-
- for (TFunctionCallVector::const_iterator iter = graph.beginUserDefinedFunctionCalls();
- iter != graph.endUserDefinedFunctionCalls();
- ++iter)
- {
- TGraphFunctionCall* samplerSymbol = *iter;
- TDependencyGraphTraverser graphTraverser;
- samplerSymbol->traverse(&graphTraverser);
- }
-
- if (traverser.getMaxDepth() > maxExpressionComplexity) {
- infoSink.info << "Expression too complex.";
- return false;
- }
- return true;
-}
-
-bool TCompiler::enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph)
-{
- RestrictFragmentShaderTiming restrictor(infoSink.info);
- restrictor.enforceRestrictions(graph);
- return restrictor.numErrors() == 0;
-}
-
-bool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root)
-{
- RestrictVertexShaderTiming restrictor(infoSink.info);
- restrictor.enforceRestrictions(root);
- return restrictor.numErrors() == 0;
-}
-
-void TCompiler::collectVariables(TIntermNode* root)
-{
- CollectVariables collect(attribs, uniforms, varyings, hashFunction);
- root->traverse(&collect);
-}
-
-bool TCompiler::enforcePackingRestrictions()
-{
- VariablePacker packer;
- bool success = packer.CheckVariablesWithinPackingLimits(maxUniformVectors, uniforms);
- if (!success) {
- infoSink.info.prefix(EPrefixError);
- infoSink.info << "too many uniforms";
- return false;
- }
-
- success = packer.CheckVariablesWithinPackingLimits(maxVaryingVectors, varyings);
-
- if (!success) {
- infoSink.info.prefix(EPrefixError);
- infoSink.info << "too many varyings";
- return false;
- }
-
- return true;
-}
-
-void TCompiler::mapLongVariableNames(TIntermNode* root)
-{
- ASSERT(longNameMap);
- MapLongVariableNames map(longNameMap);
- root->traverse(&map);
-}
-
-int TCompiler::getMappedNameMaxLength() const
-{
- return MAX_SHORTENED_IDENTIFIER_SIZE + 1;
-}
-
-const TExtensionBehavior& TCompiler::getExtensionBehavior() const
-{
- return extensionBehavior;
-}
-
-const ShBuiltInResources& TCompiler::getResources() const
-{
- return compileResources;
-}
-
-const ArrayBoundsClamper& TCompiler::getArrayBoundsClamper() const
-{
- return arrayBoundsClamper;
-}
-
-ShArrayIndexClampingStrategy TCompiler::getArrayIndexClampingStrategy() const
-{
- return clampingStrategy;
-}
-
-const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
-{
- return builtInFunctionEmulator;
-}