ProgramPipeline.h (5439B)
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.h: Defines 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 #ifndef LIBANGLE_PROGRAMPIPELINE_H_ 12 #define LIBANGLE_PROGRAMPIPELINE_H_ 13 14 #include <memory> 15 16 #include "common/angleutils.h" 17 #include "libANGLE/Debug.h" 18 #include "libANGLE/Program.h" 19 #include "libANGLE/ProgramExecutable.h" 20 #include "libANGLE/RefCountObject.h" 21 22 namespace rx 23 { 24 class GLImplFactory; 25 class ProgramPipelineImpl; 26 } // namespace rx 27 28 namespace gl 29 { 30 class Context; 31 class ProgramPipeline; 32 33 class ProgramPipelineState final : angle::NonCopyable 34 { 35 public: 36 ProgramPipelineState(); 37 ~ProgramPipelineState(); 38 39 const std::string &getLabel() const; 40 41 ProgramExecutable &getExecutable() const 42 { 43 ASSERT(mExecutable); 44 return *mExecutable; 45 } 46 47 void activeShaderProgram(Program *shaderProgram); 48 void useProgramStages(const Context *context, 49 const gl::ShaderBitSet &shaderTypes, 50 Program *shaderProgram, 51 std::vector<angle::ObserverBinding> *programObserverBindings); 52 53 Program *getActiveShaderProgram() { return mActiveShaderProgram; } 54 55 GLboolean isValid() const { return mValid; } 56 57 const Program *getShaderProgram(ShaderType shaderType) const { return mPrograms[shaderType]; } 58 59 bool usesShaderProgram(ShaderProgramID program) const; 60 61 void updateExecutableTextures(); 62 63 rx::SpecConstUsageBits getSpecConstUsageBits() const; 64 65 private: 66 void useProgramStage(const Context *context, 67 ShaderType shaderType, 68 Program *shaderProgram, 69 angle::ObserverBinding *programObserverBindings); 70 71 friend class ProgramPipeline; 72 73 std::string mLabel; 74 75 // The active shader program 76 Program *mActiveShaderProgram; 77 // The shader programs for each stage. 78 ShaderMap<Program *> mPrograms; 79 80 GLboolean mValid; 81 82 ProgramExecutable *mExecutable; 83 84 bool mIsLinked; 85 }; 86 87 class ProgramPipeline final : public RefCountObject<ProgramPipelineID>, 88 public LabeledObject, 89 public angle::ObserverInterface, 90 public angle::Subject 91 { 92 public: 93 ProgramPipeline(rx::GLImplFactory *factory, ProgramPipelineID handle); 94 ~ProgramPipeline() override; 95 96 void onDestroy(const Context *context) override; 97 98 angle::Result setLabel(const Context *context, const std::string &label) override; 99 const std::string &getLabel() const override; 100 101 const ProgramPipelineState &getState() const { return mState; } 102 ProgramPipelineState &getState() { return mState; } 103 104 ProgramExecutable &getExecutable() const { return mState.getExecutable(); } 105 106 rx::ProgramPipelineImpl *getImplementation() const; 107 108 Program *getActiveShaderProgram() { return mState.getActiveShaderProgram(); } 109 void activeShaderProgram(Program *shaderProgram); 110 Program *getLinkedActiveShaderProgram(const Context *context) 111 { 112 Program *program = mState.getActiveShaderProgram(); 113 if (program) 114 { 115 program->resolveLink(context); 116 } 117 return program; 118 } 119 120 angle::Result useProgramStages(const Context *context, 121 GLbitfield stages, 122 Program *shaderProgram); 123 124 Program *getShaderProgram(ShaderType shaderType) const { return mState.mPrograms[shaderType]; } 125 126 void resetIsLinked() { mState.mIsLinked = false; } 127 angle::Result link(const gl::Context *context); 128 129 // Ensure program pipeline is linked. Inlined to make sure its overhead is as low as possible. 130 void resolveLink(const Context *context) 131 { 132 if (mState.mIsLinked) 133 { 134 // Already linked, nothing to do. 135 return; 136 } 137 138 angle::Result linkResult = link(context); 139 if (linkResult != angle::Result::Continue) 140 { 141 // If the link failed then log a warning, swallow the error and move on. 142 WARN() << "ProgramPipeline link failed" << std::endl; 143 } 144 return; 145 } 146 147 void validate(const gl::Context *context); 148 GLboolean isValid() const { return mState.isValid(); } 149 bool isLinked() const { return mState.mIsLinked; } 150 151 // ObserverInterface implementation. 152 void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 153 154 private: 155 bool linkVaryings(InfoLog &infoLog) const; 156 void updateLinkedShaderStages(); 157 void updateExecutableAttributes(); 158 void updateTransformFeedbackMembers(); 159 void updateShaderStorageBlocks(); 160 void updateImageBindings(); 161 void updateExecutableGeometryProperties(); 162 void updateExecutableTessellationProperties(); 163 void updateFragmentInoutRangeAndEnablesPerSampleShading(); 164 void updateLinkedVaryings(); 165 void updateExecutable(); 166 167 std::unique_ptr<rx::ProgramPipelineImpl> mProgramPipelineImpl; 168 169 ProgramPipelineState mState; 170 171 std::vector<angle::ObserverBinding> mProgramObserverBindings; 172 angle::ObserverBinding mExecutableObserverBinding; 173 }; 174 } // namespace gl 175 176 #endif // LIBANGLE_PROGRAMPIPELINE_H_