tor-browser

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

ProgramExecutable.h (20443B)


      1 //
      2 // Copyright 2020 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 // ProgramExecutable.h: Collects the information and interfaces common to both Programs and
      7 // ProgramPipelines in order to execute/draw with either.
      8 
      9 #ifndef LIBANGLE_PROGRAMEXECUTABLE_H_
     10 #define LIBANGLE_PROGRAMEXECUTABLE_H_
     11 
     12 #include "BinaryStream.h"
     13 #include "libANGLE/Caps.h"
     14 #include "libANGLE/InfoLog.h"
     15 #include "libANGLE/ProgramLinkedResources.h"
     16 #include "libANGLE/Shader.h"
     17 #include "libANGLE/Uniform.h"
     18 #include "libANGLE/VaryingPacking.h"
     19 #include "libANGLE/angletypes.h"
     20 
     21 namespace gl
     22 {
     23 
     24 // This small structure encapsulates binding sampler uniforms to active GL textures.
     25 struct SamplerBinding
     26 {
     27    SamplerBinding(TextureType textureTypeIn,
     28                   GLenum samplerTypeIn,
     29                   SamplerFormat formatIn,
     30                   size_t elementCount);
     31    SamplerBinding(const SamplerBinding &other);
     32    ~SamplerBinding();
     33 
     34    // Necessary for retrieving active textures from the GL state.
     35    TextureType textureType;
     36 
     37    GLenum samplerType;
     38 
     39    SamplerFormat format;
     40 
     41    // List of all textures bound to this sampler, of type textureType.
     42    // Cropped by the amount of unused elements reported by the driver.
     43    std::vector<GLuint> boundTextureUnits;
     44 };
     45 
     46 struct ImageBinding
     47 {
     48    ImageBinding(size_t count, TextureType textureTypeIn);
     49    ImageBinding(GLuint imageUnit, size_t count, TextureType textureTypeIn);
     50    ImageBinding(const ImageBinding &other);
     51    ~ImageBinding();
     52 
     53    // Necessary for distinguishing between textures with images and texture buffers.
     54    TextureType textureType;
     55 
     56    // List of all textures bound.
     57    // Cropped by the amount of unused elements reported by the driver.
     58    std::vector<GLuint> boundImageUnits;
     59 };
     60 
     61 // A varying with transform feedback enabled. If it's an array, either the whole array or one of its
     62 // elements specified by 'arrayIndex' can set to be enabled.
     63 struct TransformFeedbackVarying : public sh::ShaderVariable
     64 {
     65    TransformFeedbackVarying(const sh::ShaderVariable &varyingIn, GLuint arrayIndexIn)
     66        : sh::ShaderVariable(varyingIn), arrayIndex(arrayIndexIn)
     67    {
     68        ASSERT(!isArrayOfArrays());
     69    }
     70 
     71    TransformFeedbackVarying(const sh::ShaderVariable &field, const sh::ShaderVariable &parent)
     72        : arrayIndex(GL_INVALID_INDEX)
     73    {
     74        sh::ShaderVariable *thisVar = this;
     75        *thisVar                    = field;
     76        interpolation               = parent.interpolation;
     77        isInvariant                 = parent.isInvariant;
     78        ASSERT(parent.isShaderIOBlock || !parent.name.empty());
     79        if (!parent.name.empty())
     80        {
     81            name       = parent.name + "." + name;
     82            mappedName = parent.mappedName + "." + mappedName;
     83        }
     84        structOrBlockName       = parent.structOrBlockName;
     85        mappedStructOrBlockName = parent.mappedStructOrBlockName;
     86    }
     87 
     88    std::string nameWithArrayIndex() const
     89    {
     90        std::stringstream fullNameStr;
     91        fullNameStr << name;
     92        if (arrayIndex != GL_INVALID_INDEX)
     93        {
     94            fullNameStr << "[" << arrayIndex << "]";
     95        }
     96        return fullNameStr.str();
     97    }
     98    GLsizei size() const
     99    {
    100        return (isArray() && arrayIndex == GL_INVALID_INDEX ? getOutermostArraySize() : 1);
    101    }
    102 
    103    GLuint arrayIndex;
    104 };
    105 
    106 class ProgramState;
    107 class ProgramPipelineState;
    108 
    109 class ProgramExecutable final : public angle::Subject
    110 {
    111  public:
    112    ProgramExecutable();
    113    ProgramExecutable(const ProgramExecutable &other);
    114    ~ProgramExecutable() override;
    115 
    116    void reset(bool clearInfoLog);
    117 
    118    void save(bool isSeparable, gl::BinaryOutputStream *stream) const;
    119    void load(bool isSeparable, gl::BinaryInputStream *stream);
    120 
    121    int getInfoLogLength() const;
    122    InfoLog &getInfoLog() { return mInfoLog; }
    123    void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const;
    124    std::string getInfoLogString() const;
    125    void resetInfoLog() { mInfoLog.reset(); }
    126 
    127    void resetLinkedShaderStages() { mLinkedShaderStages.reset(); }
    128    const ShaderBitSet &getLinkedShaderStages() const { return mLinkedShaderStages; }
    129    void setLinkedShaderStages(ShaderType shaderType)
    130    {
    131        mLinkedShaderStages.set(shaderType);
    132        updateCanDrawWith();
    133    }
    134    bool hasLinkedShaderStage(ShaderType shaderType) const
    135    {
    136        ASSERT(shaderType != ShaderType::InvalidEnum);
    137        return mLinkedShaderStages[shaderType];
    138    }
    139    size_t getLinkedShaderStageCount() const { return mLinkedShaderStages.count(); }
    140    bool hasLinkedGraphicsShader() const
    141    {
    142        return mLinkedShaderStages.any() &&
    143               mLinkedShaderStages != gl::ShaderBitSet{gl::ShaderType::Compute};
    144    }
    145    bool hasLinkedTessellationShader() const
    146    {
    147        return mLinkedShaderStages[ShaderType::TessEvaluation];
    148    }
    149 
    150    ShaderType getLinkedTransformFeedbackStage() const;
    151 
    152    const AttributesMask &getActiveAttribLocationsMask() const
    153    {
    154        return mActiveAttribLocationsMask;
    155    }
    156    bool isAttribLocationActive(size_t attribLocation) const;
    157    const AttributesMask &getNonBuiltinAttribLocationsMask() const { return mAttributesMask; }
    158    unsigned int getMaxActiveAttribLocation() const { return mMaxActiveAttribLocation; }
    159    const ComponentTypeMask &getAttributesTypeMask() const { return mAttributesTypeMask; }
    160    AttributesMask getAttributesMask() const;
    161 
    162    const ActiveTextureMask &getActiveSamplersMask() const { return mActiveSamplersMask; }
    163    void setActiveTextureMask(ActiveTextureMask mask) { mActiveSamplersMask = mask; }
    164    SamplerFormat getSamplerFormatForTextureUnitIndex(size_t textureUnitIndex) const
    165    {
    166        return mActiveSamplerFormats[textureUnitIndex];
    167    }
    168    const ShaderBitSet getSamplerShaderBitsForTextureUnitIndex(size_t textureUnitIndex) const
    169    {
    170        return mActiveSamplerShaderBits[textureUnitIndex];
    171    }
    172    const ActiveTextureMask &getActiveImagesMask() const { return mActiveImagesMask; }
    173    void setActiveImagesMask(ActiveTextureMask mask) { mActiveImagesMask = mask; }
    174    const ActiveTextureArray<ShaderBitSet> &getActiveImageShaderBits() const
    175    {
    176        return mActiveImageShaderBits;
    177    }
    178 
    179    const ActiveTextureMask &getActiveYUVSamplers() const { return mActiveSamplerYUV; }
    180 
    181    const ActiveTextureArray<TextureType> &getActiveSamplerTypes() const
    182    {
    183        return mActiveSamplerTypes;
    184    }
    185 
    186    void setActive(size_t textureUnit,
    187                   const SamplerBinding &samplerBinding,
    188                   const gl::LinkedUniform &samplerUniform);
    189    void setInactive(size_t textureUnit);
    190    void hasSamplerTypeConflict(size_t textureUnit);
    191    void hasSamplerFormatConflict(size_t textureUnit);
    192 
    193    void updateActiveSamplers(const ProgramState &programState);
    194 
    195    bool hasDefaultUniforms() const;
    196    bool hasTextures() const;
    197    bool hasUniformBuffers() const;
    198    bool hasStorageBuffers() const;
    199    bool hasAtomicCounterBuffers() const;
    200    bool hasImages() const;
    201    bool hasTransformFeedbackOutput() const
    202    {
    203        return !getLinkedTransformFeedbackVaryings().empty();
    204    }
    205    bool usesFramebufferFetch() const;
    206 
    207    // Count the number of uniform and storage buffer declarations, counting arrays as one.
    208    size_t getTransformFeedbackBufferCount() const { return mTransformFeedbackStrides.size(); }
    209 
    210    void updateCanDrawWith();
    211    bool hasVertexShader() const { return mCanDrawWith; }
    212 
    213    const std::vector<sh::ShaderVariable> &getProgramInputs() const { return mProgramInputs; }
    214    const std::vector<sh::ShaderVariable> &getOutputVariables() const { return mOutputVariables; }
    215    const std::vector<VariableLocation> &getOutputLocations() const { return mOutputLocations; }
    216    const std::vector<VariableLocation> &getSecondaryOutputLocations() const
    217    {
    218        return mSecondaryOutputLocations;
    219    }
    220    const std::vector<LinkedUniform> &getUniforms() const { return mUniforms; }
    221    const std::vector<InterfaceBlock> &getUniformBlocks() const { return mUniformBlocks; }
    222    const UniformBlockBindingMask &getActiveUniformBlockBindings() const
    223    {
    224        return mActiveUniformBlockBindings;
    225    }
    226    const std::vector<SamplerBinding> &getSamplerBindings() const { return mSamplerBindings; }
    227    const std::vector<ImageBinding> &getImageBindings() const { return mImageBindings; }
    228    std::vector<ImageBinding> *getImageBindings() { return &mImageBindings; }
    229    const RangeUI &getDefaultUniformRange() const { return mDefaultUniformRange; }
    230    const RangeUI &getSamplerUniformRange() const { return mSamplerUniformRange; }
    231    const RangeUI &getImageUniformRange() const { return mImageUniformRange; }
    232    const RangeUI &getAtomicCounterUniformRange() const { return mAtomicCounterUniformRange; }
    233    const RangeUI &getFragmentInoutRange() const { return mFragmentInoutRange; }
    234    bool hasDiscard() const { return mHasDiscard; }
    235    bool enablesPerSampleShading() const { return mEnablesPerSampleShading; }
    236    BlendEquationBitSet getAdvancedBlendEquations() const { return mAdvancedBlendEquations; }
    237    const std::vector<TransformFeedbackVarying> &getLinkedTransformFeedbackVaryings() const
    238    {
    239        return mLinkedTransformFeedbackVaryings;
    240    }
    241    GLint getTransformFeedbackBufferMode() const { return mTransformFeedbackBufferMode; }
    242    GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const
    243    {
    244        ASSERT(uniformBlockIndex < mUniformBlocks.size());
    245        return mUniformBlocks[uniformBlockIndex].binding;
    246    }
    247    GLuint getShaderStorageBlockBinding(GLuint blockIndex) const
    248    {
    249        ASSERT(blockIndex < mShaderStorageBlocks.size());
    250        return mShaderStorageBlocks[blockIndex].binding;
    251    }
    252    const std::vector<GLsizei> &getTransformFeedbackStrides() const
    253    {
    254        return mTransformFeedbackStrides;
    255    }
    256    const std::vector<AtomicCounterBuffer> &getAtomicCounterBuffers() const
    257    {
    258        return mAtomicCounterBuffers;
    259    }
    260    const std::vector<InterfaceBlock> &getShaderStorageBlocks() const
    261    {
    262        return mShaderStorageBlocks;
    263    }
    264    const LinkedUniform &getUniformByIndex(GLuint index) const
    265    {
    266        ASSERT(index < static_cast<size_t>(mUniforms.size()));
    267        return mUniforms[index];
    268    }
    269 
    270    ANGLE_INLINE GLuint getActiveUniformBlockCount() const
    271    {
    272        return static_cast<GLuint>(mUniformBlocks.size());
    273    }
    274 
    275    ANGLE_INLINE GLuint getActiveAtomicCounterBufferCount() const
    276    {
    277        return static_cast<GLuint>(mAtomicCounterBuffers.size());
    278    }
    279 
    280    ANGLE_INLINE GLuint getActiveShaderStorageBlockCount() const
    281    {
    282        size_t shaderStorageBlocksSize = mShaderStorageBlocks.size();
    283        return static_cast<GLuint>(shaderStorageBlocksSize);
    284    }
    285 
    286    GLuint getUniformIndexFromImageIndex(GLuint imageIndex) const;
    287 
    288    GLuint getUniformIndexFromSamplerIndex(GLuint samplerIndex) const;
    289 
    290    void saveLinkedStateInfo(const Context *context, const ProgramState &state);
    291    const std::vector<sh::ShaderVariable> &getLinkedOutputVaryings(ShaderType shaderType) const
    292    {
    293        return mLinkedOutputVaryings[shaderType];
    294    }
    295    const std::vector<sh::ShaderVariable> &getLinkedInputVaryings(ShaderType shaderType) const
    296    {
    297        return mLinkedInputVaryings[shaderType];
    298    }
    299 
    300    const std::vector<sh::ShaderVariable> &getLinkedUniforms(ShaderType shaderType) const
    301    {
    302        return mLinkedUniforms[shaderType];
    303    }
    304 
    305    const std::vector<sh::InterfaceBlock> &getLinkedUniformBlocks(ShaderType shaderType) const
    306    {
    307        return mLinkedUniformBlocks[shaderType];
    308    }
    309 
    310    int getLinkedShaderVersion(ShaderType shaderType) const
    311    {
    312        return mLinkedShaderVersions[shaderType];
    313    }
    314 
    315    bool isYUVOutput() const;
    316 
    317    PrimitiveMode getGeometryShaderInputPrimitiveType() const
    318    {
    319        return mGeometryShaderInputPrimitiveType;
    320    }
    321 
    322    PrimitiveMode getGeometryShaderOutputPrimitiveType() const
    323    {
    324        return mGeometryShaderOutputPrimitiveType;
    325    }
    326 
    327    int getGeometryShaderInvocations() const { return mGeometryShaderInvocations; }
    328 
    329    int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; }
    330 
    331    GLenum getTessGenMode() const { return mTessGenMode; }
    332 
    333    void resetCachedValidateSamplersResult() { mCachedValidateSamplersResult.reset(); }
    334    bool validateSamplers(InfoLog *infoLog, const Caps &caps) const
    335    {
    336        // Use the cache if:
    337        // - we aren't using an info log (which gives the full error).
    338        // - The sample mapping hasn't changed and we've already validated.
    339        if (infoLog == nullptr && mCachedValidateSamplersResult.valid())
    340        {
    341            return mCachedValidateSamplersResult.value();
    342        }
    343 
    344        return validateSamplersImpl(infoLog, caps);
    345    }
    346 
    347    ComponentTypeMask getFragmentOutputsTypeMask() const { return mDrawBufferTypeMask; }
    348    DrawBufferMask getActiveOutputVariablesMask() const { return mActiveOutputVariablesMask; }
    349 
    350    bool linkUniforms(const Context *context,
    351                      const ShaderMap<std::vector<sh::ShaderVariable>> &shaderUniforms,
    352                      InfoLog &infoLog,
    353                      const ProgramAliasedBindings &uniformLocationBindings,
    354                      GLuint *combinedImageUniformsCount,
    355                      std::vector<UnusedUniform> *unusedUniforms,
    356                      std::vector<VariableLocation> *uniformLocationsOutOrNull);
    357 
    358    void copyInputsFromProgram(const ProgramState &programState);
    359    void copyShaderBuffersFromProgram(const ProgramState &programState, ShaderType shaderType);
    360    void clearSamplerBindings();
    361    void copySamplerBindingsFromProgram(const ProgramState &programState);
    362    void copyImageBindingsFromProgram(const ProgramState &programState);
    363    void copyOutputsFromProgram(const ProgramState &programState);
    364    void copyUniformsFromProgramMap(const ShaderMap<Program *> &programs);
    365 
    366  private:
    367    friend class Program;
    368    friend class ProgramPipeline;
    369    friend class ProgramState;
    370 
    371    void updateActiveImages(const ProgramExecutable &executable);
    372 
    373    // Scans the sampler bindings for type conflicts with sampler 'textureUnitIndex'.
    374    void setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex,
    375                                               std::vector<SamplerBinding> &samplerBindings);
    376 
    377    bool linkMergedVaryings(const Context *context,
    378                            const ProgramMergedVaryings &mergedVaryings,
    379                            const std::vector<std::string> &transformFeedbackVaryingNames,
    380                            const LinkingVariables &linkingVariables,
    381                            bool isSeparable,
    382                            ProgramVaryingPacking *varyingPacking);
    383 
    384    bool linkValidateTransformFeedback(
    385        const Context *context,
    386        const ProgramMergedVaryings &varyings,
    387        ShaderType stage,
    388        const std::vector<std::string> &transformFeedbackVaryingNames);
    389 
    390    void gatherTransformFeedbackVaryings(
    391        const ProgramMergedVaryings &varyings,
    392        ShaderType stage,
    393        const std::vector<std::string> &transformFeedbackVaryingNames);
    394 
    395    void updateTransformFeedbackStrides();
    396 
    397    bool validateSamplersImpl(InfoLog *infoLog, const Caps &caps) const;
    398 
    399    bool linkValidateOutputVariables(const Caps &caps,
    400                                     const Extensions &extensions,
    401                                     const Version &version,
    402                                     GLuint combinedImageUniformsCount,
    403                                     GLuint combinedShaderStorageBlocksCount,
    404                                     const std::vector<sh::ShaderVariable> &outputVariables,
    405                                     int fragmentShaderVersion,
    406                                     const ProgramAliasedBindings &fragmentOutputLocations,
    407                                     const ProgramAliasedBindings &fragmentOutputIndices);
    408 
    409    void linkSamplerAndImageBindings(GLuint *combinedImageUniformsCount);
    410    bool linkAtomicCounterBuffers(const Context *context, InfoLog &infoLog);
    411 
    412    InfoLog mInfoLog;
    413 
    414    ShaderBitSet mLinkedShaderStages;
    415 
    416    angle::BitSet<MAX_VERTEX_ATTRIBS> mActiveAttribLocationsMask;
    417    unsigned int mMaxActiveAttribLocation;
    418    ComponentTypeMask mAttributesTypeMask;
    419    // mAttributesMask is identical to mActiveAttribLocationsMask with built-in attributes removed.
    420    AttributesMask mAttributesMask;
    421 
    422    // Cached mask of active samplers and sampler types.
    423    ActiveTextureMask mActiveSamplersMask;
    424    ActiveTextureArray<uint32_t> mActiveSamplerRefCounts;
    425    ActiveTextureArray<TextureType> mActiveSamplerTypes;
    426    ActiveTextureMask mActiveSamplerYUV;
    427    ActiveTextureArray<SamplerFormat> mActiveSamplerFormats;
    428    ActiveTextureArray<ShaderBitSet> mActiveSamplerShaderBits;
    429 
    430    // Cached mask of active images.
    431    ActiveTextureMask mActiveImagesMask;
    432    ActiveTextureArray<ShaderBitSet> mActiveImageShaderBits;
    433 
    434    bool mCanDrawWith;
    435 
    436    // Names and mapped names of output variables that are arrays include [0] in the end, similarly
    437    // to uniforms.
    438    std::vector<sh::ShaderVariable> mOutputVariables;
    439    std::vector<VariableLocation> mOutputLocations;
    440    DrawBufferMask mActiveOutputVariablesMask;
    441    // EXT_blend_func_extended secondary outputs (ones with index 1)
    442    std::vector<VariableLocation> mSecondaryOutputLocations;
    443    bool mYUVOutput;
    444    // Vertex attributes, Fragment input varyings, etc.
    445    std::vector<sh::ShaderVariable> mProgramInputs;
    446    std::vector<TransformFeedbackVarying> mLinkedTransformFeedbackVaryings;
    447    // The size of the data written to each transform feedback buffer per vertex.
    448    std::vector<GLsizei> mTransformFeedbackStrides;
    449    GLenum mTransformFeedbackBufferMode;
    450    // Uniforms are sorted in order:
    451    //  1. Non-opaque uniforms
    452    //  2. Sampler uniforms
    453    //  3. Image uniforms
    454    //  4. Atomic counter uniforms
    455    //  5. Subpass Input uniforms (Only for Vulkan)
    456    //  6. Uniform block uniforms
    457    // This makes opaque uniform validation easier, since we don't need a separate list.
    458    // For generating the entries and naming them we follow the spec: GLES 3.1 November 2016 section
    459    // 7.3.1.1 Naming Active Resources. There's a separate entry for each struct member and each
    460    // inner array of an array of arrays. Names and mapped names of uniforms that are arrays include
    461    // [0] in the end. This makes implementation of queries simpler.
    462    std::vector<LinkedUniform> mUniforms;
    463    RangeUI mDefaultUniformRange;
    464    RangeUI mSamplerUniformRange;
    465    RangeUI mImageUniformRange;
    466    RangeUI mAtomicCounterUniformRange;
    467    std::vector<InterfaceBlock> mUniformBlocks;
    468 
    469    // For faster iteration on the blocks currently being bound.
    470    UniformBlockBindingMask mActiveUniformBlockBindings;
    471 
    472    std::vector<AtomicCounterBuffer> mAtomicCounterBuffers;
    473    std::vector<InterfaceBlock> mShaderStorageBlocks;
    474 
    475    RangeUI mFragmentInoutRange;
    476    bool mHasDiscard;
    477    bool mEnablesPerSampleShading;
    478 
    479    // KHR_blend_equation_advanced supported equation list
    480    BlendEquationBitSet mAdvancedBlendEquations;
    481 
    482    // An array of the samplers that are used by the program
    483    std::vector<SamplerBinding> mSamplerBindings;
    484 
    485    // An array of the images that are used by the program
    486    std::vector<ImageBinding> mImageBindings;
    487 
    488    ShaderMap<std::vector<sh::ShaderVariable>> mLinkedOutputVaryings;
    489    ShaderMap<std::vector<sh::ShaderVariable>> mLinkedInputVaryings;
    490    ShaderMap<std::vector<sh::ShaderVariable>> mLinkedUniforms;
    491    ShaderMap<std::vector<sh::InterfaceBlock>> mLinkedUniformBlocks;
    492 
    493    ShaderMap<int> mLinkedShaderVersions;
    494 
    495    // GL_EXT_geometry_shader.
    496    PrimitiveMode mGeometryShaderInputPrimitiveType;
    497    PrimitiveMode mGeometryShaderOutputPrimitiveType;
    498    int mGeometryShaderInvocations;
    499    int mGeometryShaderMaxVertices;
    500 
    501    // GL_EXT_tessellation_shader
    502    int mTessControlShaderVertices;
    503    GLenum mTessGenMode;
    504    GLenum mTessGenSpacing;
    505    GLenum mTessGenVertexOrder;
    506    GLenum mTessGenPointMode;
    507 
    508    // Fragment output variable base types: FLOAT, INT, or UINT.  Ordered by location.
    509    std::vector<GLenum> mOutputVariableTypes;
    510    ComponentTypeMask mDrawBufferTypeMask;
    511 
    512    // Cache for sampler validation
    513    mutable Optional<bool> mCachedValidateSamplersResult;
    514 };
    515 }  // namespace gl
    516 
    517 #endif  // LIBANGLE_PROGRAMEXECUTABLE_H_