Create memory::Buffer & Implement StagingBuffer as derivative

A `Buffer` class was created to hold any generic Vulkan buffer object with `span` semantics, `StagingBuffer` was implemented atop it as a wrapper for `Buffer` that inherits from `FenceCycleDependency` and can be used as such.
This commit is contained in:
PixelyIon 2021-12-02 01:21:18 +05:30
parent a55aca76c6
commit 8f3887c56a
2 changed files with 42 additions and 8 deletions

View File

@ -13,7 +13,7 @@ namespace skyline::gpu::memory {
vk::throwResultException(vk::Result(result), function); vk::throwResultException(vk::Result(result), function);
} }
StagingBuffer::~StagingBuffer() { Buffer::~Buffer() {
if (vmaAllocator && vmaAllocation && vkBuffer) if (vmaAllocator && vmaAllocation && vkBuffer)
vmaDestroyBuffer(vmaAllocator, vkBuffer, vmaAllocation); vmaDestroyBuffer(vmaAllocator, vkBuffer, vmaAllocation);
} }
@ -95,6 +95,28 @@ namespace skyline::gpu::memory {
return std::make_shared<memory::StagingBuffer>(reinterpret_cast<u8 *>(allocationInfo.pMappedData), allocationInfo.size, vmaAllocator, buffer, allocation); return std::make_shared<memory::StagingBuffer>(reinterpret_cast<u8 *>(allocationInfo.pMappedData), allocationInfo.size, vmaAllocator, buffer, allocation);
} }
Buffer MemoryManager::AllocateBuffer(vk::DeviceSize size) {
vk::BufferCreateInfo bufferCreateInfo{
.size = size,
.usage = vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst | vk::BufferUsageFlagBits::eUniformTexelBuffer | vk::BufferUsageFlagBits::eStorageTexelBuffer | vk::BufferUsageFlagBits::eUniformBuffer | vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eIndirectBuffer,
.sharingMode = vk::SharingMode::eExclusive,
.queueFamilyIndexCount = 1,
.pQueueFamilyIndices = &gpu.vkQueueFamilyIndex,
};
VmaAllocationCreateInfo allocationCreateInfo{
.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT,
.usage = VMA_MEMORY_USAGE_UNKNOWN,
.requiredFlags = static_cast<VkMemoryPropertyFlags>(vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eDeviceLocal),
};
VkBuffer buffer;
VmaAllocation allocation;
VmaAllocationInfo allocationInfo;
ThrowOnFail(vmaCreateBuffer(vmaAllocator, &static_cast<const VkBufferCreateInfo &>(bufferCreateInfo), &allocationCreateInfo, &buffer, &allocation, &allocationInfo));
return Buffer(reinterpret_cast<u8 *>(allocationInfo.pMappedData), allocationInfo.size, vmaAllocator, buffer, allocation);
}
Image MemoryManager::AllocateImage(const vk::ImageCreateInfo &createInfo) { Image MemoryManager::AllocateImage(const vk::ImageCreateInfo &createInfo) {
VmaAllocationCreateInfo allocationCreateInfo{ VmaAllocationCreateInfo allocationCreateInfo{
.usage = VMA_MEMORY_USAGE_GPU_ONLY, .usage = VMA_MEMORY_USAGE_GPU_ONLY,

View File

@ -11,29 +11,36 @@ namespace skyline::gpu::memory {
* @brief A view into a CPU mapping of a Vulkan buffer * @brief A view into a CPU mapping of a Vulkan buffer
* @note The mapping **should not** be used after the lifetime of the object has ended * @note The mapping **should not** be used after the lifetime of the object has ended
*/ */
struct StagingBuffer : public span<u8>, public FenceCycleDependency { struct Buffer : public span<u8> {
VmaAllocator vmaAllocator; VmaAllocator vmaAllocator;
VmaAllocation vmaAllocation; VmaAllocation vmaAllocation;
vk::Buffer vkBuffer; vk::Buffer vkBuffer;
constexpr StagingBuffer(u8 *pointer, size_t size, VmaAllocator vmaAllocator, vk::Buffer vkBuffer, VmaAllocation vmaAllocation) constexpr Buffer(u8 *pointer, size_t size, VmaAllocator vmaAllocator, vk::Buffer vkBuffer, VmaAllocation vmaAllocation)
: vmaAllocator(vmaAllocator), : vmaAllocator(vmaAllocator),
vkBuffer(vkBuffer), vkBuffer(vkBuffer),
vmaAllocation(vmaAllocation), vmaAllocation(vmaAllocation),
span(pointer, size) {} span(pointer, size) {}
StagingBuffer(const StagingBuffer &) = delete; Buffer(const Buffer &) = delete;
constexpr StagingBuffer(StagingBuffer &&other) constexpr Buffer(Buffer &&other)
: vmaAllocator(std::exchange(other.vmaAllocator, nullptr)), : vmaAllocator(std::exchange(other.vmaAllocator, nullptr)),
vmaAllocation(std::exchange(other.vmaAllocation, nullptr)), vmaAllocation(std::exchange(other.vmaAllocation, nullptr)),
vkBuffer(std::exchange(other.vkBuffer, {})) {} vkBuffer(std::exchange(other.vkBuffer, {})) {}
StagingBuffer &operator=(const StagingBuffer &) = delete; Buffer &operator=(const Buffer &) = delete;
StagingBuffer &operator=(StagingBuffer &&) = default; Buffer &operator=(Buffer &&) = default;
~StagingBuffer(); ~Buffer();
};
/**
* @brief A Buffer that can be independently attached to a fence cycle
*/
class StagingBuffer : public Buffer, public FenceCycleDependency {
using Buffer::Buffer;
}; };
/** /**
@ -99,6 +106,11 @@ namespace skyline::gpu::memory {
*/ */
std::shared_ptr<StagingBuffer> AllocateStagingBuffer(vk::DeviceSize size); std::shared_ptr<StagingBuffer> AllocateStagingBuffer(vk::DeviceSize size);
/**
* @brief Creates a buffer with a CPU mapping and all usage flags
*/
Buffer AllocateBuffer(vk::DeviceSize size);
/** /**
* @brief Creates an image which is allocated and deallocated using RAII * @brief Creates an image which is allocated and deallocated using RAII
*/ */