83 lines
2.4 KiB
C++
83 lines
2.4 KiB
C++
#pragma once
|
|
|
|
#include <vulkan/vulkan.h>
|
|
#include "VulkanLogicalDevice.h"
|
|
#include "VulkanMemory.h"
|
|
#include "IntrusivePtr.h"
|
|
|
|
class VulkanBuffer : public RefCountedObject {
|
|
public:
|
|
VulkanBuffer(IntrusivePtr<VulkanLogicalDevice> 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<VulkanLogicalDevice> 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<VulkanMemory> 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<VulkanMemory>(new VulkanMemory(_device, memoryRequirements.size, suitableIndices[0]));
|
|
bindMemory(memory);
|
|
}
|
|
|
|
VkBuffer native() const {
|
|
return _buffer;
|
|
}
|
|
VkDeviceSize size() const {
|
|
return _size;
|
|
}
|
|
IntrusivePtr<VulkanMemory> 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<VulkanLogicalDevice> _device;
|
|
IntrusivePtr<VulkanMemory> _memory;
|
|
};
|