Commit 254b32cb by Shahbaz Youssefi Committed by Commit Bot

Vulkan: Make DynamicBuffer use BufferHelper

This is so that the resulting buffers can be written to by the GPU. Additionally, the class is given the ability to create host-visible or device-local buffers, making map()-on-init() optional. This is in preparation for vertex/index transformations in compute. Bug: angleproject:2958 Change-Id: Ib8f5829e33a1e49fa8f80c70dbde74f313ae49ec Reviewed-on: https://chromium-review.googlesource.com/c/1351113 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent b29fccfe
...@@ -196,6 +196,10 @@ class RecordableGraphResource : public CommandGraphResource ...@@ -196,6 +196,10 @@ class RecordableGraphResource : public CommandGraphResource
// Sets up dependency relations. 'this' resource is the resource being read. // Sets up dependency relations. 'this' resource is the resource being read.
void addReadDependency(RecordableGraphResource *readingResource); void addReadDependency(RecordableGraphResource *readingResource);
// Updates the in-use serial tracked for this resource. Will clear dependencies if the resource
// was not used in this set of command nodes.
void updateQueueSerial(Serial queueSerial);
// Allocates a write node via getNewWriteNode and returns a started command buffer. // Allocates a write node via getNewWriteNode and returns a started command buffer.
// The started command buffer will render outside of a RenderPass. // The started command buffer will render outside of a RenderPass.
// Will append to an existing command buffer/graph node if possible. // Will append to an existing command buffer/graph node if possible.
...@@ -251,10 +255,6 @@ class RecordableGraphResource : public CommandGraphResource ...@@ -251,10 +255,6 @@ class RecordableGraphResource : public CommandGraphResource
mCurrentWritingNode->getInsideRenderPassCommands()->valid(); mCurrentWritingNode->getInsideRenderPassCommands()->valid();
} }
// Updates the in-use serial tracked for this resource. Will clear dependencies if the resource
// was not used in this set of command nodes.
void updateQueueSerial(Serial queueSerial);
void startNewCommands(RendererVk *renderer); void startNewCommands(RendererVk *renderer);
void onWriteImpl(CommandGraphNode *writingNode, Serial currentSerial); void onWriteImpl(CommandGraphNode *writingNode, Serial currentSerial);
......
...@@ -101,9 +101,9 @@ constexpr size_t kDefaultBufferSize = kDefaultValueSize * 16; ...@@ -101,9 +101,9 @@ constexpr size_t kDefaultBufferSize = kDefaultValueSize * 16;
} // anonymous namespace } // anonymous namespace
// std::array only uses aggregate init. Thus we make a helper macro to reduce on code duplication. // std::array only uses aggregate init. Thus we make a helper macro to reduce on code duplication.
#define INIT \ #define INIT \
{ \ { \
kVertexBufferUsage, kDefaultBufferSize \ kVertexBufferUsage, kDefaultBufferSize, true \
} }
ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer) ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer)
...@@ -117,7 +117,7 @@ ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer) ...@@ -117,7 +117,7 @@ ContextVk::ContextVk(const gl::ContextState &state, RendererVk *renderer)
mCurrentDrawElementsType(GL_NONE), mCurrentDrawElementsType(GL_NONE),
mClearColorMask(kAllColorChannelsMask), mClearColorMask(kAllColorChannelsMask),
mFlipYForCurrentSurface(false), mFlipYForCurrentSurface(false),
mDriverUniformsBuffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, sizeof(DriverUniforms) * 16), mDriverUniformsBuffer(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, sizeof(DriverUniforms) * 16, true),
mDriverUniformsDescriptorSet(VK_NULL_HANDLE), mDriverUniformsDescriptorSet(VK_NULL_HANDLE),
mDefaultAttribBuffers{{INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, mDefaultAttribBuffers{{INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT, INIT,
INIT, INIT, INIT, INIT}}, INIT, INIT, INIT, INIT}},
...@@ -1159,9 +1159,8 @@ angle::Result ContextVk::handleDirtyDriverUniforms(const gl::Context *context, ...@@ -1159,9 +1159,8 @@ angle::Result ContextVk::handleDirtyDriverUniforms(const gl::Context *context,
uint8_t *ptr = nullptr; uint8_t *ptr = nullptr;
VkBuffer buffer = VK_NULL_HANDLE; VkBuffer buffer = VK_NULL_HANDLE;
VkDeviceSize offset = 0; VkDeviceSize offset = 0;
bool newBufferAllocated = false;
ANGLE_TRY(mDriverUniformsBuffer.allocate(this, sizeof(DriverUniforms), &ptr, &buffer, &offset, ANGLE_TRY(mDriverUniformsBuffer.allocate(this, sizeof(DriverUniforms), &ptr, &buffer, &offset,
&newBufferAllocated)); nullptr));
float scaleY = isViewportFlipEnabledForDrawFBO() ? -1.0f : 1.0f; float scaleY = isViewportFlipEnabledForDrawFBO() ? -1.0f : 1.0f;
float depthRangeNear = mState.getState().getNearPlane(); float depthRangeNear = mState.getState().getNearPlane();
......
...@@ -123,8 +123,8 @@ FramebufferVk::FramebufferVk(RendererVk *renderer, ...@@ -123,8 +123,8 @@ FramebufferVk::FramebufferVk(RendererVk *renderer,
: FramebufferImpl(state), : FramebufferImpl(state),
mBackbuffer(backbuffer), mBackbuffer(backbuffer),
mActiveColorComponents(0), mActiveColorComponents(0),
mReadPixelBuffer(VK_BUFFER_USAGE_TRANSFER_DST_BIT, kMinReadPixelsBufferSize), mReadPixelBuffer(VK_BUFFER_USAGE_TRANSFER_DST_BIT, kMinReadPixelsBufferSize, true),
mBlitPixelBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, kMinReadPixelsBufferSize) mBlitPixelBuffer(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, kMinReadPixelsBufferSize, true)
{ {
mBlitPixelBuffer.init(1, renderer); mBlitPixelBuffer.init(1, renderer);
mReadPixelBuffer.init(4, renderer); mReadPixelBuffer.init(4, renderer);
...@@ -1189,12 +1189,11 @@ angle::Result FramebufferVk::readPixelsImpl(ContextVk *contextVk, ...@@ -1189,12 +1189,11 @@ angle::Result FramebufferVk::readPixelsImpl(ContextVk *contextVk,
VkBuffer bufferHandle = VK_NULL_HANDLE; VkBuffer bufferHandle = VK_NULL_HANDLE;
uint8_t *readPixelBuffer = nullptr; uint8_t *readPixelBuffer = nullptr;
bool newBufferAllocated = false;
VkDeviceSize stagingOffset = 0; VkDeviceSize stagingOffset = 0;
size_t allocationSize = readFormat->pixelBytes * area.width * area.height; size_t allocationSize = readFormat->pixelBytes * area.width * area.height;
ANGLE_TRY(mReadPixelBuffer.allocate(contextVk, allocationSize, &readPixelBuffer, &bufferHandle, ANGLE_TRY(mReadPixelBuffer.allocate(contextVk, allocationSize, &readPixelBuffer, &bufferHandle,
&stagingOffset, &newBufferAllocated)); &stagingOffset, nullptr));
VkBufferImageCopy region = {}; VkBufferImageCopy region = {};
region.bufferImageHeight = area.height; region.bufferImageHeight = area.height;
......
...@@ -186,7 +186,8 @@ bool ProgramVk::ShaderInfo::valid() const ...@@ -186,7 +186,8 @@ bool ProgramVk::ShaderInfo::valid() const
// ProgramVk implementation. // ProgramVk implementation.
ProgramVk::DefaultUniformBlock::DefaultUniformBlock() ProgramVk::DefaultUniformBlock::DefaultUniformBlock()
: storage(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT, : storage(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
kUniformBlockDynamicBufferMinSize) kUniformBlockDynamicBufferMinSize,
true)
{} {}
ProgramVk::DefaultUniformBlock::~DefaultUniformBlock() = default; ProgramVk::DefaultUniformBlock::~DefaultUniformBlock() = default;
...@@ -220,9 +221,7 @@ void ProgramVk::reset(RendererVk *renderer) ...@@ -220,9 +221,7 @@ void ProgramVk::reset(RendererVk *renderer)
mDefaultShaderInfo.release(renderer); mDefaultShaderInfo.release(renderer);
mLineRasterShaderInfo.release(renderer); mLineRasterShaderInfo.release(renderer);
Serial currentSerial = renderer->getCurrentQueueSerial(); mEmptyUniformBlockStorage.release(renderer);
renderer->releaseObject(currentSerial, &mEmptyUniformBlockStorage.memory);
renderer->releaseObject(currentSerial, &mEmptyUniformBlockStorage.buffer);
mDescriptorSets.clear(); mDescriptorSets.clear();
mUsedDescriptorSetRange.invalidate(); mUsedDescriptorSetRange.invalidate();
...@@ -437,16 +436,10 @@ angle::Result ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext) ...@@ -437,16 +436,10 @@ angle::Result ProgramVk::initDefaultUniformBlocks(const gl::Context *glContext)
uniformBufferInfo.queueFamilyIndexCount = 0; uniformBufferInfo.queueFamilyIndexCount = 0;
uniformBufferInfo.pQueueFamilyIndices = nullptr; uniformBufferInfo.pQueueFamilyIndices = nullptr;
ANGLE_VK_TRY(contextVk, mEmptyUniformBlockStorage.buffer.init(contextVk->getDevice(),
uniformBufferInfo));
// Assume host visible/coherent memory available. // Assume host visible/coherent memory available.
VkMemoryPropertyFlags flags = VkMemoryPropertyFlags flags =
(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
VkMemoryPropertyFlags flagsOut = 0; ANGLE_TRY(mEmptyUniformBlockStorage.init(contextVk, uniformBufferInfo, flags));
ANGLE_TRY(AllocateBufferMemory(contextVk, flags, &flagsOut,
&mEmptyUniformBlockStorage.buffer,
&mEmptyUniformBlockStorage.memory));
} }
} }
...@@ -837,11 +830,11 @@ angle::Result ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk ...@@ -837,11 +830,11 @@ angle::Result ProgramVk::updateDefaultUniformsDescriptorSet(ContextVk *contextVk
if (!uniformBlock.uniformData.empty()) if (!uniformBlock.uniformData.empty())
{ {
bufferInfo.buffer = uniformBlock.storage.getCurrentBufferHandle(); bufferInfo.buffer = uniformBlock.storage.getCurrentBuffer()->getBuffer().getHandle();
} }
else else
{ {
bufferInfo.buffer = mEmptyUniformBlockStorage.buffer.getHandle(); bufferInfo.buffer = mEmptyUniformBlockStorage.getBuffer().getHandle();
} }
bufferInfo.offset = 0; bufferInfo.offset = 0;
......
...@@ -174,7 +174,7 @@ class ProgramVk : public ProgramImpl ...@@ -174,7 +174,7 @@ class ProgramVk : public ProgramImpl
// This is a special "empty" placeholder buffer for when a shader has no uniforms. // This is a special "empty" placeholder buffer for when a shader has no uniforms.
// It is necessary because we want to keep a compatible pipeline layout in all cases, // It is necessary because we want to keep a compatible pipeline layout in all cases,
// and Vulkan does not tolerate having null handles in a descriptor set. // and Vulkan does not tolerate having null handles in a descriptor set.
vk::BufferAndMemory mEmptyUniformBlockStorage; vk::BufferHelper mEmptyUniformBlockStorage;
// Descriptor sets for uniform blocks and textures for this program. // Descriptor sets for uniform blocks and textures for this program.
std::vector<VkDescriptorSet> mDescriptorSets; std::vector<VkDescriptorSet> mDescriptorSets;
......
...@@ -61,7 +61,7 @@ constexpr VkFormatFeatureFlags kBlitFeatureFlags = ...@@ -61,7 +61,7 @@ constexpr VkFormatFeatureFlags kBlitFeatureFlags =
// StagingStorage implementation. // StagingStorage implementation.
PixelBuffer::PixelBuffer(RendererVk *renderer) PixelBuffer::PixelBuffer(RendererVk *renderer)
: mStagingBuffer(kStagingBufferFlags, kStagingBufferSize) : mStagingBuffer(kStagingBufferFlags, kStagingBufferSize, true)
{ {
// vkCmdCopyBufferToImage must have an offset that is a multiple of 4. // vkCmdCopyBufferToImage must have an offset that is a multiple of 4.
// https://www.khronos.org/registry/vulkan/specs/1.0/man/html/VkBufferImageCopy.html // https://www.khronos.org/registry/vulkan/specs/1.0/man/html/VkBufferImageCopy.html
...@@ -125,11 +125,10 @@ angle::Result PixelBuffer::stageSubresourceUpdate(ContextVk *contextVk, ...@@ -125,11 +125,10 @@ angle::Result PixelBuffer::stageSubresourceUpdate(ContextVk *contextVk,
VkBuffer bufferHandle = VK_NULL_HANDLE; VkBuffer bufferHandle = VK_NULL_HANDLE;
uint8_t *stagingPointer = nullptr; uint8_t *stagingPointer = nullptr;
bool newBufferAllocated = false;
VkDeviceSize stagingOffset = 0; VkDeviceSize stagingOffset = 0;
size_t allocationSize = outputDepthPitch * extents.depth; size_t allocationSize = outputDepthPitch * extents.depth;
ANGLE_TRY(mStagingBuffer.allocate(contextVk, allocationSize, &stagingPointer, &bufferHandle, ANGLE_TRY(mStagingBuffer.allocate(contextVk, allocationSize, &stagingPointer, &bufferHandle,
&stagingOffset, &newBufferAllocated)); &stagingOffset, nullptr));
const uint8_t *source = pixels + inputSkipBytes; const uint8_t *source = pixels + inputSkipBytes;
...@@ -196,13 +195,12 @@ angle::Result PixelBuffer::stageSubresourceUpdateFromFramebuffer( ...@@ -196,13 +195,12 @@ angle::Result PixelBuffer::stageSubresourceUpdateFromFramebuffer(
VkBuffer bufferHandle = VK_NULL_HANDLE; VkBuffer bufferHandle = VK_NULL_HANDLE;
uint8_t *stagingPointer = nullptr; uint8_t *stagingPointer = nullptr;
bool newBufferAllocated = false;
VkDeviceSize stagingOffset = 0; VkDeviceSize stagingOffset = 0;
// The destination is only one layer deep. // The destination is only one layer deep.
size_t allocationSize = outputDepthPitch; size_t allocationSize = outputDepthPitch;
ANGLE_TRY(mStagingBuffer.allocate(contextVk, allocationSize, &stagingPointer, &bufferHandle, ANGLE_TRY(mStagingBuffer.allocate(contextVk, allocationSize, &stagingPointer, &bufferHandle,
&stagingOffset, &newBufferAllocated)); &stagingOffset, nullptr));
const angle::Format &copyFormat = const angle::Format &copyFormat =
GetFormatFromFormatType(formatInfo.internalFormat, formatInfo.type); GetFormatFromFormatType(formatInfo.internalFormat, formatInfo.type);
...@@ -335,9 +333,8 @@ angle::Result PixelBuffer::stageSubresourceUpdateAndGetData(ContextVk *contextVk ...@@ -335,9 +333,8 @@ angle::Result PixelBuffer::stageSubresourceUpdateAndGetData(ContextVk *contextVk
{ {
VkBuffer bufferHandle; VkBuffer bufferHandle;
VkDeviceSize stagingOffset = 0; VkDeviceSize stagingOffset = 0;
bool newBufferAllocated = false;
ANGLE_TRY(mStagingBuffer.allocate(contextVk, allocationSize, destData, &bufferHandle, ANGLE_TRY(mStagingBuffer.allocate(contextVk, allocationSize, destData, &bufferHandle,
&stagingOffset, &newBufferAllocated)); &stagingOffset, nullptr));
VkBufferImageCopy copy = {}; VkBufferImageCopy copy = {};
copy.bufferOffset = stagingOffset; copy.bufferOffset = stagingOffset;
...@@ -772,11 +769,10 @@ angle::Result TextureVk::copyImageDataToBuffer(ContextVk *contextVk, ...@@ -772,11 +769,10 @@ angle::Result TextureVk::copyImageDataToBuffer(ContextVk *contextVk,
// Allocate enough memory to copy the sourceArea region of the source texture into its pixel // Allocate enough memory to copy the sourceArea region of the source texture into its pixel
// buffer. // buffer.
bool newBufferAllocated = false;
VkBuffer copyBufferHandle = VK_NULL_HANDLE; VkBuffer copyBufferHandle = VK_NULL_HANDLE;
VkDeviceSize sourceCopyOffset = 0; VkDeviceSize sourceCopyOffset = 0;
ANGLE_TRY(mPixelBuffer.allocate(contextVk, sourceCopyAllocationSize, outDataPtr, ANGLE_TRY(mPixelBuffer.allocate(contextVk, sourceCopyAllocationSize, outDataPtr,
&copyBufferHandle, &sourceCopyOffset, &newBufferAllocated)); &copyBufferHandle, &sourceCopyOffset, nullptr));
VkBufferImageCopy region = {}; VkBufferImageCopy region = {};
region.bufferOffset = sourceCopyOffset; region.bufferOffset = sourceCopyOffset;
......
...@@ -26,6 +26,10 @@ namespace ...@@ -26,6 +26,10 @@ namespace
constexpr size_t kDynamicVertexDataSize = 1024 * 1024; constexpr size_t kDynamicVertexDataSize = 1024 * 1024;
constexpr size_t kDynamicIndexDataSize = 1024 * 8; constexpr size_t kDynamicIndexDataSize = 1024 * 8;
constexpr size_t kMaxVertexFormatAlignment = 4; constexpr size_t kMaxVertexFormatAlignment = 4;
constexpr VkBufferUsageFlags kVertexBufferUsageFlags =
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
constexpr VkBufferUsageFlags kIndexBufferUsageFlags =
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
bool BindingIsAligned(const gl::VertexBinding &binding, unsigned componentSize) bool BindingIsAligned(const gl::VertexBinding &binding, unsigned componentSize)
{ {
...@@ -55,9 +59,9 @@ angle::Result StreamVertexData(ContextVk *contextVk, ...@@ -55,9 +59,9 @@ angle::Result StreamVertexData(ContextVk *contextVk,
} // anonymous namespace } // anonymous namespace
#define INIT \ #define INIT \
{ \ { \
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, 1024 * 8 \ kVertexBufferUsageFlags, 1024 * 8, true \
} }
VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state, RendererVk *renderer) VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state, RendererVk *renderer)
...@@ -91,9 +95,9 @@ VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state, RendererVk *rend ...@@ -91,9 +95,9 @@ VertexArrayVk::VertexArrayVk(const gl::VertexArrayState &state, RendererVk *rend
mCurrentElementArrayBuffer(nullptr), mCurrentElementArrayBuffer(nullptr),
mPackedInputBindings{}, mPackedInputBindings{},
mPackedInputAttributes{}, mPackedInputAttributes{},
mDynamicVertexData(VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, kDynamicVertexDataSize), mDynamicVertexData(kVertexBufferUsageFlags, kDynamicVertexDataSize, true),
mDynamicIndexData(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, kDynamicIndexDataSize), mDynamicIndexData(kIndexBufferUsageFlags, kDynamicIndexDataSize, true),
mTranslatedByteIndexData(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, kDynamicIndexDataSize), mTranslatedByteIndexData(kIndexBufferUsageFlags, kDynamicIndexDataSize, true),
mLineLoopHelper(renderer), mLineLoopHelper(renderer),
mDirtyLineLoopTranslation(true) mDirtyLineLoopTranslation(true)
{ {
......
...@@ -28,22 +28,24 @@ namespace vk ...@@ -28,22 +28,24 @@ namespace vk
// //
// Dynamic buffers are used to implement a variety of data streaming operations in Vulkan, such // Dynamic buffers are used to implement a variety of data streaming operations in Vulkan, such
// as for immediate vertex array and element array data, uniform updates, and other dynamic data. // as for immediate vertex array and element array data, uniform updates, and other dynamic data.
class BufferHelper;
class DynamicBuffer : angle::NonCopyable class DynamicBuffer : angle::NonCopyable
{ {
public: public:
DynamicBuffer(VkBufferUsageFlags usage, size_t minSize); DynamicBuffer(VkBufferUsageFlags usage, size_t minSize, bool hostVisible);
~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(size_t alignment, RendererVk *renderer);
// 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 'newBufferAllocatedOut'. This param may // a new buffer to be created (which is returned in the optional parameter
// be nullptr. // `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(Context *context, angle::Result allocate(Context *context,
size_t sizeInBytes, size_t sizeInBytes,
uint8_t **ptrOut, uint8_t **ptrOut,
VkBuffer *handleOut, VkBuffer *bufferOut,
VkDeviceSize *offsetOut, VkDeviceSize *offsetOut,
bool *newBufferAllocatedOut); bool *newBufferAllocatedOut);
...@@ -62,27 +64,24 @@ class DynamicBuffer : angle::NonCopyable ...@@ -62,27 +64,24 @@ class DynamicBuffer : angle::NonCopyable
// This frees resources immediately. // This frees resources immediately.
void destroy(VkDevice device); void destroy(VkDevice device);
VkBuffer getCurrentBufferHandle() const; BufferHelper *getCurrentBuffer() { return mBuffer; };
// For testing only! // For testing only!
void setMinimumSizeForTesting(size_t minSize); void setMinimumSizeForTesting(size_t minSize);
private: private:
void unmap(VkDevice device);
void reset(); void reset();
VkBufferUsageFlags mUsage; VkBufferUsageFlags mUsage;
bool mHostVisible;
size_t mMinSize; size_t mMinSize;
Buffer mBuffer; BufferHelper *mBuffer;
DeviceMemory mMemory;
bool mHostCoherent;
uint32_t mNextAllocationOffset; uint32_t mNextAllocationOffset;
uint32_t mLastFlushOrInvalidateOffset; uint32_t mLastFlushOrInvalidateOffset;
size_t mSize; size_t mSize;
size_t mAlignment; size_t mAlignment;
uint8_t *mMappedMemory;
std::vector<BufferAndMemory> mRetainedBuffers; std::vector<BufferHelper *> mRetainedBuffers;
}; };
// Uses DescriptorPool to allocate descriptor sets as needed. If a descriptor pool becomes full, we // Uses DescriptorPool to allocate descriptor sets as needed. If a descriptor pool becomes full, we
...@@ -381,6 +380,7 @@ class BufferHelper final : public RecordableGraphResource ...@@ -381,6 +380,7 @@ class BufferHelper final : public RecordableGraphResource
angle::Result init(Context *context, angle::Result init(Context *context,
const VkBufferCreateInfo &createInfo, const VkBufferCreateInfo &createInfo,
VkMemoryPropertyFlags memoryPropertyFlags); VkMemoryPropertyFlags memoryPropertyFlags);
void destroy(VkDevice device);
void release(RendererVk *renderer); void release(RendererVk *renderer);
bool valid() const { return mBuffer.valid(); } bool valid() const { return mBuffer.valid(); }
...@@ -408,7 +408,25 @@ class BufferHelper final : public RecordableGraphResource ...@@ -408,7 +408,25 @@ class BufferHelper final : public RecordableGraphResource
return angle::Result::Continue(); return angle::Result::Continue();
} }
angle::Result map(Context *context, uint8_t **ptrOut)
{
if (!mMappedMemory)
{
ANGLE_TRY(mapImpl(context));
}
*ptrOut = mMappedMemory;
return angle::Result::Continue();
}
void unmap(VkDevice device);
// After a sequence of writes, call flush to ensure the data is visible to the device.
angle::Result flush(Context *context, size_t offset, size_t size);
// After a sequence of writes, call invalidate to ensure the data is visible to the host.
angle::Result invalidate(Context *context, size_t offset, size_t size);
private: private:
angle::Result mapImpl(Context *context);
angle::Result initBufferView(Context *context, const Format &format); angle::Result initBufferView(Context *context, const Format &format);
// Vulkan objects. // Vulkan objects.
...@@ -419,6 +437,7 @@ class BufferHelper final : public RecordableGraphResource ...@@ -419,6 +437,7 @@ class BufferHelper final : public RecordableGraphResource
// Cached properties. // Cached properties.
VkMemoryPropertyFlags mMemoryPropertyFlags; VkMemoryPropertyFlags mMemoryPropertyFlags;
VkDeviceSize mSize; VkDeviceSize mSize;
uint8_t *mMappedMemory;
// For memory barriers. // For memory barriers.
VkFlags mCurrentWriteAccess; VkFlags mCurrentWriteAccess;
......
...@@ -279,24 +279,6 @@ VkDevice Context::getDevice() const ...@@ -279,24 +279,6 @@ VkDevice Context::getDevice() const
return mRenderer->getDevice(); return mRenderer->getDevice();
} }
// BufferAndMemory implementation.
BufferAndMemory::BufferAndMemory() = default;
BufferAndMemory::BufferAndMemory(Buffer &&buffer, DeviceMemory &&deviceMemory)
: buffer(std::move(buffer)), memory(std::move(deviceMemory))
{}
BufferAndMemory::BufferAndMemory(BufferAndMemory &&other)
: buffer(std::move(other.buffer)), memory(std::move(other.memory))
{}
BufferAndMemory &BufferAndMemory::operator=(BufferAndMemory &&other)
{
buffer = std::move(other.buffer);
memory = std::move(other.memory);
return *this;
}
// CommandPool implementation. // CommandPool implementation.
CommandPool::CommandPool() {} CommandPool::CommandPool() {}
......
...@@ -738,17 +738,6 @@ angle::Result AllocateBufferMemory(vk::Context *context, ...@@ -738,17 +738,6 @@ angle::Result AllocateBufferMemory(vk::Context *context,
Buffer *buffer, Buffer *buffer,
DeviceMemory *deviceMemoryOut); DeviceMemory *deviceMemoryOut);
struct BufferAndMemory final : angle::NonCopyable
{
BufferAndMemory();
BufferAndMemory(Buffer &&buffer, DeviceMemory &&deviceMemory);
BufferAndMemory(BufferAndMemory &&other);
BufferAndMemory &operator=(BufferAndMemory &&other);
Buffer buffer;
DeviceMemory memory;
};
angle::Result AllocateImageMemory(vk::Context *context, angle::Result AllocateImageMemory(vk::Context *context,
VkMemoryPropertyFlags memoryPropertyFlags, VkMemoryPropertyFlags memoryPropertyFlags,
Image *image, Image *image,
......
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