tor-browser

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

ProgramPipeline.cpp (25779B)


      1 //
      2 // Copyright 2017 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 // ProgramPipeline.cpp: Implements the gl::ProgramPipeline class.
      8 // Implements GL program pipeline objects and related functionality.
      9 // [OpenGL ES 3.1] section 7.4 page 105.
     10 
     11 #include "libANGLE/ProgramPipeline.h"
     12 
     13 #include <algorithm>
     14 
     15 #include "libANGLE/Context.h"
     16 #include "libANGLE/Program.h"
     17 #include "libANGLE/angletypes.h"
     18 #include "libANGLE/renderer/GLImplFactory.h"
     19 #include "libANGLE/renderer/ProgramPipelineImpl.h"
     20 
     21 namespace gl
     22 {
     23 
     24 enum SubjectIndexes : angle::SubjectIndex
     25 {
     26    kExecutableSubjectIndex = 0
     27 };
     28 
     29 ProgramPipelineState::ProgramPipelineState()
     30    : mLabel(),
     31      mActiveShaderProgram(nullptr),
     32      mValid(false),
     33      mExecutable(new ProgramExecutable()),
     34      mIsLinked(false)
     35 {
     36    for (const ShaderType shaderType : gl::AllShaderTypes())
     37    {
     38        mPrograms[shaderType] = nullptr;
     39    }
     40 }
     41 
     42 ProgramPipelineState::~ProgramPipelineState()
     43 {
     44    SafeDelete(mExecutable);
     45 }
     46 
     47 const std::string &ProgramPipelineState::getLabel() const
     48 {
     49    return mLabel;
     50 }
     51 
     52 void ProgramPipelineState::activeShaderProgram(Program *shaderProgram)
     53 {
     54    mActiveShaderProgram = shaderProgram;
     55 }
     56 
     57 void ProgramPipelineState::useProgramStage(const Context *context,
     58                                           const ShaderType shaderType,
     59                                           Program *shaderProgram,
     60                                           angle::ObserverBinding *programObserverBindings)
     61 {
     62    Program *oldProgram = mPrograms[shaderType];
     63    if (oldProgram)
     64    {
     65        oldProgram->release(context);
     66    }
     67 
     68    // If program refers to a program object with a valid shader attached for the indicated shader
     69    // stage, glUseProgramStages installs the executable code for that stage in the indicated
     70    // program pipeline object pipeline.
     71    if (shaderProgram && (shaderProgram->id().value != 0) &&
     72        shaderProgram->getExecutable().hasLinkedShaderStage(shaderType))
     73    {
     74        mPrograms[shaderType] = shaderProgram;
     75        shaderProgram->addRef();
     76    }
     77    else
     78    {
     79        // If program is zero, or refers to a program object with no valid shader executable for the
     80        // given stage, it is as if the pipeline object has no programmable stage configured for the
     81        // indicated shader stage.
     82        mPrograms[shaderType] = nullptr;
     83    }
     84 
     85    Program *program = mPrograms[shaderType];
     86    programObserverBindings->bind(program);
     87 }
     88 
     89 void ProgramPipelineState::useProgramStages(
     90    const Context *context,
     91    const gl::ShaderBitSet &shaderTypes,
     92    Program *shaderProgram,
     93    std::vector<angle::ObserverBinding> *programObserverBindings)
     94 {
     95    for (ShaderType shaderType : shaderTypes)
     96    {
     97        useProgramStage(context, shaderType, shaderProgram,
     98                        &programObserverBindings->at(static_cast<size_t>(shaderType)));
     99    }
    100 }
    101 
    102 bool ProgramPipelineState::usesShaderProgram(ShaderProgramID programId) const
    103 {
    104    for (const Program *program : mPrograms)
    105    {
    106        if (program && (program->id() == programId))
    107        {
    108            return true;
    109        }
    110    }
    111 
    112    return false;
    113 }
    114 
    115 void ProgramPipelineState::updateExecutableTextures()
    116 {
    117    for (const ShaderType shaderType : mExecutable->getLinkedShaderStages())
    118    {
    119        const Program *program = getShaderProgram(shaderType);
    120        ASSERT(program);
    121        mExecutable->setActiveTextureMask(mExecutable->getActiveSamplersMask() |
    122                                          program->getExecutable().getActiveSamplersMask());
    123        mExecutable->setActiveImagesMask(mExecutable->getActiveImagesMask() |
    124                                         program->getExecutable().getActiveImagesMask());
    125        // Updates mActiveSamplerRefCounts, mActiveSamplerTypes, and mActiveSamplerFormats
    126        mExecutable->updateActiveSamplers(program->getState());
    127    }
    128 }
    129 
    130 rx::SpecConstUsageBits ProgramPipelineState::getSpecConstUsageBits() const
    131 {
    132    rx::SpecConstUsageBits specConstUsageBits;
    133    for (const ShaderType shaderType : mExecutable->getLinkedShaderStages())
    134    {
    135        const Program *program = getShaderProgram(shaderType);
    136        ASSERT(program);
    137        specConstUsageBits |= program->getState().getSpecConstUsageBits();
    138    }
    139    return specConstUsageBits;
    140 }
    141 
    142 ProgramPipeline::ProgramPipeline(rx::GLImplFactory *factory, ProgramPipelineID handle)
    143    : RefCountObject(factory->generateSerial(), handle),
    144      mProgramPipelineImpl(factory->createProgramPipeline(mState)),
    145      mExecutableObserverBinding(this, kExecutableSubjectIndex)
    146 {
    147    ASSERT(mProgramPipelineImpl);
    148 
    149    for (const ShaderType shaderType : gl::AllShaderTypes())
    150    {
    151        mProgramObserverBindings.emplace_back(this, static_cast<angle::SubjectIndex>(shaderType));
    152    }
    153    mExecutableObserverBinding.bind(mState.mExecutable);
    154 }
    155 
    156 ProgramPipeline::~ProgramPipeline()
    157 {
    158    mProgramPipelineImpl.reset(nullptr);
    159 }
    160 
    161 void ProgramPipeline::onDestroy(const Context *context)
    162 {
    163    for (Program *program : mState.mPrograms)
    164    {
    165        if (program)
    166        {
    167            ASSERT(program->getRefCount());
    168            program->release(context);
    169        }
    170    }
    171 
    172    getImplementation()->destroy(context);
    173 }
    174 
    175 angle::Result ProgramPipeline::setLabel(const Context *context, const std::string &label)
    176 {
    177    mState.mLabel = label;
    178 
    179    if (mProgramPipelineImpl)
    180    {
    181        return mProgramPipelineImpl->onLabelUpdate(context);
    182    }
    183    return angle::Result::Continue;
    184 }
    185 
    186 const std::string &ProgramPipeline::getLabel() const
    187 {
    188    return mState.mLabel;
    189 }
    190 
    191 rx::ProgramPipelineImpl *ProgramPipeline::getImplementation() const
    192 {
    193    return mProgramPipelineImpl.get();
    194 }
    195 
    196 void ProgramPipeline::activeShaderProgram(Program *shaderProgram)
    197 {
    198    mState.activeShaderProgram(shaderProgram);
    199 }
    200 
    201 angle::Result ProgramPipeline::useProgramStages(const Context *context,
    202                                                GLbitfield stages,
    203                                                Program *shaderProgram)
    204 {
    205    bool needToUpdatePipelineState = false;
    206    gl::ShaderBitSet shaderTypes;
    207    if (stages != GL_ALL_SHADER_BITS)
    208    {
    209        ASSERT(stages < 256u);
    210        for (size_t singleShaderBit : angle::BitSet<8>(stages))
    211        {
    212            // Cast back to a bit after the iterator returns an index.
    213            ShaderType shaderType = GetShaderTypeFromBitfield(angle::Bit<size_t>(singleShaderBit));
    214            ASSERT(shaderType != ShaderType::InvalidEnum);
    215            shaderTypes.set(shaderType);
    216        }
    217    }
    218    else
    219    {
    220        shaderTypes.set();
    221    }
    222    ASSERT(shaderTypes.any());
    223 
    224    for (ShaderType shaderType : shaderTypes)
    225    {
    226        if (mState.getShaderProgram(shaderType) != shaderProgram ||
    227            (shaderProgram && shaderProgram->hasAnyDirtyBit()))
    228        {
    229            needToUpdatePipelineState = true;
    230            break;
    231        }
    232    }
    233 
    234    if (!needToUpdatePipelineState)
    235    {
    236        return angle::Result::Continue;
    237    }
    238 
    239    mState.useProgramStages(context, shaderTypes, shaderProgram, &mProgramObserverBindings);
    240    updateLinkedShaderStages();
    241 
    242    mState.mIsLinked = false;
    243    onStateChange(angle::SubjectMessage::SubjectChanged);
    244 
    245    return angle::Result::Continue;
    246 }
    247 
    248 void ProgramPipeline::updateLinkedShaderStages()
    249 {
    250    mState.mExecutable->resetLinkedShaderStages();
    251 
    252    for (const ShaderType shaderType : gl::AllShaderTypes())
    253    {
    254        Program *program = mState.mPrograms[shaderType];
    255        if (program)
    256        {
    257            mState.mExecutable->setLinkedShaderStages(shaderType);
    258        }
    259    }
    260 
    261    mState.mExecutable->updateCanDrawWith();
    262 }
    263 
    264 void ProgramPipeline::updateExecutableAttributes()
    265 {
    266    Program *vertexProgram = getShaderProgram(gl::ShaderType::Vertex);
    267 
    268    if (!vertexProgram)
    269    {
    270        return;
    271    }
    272 
    273    const ProgramExecutable &vertexExecutable      = vertexProgram->getExecutable();
    274    mState.mExecutable->mActiveAttribLocationsMask = vertexExecutable.mActiveAttribLocationsMask;
    275    mState.mExecutable->mMaxActiveAttribLocation   = vertexExecutable.mMaxActiveAttribLocation;
    276    mState.mExecutable->mAttributesTypeMask        = vertexExecutable.mAttributesTypeMask;
    277    mState.mExecutable->mAttributesMask            = vertexExecutable.mAttributesMask;
    278    mState.mExecutable->mProgramInputs             = vertexExecutable.mProgramInputs;
    279 }
    280 
    281 void ProgramPipeline::updateTransformFeedbackMembers()
    282 {
    283    ShaderType lastVertexProcessingStage =
    284        gl::GetLastPreFragmentStage(getExecutable().getLinkedShaderStages());
    285    if (lastVertexProcessingStage == ShaderType::InvalidEnum)
    286    {
    287        return;
    288    }
    289 
    290    Program *shaderProgram = getShaderProgram(lastVertexProcessingStage);
    291    ASSERT(shaderProgram);
    292 
    293    const ProgramExecutable &lastPreFragmentExecutable = shaderProgram->getExecutable();
    294    mState.mExecutable->mTransformFeedbackStrides =
    295        lastPreFragmentExecutable.mTransformFeedbackStrides;
    296    mState.mExecutable->mLinkedTransformFeedbackVaryings =
    297        lastPreFragmentExecutable.mLinkedTransformFeedbackVaryings;
    298 }
    299 
    300 void ProgramPipeline::updateShaderStorageBlocks()
    301 {
    302    mState.mExecutable->mShaderStorageBlocks.clear();
    303 
    304    // Only copy the storage blocks from each Program in the PPO once, since each Program could
    305    // contain multiple shader stages.
    306    ShaderBitSet handledStages;
    307 
    308    for (const gl::ShaderType shaderType : gl::AllShaderTypes())
    309    {
    310        const Program *shaderProgram = getShaderProgram(shaderType);
    311        if (shaderProgram && !handledStages.test(shaderType))
    312        {
    313            // Only add each Program's blocks once.
    314            handledStages |= shaderProgram->getExecutable().getLinkedShaderStages();
    315 
    316            for (const InterfaceBlock &block :
    317                 shaderProgram->getExecutable().getShaderStorageBlocks())
    318            {
    319                mState.mExecutable->mShaderStorageBlocks.emplace_back(block);
    320            }
    321        }
    322    }
    323 }
    324 
    325 void ProgramPipeline::updateImageBindings()
    326 {
    327    mState.mExecutable->mImageBindings.clear();
    328    mState.mExecutable->mActiveImageShaderBits.fill({});
    329 
    330    // Only copy the storage blocks from each Program in the PPO once, since each Program could
    331    // contain multiple shader stages.
    332    ShaderBitSet handledStages;
    333 
    334    for (const gl::ShaderType shaderType : gl::AllShaderTypes())
    335    {
    336        const Program *shaderProgram = getShaderProgram(shaderType);
    337        if (shaderProgram && !handledStages.test(shaderType))
    338        {
    339            // Only add each Program's blocks once.
    340            handledStages |= shaderProgram->getExecutable().getLinkedShaderStages();
    341 
    342            for (const ImageBinding &imageBinding : shaderProgram->getState().getImageBindings())
    343            {
    344                mState.mExecutable->mImageBindings.emplace_back(imageBinding);
    345            }
    346 
    347            mState.mExecutable->updateActiveImages(shaderProgram->getExecutable());
    348        }
    349    }
    350 }
    351 
    352 void ProgramPipeline::updateExecutableGeometryProperties()
    353 {
    354    Program *geometryProgram = getShaderProgram(gl::ShaderType::Geometry);
    355 
    356    if (!geometryProgram)
    357    {
    358        return;
    359    }
    360 
    361    const ProgramExecutable &geometryExecutable = geometryProgram->getExecutable();
    362    mState.mExecutable->mGeometryShaderInputPrimitiveType =
    363        geometryExecutable.mGeometryShaderInputPrimitiveType;
    364    mState.mExecutable->mGeometryShaderOutputPrimitiveType =
    365        geometryExecutable.mGeometryShaderOutputPrimitiveType;
    366    mState.mExecutable->mGeometryShaderInvocations = geometryExecutable.mGeometryShaderInvocations;
    367    mState.mExecutable->mGeometryShaderMaxVertices = geometryExecutable.mGeometryShaderMaxVertices;
    368 }
    369 
    370 void ProgramPipeline::updateExecutableTessellationProperties()
    371 {
    372    Program *tessControlProgram = getShaderProgram(gl::ShaderType::TessControl);
    373    Program *tessEvalProgram    = getShaderProgram(gl::ShaderType::TessEvaluation);
    374 
    375    if (tessControlProgram)
    376    {
    377        const ProgramExecutable &tessControlExecutable = tessControlProgram->getExecutable();
    378        mState.mExecutable->mTessControlShaderVertices =
    379            tessControlExecutable.mTessControlShaderVertices;
    380    }
    381 
    382    if (tessEvalProgram)
    383    {
    384        const ProgramExecutable &tessEvalExecutable = tessEvalProgram->getExecutable();
    385        mState.mExecutable->mTessGenMode            = tessEvalExecutable.mTessGenMode;
    386        mState.mExecutable->mTessGenSpacing         = tessEvalExecutable.mTessGenSpacing;
    387        mState.mExecutable->mTessGenVertexOrder     = tessEvalExecutable.mTessGenVertexOrder;
    388        mState.mExecutable->mTessGenPointMode       = tessEvalExecutable.mTessGenPointMode;
    389    }
    390 }
    391 
    392 void ProgramPipeline::updateFragmentInoutRangeAndEnablesPerSampleShading()
    393 {
    394    Program *fragmentProgram = getShaderProgram(gl::ShaderType::Fragment);
    395 
    396    if (!fragmentProgram)
    397    {
    398        return;
    399    }
    400 
    401    const ProgramExecutable &fragmentExecutable  = fragmentProgram->getExecutable();
    402    mState.mExecutable->mFragmentInoutRange      = fragmentExecutable.mFragmentInoutRange;
    403    mState.mExecutable->mHasDiscard              = fragmentExecutable.mHasDiscard;
    404    mState.mExecutable->mEnablesPerSampleShading = fragmentExecutable.mEnablesPerSampleShading;
    405 }
    406 
    407 void ProgramPipeline::updateLinkedVaryings()
    408 {
    409    // Need to check all of the shader stages, not just linked, so we handle Compute correctly.
    410    for (const gl::ShaderType shaderType : kAllGraphicsShaderTypes)
    411    {
    412        const Program *shaderProgram = getShaderProgram(shaderType);
    413        if (shaderProgram && shaderProgram->isLinked())
    414        {
    415            const ProgramExecutable &executable = shaderProgram->getExecutable();
    416            mState.mExecutable->mLinkedOutputVaryings[shaderType] =
    417                executable.getLinkedOutputVaryings(shaderType);
    418            mState.mExecutable->mLinkedInputVaryings[shaderType] =
    419                executable.getLinkedInputVaryings(shaderType);
    420        }
    421    }
    422 
    423    const Program *computeProgram = getShaderProgram(ShaderType::Compute);
    424    if (computeProgram && computeProgram->isLinked())
    425    {
    426        const ProgramExecutable &executable = computeProgram->getExecutable();
    427        mState.mExecutable->mLinkedOutputVaryings[ShaderType::Compute] =
    428            executable.getLinkedOutputVaryings(ShaderType::Compute);
    429        mState.mExecutable->mLinkedInputVaryings[ShaderType::Compute] =
    430            executable.getLinkedInputVaryings(ShaderType::Compute);
    431    }
    432 }
    433 
    434 void ProgramPipeline::updateExecutable()
    435 {
    436    // Vertex Shader ProgramExecutable properties
    437    updateExecutableAttributes();
    438    updateTransformFeedbackMembers();
    439    updateShaderStorageBlocks();
    440    updateImageBindings();
    441 
    442    // Geometry Shader ProgramExecutable properties
    443    updateExecutableGeometryProperties();
    444 
    445    // Tessellation Shaders ProgramExecutable properties
    446    updateExecutableTessellationProperties();
    447 
    448    // Fragment Shader ProgramExecutable properties
    449    updateFragmentInoutRangeAndEnablesPerSampleShading();
    450 
    451    // All Shader ProgramExecutable properties
    452    mState.updateExecutableTextures();
    453    updateLinkedVaryings();
    454 }
    455 
    456 // The attached shaders are checked for linking errors by matching up their variables.
    457 // Uniform, input and output variables get collected.
    458 // The code gets compiled into binaries.
    459 angle::Result ProgramPipeline::link(const Context *context)
    460 {
    461    ASSERT(!mState.mIsLinked);
    462 
    463    ProgramMergedVaryings mergedVaryings;
    464    ProgramVaryingPacking varyingPacking;
    465    LinkingVariables linkingVariables(mState);
    466 
    467    mState.mExecutable->reset(true);
    468 
    469    InfoLog &infoLog = mState.mExecutable->getInfoLog();
    470    infoLog.reset();
    471 
    472    // Build shader variable uniforms map for gl::UniformLinker.
    473    ShaderMap<std::vector<sh::ShaderVariable>> shaderUniforms;
    474    for (ShaderType shaderType : mState.mExecutable->mLinkedShaderStages)
    475    {
    476        for (const LinkedUniform &uniform : mState.mPrograms[shaderType]->getUniforms())
    477        {
    478            shaderUniforms[shaderType].push_back(uniform);
    479        }
    480    }
    481 
    482    if (mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Vertex))
    483    {
    484        if (!linkVaryings(infoLog))
    485        {
    486            return angle::Result::Stop;
    487        }
    488 
    489        if (!LinkValidateProgramGlobalNames(infoLog, getExecutable(), linkingVariables))
    490        {
    491            return angle::Result::Stop;
    492        }
    493 
    494        Program *fragmentShaderProgram = getShaderProgram(ShaderType::Fragment);
    495        if (fragmentShaderProgram)
    496        {
    497            // We should also be validating SSBO and image uniform counts.
    498            const GLuint combinedImageUniforms          = 0;
    499            const GLuint combinedShaderStorageBlocks    = 0;
    500            const ProgramExecutable &fragmentExecutable = fragmentShaderProgram->getExecutable();
    501            if (!mState.mExecutable->linkValidateOutputVariables(
    502                    context->getCaps(), context->getExtensions(), context->getClientVersion(),
    503                    combinedImageUniforms, combinedShaderStorageBlocks,
    504                    fragmentExecutable.getOutputVariables(),
    505                    fragmentExecutable.getLinkedShaderVersion(ShaderType::Fragment),
    506                    ProgramAliasedBindings(), ProgramAliasedBindings()))
    507            {
    508                return angle::Result::Continue;
    509            }
    510        }
    511        mergedVaryings = GetMergedVaryingsFromLinkingVariables(linkingVariables);
    512        // If separable program objects are in use, the set of attributes captured is taken
    513        // from the program object active on the last vertex processing stage.
    514        ShaderType lastVertexProcessingStage =
    515            gl::GetLastPreFragmentStage(getExecutable().getLinkedShaderStages());
    516        if (lastVertexProcessingStage == ShaderType::InvalidEnum)
    517        {
    518            //  If there is no active program for the vertex or fragment shader stages, the results
    519            //  of vertex and fragment shader execution will respectively be undefined. However,
    520            //  this is not an error.
    521            return angle::Result::Continue;
    522        }
    523 
    524        Program *tfProgram = getShaderProgram(lastVertexProcessingStage);
    525        ASSERT(tfProgram);
    526 
    527        if (!tfProgram)
    528        {
    529            tfProgram = mState.mPrograms[ShaderType::Vertex];
    530        }
    531 
    532        const std::vector<std::string> &transformFeedbackVaryingNames =
    533            tfProgram->getState().getTransformFeedbackVaryingNames();
    534 
    535        if (!mState.mExecutable->linkMergedVaryings(context, mergedVaryings,
    536                                                    transformFeedbackVaryingNames, linkingVariables,
    537                                                    false, &varyingPacking))
    538        {
    539            return angle::Result::Stop;
    540        }
    541    }
    542 
    543    // Merge uniforms.
    544    mState.mExecutable->copyUniformsFromProgramMap(mState.mPrograms);
    545 
    546    if (mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Vertex))
    547    {
    548        const ProgramState &programState = mState.mPrograms[gl::ShaderType::Vertex]->getState();
    549        mState.mExecutable->copyInputsFromProgram(programState);
    550    }
    551 
    552    // Merge shader buffers (UBOs, SSBOs, and atomic counter buffers) into the executable.
    553    // Also copy over image and sampler bindings.
    554    for (ShaderType shaderType : mState.mExecutable->getLinkedShaderStages())
    555    {
    556        const ProgramState &programState = mState.mPrograms[shaderType]->getState();
    557        mState.mExecutable->copyShaderBuffersFromProgram(programState, shaderType);
    558        mState.mExecutable->copySamplerBindingsFromProgram(programState);
    559        mState.mExecutable->copyImageBindingsFromProgram(programState);
    560    }
    561 
    562    if (mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Fragment))
    563    {
    564        const ProgramState &programState = mState.mPrograms[gl::ShaderType::Fragment]->getState();
    565        mState.mExecutable->copyOutputsFromProgram(programState);
    566    }
    567 
    568    if (mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Vertex) ||
    569        mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Compute))
    570    {
    571        ANGLE_TRY(getImplementation()->link(context, mergedVaryings, varyingPacking));
    572    }
    573 
    574    mState.mExecutable->mActiveSamplerRefCounts.fill(0);
    575    updateExecutable();
    576 
    577    mState.mIsLinked = true;
    578    onStateChange(angle::SubjectMessage::SubjectChanged);
    579 
    580    return angle::Result::Continue;
    581 }
    582 
    583 bool ProgramPipeline::linkVaryings(InfoLog &infoLog) const
    584 {
    585    ShaderType previousShaderType = ShaderType::InvalidEnum;
    586    for (ShaderType shaderType : kAllGraphicsShaderTypes)
    587    {
    588        Program *program = getShaderProgram(shaderType);
    589        if (!program)
    590        {
    591            continue;
    592        }
    593        ProgramExecutable &executable = program->getExecutable();
    594 
    595        if (previousShaderType != ShaderType::InvalidEnum)
    596        {
    597            Program *previousProgram = getShaderProgram(previousShaderType);
    598            ASSERT(previousProgram);
    599            const ProgramExecutable &previousExecutable = previousProgram->getExecutable();
    600 
    601            if (!LinkValidateShaderInterfaceMatching(
    602                    previousExecutable.getLinkedOutputVaryings(previousShaderType),
    603                    executable.getLinkedInputVaryings(shaderType), previousShaderType, shaderType,
    604                    previousExecutable.getLinkedShaderVersion(previousShaderType),
    605                    executable.getLinkedShaderVersion(shaderType), true, infoLog))
    606            {
    607                return false;
    608            }
    609        }
    610        previousShaderType = shaderType;
    611    }
    612 
    613    // TODO: http://anglebug.com/3571 and http://anglebug.com/3572
    614    // Need to move logic of validating builtin varyings inside the for-loop above.
    615    // This is because the built-in symbols `gl_ClipDistance` and `gl_CullDistance`
    616    // can be redeclared in Geometry or Tessellation shaders as well.
    617    Program *vertexProgram   = mState.mPrograms[ShaderType::Vertex];
    618    Program *fragmentProgram = mState.mPrograms[ShaderType::Fragment];
    619    if (!vertexProgram || !fragmentProgram)
    620    {
    621        return true;
    622    }
    623    ProgramExecutable &vertexExecutable   = vertexProgram->getExecutable();
    624    ProgramExecutable &fragmentExecutable = fragmentProgram->getExecutable();
    625    return LinkValidateBuiltInVaryings(
    626        vertexExecutable.getLinkedOutputVaryings(ShaderType::Vertex),
    627        fragmentExecutable.getLinkedInputVaryings(ShaderType::Fragment), ShaderType::Vertex,
    628        ShaderType::Fragment, vertexExecutable.getLinkedShaderVersion(ShaderType::Vertex),
    629        fragmentExecutable.getLinkedShaderVersion(ShaderType::Fragment), infoLog);
    630 }
    631 
    632 void ProgramPipeline::validate(const gl::Context *context)
    633 {
    634    const Caps &caps = context->getCaps();
    635    mState.mValid    = true;
    636    InfoLog &infoLog = mState.mExecutable->getInfoLog();
    637    infoLog.reset();
    638 
    639    for (const ShaderType shaderType : mState.mExecutable->getLinkedShaderStages())
    640    {
    641        Program *shaderProgram = mState.mPrograms[shaderType];
    642        if (shaderProgram)
    643        {
    644            shaderProgram->resolveLink(context);
    645            shaderProgram->validate(caps);
    646            std::string shaderInfoString = shaderProgram->getExecutable().getInfoLogString();
    647            if (shaderInfoString.length())
    648            {
    649                mState.mValid = false;
    650                infoLog << shaderInfoString << "\n";
    651                return;
    652            }
    653            if (!shaderProgram->isSeparable())
    654            {
    655                mState.mValid = false;
    656                infoLog << GetShaderTypeString(shaderType) << " is not marked separable."
    657                        << "\n";
    658                return;
    659            }
    660        }
    661    }
    662 
    663    intptr_t programPipelineError = context->getStateCache().getProgramPipelineError(context);
    664    if (programPipelineError)
    665    {
    666        mState.mValid            = false;
    667        const char *errorMessage = reinterpret_cast<const char *>(programPipelineError);
    668        infoLog << errorMessage << "\n";
    669        return;
    670    }
    671 
    672    if (!linkVaryings(infoLog))
    673    {
    674        mState.mValid = false;
    675 
    676        for (const ShaderType shaderType : mState.mExecutable->getLinkedShaderStages())
    677        {
    678            Program *shaderProgram = mState.mPrograms[shaderType];
    679            ASSERT(shaderProgram);
    680            shaderProgram->validate(caps);
    681            std::string shaderInfoString = shaderProgram->getExecutable().getInfoLogString();
    682            if (shaderInfoString.length())
    683            {
    684                infoLog << shaderInfoString << "\n";
    685            }
    686        }
    687    }
    688 }
    689 
    690 void ProgramPipeline::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
    691 {
    692    switch (message)
    693    {
    694        case angle::SubjectMessage::ProgramTextureOrImageBindingChanged:
    695            mState.mExecutable->mActiveSamplerRefCounts.fill(0);
    696            mState.updateExecutableTextures();
    697            break;
    698 
    699        case angle::SubjectMessage::ProgramRelinked:
    700            mState.mIsLinked = false;
    701            onStateChange(angle::SubjectMessage::ProgramRelinked);
    702            break;
    703        case angle::SubjectMessage::SamplerUniformsUpdated:
    704            mState.mExecutable->clearSamplerBindings();
    705            for (ShaderType shaderType : mState.mExecutable->getLinkedShaderStages())
    706            {
    707                const ProgramState &programState = mState.mPrograms[shaderType]->getState();
    708                mState.mExecutable->copySamplerBindingsFromProgram(programState);
    709            }
    710            mState.mExecutable->mActiveSamplerRefCounts.fill(0);
    711            mState.updateExecutableTextures();
    712            break;
    713        case angle::SubjectMessage::ProgramUniformUpdated:
    714            mProgramPipelineImpl->onProgramUniformUpdate(static_cast<ShaderType>(index));
    715            break;
    716        default:
    717            UNREACHABLE();
    718            break;
    719    }
    720 }
    721 }  // namespace gl