Vulkan: Refactor VertexArrayVk::streamVertexData.
Merges duplicated code in convertVertexBuffer with streamVertexData.
Refactoring change only.
Bug: angleproject:2786
Change-Id: I32baaad42d74918cfb17f04970d3c7e9b88362e7
Reviewed-on: https://chromium-review.googlesource.com/1188950
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
index f27f898..e1bd3e9 100644
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
@@ -30,6 +30,27 @@
{
return (binding.getOffset() % componentSize == 0) && (binding.getStride() % componentSize == 0);
}
+
+angle::Result StreamVertexData(ContextVk *contextVk,
+ vk::DynamicBuffer *dynamicBuffer,
+ const uint8_t *sourceData,
+ size_t bytesToAllocate,
+ size_t destOffset,
+ size_t vertexCount,
+ size_t stride,
+ VertexCopyFunction vertexLoadFunction,
+ VkBuffer *bufferHandleOut,
+ VkDeviceSize *bufferOffsetOut)
+{
+ uint8_t *dst = nullptr;
+ ANGLE_TRY(dynamicBuffer->allocate(contextVk, bytesToAllocate, &dst, bufferHandleOut,
+ bufferOffsetOut, nullptr));
+ dst += destOffset;
+ vertexLoadFunction(sourceData, stride, vertexCount, dst);
+
+ ANGLE_TRY(dynamicBuffer->flush(contextVk));
+ return angle::Result::Continue();
+}
} // anonymous namespace
#define INIT \
@@ -94,52 +115,13 @@
mLineLoopHelper.destroy(device);
}
-angle::Result VertexArrayVk::streamVertexData(ContextVk *contextVk,
- const gl::AttributesMask &attribsToStream,
- const gl::DrawCallParams &drawCallParams)
-{
- ASSERT(!attribsToStream.none());
-
- const auto &attribs = mState.getVertexAttributes();
- const auto &bindings = mState.getVertexBindings();
-
- // TODO(fjhenigman): When we have a bunch of interleaved attributes, they end up
- // un-interleaved, wasting space and copying time. Consider improving on that.
- for (size_t attribIndex : attribsToStream)
- {
- const gl::VertexAttribute &attrib = attribs[attribIndex];
- const gl::VertexBinding &binding = bindings[attrib.bindingIndex];
- ASSERT(attrib.enabled && binding.getBuffer().get() == nullptr);
-
- // Only vertexCount() vertices will be used by the upcoming draw so that is
- // all we copy, but we allocate space firstVertex() + vertexCount() so indexing
- // will work. If we don't start at zero all the indices will be off.
- // TODO(fjhenigman): See if we can account for indices being off by adjusting
- // the offset, thus avoiding wasted memory.
- const size_t bytesAllocated =
- (drawCallParams.firstVertex() + drawCallParams.vertexCount()) *
- mCurrentArrayBufferStrides[attribIndex];
- const uint8_t *src = static_cast<const uint8_t *>(attrib.pointer) +
- drawCallParams.firstVertex() * binding.getStride();
- uint8_t *dst = nullptr;
- ANGLE_TRY(mDynamicVertexData.allocate(contextVk, bytesAllocated, &dst,
- &mCurrentArrayBufferHandles[attribIndex],
- &mCurrentArrayBufferOffsets[attribIndex], nullptr));
- dst += drawCallParams.firstVertex() * mCurrentArrayBufferStrides[attribIndex];
- mCurrentArrayBufferFormats[attribIndex]->vertexLoadFunction(
- src, binding.getStride(), drawCallParams.vertexCount(), dst);
- }
-
- ANGLE_TRY(mDynamicVertexData.flush(contextVk));
- mDynamicVertexData.releaseRetainedBuffers(contextVk->getRenderer());
- return angle::Result::Continue();
-}
-
angle::Result VertexArrayVk::streamIndexData(ContextVk *contextVk,
const gl::DrawCallParams &drawCallParams)
{
ASSERT(!mState.getElementArrayBuffer().get());
+ mDynamicIndexData.releaseRetainedBuffers(contextVk->getRenderer());
+
const GLsizei amount = sizeof(GLushort) * drawCallParams.indexCount();
GLubyte *dst = nullptr;
@@ -161,7 +143,6 @@
memcpy(dst, drawCallParams.indices(), amount);
}
ANGLE_TRY(mDynamicIndexData.flush(contextVk));
- mDynamicIndexData.releaseRetainedBuffers(contextVk->getRenderer());
return angle::Result::Continue();
}
@@ -169,17 +150,19 @@
// and/or align it as we copy it to a DynamicBuffer. The assumption could be wrong
// but the alternative of copying it piecemeal on each draw would have a lot more
// overhead.
-angle::Result VertexArrayVk::convertVertexBuffer(ContextVk *context,
+angle::Result VertexArrayVk::convertVertexBuffer(ContextVk *contextVk,
BufferVk *srcBuffer,
const gl::VertexBinding &binding,
size_t attribIndex)
{
// Preparation for mapping source buffer.
- ANGLE_TRY(context->getRenderer()->finish(context));
+ ANGLE_TRY(contextVk->getRenderer()->finish(contextVk));
unsigned srcFormatSize = mCurrentArrayBufferFormats[attribIndex]->angleFormat().pixelBytes;
- unsigned dstFormatSize = mCurrentArrayBufferFormats[attribIndex]->bufferFormat().pixelBytes;
+ unsigned dstFormatSize = mCurrentArrayBufferStrides[attribIndex];
+
+ mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(contextVk->getRenderer());
// Bytes usable for vertex data.
GLint64 bytes = srcBuffer->getSize() - binding.getOffset();
@@ -195,20 +178,17 @@
numVertices += static_cast<size_t>(bytes) / binding.getStride();
void *src = nullptr;
- uint8_t *dst = nullptr;
-
- ANGLE_TRY(mCurrentArrayBufferConversion[attribIndex].allocate(
- context, numVertices * dstFormatSize, &dst, &mCurrentArrayBufferHandles[attribIndex],
- &mCurrentArrayBufferOffsets[attribIndex], nullptr));
- ANGLE_TRY(srcBuffer->mapImpl(context, &src));
- mCurrentArrayBufferFormats[attribIndex]->vertexLoadFunction(
- static_cast<const uint8_t *>(src) + binding.getOffset(), binding.getStride(), numVertices,
- dst);
- ANGLE_TRY(srcBuffer->unmapImpl(context));
- ANGLE_TRY(mCurrentArrayBufferConversion[attribIndex].flush(context));
+ ANGLE_TRY(srcBuffer->mapImpl(contextVk, &src));
+ const uint8_t *srcBytes = reinterpret_cast<const uint8_t *>(src);
+ srcBytes += binding.getOffset();
+ ANGLE_TRY(StreamVertexData(contextVk, &mCurrentArrayBufferConversion[attribIndex], srcBytes,
+ numVertices * dstFormatSize, 0, numVertices, binding.getStride(),
+ mCurrentArrayBufferFormats[attribIndex]->vertexLoadFunction,
+ &mCurrentArrayBufferHandles[attribIndex],
+ &mCurrentArrayBufferOffsets[attribIndex]));
+ ANGLE_TRY(srcBuffer->unmapImpl(contextVk));
mCurrentArrayBufferConversionCanRelease[attribIndex] = true;
- mCurrentArrayBufferStrides[attribIndex] = dstFormatSize;
return angle::Result::Continue();
}
@@ -335,9 +315,11 @@
if (mCurrentArrayBufferFormats[attribIndex]->vertexLoadRequiresConversion ||
!BindingIsAligned(binding, componentSize))
{
+ mCurrentArrayBufferStrides[attribIndex] =
+ mCurrentArrayBufferFormats[attribIndex]->bufferFormat().pixelBytes;
+
ANGLE_TRY(convertVertexBuffer(contextVk, bufferVk, binding, attribIndex));
- mCurrentArrayBufferConversion[attribIndex].releaseRetainedBuffers(renderer);
mCurrentArrayBufferResources[attribIndex] = nullptr;
releaseConversion = false;
}
@@ -565,7 +547,42 @@
if (clientAttribs.any())
{
ANGLE_TRY(drawCallParams.ensureIndexRangeResolved(context));
- ANGLE_TRY(streamVertexData(contextVk, clientAttribs, drawCallParams));
+
+ mDynamicVertexData.releaseRetainedBuffers(contextVk->getRenderer());
+
+ const auto &attribs = mState.getVertexAttributes();
+ const auto &bindings = mState.getVertexBindings();
+
+ // TODO(fjhenigman): When we have a bunch of interleaved attributes, they end up
+ // un-interleaved, wasting space and copying time. Consider improving on that.
+ for (size_t attribIndex : clientAttribs)
+ {
+ const gl::VertexAttribute &attrib = attribs[attribIndex];
+ const gl::VertexBinding &binding = bindings[attrib.bindingIndex];
+ ASSERT(attrib.enabled && binding.getBuffer().get() == nullptr);
+
+ const size_t bytesToAllocate =
+ (drawCallParams.firstVertex() + drawCallParams.vertexCount()) *
+ mCurrentArrayBufferStrides[attribIndex];
+ const uint8_t *src = static_cast<const uint8_t *>(attrib.pointer) +
+ drawCallParams.firstVertex() * binding.getStride();
+
+ size_t destOffset =
+ drawCallParams.firstVertex() * mCurrentArrayBufferStrides[attribIndex];
+
+ // Only vertexCount() vertices will be used by the upcoming draw so that is all we copy,
+ // but we allocate space firstVertex() + vertexCount() so indexing will work. If we
+ // don't start at zero all the indices will be off.
+ // TODO(fjhenigman): See if we can account for indices being off by adjusting the
+ // offset, thus avoiding wasted memory.
+ ANGLE_TRY(StreamVertexData(contextVk, &mDynamicVertexData, src, bytesToAllocate,
+ destOffset, drawCallParams.vertexCount(),
+ binding.getStride(),
+ mCurrentArrayBufferFormats[attribIndex]->vertexLoadFunction,
+ &mCurrentArrayBufferHandles[attribIndex],
+ &mCurrentArrayBufferOffsets[attribIndex]));
+ }
+
commandBuffer->bindVertexBuffers(0, maxAttrib, mCurrentArrayBufferHandles.data(),
mCurrentArrayBufferOffsets.data());
}