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, ...@@ -36,9 +36,9 @@ ConversionBuffer::ConversionBuffer(RendererVk *renderer,
VkBufferUsageFlags usageFlags, VkBufferUsageFlags usageFlags,
size_t initialSize, size_t initialSize,
size_t alignment) 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; ConversionBuffer::~ConversionBuffer() = default;
......
...@@ -138,12 +138,6 @@ void ApplySampleCoverage(const gl::State &glState, ...@@ -138,12 +138,6 @@ void ApplySampleCoverage(const gl::State &glState,
} // anonymous namespace } // 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. // CommandBatch implementation.
ContextVk::CommandBatch::CommandBatch() = default; ContextVk::CommandBatch::CommandBatch() = default;
...@@ -182,11 +176,8 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk ...@@ -182,11 +176,8 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mClearColorMask(kAllColorChannelsMask), mClearColorMask(kAllColorChannelsMask),
mFlipYForCurrentSurface(false), mFlipYForCurrentSurface(false),
mIsAnyHostVisibleBufferWritten(false), mIsAnyHostVisibleBufferWritten(false),
mDriverUniformsBuffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, sizeof(DriverUniforms) * 16, true),
mDriverUniformsDescriptorSet(VK_NULL_HANDLE), mDriverUniformsDescriptorSet(VK_NULL_HANDLE),
mDriverUniformsDynamicOffset(0), mDriverUniformsDynamicOffset(0),
mDefaultAttribBuffers{{INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT,
INIT, INIT, INIT, INIT}},
mLastCompletedQueueSerial(renderer->nextSerial()), mLastCompletedQueueSerial(renderer->nextSerial()),
mCurrentQueueSerial(renderer->nextSerial()), mCurrentQueueSerial(renderer->nextSerial()),
mPoolAllocator(kDefaultPoolAllocatorPageSize, 1), mPoolAllocator(kDefaultPoolAllocatorPageSize, 1),
...@@ -227,8 +218,6 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk ...@@ -227,8 +218,6 @@ ContextVk::ContextVk(const gl::State &state, gl::ErrorSet *errorSet, RendererVk
mPipelineDirtyBitsMask.reset(gl::State::DIRTY_BIT_TEXTURE_BINDINGS); mPipelineDirtyBitsMask.reset(gl::State::DIRTY_BIT_TEXTURE_BINDINGS);
} }
#undef INIT
ContextVk::~ContextVk() = default; ContextVk::~ContextVk() = default;
void ContextVk::onDestroy(const gl::Context *context) void ContextVk::onDestroy(const gl::Context *context)
...@@ -300,7 +289,8 @@ angle::Result ContextVk::initialize() ...@@ -300,7 +289,8 @@ angle::Result ContextVk::initialize()
size_t minAlignment = static_cast<size_t>( size_t minAlignment = static_cast<size_t>(
mRenderer->getPhysicalDeviceProperties().limits.minUniformBufferOffsetAlignment); 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. // Get the descriptor set layout.
vk::DescriptorSetLayoutDesc desc = getDriverUniformsDescriptorSetDesc(); vk::DescriptorSetLayoutDesc desc = getDriverUniformsDescriptorSetDesc();
...@@ -312,7 +302,7 @@ angle::Result ContextVk::initialize() ...@@ -312,7 +302,7 @@ angle::Result ContextVk::initialize()
// Initialize current value/default attribute buffers. // Initialize current value/default attribute buffers.
for (vk::DynamicBuffer &buffer : mDefaultAttribBuffers) 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. // Initialize the command pool now that we know the queue family index.
......
...@@ -162,14 +162,10 @@ FramebufferVk *FramebufferVk::CreateDefaultFBO(RendererVk *renderer, ...@@ -162,14 +162,10 @@ FramebufferVk *FramebufferVk::CreateDefaultFBO(RendererVk *renderer,
FramebufferVk::FramebufferVk(RendererVk *renderer, FramebufferVk::FramebufferVk(RendererVk *renderer,
const gl::FramebufferState &state, const gl::FramebufferState &state,
WindowSurfaceVk *backbuffer) WindowSurfaceVk *backbuffer)
: FramebufferImpl(state), : FramebufferImpl(state), mBackbuffer(backbuffer), mActiveColorComponents(0)
mBackbuffer(backbuffer),
mActiveColorComponents(0),
mReadPixelBuffer(VK_BUFFER_USAGE_TRANSFER_DST_BIT, kMinReadPixelsBufferSize, true),
mBlitPixelBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, kMinReadPixelsBufferSize, true)
{ {
mBlitPixelBuffer.init(1, renderer); mReadPixelBuffer.init(renderer, VK_BUFFER_USAGE_TRANSFER_DST_BIT, 4, kMinReadPixelsBufferSize,
mReadPixelBuffer.init(4, renderer); true);
} }
FramebufferVk::~FramebufferVk() = default; FramebufferVk::~FramebufferVk() = default;
...@@ -180,7 +176,6 @@ void FramebufferVk::destroy(const gl::Context *context) ...@@ -180,7 +176,6 @@ void FramebufferVk::destroy(const gl::Context *context)
mFramebuffer.release(contextVk); mFramebuffer.release(contextVk);
mReadPixelBuffer.release(contextVk); mReadPixelBuffer.release(contextVk);
mBlitPixelBuffer.release(contextVk);
} }
angle::Result FramebufferVk::discard(const gl::Context *context, angle::Result FramebufferVk::discard(const gl::Context *context,
......
...@@ -192,7 +192,6 @@ class FramebufferVk : public FramebufferImpl ...@@ -192,7 +192,6 @@ class FramebufferVk : public FramebufferImpl
VkColorComponentFlags mActiveColorComponents; VkColorComponentFlags mActiveColorComponents;
gl::DrawBufferMask mActiveColorComponentMasksForClear[4]; gl::DrawBufferMask mActiveColorComponentMasksForClear[4];
vk::DynamicBuffer mReadPixelBuffer; vk::DynamicBuffer mReadPixelBuffer;
vk::DynamicBuffer mBlitPixelBuffer;
// When we draw to the framebuffer, and the real format has an alpha channel but the format of // 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 // 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) ...@@ -213,11 +213,7 @@ void ProgramVk::ShaderInfo::release(ContextVk *contextVk)
} }
// ProgramVk implementation. // ProgramVk implementation.
ProgramVk::DefaultUniformBlock::DefaultUniformBlock() ProgramVk::DefaultUniformBlock::DefaultUniformBlock() {}
: storage(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
kUniformBlockDynamicBufferMinSize,
true)
{}
ProgramVk::DefaultUniformBlock::~DefaultUniformBlock() = default; ProgramVk::DefaultUniformBlock::~DefaultUniformBlock() = default;
...@@ -470,7 +466,9 @@ angle::Result ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext) ...@@ -470,7 +466,9 @@ angle::Result ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
size_t minAlignment = static_cast<size_t>( size_t minAlignment = static_cast<size_t>(
renderer->getPhysicalDeviceProperties().limits.minUniformBufferOffsetAlignment); 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. // Initialize uniform buffer memory to zero by default.
mDefaultUniformBlocks[shaderType].uniformData.fill(0); mDefaultUniformBlocks[shaderType].uniformData.fill(0);
......
...@@ -92,9 +92,6 @@ VertexArrayVk::VertexArrayVk(ContextVk *contextVk, const gl::VertexArrayState &s ...@@ -92,9 +92,6 @@ VertexArrayVk::VertexArrayVk(ContextVk *contextVk, const gl::VertexArrayState &s
mCurrentArrayBuffers{}, mCurrentArrayBuffers{},
mCurrentElementArrayBufferOffset(0), mCurrentElementArrayBufferOffset(0),
mCurrentElementArrayBuffer(nullptr), mCurrentElementArrayBuffer(nullptr),
mDynamicVertexData(vk::kVertexBufferUsageFlags, kDynamicVertexDataSize, true),
mDynamicIndexData(vk::kIndexBufferUsageFlags, kDynamicIndexDataSize, true),
mTranslatedByteIndexData(vk::kIndexBufferUsageFlags, kDynamicIndexDataSize, true),
mLineLoopHelper(contextVk->getRenderer()), mLineLoopHelper(contextVk->getRenderer()),
mDirtyLineLoopTranslation(true) mDirtyLineLoopTranslation(true)
{ {
...@@ -110,12 +107,15 @@ VertexArrayVk::VertexArrayVk(ContextVk *contextVk, const gl::VertexArrayState &s ...@@ -110,12 +107,15 @@ VertexArrayVk::VertexArrayVk(ContextVk *contextVk, const gl::VertexArrayState &s
mCurrentArrayBufferOffsets.fill(0); mCurrentArrayBufferOffsets.fill(0);
mCurrentArrayBuffers.fill(&mTheNullBuffer); 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 // We use an alignment of four for index data. This ensures that compute shaders can read index
// elements from "uint" aligned addresses. // elements from "uint" aligned addresses.
mDynamicIndexData.init(vk::kIndexBufferAlignment, renderer); mDynamicIndexData.init(renderer, vk::kIndexBufferUsageFlags, vk::kIndexBufferAlignment,
mTranslatedByteIndexData.init(vk::kIndexBufferAlignment, renderer); kDynamicIndexDataSize, true);
mTranslatedByteIndexData.init(renderer, vk::kIndexBufferUsageFlags, vk::kIndexBufferAlignment,
kDynamicIndexDataSize, true);
} }
VertexArrayVk::~VertexArrayVk() {} VertexArrayVk::~VertexArrayVk() {}
......
...@@ -36,7 +36,7 @@ constexpr VkClearDepthStencilValue kWebGLInitDepthStencilValue = {1.0f, 0}; ...@@ -36,7 +36,7 @@ constexpr VkClearDepthStencilValue kWebGLInitDepthStencilValue = {1.0f, 0};
constexpr VkBufferUsageFlags kLineLoopDynamicBufferUsage = constexpr VkBufferUsageFlags kLineLoopDynamicBufferUsage =
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | 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; 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. // This is an arbitrary max. We can change this later if necessary.
constexpr uint32_t kDefaultDescriptorPoolMaxSets = 128; constexpr uint32_t kDefaultDescriptorPoolMaxSets = 128;
...@@ -242,10 +242,10 @@ void HandlePrimitiveRestart(gl::DrawElementsType glIndexType, ...@@ -242,10 +242,10 @@ void HandlePrimitiveRestart(gl::DrawElementsType glIndexType,
} // anonymous namespace } // anonymous namespace
// DynamicBuffer implementation. // DynamicBuffer implementation.
DynamicBuffer::DynamicBuffer(VkBufferUsageFlags usage, size_t minSize, bool hostVisible) DynamicBuffer::DynamicBuffer()
: mUsage(usage), : mUsage(0),
mHostVisible(hostVisible), mHostVisible(false),
mMinSize(minSize), mInitialSize(0),
mBuffer(nullptr), mBuffer(nullptr),
mNextAllocationOffset(0), mNextAllocationOffset(0),
mLastFlushOrInvalidateOffset(0), mLastFlushOrInvalidateOffset(0),
...@@ -256,7 +256,7 @@ DynamicBuffer::DynamicBuffer(VkBufferUsageFlags usage, size_t minSize, bool host ...@@ -256,7 +256,7 @@ DynamicBuffer::DynamicBuffer(VkBufferUsageFlags usage, size_t minSize, bool host
DynamicBuffer::DynamicBuffer(DynamicBuffer &&other) DynamicBuffer::DynamicBuffer(DynamicBuffer &&other)
: mUsage(other.mUsage), : mUsage(other.mUsage),
mHostVisible(other.mHostVisible), mHostVisible(other.mHostVisible),
mMinSize(other.mMinSize), mInitialSize(other.mInitialSize),
mBuffer(other.mBuffer), mBuffer(other.mBuffer),
mNextAllocationOffset(other.mNextAllocationOffset), mNextAllocationOffset(other.mNextAllocationOffset),
mLastFlushOrInvalidateOffset(other.mLastFlushOrInvalidateOffset), mLastFlushOrInvalidateOffset(other.mLastFlushOrInvalidateOffset),
...@@ -267,13 +267,21 @@ DynamicBuffer::DynamicBuffer(DynamicBuffer &&other) ...@@ -267,13 +267,21 @@ DynamicBuffer::DynamicBuffer(DynamicBuffer &&other)
other.mBuffer = nullptr; 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. // 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. // Could be removed if https://github.com/KhronosGroup/Vulkan-Tools/issues/84 is fixed.
if (renderer->isMockICDEnabled()) if (renderer->isMockICDEnabled())
{ {
mMinSize = std::min<size_t>(mMinSize, 0x1000); mInitialSize = std::min<size_t>(mInitialSize, 0x1000);
} }
updateAlignment(renderer, alignment); updateAlignment(renderer, alignment);
...@@ -307,7 +315,7 @@ angle::Result DynamicBuffer::allocate(ContextVk *contextVk, ...@@ -307,7 +315,7 @@ angle::Result DynamicBuffer::allocate(ContextVk *contextVk,
mBuffer = nullptr; mBuffer = nullptr;
} }
mSize = std::max(sizeToAllocate, mMinSize); mSize = std::max(sizeToAllocate, mInitialSize);
std::unique_ptr<BufferHelper> buffer = std::make_unique<BufferHelper>(); std::unique_ptr<BufferHelper> buffer = std::make_unique<BufferHelper>();
...@@ -488,7 +496,7 @@ void DynamicBuffer::updateAlignment(RendererVk *renderer, size_t alignment) ...@@ -488,7 +496,7 @@ void DynamicBuffer::updateAlignment(RendererVk *renderer, size_t alignment)
void DynamicBuffer::setMinimumSizeForTesting(size_t minSize) void DynamicBuffer::setMinimumSizeForTesting(size_t minSize)
{ {
// This will really only have an effect next time we call allocate. // This will really only have an effect next time we call allocate.
mMinSize = minSize; mInitialSize = minSize;
// Forces a new allocation on the next allocate. // Forces a new allocation on the next allocate.
mSize = 0; mSize = 0;
...@@ -994,14 +1002,14 @@ void SemaphoreHelper::deinit() ...@@ -994,14 +1002,14 @@ void SemaphoreHelper::deinit()
// LineLoopHelper implementation. // LineLoopHelper implementation.
LineLoopHelper::LineLoopHelper(RendererVk *renderer) 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 // 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 // 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 // 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, // 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'. // 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; LineLoopHelper::~LineLoopHelper() = default;
...@@ -1369,8 +1377,7 @@ ImageHelper::ImageHelper() ...@@ -1369,8 +1377,7 @@ ImageHelper::ImageHelper()
mCurrentLayout(ImageLayout::Undefined), mCurrentLayout(ImageLayout::Undefined),
mCurrentQueueFamilyIndex(std::numeric_limits<uint32_t>::max()), mCurrentQueueFamilyIndex(std::numeric_limits<uint32_t>::max()),
mLayerCount(0), mLayerCount(0),
mLevelCount(0), mLevelCount(0)
mStagingBuffer(kStagingBufferFlags, kStagingBufferSize, true)
{} {}
ImageHelper::ImageHelper(ImageHelper &&other) ImageHelper::ImageHelper(ImageHelper &&other)
...@@ -1400,7 +1407,8 @@ ImageHelper::~ImageHelper() ...@@ -1400,7 +1407,8 @@ ImageHelper::~ImageHelper()
void ImageHelper::initStagingBuffer(RendererVk *renderer, const vk::Format &format) 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, angle::Result ImageHelper::init(Context *context,
......
...@@ -39,12 +39,16 @@ class BufferHelper; ...@@ -39,12 +39,16 @@ class BufferHelper;
class DynamicBuffer : angle::NonCopyable class DynamicBuffer : angle::NonCopyable
{ {
public: public:
DynamicBuffer(VkBufferUsageFlags usage, size_t minSize, bool hostVisible); DynamicBuffer();
DynamicBuffer(DynamicBuffer &&other); DynamicBuffer(DynamicBuffer &&other);
~DynamicBuffer(); ~DynamicBuffer();
// Init is called after the buffer creation so that the alignment can be specified later. // 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 // 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 // a new buffer to be created (which is returned in the optional parameter
...@@ -87,7 +91,7 @@ class DynamicBuffer : angle::NonCopyable ...@@ -87,7 +91,7 @@ class DynamicBuffer : angle::NonCopyable
VkBufferUsageFlags mUsage; VkBufferUsageFlags mUsage;
bool mHostVisible; bool mHostVisible;
size_t mMinSize; size_t mInitialSize;
BufferHelper *mBuffer; BufferHelper *mBuffer;
uint32_t mNextAllocationOffset; uint32_t mNextAllocationOffset;
uint32_t mLastFlushOrInvalidateOffset; uint32_t mLastFlushOrInvalidateOffset;
......
...@@ -78,7 +78,14 @@ void main() ...@@ -78,7 +78,14 @@ void main()
GLint mAttribLocation; 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); glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
EXPECT_GL_NO_ERROR(); 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