diff options
author | android-autoroll <android-autoroll@skia-public.iam.gserviceaccount.com> | 2022-04-20 06:23:29 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2022-04-20 06:23:29 +0000 |
commit | b370bceed25abf04af1738f3aa6b9252ee586cd2 (patch) | |
tree | 6a38c8c218b815e33c02c67d2287f0fadcf54b27 | |
parent | 575947b41f330732766494a803effd806c3f3f9b (diff) | |
parent | d7e8e849313c53d85acf739cd8f1d377a193b4fa (diff) | |
download | angle-b370bceed25abf04af1738f3aa6b9252ee586cd2.tar.gz |
Roll ANGLE from 55c21842b204 to 5014ce664ca5 (1 revision) am: 38d4545ae8 am: 862d6bc8db am: d7e8e84931
Original change: https://android-review.googlesource.com/c/platform/external/angle/+/2068668
Change-Id: I7954d19f0f13273fbc40325347cbf3e1b7a0e458
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | src/libANGLE/renderer/vulkan/ContextVk.cpp | 21 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/ContextVk.h | 11 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/DisplayVk.cpp | 65 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/DisplayVk.h | 5 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/RendererVk.cpp | 60 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/RendererVk.h | 15 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/vk_helpers.cpp | 14 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/vk_helpers.h | 8 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/vk_utils.cpp | 69 | ||||
-rw-r--r-- | src/libANGLE/renderer/vulkan/vk_utils.h | 12 |
10 files changed, 118 insertions, 162 deletions
diff --git a/src/libANGLE/renderer/vulkan/ContextVk.cpp b/src/libANGLE/renderer/vulkan/ContextVk.cpp index bdc4ea1726..ae4061a413 100644 --- a/src/libANGLE/renderer/vulkan/ContextVk.cpp +++ b/src/libANGLE/renderer/vulkan/ContextVk.cpp @@ -6165,9 +6165,9 @@ angle::Result ContextVk::flushAndGetSerial(const vk::Semaphore *signalSemaphore, if ((renderPassClosureReason == RenderPassClosureReason::GLFlush || renderPassClosureReason == RenderPassClosureReason::GLFinish || renderPassClosureReason == RenderPassClosureReason::EGLSwapBuffers) && - isDueForBufferPoolPrune()) + mShareGroupVk->isDueForBufferPoolPrune()) { - pruneDefaultBufferPools(); + mShareGroupVk->pruneDefaultBufferPools(mRenderer); } return angle::Result::Continue; @@ -7221,23 +7221,6 @@ uint32_t UpdateDescriptorSetsBuilder::flushDescriptorSetUpdates(VkDevice device) return retVal; } -bool ContextVk::isDueForBufferPoolPrune() const -{ - if (mState.hasDisplayTextureShareGroup()) - { - return mRenderer->isDueForBufferPoolPrune(); - } - return mShareGroupVk->isDueForBufferPoolPrune(); -} - -void ContextVk::pruneDefaultBufferPools() -{ - if (mState.hasDisplayTextureShareGroup()) - { - return mRenderer->pruneDefaultBufferPools(); - } - return mShareGroupVk->pruneDefaultBufferPools(mRenderer); -} void ContextVk::resetPerFramePerfCounters() { diff --git a/src/libANGLE/renderer/vulkan/ContextVk.h b/src/libANGLE/renderer/vulkan/ContextVk.h index 85f64ae14f..78178560aa 100644 --- a/src/libANGLE/renderer/vulkan/ContextVk.h +++ b/src/libANGLE/renderer/vulkan/ContextVk.h @@ -718,14 +718,7 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText vk::BufferPool *getDefaultBufferPool(VkDeviceSize size, uint32_t memoryTypeIndex) { - if (mState.hasDisplayTextureShareGroup()) - { - return mRenderer->getDefaultBufferPool(size, memoryTypeIndex); - } - else - { - return mShareGroupVk->getDefaultBufferPool(mRenderer, size, memoryTypeIndex); - } + return mShareGroupVk->getDefaultBufferPool(mRenderer, size, memoryTypeIndex); } angle::Result allocateStreamedVertexBuffer(size_t attribIndex, @@ -1171,8 +1164,6 @@ class ContextVk : public ContextImpl, public vk::Context, public MultisampleText void updateShaderResourcesDescriptorDesc(PipelineType pipelineType); - bool isDueForBufferPoolPrune() const; - void pruneDefaultBufferPools(); void resetPerFramePerfCounters(); std::array<GraphicsDirtyBitHandler, DIRTY_BIT_MAX> mGraphicsDirtyBitHandlers; diff --git a/src/libANGLE/renderer/vulkan/DisplayVk.cpp b/src/libANGLE/renderer/vulkan/DisplayVk.cpp index 6f13790e48..2f5a4846ef 100644 --- a/src/libANGLE/renderer/vulkan/DisplayVk.cpp +++ b/src/libANGLE/renderer/vulkan/DisplayVk.cpp @@ -25,6 +25,8 @@ namespace rx { +// Time interval in seconds that we should try to prune default buffer pools. +constexpr double kTimeElapsedForPruneDefaultBufferPool = 0.25; DisplayVk::DisplayVk(const egl::DisplayState &state) : DisplayImpl(state), @@ -409,12 +411,18 @@ void DisplayVk::populateFeatureList(angle::FeatureList *features) ShareGroupVk::ShareGroupVk() { - mLastPruneTime = angle::GetCurrentSystemTime(); + mLastPruneTime = angle::GetCurrentSystemTime(); + mOrphanNonEmptyBufferBlock = false; } void ShareGroupVk::addContext(ContextVk *contextVk) { mContexts.insert(contextVk); + + if (contextVk->getState().hasDisplayTextureShareGroup()) + { + mOrphanNonEmptyBufferBlock = true; + } } void ShareGroupVk::removeContext(ContextVk *contextVk) @@ -430,13 +438,13 @@ void ShareGroupVk::onDestroy(const egl::Display *display) { if (pool) { - pool->destroy(renderer); + pool->destroy(renderer, mOrphanNonEmptyBufferBlock); } } if (mSmallBufferPool) { - mSmallBufferPool->destroy(renderer); + mSmallBufferPool->destroy(renderer, mOrphanNonEmptyBufferBlock); } mPipelineLayoutCache.destroy(renderer); @@ -461,19 +469,62 @@ vk::BufferPool *ShareGroupVk::getDefaultBufferPool(RendererVk *renderer, VkDeviceSize size, uint32_t memoryTypeIndex) { - return vk::GetDefaultBufferPool(mSmallBufferPool, mDefaultBufferPools, renderer, size, - memoryTypeIndex); + if (size <= kMaxSizeToUseSmallBufferPool && + memoryTypeIndex == + renderer->getVertexConversionBufferMemoryTypeIndex(vk::MemoryHostVisibility::Visible)) + { + if (!mSmallBufferPool) + { + const vk::Allocator &allocator = renderer->getAllocator(); + VkBufferUsageFlags usageFlags = GetDefaultBufferUsageFlags(renderer); + + VkMemoryPropertyFlags memoryPropertyFlags; + allocator.getMemoryTypeProperties(memoryTypeIndex, &memoryPropertyFlags); + + std::unique_ptr<vk::BufferPool> pool = std::make_unique<vk::BufferPool>(); + pool->initWithFlags(renderer, vma::VirtualBlockCreateFlagBits::BUDDY, usageFlags, 0, + memoryTypeIndex, memoryPropertyFlags); + mSmallBufferPool = std::move(pool); + } + return mSmallBufferPool.get(); + } + else if (!mDefaultBufferPools[memoryTypeIndex]) + { + const vk::Allocator &allocator = renderer->getAllocator(); + VkBufferUsageFlags usageFlags = GetDefaultBufferUsageFlags(renderer); + + VkMemoryPropertyFlags memoryPropertyFlags; + allocator.getMemoryTypeProperties(memoryTypeIndex, &memoryPropertyFlags); + + std::unique_ptr<vk::BufferPool> pool = std::make_unique<vk::BufferPool>(); + pool->initWithFlags(renderer, vma::VirtualBlockCreateFlagBits::GENERAL, usageFlags, 0, + memoryTypeIndex, memoryPropertyFlags); + mDefaultBufferPools[memoryTypeIndex] = std::move(pool); + } + + return mDefaultBufferPools[memoryTypeIndex].get(); } void ShareGroupVk::pruneDefaultBufferPools(RendererVk *renderer) { mLastPruneTime = angle::GetCurrentSystemTime(); - vk::PruneDefaultBufferPools(renderer, mDefaultBufferPools, mSmallBufferPool); + for (std::unique_ptr<vk::BufferPool> &pool : mDefaultBufferPools) + { + if (pool) + { + pool->pruneEmptyBuffers(renderer); + } + } + if (mSmallBufferPool) + { + mSmallBufferPool->pruneEmptyBuffers(renderer); + } } bool ShareGroupVk::isDueForBufferPoolPrune() { - return vk::IsDueForBufferPoolPrune(mLastPruneTime); + double timeElapsed = angle::GetCurrentSystemTime() - mLastPruneTime; + return timeElapsed > kTimeElapsedForPruneDefaultBufferPool; } } // namespace rx diff --git a/src/libANGLE/renderer/vulkan/DisplayVk.h b/src/libANGLE/renderer/vulkan/DisplayVk.h index 4ce0c22485..a4ae8d51f5 100644 --- a/src/libANGLE/renderer/vulkan/DisplayVk.h +++ b/src/libANGLE/renderer/vulkan/DisplayVk.h @@ -70,9 +70,14 @@ class ShareGroupVk : public ShareGroupImpl // The pool dedicated for small allocations that uses faster buddy algorithm std::unique_ptr<vk::BufferPool> mSmallBufferPool; + static constexpr VkDeviceSize kMaxSizeToUseSmallBufferPool = 256; // The system time when last pruneEmptyBuffer gets called. double mLastPruneTime; + + // If true, it is expected that a BufferBlock may still in used by textures that outlived + // ShareGroup. The non-empty BufferBlock will be put into RendererVk's orphan list instead. + bool mOrphanNonEmptyBufferBlock; }; class DisplayVk : public DisplayImpl, public vk::Context diff --git a/src/libANGLE/renderer/vulkan/RendererVk.cpp b/src/libANGLE/renderer/vulkan/RendererVk.cpp index 3b79e53f4b..1b901b9a32 100644 --- a/src/libANGLE/renderer/vulkan/RendererVk.cpp +++ b/src/libANGLE/renderer/vulkan/RendererVk.cpp @@ -1142,8 +1142,7 @@ RendererVk::RendererVk() mPipelineCacheInitialized(false), mValidationMessageCount(0), mCommandProcessor(this), - mSupportedVulkanPipelineStageMask(0), - mLastPruneTime(angle::GetCurrentSystemTime()) + mSupportedVulkanPipelineStageMask(0) { VkFormatProperties invalid = {0, 0, kInvalidFormatFeatureFlags}; mFormatProperties.fill(invalid); @@ -1198,18 +1197,12 @@ void RendererVk::onDestroy(vk::Context *context) handleDeviceLost(); } - for (std::unique_ptr<vk::BufferPool> &pool : mDefaultBufferPools) + for (std::unique_ptr<vk::BufferBlock> &block : mOrphanedBufferBlocks) { - if (pool) - { - pool->destroy(this); - } - } - - if (mSmallBufferPool) - { - mSmallBufferPool->destroy(this); + ASSERT(block->isEmpty()); + block->destroy(this); } + mOrphanedBufferBlocks.clear(); { vk::ScopedCommandQueueLock lock(this, mCommandQueueMutex); @@ -3691,10 +3684,35 @@ bool RendererVk::haveSameFormatFeatureBits(angle::FormatID formatID1, hasImageFormatFeatureBits(formatID2, fmt1OptimalFeatureBits); } +void RendererVk::addBufferBlockToOrphanList(vk::BufferBlock *block) +{ + std::lock_guard<std::mutex> lock(mGarbageMutex); + mOrphanedBufferBlocks.emplace_back(block); +} + +void RendererVk::pruneOrphanedBufferBlocks() +{ + for (auto iter = mOrphanedBufferBlocks.begin(); iter != mOrphanedBufferBlocks.end();) + { + if (!(*iter)->isEmpty()) + { + ++iter; + continue; + } + (*iter)->destroy(this); + iter = mOrphanedBufferBlocks.erase(iter); + } +} + angle::Result RendererVk::cleanupGarbage(Serial lastCompletedQueueSerial) { std::lock_guard<std::mutex> lock(mGarbageMutex); + if (!mOrphanedBufferBlocks.empty()) + { + pruneOrphanedBufferBlocks(); + } + // Clean up general garbages while (!mSharedGarbage.empty()) { @@ -4239,24 +4257,6 @@ VkDeviceSize RendererVk::getPreferedBufferBlockSize(uint32_t memoryTypeIndex) co return std::min(heapSize / 64, mPreferredLargeHeapBlockSize); } -vk::BufferPool *RendererVk::getDefaultBufferPool(VkDeviceSize size, uint32_t memoryTypeIndex) -{ - return vk::GetDefaultBufferPool(mSmallBufferPool, mDefaultBufferPools, this, size, - memoryTypeIndex); -} - -void RendererVk::pruneDefaultBufferPools() -{ - mLastPruneTime = angle::GetCurrentSystemTime(); - - vk::PruneDefaultBufferPools(this, mDefaultBufferPools, mSmallBufferPool); -} - -bool RendererVk::isDueForBufferPoolPrune() -{ - return vk::IsDueForBufferPoolPrune(mLastPruneTime); -} - namespace vk { MemoryReport::MemoryReport() diff --git a/src/libANGLE/renderer/vulkan/RendererVk.h b/src/libANGLE/renderer/vulkan/RendererVk.h index ec3dbd12a4..49c2f52208 100644 --- a/src/libANGLE/renderer/vulkan/RendererVk.h +++ b/src/libANGLE/renderer/vulkan/RendererVk.h @@ -547,10 +547,8 @@ class RendererVk : angle::NonCopyable return mDeviceLocalVertexConversionBufferMemoryTypeIndex; } - vk::BufferPool *getDefaultBufferPool(VkDeviceSize size, uint32_t memoryTypeIndex); - - void pruneDefaultBufferPools(); - bool isDueForBufferPoolPrune(); + void addBufferBlockToOrphanList(vk::BufferBlock *block); + void pruneOrphanedBufferBlocks(); private: angle::Result initializeDevice(DisplayVk *displayVk, uint32_t queueFamilyIndex); @@ -670,6 +668,9 @@ class RendererVk : angle::NonCopyable uint32_t mDeviceLocalVertexConversionBufferMemoryTypeIndex; size_t mVertexConversionBufferAlignment; + // Holds orphaned BufferBlocks when ShareGroup gets destroyed + vk::BufferBlockPointerVector mOrphanedBufferBlocks; + // All access to the pipeline cache is done through EGL objects so it is thread safe to not use // a lock. std::mutex mPipelineCacheMutex; @@ -753,12 +754,6 @@ class RendererVk : angle::NonCopyable vk::ExtensionNameList mEnabledInstanceExtensions; vk::ExtensionNameList mEnabledDeviceExtensions; - - vk::BufferPoolPointerArray mDefaultBufferPools; - - std::unique_ptr<vk::BufferPool> mSmallBufferPool; - - double mLastPruneTime; }; } // namespace rx diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.cpp b/src/libANGLE/renderer/vulkan/vk_helpers.cpp index d562aa64df..e75ff8f13c 100644 --- a/src/libANGLE/renderer/vulkan/vk_helpers.cpp +++ b/src/libANGLE/renderer/vulkan/vk_helpers.cpp @@ -2959,12 +2959,20 @@ angle::Result BufferPool::allocateBuffer(Context *context, return angle::Result::Continue; } -void BufferPool::destroy(RendererVk *renderer) +void BufferPool::destroy(RendererVk *renderer, bool orphanNonEmptyBufferBlock) { for (std::unique_ptr<BufferBlock> &block : mBufferBlocks) { - ASSERT(block->isEmpty()); - block->destroy(renderer); + if (block->isEmpty()) + { + block->destroy(renderer); + } + else + { + // When orphan is not allowed, all BufferBlocks must be empty. + ASSERT(orphanNonEmptyBufferBlock); + renderer->addBufferBlockToOrphanList(block.release()); + } } mBufferBlocks.clear(); } diff --git a/src/libANGLE/renderer/vulkan/vk_helpers.h b/src/libANGLE/renderer/vulkan/vk_helpers.h index f6fc14fa5a..b9a0d87471 100644 --- a/src/libANGLE/renderer/vulkan/vk_helpers.h +++ b/src/libANGLE/renderer/vulkan/vk_helpers.h @@ -848,9 +848,10 @@ class BufferPool : angle::NonCopyable VkDeviceSize alignment, BufferSuballocation *suballocation); - // This frees resources immediately. - void destroy(RendererVk *renderer); - + // Frees resources immediately, or orphan the non-empty BufferBlocks if allowed. If orphan is + // not allowed, it will assert if BufferBlock is still not empty. + void destroy(RendererVk *renderer, bool orphanAllowed); + // Remove and destroy empty BufferBlocks void pruneEmptyBuffers(RendererVk *renderer); bool valid() const { return mSize != 0; } @@ -875,6 +876,7 @@ class BufferPool : angle::NonCopyable // will call into vulkan directly to allocate a dedicated VkDeviceMemory. static constexpr size_t kMaxBufferSizeForSuballocation = 4 * 1024 * 1024; }; +using BufferPoolPointerArray = std::array<std::unique_ptr<BufferPool>, VK_MAX_MEMORY_TYPES>; enum class BufferAccess { diff --git a/src/libANGLE/renderer/vulkan/vk_utils.cpp b/src/libANGLE/renderer/vulkan/vk_utils.cpp index 2d1e7d8419..7285841ad3 100644 --- a/src/libANGLE/renderer/vulkan/vk_utils.cpp +++ b/src/libANGLE/renderer/vulkan/vk_utils.cpp @@ -6,8 +6,8 @@ // vk_utils: // Helper functions for the Vulkan Renderer. // + #include "libANGLE/renderer/vulkan/vk_utils.h" -#include "common/system_utils.h" #include "libANGLE/Context.h" #include "libANGLE/renderer/vulkan/BufferVk.h" @@ -40,8 +40,6 @@ namespace // Pick an arbitrary value to initialize non-zero memory for sanitization. Note that 0x3F3F3F3F // as float is about 0.75. constexpr int kNonZeroInitValue = 0x3F; -// Time interval in seconds that we should try to prune default buffer pools. -constexpr double kTimeElapsedForPruneDefaultBufferPool = 0.25; VkImageUsageFlags GetStagingBufferUsageFlags(vk::StagingUsage usage) { @@ -643,71 +641,6 @@ angle::Result AllocateBufferMemoryWithRequirements(Context *context, buffer, deviceMemoryOut); } -BufferPool *GetDefaultBufferPool(std::unique_ptr<vk::BufferPool> &smallBufferPool, - vk::BufferPoolPointerArray &defaultBufferPools, - RendererVk *renderer, - VkDeviceSize size, - uint32_t memoryTypeIndex) -{ - if (size <= kMaxSizeToUseSmallBufferPool && - memoryTypeIndex == - renderer->getVertexConversionBufferMemoryTypeIndex(vk::MemoryHostVisibility::Visible)) - { - if (!smallBufferPool) - { - const vk::Allocator &allocator = renderer->getAllocator(); - VkBufferUsageFlags usageFlags = GetDefaultBufferUsageFlags(renderer); - - VkMemoryPropertyFlags memoryPropertyFlags; - allocator.getMemoryTypeProperties(memoryTypeIndex, &memoryPropertyFlags); - - std::unique_ptr<vk::BufferPool> pool = std::make_unique<vk::BufferPool>(); - pool->initWithFlags(renderer, vma::VirtualBlockCreateFlagBits::BUDDY, usageFlags, 0, - memoryTypeIndex, memoryPropertyFlags); - smallBufferPool = std::move(pool); - } - return smallBufferPool.get(); - } - else if (!defaultBufferPools[memoryTypeIndex]) - { - const vk::Allocator &allocator = renderer->getAllocator(); - VkBufferUsageFlags usageFlags = GetDefaultBufferUsageFlags(renderer); - - VkMemoryPropertyFlags memoryPropertyFlags; - allocator.getMemoryTypeProperties(memoryTypeIndex, &memoryPropertyFlags); - - std::unique_ptr<vk::BufferPool> pool = std::make_unique<vk::BufferPool>(); - pool->initWithFlags(renderer, vma::VirtualBlockCreateFlagBits::GENERAL, usageFlags, 0, - memoryTypeIndex, memoryPropertyFlags); - defaultBufferPools[memoryTypeIndex] = std::move(pool); - } - - return defaultBufferPools[memoryTypeIndex].get(); -} - -void PruneDefaultBufferPools(RendererVk *renderer, - BufferPoolPointerArray &defaultBufferPools, - std::unique_ptr<vk::BufferPool> &smallBufferPool) -{ - for (std::unique_ptr<vk::BufferPool> &pool : defaultBufferPools) - { - if (pool) - { - pool->pruneEmptyBuffers(renderer); - } - } - if (smallBufferPool) - { - smallBufferPool->pruneEmptyBuffers(renderer); - } -} - -bool IsDueForBufferPoolPrune(double lastPruneTime) -{ - double timeElapsed = angle::GetCurrentSystemTime() - lastPruneTime; - return timeElapsed > kTimeElapsedForPruneDefaultBufferPool; -} - angle::Result InitShaderAndSerial(Context *context, ShaderAndSerial *shaderAndSerial, const uint32_t *shaderCode, diff --git a/src/libANGLE/renderer/vulkan/vk_utils.h b/src/libANGLE/renderer/vulkan/vk_utils.h index 80e19aacff..a53c8a462f 100644 --- a/src/libANGLE/renderer/vulkan/vk_utils.h +++ b/src/libANGLE/renderer/vulkan/vk_utils.h @@ -466,18 +466,6 @@ angle::Result AllocateBufferMemoryWithRequirements(Context *context, Buffer *buffer, VkMemoryPropertyFlags *memoryPropertyFlagsOut, DeviceMemory *deviceMemoryOut); -class BufferPool; -static constexpr VkDeviceSize kMaxSizeToUseSmallBufferPool = 256; -using BufferPoolPointerArray = std::array<std::unique_ptr<BufferPool>, VK_MAX_MEMORY_TYPES>; -BufferPool *GetDefaultBufferPool(std::unique_ptr<vk::BufferPool> &smallBufferPool, - vk::BufferPoolPointerArray &defaultBufferPools, - RendererVk *renderer, - VkDeviceSize size, - uint32_t memoryTypeIndex); -void PruneDefaultBufferPools(RendererVk *renderer, - BufferPoolPointerArray &defaultBufferPools, - std::unique_ptr<vk::BufferPool> &smallBufferPool); -bool IsDueForBufferPoolPrune(double lastPruneTime); using ShaderAndSerial = ObjectAndSerial<ShaderModule>; |