• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2002 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 <GLSLANG/ShaderVars.h>
18 
19 #include "common/PackedEnums.h"
20 #include "compiler/translator/BuiltInFunctionEmulator.h"
21 #include "compiler/translator/CallDAG.h"
22 #include "compiler/translator/Diagnostics.h"
23 #include "compiler/translator/ExtensionBehavior.h"
24 #include "compiler/translator/HashNames.h"
25 #include "compiler/translator/InfoSink.h"
26 #include "compiler/translator/Pragma.h"
27 #include "compiler/translator/SymbolTable.h"
28 #include "compiler/translator/ValidateAST.h"
29 
30 namespace sh
31 {
32 
33 class TCompiler;
34 class TParseContext;
35 #ifdef ANGLE_ENABLE_HLSL
36 class TranslatorHLSL;
37 #endif  // ANGLE_ENABLE_HLSL
38 #ifdef ANGLE_ENABLE_METAL
39 class TranslatorMetalDirect;
40 #endif  // ANGLE_ENABLE_METAL
41 
42 using SpecConstUsageBits = angle::PackedEnumBitSet<vk::SpecConstUsage, uint32_t>;
43 
44 //
45 // Helper function to check if the shader type is GLSL.
46 //
47 bool IsGLSL130OrNewer(ShShaderOutput output);
48 bool IsGLSL420OrNewer(ShShaderOutput output);
49 bool IsGLSL410OrOlder(ShShaderOutput output);
50 
51 //
52 // Helper function to check if the invariant qualifier can be removed.
53 //
54 bool RemoveInvariant(sh::GLenum shaderType,
55                      int shaderVersion,
56                      ShShaderOutput outputType,
57                      ShCompileOptions compileOptions);
58 
59 //
60 // The base class used to back handles returned to the driver.
61 //
62 class TShHandleBase
63 {
64   public:
65     TShHandleBase();
66     virtual ~TShHandleBase();
getAsCompiler()67     virtual TCompiler *getAsCompiler() { return 0; }
68 #ifdef ANGLE_ENABLE_HLSL
getAsTranslatorHLSL()69     virtual TranslatorHLSL *getAsTranslatorHLSL() { return 0; }
70 #endif  // ANGLE_ENABLE_HLSL
71 #ifdef ANGLE_ENABLE_METAL
getAsTranslatorMetalDirect()72     virtual TranslatorMetalDirect *getAsTranslatorMetalDirect() { return nullptr; }
73 #endif  // ANGLE_ENABLE_METAL
74 
75   protected:
76     // Memory allocator. Allocates and tracks memory required by the compiler.
77     // Deallocates all memory when compiler is destructed.
78     angle::PoolAllocator allocator;
79 };
80 
81 struct TFunctionMetadata
82 {
83     bool used = false;
84 };
85 
86 //
87 // The base class for the machine dependent compiler to derive from
88 // for managing object code from the compile.
89 //
90 class TCompiler : public TShHandleBase
91 {
92   public:
93     TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
94     ~TCompiler() override;
getAsCompiler()95     TCompiler *getAsCompiler() override { return this; }
96 
97     bool Init(const ShBuiltInResources &resources);
98 
99     // compileTreeForTesting should be used only when tests require access to
100     // the AST. Users of this function need to manually manage the global pool
101     // allocator. Returns nullptr whenever there are compilation errors.
102     TIntermBlock *compileTreeForTesting(const char *const shaderStrings[],
103                                         size_t numStrings,
104                                         ShCompileOptions compileOptions);
105 
106     bool compile(const char *const shaderStrings[],
107                  size_t numStrings,
108                  ShCompileOptions compileOptions);
109 
110     // Get results of the last compilation.
getShaderVersion()111     int getShaderVersion() const { return mShaderVersion; }
getInfoSink()112     TInfoSink &getInfoSink() { return mInfoSink; }
113 
isEarlyFragmentTestsSpecified()114     bool isEarlyFragmentTestsSpecified() const { return mEarlyFragmentTestsSpecified; }
isEarlyFragmentTestsOptimized()115     bool isEarlyFragmentTestsOptimized() const { return mEarlyFragmentTestsOptimized; }
getSpecConstUsageBits()116     SpecConstUsageBits getSpecConstUsageBits() const { return mSpecConstUsageBits; }
117 
isComputeShaderLocalSizeDeclared()118     bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; }
getComputeShaderLocalSize()119     const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; }
getNumViews()120     int getNumViews() const { return mNumViews; }
121 
122     // Clears the results from the previous compilation.
123     void clearResults();
124 
getAttributes()125     const std::vector<sh::ShaderVariable> &getAttributes() const { return mAttributes; }
getOutputVariables()126     const std::vector<sh::ShaderVariable> &getOutputVariables() const { return mOutputVariables; }
getUniforms()127     const std::vector<sh::ShaderVariable> &getUniforms() const { return mUniforms; }
getInputVaryings()128     const std::vector<sh::ShaderVariable> &getInputVaryings() const { return mInputVaryings; }
getOutputVaryings()129     const std::vector<sh::ShaderVariable> &getOutputVaryings() const { return mOutputVaryings; }
getInterfaceBlocks()130     const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return mInterfaceBlocks; }
getUniformBlocks()131     const std::vector<sh::InterfaceBlock> &getUniformBlocks() const { return mUniformBlocks; }
getShaderStorageBlocks()132     const std::vector<sh::InterfaceBlock> &getShaderStorageBlocks() const
133     {
134         return mShaderStorageBlocks;
135     }
136 
getHashFunction()137     ShHashFunction64 getHashFunction() const { return mResources.HashFunction; }
getNameMap()138     NameMap &getNameMap() { return mNameMap; }
getSymbolTable()139     TSymbolTable &getSymbolTable() { return mSymbolTable; }
getShaderSpec()140     ShShaderSpec getShaderSpec() const { return mShaderSpec; }
getOutputType()141     ShShaderOutput getOutputType() const { return mOutputType; }
getBuiltInResourcesString()142     const std::string &getBuiltInResourcesString() const { return mBuiltInResourcesString; }
143 
144     bool isHighPrecisionSupported() const;
145 
146     bool shouldRunLoopAndIndexingValidation(ShCompileOptions compileOptions) const;
147     bool shouldLimitTypeSizes() const;
148 
149     // Get the resources set by InitBuiltInSymbolTable
150     const ShBuiltInResources &getResources() const;
151 
getPragma()152     const TPragma &getPragma() const { return mPragma; }
153 
getGeometryShaderMaxVertices()154     int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; }
getGeometryShaderInvocations()155     int getGeometryShaderInvocations() const { return mGeometryShaderInvocations; }
getGeometryShaderInputPrimitiveType()156     TLayoutPrimitiveType getGeometryShaderInputPrimitiveType() const
157     {
158         return mGeometryShaderInputPrimitiveType;
159     }
getGeometryShaderOutputPrimitiveType()160     TLayoutPrimitiveType getGeometryShaderOutputPrimitiveType() const
161     {
162         return mGeometryShaderOutputPrimitiveType;
163     }
164 
165     unsigned int getStructSize(const ShaderVariable &var) const;
166 
getTessControlShaderOutputVertices()167     int getTessControlShaderOutputVertices() const { return mTessControlShaderOutputVertices; }
getTessEvaluationShaderInputPrimitiveType()168     TLayoutTessEvaluationType getTessEvaluationShaderInputPrimitiveType() const
169     {
170         return mTessEvaluationShaderInputPrimitiveType;
171     }
getTessEvaluationShaderInputVertexSpacingType()172     TLayoutTessEvaluationType getTessEvaluationShaderInputVertexSpacingType() const
173     {
174         return mTessEvaluationShaderInputVertexSpacingType;
175     }
getTessEvaluationShaderInputOrderingType()176     TLayoutTessEvaluationType getTessEvaluationShaderInputOrderingType() const
177     {
178         return mTessEvaluationShaderInputOrderingType;
179     }
getTessEvaluationShaderInputPointType()180     TLayoutTessEvaluationType getTessEvaluationShaderInputPointType() const
181     {
182         return mTessEvaluationShaderInputPointType;
183     }
184 
hasAnyPreciseType()185     bool hasAnyPreciseType() const { return mHasAnyPreciseType; }
186 
187     unsigned int getSharedMemorySize() const;
188 
getShaderType()189     sh::GLenum getShaderType() const { return mShaderType; }
190 
191     // Validate the AST and produce errors if it is inconsistent.
192     bool validateAST(TIntermNode *root);
193     // Some transformations may need to temporarily disable validation until they are complete.  A
194     // set of disable/enable helpers are used for this purpose.
195     bool disableValidateFunctionCall();
196     void restoreValidateFunctionCall(bool enable);
197     bool disableValidateVariableReferences();
198     void restoreValidateVariableReferences(bool enable);
199     // When the AST is post-processed (such as to determine precise-ness of intermediate nodes),
200     // it's expected to no longer transform.
201     void enableValidateNoMoreTransformations();
202 
203   protected:
204     // Add emulated functions to the built-in function emulator.
initBuiltInFunctionEmulator(BuiltInFunctionEmulator * emu,ShCompileOptions compileOptions)205     virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
206                                              ShCompileOptions compileOptions)
207     {}
208     // Translate to object code. May generate performance warnings through the diagnostics.
209     ANGLE_NO_DISCARD virtual bool translate(TIntermBlock *root,
210                                             ShCompileOptions compileOptions,
211                                             PerformanceDiagnostics *perfDiagnostics) = 0;
212     // Get built-in extensions with default behavior.
213     const TExtensionBehavior &getExtensionBehavior() const;
214     const char *getSourcePath() const;
215     // Relies on collectVariables having been called.
216     bool isVaryingDefined(const char *varyingName);
217 
218     const BuiltInFunctionEmulator &getBuiltInFunctionEmulator() const;
219 
220     virtual bool shouldFlattenPragmaStdglInvariantAll() = 0;
221     virtual bool shouldCollectVariables(ShCompileOptions compileOptions);
222 
223     bool wereVariablesCollected() const;
224     std::vector<sh::ShaderVariable> mAttributes;
225     std::vector<sh::ShaderVariable> mOutputVariables;
226     std::vector<sh::ShaderVariable> mUniforms;
227     std::vector<sh::ShaderVariable> mInputVaryings;
228     std::vector<sh::ShaderVariable> mOutputVaryings;
229     std::vector<sh::ShaderVariable> mSharedVariables;
230     std::vector<sh::InterfaceBlock> mInterfaceBlocks;
231     std::vector<sh::InterfaceBlock> mUniformBlocks;
232     std::vector<sh::InterfaceBlock> mShaderStorageBlocks;
233 
234     // Track what should be validated given passes currently applied.
235     ValidateASTOptions mValidateASTOptions;
236 
237     // Specialization constant usage bits
238     SpecConstUsageBits mSpecConstUsageBits;
239 
240   private:
241     // Initialize symbol-table with built-in symbols.
242     bool initBuiltInSymbolTable(const ShBuiltInResources &resources);
243     // Compute the string representation of the built-in resources
244     void setResourceString();
245     // Return false if the call depth is exceeded.
246     bool checkCallDepth();
247     // Insert statements to reference all members in unused uniform blocks with standard and shared
248     // layout. This is to work around a Mac driver that treats unused standard/shared
249     // uniform blocks as inactive.
250     ANGLE_NO_DISCARD bool useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root);
251     // Insert statements to initialize output variables in the beginning of main().
252     // This is to avoid undefined behaviors.
253     ANGLE_NO_DISCARD bool initializeOutputVariables(TIntermBlock *root);
254     // Insert gl_Position = vec4(0,0,0,0) to the beginning of main().
255     // It is to work around a Linux driver bug where missing this causes compile failure
256     // while spec says it is allowed.
257     // This function should only be applied to vertex shaders.
258     ANGLE_NO_DISCARD bool initializeGLPosition(TIntermBlock *root);
259     // Return true if the maximum expression complexity is below the limit.
260     bool limitExpressionComplexity(TIntermBlock *root);
261     // Creates the function call DAG for further analysis, returning false if there is a recursion
262     bool initCallDag(TIntermNode *root);
263     // Return false if "main" doesn't exist
264     bool tagUsedFunctions();
265     void internalTagUsedFunction(size_t index);
266 
267     void collectInterfaceBlocks();
268 
269     bool mVariablesCollected;
270 
271     bool mGLPositionInitialized;
272 
273     // Removes unused function declarations and prototypes from the AST
274     bool pruneUnusedFunctions(TIntermBlock *root);
275 
276     TIntermBlock *compileTreeImpl(const char *const shaderStrings[],
277                                   size_t numStrings,
278                                   const ShCompileOptions compileOptions);
279 
280     // Fetches and stores shader metadata that is not stored within the AST itself, such as shader
281     // version.
282     void setASTMetadata(const TParseContext &parseContext);
283 
284     // Check if shader version meets the requirement.
285     bool checkShaderVersion(TParseContext *parseContext);
286 
287     // Does checks that need to be run after parsing is complete and returns true if they pass.
288     bool checkAndSimplifyAST(TIntermBlock *root,
289                              const TParseContext &parseContext,
290                              ShCompileOptions compileOptions);
291 
292     sh::GLenum mShaderType;
293     ShShaderSpec mShaderSpec;
294     ShShaderOutput mOutputType;
295 
296     CallDAG mCallDag;
297     std::vector<TFunctionMetadata> mFunctionMetadata;
298 
299     ShBuiltInResources mResources;
300     std::string mBuiltInResourcesString;
301 
302     // Built-in symbol table for the given language, spec, and resources.
303     // It is preserved from compile-to-compile.
304     TSymbolTable mSymbolTable;
305     // Built-in extensions with default behavior.
306     TExtensionBehavior mExtensionBehavior;
307 
308     BuiltInFunctionEmulator mBuiltInFunctionEmulator;
309 
310     // Results of compilation.
311     int mShaderVersion;
312     TInfoSink mInfoSink;  // Output sink.
313     TDiagnostics mDiagnostics;
314     const char *mSourcePath;  // Path of source file or NULL
315 
316     // fragment shader early fragment tests
317     bool mEarlyFragmentTestsSpecified;
318     bool mEarlyFragmentTestsOptimized;
319 
320     // compute shader local group size
321     bool mComputeShaderLocalSizeDeclared;
322     sh::WorkGroupSize mComputeShaderLocalSize;
323 
324     // GL_OVR_multiview num_views.
325     int mNumViews;
326 
327     // geometry shader parameters.
328     int mGeometryShaderMaxVertices;
329     int mGeometryShaderInvocations;
330     TLayoutPrimitiveType mGeometryShaderInputPrimitiveType;
331     TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType;
332 
333     // tesssellation shader parameters
334     int mTessControlShaderOutputVertices;
335     TLayoutTessEvaluationType mTessEvaluationShaderInputPrimitiveType;
336     TLayoutTessEvaluationType mTessEvaluationShaderInputVertexSpacingType;
337     TLayoutTessEvaluationType mTessEvaluationShaderInputOrderingType;
338     TLayoutTessEvaluationType mTessEvaluationShaderInputPointType;
339 
340     bool mHasAnyPreciseType;
341 
342     // name hashing.
343     NameMap mNameMap;
344 
345     TPragma mPragma;
346 
347     ShCompileOptions mCompileOptions;
348 };
349 
350 //
351 // This is the interface between the machine independent code
352 // and the machine dependent code.
353 //
354 // The machine dependent code should derive from the classes
355 // above. Then Construct*() and Delete*() will create and
356 // destroy the machine dependent objects, which contain the
357 // above machine independent information.
358 //
359 TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
360 void DeleteCompiler(TCompiler *);
361 
362 }  // namespace sh
363 
364 #endif  // COMPILER_TRANSLATOR_COMPILER_H_
365