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