Commit 4abdf74f by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Add dynamic index buffers to graph

With DynamicBuffer outputting BufferHelper objects, these objects can participate in the command graph, i.e. record commands. This means they need appropriate dependencies in the graph as well as pipeline barriers. There are a few users of DynamicBuffer for which this change should be applied to. This change covers index buffers. This commit includes a fix to BufferHelper::copyFromBuffer for WaW hazards. It also includes a fix for a missing pipeline barrier after BufferVk::copyToBuffer. Bug: angleproject:2958 Change-Id: I3e61af56936580b2da20c28c45defece552d9a39 Reviewed-on: https://chromium-review.googlesource.com/c/1352732Reviewed-by: 's avatarTobin Ehlis <tobine@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent a9d579e8
......@@ -235,13 +235,18 @@ angle::Result BufferVk::setDataImpl(ContextVk *contextVk,
}
angle::Result BufferVk::copyToBuffer(ContextVk *contextVk,
VkBuffer destbuffer,
vk::BufferHelper *destBuffer,
uint32_t copyCount,
const VkBufferCopy *copies)
{
vk::CommandBuffer *commandBuffer;
ANGLE_TRY(mBuffer.recordCommands(contextVk, &commandBuffer));
commandBuffer->copyBuffer(mBuffer.getBuffer().getHandle(), destbuffer, copyCount, copies);
commandBuffer->copyBuffer(mBuffer.getBuffer().getHandle(), destBuffer->getBuffer().getHandle(),
copyCount, copies);
destBuffer->onRead(&mBuffer, VK_ACCESS_TRANSFER_READ_BIT);
mBuffer.onWrite(VK_ACCESS_TRANSFER_WRITE_BIT);
return angle::Result::Continue();
}
......
......@@ -73,7 +73,7 @@ class BufferVk : public BufferImpl
// Calls copyBuffer internally.
angle::Result copyToBuffer(ContextVk *contextVk,
VkBuffer destbuffer,
vk::BufferHelper *destBuffer,
uint32_t copyCount,
const VkBufferCopy *copies);
......
......@@ -434,7 +434,7 @@ angle::Result ContextVk::handleDirtyVertexBuffers(const gl::Context *context,
vk::BufferHelper *arrayBuffer = arrayBufferResources[attribIndex];
if (arrayBuffer)
{
arrayBuffer->onFramebufferRead(framebuffer, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT);
arrayBuffer->onRead(framebuffer, VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT);
}
}
......@@ -444,16 +444,16 @@ angle::Result ContextVk::handleDirtyVertexBuffers(const gl::Context *context,
angle::Result ContextVk::handleDirtyIndexBuffer(const gl::Context *context,
vk::CommandBuffer *commandBuffer)
{
commandBuffer->bindIndexBuffer(mVertexArray->getCurrentElementArrayBufferHandle(),
vk::BufferHelper *elementArrayBuffer = mVertexArray->getCurrentElementArrayBuffer();
ASSERT(elementArrayBuffer != nullptr);
commandBuffer->bindIndexBuffer(elementArrayBuffer->getBuffer().getHandle(),
mVertexArray->getCurrentElementArrayBufferOffset(),
gl_vk::kIndexTypeMap[mCurrentDrawElementsType]);
vk::BufferHelper *elementArrayBuffer = mVertexArray->getCurrentElementArrayBuffer();
if (elementArrayBuffer)
{
vk::FramebufferHelper *framebuffer = mDrawFramebuffer->getFramebuffer();
elementArrayBuffer->onFramebufferRead(framebuffer, VK_ACCESS_INDEX_READ_BIT);
}
elementArrayBuffer->onRead(framebuffer, VK_ACCESS_INDEX_READ_BIT);
return angle::Result::Continue();
}
......
......@@ -90,7 +90,6 @@ VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state, RendererVk *rend
INIT,
}},
mCurrentArrayBufferConversionCanRelease{},
mCurrentElementArrayBufferHandle(VK_NULL_HANDLE),
mCurrentElementArrayBufferOffset(0),
mCurrentElementArrayBuffer(nullptr),
mPackedInputBindings{},
......@@ -146,8 +145,9 @@ angle::Result VertexArrayVk::streamIndexData(ContextVk *contextVk,
const size_t amount = sizeof(GLushort) * indexCount;
GLubyte *dst = nullptr;
ANGLE_TRY(dynamicBuffer->allocate(contextVk, amount, &dst, &mCurrentElementArrayBufferHandle,
ANGLE_TRY(dynamicBuffer->allocate(contextVk, amount, &dst, nullptr,
&mCurrentElementArrayBufferOffset, nullptr));
mCurrentElementArrayBuffer = dynamicBuffer->getCurrentBuffer();
if (indexType == gl::DrawElementsType::UnsignedByte)
{
// Unsigned bytes don't have direct support in Vulkan so we have to expand the
......@@ -272,13 +272,10 @@ angle::Result VertexArrayVk::syncState(const gl::Context *context,
{
BufferVk *bufferVk = vk::GetImpl(bufferGL);
mCurrentElementArrayBuffer = &bufferVk->getBuffer();
mCurrentElementArrayBufferHandle =
bufferVk->getBuffer().getBuffer().getHandle();
}
else
{
mCurrentElementArrayBuffer = nullptr;
mCurrentElementArrayBufferHandle = VK_NULL_HANDLE;
}
mCurrentElementArrayBufferOffset = 0;
......@@ -512,7 +509,7 @@ angle::Result VertexArrayVk::handleLineLoop(ContextVk *contextVk,
{
ANGLE_TRY(mLineLoopHelper.streamIndices(
contextVk, indexTypeOrInvalid, vertexOrIndexCount,
reinterpret_cast<const uint8_t *>(indices), &mCurrentElementArrayBufferHandle,
reinterpret_cast<const uint8_t *>(indices), &mCurrentElementArrayBuffer,
&mCurrentElementArrayBufferOffset));
}
else
......@@ -522,7 +519,7 @@ angle::Result VertexArrayVk::handleLineLoop(ContextVk *contextVk,
BufferVk *elementArrayBufferVk = vk::GetImpl(elementArrayBuffer);
ANGLE_TRY(mLineLoopHelper.getIndexBufferForElementArrayBuffer(
contextVk, elementArrayBufferVk, indexTypeOrInvalid, vertexOrIndexCount, offset,
&mCurrentElementArrayBufferHandle, &mCurrentElementArrayBufferOffset));
&mCurrentElementArrayBuffer, &mCurrentElementArrayBufferOffset));
}
}
......@@ -543,7 +540,7 @@ angle::Result VertexArrayVk::handleLineLoop(ContextVk *contextVk,
mLineLoopBufferFirstIndex != firstVertex || mLineLoopBufferLastIndex != lastVertex)
{
ANGLE_TRY(mLineLoopHelper.getIndexBufferForDrawArrays(
contextVk, clampedVertexCount, firstVertex, &mCurrentElementArrayBufferHandle,
contextVk, clampedVertexCount, firstVertex, &mCurrentElementArrayBuffer,
&mCurrentElementArrayBufferOffset));
mLineLoopBufferFirstIndex = firstVertex;
......
......@@ -70,8 +70,6 @@ class VertexArrayVk : public VertexArrayImpl
return mCurrentArrayBuffers;
}
VkBuffer getCurrentElementArrayBufferHandle() const { return mCurrentElementArrayBufferHandle; }
VkDeviceSize getCurrentElementArrayBufferOffset() const
{
return mCurrentElementArrayBufferOffset;
......@@ -123,7 +121,6 @@ class VertexArrayVk : public VertexArrayImpl
gl::AttribArray<GLuint> mCurrentArrayBufferStrides;
gl::AttribArray<vk::DynamicBuffer> mCurrentArrayBufferConversion;
gl::AttribArray<bool> mCurrentArrayBufferConversionCanRelease;
VkBuffer mCurrentElementArrayBufferHandle;
VkDeviceSize mCurrentElementArrayBufferOffset;
vk::BufferHelper *mCurrentElementArrayBuffer;
......
......@@ -747,7 +747,7 @@ LineLoopHelper::~LineLoopHelper() = default;
angle::Result LineLoopHelper::getIndexBufferForDrawArrays(ContextVk *contextVk,
uint32_t clampedVertexCount,
GLint firstVertex,
VkBuffer *bufferHandleOut,
vk::BufferHelper **bufferOut,
VkDeviceSize *offsetOut)
{
uint32_t *indices = nullptr;
......@@ -755,8 +755,9 @@ angle::Result LineLoopHelper::getIndexBufferForDrawArrays(ContextVk *contextVk,
mDynamicIndexBuffer.releaseRetainedBuffers(contextVk->getRenderer());
ANGLE_TRY(mDynamicIndexBuffer.allocate(contextVk, allocateBytes,
reinterpret_cast<uint8_t **>(&indices), bufferHandleOut,
reinterpret_cast<uint8_t **>(&indices), nullptr,
offsetOut, nullptr));
*bufferOut = mDynamicIndexBuffer.getCurrentBuffer();
// Note: there could be an overflow in this addition.
uint32_t unsignedFirstVertex = static_cast<uint32_t>(firstVertex);
......@@ -780,7 +781,7 @@ angle::Result LineLoopHelper::getIndexBufferForElementArrayBuffer(ContextVk *con
gl::DrawElementsType glIndexType,
int indexCount,
intptr_t elementArrayOffset,
VkBuffer *bufferHandleOut,
vk::BufferHelper **bufferOut,
VkDeviceSize *bufferOffsetOut)
{
if (glIndexType == gl::DrawElementsType::UnsignedByte)
......@@ -792,7 +793,7 @@ angle::Result LineLoopHelper::getIndexBufferForElementArrayBuffer(ContextVk *con
ANGLE_TRY(elementArrayBufferVk->mapImpl(contextVk, &srcDataMapping));
ANGLE_TRY(streamIndices(contextVk, glIndexType, indexCount,
static_cast<const uint8_t *>(srcDataMapping) + elementArrayOffset,
bufferHandleOut, bufferOffsetOut));
bufferOut, bufferOffsetOut));
ANGLE_TRY(elementArrayBufferVk->unmapImpl(contextVk));
return angle::Result::Continue();
}
......@@ -806,8 +807,9 @@ angle::Result LineLoopHelper::getIndexBufferForElementArrayBuffer(ContextVk *con
mDynamicIndexBuffer.releaseRetainedBuffers(contextVk->getRenderer());
ANGLE_TRY(mDynamicIndexBuffer.allocate(contextVk, allocateBytes,
reinterpret_cast<uint8_t **>(&indices), bufferHandleOut,
reinterpret_cast<uint8_t **>(&indices), nullptr,
bufferOffsetOut, nullptr));
*bufferOut = mDynamicIndexBuffer.getCurrentBuffer();
VkDeviceSize sourceOffset = static_cast<VkDeviceSize>(elementArrayOffset);
uint64_t unitCount = static_cast<VkDeviceSize>(indexCount);
......@@ -818,8 +820,8 @@ angle::Result LineLoopHelper::getIndexBufferForElementArrayBuffer(ContextVk *con
if (contextVk->getRenderer()->getFeatures().extraCopyBufferRegion)
copies.push_back({sourceOffset, *bufferOffsetOut + (unitCount + 1) * unitSize, 1});
ANGLE_TRY(elementArrayBufferVk->copyToBuffer(contextVk, *bufferHandleOut, copies.size(),
copies.data()));
ANGLE_TRY(
elementArrayBufferVk->copyToBuffer(contextVk, *bufferOut, copies.size(), copies.data()));
ANGLE_TRY(mDynamicIndexBuffer.flush(contextVk));
return angle::Result::Continue();
}
......@@ -828,7 +830,7 @@ angle::Result LineLoopHelper::streamIndices(ContextVk *contextVk,
gl::DrawElementsType glIndexType,
GLsizei indexCount,
const uint8_t *srcPtr,
VkBuffer *bufferHandleOut,
vk::BufferHelper **bufferOut,
VkDeviceSize *bufferOffsetOut)
{
VkIndexType indexType = gl_vk::kIndexTypeMap[glIndexType];
......@@ -838,8 +840,9 @@ angle::Result LineLoopHelper::streamIndices(ContextVk *contextVk,
auto unitSize = (indexType == VK_INDEX_TYPE_UINT16 ? sizeof(uint16_t) : sizeof(uint32_t));
size_t allocateBytes = unitSize * (indexCount + 1);
ANGLE_TRY(mDynamicIndexBuffer.allocate(contextVk, allocateBytes,
reinterpret_cast<uint8_t **>(&indices), bufferHandleOut,
reinterpret_cast<uint8_t **>(&indices), nullptr,
bufferOffsetOut, nullptr));
*bufferOut = mDynamicIndexBuffer.getCurrentBuffer();
if (glIndexType == gl::DrawElementsType::UnsignedByte)
{
......@@ -923,17 +926,28 @@ void BufferHelper::release(RendererVk *renderer)
renderer->releaseObject(getStoredQueueSerial(), &mDeviceMemory);
}
void BufferHelper::onFramebufferRead(FramebufferHelper *framebuffer, VkAccessFlagBits accessType)
void BufferHelper::onRead(RecordableGraphResource *reader, VkAccessFlagBits readAccessType)
{
addReadDependency(framebuffer);
addReadDependency(reader);
if ((mCurrentWriteAccess != 0) && ((mCurrentReadAccess & accessType) == 0))
if (mCurrentWriteAccess != 0 && (mCurrentReadAccess & readAccessType) == 0)
{
framebuffer->addGlobalMemoryBarrier(mCurrentWriteAccess, accessType);
mCurrentReadAccess |= accessType;
reader->addGlobalMemoryBarrier(mCurrentWriteAccess, readAccessType);
mCurrentReadAccess |= readAccessType;
}
}
void BufferHelper::onWrite(VkAccessFlagBits writeAccessType)
{
if (mCurrentReadAccess != 0 || mCurrentWriteAccess != 0)
{
addGlobalMemoryBarrier(mCurrentReadAccess | mCurrentWriteAccess, writeAccessType);
}
mCurrentWriteAccess = writeAccessType;
mCurrentReadAccess = 0;
}
angle::Result BufferHelper::copyFromBuffer(Context *context,
const Buffer &buffer,
const VkBufferCopy &copyRegion)
......@@ -948,7 +962,7 @@ angle::Result BufferHelper::copyFromBuffer(Context *context,
// Use a global memory barrier to keep things simple.
VkMemoryBarrier memoryBarrier = {};
memoryBarrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
memoryBarrier.srcAccessMask = mCurrentReadAccess;
memoryBarrier.srcAccessMask = mCurrentReadAccess | mCurrentWriteAccess;
memoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
commandBuffer->pipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
......
......@@ -346,7 +346,7 @@ class LineLoopHelper final : angle::NonCopyable
angle::Result getIndexBufferForDrawArrays(ContextVk *contextVk,
uint32_t clampedVertexCount,
GLint firstVertex,
VkBuffer *bufferHandleOut,
vk::BufferHelper **bufferOut,
VkDeviceSize *offsetOut);
angle::Result getIndexBufferForElementArrayBuffer(ContextVk *contextVk,
......@@ -354,14 +354,14 @@ class LineLoopHelper final : angle::NonCopyable
gl::DrawElementsType glIndexType,
int indexCount,
intptr_t elementArrayOffset,
VkBuffer *bufferHandleOut,
vk::BufferHelper **bufferOut,
VkDeviceSize *bufferOffsetOut);
angle::Result streamIndices(ContextVk *contextVk,
gl::DrawElementsType glIndexType,
GLsizei indexCount,
const uint8_t *srcPtr,
VkBuffer *bufferHandleOut,
vk::BufferHelper **bufferOut,
VkDeviceSize *bufferOffsetOut);
void release(RendererVk *renderer);
......@@ -391,8 +391,9 @@ class BufferHelper final : public RecordableGraphResource
const Buffer &getBuffer() const { return mBuffer; }
const DeviceMemory &getDeviceMemory() const { return mDeviceMemory; }
// Helper for setting the graph dependencies *and* setting the appropriate barrier.
void onFramebufferRead(FramebufferHelper *framebuffer, VkAccessFlagBits accessType);
// Helpers for setting the graph dependencies *and* setting the appropriate barrier.
void onRead(RecordableGraphResource *reader, VkAccessFlagBits readAccessType);
void onWrite(VkAccessFlagBits writeAccessType);
// Also implicitly sets up the correct barriers.
angle::Result copyFromBuffer(Context *context,
......
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