aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-autoroll <android-autoroll@skia-public.iam.gserviceaccount.com>2022-04-20 04:37:43 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-04-20 04:37:43 +0000
commit862d6bc8db72cbbe47fb529608f113a0b225fed9 (patch)
tree6a38c8c218b815e33c02c67d2287f0fadcf54b27
parente0c30569974afd7fce2218fd6676da6d5792bebc (diff)
parent38d4545ae8105254f89fb511d7f43705d7dc82fa (diff)
downloadangle-862d6bc8db72cbbe47fb529608f113a0b225fed9.tar.gz
Roll ANGLE from 55c21842b204 to 5014ce664ca5 (1 revision) am: 38d4545ae8
Original change: https://android-review.googlesource.com/c/platform/external/angle/+/2068668 Change-Id: I97b8c22522cbb9bf1750d5056486a896baaa2ac2 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--src/libANGLE/renderer/vulkan/ContextVk.cpp21
-rw-r--r--src/libANGLE/renderer/vulkan/ContextVk.h11
-rw-r--r--src/libANGLE/renderer/vulkan/DisplayVk.cpp65
-rw-r--r--src/libANGLE/renderer/vulkan/DisplayVk.h5
-rw-r--r--src/libANGLE/renderer/vulkan/RendererVk.cpp60
-rw-r--r--src/libANGLE/renderer/vulkan/RendererVk.h15
-rw-r--r--src/libANGLE/renderer/vulkan/vk_helpers.cpp14
-rw-r--r--src/libANGLE/renderer/vulkan/vk_helpers.h8
-rw-r--r--src/libANGLE/renderer/vulkan/vk_utils.cpp69
-rw-r--r--src/libANGLE/renderer/vulkan/vk_utils.h12
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>;