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 "compiler/translator/BuiltInFunctionEmulator.h" 20 #include "compiler/translator/CallDAG.h" 21 #include "compiler/translator/Diagnostics.h" 22 #include "compiler/translator/ExtensionBehavior.h" 23 #include "compiler/translator/HashNames.h" 24 #include "compiler/translator/InfoSink.h" 25 #include "compiler/translator/Pragma.h" 26 #include "compiler/translator/SymbolTable.h" 27 #include "compiler/translator/ValidateAST.h" 28 #include "third_party/compiler/ArrayBoundsClamper.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 39 // 40 // Helper function to check if the shader type is GLSL. 41 // 42 bool IsGLSL130OrNewer(ShShaderOutput output); 43 bool IsGLSL420OrNewer(ShShaderOutput output); 44 bool IsGLSL410OrOlder(ShShaderOutput output); 45 46 // 47 // Helper function to check if the invariant qualifier can be removed. 48 // 49 bool RemoveInvariant(sh::GLenum shaderType, 50 int shaderVersion, 51 ShShaderOutput outputType, 52 ShCompileOptions compileOptions); 53 54 // 55 // The base class used to back handles returned to the driver. 56 // 57 class TShHandleBase 58 { 59 public: 60 TShHandleBase(); 61 virtual ~TShHandleBase(); getAsCompiler()62 virtual TCompiler *getAsCompiler() { return 0; } 63 #ifdef ANGLE_ENABLE_HLSL getAsTranslatorHLSL()64 virtual TranslatorHLSL *getAsTranslatorHLSL() { return 0; } 65 #endif // ANGLE_ENABLE_HLSL 66 67 protected: 68 // Memory allocator. Allocates and tracks memory required by the compiler. 69 // Deallocates all memory when compiler is destructed. 70 angle::PoolAllocator allocator; 71 }; 72 73 // 74 // The base class for the machine dependent compiler to derive from 75 // for managing object code from the compile. 76 // 77 class TCompiler : public TShHandleBase 78 { 79 public: 80 TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output); 81 ~TCompiler() override; getAsCompiler()82 TCompiler *getAsCompiler() override { return this; } 83 84 bool Init(const ShBuiltInResources &resources); 85 86 // compileTreeForTesting should be used only when tests require access to 87 // the AST. Users of this function need to manually manage the global pool 88 // allocator. Returns nullptr whenever there are compilation errors. 89 TIntermBlock *compileTreeForTesting(const char *const shaderStrings[], 90 size_t numStrings, 91 ShCompileOptions compileOptions); 92 93 bool compile(const char *const shaderStrings[], 94 size_t numStrings, 95 ShCompileOptions compileOptions); 96 97 // Get results of the last compilation. getShaderVersion()98 int getShaderVersion() const { return mShaderVersion; } getInfoSink()99 TInfoSink &getInfoSink() { return mInfoSink; } 100 isComputeShaderLocalSizeDeclared()101 bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; } getComputeShaderLocalSize()102 const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; } getNumViews()103 int getNumViews() const { return mNumViews; } 104 105 // Clears the results from the previous compilation. 106 void clearResults(); 107 getAttributes()108 const std::vector<sh::Attribute> &getAttributes() const { return mAttributes; } getOutputVariables()109 const std::vector<sh::OutputVariable> &getOutputVariables() const { return mOutputVariables; } getUniforms()110 const std::vector<sh::Uniform> &getUniforms() const { return mUniforms; } getInputVaryings()111 const std::vector<sh::Varying> &getInputVaryings() const { return mInputVaryings; } getOutputVaryings()112 const std::vector<sh::Varying> &getOutputVaryings() const { return mOutputVaryings; } getInterfaceBlocks()113 const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return mInterfaceBlocks; } getUniformBlocks()114 const std::vector<sh::InterfaceBlock> &getUniformBlocks() const { return mUniformBlocks; } getShaderStorageBlocks()115 const std::vector<sh::InterfaceBlock> &getShaderStorageBlocks() const 116 { 117 return mShaderStorageBlocks; 118 } getInBlocks()119 const std::vector<sh::InterfaceBlock> &getInBlocks() const { return mInBlocks; } 120 getHashFunction()121 ShHashFunction64 getHashFunction() const { return mResources.HashFunction; } getNameMap()122 NameMap &getNameMap() { return mNameMap; } getSymbolTable()123 TSymbolTable &getSymbolTable() { return mSymbolTable; } getShaderSpec()124 ShShaderSpec getShaderSpec() const { return mShaderSpec; } getOutputType()125 ShShaderOutput getOutputType() const { return mOutputType; } getBuiltInResourcesString()126 const std::string &getBuiltInResourcesString() const { return mBuiltInResourcesString; } 127 128 bool shouldRunLoopAndIndexingValidation(ShCompileOptions compileOptions) const; 129 130 // Get the resources set by InitBuiltInSymbolTable 131 const ShBuiltInResources &getResources() const; 132 getGeometryShaderMaxVertices()133 int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; } getGeometryShaderInvocations()134 int getGeometryShaderInvocations() const { return mGeometryShaderInvocations; } getGeometryShaderInputPrimitiveType()135 TLayoutPrimitiveType getGeometryShaderInputPrimitiveType() const 136 { 137 return mGeometryShaderInputPrimitiveType; 138 } getGeometryShaderOutputPrimitiveType()139 TLayoutPrimitiveType getGeometryShaderOutputPrimitiveType() const 140 { 141 return mGeometryShaderOutputPrimitiveType; 142 } 143 getShaderType()144 sh::GLenum getShaderType() const { return mShaderType; } 145 146 protected: 147 // Add emulated functions to the built-in function emulator. initBuiltInFunctionEmulator(BuiltInFunctionEmulator * emu,ShCompileOptions compileOptions)148 virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, 149 ShCompileOptions compileOptions) 150 {} 151 // Translate to object code. May generate performance warnings through the diagnostics. 152 virtual void translate(TIntermBlock *root, 153 ShCompileOptions compileOptions, 154 PerformanceDiagnostics *perfDiagnostics) = 0; 155 // Get built-in extensions with default behavior. 156 const TExtensionBehavior &getExtensionBehavior() const; 157 const char *getSourcePath() const; getPragma()158 const TPragma &getPragma() const { return mPragma; } 159 void writePragma(ShCompileOptions compileOptions); 160 // Relies on collectVariables having been called. 161 bool isVaryingDefined(const char *varyingName); 162 163 const ArrayBoundsClamper &getArrayBoundsClamper() const; 164 ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const; 165 const BuiltInFunctionEmulator &getBuiltInFunctionEmulator() const; 166 167 virtual bool shouldFlattenPragmaStdglInvariantAll() = 0; 168 virtual bool shouldCollectVariables(ShCompileOptions compileOptions); 169 170 bool wereVariablesCollected() const; 171 std::vector<sh::Attribute> mAttributes; 172 std::vector<sh::OutputVariable> mOutputVariables; 173 std::vector<sh::Uniform> mUniforms; 174 std::vector<sh::Varying> mInputVaryings; 175 std::vector<sh::Varying> mOutputVaryings; 176 std::vector<sh::InterfaceBlock> mInterfaceBlocks; 177 std::vector<sh::InterfaceBlock> mUniformBlocks; 178 std::vector<sh::InterfaceBlock> mShaderStorageBlocks; 179 std::vector<sh::InterfaceBlock> mInBlocks; 180 181 private: 182 // Initialize symbol-table with built-in symbols. 183 bool initBuiltInSymbolTable(const ShBuiltInResources &resources); 184 // Compute the string representation of the built-in resources 185 void setResourceString(); 186 // Return false if the call depth is exceeded. 187 bool checkCallDepth(); 188 // Insert statements to reference all members in unused uniform blocks with standard and shared 189 // layout. This is to work around a Mac driver that treats unused standard/shared 190 // uniform blocks as inactive. 191 void useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root); 192 // Insert statements to initialize output variables in the beginning of main(). 193 // This is to avoid undefined behaviors. 194 void initializeOutputVariables(TIntermBlock *root); 195 // Insert gl_Position = vec4(0,0,0,0) to the beginning of main(). 196 // It is to work around a Linux driver bug where missing this causes compile failure 197 // while spec says it is allowed. 198 // This function should only be applied to vertex shaders. 199 void initializeGLPosition(TIntermBlock *root); 200 // Return true if the maximum expression complexity is below the limit. 201 bool limitExpressionComplexity(TIntermBlock *root); 202 // Creates the function call DAG for further analysis, returning false if there is a recursion 203 bool initCallDag(TIntermNode *root); 204 // Return false if "main" doesn't exist 205 bool tagUsedFunctions(); 206 void internalTagUsedFunction(size_t index); 207 208 void collectInterfaceBlocks(); 209 210 bool mVariablesCollected; 211 212 bool mGLPositionInitialized; 213 214 // Removes unused function declarations and prototypes from the AST 215 class UnusedPredicate; 216 void pruneUnusedFunctions(TIntermBlock *root); 217 218 TIntermBlock *compileTreeImpl(const char *const shaderStrings[], 219 size_t numStrings, 220 const ShCompileOptions compileOptions); 221 222 // Fetches and stores shader metadata that is not stored within the AST itself, such as shader 223 // version. 224 void setASTMetadata(const TParseContext &parseContext); 225 226 // Check if shader version meets the requirement. 227 bool checkShaderVersion(TParseContext *parseContext); 228 229 // Does checks that need to be run after parsing is complete and returns true if they pass. 230 bool checkAndSimplifyAST(TIntermBlock *root, 231 const TParseContext &parseContext, 232 ShCompileOptions compileOptions); 233 234 sh::GLenum mShaderType; 235 ShShaderSpec mShaderSpec; 236 ShShaderOutput mOutputType; 237 238 struct FunctionMetadata 239 { FunctionMetadataFunctionMetadata240 FunctionMetadata() : used(false) {} 241 bool used; 242 }; 243 244 CallDAG mCallDag; 245 std::vector<FunctionMetadata> mFunctionMetadata; 246 247 ShBuiltInResources mResources; 248 std::string mBuiltInResourcesString; 249 250 // Built-in symbol table for the given language, spec, and resources. 251 // It is preserved from compile-to-compile. 252 TSymbolTable mSymbolTable; 253 // Built-in extensions with default behavior. 254 TExtensionBehavior mExtensionBehavior; 255 256 ArrayBoundsClamper mArrayBoundsClamper; 257 BuiltInFunctionEmulator mBuiltInFunctionEmulator; 258 259 // Results of compilation. 260 int mShaderVersion; 261 TInfoSink mInfoSink; // Output sink. 262 TDiagnostics mDiagnostics; 263 const char *mSourcePath; // Path of source file or NULL 264 265 // compute shader local group size 266 bool mComputeShaderLocalSizeDeclared; 267 sh::WorkGroupSize mComputeShaderLocalSize; 268 269 // GL_OVR_multiview num_views. 270 int mNumViews; 271 272 // geometry shader parameters. 273 int mGeometryShaderMaxVertices; 274 int mGeometryShaderInvocations; 275 TLayoutPrimitiveType mGeometryShaderInputPrimitiveType; 276 TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType; 277 278 // name hashing. 279 NameMap mNameMap; 280 281 TPragma mPragma; 282 283 // Track what should be validated given passes currently applied. 284 ValidateASTOptions mValidateASTOptions; 285 }; 286 287 // 288 // This is the interface between the machine independent code 289 // and the machine dependent code. 290 // 291 // The machine dependent code should derive from the classes 292 // above. Then Construct*() and Delete*() will create and 293 // destroy the machine dependent objects, which contain the 294 // above machine independent information. 295 // 296 TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output); 297 void DeleteCompiler(TCompiler *); 298 299 void EmitWorkGroupSizeGLSL(const TCompiler &, TInfoSinkBase &sink); 300 void EmitMultiviewGLSL(const TCompiler &, const ShCompileOptions &, TBehavior, TInfoSinkBase &sink); 301 302 } // namespace sh 303 304 #endif // COMPILER_TRANSLATOR_COMPILER_H_ 305