• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2023 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 // ShareGroupVk.h:
7 //    Defines the class interface for ShareGroupVk, implementing ShareGroupImpl.
8 //
9 
10 #ifndef LIBANGLE_RENDERER_VULKAN_SHAREGROUPVK_H_
11 #define LIBANGLE_RENDERER_VULKAN_SHAREGROUPVK_H_
12 
13 #include "libANGLE/renderer/ShareGroupImpl.h"
14 #include "libANGLE/renderer/vulkan/vk_cache_utils.h"
15 #include "libANGLE/renderer/vulkan/vk_helpers.h"
16 #include "libANGLE/renderer/vulkan/vk_resource.h"
17 #include "libANGLE/renderer/vulkan/vk_utils.h"
18 
19 namespace rx
20 {
21 constexpr VkDeviceSize kMaxTotalEmptyBufferBytes = 16 * 1024 * 1024;
22 
23 class TextureUpload
24 {
25   public:
TextureUpload()26     TextureUpload() { mPrevUploadedMutableTexture = nullptr; }
~TextureUpload()27     ~TextureUpload() { resetPrevTexture(); }
28     angle::Result onMutableTextureUpload(ContextVk *contextVk, TextureVk *newTexture);
29     void onTextureRelease(TextureVk *textureVk);
resetPrevTexture()30     void resetPrevTexture() { mPrevUploadedMutableTexture = nullptr; }
31 
32   private:
33     // Keep track of the previously stored texture. Used to flush mutable textures.
34     TextureVk *mPrevUploadedMutableTexture;
35 };
36 
37 class ShareGroupVk : public ShareGroupImpl
38 {
39   public:
40     ShareGroupVk(const egl::ShareGroupState &state);
41     void onDestroy(const egl::Display *display) override;
42 
43     void onContextAdd() override;
44 
getFramebufferCache()45     FramebufferCache &getFramebufferCache() { return mFramebufferCache; }
46 
hasAnyContextWithRobustness()47     bool hasAnyContextWithRobustness() const { return mState.hasAnyContextWithRobustness(); }
48 
49     // PipelineLayoutCache and DescriptorSetLayoutCache can be shared between multiple threads
50     // accessing them via shared contexts. The ShareGroup locks around gl entrypoints ensuring
51     // synchronous update to the caches.
getPipelineLayoutCache()52     PipelineLayoutCache &getPipelineLayoutCache() { return mPipelineLayoutCache; }
getDescriptorSetLayoutCache()53     DescriptorSetLayoutCache &getDescriptorSetLayoutCache() { return mDescriptorSetLayoutCache; }
getContexts()54     const egl::ContextMap &getContexts() const { return mState.getContexts(); }
getMetaDescriptorPools()55     vk::DescriptorSetArray<vk::MetaDescriptorPool> &getMetaDescriptorPools()
56     {
57         return mMetaDescriptorPools;
58     }
59 
60     // Used to flush the mutable textures more often.
61     angle::Result onMutableTextureUpload(ContextVk *contextVk, TextureVk *newTexture);
62 
63     vk::BufferPool *getDefaultBufferPool(vk::Renderer *renderer,
64                                          VkDeviceSize size,
65                                          uint32_t memoryTypeIndex,
66                                          BufferUsageType usageType);
67     void pruneDefaultBufferPools(vk::Renderer *renderer);
68     bool isDueForBufferPoolPrune(vk::Renderer *renderer);
69 
70     void calculateTotalBufferCount(size_t *bufferCount, VkDeviceSize *totalSize) const;
71     void logBufferPools() const;
72 
73     // Temporary workaround until VkSemaphore(s) will be used between different priorities.
74     angle::Result unifyContextsPriority(ContextVk *newContextVk);
75     // Temporary workaround until VkSemaphore(s) will be used between different priorities.
76     angle::Result lockDefaultContextsPriority(ContextVk *contextVk);
77 
getUpdateDescriptorSetsBuilder()78     UpdateDescriptorSetsBuilder *getUpdateDescriptorSetsBuilder()
79     {
80         return &mUpdateDescriptorSetsBuilder;
81     }
82 
83     void onTextureRelease(TextureVk *textureVk);
84 
getVertexInputGraphicsPipelineCache()85     VertexInputGraphicsPipelineCache *getVertexInputGraphicsPipelineCache()
86     {
87         return &mVertexInputGraphicsPipelineCache;
88     }
getFragmentOutputGraphicsPipelineCache()89     FragmentOutputGraphicsPipelineCache *getFragmentOutputGraphicsPipelineCache()
90     {
91         return &mFragmentOutputGraphicsPipelineCache;
92     }
93 
94     angle::Result scheduleMonolithicPipelineCreationTask(
95         ContextVk *contextVk,
96         vk::WaitableMonolithicPipelineCreationTask *taskOut);
97     void waitForCurrentMonolithicPipelineCreationTask();
98 
getRefCountedEventsGarbageRecycler()99     vk::RefCountedEventsGarbageRecycler *getRefCountedEventsGarbageRecycler()
100     {
101         return &mRefCountedEventsGarbageRecycler;
102     }
cleanupRefCountedEventGarbage(vk::Renderer * renderer)103     void cleanupRefCountedEventGarbage(vk::Renderer *renderer)
104     {
105         mRefCountedEventsGarbageRecycler.cleanup(renderer);
106     }
cleanupExcessiveRefCountedEventGarbage(vk::Renderer * renderer)107     void cleanupExcessiveRefCountedEventGarbage(vk::Renderer *renderer)
108     {
109         // TODO: b/336844257 needs tune.
110         constexpr size_t kExcessiveGarbageCountThreshold = 256;
111         if (mRefCountedEventsGarbageRecycler.getGarbageCount() > kExcessiveGarbageCountThreshold)
112         {
113             mRefCountedEventsGarbageRecycler.cleanup(renderer);
114         }
115     }
116 
117   private:
118     angle::Result updateContextsPriority(ContextVk *contextVk, egl::ContextPriority newPriority);
119 
120     // VkFramebuffer caches
121     FramebufferCache mFramebufferCache;
122 
resetPrevTexture()123     void resetPrevTexture() { mTextureUpload.resetPrevTexture(); }
124 
125     // ANGLE uses a PipelineLayout cache to store compatible pipeline layouts.
126     PipelineLayoutCache mPipelineLayoutCache;
127 
128     // DescriptorSetLayouts are also managed in a cache.
129     DescriptorSetLayoutCache mDescriptorSetLayoutCache;
130 
131     // Descriptor set caches
132     vk::DescriptorSetArray<vk::MetaDescriptorPool> mMetaDescriptorPools;
133 
134     // Priority of all Contexts in the context set
135     egl::ContextPriority mContextsPriority;
136     bool mIsContextsPriorityLocked;
137 
138     // Storage for vkUpdateDescriptorSets
139     UpdateDescriptorSetsBuilder mUpdateDescriptorSetsBuilder;
140 
141     // The per shared group buffer pools that all buffers should sub-allocate from.
142     vk::BufferPoolPointerArray mDefaultBufferPools;
143 
144     // The system time when last pruneEmptyBuffer gets called.
145     double mLastPruneTime;
146 
147     // Used when VK_EXT_graphics_pipeline_library is available, the vertex input and fragment output
148     // partial pipelines are created in the following caches.  These caches are in the share group
149     // because linked pipelines using these pipeline libraries are referenced from
150     // ProgramExecutableVk, and as such must stay alive as long as the program may be alive.
151     VertexInputGraphicsPipelineCache mVertexInputGraphicsPipelineCache;
152     FragmentOutputGraphicsPipelineCache mFragmentOutputGraphicsPipelineCache;
153 
154     // The system time when the last monolithic pipeline creation job was launched.  This is
155     // rate-limited to avoid hogging all cores and interfering with the application threads.  A
156     // single pipeline creation job is currently supported.
157     double mLastMonolithicPipelineJobTime;
158     std::shared_ptr<angle::WaitableEvent> mMonolithicPipelineCreationEvent;
159 
160     // Texture update manager used to flush uploaded mutable textures.
161     TextureUpload mTextureUpload;
162 
163     // Holds RefCountedEvent that are free and ready to reuse
164     vk::RefCountedEventsGarbageRecycler mRefCountedEventsGarbageRecycler;
165 };
166 }  // namespace rx
167 
168 #endif  // LIBANGLE_RENDERER_VULKAN_SHAREGROUPVK_H_
169