diff --git a/app/src/main/cpp/skyline/gpu/memory_manager.cpp b/app/src/main/cpp/skyline/gpu/memory_manager.cpp index 40792d38..6e132ac0 100644 --- a/app/src/main/cpp/skyline/gpu/memory_manager.cpp +++ b/app/src/main/cpp/skyline/gpu/memory_manager.cpp @@ -13,7 +13,7 @@ namespace skyline::gpu::memory { vk::throwResultException(vk::Result(result), function); } - StagingBuffer::~StagingBuffer() { + Buffer::~Buffer() { if (vmaAllocator && vmaAllocation && vkBuffer) vmaDestroyBuffer(vmaAllocator, vkBuffer, vmaAllocation); } @@ -95,6 +95,28 @@ namespace skyline::gpu::memory { return std::make_shared(reinterpret_cast(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(vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent | vk::MemoryPropertyFlagBits::eDeviceLocal), + }; + + VkBuffer buffer; + VmaAllocation allocation; + VmaAllocationInfo allocationInfo; + ThrowOnFail(vmaCreateBuffer(vmaAllocator, &static_cast(bufferCreateInfo), &allocationCreateInfo, &buffer, &allocation, &allocationInfo)); + + return Buffer(reinterpret_cast(allocationInfo.pMappedData), allocationInfo.size, vmaAllocator, buffer, allocation); + } + Image MemoryManager::AllocateImage(const vk::ImageCreateInfo &createInfo) { VmaAllocationCreateInfo allocationCreateInfo{ .usage = VMA_MEMORY_USAGE_GPU_ONLY, diff --git a/app/src/main/cpp/skyline/gpu/memory_manager.h b/app/src/main/cpp/skyline/gpu/memory_manager.h index e166c260..a60bb0a7 100644 --- a/app/src/main/cpp/skyline/gpu/memory_manager.h +++ b/app/src/main/cpp/skyline/gpu/memory_manager.h @@ -11,29 +11,36 @@ namespace skyline::gpu::memory { * @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 */ - struct StagingBuffer : public span, public FenceCycleDependency { + struct Buffer : public span { VmaAllocator vmaAllocator; VmaAllocation vmaAllocation; 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), vkBuffer(vkBuffer), vmaAllocation(vmaAllocation), 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)), vmaAllocation(std::exchange(other.vmaAllocation, nullptr)), 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 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 */