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 // A PPO can have both graphics and compute programs attached, so 42 // we don't know if the PPO is a 'graphics' or 'compute' PPO until the 43 // actual draw/dispatch call. isCompute()44 bool isCompute() const { return mIsCompute; } setIsCompute(bool isCompute)45 void setIsCompute(bool isCompute) { mIsCompute = isCompute; } 46 getProgramExecutable()47 const ProgramExecutable &getProgramExecutable() const 48 { 49 ASSERT(mExecutable); 50 return *mExecutable; 51 } getProgramExecutable()52 ProgramExecutable &getProgramExecutable() 53 { 54 ASSERT(mExecutable); 55 return *mExecutable; 56 } 57 58 void activeShaderProgram(Program *shaderProgram); 59 void useProgramStages(const Context *context, GLbitfield stages, Program *shaderProgram); 60 getActiveShaderProgram()61 Program *getActiveShaderProgram() { return mActiveShaderProgram; } 62 isValid()63 GLboolean isValid() const { return mValid; } 64 getShaderProgram(ShaderType shaderType)65 const Program *getShaderProgram(ShaderType shaderType) const { return mPrograms[shaderType]; } 66 67 bool usesShaderProgram(ShaderProgramID program) const; 68 69 bool hasDefaultUniforms() const; 70 bool hasTextures() const; 71 bool hasImages() const; 72 73 private: 74 void useProgramStage(const Context *context, ShaderType shaderType, Program *shaderProgram); 75 76 friend class ProgramPipeline; 77 78 std::string mLabel; 79 80 bool mIsCompute; 81 82 // The active shader program 83 Program *mActiveShaderProgram; 84 // The shader programs for each stage. 85 ShaderMap<Program *> mPrograms; 86 87 GLboolean mValid; 88 89 GLboolean mHasBeenBound; 90 91 ProgramExecutable *mExecutable; 92 }; 93 94 class ProgramPipeline final : public RefCountObject<ProgramPipelineID>, public LabeledObject 95 { 96 public: 97 ProgramPipeline(rx::GLImplFactory *factory, ProgramPipelineID handle); 98 ~ProgramPipeline() override; 99 100 void onDestroy(const Context *context) override; 101 102 void setLabel(const Context *context, const std::string &label) override; 103 const std::string &getLabel() const override; 104 getState()105 const ProgramPipelineState &getState() const { return mState; } 106 getExecutable()107 const ProgramExecutable &getExecutable() const { return mState.getProgramExecutable(); } getExecutable()108 ProgramExecutable &getExecutable() { return mState.getProgramExecutable(); } 109 110 rx::ProgramPipelineImpl *getImplementation() const; 111 getActiveShaderProgram()112 Program *getActiveShaderProgram() { return mState.getActiveShaderProgram(); } 113 void activeShaderProgram(Program *shaderProgram); getLinkedActiveShaderProgram(const Context * context)114 Program *getLinkedActiveShaderProgram(const Context *context) 115 { 116 Program *program = mState.getActiveShaderProgram(); 117 if (program) 118 { 119 program->resolveLink(context); 120 } 121 return program; 122 } 123 124 void useProgramStages(const Context *context, GLbitfield stages, Program *shaderProgram); 125 getShaderProgram(ShaderType shaderType)126 Program *getShaderProgram(ShaderType shaderType) const { return mState.mPrograms[shaderType]; } 127 128 ProgramMergedVaryings getMergedVaryings() const; 129 angle::Result link(const gl::Context *context); 130 bool linkVaryings(InfoLog &infoLog) const; 131 void validate(const gl::Context *context); 132 bool validateSamplers(InfoLog *infoLog, const Caps &caps); 133 usesShaderProgram(ShaderProgramID program)134 bool usesShaderProgram(ShaderProgramID program) const 135 { 136 return mState.usesShaderProgram(program); 137 } 138 hasAnyDirtyBit()139 bool hasAnyDirtyBit() const { return mDirtyBits.any(); } 140 isValid()141 GLboolean isValid() const { return mState.isValid(); } 142 bind()143 void bind() { mState.mHasBeenBound = true; } hasBeenBound()144 GLboolean hasBeenBound() const { return mState.mHasBeenBound; } 145 146 // Program pipeline dirty bits. 147 enum DirtyBitType 148 { 149 // One of the program stages in the PPO changed. 150 DIRTY_BIT_PROGRAM_STAGE, 151 DIRTY_BIT_DRAW_DISPATCH_CHANGE, 152 153 DIRTY_BIT_COUNT = DIRTY_BIT_DRAW_DISPATCH_CHANGE + 1, 154 }; 155 156 using DirtyBits = angle::BitSet<DIRTY_BIT_COUNT>; 157 158 angle::Result syncState(const Context *context); setDirtyBit(DirtyBitType dirtyBitType)159 void setDirtyBit(DirtyBitType dirtyBitType) { mDirtyBits.set(dirtyBitType); } 160 161 private: 162 void updateLinkedShaderStages(); 163 void updateExecutableAttributes(); 164 void updateTransformFeedbackMembers(); 165 void updateExecutableTextures(); 166 void updateHasBuffers(); 167 void updateExecutable(); 168 169 std::unique_ptr<rx::ProgramPipelineImpl> mProgramPipelineImpl; 170 171 ProgramPipelineState mState; 172 173 DirtyBits mDirtyBits; 174 }; 175 } // namespace gl 176 177 #endif // LIBANGLE_PROGRAMPIPELINE_H_ 178