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, ...@@ -1295,13 +1295,16 @@ bool DynamicBuffer::allocateFromCurrentBuffer(size_t sizeInBytes,
return true; return true;
} }
angle::Result DynamicBuffer::allocate(ContextVk *contextVk, angle::Result DynamicBuffer::allocateWithAlignment(ContextVk *contextVk,
size_t sizeInBytes, size_t sizeInBytes,
uint8_t **ptrOut, size_t alignment,
VkBuffer *bufferOut, uint8_t **ptrOut,
VkDeviceSize *offsetOut, VkBuffer *bufferOut,
bool *newBufferAllocatedOut) VkDeviceSize *offsetOut,
{ bool *newBufferAllocatedOut)
{
mNextAllocationOffset =
roundUp<uint32_t>(mNextAllocationOffset, static_cast<uint32_t>(alignment));
size_t sizeToAllocate = roundUp(sizeInBytes, mAlignment); size_t sizeToAllocate = roundUp(sizeInBytes, mAlignment);
angle::base::CheckedNumeric<size_t> checkedNextWriteOffset = mNextAllocationOffset; angle::base::CheckedNumeric<size_t> checkedNextWriteOffset = mNextAllocationOffset;
...@@ -3870,8 +3873,10 @@ angle::Result ImageHelper::stageSubresourceUpdateImpl(ContextVk *contextVk, ...@@ -3870,8 +3873,10 @@ angle::Result ImageHelper::stageSubresourceUpdateImpl(ContextVk *contextVk,
VkDeviceSize stagingOffset = 0; VkDeviceSize stagingOffset = 0;
// If caller has provided a staging buffer, use it. // If caller has provided a staging buffer, use it.
DynamicBuffer *stagingBuffer = stagingBufferOverride ? stagingBufferOverride : &mStagingBuffer; DynamicBuffer *stagingBuffer = stagingBufferOverride ? stagingBufferOverride : &mStagingBuffer;
ANGLE_TRY(stagingBuffer->allocate(contextVk, allocationSize, &stagingPointer, &bufferHandle, size_t alignment = mStagingBuffer.getAlignment();
&stagingOffset, nullptr)); ANGLE_TRY(stagingBuffer->allocateWithAlignment(contextVk, allocationSize, alignment,
&stagingPointer, &bufferHandle, &stagingOffset,
nullptr));
BufferHelper *currentBuffer = stagingBuffer->getCurrentBuffer(); BufferHelper *currentBuffer = stagingBuffer->getCurrentBuffer();
const uint8_t *source = pixels + static_cast<ptrdiff_t>(inputSkipBytes); const uint8_t *source = pixels + static_cast<ptrdiff_t>(inputSkipBytes);
...@@ -4754,8 +4759,10 @@ angle::Result ImageHelper::copyImageDataToBuffer(ContextVk *contextVk, ...@@ -4754,8 +4759,10 @@ angle::Result ImageHelper::copyImageDataToBuffer(ContextVk *contextVk,
// Allocate staging buffer data from context // Allocate staging buffer data from context
VkBuffer bufferHandle; VkBuffer bufferHandle;
ANGLE_TRY(contextVk->getStagingBuffer()->allocate( size_t alignment = mStagingBuffer.getAlignment();
contextVk, *bufferSize, outDataPtr, &bufferHandle, &(*bufferOffsetsOut)[0], nullptr)); ANGLE_TRY(contextVk->getStagingBuffer()->allocateWithAlignment(
contextVk, *bufferSize, alignment, outDataPtr, &bufferHandle, &(*bufferOffsetsOut)[0],
nullptr));
*bufferOut = contextVk->getStagingBuffer()->getCurrentBuffer(); *bufferOut = contextVk->getStagingBuffer()->getCurrentBuffer();
uint32_t sourceLevelVk = static_cast<uint32_t>(sourceLevelGL) - mBaseLevel; uint32_t sourceLevelVk = static_cast<uint32_t>(sourceLevelGL) - mBaseLevel;
......
...@@ -88,12 +88,25 @@ class DynamicBuffer : angle::NonCopyable ...@@ -88,12 +88,25 @@ class DynamicBuffer : angle::NonCopyable
// a new buffer to be created (which is returned in the optional parameter // 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 // `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. // a memory pointer is given, the buffer will be automatically map()ed.
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, angle::Result allocate(ContextVk *contextVk,
size_t sizeInBytes, size_t sizeInBytes,
uint8_t **ptrOut, uint8_t **ptrOut,
VkBuffer *bufferOut, VkBuffer *bufferOut,
VkDeviceSize *offsetOut, VkDeviceSize *offsetOut,
bool *newBufferAllocatedOut); 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. // After a sequence of writes, call flush to ensure the data is visible to the device.
angle::Result flush(ContextVk *contextVk); angle::Result flush(ContextVk *contextVk);
...@@ -120,6 +133,7 @@ class DynamicBuffer : angle::NonCopyable ...@@ -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 // 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. // lcm of all alignments set in its lifetime.
void requireAlignment(RendererVk *renderer, size_t alignment); void requireAlignment(RendererVk *renderer, size_t alignment);
size_t getAlignment() const { return mAlignment; }
// For testing only! // For testing only!
void setMinimumSizeForTesting(size_t minSize); 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