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