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