xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/ShareGroupVk.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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, vk::Renderer *renderer);
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(VkDeviceSize size,
64                                          uint32_t memoryTypeIndex,
65                                          BufferUsageType usageType);
66 
67     void pruneDefaultBufferPools();
68 
69     void calculateTotalBufferCount(size_t *bufferCount, VkDeviceSize *totalSize) const;
70     void logBufferPools() const;
71 
72     // Temporary workaround until VkSemaphore(s) will be used between different priorities.
73     angle::Result unifyContextsPriority(ContextVk *newContextVk);
74     // Temporary workaround until VkSemaphore(s) will be used between different priorities.
75     angle::Result lockDefaultContextsPriority(ContextVk *contextVk);
76 
getUpdateDescriptorSetsBuilder()77     UpdateDescriptorSetsBuilder *getUpdateDescriptorSetsBuilder()
78     {
79         return &mUpdateDescriptorSetsBuilder;
80     }
81 
82     void onTextureRelease(TextureVk *textureVk);
83 
getVertexInputGraphicsPipelineCache()84     VertexInputGraphicsPipelineCache *getVertexInputGraphicsPipelineCache()
85     {
86         return &mVertexInputGraphicsPipelineCache;
87     }
getFragmentOutputGraphicsPipelineCache()88     FragmentOutputGraphicsPipelineCache *getFragmentOutputGraphicsPipelineCache()
89     {
90         return &mFragmentOutputGraphicsPipelineCache;
91     }
92 
93     angle::Result scheduleMonolithicPipelineCreationTask(
94         ContextVk *contextVk,
95         vk::WaitableMonolithicPipelineCreationTask *taskOut);
96     void waitForCurrentMonolithicPipelineCreationTask();
97 
getRefCountedEventsGarbageRecycler()98     vk::RefCountedEventsGarbageRecycler *getRefCountedEventsGarbageRecycler()
99     {
100         return &mRefCountedEventsGarbageRecycler;
101     }
cleanupRefCountedEventGarbage()102     void cleanupRefCountedEventGarbage() { mRefCountedEventsGarbageRecycler.cleanup(mRenderer); }
cleanupExcessiveRefCountedEventGarbage()103     void cleanupExcessiveRefCountedEventGarbage()
104     {
105         // TODO: b/336844257 needs tune.
106         constexpr size_t kExcessiveGarbageCountThreshold = 256;
107         if (mRefCountedEventsGarbageRecycler.getGarbageCount() > kExcessiveGarbageCountThreshold)
108         {
109             mRefCountedEventsGarbageRecycler.cleanup(mRenderer);
110         }
111     }
112 
113     void onFramebufferBoundary();
getCurrentFrameCount()114     uint32_t getCurrentFrameCount() const { return mCurrentFrameCount; }
115 
116   private:
117     angle::Result updateContextsPriority(ContextVk *contextVk, egl::ContextPriority newPriority);
118 
119     bool isDueForBufferPoolPrune();
120 
121     vk::Renderer *mRenderer;
122 
123     // Tracks the total number of frames rendered.
124     uint32_t mCurrentFrameCount;
125 
126     // VkFramebuffer caches
127     FramebufferCache mFramebufferCache;
128 
resetPrevTexture()129     void resetPrevTexture() { mTextureUpload.resetPrevTexture(); }
130 
131     // ANGLE uses a PipelineLayout cache to store compatible pipeline layouts.
132     PipelineLayoutCache mPipelineLayoutCache;
133 
134     // DescriptorSetLayouts are also managed in a cache.
135     DescriptorSetLayoutCache mDescriptorSetLayoutCache;
136 
137     // Descriptor set caches
138     vk::DescriptorSetArray<vk::MetaDescriptorPool> mMetaDescriptorPools;
139 
140     // Priority of all Contexts in the context set
141     egl::ContextPriority mContextsPriority;
142     bool mIsContextsPriorityLocked;
143 
144     // Storage for vkUpdateDescriptorSets
145     UpdateDescriptorSetsBuilder mUpdateDescriptorSetsBuilder;
146 
147     // The per shared group buffer pools that all buffers should sub-allocate from.
148     vk::BufferPoolPointerArray mDefaultBufferPools;
149 
150     // The system time when last pruneEmptyBuffer gets called.
151     double mLastPruneTime;
152 
153     // Used when VK_EXT_graphics_pipeline_library is available, the vertex input and fragment output
154     // partial pipelines are created in the following caches.  These caches are in the share group
155     // because linked pipelines using these pipeline libraries are referenced from
156     // ProgramExecutableVk, and as such must stay alive as long as the program may be alive.
157     VertexInputGraphicsPipelineCache mVertexInputGraphicsPipelineCache;
158     FragmentOutputGraphicsPipelineCache mFragmentOutputGraphicsPipelineCache;
159 
160     // The system time when the last monolithic pipeline creation job was launched.  This is
161     // rate-limited to avoid hogging all cores and interfering with the application threads.  A
162     // single pipeline creation job is currently supported.
163     double mLastMonolithicPipelineJobTime;
164     std::shared_ptr<angle::WaitableEvent> mMonolithicPipelineCreationEvent;
165 
166     // Texture update manager used to flush uploaded mutable textures.
167     TextureUpload mTextureUpload;
168 
169     // Holds RefCountedEvent that are free and ready to reuse
170     vk::RefCountedEventsGarbageRecycler mRefCountedEventsGarbageRecycler;
171 };
172 }  // namespace rx
173 
174 #endif  // LIBANGLE_RENDERER_VULKAN_SHAREGROUPVK_H_
175