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 ...@@ -84,14 +84,14 @@ class BufferVk : public BufferImpl
const vk::BufferHelper &getBuffer() const const vk::BufferHelper &getBuffer() const
{ {
ASSERT(mBuffer.valid()); ASSERT(mBuffer && mBuffer->valid());
return mBuffer; return *mBuffer;
} }
vk::BufferHelper &getBuffer() vk::BufferHelper &getBuffer()
{ {
ASSERT(mBuffer.valid()); ASSERT(mBuffer && mBuffer->valid());
return mBuffer; return *mBuffer;
} }
angle::Result mapImpl(ContextVk *contextVk, void **mapPtr); angle::Result mapImpl(ContextVk *contextVk, void **mapPtr);
...@@ -146,6 +146,10 @@ class BufferVk : public BufferImpl ...@@ -146,6 +146,10 @@ class BufferVk : public BufferImpl
void release(ContextVk *context); void release(ContextVk *context);
void markConversionBuffersDirty(); void markConversionBuffersDirty();
angle::Result acquireBufferHelper(ContextVk *contextVk,
size_t sizeInBytes,
vk::BufferHelper **bufferHelperOut);
struct VertexConversionBuffer : public ConversionBuffer struct VertexConversionBuffer : public ConversionBuffer
{ {
VertexConversionBuffer(RendererVk *renderer, VertexConversionBuffer(RendererVk *renderer,
...@@ -163,7 +167,10 @@ class BufferVk : public BufferImpl ...@@ -163,7 +167,10 @@ class BufferVk : public BufferImpl
size_t offset; 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. // All staging buffer support is provided by a DynamicBuffer.
vk::DynamicBuffer mStagingBuffer; vk::DynamicBuffer mStagingBuffer;
......
...@@ -462,7 +462,8 @@ DynamicBuffer::DynamicBuffer() ...@@ -462,7 +462,8 @@ DynamicBuffer::DynamicBuffer()
mNextAllocationOffset(0), mNextAllocationOffset(0),
mLastFlushOrInvalidateOffset(0), mLastFlushOrInvalidateOffset(0),
mSize(0), mSize(0),
mAlignment(0) mAlignment(0),
mMemoryPropertyFlags(0)
{} {}
DynamicBuffer::DynamicBuffer(DynamicBuffer &&other) DynamicBuffer::DynamicBuffer(DynamicBuffer &&other)
...@@ -474,6 +475,7 @@ DynamicBuffer::DynamicBuffer(DynamicBuffer &&other) ...@@ -474,6 +475,7 @@ DynamicBuffer::DynamicBuffer(DynamicBuffer &&other)
mLastFlushOrInvalidateOffset(other.mLastFlushOrInvalidateOffset), mLastFlushOrInvalidateOffset(other.mLastFlushOrInvalidateOffset),
mSize(other.mSize), mSize(other.mSize),
mAlignment(other.mAlignment), mAlignment(other.mAlignment),
mMemoryPropertyFlags(other.mMemoryPropertyFlags),
mInFlightBuffers(std::move(other.mInFlightBuffers)) mInFlightBuffers(std::move(other.mInFlightBuffers))
{ {
other.mBuffer = nullptr; other.mBuffer = nullptr;
...@@ -485,8 +487,21 @@ void DynamicBuffer::init(RendererVk *renderer, ...@@ -485,8 +487,21 @@ void DynamicBuffer::init(RendererVk *renderer,
size_t initialSize, size_t initialSize,
bool hostVisible) bool hostVisible)
{ {
mUsage = usage; VkMemoryPropertyFlags memoryPropertyFlags =
mHostVisible = hostVisible; (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. // Check that we haven't overriden the initial size of the buffer in setMinimumSizeForTesting.
if (mInitialSize == 0) if (mInitialSize == 0)
...@@ -523,9 +538,7 @@ angle::Result DynamicBuffer::allocateNewBuffer(ContextVk *contextVk) ...@@ -523,9 +538,7 @@ angle::Result DynamicBuffer::allocateNewBuffer(ContextVk *contextVk)
createInfo.queueFamilyIndexCount = 0; createInfo.queueFamilyIndexCount = 0;
createInfo.pQueueFamilyIndices = nullptr; createInfo.pQueueFamilyIndices = nullptr;
const VkMemoryPropertyFlags memoryProperty = ANGLE_TRY(buffer->init(contextVk, createInfo, mMemoryPropertyFlags));
mHostVisible ? VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT : VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
ANGLE_TRY(buffer->init(contextVk, createInfo, memoryProperty));
ASSERT(!mBuffer); ASSERT(!mBuffer);
mBuffer = buffer.release(); mBuffer = buffer.release();
...@@ -612,7 +625,11 @@ angle::Result DynamicBuffer::allocate(ContextVk *contextVk, ...@@ -612,7 +625,11 @@ angle::Result DynamicBuffer::allocate(ContextVk *contextVk,
*ptrOut = mappedMemory + mNextAllocationOffset; *ptrOut = mappedMemory + mNextAllocationOffset;
} }
*offsetOut = static_cast<VkDeviceSize>(mNextAllocationOffset); if (offsetOut != nullptr)
{
*offsetOut = static_cast<VkDeviceSize>(mNextAllocationOffset);
}
mNextAllocationOffset += static_cast<uint32_t>(sizeToAllocate); mNextAllocationOffset += static_cast<uint32_t>(sizeToAllocate);
return angle::Result::Continue; return angle::Result::Continue;
} }
......
...@@ -70,6 +70,13 @@ class DynamicBuffer : angle::NonCopyable ...@@ -70,6 +70,13 @@ class DynamicBuffer : angle::NonCopyable
size_t initialSize, size_t initialSize,
bool hostVisible); 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 // 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 // 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 // `newBufferAllocatedOut`). The new region will be in the returned buffer at given offset. If
...@@ -117,6 +124,7 @@ class DynamicBuffer : angle::NonCopyable ...@@ -117,6 +124,7 @@ class DynamicBuffer : angle::NonCopyable
uint32_t mLastFlushOrInvalidateOffset; uint32_t mLastFlushOrInvalidateOffset;
size_t mSize; size_t mSize;
size_t mAlignment; size_t mAlignment;
VkMemoryPropertyFlags mMemoryPropertyFlags;
std::vector<BufferHelper *> mInFlightBuffers; std::vector<BufferHelper *> mInFlightBuffers;
std::vector<BufferHelper *> mBufferFreeList; 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