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