tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Compiler.h (15351B)


      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                     const 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();
     67    virtual TCompiler *getAsCompiler() { return 0; }
     68 #ifdef ANGLE_ENABLE_HLSL
     69    virtual TranslatorHLSL *getAsTranslatorHLSL() { return 0; }
     70 #endif  // ANGLE_ENABLE_HLSL
     71 #ifdef ANGLE_ENABLE_METAL
     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;
     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                                        const ShCompileOptions &compileOptions);
    105 
    106    bool compile(const char *const shaderStrings[],
    107                 size_t numStrings,
    108                 const ShCompileOptions &compileOptions);
    109 
    110    // Get results of the last compilation.
    111    int getShaderVersion() const { return mShaderVersion; }
    112    TInfoSink &getInfoSink() { return mInfoSink; }
    113 
    114    bool specifyEarlyFragmentTests() { return mEarlyFragmentTestsSpecified = true; }
    115    bool isEarlyFragmentTestsSpecified() const { return mEarlyFragmentTestsSpecified; }
    116    bool hasDiscard() const { return mHasDiscard; }
    117    bool enablesPerSampleShading() const { return mEnablesPerSampleShading; }
    118    SpecConstUsageBits getSpecConstUsageBits() const { return mSpecConstUsageBits; }
    119 
    120    bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; }
    121    const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; }
    122    int getNumViews() const { return mNumViews; }
    123 
    124    // Clears the results from the previous compilation.
    125    void clearResults();
    126 
    127    const std::vector<sh::ShaderVariable> &getAttributes() const { return mAttributes; }
    128    const std::vector<sh::ShaderVariable> &getOutputVariables() const { return mOutputVariables; }
    129    const std::vector<sh::ShaderVariable> &getUniforms() const { return mUniforms; }
    130    const std::vector<sh::ShaderVariable> &getInputVaryings() const { return mInputVaryings; }
    131    const std::vector<sh::ShaderVariable> &getOutputVaryings() const { return mOutputVaryings; }
    132    const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return mInterfaceBlocks; }
    133    const std::vector<sh::InterfaceBlock> &getUniformBlocks() const { return mUniformBlocks; }
    134    const std::vector<sh::InterfaceBlock> &getShaderStorageBlocks() const
    135    {
    136        return mShaderStorageBlocks;
    137    }
    138 
    139    ShHashFunction64 getHashFunction() const { return mResources.HashFunction; }
    140    NameMap &getNameMap() { return mNameMap; }
    141    TSymbolTable &getSymbolTable() { return mSymbolTable; }
    142    ShShaderSpec getShaderSpec() const { return mShaderSpec; }
    143    ShShaderOutput getOutputType() const { return mOutputType; }
    144    ShBuiltInResources getBuiltInResources() const { return mResources; }
    145    const std::string &getBuiltInResourcesString() const { return mBuiltInResourcesString; }
    146 
    147    bool isHighPrecisionSupported() const;
    148 
    149    bool shouldRunLoopAndIndexingValidation(const ShCompileOptions &compileOptions) const;
    150    bool shouldLimitTypeSizes() const;
    151 
    152    // Get the resources set by InitBuiltInSymbolTable
    153    const ShBuiltInResources &getResources() const;
    154 
    155    const TPragma &getPragma() const { return mPragma; }
    156 
    157    int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; }
    158    int getGeometryShaderInvocations() const { return mGeometryShaderInvocations; }
    159    TLayoutPrimitiveType getGeometryShaderInputPrimitiveType() const
    160    {
    161        return mGeometryShaderInputPrimitiveType;
    162    }
    163    TLayoutPrimitiveType getGeometryShaderOutputPrimitiveType() const
    164    {
    165        return mGeometryShaderOutputPrimitiveType;
    166    }
    167 
    168    unsigned int getStructSize(const ShaderVariable &var) const;
    169 
    170    int getTessControlShaderOutputVertices() const { return mTessControlShaderOutputVertices; }
    171    TLayoutTessEvaluationType getTessEvaluationShaderInputPrimitiveType() const
    172    {
    173        return mTessEvaluationShaderInputPrimitiveType;
    174    }
    175    TLayoutTessEvaluationType getTessEvaluationShaderInputVertexSpacingType() const
    176    {
    177        return mTessEvaluationShaderInputVertexSpacingType;
    178    }
    179    TLayoutTessEvaluationType getTessEvaluationShaderInputOrderingType() const
    180    {
    181        return mTessEvaluationShaderInputOrderingType;
    182    }
    183    TLayoutTessEvaluationType getTessEvaluationShaderInputPointType() const
    184    {
    185        return mTessEvaluationShaderInputPointType;
    186    }
    187 
    188    bool hasAnyPreciseType() const { return mHasAnyPreciseType; }
    189 
    190    AdvancedBlendEquations getAdvancedBlendEquations() const { return mAdvancedBlendEquations; }
    191 
    192    bool hasPixelLocalStorageUniforms() const { return mHasPixelLocalStorageUniforms; }
    193 
    194    unsigned int getSharedMemorySize() const;
    195 
    196    sh::GLenum getShaderType() const { return mShaderType; }
    197 
    198    // Validate the AST and produce errors if it is inconsistent.
    199    bool validateAST(TIntermNode *root);
    200    // Some transformations may need to temporarily disable validation until they are complete.  A
    201    // set of disable/enable helpers are used for this purpose.
    202    bool disableValidateFunctionCall();
    203    void restoreValidateFunctionCall(bool enable);
    204    bool disableValidateVariableReferences();
    205    void restoreValidateVariableReferences(bool enable);
    206    // When the AST is post-processed (such as to determine precise-ness of intermediate nodes),
    207    // it's expected to no longer transform.
    208    void enableValidateNoMoreTransformations();
    209 
    210  protected:
    211    // Add emulated functions to the built-in function emulator.
    212    virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
    213                                             const ShCompileOptions &compileOptions)
    214    {}
    215    // Translate to object code. May generate performance warnings through the diagnostics.
    216    [[nodiscard]] virtual bool translate(TIntermBlock *root,
    217                                         const ShCompileOptions &compileOptions,
    218                                         PerformanceDiagnostics *perfDiagnostics) = 0;
    219    // Get built-in extensions with default behavior.
    220    const TExtensionBehavior &getExtensionBehavior() const;
    221    const char *getSourcePath() const;
    222    // Relies on collectVariables having been called.
    223    bool isVaryingDefined(const char *varyingName);
    224 
    225    const BuiltInFunctionEmulator &getBuiltInFunctionEmulator() const;
    226 
    227    virtual bool shouldFlattenPragmaStdglInvariantAll() = 0;
    228    virtual bool shouldCollectVariables(const ShCompileOptions &compileOptions);
    229 
    230    bool wereVariablesCollected() const;
    231    std::vector<sh::ShaderVariable> mAttributes;
    232    std::vector<sh::ShaderVariable> mOutputVariables;
    233    std::vector<sh::ShaderVariable> mUniforms;
    234    std::vector<sh::ShaderVariable> mInputVaryings;
    235    std::vector<sh::ShaderVariable> mOutputVaryings;
    236    std::vector<sh::ShaderVariable> mSharedVariables;
    237    std::vector<sh::InterfaceBlock> mInterfaceBlocks;
    238    std::vector<sh::InterfaceBlock> mUniformBlocks;
    239    std::vector<sh::InterfaceBlock> mShaderStorageBlocks;
    240 
    241    // Track what should be validated given passes currently applied.
    242    ValidateASTOptions mValidateASTOptions;
    243 
    244    // Specialization constant usage bits
    245    SpecConstUsageBits mSpecConstUsageBits;
    246 
    247  private:
    248    // Initialize symbol-table with built-in symbols.
    249    bool initBuiltInSymbolTable(const ShBuiltInResources &resources);
    250    // Compute the string representation of the built-in resources
    251    void setResourceString();
    252    // Return false if the call depth is exceeded.
    253    bool checkCallDepth();
    254    // Insert statements to reference all members in unused uniform blocks with standard and shared
    255    // layout. This is to work around a Mac driver that treats unused standard/shared
    256    // uniform blocks as inactive.
    257    [[nodiscard]] bool useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root);
    258    // Insert statements to initialize output variables in the beginning of main().
    259    // This is to avoid undefined behaviors.
    260    [[nodiscard]] bool initializeOutputVariables(TIntermBlock *root);
    261    // Insert gl_Position = vec4(0,0,0,0) to the beginning of main().
    262    // It is to work around a Linux driver bug where missing this causes compile failure
    263    // while spec says it is allowed.
    264    // This function should only be applied to vertex shaders.
    265    [[nodiscard]] bool initializeGLPosition(TIntermBlock *root);
    266    // Return true if the maximum expression complexity is below the limit.
    267    bool limitExpressionComplexity(TIntermBlock *root);
    268    // Creates the function call DAG for further analysis, returning false if there is a recursion
    269    bool initCallDag(TIntermNode *root);
    270    // Return false if "main" doesn't exist
    271    bool tagUsedFunctions();
    272    void internalTagUsedFunction(size_t index);
    273 
    274    void collectInterfaceBlocks();
    275 
    276    bool mVariablesCollected;
    277 
    278    bool mGLPositionInitialized;
    279 
    280    // Removes unused function declarations and prototypes from the AST
    281    bool pruneUnusedFunctions(TIntermBlock *root);
    282 
    283    TIntermBlock *compileTreeImpl(const char *const shaderStrings[],
    284                                  size_t numStrings,
    285                                  const ShCompileOptions &compileOptions);
    286 
    287    // Fetches and stores shader metadata that is not stored within the AST itself, such as shader
    288    // version.
    289    void setASTMetadata(const TParseContext &parseContext);
    290 
    291    // Check if shader version meets the requirement.
    292    bool checkShaderVersion(TParseContext *parseContext);
    293 
    294    // Does checks that need to be run after parsing is complete and returns true if they pass.
    295    bool checkAndSimplifyAST(TIntermBlock *root,
    296                             const TParseContext &parseContext,
    297                             const ShCompileOptions &compileOptions);
    298 
    299    bool postParseChecks(const TParseContext &parseContext);
    300 
    301    sh::GLenum mShaderType;
    302    ShShaderSpec mShaderSpec;
    303    ShShaderOutput mOutputType;
    304 
    305    CallDAG mCallDag;
    306    std::vector<TFunctionMetadata> mFunctionMetadata;
    307 
    308    ShBuiltInResources mResources;
    309    std::string mBuiltInResourcesString;
    310 
    311    // Built-in symbol table for the given language, spec, and resources.
    312    // It is preserved from compile-to-compile.
    313    TSymbolTable mSymbolTable;
    314    // Built-in extensions with default behavior.
    315    TExtensionBehavior mExtensionBehavior;
    316 
    317    BuiltInFunctionEmulator mBuiltInFunctionEmulator;
    318 
    319    // Results of compilation.
    320    int mShaderVersion;
    321    TInfoSink mInfoSink;  // Output sink.
    322    TDiagnostics mDiagnostics;
    323    const char *mSourcePath;  // Path of source file or NULL
    324 
    325    // Fragment shader early fragment tests
    326    bool mEarlyFragmentTestsSpecified;
    327 
    328    // Fragment shader has the discard instruction
    329    bool mHasDiscard;
    330 
    331    // Whether per-sample shading is enabled by the shader.  In OpenGL, this keyword should
    332    // implicitly trigger per-sample shading without the API enabling it.
    333    bool mEnablesPerSampleShading;
    334 
    335    // compute shader local group size
    336    bool mComputeShaderLocalSizeDeclared;
    337    sh::WorkGroupSize mComputeShaderLocalSize;
    338 
    339    // GL_OVR_multiview num_views.
    340    int mNumViews;
    341 
    342    // geometry shader parameters.
    343    int mGeometryShaderMaxVertices;
    344    int mGeometryShaderInvocations;
    345    TLayoutPrimitiveType mGeometryShaderInputPrimitiveType;
    346    TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType;
    347 
    348    // tesssellation shader parameters
    349    int mTessControlShaderOutputVertices;
    350    TLayoutTessEvaluationType mTessEvaluationShaderInputPrimitiveType;
    351    TLayoutTessEvaluationType mTessEvaluationShaderInputVertexSpacingType;
    352    TLayoutTessEvaluationType mTessEvaluationShaderInputOrderingType;
    353    TLayoutTessEvaluationType mTessEvaluationShaderInputPointType;
    354 
    355    bool mHasAnyPreciseType;
    356 
    357    // advanced blend equation parameters
    358    AdvancedBlendEquations mAdvancedBlendEquations;
    359 
    360    // ANGLE_shader_pixel_local_storage.
    361    bool mHasPixelLocalStorageUniforms;
    362 
    363    // name hashing.
    364    NameMap mNameMap;
    365 
    366    TPragma mPragma;
    367 
    368    ShCompileOptions mCompileOptions;
    369 };
    370 
    371 //
    372 // This is the interface between the machine independent code
    373 // and the machine dependent code.
    374 //
    375 // The machine dependent code should derive from the classes
    376 // above. Then Construct*() and Delete*() will create and
    377 // destroy the machine dependent objects, which contain the
    378 // above machine independent information.
    379 //
    380 TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
    381 void DeleteCompiler(TCompiler *);
    382 
    383 struct ShaderDumpHeader
    384 {
    385    uint32_t type;
    386    uint32_t spec;
    387    uint32_t output;
    388    uint8_t basicCompileOptions[32];
    389    uint8_t metalCompileOptions[32];
    390    uint8_t plsCompileOptions[32];
    391    uint8_t padding[20];
    392 };
    393 static_assert(sizeof(ShaderDumpHeader) == 128);
    394 
    395 }  // namespace sh
    396 
    397 #endif  // COMPILER_TRANSLATOR_COMPILER_H_