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
19namespace rx
20{
21constexpr VkDeviceSize kMaxTotalEmptyBufferBytes = 16 * 1024 * 1024;
22
23class RendererVk;
24
25class TextureUpload
26{
27 public:
28 TextureUpload() { mPrevUploadedMutableTexture = nullptr; }
29 ~TextureUpload() { resetPrevTexture(); }
30 angle::Result onMutableTextureUpload(ContextVk *contextVk, TextureVk *newTexture);
31 void onTextureRelease(TextureVk *textureVk);
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
39class 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
50 VkDescriptorBufferInfo &allocDescriptorBufferInfo() { return *allocDescriptorBufferInfos(count: 1); }
51 VkDescriptorImageInfo &allocDescriptorImageInfo() { return *allocDescriptorImageInfos(count: 1); }
52 VkWriteDescriptorSet &allocWriteDescriptorSet() { return *allocWriteDescriptorSets(count: 1); }
53 VkBufferView &allocBufferView() { return *allocBufferViews(count: 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
70class 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
78 FramebufferCache &getFramebufferCache() { return mFramebufferCache; }
79
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.
85 PipelineLayoutCache &getPipelineLayoutCache() { return mPipelineLayoutCache; }
86 DescriptorSetLayoutCache &getDescriptorSetLayoutCache() { return mDescriptorSetLayoutCache; }
87 const egl::ContextMap &getContexts() const { return mState.getContexts(); }
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
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
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

source code of flutter_engine/third_party/angle/src/libANGLE/renderer/vulkan/ShareGroupVk.h