Commit 9e544a84 by Charlie Lao Committed by Commit Bot

Vulkan: Fix alignment issue with context staging buffer

Context's staging buffer is shared for all kind of usages. We should pass in alignment requirement for allocate call whenever it is different from the default alignment. This adds allocateWithAlignment call to DynamicBuffer call and switch ImgeHelper's usage of it to allocateWithAlignment Bug: b/164511310 Change-Id: Idcb6b6f95d6862ee6cb8fca9c164910b7e085a17 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2373590 Commit-Queue: Charlie Lao <cclao@google.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTim Van Patten <timvp@google.com>
parent 1c654d54
......@@ -1295,13 +1295,16 @@ bool DynamicBuffer::allocateFromCurrentBuffer(size_t sizeInBytes,
return true;
}
angle::Result DynamicBuffer::allocate(ContextVk *contextVk,
angle::Result DynamicBuffer::allocateWithAlignment(ContextVk *contextVk,
size_t sizeInBytes,
size_t alignment,
uint8_t **ptrOut,
VkBuffer *bufferOut,
VkDeviceSize *offsetOut,
bool *newBufferAllocatedOut)
{
mNextAllocationOffset =
roundUp<uint32_t>(mNextAllocationOffset, static_cast<uint32_t>(alignment));
size_t sizeToAllocate = roundUp(sizeInBytes, mAlignment);
angle::base::CheckedNumeric<size_t> checkedNextWriteOffset = mNextAllocationOffset;
......@@ -3870,8 +3873,10 @@ angle::Result ImageHelper::stageSubresourceUpdateImpl(ContextVk *contextVk,
VkDeviceSize stagingOffset = 0;
// If caller has provided a staging buffer, use it.
DynamicBuffer *stagingBuffer = stagingBufferOverride ? stagingBufferOverride : &mStagingBuffer;
ANGLE_TRY(stagingBuffer->allocate(contextVk, allocationSize, &stagingPointer, &bufferHandle,
&stagingOffset, nullptr));
size_t alignment = mStagingBuffer.getAlignment();
ANGLE_TRY(stagingBuffer->allocateWithAlignment(contextVk, allocationSize, alignment,
&stagingPointer, &bufferHandle, &stagingOffset,
nullptr));
BufferHelper *currentBuffer = stagingBuffer->getCurrentBuffer();
const uint8_t *source = pixels + static_cast<ptrdiff_t>(inputSkipBytes);
......@@ -4754,8 +4759,10 @@ angle::Result ImageHelper::copyImageDataToBuffer(ContextVk *contextVk,
// Allocate staging buffer data from context
VkBuffer bufferHandle;
ANGLE_TRY(contextVk->getStagingBuffer()->allocate(
contextVk, *bufferSize, outDataPtr, &bufferHandle, &(*bufferOffsetsOut)[0], nullptr));
size_t alignment = mStagingBuffer.getAlignment();
ANGLE_TRY(contextVk->getStagingBuffer()->allocateWithAlignment(
contextVk, *bufferSize, alignment, outDataPtr, &bufferHandle, &(*bufferOffsetsOut)[0],
nullptr));
*bufferOut = contextVk->getStagingBuffer()->getCurrentBuffer();
uint32_t sourceLevelVk = static_cast<uint32_t>(sourceLevelGL) - mBaseLevel;
......
......@@ -88,13 +88,26 @@ class DynamicBuffer : angle::NonCopyable
// 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
// a memory pointer is given, the buffer will be automatically map()ed.
angle::Result allocate(ContextVk *contextVk,
angle::Result allocateWithAlignment(ContextVk *contextVk,
size_t sizeInBytes,
size_t alignment,
uint8_t **ptrOut,
VkBuffer *bufferOut,
VkDeviceSize *offsetOut,
bool *newBufferAllocatedOut);
// Allocate with default alignment
angle::Result allocate(ContextVk *contextVk,
size_t sizeInBytes,
uint8_t **ptrOut,
VkBuffer *bufferOut,
VkDeviceSize *offsetOut,
bool *newBufferAllocatedOut)
{
return allocateWithAlignment(contextVk, sizeInBytes, mAlignment, ptrOut, bufferOut,
offsetOut, newBufferAllocatedOut);
}
// After a sequence of writes, call flush to ensure the data is visible to the device.
angle::Result flush(ContextVk *contextVk);
......@@ -120,6 +133,7 @@ class DynamicBuffer : angle::NonCopyable
// The staging buffer should have an alignment that can satisfy all those formats, i.e. it's the
// lcm of all alignments set in its lifetime.
void requireAlignment(RendererVk *renderer, size_t alignment);
size_t getAlignment() const { return mAlignment; }
// For testing only!
void setMinimumSizeForTesting(size_t minSize);
......
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