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