xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/ProgramImpl.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2014 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 // ProgramImpl.h: Defines the abstract rx::ProgramImpl class.
8 
9 #ifndef LIBANGLE_RENDERER_PROGRAMIMPL_H_
10 #define LIBANGLE_RENDERER_PROGRAMIMPL_H_
11 
12 #include "common/BinaryStream.h"
13 #include "common/WorkerThread.h"
14 #include "common/angleutils.h"
15 #include "libANGLE/Constants.h"
16 #include "libANGLE/Program.h"
17 #include "libANGLE/Shader.h"
18 
19 #include <functional>
20 #include <map>
21 
22 namespace gl
23 {
24 class Context;
25 struct ProgramLinkedResources;
26 }  // namespace gl
27 
28 namespace sh
29 {
30 struct BlockMemberInfo;
31 }
32 
33 namespace rx
34 {
35 // The link job is split as such:
36 //
37 // - Front-end link
38 // - Back-end link
39 // - Independent back-end link subtasks (typically native driver compile jobs)
40 // - Post-link finalization
41 //
42 // Each step depends on the previous.  These steps are executed as such:
43 //
44 // 1. Program::link calls into ProgramImpl::link
45 //   - ProgramImpl::link runs whatever needs the Context, such as releasing resources
46 //   - ProgramImpl::link returns a LinkTask
47 // 2. Program::link implements a closure that calls the front-end link and passes the results to
48 //    the backend's LinkTask.
49 // 3. The LinkTask potentially returns a set of LinkSubTasks to be scheduled by the worker pool
50 // 4. Once the link is resolved, the post-link finalization is run
51 //
52 // In the above, steps 1 and 4 are done under the share group lock.  Steps 2 and 3 can be done in
53 // threads or without holding the share group lock if the backend supports it.
54 class LinkSubTask : public angle::Closure
55 {
56   public:
57     ~LinkSubTask() override                                                           = default;
58     virtual angle::Result getResult(const gl::Context *context, gl::InfoLog &infoLog) = 0;
59 };
60 class LinkTask
61 {
62   public:
63     virtual ~LinkTask() = default;
64     // Used for link()
65     // Backends should populate only one of linkSubTasksOut or postLinkSubTasksOut.
66     virtual void link(const gl::ProgramLinkedResources &resources,
67                       const gl::ProgramMergedVaryings &mergedVaryings,
68                       std::vector<std::shared_ptr<LinkSubTask>> *linkSubTasksOut,
69                       std::vector<std::shared_ptr<LinkSubTask>> *postLinkSubTasksOut);
70     // Used for load()
71     // Backends should populate only one of linkSubTasksOut or postLinkSubTasksOut.
72     virtual void load(std::vector<std::shared_ptr<LinkSubTask>> *linkSubTasksOut,
73                       std::vector<std::shared_ptr<LinkSubTask>> *postLinkSubTasksOut);
74     virtual angle::Result getResult(const gl::Context *context, gl::InfoLog &infoLog) = 0;
75 
76     // Used by the GL backend to query whether the driver is linking in parallel internally.
77     virtual bool isLinkingInternally();
78 };
79 
80 class ProgramImpl : angle::NonCopyable
81 {
82   public:
ProgramImpl(const gl::ProgramState & state)83     ProgramImpl(const gl::ProgramState &state) : mState(state) {}
~ProgramImpl()84     virtual ~ProgramImpl() {}
destroy(const gl::Context * context)85     virtual void destroy(const gl::Context *context) {}
86 
87     virtual angle::Result load(const gl::Context *context,
88                                gl::BinaryInputStream *stream,
89                                std::shared_ptr<LinkTask> *loadTaskOut,
90                                egl::CacheGetResult *resultOut)                    = 0;
91     virtual void save(const gl::Context *context, gl::BinaryOutputStream *stream) = 0;
92     virtual void setBinaryRetrievableHint(bool retrievable)                       = 0;
93     virtual void setSeparable(bool separable)                                     = 0;
94 
prepareForLink(const gl::ShaderMap<ShaderImpl * > & shaders)95     virtual void prepareForLink(const gl::ShaderMap<ShaderImpl *> &shaders) {}
96     virtual angle::Result link(const gl::Context *context,
97                                std::shared_ptr<LinkTask> *linkTaskOut) = 0;
98     virtual GLboolean validate(const gl::Caps &caps)                   = 0;
99 
100     // Implementation-specific method for ignoring unreferenced uniforms. Some implementations may
101     // perform more extensive analysis and ignore some locations that ANGLE doesn't detect as
102     // unreferenced. This method is not required to be overriden by a back-end.
markUnusedUniformLocations(std::vector<gl::VariableLocation> * uniformLocations,std::vector<gl::SamplerBinding> * samplerBindings,std::vector<gl::ImageBinding> * imageBindings)103     virtual void markUnusedUniformLocations(std::vector<gl::VariableLocation> *uniformLocations,
104                                             std::vector<gl::SamplerBinding> *samplerBindings,
105                                             std::vector<gl::ImageBinding> *imageBindings)
106     {}
107 
getState()108     const gl::ProgramState &getState() const { return mState; }
109 
110     virtual angle::Result onLabelUpdate(const gl::Context *context);
111 
112     // Called when glUniformBlockBinding is called.
onUniformBlockBinding(gl::UniformBlockIndex uniformBlockIndex)113     virtual void onUniformBlockBinding(gl::UniformBlockIndex uniformBlockIndex) {}
114 
115   protected:
116     const gl::ProgramState &mState;
117 };
118 
119 }  // namespace rx
120 
121 #endif  // LIBANGLE_RENDERER_PROGRAMIMPL_H_
122