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