Commit 7f2520f1 by Jamie Madill Committed by Commit Bot

Vulkan: Refactor DynamicBuffer::init.

This will allow us to more easily create a white box test that sets a very small initial size for a dynamic buffer. Bug: angleproject:3082 Change-Id: Ic02bbee83ee8e0f4bfe182e9448c2ce60dea66d5 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1667645 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarTobin Ehlis <tobine@google.com>
parent 8929b9c5
......@@ -36,9 +36,9 @@ ConversionBuffer::ConversionBuffer(RendererVk *renderer,
VkBufferUsageFlags usageFlags,
size_t initialSize,
size_t alignment)
: dirty(true), lastAllocationOffset(0), data(usageFlags, initialSize, true)
: dirty(true), lastAllocationOffset(0)
{
data.init(alignment, renderer);
data.init(renderer, usageFlags, alignment, initialSize, true);
}
ConversionBuffer::~ConversionBuffer() = default;
......
......@@ -138,12 +138,6 @@ void ApplySampleCoverage(const gl::State &glState,
} // anonymous namespace
// std::array only uses aggregate init. Thus we make a helper macro to reduce on code duplication.
#define INIT \
{ \
kVertexBufferUsage, kDefaultBufferSize, true \
}
// CommandBatch implementation.
ContextVk::CommandBatch::CommandBatch() = default;
......@@ -182,11 +176,8 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mClearColorMask(kAllColorChannelsMask),
mFlipYForCurrentSurface(false),
mIsAnyHostVisibleBufferWritten(false),
mDriverUniformsBuffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, sizeof(DriverUniforms) * 16, true),
mDriverUniformsDescriptorSet(VK_NULL_HANDLE),
mDriverUniformsDynamicOffset(0),
mDefaultAttribBuffers{{INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT,
INIT, INIT, INIT, INIT}},
mLastCompletedQueueSerial(renderer->nextSerial()),
mCurrentQueueSerial(renderer->nextSerial()),
mPoolAllocator(kDefaultPoolAllocatorPageSize, 1),
......@@ -227,8 +218,6 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mPipelineDirtyBitsMask.reset(gl::State::DIRTY_BIT_TEXTURE_BINDINGS);
}
#undef INIT
ContextVk::~ContextVk() = default;
void ContextVk::onDestroy(const gl::Context *context)
......@@ -300,7 +289,8 @@ angle::Result ContextVk::initialize()
size_t minAlignment = static_cast<size_t>(
mRenderer->getPhysicalDeviceProperties().limits.minUniformBufferOffsetAlignment);
mDriverUniformsBuffer.init(minAlignment, mRenderer);
mDriverUniformsBuffer.init(mRenderer, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, minAlignment,
sizeof(DriverUniforms) * 16, true);
// Get the descriptor set layout.
vk::DescriptorSetLayoutDesc desc = getDriverUniformsDescriptorSetDesc();
......@@ -312,7 +302,7 @@ angle::Result ContextVk::initialize()
// Initialize current value/default attribute buffers.
for (vk::DynamicBuffer &buffer : mDefaultAttribBuffers)
{
buffer.init(1, mRenderer);
buffer.init(mRenderer, kVertexBufferUsage, 1, kDefaultBufferSize, true);
}
// Initialize the command pool now that we know the queue family index.
......
......@@ -162,14 +162,10 @@ FramebufferVk *FramebufferVk::CreateDefaultFBO(RendererVk *renderer,
FramebufferVk::FramebufferVk(RendererVk *renderer,
const gl::FramebufferState &state,
WindowSurfaceVk *backbuffer)
: FramebufferImpl(state),
mBackbuffer(backbuffer),
mActiveColorComponents(0),
mReadPixelBuffer(VK_BUFFER_USAGE_TRANSFER_DST_BIT, kMinReadPixelsBufferSize, true),
mBlitPixelBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, kMinReadPixelsBufferSize, true)
: FramebufferImpl(state), mBackbuffer(backbuffer), mActiveColorComponents(0)
{
mBlitPixelBuffer.init(1, renderer);
mReadPixelBuffer.init(4, renderer);
mReadPixelBuffer.init(renderer, VK_BUFFER_USAGE_TRANSFER_DST_BIT, 4, kMinReadPixelsBufferSize,
true);
}
FramebufferVk::~FramebufferVk() = default;
......@@ -180,7 +176,6 @@ void FramebufferVk::destroy(const gl::Context *context)
mFramebuffer.release(contextVk);
mReadPixelBuffer.release(contextVk);
mBlitPixelBuffer.release(contextVk);
}
angle::Result FramebufferVk::discard(const gl::Context *context,
......
......@@ -192,7 +192,6 @@ class FramebufferVk : public FramebufferImpl
VkColorComponentFlags mActiveColorComponents;
gl::DrawBufferMask mActiveColorComponentMasksForClear[4];
vk::DynamicBuffer mReadPixelBuffer;
vk::DynamicBuffer mBlitPixelBuffer;
// When we draw to the framebuffer, and the real format has an alpha channel but the format of
// the framebuffer does not, we need to mask out the alpha channel. This DrawBufferMask will
......
......@@ -213,11 +213,7 @@ void ProgramVk::ShaderInfo::release(ContextVk *contextVk)
}
// ProgramVk implementation.
ProgramVk::DefaultUniformBlock::DefaultUniformBlock()
: storage(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
kUniformBlockDynamicBufferMinSize,
true)
{}
ProgramVk::DefaultUniformBlock::DefaultUniformBlock() {}
ProgramVk::DefaultUniformBlock::~DefaultUniformBlock() = default;
......@@ -470,7 +466,9 @@ angle::Result ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
size_t minAlignment = static_cast<size_t>(
renderer->getPhysicalDeviceProperties().limits.minUniformBufferOffsetAlignment);
mDefaultUniformBlocks[shaderType].storage.init(minAlignment, renderer);
mDefaultUniformBlocks[shaderType].storage.init(
renderer, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
minAlignment, kUniformBlockDynamicBufferMinSize, true);
// Initialize uniform buffer memory to zero by default.
mDefaultUniformBlocks[shaderType].uniformData.fill(0);
......
......@@ -92,9 +92,6 @@ VertexArrayVk::VertexArrayVk(ContextVk *contextVk, const gl::VertexArrayState &s
mCurrentArrayBuffers{},
mCurrentElementArrayBufferOffset(0),
mCurrentElementArrayBuffer(nullptr),
mDynamicVertexData(vk::kVertexBufferUsageFlags, kDynamicVertexDataSize, true),
mDynamicIndexData(vk::kIndexBufferUsageFlags, kDynamicIndexDataSize, true),
mTranslatedByteIndexData(vk::kIndexBufferUsageFlags, kDynamicIndexDataSize, true),
mLineLoopHelper(contextVk->getRenderer()),
mDirtyLineLoopTranslation(true)
{
......@@ -110,12 +107,15 @@ VertexArrayVk::VertexArrayVk(ContextVk *contextVk, const gl::VertexArrayState &s
mCurrentArrayBufferOffsets.fill(0);
mCurrentArrayBuffers.fill(&mTheNullBuffer);
mDynamicVertexData.init(vk::kVertexBufferAlignment, renderer);
mDynamicVertexData.init(renderer, vk::kVertexBufferUsageFlags, vk::kVertexBufferAlignment,
kDynamicVertexDataSize, true);
// We use an alignment of four for index data. This ensures that compute shaders can read index
// elements from "uint" aligned addresses.
mDynamicIndexData.init(vk::kIndexBufferAlignment, renderer);
mTranslatedByteIndexData.init(vk::kIndexBufferAlignment, renderer);
mDynamicIndexData.init(renderer, vk::kIndexBufferUsageFlags, vk::kIndexBufferAlignment,
kDynamicIndexDataSize, true);
mTranslatedByteIndexData.init(renderer, vk::kIndexBufferUsageFlags, vk::kIndexBufferAlignment,
kDynamicIndexDataSize, true);
}
VertexArrayVk::~VertexArrayVk() {}
......
......@@ -36,7 +36,7 @@ constexpr VkClearDepthStencilValue kWebGLInitDepthStencilValue = {1.0f, 0};
constexpr VkBufferUsageFlags kLineLoopDynamicBufferUsage =
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
constexpr int kLineLoopDynamicBufferMinSize = 1024 * 1024;
constexpr int kLineLoopDynamicBufferInitialSize = 1024 * 1024;
// This is an arbitrary max. We can change this later if necessary.
constexpr uint32_t kDefaultDescriptorPoolMaxSets = 128;
......@@ -242,10 +242,10 @@ void HandlePrimitiveRestart(gl::DrawElementsType glIndexType,
} // anonymous namespace
// DynamicBuffer implementation.
DynamicBuffer::DynamicBuffer(VkBufferUsageFlags usage, size_t minSize, bool hostVisible)
: mUsage(usage),
mHostVisible(hostVisible),
mMinSize(minSize),
DynamicBuffer::DynamicBuffer()
: mUsage(0),
mHostVisible(false),
mInitialSize(0),
mBuffer(nullptr),
mNextAllocationOffset(0),
mLastFlushOrInvalidateOffset(0),
......@@ -256,7 +256,7 @@ DynamicBuffer::DynamicBuffer(VkBufferUsageFlags usage, size_t minSize, bool host
DynamicBuffer::DynamicBuffer(DynamicBuffer &&other)
: mUsage(other.mUsage),
mHostVisible(other.mHostVisible),
mMinSize(other.mMinSize),
mInitialSize(other.mInitialSize),
mBuffer(other.mBuffer),
mNextAllocationOffset(other.mNextAllocationOffset),
mLastFlushOrInvalidateOffset(other.mLastFlushOrInvalidateOffset),
......@@ -267,13 +267,21 @@ DynamicBuffer::DynamicBuffer(DynamicBuffer &&other)
other.mBuffer = nullptr;
}
void DynamicBuffer::init(size_t alignment, RendererVk *renderer)
void DynamicBuffer::init(RendererVk *renderer,
VkBufferUsageFlags usage,
size_t alignment,
size_t initialSize,
bool hostVisible)
{
mUsage = usage;
mInitialSize = initialSize;
mHostVisible = hostVisible;
// Workaround for the mock ICD not supporting allocations greater than 0x1000.
// Could be removed if https://github.com/KhronosGroup/Vulkan-Tools/issues/84 is fixed.
if (renderer->isMockICDEnabled())
{
mMinSize = std::min<size_t>(mMinSize, 0x1000);
mInitialSize = std::min<size_t>(mInitialSize, 0x1000);
}
updateAlignment(renderer, alignment);
......@@ -307,7 +315,7 @@ angle::Result DynamicBuffer::allocate(ContextVk *contextVk,
mBuffer = nullptr;
}
mSize = std::max(sizeToAllocate, mMinSize);
mSize = std::max(sizeToAllocate, mInitialSize);
std::unique_ptr<BufferHelper> buffer = std::make_unique<BufferHelper>();
......@@ -488,7 +496,7 @@ void DynamicBuffer::updateAlignment(RendererVk *renderer, size_t alignment)
void DynamicBuffer::setMinimumSizeForTesting(size_t minSize)
{
// This will really only have an effect next time we call allocate.
mMinSize = minSize;
mInitialSize = minSize;
// Forces a new allocation on the next allocate.
mSize = 0;
......@@ -994,14 +1002,14 @@ void SemaphoreHelper::deinit()
// LineLoopHelper implementation.
LineLoopHelper::LineLoopHelper(RendererVk *renderer)
: mDynamicIndexBuffer(kLineLoopDynamicBufferUsage, kLineLoopDynamicBufferMinSize, true)
{
// We need to use an alignment of the maximum size we're going to allocate, which is
// VK_INDEX_TYPE_UINT32. When we switch from a drawElement to a drawArray call, the allocations
// can vary in size. According to the Vulkan spec, when calling vkCmdBindIndexBuffer: 'The
// sum of offset and the address of the range of VkDeviceMemory object that is backing buffer,
// must be a multiple of the type indicated by indexType'.
mDynamicIndexBuffer.init(sizeof(uint32_t), renderer);
mDynamicIndexBuffer.init(renderer, kLineLoopDynamicBufferUsage, sizeof(uint32_t),
kLineLoopDynamicBufferInitialSize, true);
}
LineLoopHelper::~LineLoopHelper() = default;
......@@ -1369,8 +1377,7 @@ ImageHelper::ImageHelper()
mCurrentLayout(ImageLayout::Undefined),
mCurrentQueueFamilyIndex(std::numeric_limits<uint32_t>::max()),
mLayerCount(0),
mLevelCount(0),
mStagingBuffer(kStagingBufferFlags, kStagingBufferSize, true)
mLevelCount(0)
{}
ImageHelper::ImageHelper(ImageHelper &&other)
......@@ -1400,7 +1407,8 @@ ImageHelper::~ImageHelper()
void ImageHelper::initStagingBuffer(RendererVk *renderer, const vk::Format &format)
{
mStagingBuffer.updateAlignment(renderer, format.getImageCopyBufferAlignment());
mStagingBuffer.init(renderer, kStagingBufferFlags, format.getImageCopyBufferAlignment(),
kStagingBufferSize, true);
}
angle::Result ImageHelper::init(Context *context,
......
......@@ -39,12 +39,16 @@ class BufferHelper;
class DynamicBuffer : angle::NonCopyable
{
public:
DynamicBuffer(VkBufferUsageFlags usage, size_t minSize, bool hostVisible);
DynamicBuffer();
DynamicBuffer(DynamicBuffer &&other);
~DynamicBuffer();
// Init is called after the buffer creation so that the alignment can be specified later.
void init(size_t alignment, RendererVk *renderer);
void init(RendererVk *renderer,
VkBufferUsageFlags usage,
size_t alignment,
size_t initialSize,
bool hostVisible);
// This call will allocate a new region at the end of the buffer. It internally may trigger
// a new buffer to be created (which is returned in the optional parameter
......@@ -87,7 +91,7 @@ class DynamicBuffer : angle::NonCopyable
VkBufferUsageFlags mUsage;
bool mHostVisible;
size_t mMinSize;
size_t mInitialSize;
BufferHelper *mBuffer;
uint32_t mNextAllocationOffset;
uint32_t mLastFlushOrInvalidateOffset;
......
......@@ -78,7 +78,14 @@ void main()
GLint mAttribLocation;
};
TEST_P(BufferDataTest, NULLData)
// Disabled in debug because it's way too slow.
#if !defined(NDEBUG)
# define MAYBE_NULLData DISABLED_NULLData
#else
# define MAYBE_NULLData NULLData
#endif // !defined(NDEBUG)
TEST_P(BufferDataTest, MAYBE_NULLData)
{
glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
EXPECT_GL_NO_ERROR();
......
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