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 getExecutable()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 getActiveShaderProgram()53 Program *getActiveShaderProgram() { return mActiveShaderProgram; } 54 isValid()55 GLboolean isValid() const { return mValid; } 56 getShaderProgram(ShaderType shaderType)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 getState()101 const ProgramPipelineState &getState() const { return mState; } getState()102 ProgramPipelineState &getState() { return mState; } 103 getExecutable()104 ProgramExecutable &getExecutable() const { return mState.getExecutable(); } 105 106 rx::ProgramPipelineImpl *getImplementation() const; 107 getActiveShaderProgram()108 Program *getActiveShaderProgram() { return mState.getActiveShaderProgram(); } 109 void activeShaderProgram(Program *shaderProgram); getLinkedActiveShaderProgram(const Context * context)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 getShaderProgram(ShaderType shaderType)124 Program *getShaderProgram(ShaderType shaderType) const { return mState.mPrograms[shaderType]; } 125 resetIsLinked()126 void resetIsLinked() { mState.mIsLinked = false; } 127 angle::Result link(const gl::Context *context); 128 129 angle::Result syncState(const Context *context); 130 131 // Ensure program pipeline is linked. Inlined to make sure its overhead is as low as possible. resolveLink(const Context * context)132 void resolveLink(const Context *context) 133 { 134 if (mState.mIsLinked) 135 { 136 // Already linked, nothing to do. 137 return; 138 } 139 140 angle::Result linkResult = link(context); 141 if (linkResult != angle::Result::Continue) 142 { 143 // If the link failed then log a warning, swallow the error and move on. 144 WARN() << "ProgramPipeline link failed" << std::endl; 145 } 146 return; 147 } 148 149 void validate(const gl::Context *context); isValid()150 GLboolean isValid() const { return mState.isValid(); } isLinked()151 bool isLinked() const { return mState.mIsLinked; } 152 153 void onUniformBufferStateChange(size_t uniformBufferIndex); 154 // ObserverInterface implementation. 155 void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 156 157 private: 158 bool linkVaryings(InfoLog &infoLog) const; 159 void updateLinkedShaderStages(); 160 void updateExecutableAttributes(); 161 void updateTransformFeedbackMembers(); 162 void updateShaderStorageBlocks(); 163 void updateImageBindings(); 164 void updateExecutableGeometryProperties(); 165 void updateExecutableTessellationProperties(); 166 void updateFragmentInoutRangeAndEnablesPerSampleShading(); 167 void updateLinkedVaryings(); 168 void updateExecutable(); 169 170 std::unique_ptr<rx::ProgramPipelineImpl> mProgramPipelineImpl; 171 172 ProgramPipelineState mState; 173 174 std::vector<angle::ObserverBinding> mProgramObserverBindings; 175 angle::ObserverBinding mExecutableObserverBinding; 176 }; 177 } // namespace gl 178 179 #endif // LIBANGLE_PROGRAMPIPELINE_H_ 180