Vulkan: inline some of the BufferSuballocation APIs

These are simply get* calls and frequent used ones. The measurement I
have on Pixel6 shows there is 0.01ms out of 2.28ms on CPU overhead with
asphalt_8 app trace measured with --minimize-gpu-work.

Bug: b/205337962
Change-Id: I746a1ccc67c589d1aba25495601ad874ddc034a4
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3403159
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Charlie Lao <cclao@google.com>
This commit is contained in:
Charlie Lao 2022-01-19 14:14:16 -08:00 коммит произвёл Angle LUCI CQ
Родитель 1b5efe51aa
Коммит a83f7e91c9
2 изменённых файлов: 161 добавлений и 157 удалений

Просмотреть файл

@ -1768,47 +1768,6 @@ void BufferBlock::initWithoutVirtualBlock(ContextVk *contextVk,
mSerial = renderer->getResourceSerialFactory().generateBufferSerial();
}
Buffer *BufferBlock::getBuffer()
{
return &mBuffer;
}
const Allocation &BufferBlock::getAllocation() const
{
return mAllocation;
}
VkMemoryPropertyFlags BufferBlock::getMemoryPropertyFlags() const
{
return mMemoryPropertyFlags;
}
VkDeviceSize BufferBlock::getMemorySize() const
{
return mSize;
}
VkBool32 BufferBlock::isEmpty()
{
std::lock_guard<ConditionalMutex> lock(mVirtualBlockMutex);
return vma::IsVirtualBlockEmpty(mVirtualBlock.getHandle());
}
bool BufferBlock::isHostVisible() const
{
return (mMemoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0;
}
bool BufferBlock::isCoherent() const
{
return (mMemoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0;
}
bool BufferBlock::isMapped() const
{
return mMappedMemory != nullptr;
}
angle::Result BufferBlock::map(ContextVk *contextVk)
{
ASSERT(mMappedMemory == nullptr);
@ -1823,19 +1782,6 @@ void BufferBlock::unmap(const Allocator &allocator)
mMappedMemory = nullptr;
}
uint8_t *BufferBlock::getMappedMemory() const
{
ASSERT(mMappedMemory != nullptr);
return mMappedMemory;
}
VkResult BufferBlock::allocate(VkDeviceSize size, VkDeviceSize alignment, VkDeviceSize *offsetOut)
{
std::lock_guard<ConditionalMutex> lock(mVirtualBlockMutex);
mCountRemainsEmpty = 0;
return mVirtualBlock.allocate(size, alignment, offsetOut);
}
void BufferBlock::free(VkDeviceSize offset)
{
std::lock_guard<ConditionalMutex> lock(mVirtualBlockMutex);
@ -1846,108 +1792,5 @@ int32_t BufferBlock::getAndIncrementEmptyCounter()
{
return ++mCountRemainsEmpty;
}
// BufferSuballocation implementation.
void BufferSuballocation::destroy(RendererVk *renderer)
{
if (valid())
{
DestroyVmaBufferSuballocation(renderer, mHandle);
mHandle = VK_NULL_HANDLE;
}
}
VkResult BufferSuballocation::init(VkDevice device,
BufferBlock *block,
VkDeviceSize offset,
VkDeviceSize size)
{
ASSERT(!valid());
ASSERT(block != nullptr);
ASSERT(offset != VK_WHOLE_SIZE);
return CreateVmaBufferSuballocation(block, offset, size, &mHandle);
}
VkResult BufferSuballocation::initWithEntireBuffer(ContextVk *contextVk,
Buffer &buffer,
Allocation &allocation,
VkMemoryPropertyFlags memoryPropertyFlags,
VkDeviceSize size)
{
ASSERT(!valid());
std::unique_ptr<BufferBlock> block = std::make_unique<BufferBlock>();
block->initWithoutVirtualBlock(contextVk, buffer, allocation, memoryPropertyFlags, size);
VmaBufferSuballocation vmaBufferSuballocation = new VmaBufferSuballocation_T;
if (vmaBufferSuballocation == nullptr)
{
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
else
{
vmaBufferSuballocation->mBufferBlock = block.release();
vmaBufferSuballocation->mOffset = 0;
vmaBufferSuballocation->mSize = vmaBufferSuballocation->mBufferBlock->getMemorySize();
}
mHandle = vmaBufferSuballocation;
return VK_SUCCESS;
}
BufferBlock *BufferSuballocation::getBlock() const
{
return mHandle->mBufferBlock;
}
const Buffer &BufferSuballocation::getBuffer() const
{
return *getBlock()->getBuffer();
}
VkDeviceSize BufferSuballocation::getSize() const
{
return mHandle->mSize;
}
const Allocation &BufferSuballocation::getAllocation() const
{
return mHandle->mBufferBlock->getAllocation();
}
VkMemoryMapFlags BufferSuballocation::getMemoryPropertyFlags() const
{
return mHandle->mBufferBlock->getMemoryPropertyFlags();
}
bool BufferSuballocation::isHostVisible() const
{
return mHandle->mBufferBlock->isHostVisible();
}
bool BufferSuballocation::isCoherent() const
{
return mHandle->mBufferBlock->isCoherent();
}
bool BufferSuballocation::isMapped() const
{
return mHandle->mBufferBlock->isMapped();
}
uint8_t *BufferSuballocation::getMappedMemory() const
{
return mHandle->mBufferBlock->getMappedMemory() + getOffset();
}
void BufferSuballocation::flush(const Allocator &allocator) const
{
mHandle->mBufferBlock->getAllocation().flush(allocator, getOffset(), mHandle->mSize);
}
void BufferSuballocation::invalidate(const Allocator &allocator) const
{
mHandle->mBufferBlock->getAllocation().invalidate(allocator, getOffset(), mHandle->mSize);
}
VkDeviceSize BufferSuballocation::getOffset() const
{
return mHandle->mOffset;
}
} // namespace vk
} // namespace rx

Просмотреть файл

@ -1063,6 +1063,167 @@ class BufferSuballocation final : public WrappedObject<BufferSuballocation, VmaB
VkDeviceSize getOffset() const;
};
// BufferBlock implementation.
ANGLE_INLINE Buffer *BufferBlock::getBuffer()
{
return &mBuffer;
}
ANGLE_INLINE const Allocation &BufferBlock::getAllocation() const
{
return mAllocation;
}
ANGLE_INLINE VkMemoryPropertyFlags BufferBlock::getMemoryPropertyFlags() const
{
return mMemoryPropertyFlags;
}
ANGLE_INLINE VkDeviceSize BufferBlock::getMemorySize() const
{
return mSize;
}
ANGLE_INLINE VkBool32 BufferBlock::isEmpty()
{
std::lock_guard<ConditionalMutex> lock(mVirtualBlockMutex);
return vma::IsVirtualBlockEmpty(mVirtualBlock.getHandle());
}
ANGLE_INLINE bool BufferBlock::isHostVisible() const
{
return (mMemoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0;
}
ANGLE_INLINE bool BufferBlock::isCoherent() const
{
return (mMemoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT) != 0;
}
ANGLE_INLINE bool BufferBlock::isMapped() const
{
return mMappedMemory != nullptr;
}
ANGLE_INLINE uint8_t *BufferBlock::getMappedMemory() const
{
ASSERT(mMappedMemory != nullptr);
return mMappedMemory;
}
ANGLE_INLINE VkResult BufferBlock::allocate(VkDeviceSize size,
VkDeviceSize alignment,
VkDeviceSize *offsetOut)
{
std::lock_guard<ConditionalMutex> lock(mVirtualBlockMutex);
mCountRemainsEmpty = 0;
return mVirtualBlock.allocate(size, alignment, offsetOut);
}
// BufferSuballocation implementation.
ANGLE_INLINE void BufferSuballocation::destroy(RendererVk *renderer)
{
if (valid())
{
DestroyVmaBufferSuballocation(renderer, mHandle);
mHandle = VK_NULL_HANDLE;
}
}
ANGLE_INLINE VkResult BufferSuballocation::init(VkDevice device,
BufferBlock *block,
VkDeviceSize offset,
VkDeviceSize size)
{
ASSERT(!valid());
ASSERT(block != nullptr);
ASSERT(offset != VK_WHOLE_SIZE);
return CreateVmaBufferSuballocation(block, offset, size, &mHandle);
}
ANGLE_INLINE VkResult
BufferSuballocation::initWithEntireBuffer(ContextVk *contextVk,
Buffer &buffer,
Allocation &allocation,
VkMemoryPropertyFlags memoryPropertyFlags,
VkDeviceSize size)
{
ASSERT(!valid());
std::unique_ptr<BufferBlock> block = std::make_unique<BufferBlock>();
block->initWithoutVirtualBlock(contextVk, buffer, allocation, memoryPropertyFlags, size);
VmaBufferSuballocation vmaBufferSuballocation = new VmaBufferSuballocation_T;
if (vmaBufferSuballocation == nullptr)
{
return VK_ERROR_OUT_OF_HOST_MEMORY;
}
else
{
vmaBufferSuballocation->mBufferBlock = block.release();
vmaBufferSuballocation->mOffset = 0;
vmaBufferSuballocation->mSize = vmaBufferSuballocation->mBufferBlock->getMemorySize();
}
mHandle = vmaBufferSuballocation;
return VK_SUCCESS;
}
ANGLE_INLINE BufferBlock *BufferSuballocation::getBlock() const
{
return mHandle->mBufferBlock;
}
ANGLE_INLINE const Buffer &BufferSuballocation::getBuffer() const
{
return *getBlock()->getBuffer();
}
ANGLE_INLINE VkDeviceSize BufferSuballocation::getSize() const
{
return mHandle->mSize;
}
ANGLE_INLINE const Allocation &BufferSuballocation::getAllocation() const
{
return mHandle->mBufferBlock->getAllocation();
}
ANGLE_INLINE VkMemoryMapFlags BufferSuballocation::getMemoryPropertyFlags() const
{
return mHandle->mBufferBlock->getMemoryPropertyFlags();
}
ANGLE_INLINE bool BufferSuballocation::isHostVisible() const
{
return mHandle->mBufferBlock->isHostVisible();
}
ANGLE_INLINE bool BufferSuballocation::isCoherent() const
{
return mHandle->mBufferBlock->isCoherent();
}
ANGLE_INLINE bool BufferSuballocation::isMapped() const
{
return mHandle->mBufferBlock->isMapped();
}
ANGLE_INLINE uint8_t *BufferSuballocation::getMappedMemory() const
{
return mHandle->mBufferBlock->getMappedMemory() + getOffset();
}
ANGLE_INLINE void BufferSuballocation::flush(const Allocator &allocator) const
{
mHandle->mBufferBlock->getAllocation().flush(allocator, getOffset(), mHandle->mSize);
}
ANGLE_INLINE void BufferSuballocation::invalidate(const Allocator &allocator) const
{
mHandle->mBufferBlock->getAllocation().invalidate(allocator, getOffset(), mHandle->mSize);
}
ANGLE_INLINE VkDeviceSize BufferSuballocation::getOffset() const
{
return mHandle->mOffset;
}
#if defined(ANGLE_ENABLE_PERF_COUNTER_OUTPUT)
constexpr bool kOutputCumulativePerfCounters = ANGLE_ENABLE_PERF_COUNTER_OUTPUT;
#else