#pragma once #include #include "VulkanLogicalDevice.h" #include "VulkanMemory.h" #include "IntrusivePtr.h" class VulkanBuffer : public RefCountedObject { public: VulkanBuffer(IntrusivePtr device, VkBufferCreateInfo createInfo):_device(device) { internalConstruct(createInfo); } VulkanBuffer(const VulkanBuffer&) = delete; VulkanBuffer(VulkanBuffer&& other) noexcept { _buffer = other._buffer; _size = other._size; _device = other._device; _memory = other._memory; other._buffer = nullptr; other._size = 0; other._device = nullptr; other._memory = nullptr; } VulkanBuffer(IntrusivePtr device, VkDeviceSize size, VkBufferUsageFlags usageFlags) : _device(device) { VkBufferCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; createInfo.size = size; createInfo.usage = usageFlags; internalConstruct(createInfo); } VkMemoryRequirements getMemoryRequirements() { VkMemoryRequirements result; _device->functions().vkGetBufferMemoryRequirements(_buffer, &result); return result; } void bindMemory(IntrusivePtr memory) { _memory = memory; if (_device->functions().vkBindBufferMemory(_buffer, _memory->native(), 0) != VK_SUCCESS) { throw std::runtime_error("Failed to bind memory to vulkan buffer"); } } void allocateMemory(VkMemoryPropertyFlags flags) { auto memoryProps = _device->physicalDevice()->getMemoryProperties(); auto memoryRequirements = getMemoryRequirements(); auto suitableIndices = memoryProps.findSuitableMemoryTypeIndices(flags, memoryRequirements.memoryTypeBits); auto memory = IntrusivePtr(new VulkanMemory(_device, memoryRequirements.size, suitableIndices[0])); bindMemory(memory); } VkBuffer native() const { return _buffer; } VkDeviceSize size() const { return _size; } IntrusivePtr memory() { return _memory; } ~VulkanBuffer() { if (_buffer != nullptr) { _device->functions().vkDestroyBuffer(_buffer, nullptr); } } private: void internalConstruct( VkBufferCreateInfo createInfo) { if (_device->functions().vkCreateBuffer(&createInfo, nullptr, &_buffer) != VK_SUCCESS) { throw std::runtime_error("Failed to create vulkan buffer"); } _size = createInfo.size; } VkBuffer _buffer = {}; VkDeviceSize _size; IntrusivePtr _device; IntrusivePtr _memory; };