1//
2// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7#ifndef COMPILER_TRANSLATOR_COMPILER_H_
8#define COMPILER_TRANSLATOR_COMPILER_H_
9
10//
11// Machine independent part of the compiler private objects
12// sent as ShHandle to the driver.
13//
14// This should not be included by driver code.
15//
16
17#include "compiler/translator/BuiltInFunctionEmulator.h"
18#include "compiler/translator/CallDAG.h"
19#include "compiler/translator/ExtensionBehavior.h"
20#include "compiler/translator/HashNames.h"
21#include "compiler/translator/InfoSink.h"
22#include "compiler/translator/Pragma.h"
23#include "compiler/translator/SymbolTable.h"
24#include "compiler/translator/VariableInfo.h"
25#include "third_party/compiler/ArrayBoundsClamper.h"
26
27class TCompiler;
28class TDependencyGraph;
29#ifdef ANGLE_ENABLE_HLSL
30class TranslatorHLSL;
31#endif // ANGLE_ENABLE_HLSL
32
33//
34// Helper function to identify specs that are based on the WebGL spec,
35// like the CSS Shaders spec.
36//
37bool IsWebGLBasedSpec(ShShaderSpec spec);
38
39//
40// Helper function to check if the shader type is GLSL.
41//
42bool IsGLSL130OrNewer(ShShaderOutput output);
43
44//
45// The base class used to back handles returned to the driver.
46//
47class TShHandleBase {
48public:
49 TShHandleBase();
50 virtual ~TShHandleBase();
51 virtual TCompiler* getAsCompiler() { return 0; }
52#ifdef ANGLE_ENABLE_HLSL
53 virtual TranslatorHLSL* getAsTranslatorHLSL() { return 0; }
54#endif // ANGLE_ENABLE_HLSL
55
56protected:
57 // Memory allocator. Allocates and tracks memory required by the compiler.
58 // Deallocates all memory when compiler is destructed.
59 TPoolAllocator allocator;
60};
61
62//
63// The base class for the machine dependent compiler to derive from
64// for managing object code from the compile.
65//
66class TCompiler : public TShHandleBase
67{
68 public:
69 TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
70 virtual ~TCompiler();
71 virtual TCompiler* getAsCompiler() { return this; }
72
73 bool Init(const ShBuiltInResources& resources);
74
75 // compileTreeForTesting should be used only when tests require access to
76 // the AST. Users of this function need to manually manage the global pool
77 // allocator. Returns NULL whenever there are compilation errors.
78 TIntermNode *compileTreeForTesting(const char* const shaderStrings[],
79 size_t numStrings, int compileOptions);
80
81 bool compile(const char* const shaderStrings[],
82 size_t numStrings, int compileOptions);
83
84 // Get results of the last compilation.
85 int getShaderVersion() const { return shaderVersion; }
86 TInfoSink& getInfoSink() { return infoSink; }
87
88 const std::vector<sh::Attribute> &getAttributes() const { return attributes; }
89 const std::vector<sh::Attribute> &getOutputVariables() const { return outputVariables; }
90 const std::vector<sh::Uniform> &getUniforms() const { return uniforms; }
91 const std::vector<sh::Varying> &getVaryings() const { return varyings; }
92 const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return interfaceBlocks; }
93
94 ShHashFunction64 getHashFunction() const { return hashFunction; }
95 NameMap& getNameMap() { return nameMap; }
96 TSymbolTable& getSymbolTable() { return symbolTable; }
97 ShShaderSpec getShaderSpec() const { return shaderSpec; }
98 ShShaderOutput getOutputType() const { return outputType; }
99 const std::string &getBuiltInResourcesString() const { return builtInResourcesString; }
100
101 // Get the resources set by InitBuiltInSymbolTable
102 const ShBuiltInResources& getResources() const;
103
104 protected:
105 sh::GLenum getShaderType() const { return shaderType; }
106 // Initialize symbol-table with built-in symbols.
107 bool InitBuiltInSymbolTable(const ShBuiltInResources& resources);
108 // Compute the string representation of the built-in resources
109 void setResourceString();
110 // Clears the results from the previous compilation.
111 void clearResults();
112 // Return false if the call depth is exceeded.
113 bool checkCallDepth();
114 // Returns true if a program has no conflicting or missing fragment outputs
115 bool validateOutputs(TIntermNode* root);
116 // Rewrites a shader's intermediate tree according to the CSS Shaders spec.
117 void rewriteCSSShader(TIntermNode* root);
118 // Returns true if the given shader does not exceed the minimum
119 // functionality mandated in GLSL 1.0 spec Appendix A.
120 bool validateLimitations(TIntermNode* root);
121 // Collect info for all attribs, uniforms, varyings.
122 void collectVariables(TIntermNode* root);
123 // Add emulated functions to the built-in function emulator.
124 virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, int compileOptions) {};
125 // Translate to object code.
126 virtual void translate(TIntermNode *root, int compileOptions) = 0;
127 // Returns true if, after applying the packing rules in the GLSL 1.017 spec
128 // Appendix A, section 7, the shader does not use too many uniforms.
129 bool enforcePackingRestrictions();
130 // Insert statements to initialize varyings without static use in the beginning
131 // of main(). It is to work around a Mac driver where such varyings in a vertex
132 // shader may be optimized out incorrectly at compile time, causing a link failure.
133 // This function should only be applied to vertex shaders.
134 void initializeVaryingsWithoutStaticUse(TIntermNode* root);
135 // Insert gl_Position = vec4(0,0,0,0) to the beginning of main().
136 // It is to work around a Linux driver bug where missing this causes compile failure
137 // while spec says it is allowed.
138 // This function should only be applied to vertex shaders.
139 void initializeGLPosition(TIntermNode* root);
140 // Returns true if the shader passes the restrictions that aim to prevent timing attacks.
141 bool enforceTimingRestrictions(TIntermNode* root, bool outputGraph);
142 // Returns true if the shader does not use samplers.
143 bool enforceVertexShaderTimingRestrictions(TIntermNode* root);
144 // Returns true if the shader does not use sampler dependent values to affect control
145 // flow or in operations whose time can depend on the input values.
146 bool enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph);
147 // Return true if the maximum expression complexity is below the limit.
148 bool limitExpressionComplexity(TIntermNode* root);
149 // Get built-in extensions with default behavior.
150 const TExtensionBehavior& getExtensionBehavior() const;
151 const char *getSourcePath() const;
152 const TPragma& getPragma() const { return mPragma; }
153 void writePragma();
154
155 const ArrayBoundsClamper& getArrayBoundsClamper() const;
156 ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
157 const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const;
158
159 std::vector<sh::Attribute> attributes;
160 std::vector<sh::Attribute> outputVariables;
161 std::vector<sh::Uniform> uniforms;
162 std::vector<sh::ShaderVariable> expandedUniforms;
163 std::vector<sh::Varying> varyings;
164 std::vector<sh::InterfaceBlock> interfaceBlocks;
165
166 private:
167 // Creates the function call DAG for further analysis, returning false if there is a recursion
168 bool initCallDag(TIntermNode *root);
169 // Return false if "main" doesn't exist
170 bool tagUsedFunctions();
171 void internalTagUsedFunction(size_t index);
172
173 // Removes unused function declarations and prototypes from the AST
174 class UnusedPredicate;
175 bool pruneUnusedFunctions(TIntermNode *root);
176
177 TIntermNode *compileTreeImpl(const char* const shaderStrings[],
178 size_t numStrings, int compileOptions);
179
180 sh::GLenum shaderType;
181 ShShaderSpec shaderSpec;
182 ShShaderOutput outputType;
183
184 struct FunctionMetadata
185 {
186 FunctionMetadata()
187 : used(false)
188 {
189 }
190 bool used;
191 };
192
193 CallDAG mCallDag;
194 std::vector<FunctionMetadata> functionMetadata;
195
196 int maxUniformVectors;
197 int maxExpressionComplexity;
198 int maxCallStackDepth;
199
200 ShBuiltInResources compileResources;
201 std::string builtInResourcesString;
202
203 // Built-in symbol table for the given language, spec, and resources.
204 // It is preserved from compile-to-compile.
205 TSymbolTable symbolTable;
206 // Built-in extensions with default behavior.
207 TExtensionBehavior extensionBehavior;
208 bool fragmentPrecisionHigh;
209
210 ArrayBoundsClamper arrayBoundsClamper;
211 ShArrayIndexClampingStrategy clampingStrategy;
212 BuiltInFunctionEmulator builtInFunctionEmulator;
213
214 // Results of compilation.
215 int shaderVersion;
216 TInfoSink infoSink; // Output sink.
217 const char *mSourcePath; // Path of source file or NULL
218
219 // name hashing.
220 ShHashFunction64 hashFunction;
221 NameMap nameMap;
222
223 TPragma mPragma;
224};
225
226//
227// This is the interface between the machine independent code
228// and the machine dependent code.
229//
230// The machine dependent code should derive from the classes
231// above. Then Construct*() and Delete*() will create and
232// destroy the machine dependent objects, which contain the
233// above machine independent information.
234//
235TCompiler* ConstructCompiler(
236 sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
237void DeleteCompiler(TCompiler*);
238
239#endif // COMPILER_TRANSLATOR_COMPILER_H_
240