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 isEarlyFragmentTestsSpecified()101 bool isEarlyFragmentTestsSpecified() const { return mEarlyFragmentTestsSpecified; } 102 isComputeShaderLocalSizeDeclared()103 bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; } getComputeShaderLocalSize()104 const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; } getNumViews()105 int getNumViews() const { return mNumViews; } 106 107 // Clears the results from the previous compilation. 108 void clearResults(); 109 getAttributes()110 const std::vector<sh::ShaderVariable> &getAttributes() const { return mAttributes; } getOutputVariables()111 const std::vector<sh::ShaderVariable> &getOutputVariables() const { return mOutputVariables; } getUniforms()112 const std::vector<sh::ShaderVariable> &getUniforms() const { return mUniforms; } getInputVaryings()113 const std::vector<sh::ShaderVariable> &getInputVaryings() const { return mInputVaryings; } getOutputVaryings()114 const std::vector<sh::ShaderVariable> &getOutputVaryings() const { return mOutputVaryings; } getInterfaceBlocks()115 const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return mInterfaceBlocks; } getUniformBlocks()116 const std::vector<sh::InterfaceBlock> &getUniformBlocks() const { return mUniformBlocks; } getShaderStorageBlocks()117 const std::vector<sh::InterfaceBlock> &getShaderStorageBlocks() const 118 { 119 return mShaderStorageBlocks; 120 } getInBlocks()121 const std::vector<sh::InterfaceBlock> &getInBlocks() const { return mInBlocks; } 122 getHashFunction()123 ShHashFunction64 getHashFunction() const { return mResources.HashFunction; } getNameMap()124 NameMap &getNameMap() { return mNameMap; } getSymbolTable()125 TSymbolTable &getSymbolTable() { return mSymbolTable; } getShaderSpec()126 ShShaderSpec getShaderSpec() const { return mShaderSpec; } getOutputType()127 ShShaderOutput getOutputType() const { return mOutputType; } getBuiltInResourcesString()128 const std::string &getBuiltInResourcesString() const { return mBuiltInResourcesString; } 129 130 bool shouldRunLoopAndIndexingValidation(ShCompileOptions compileOptions) const; 131 132 // Get the resources set by InitBuiltInSymbolTable 133 const ShBuiltInResources &getResources() const; 134 getGeometryShaderMaxVertices()135 int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; } getGeometryShaderInvocations()136 int getGeometryShaderInvocations() const { return mGeometryShaderInvocations; } getGeometryShaderInputPrimitiveType()137 TLayoutPrimitiveType getGeometryShaderInputPrimitiveType() const 138 { 139 return mGeometryShaderInputPrimitiveType; 140 } getGeometryShaderOutputPrimitiveType()141 TLayoutPrimitiveType getGeometryShaderOutputPrimitiveType() const 142 { 143 return mGeometryShaderOutputPrimitiveType; 144 } 145 146 unsigned int getStructSize(const ShaderVariable &var) const; 147 unsigned int getSharedMemorySize() const; 148 getShaderType()149 sh::GLenum getShaderType() const { return mShaderType; } 150 151 bool validateAST(TIntermNode *root); 152 153 protected: 154 // Add emulated functions to the built-in function emulator. initBuiltInFunctionEmulator(BuiltInFunctionEmulator * emu,ShCompileOptions compileOptions)155 virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu, 156 ShCompileOptions compileOptions) 157 {} 158 // Translate to object code. May generate performance warnings through the diagnostics. 159 ANGLE_NO_DISCARD virtual bool translate(TIntermBlock *root, 160 ShCompileOptions compileOptions, 161 PerformanceDiagnostics *perfDiagnostics) = 0; 162 // Get built-in extensions with default behavior. 163 const TExtensionBehavior &getExtensionBehavior() const; 164 const char *getSourcePath() const; getPragma()165 const TPragma &getPragma() const { return mPragma; } 166 void writePragma(ShCompileOptions compileOptions); 167 // Relies on collectVariables having been called. 168 bool isVaryingDefined(const char *varyingName); 169 170 const ArrayBoundsClamper &getArrayBoundsClamper() const; 171 ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const; 172 const BuiltInFunctionEmulator &getBuiltInFunctionEmulator() const; 173 174 virtual bool shouldFlattenPragmaStdglInvariantAll() = 0; 175 virtual bool shouldCollectVariables(ShCompileOptions compileOptions); 176 // If precision emulation needed, set isNeeded to true and emulate precision for given 177 // outputLanguage, returning false if that fails, else returning true. 178 bool emulatePrecisionIfNeeded(TIntermBlock *root, 179 TInfoSinkBase &sink, 180 bool *isNeeded, 181 const ShShaderOutput outputLanguage); 182 183 bool wereVariablesCollected() const; 184 std::vector<sh::ShaderVariable> mAttributes; 185 std::vector<sh::ShaderVariable> mOutputVariables; 186 std::vector<sh::ShaderVariable> mUniforms; 187 std::vector<sh::ShaderVariable> mInputVaryings; 188 std::vector<sh::ShaderVariable> mOutputVaryings; 189 std::vector<sh::ShaderVariable> mSharedVariables; 190 std::vector<sh::InterfaceBlock> mInterfaceBlocks; 191 std::vector<sh::InterfaceBlock> mUniformBlocks; 192 std::vector<sh::InterfaceBlock> mShaderStorageBlocks; 193 std::vector<sh::InterfaceBlock> mInBlocks; 194 195 private: 196 // Initialize symbol-table with built-in symbols. 197 bool initBuiltInSymbolTable(const ShBuiltInResources &resources); 198 // Compute the string representation of the built-in resources 199 void setResourceString(); 200 // Return false if the call depth is exceeded. 201 bool checkCallDepth(); 202 // Insert statements to reference all members in unused uniform blocks with standard and shared 203 // layout. This is to work around a Mac driver that treats unused standard/shared 204 // uniform blocks as inactive. 205 ANGLE_NO_DISCARD bool useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root); 206 // Insert statements to initialize output variables in the beginning of main(). 207 // This is to avoid undefined behaviors. 208 ANGLE_NO_DISCARD bool initializeOutputVariables(TIntermBlock *root); 209 // Insert gl_Position = vec4(0,0,0,0) to the beginning of main(). 210 // It is to work around a Linux driver bug where missing this causes compile failure 211 // while spec says it is allowed. 212 // This function should only be applied to vertex shaders. 213 ANGLE_NO_DISCARD bool initializeGLPosition(TIntermBlock *root); 214 // Return true if the maximum expression complexity is below the limit. 215 bool limitExpressionComplexity(TIntermBlock *root); 216 // Creates the function call DAG for further analysis, returning false if there is a recursion 217 bool initCallDag(TIntermNode *root); 218 // Return false if "main" doesn't exist 219 bool tagUsedFunctions(); 220 void internalTagUsedFunction(size_t index); 221 222 void collectInterfaceBlocks(); 223 224 bool mVariablesCollected; 225 226 bool mGLPositionInitialized; 227 228 // Removes unused function declarations and prototypes from the AST 229 class UnusedPredicate; 230 void pruneUnusedFunctions(TIntermBlock *root); 231 232 TIntermBlock *compileTreeImpl(const char *const shaderStrings[], 233 size_t numStrings, 234 const ShCompileOptions compileOptions); 235 236 // Fetches and stores shader metadata that is not stored within the AST itself, such as shader 237 // version. 238 void setASTMetadata(const TParseContext &parseContext); 239 240 // Check if shader version meets the requirement. 241 bool checkShaderVersion(TParseContext *parseContext); 242 243 // Does checks that need to be run after parsing is complete and returns true if they pass. 244 bool checkAndSimplifyAST(TIntermBlock *root, 245 const TParseContext &parseContext, 246 ShCompileOptions compileOptions); 247 248 sh::GLenum mShaderType; 249 ShShaderSpec mShaderSpec; 250 ShShaderOutput mOutputType; 251 252 struct FunctionMetadata 253 { FunctionMetadataFunctionMetadata254 FunctionMetadata() : used(false) {} 255 bool used; 256 }; 257 258 CallDAG mCallDag; 259 std::vector<FunctionMetadata> mFunctionMetadata; 260 261 ShBuiltInResources mResources; 262 std::string mBuiltInResourcesString; 263 264 // Built-in symbol table for the given language, spec, and resources. 265 // It is preserved from compile-to-compile. 266 TSymbolTable mSymbolTable; 267 // Built-in extensions with default behavior. 268 TExtensionBehavior mExtensionBehavior; 269 270 ArrayBoundsClamper mArrayBoundsClamper; 271 BuiltInFunctionEmulator mBuiltInFunctionEmulator; 272 273 // Results of compilation. 274 int mShaderVersion; 275 TInfoSink mInfoSink; // Output sink. 276 TDiagnostics mDiagnostics; 277 const char *mSourcePath; // Path of source file or NULL 278 279 // fragment shader early fragment tests 280 bool mEarlyFragmentTestsSpecified; 281 282 // compute shader local group size 283 bool mComputeShaderLocalSizeDeclared; 284 sh::WorkGroupSize mComputeShaderLocalSize; 285 286 // GL_OVR_multiview num_views. 287 int mNumViews; 288 289 // geometry shader parameters. 290 int mGeometryShaderMaxVertices; 291 int mGeometryShaderInvocations; 292 TLayoutPrimitiveType mGeometryShaderInputPrimitiveType; 293 TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType; 294 295 // name hashing. 296 NameMap mNameMap; 297 298 TPragma mPragma; 299 300 // Track what should be validated given passes currently applied. 301 ValidateASTOptions mValidateASTOptions; 302 303 ShCompileOptions mCompileOptions; 304 }; 305 306 // 307 // This is the interface between the machine independent code 308 // and the machine dependent code. 309 // 310 // The machine dependent code should derive from the classes 311 // above. Then Construct*() and Delete*() will create and 312 // destroy the machine dependent objects, which contain the 313 // above machine independent information. 314 // 315 TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output); 316 void DeleteCompiler(TCompiler *); 317 318 void EmitEarlyFragmentTestsGLSL(const TCompiler &, TInfoSinkBase &sink); 319 void EmitWorkGroupSizeGLSL(const TCompiler &, TInfoSinkBase &sink); 320 void EmitMultiviewGLSL(const TCompiler &, 321 const ShCompileOptions &, 322 const TExtension, 323 const TBehavior, 324 TInfoSinkBase &sink); 325 326 } // namespace sh 327 328 #endif // COMPILER_TRANSLATOR_COMPILER_H_ 329