• 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, 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 
84     angle::Result scheduleMonolithicPipelineCreationTask(
85         ContextVk *contextVk,
86         vk::WaitableMonolithicPipelineCreationTask *taskOut);
87     void waitForCurrentMonolithicPipelineCreationTask();
88 
getRefCountedEventsGarbageRecycler()89     vk::RefCountedEventsGarbageRecycler *getRefCountedEventsGarbageRecycler()
90     {
91         return &mRefCountedEventsGarbageRecycler;
92     }
cleanupRefCountedEventGarbage()93     void cleanupRefCountedEventGarbage() { mRefCountedEventsGarbageRecycler.cleanup(mRenderer); }
cleanupExcessiveRefCountedEventGarbage()94     void cleanupExcessiveRefCountedEventGarbage()
95     {
96         // TODO: b/336844257 needs tune.
97         constexpr size_t kExcessiveGarbageCountThreshold = 256;
98         if (mRefCountedEventsGarbageRecycler.getGarbageCount() > kExcessiveGarbageCountThreshold)
99         {
100             mRefCountedEventsGarbageRecycler.cleanup(mRenderer);
101         }
102     }
103 
104     void onFramebufferBoundary();
getCurrentFrameCount()105     uint32_t getCurrentFrameCount() const { return mCurrentFrameCount; }
106 
107   private:
108     angle::Result updateContextsPriority(ContextVk *contextVk, egl::ContextPriority newPriority);
109 
110     bool isDueForBufferPoolPrune();
111 
112     vk::Renderer *mRenderer;
113 
114     // Tracks the total number of frames rendered.
115     uint32_t mCurrentFrameCount;
116 
117     // VkFramebuffer caches
118     FramebufferCache mFramebufferCache;
119 
resetPrevTexture()120     void resetPrevTexture() { mTextureUpload.resetPrevTexture(); }
121 
122     // ANGLE uses a PipelineLayout cache to store compatible pipeline layouts.
123     PipelineLayoutCache mPipelineLayoutCache;
124 
125     // DescriptorSetLayouts are also managed in a cache.
126     DescriptorSetLayoutCache mDescriptorSetLayoutCache;
127 
128     // Descriptor set caches
129     vk::DescriptorSetArray<vk::MetaDescriptorPool> mMetaDescriptorPools;
130 
131     // Priority of all Contexts in the context set
132     egl::ContextPriority mContextsPriority;
133     bool mIsContextsPriorityLocked;
134 
135     // Storage for vkUpdateDescriptorSets
136     UpdateDescriptorSetsBuilder mUpdateDescriptorSetsBuilder;
137 
138     // The per shared group buffer pools that all buffers should sub-allocate from.
139     vk::BufferPoolPointerArray mDefaultBufferPools;
140 
141     // The system time when last pruneEmptyBuffer gets called.
142     double mLastPruneTime;
143 
144     // The system time when the last monolithic pipeline creation job was launched.  This is
145     // rate-limited to avoid hogging all cores and interfering with the application threads.  A
146     // single pipeline creation job is currently supported.
147     double mLastMonolithicPipelineJobTime;
148     std::shared_ptr<angle::WaitableEvent> mMonolithicPipelineCreationEvent;
149 
150     // Texture update manager used to flush uploaded mutable textures.
151     TextureUpload mTextureUpload;
152 
153     // Holds RefCountedEvent that are free and ready to reuse
154     vk::RefCountedEventsGarbageRecycler mRefCountedEventsGarbageRecycler;
155 };
156 }  // namespace rx
157 
158 #endif  // LIBANGLE_RENDERER_VULKAN_SHAREGROUPVK_H_
159