xref: /aosp_15_r20/external/angle/src/libANGLE/ProgramPipeline.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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(rx::GLImplFactory *factory);
37     ~ProgramPipelineState();
38 
39     const std::string &getLabel() const;
40 
getExecutable()41     ProgramExecutable &getExecutable() const
42     {
43         ASSERT(mExecutable);
44         return *mExecutable;
45     }
46 
getSharedExecutable()47     const SharedProgramExecutable &getSharedExecutable() const
48     {
49         ASSERT(mExecutable);
50         return mExecutable;
51     }
52 
53     void activeShaderProgram(Program *shaderProgram);
54     void useProgramStages(const Context *context,
55                           const gl::ShaderBitSet &shaderTypes,
56                           Program *shaderProgram,
57                           std::vector<angle::ObserverBinding> *programObserverBindings,
58                           std::vector<angle::ObserverBinding> *programExecutableObserverBindings);
59 
getActiveShaderProgram()60     Program *getActiveShaderProgram() { return mActiveShaderProgram; }
61 
isValid()62     GLboolean isValid() const { return mValid; }
63 
getShaderProgram(ShaderType shaderType)64     const Program *getShaderProgram(ShaderType shaderType) const { return mPrograms[shaderType]; }
getShaderProgramExecutable(ShaderType shaderType)65     const SharedProgramExecutable &getShaderProgramExecutable(ShaderType shaderType) const
66     {
67         return mExecutable->mPPOProgramExecutables[shaderType];
68     }
69 
70     bool usesShaderProgram(ShaderProgramID program) const;
71 
72     void updateExecutableTextures();
73 
74     void updateExecutableSpecConstUsageBits();
75 
76   private:
77     SharedProgramExecutable makeNewExecutable(
78         rx::GLImplFactory *factory,
79         ShaderMap<SharedProgramExecutable> &&ppoProgramExecutables);
80     void useProgramStage(const Context *context,
81                          ShaderType shaderType,
82                          Program *shaderProgram,
83                          angle::ObserverBinding *programObserverBinding,
84                          angle::ObserverBinding *programExecutableObserverBinding);
85     void destroyDiscardedExecutables(const Context *context);
86 
87     friend class ProgramPipeline;
88 
89     std::string mLabel;
90 
91     // The active shader program
92     Program *mActiveShaderProgram;
93     // The shader programs for each stage.
94     ShaderMap<Program *> mPrograms;
95 
96     // Mapping from program's UBOs into the program executable's UBOs.
97     ShaderMap<ProgramUniformBlockArray<GLuint>> mUniformBlockMap;
98 
99     // A list of executables to be garbage collected.  This is populated as the pipeline is
100     // notified about program relinks, but cannot immediately destroy the old executables due to
101     // lack of access to context.
102     std::vector<SharedProgramExecutable> mProgramExecutablesToDiscard;
103 
104     GLboolean mValid;
105 
106     InfoLog mInfoLog;
107 
108     SharedProgramExecutable mExecutable;
109 
110     bool mIsLinked;
111 };
112 
113 class ProgramPipeline final : public RefCountObject<ProgramPipelineID>,
114                               public LabeledObject,
115                               public angle::ObserverInterface,
116                               public angle::Subject
117 {
118   public:
119     ProgramPipeline(rx::GLImplFactory *factory, ProgramPipelineID handle);
120     ~ProgramPipeline() override;
121 
122     void onDestroy(const Context *context) override;
123 
124     angle::Result setLabel(const Context *context, const std::string &label) override;
125     const std::string &getLabel() const override;
126 
getState()127     const ProgramPipelineState &getState() const { return mState; }
getState()128     ProgramPipelineState &getState() { return mState; }
129 
getExecutable()130     ProgramExecutable &getExecutable() const { return mState.getExecutable(); }
getSharedExecutable()131     const SharedProgramExecutable &getSharedExecutable() const
132     {
133         return mState.getSharedExecutable();
134     }
135 
136     rx::ProgramPipelineImpl *getImplementation() const;
137 
getActiveShaderProgram()138     Program *getActiveShaderProgram() { return mState.getActiveShaderProgram(); }
139     void activeShaderProgram(Program *shaderProgram);
getLinkedActiveShaderProgram(const Context * context)140     Program *getLinkedActiveShaderProgram(const Context *context)
141     {
142         Program *program = mState.getActiveShaderProgram();
143         if (program)
144         {
145             program->resolveLink(context);
146         }
147         return program;
148     }
149 
150     angle::Result useProgramStages(const Context *context,
151                                    GLbitfield stages,
152                                    Program *shaderProgram);
153 
getShaderProgram(ShaderType shaderType)154     const Program *getShaderProgram(ShaderType shaderType) const
155     {
156         return mState.getShaderProgram(shaderType);
157     }
getShaderProgramExecutable(ShaderType shaderType)158     const SharedProgramExecutable &getShaderProgramExecutable(ShaderType shaderType) const
159     {
160         return mState.getShaderProgramExecutable(shaderType);
161     }
162 
resetIsLinked()163     void resetIsLinked() { mState.mIsLinked = false; }
164     angle::Result link(const gl::Context *context);
165 
getInfoLog()166     InfoLog &getInfoLog() { return mState.mInfoLog; }
167     int getInfoLogLength() const;
168     void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const;
169 
170     // Ensure program pipeline is linked. Inlined to make sure its overhead is as low as possible.
resolveLink(const Context * context)171     void resolveLink(const Context *context)
172     {
173         if (mState.mIsLinked)
174         {
175             // Already linked, nothing to do.
176             return;
177         }
178 
179         resolveAttachedPrograms(context);
180         angle::Result linkResult = link(context);
181         if (linkResult != angle::Result::Continue)
182         {
183             // If the link failed then log a warning, swallow the error and move on.
184             WARN() << "ProgramPipeline link failed" << std::endl;
185         }
186         return;
187     }
188     void resolveAttachedPrograms(const Context *context);
189 
190     void validate(const gl::Context *context);
isValid()191     GLboolean isValid() const { return mState.isValid(); }
isLinked()192     bool isLinked() const { return mState.mIsLinked; }
193 
194     // ObserverInterface implementation.
195     void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
196 
197   private:
198     bool linkVaryings();
199     void updateLinkedShaderStages();
200     void updateExecutableAttributes();
201     void updateTransformFeedbackMembers();
202     void updateShaderStorageBlocks();
203     void updateImageBindings();
204     void updateExecutableGeometryProperties();
205     void updateExecutableTessellationProperties();
206     void updateFragmentInoutRangeAndEnablesPerSampleShading();
207     void updateLinkedVaryings();
208     void updateExecutable();
209 
210     std::unique_ptr<rx::ProgramPipelineImpl> mProgramPipelineImpl;
211 
212     ProgramPipelineState mState;
213 
214     std::vector<angle::ObserverBinding> mProgramObserverBindings;
215     std::vector<angle::ObserverBinding> mProgramExecutableObserverBindings;
216 };
217 }  // namespace gl
218 
219 #endif  // LIBANGLE_PROGRAMPIPELINE_H_
220