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 | |
27 | class TCompiler; |
28 | class TDependencyGraph; |
29 | #ifdef ANGLE_ENABLE_HLSL |
30 | class 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 | // |
37 | bool IsWebGLBasedSpec(ShShaderSpec spec); |
38 | |
39 | // |
40 | // Helper function to check if the shader type is GLSL. |
41 | // |
42 | bool IsGLSL130OrNewer(ShShaderOutput output); |
43 | |
44 | // |
45 | // The base class used to back handles returned to the driver. |
46 | // |
47 | class TShHandleBase { |
48 | public: |
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 | |
56 | protected: |
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 | // |
66 | class 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 | // |
235 | TCompiler* ConstructCompiler( |
236 | sh::GLenum type, ShShaderSpec spec, ShShaderOutput output); |
237 | void DeleteCompiler(TCompiler*); |
238 | |
239 | #endif // COMPILER_TRANSLATOR_COMPILER_H_ |
240 | |