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