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