Commit fa03eb9d by Brandon Schade Committed by Commit Bot

Vulkan: Use DynamicBuffer for BufferVk

When there is glBufferData API call, if the current VkBuffer is in use, we copy to a staging buffer to be gpu copied later. Instead of doing this second copy, write directly to a new buffer that will be used for subsequent gpu operations. BufferVk now has a DynamicBuffer to handle the logic of acquiring a new/free buffer to be used. Bug: angleproject:4380 Change-Id: I207f334013ae944090eb48c26c692a09e8815f74 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2040513Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCharlie Lao <cclao@google.com> Commit-Queue: Mohan Maiya <m.maiya@samsung.com>
parent 92b3a720
......@@ -84,14 +84,14 @@ class BufferVk : public BufferImpl
const vk::BufferHelper &getBuffer() const
{
ASSERT(mBuffer.valid());
return mBuffer;
ASSERT(mBuffer && mBuffer->valid());
return *mBuffer;
}
vk::BufferHelper &getBuffer()
{
ASSERT(mBuffer.valid());
return mBuffer;
ASSERT(mBuffer && mBuffer->valid());
return *mBuffer;
}
angle::Result mapImpl(ContextVk *contextVk, void **mapPtr);
......@@ -146,6 +146,10 @@ class BufferVk : public BufferImpl
void release(ContextVk *context);
void markConversionBuffersDirty();
angle::Result acquireBufferHelper(ContextVk *contextVk,
size_t sizeInBytes,
vk::BufferHelper **bufferHelperOut);
struct VertexConversionBuffer : public ConversionBuffer
{
VertexConversionBuffer(RendererVk *renderer,
......@@ -163,7 +167,10 @@ class BufferVk : public BufferImpl
size_t offset;
};
vk::BufferHelper mBuffer;
vk::BufferHelper *mBuffer;
// Pool of BufferHelpers for mBuffer to acquire from
vk::DynamicBuffer mBufferPool;
// All staging buffer support is provided by a DynamicBuffer.
vk::DynamicBuffer mStagingBuffer;
......
......@@ -462,7 +462,8 @@ DynamicBuffer::DynamicBuffer()
mNextAllocationOffset(0),
mLastFlushOrInvalidateOffset(0),
mSize(0),
mAlignment(0)
mAlignment(0),
mMemoryPropertyFlags(0)
{}
DynamicBuffer::DynamicBuffer(DynamicBuffer &&other)
......@@ -474,6 +475,7 @@ DynamicBuffer::DynamicBuffer(DynamicBuffer &&other)
mLastFlushOrInvalidateOffset(other.mLastFlushOrInvalidateOffset),
mSize(other.mSize),
mAlignment(other.mAlignment),
mMemoryPropertyFlags(other.mMemoryPropertyFlags),
mInFlightBuffers(std::move(other.mInFlightBuffers))
{
other.mBuffer = nullptr;
......@@ -485,8 +487,21 @@ void DynamicBuffer::init(RendererVk *renderer,
size_t initialSize,
bool hostVisible)
{
mUsage = usage;
mHostVisible = hostVisible;
VkMemoryPropertyFlags memoryPropertyFlags =
(hostVisible) ? VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT : VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
initWithFlags(renderer, usage, alignment, initialSize, memoryPropertyFlags);
}
void DynamicBuffer::initWithFlags(RendererVk *renderer,
VkBufferUsageFlags usage,
size_t alignment,
size_t initialSize,
VkMemoryPropertyFlags memoryPropertyFlags)
{
mUsage = usage;
mHostVisible = ((memoryPropertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0);
mMemoryPropertyFlags = memoryPropertyFlags;
// Check that we haven't overriden the initial size of the buffer in setMinimumSizeForTesting.
if (mInitialSize == 0)
......@@ -523,9 +538,7 @@ angle::Result DynamicBuffer::allocateNewBuffer(ContextVk *contextVk)
createInfo.queueFamilyIndexCount = 0;
createInfo.pQueueFamilyIndices = nullptr;
const VkMemoryPropertyFlags memoryProperty =
mHostVisible ? VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT : VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(buffer->init(contextVk, createInfo, memoryProperty));
ANGLE_TRY(buffer->init(contextVk, createInfo, mMemoryPropertyFlags));
ASSERT(!mBuffer);
mBuffer = buffer.release();
......@@ -612,7 +625,11 @@ angle::Result DynamicBuffer::allocate(ContextVk *contextVk,
*ptrOut = mappedMemory + mNextAllocationOffset;
}
*offsetOut = static_cast<VkDeviceSize>(mNextAllocationOffset);
if (offsetOut != nullptr)
{
*offsetOut = static_cast<VkDeviceSize>(mNextAllocationOffset);
}
mNextAllocationOffset += static_cast<uint32_t>(sizeToAllocate);
return angle::Result::Continue;
}
......
......@@ -70,6 +70,13 @@ class DynamicBuffer : angle::NonCopyable
size_t initialSize,
bool hostVisible);
// Init that gives the ability to pass in specified memory property flags for the buffer.
void initWithFlags(RendererVk *renderer,
VkBufferUsageFlags usage,
size_t alignment,
size_t initialSize,
VkMemoryPropertyFlags memoryProperty);
// This call will allocate a new region at the end of the buffer. It internally may trigger
// a new buffer to be created (which is returned in the optional parameter
// `newBufferAllocatedOut`). The new region will be in the returned buffer at given offset. If
......@@ -117,6 +124,7 @@ class DynamicBuffer : angle::NonCopyable
uint32_t mLastFlushOrInvalidateOffset;
size_t mSize;
size_t mAlignment;
VkMemoryPropertyFlags mMemoryPropertyFlags;
std::vector<BufferHelper *> mInFlightBuffers;
std::vector<BufferHelper *> mBufferFreeList;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment