Commit c972435b by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Support non-pow2 buffer alignments

Bug: angleproject:2898 Change-Id: I7c8e548a1a449f48225516c37d830ecc201b064d Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1762496Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org>
parent 1d83e1e8
...@@ -38,8 +38,9 @@ constexpr unsigned int kEmulatedAlphaValue = 1; ...@@ -38,8 +38,9 @@ constexpr unsigned int kEmulatedAlphaValue = 1;
constexpr size_t kMinReadPixelsBufferSize = 128000; constexpr size_t kMinReadPixelsBufferSize = 128000;
// Alignment value to accommodate the largest known, for now, uncompressed Vulkan format // Alignment value to accommodate the largest known, for now, uncompressed Vulkan format
// VK_FORMAT_R64G64B64A64_SFLOAT // VK_FORMAT_R64G64B64A64_SFLOAT, while supporting 3-component types such as
constexpr size_t kReadPixelsBufferAlignment = 32; // VK_FORMAT_R16G16B16_SFLOAT.
constexpr size_t kReadPixelsBufferAlignment = 32 * 3;
// Clear values are only used when loadOp=Clear is set in clearWithRenderPassOp. When starting a // Clear values are only used when loadOp=Clear is set in clearWithRenderPassOp. When starting a
// new render pass, the clear value is set to an unlikely value (bright pink) to stand out better // new render pass, the clear value is set to an unlikely value (bright pink) to stand out better
......
...@@ -330,7 +330,7 @@ angle::Result DynamicBuffer::allocate(ContextVk *contextVk, ...@@ -330,7 +330,7 @@ angle::Result DynamicBuffer::allocate(ContextVk *contextVk,
VkDeviceSize *offsetOut, VkDeviceSize *offsetOut,
bool *newBufferAllocatedOut) bool *newBufferAllocatedOut)
{ {
size_t sizeToAllocate = roundUpPow2(sizeInBytes, mAlignment); size_t sizeToAllocate = roundUp(sizeInBytes, mAlignment);
angle::base::CheckedNumeric<size_t> checkedNextWriteOffset = mNextAllocationOffset; angle::base::CheckedNumeric<size_t> checkedNextWriteOffset = mNextAllocationOffset;
checkedNextWriteOffset += sizeToAllocate; checkedNextWriteOffset += sizeToAllocate;
...@@ -546,17 +546,30 @@ void DynamicBuffer::updateAlignment(RendererVk *renderer, size_t alignment) ...@@ -546,17 +546,30 @@ void DynamicBuffer::updateAlignment(RendererVk *renderer, size_t alignment)
size_t atomSize = size_t atomSize =
static_cast<size_t>(renderer->getPhysicalDeviceProperties().limits.nonCoherentAtomSize); static_cast<size_t>(renderer->getPhysicalDeviceProperties().limits.nonCoherentAtomSize);
// We need lcm(alignment, atomSize), we are assuming one divides the other so std::max() could // We need lcm(alignment, atomSize). Usually, one divides the other so std::max() could be used
// be used instead. // instead. Only known case where this assumption breaks is for 3-component types with 16- or
ASSERT(alignment % atomSize == 0 || atomSize % alignment == 0); // 32-bit channels, so that's special-cased to avoid a full-fledged lcm implementation.
alignment = std::max(alignment, atomSize);
ASSERT(gl::isPow2(alignment)); if (gl::isPow2(alignment))
{
ASSERT(alignment % atomSize == 0 || atomSize % alignment == 0);
ASSERT(gl::isPow2(atomSize));
alignment = std::max(alignment, atomSize);
}
else
{
ASSERT(gl::isPow2(atomSize));
ASSERT(alignment % 3 == 0);
ASSERT(gl::isPow2(alignment / 3));
alignment = std::max(alignment / 3, atomSize) * 3;
}
// If alignment has changed, make sure the next allocation is done at an aligned offset. // If alignment has changed, make sure the next allocation is done at an aligned offset.
if (alignment != mAlignment) if (alignment != mAlignment)
{ {
mNextAllocationOffset = mNextAllocationOffset = roundUp(mNextAllocationOffset, static_cast<uint32_t>(alignment));
roundUpPow2(mNextAllocationOffset, static_cast<uint32_t>(alignment));
} }
mAlignment = alignment; mAlignment = alignment;
......
...@@ -93,7 +93,6 @@ class DynamicBuffer : angle::NonCopyable ...@@ -93,7 +93,6 @@ class DynamicBuffer : angle::NonCopyable
BufferHelper *getCurrentBuffer() { return mBuffer; } BufferHelper *getCurrentBuffer() { return mBuffer; }
size_t getAlignment() { return mAlignment; }
void updateAlignment(RendererVk *renderer, size_t alignment); void updateAlignment(RendererVk *renderer, size_t alignment);
// For testing only! // For testing only!
......
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