• 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.reset(nullptr);
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 
updateUsesEarlyFragmentTestsOptimization()370 void ProgramPipeline::updateUsesEarlyFragmentTestsOptimization()
371 {
372     Program *fragmentProgram = getShaderProgram(gl::ShaderType::Fragment);
373 
374     if (!fragmentProgram)
375     {
376         return;
377     }
378 
379     const ProgramExecutable &fragmentExecutable = fragmentProgram->getExecutable();
380     mState.mExecutable->mUsesEarlyFragmentTestsOptimization =
381         fragmentExecutable.mUsesEarlyFragmentTestsOptimization;
382 }
383 
updateLinkedVaryings()384 void ProgramPipeline::updateLinkedVaryings()
385 {
386     // Need to check all of the shader stages, not just linked, so we handle Compute correctly.
387     for (const gl::ShaderType shaderType : kAllGraphicsShaderTypes)
388     {
389         const Program *shaderProgram = getShaderProgram(shaderType);
390         if (shaderProgram && shaderProgram->isLinked())
391         {
392             const ProgramExecutable &executable = shaderProgram->getExecutable();
393             mState.mExecutable->mLinkedOutputVaryings[shaderType] =
394                 executable.getLinkedOutputVaryings(shaderType);
395             mState.mExecutable->mLinkedInputVaryings[shaderType] =
396                 executable.getLinkedInputVaryings(shaderType);
397         }
398     }
399 
400     const Program *computeProgram = getShaderProgram(ShaderType::Compute);
401     if (computeProgram && computeProgram->isLinked())
402     {
403         const ProgramExecutable &executable = computeProgram->getExecutable();
404         mState.mExecutable->mLinkedOutputVaryings[ShaderType::Compute] =
405             executable.getLinkedOutputVaryings(ShaderType::Compute);
406         mState.mExecutable->mLinkedInputVaryings[ShaderType::Compute] =
407             executable.getLinkedInputVaryings(ShaderType::Compute);
408     }
409 }
410 
updateExecutable()411 void ProgramPipeline::updateExecutable()
412 {
413     // Vertex Shader ProgramExecutable properties
414     updateExecutableAttributes();
415     updateTransformFeedbackMembers();
416     updateShaderStorageBlocks();
417     updateImageBindings();
418 
419     // Geometry Shader ProgramExecutable properties
420     updateExecutableGeometryProperties();
421 
422     // Tessellation Shaders ProgramExecutable properties
423     updateExecutableTessellationProperties();
424 
425     // Fragment Shader ProgramExecutable properties
426     updateFragmentInoutRange();
427     updateUsesEarlyFragmentTestsOptimization();
428 
429     // All Shader ProgramExecutable properties
430     mState.updateExecutableTextures();
431     updateLinkedVaryings();
432 }
433 
434 // The attached shaders are checked for linking errors by matching up their variables.
435 // Uniform, input and output variables get collected.
436 // The code gets compiled into binaries.
link(const Context * context)437 angle::Result ProgramPipeline::link(const Context *context)
438 {
439     if (mState.mIsLinked)
440     {
441         return angle::Result::Continue;
442     }
443 
444     ProgramMergedVaryings mergedVaryings;
445     ProgramVaryingPacking varyingPacking;
446     LinkingVariables linkingVariables(mState);
447 
448     mState.mExecutable->reset();
449 
450     InfoLog &infoLog = mState.mExecutable->getInfoLog();
451     infoLog.reset();
452 
453     // Build shader variable uniforms map for gl::UniformLinker.
454     ShaderMap<std::vector<sh::ShaderVariable>> shaderUniforms;
455     for (ShaderType shaderType : mState.mExecutable->mLinkedShaderStages)
456     {
457         for (const LinkedUniform &uniform : mState.mPrograms[shaderType]->getUniforms())
458         {
459             shaderUniforms[shaderType].push_back(uniform);
460         }
461     }
462 
463     if (mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Vertex))
464     {
465         if (!linkVaryings(infoLog))
466         {
467             return angle::Result::Stop;
468         }
469 
470         if (!LinkValidateProgramGlobalNames(infoLog, getExecutable(), linkingVariables))
471         {
472             return angle::Result::Stop;
473         }
474 
475         Program *fragmentShaderProgram = getShaderProgram(ShaderType::Fragment);
476         if (fragmentShaderProgram)
477         {
478             // We should also be validating SSBO and image uniform counts.
479             const GLuint combinedImageUniforms          = 0;
480             const GLuint combinedShaderStorageBlocks    = 0;
481             const ProgramExecutable &fragmentExecutable = fragmentShaderProgram->getExecutable();
482             if (!mState.mExecutable->linkValidateOutputVariables(
483                     context->getCaps(), context->getExtensions(), context->getClientVersion(),
484                     combinedImageUniforms, combinedShaderStorageBlocks,
485                     fragmentExecutable.getOutputVariables(),
486                     fragmentExecutable.getLinkedShaderVersion(ShaderType::Fragment),
487                     ProgramAliasedBindings(), ProgramAliasedBindings()))
488             {
489                 return angle::Result::Continue;
490             }
491         }
492         mergedVaryings = GetMergedVaryingsFromLinkingVariables(linkingVariables);
493         // If separable program objects are in use, the set of attributes captured is taken
494         // from the program object active on the last vertex processing stage.
495         ShaderType lastVertexProcessingStage =
496             gl::GetLastPreFragmentStage(getExecutable().getLinkedShaderStages());
497         if (lastVertexProcessingStage == ShaderType::InvalidEnum)
498         {
499             //  If there is no active program for the vertex or fragment shader stages, the results
500             //  of vertex and fragment shader execution will respectively be undefined. However,
501             //  this is not an error.
502             return angle::Result::Continue;
503         }
504 
505         Program *tfProgram = getShaderProgram(lastVertexProcessingStage);
506         ASSERT(tfProgram);
507 
508         if (!tfProgram)
509         {
510             tfProgram = mState.mPrograms[ShaderType::Vertex];
511         }
512 
513         const std::vector<std::string> &transformFeedbackVaryingNames =
514             tfProgram->getState().getTransformFeedbackVaryingNames();
515 
516         if (!mState.mExecutable->linkMergedVaryings(context, mergedVaryings,
517                                                     transformFeedbackVaryingNames, linkingVariables,
518                                                     false, &varyingPacking))
519         {
520             return angle::Result::Stop;
521         }
522     }
523 
524     // Merge uniforms.
525     mState.mExecutable->copyUniformsFromProgramMap(mState.mPrograms);
526 
527     if (mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Vertex))
528     {
529         const ProgramState &programState = mState.mPrograms[gl::ShaderType::Vertex]->getState();
530         mState.mExecutable->copyInputsFromProgram(programState);
531     }
532 
533     // Merge shader buffers (UBOs, SSBOs, and atomic counter buffers) into the executable.
534     // Also copy over image and sampler bindings.
535     for (ShaderType shaderType : mState.mExecutable->getLinkedShaderStages())
536     {
537         const ProgramState &programState = mState.mPrograms[shaderType]->getState();
538         mState.mExecutable->copyShaderBuffersFromProgram(programState, shaderType);
539         mState.mExecutable->copySamplerBindingsFromProgram(programState);
540         mState.mExecutable->copyImageBindingsFromProgram(programState);
541     }
542 
543     if (mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Fragment))
544     {
545         const ProgramState &programState = mState.mPrograms[gl::ShaderType::Fragment]->getState();
546         mState.mExecutable->copyOutputsFromProgram(programState);
547     }
548 
549     if (mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Vertex) ||
550         mState.mExecutable->hasLinkedShaderStage(gl::ShaderType::Compute))
551     {
552         ANGLE_TRY(getImplementation()->link(context, mergedVaryings, varyingPacking));
553     }
554 
555     mState.mExecutable->mActiveSamplerRefCounts.fill(0);
556     updateExecutable();
557 
558     mState.mIsLinked = true;
559     onStateChange(angle::SubjectMessage::SubjectChanged);
560 
561     return angle::Result::Continue;
562 }
563 
linkVaryings(InfoLog & infoLog) const564 bool ProgramPipeline::linkVaryings(InfoLog &infoLog) const
565 {
566     ShaderType previousShaderType = ShaderType::InvalidEnum;
567     for (ShaderType shaderType : kAllGraphicsShaderTypes)
568     {
569         Program *program = getShaderProgram(shaderType);
570         if (!program)
571         {
572             continue;
573         }
574         ProgramExecutable &executable = program->getExecutable();
575 
576         if (previousShaderType != ShaderType::InvalidEnum)
577         {
578             Program *previousProgram = getShaderProgram(previousShaderType);
579             ASSERT(previousProgram);
580             const ProgramExecutable &previousExecutable = previousProgram->getExecutable();
581 
582             if (!LinkValidateShaderInterfaceMatching(
583                     previousExecutable.getLinkedOutputVaryings(previousShaderType),
584                     executable.getLinkedInputVaryings(shaderType), previousShaderType, shaderType,
585                     previousExecutable.getLinkedShaderVersion(previousShaderType),
586                     executable.getLinkedShaderVersion(shaderType), true, infoLog))
587             {
588                 return false;
589             }
590         }
591         previousShaderType = shaderType;
592     }
593 
594     // TODO: http://anglebug.com/3571 and http://anglebug.com/3572
595     // Need to move logic of validating builtin varyings inside the for-loop above.
596     // This is because the built-in symbols `gl_ClipDistance` and `gl_CullDistance`
597     // can be redeclared in Geometry or Tessellation shaders as well.
598     Program *vertexProgram   = mState.mPrograms[ShaderType::Vertex];
599     Program *fragmentProgram = mState.mPrograms[ShaderType::Fragment];
600     if (!vertexProgram || !fragmentProgram)
601     {
602         return true;
603     }
604     ProgramExecutable &vertexExecutable   = vertexProgram->getExecutable();
605     ProgramExecutable &fragmentExecutable = fragmentProgram->getExecutable();
606     return LinkValidateBuiltInVaryings(
607         vertexExecutable.getLinkedOutputVaryings(ShaderType::Vertex),
608         fragmentExecutable.getLinkedInputVaryings(ShaderType::Fragment), ShaderType::Vertex,
609         ShaderType::Fragment, vertexExecutable.getLinkedShaderVersion(ShaderType::Vertex),
610         fragmentExecutable.getLinkedShaderVersion(ShaderType::Fragment), infoLog);
611 }
612 
validate(const gl::Context * context)613 void ProgramPipeline::validate(const gl::Context *context)
614 {
615     const Caps &caps = context->getCaps();
616     mState.mValid    = true;
617     InfoLog &infoLog = mState.mExecutable->getInfoLog();
618     infoLog.reset();
619 
620     for (const ShaderType shaderType : mState.mExecutable->getLinkedShaderStages())
621     {
622         Program *shaderProgram = mState.mPrograms[shaderType];
623         if (shaderProgram)
624         {
625             shaderProgram->resolveLink(context);
626             shaderProgram->validate(caps);
627             std::string shaderInfoString = shaderProgram->getExecutable().getInfoLogString();
628             if (shaderInfoString.length())
629             {
630                 mState.mValid = false;
631                 infoLog << shaderInfoString << "\n";
632                 return;
633             }
634             if (!shaderProgram->isSeparable())
635             {
636                 mState.mValid = false;
637                 infoLog << GetShaderTypeString(shaderType) << " is not marked separable."
638                         << "\n";
639                 return;
640             }
641         }
642     }
643 
644     intptr_t drawStatesError = context->getStateCache().getBasicDrawStatesError(context);
645     if (drawStatesError)
646     {
647         mState.mValid            = false;
648         const char *errorMessage = reinterpret_cast<const char *>(drawStatesError);
649         infoLog << errorMessage << "\n";
650         return;
651     }
652 
653     if (!linkVaryings(infoLog))
654     {
655         mState.mValid = false;
656 
657         for (const ShaderType shaderType : mState.mExecutable->getLinkedShaderStages())
658         {
659             Program *shaderProgram = mState.mPrograms[shaderType];
660             ASSERT(shaderProgram);
661             shaderProgram->validate(caps);
662             std::string shaderInfoString = shaderProgram->getExecutable().getInfoLogString();
663             if (shaderInfoString.length())
664             {
665                 infoLog << shaderInfoString << "\n";
666             }
667         }
668     }
669 }
670 
onSubjectStateChange(angle::SubjectIndex index,angle::SubjectMessage message)671 void ProgramPipeline::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
672 {
673     switch (message)
674     {
675         case angle::SubjectMessage::ProgramTextureOrImageBindingChanged:
676             mState.mExecutable->mActiveSamplerRefCounts.fill(0);
677             mState.updateExecutableTextures();
678             break;
679 
680         case angle::SubjectMessage::ProgramRelinked:
681             mState.mIsLinked = false;
682             onStateChange(angle::SubjectMessage::ProgramRelinked);
683             break;
684         case angle::SubjectMessage::SamplerUniformsUpdated:
685             mState.mExecutable->clearSamplerBindings();
686             for (ShaderType shaderType : mState.mExecutable->getLinkedShaderStages())
687             {
688                 const ProgramState &programState = mState.mPrograms[shaderType]->getState();
689                 mState.mExecutable->copySamplerBindingsFromProgram(programState);
690             }
691             mState.mExecutable->mActiveSamplerRefCounts.fill(0);
692             mState.updateExecutableTextures();
693             break;
694         case angle::SubjectMessage::ProgramUniformUpdated:
695             mProgramPipelineImpl->onProgramUniformUpdate(static_cast<ShaderType>(index));
696             break;
697         default:
698             UNREACHABLE();
699             break;
700     }
701 }
702 }  // namespace gl
703