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