Commit e3dc5dd0 by Luc Ferron Committed by Commit Bot

Vulkan: Add 2 features to StreamingBuffer

This is prerequisite work to dynamic uniform buffer updates. 1- Alignment parameter to be able to allocate by chunks of this alignment. 2- Out boolean to indicate if a new VkBuffer has been assigned on the allocate operation. Bug:angleproject:2392 Change-Id: If346e13200455febbe78045e908ae89c9dc93cdb Reviewed-on: https://chromium-review.googlesource.com/965612 Commit-Queue: Luc Ferron <lucferron@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 3761dc7b
......@@ -73,8 +73,8 @@ ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer)
mCurrentDrawMode(GL_NONE),
mVertexArrayDirty(false),
mTexturesDirty(false),
mStreamingVertexData(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, kStreamingVertexDataSize),
mStreamingIndexData(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, kStreamingIndexDataSize)
mStreamingVertexData(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, kStreamingVertexDataSize, 1),
mStreamingIndexData(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, kStreamingIndexDataSize, 1)
{
memset(&mClearColorValue, 0, sizeof(mClearColorValue));
memset(&mClearDepthStencilValue, 0, sizeof(mClearDepthStencilValue));
......@@ -367,7 +367,8 @@ gl::Error ContextVk::drawElements(const gl::Context *context,
const GLsizei amount = sizeof(GLushort) * count;
GLubyte *dst = nullptr;
ANGLE_TRY(mStreamingIndexData.allocate(contextVk, amount, &dst, &buffer, &offset));
ANGLE_TRY(
mStreamingIndexData.allocate(contextVk, amount, &dst, &buffer, &offset, nullptr));
if (type == GL_UNSIGNED_BYTE)
{
// Unsigned bytes don't have direct support in Vulkan so we have to expand the
......
......@@ -17,12 +17,13 @@
namespace rx
{
StreamingBuffer::StreamingBuffer(VkBufferUsageFlags usage, size_t minSize)
StreamingBuffer::StreamingBuffer(VkBufferUsageFlags usage, size_t minSize, size_t minAlignment)
: mUsage(usage),
mMinSize(minSize),
mNextWriteOffset(0),
mLastFlushOffset(0),
mSize(0),
mMinAlignment(minAlignment),
mMappedMemory(nullptr)
{
}
......@@ -35,7 +36,8 @@ gl::Error StreamingBuffer::allocate(ContextVk *context,
size_t sizeInBytes,
uint8_t **ptrOut,
VkBuffer *handleOut,
VkDeviceSize *offsetOut)
VkDeviceSize *offsetOut,
bool *outNewBufferAllocated)
{
RendererVk *renderer = context->getRenderer();
......@@ -43,8 +45,10 @@ gl::Error StreamingBuffer::allocate(ContextVk *context,
// persist longer than one frame.
updateQueueSerial(renderer->getCurrentQueueSerial());
size_t sizeToAllocate = roundUp(sizeInBytes, mMinAlignment);
angle::base::CheckedNumeric<size_t> checkedNextWriteOffset = mNextWriteOffset;
checkedNextWriteOffset += sizeInBytes;
checkedNextWriteOffset += sizeToAllocate;
if (!checkedNextWriteOffset.IsValid() || checkedNextWriteOffset.ValueOrDie() > mSize)
{
......@@ -62,7 +66,7 @@ gl::Error StreamingBuffer::allocate(ContextVk *context,
createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
createInfo.pNext = nullptr;
createInfo.flags = 0;
createInfo.size = std::max(sizeInBytes, mMinSize);
createInfo.size = std::max(sizeToAllocate, mMinSize);
createInfo.usage = mUsage;
createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
createInfo.queueFamilyIndexCount = 0;
......@@ -74,6 +78,18 @@ gl::Error StreamingBuffer::allocate(ContextVk *context,
ANGLE_TRY(mMemory.map(device, 0, mSize, 0, &mMappedMemory));
mNextWriteOffset = 0;
mLastFlushOffset = 0;
if (outNewBufferAllocated != nullptr)
{
*outNewBufferAllocated = true;
}
}
else
{
if (outNewBufferAllocated != nullptr)
{
*outNewBufferAllocated = false;
}
}
ASSERT(mBuffer.valid());
......@@ -82,7 +98,7 @@ gl::Error StreamingBuffer::allocate(ContextVk *context,
ASSERT(mMappedMemory);
*ptrOut = mMappedMemory + mNextWriteOffset;
*offsetOut = mNextWriteOffset;
mNextWriteOffset += sizeInBytes;
mNextWriteOffset += sizeToAllocate;
return gl::NoError();
}
......
......@@ -19,13 +19,14 @@ namespace rx
class StreamingBuffer : public ResourceVk
{
public:
StreamingBuffer(VkBufferUsageFlags usage, size_t minSize);
StreamingBuffer(VkBufferUsageFlags usage, size_t minSize, size_t minAlignment);
~StreamingBuffer();
gl::Error allocate(ContextVk *context,
size_t amount,
size_t sizeInBytes,
uint8_t **ptrOut,
VkBuffer *handleOut,
VkDeviceSize *offsetOut);
VkDeviceSize *offsetOut,
bool *outNewBufferAllocated);
gl::Error flush(ContextVk *context);
void destroy(VkDevice device);
......@@ -37,6 +38,7 @@ class StreamingBuffer : public ResourceVk
size_t mNextWriteOffset;
size_t mLastFlushOffset;
size_t mSize;
size_t mMinAlignment;
uint8_t *mMappedMemory;
};
......
......@@ -83,7 +83,7 @@ gl::Error VertexArrayVk::streamVertexData(ContextVk *context,
uint8_t *dst = nullptr;
ANGLE_TRY(stream->allocate(context, lastByte, &dst,
&mCurrentArrayBufferHandles[attribIndex],
&mCurrentArrayBufferOffsets[attribIndex]));
&mCurrentArrayBufferOffsets[attribIndex], nullptr));
memcpy(dst + firstByte, static_cast<const uint8_t *>(attrib.pointer) + firstByte,
lastByte - firstByte);
}
......
......@@ -1353,7 +1353,8 @@ LineLoopHandler::LineLoopHandler()
: mObserverBinding(this, 0u),
mStreamingLineLoopIndicesData(
new StreamingBuffer(VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
kLineLoopStreamingBufferMinSize)),
kLineLoopStreamingBufferMinSize,
1)),
mLineLoopIndexBuffer(VK_NULL_HANDLE),
mLineLoopIndexBufferOffset(VK_NULL_HANDLE)
{
......@@ -1374,10 +1375,10 @@ gl::Error LineLoopHandler::createIndexBuffer(ContextVk *contextVk, int firstVert
mLineLoopBufferLastIndex != lastVertex)
{
uint32_t *indices = nullptr;
size_t allocateBytes = sizeof(uint32_t) * (count + 1);
ANGLE_TRY(mStreamingLineLoopIndicesData->allocate(
contextVk, sizeof(uint32_t) * (count + 1), reinterpret_cast<uint8_t **>(&indices),
&mLineLoopIndexBuffer, &mLineLoopIndexBufferOffset));
contextVk, allocateBytes, reinterpret_cast<uint8_t **>(&indices), &mLineLoopIndexBuffer,
&mLineLoopIndexBufferOffset, nullptr));
auto unsignedFirstVertex = static_cast<uint32_t>(firstVertex);
for (auto vertexIndex = unsignedFirstVertex; vertexIndex < (count + unsignedFirstVertex);
......@@ -1418,9 +1419,10 @@ gl::Error LineLoopHandler::createIndexBufferFromElementArrayBuffer(ContextVk *co
uint32_t *indices = nullptr;
auto unitSize = (indexType == VK_INDEX_TYPE_UINT16 ? sizeof(uint16_t) : sizeof(uint32_t));
size_t allocateBytes = unitSize * (count + 1);
ANGLE_TRY(mStreamingLineLoopIndicesData->allocate(
contextVk, unitSize * (count + 1), reinterpret_cast<uint8_t **>(&indices),
&mLineLoopIndexBuffer, &mLineLoopIndexBufferOffset));
contextVk, allocateBytes, reinterpret_cast<uint8_t **>(&indices), &mLineLoopIndexBuffer,
&mLineLoopIndexBufferOffset, nullptr));
VkBufferCopy copy1 = {0, mLineLoopIndexBufferOffset,
static_cast<VkDeviceSize>(count) * unitSize};
......
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