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