• 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/ResourceVk.h"
15 #include "libANGLE/renderer/vulkan/vk_cache_utils.h"
16 #include "libANGLE/renderer/vulkan/vk_helpers.h"
17 #include "libANGLE/renderer/vulkan/vk_utils.h"
18 
19 namespace rx
20 {
21 constexpr VkDeviceSize kMaxTotalEmptyBufferBytes = 16 * 1024 * 1024;
22 
23 class RendererVk;
24 
25 class TextureUpload
26 {
27   public:
TextureUpload()28     TextureUpload() { mPrevUploadedMutableTexture = nullptr; }
~TextureUpload()29     ~TextureUpload() { resetPrevTexture(); }
30     angle::Result onMutableTextureUpload(ContextVk *contextVk, TextureVk *newTexture);
31     void onTextureRelease(TextureVk *textureVk);
resetPrevTexture()32     void resetPrevTexture() { mPrevUploadedMutableTexture = nullptr; }
33 
34   private:
35     // Keep track of the previously stored texture. Used to flush mutable textures.
36     TextureVk *mPrevUploadedMutableTexture;
37 };
38 
39 class UpdateDescriptorSetsBuilder final : angle::NonCopyable
40 {
41   public:
42     UpdateDescriptorSetsBuilder();
43     ~UpdateDescriptorSetsBuilder();
44 
45     VkDescriptorBufferInfo *allocDescriptorBufferInfos(size_t count);
46     VkDescriptorImageInfo *allocDescriptorImageInfos(size_t count);
47     VkWriteDescriptorSet *allocWriteDescriptorSets(size_t count);
48     VkBufferView *allocBufferViews(size_t count);
49 
allocDescriptorBufferInfo()50     VkDescriptorBufferInfo &allocDescriptorBufferInfo() { return *allocDescriptorBufferInfos(1); }
allocDescriptorImageInfo()51     VkDescriptorImageInfo &allocDescriptorImageInfo() { return *allocDescriptorImageInfos(1); }
allocWriteDescriptorSet()52     VkWriteDescriptorSet &allocWriteDescriptorSet() { return *allocWriteDescriptorSets(1); }
allocBufferView()53     VkBufferView &allocBufferView() { return *allocBufferViews(1); }
54 
55     // Returns the number of written descriptor sets.
56     uint32_t flushDescriptorSetUpdates(VkDevice device);
57 
58   private:
59     template <typename T, const T *VkWriteDescriptorSet::*pInfo>
60     T *allocDescriptorInfos(std::vector<T> *descriptorVector, size_t count);
61     template <typename T, const T *VkWriteDescriptorSet::*pInfo>
62     void growDescriptorCapacity(std::vector<T> *descriptorVector, size_t newSize);
63 
64     std::vector<VkDescriptorBufferInfo> mDescriptorBufferInfos;
65     std::vector<VkDescriptorImageInfo> mDescriptorImageInfos;
66     std::vector<VkWriteDescriptorSet> mWriteDescriptorSets;
67     std::vector<VkBufferView> mBufferViews;
68 };
69 
70 class ShareGroupVk : public ShareGroupImpl
71 {
72   public:
73     ShareGroupVk(const egl::ShareGroupState &state);
74     void onDestroy(const egl::Display *display) override;
75 
76     void onContextAdd() override;
77 
getFramebufferCache()78     FramebufferCache &getFramebufferCache() { return mFramebufferCache; }
79 
hasAnyContextWithRobustness()80     bool hasAnyContextWithRobustness() const { return mState.hasAnyContextWithRobustness(); }
81 
82     // PipelineLayoutCache and DescriptorSetLayoutCache can be shared between multiple threads
83     // accessing them via shared contexts. The ShareGroup locks around gl entrypoints ensuring
84     // synchronous update to the caches.
getPipelineLayoutCache()85     PipelineLayoutCache &getPipelineLayoutCache() { return mPipelineLayoutCache; }
getDescriptorSetLayoutCache()86     DescriptorSetLayoutCache &getDescriptorSetLayoutCache() { return mDescriptorSetLayoutCache; }
getContexts()87     const egl::ContextMap &getContexts() const { return mState.getContexts(); }
getMetaDescriptorPool(DescriptorSetIndex descriptorSetIndex)88     vk::MetaDescriptorPool &getMetaDescriptorPool(DescriptorSetIndex descriptorSetIndex)
89     {
90         return mMetaDescriptorPools[descriptorSetIndex];
91     }
92 
93     // Used to flush the mutable textures more often.
94     angle::Result onMutableTextureUpload(ContextVk *contextVk, TextureVk *newTexture);
95 
96     vk::BufferPool *getDefaultBufferPool(RendererVk *renderer,
97                                          VkDeviceSize size,
98                                          uint32_t memoryTypeIndex,
99                                          BufferUsageType usageType);
100     void pruneDefaultBufferPools(RendererVk *renderer);
101     bool isDueForBufferPoolPrune(RendererVk *renderer);
102 
103     void calculateTotalBufferCount(size_t *bufferCount, VkDeviceSize *totalSize) const;
104     void logBufferPools() const;
105 
106     // Temporary workaround until VkSemaphore(s) will be used between different priorities.
107     angle::Result unifyContextsPriority(ContextVk *newContextVk);
108     // Temporary workaround until VkSemaphore(s) will be used between different priorities.
109     angle::Result lockDefaultContextsPriority(ContextVk *contextVk);
110 
getUpdateDescriptorSetsBuilder()111     UpdateDescriptorSetsBuilder *getUpdateDescriptorSetsBuilder()
112     {
113         return &mUpdateDescriptorSetsBuilder;
114     }
115 
116     void onTextureRelease(TextureVk *textureVk);
117 
118     angle::Result scheduleMonolithicPipelineCreationTask(
119         ContextVk *contextVk,
120         vk::WaitableMonolithicPipelineCreationTask *taskOut);
121     void waitForCurrentMonolithicPipelineCreationTask();
122 
123   private:
124     angle::Result updateContextsPriority(ContextVk *contextVk, egl::ContextPriority newPriority);
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     enum class SuballocationAlgorithm : uint8_t
149     {
150         Buddy       = 0,
151         General     = 1,
152         InvalidEnum = 2,
153         EnumCount   = InvalidEnum,
154     };
155     angle::PackedEnumMap<SuballocationAlgorithm, vk::BufferPoolPointerArray> mDefaultBufferPools;
156     angle::PackedEnumMap<BufferUsageType, size_t> mSizeLimitForBuddyAlgorithm;
157 
158     // The system time when last pruneEmptyBuffer gets called.
159     double mLastPruneTime;
160 
161     // The system time when the last monolithic pipeline creation job was launched.  This is
162     // rate-limited to avoid hogging all cores and interfering with the application threads.  A
163     // single pipeline creation job is currently supported.
164     double mLastMonolithicPipelineJobTime;
165     std::shared_ptr<angle::WaitableEvent> mMonolithicPipelineCreationEvent;
166 
167     // Texture update manager used to flush uploaded mutable textures.
168     TextureUpload mTextureUpload;
169 };
170 }  // namespace rx
171 
172 #endif  // LIBANGLE_RENDERER_VULKAN_SHAREGROUPVK_H_
173