From a5082d2962d621dc7145614d655016c59ddacc5b Mon Sep 17 00:00:00 2001 From: Jean-Philippe Bruyère Date: Fri, 26 Oct 2018 13:28:54 +0200 Subject: restructuration and test --- src/buffer.cpp | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 src/buffer.cpp (limited to 'src/buffer.cpp') diff --git a/src/buffer.cpp b/src/buffer.cpp new file mode 100644 index 0000000..1974cfa --- /dev/null +++ b/src/buffer.cpp @@ -0,0 +1,142 @@ +#include "VulkanBuffer.hpp" + +#include "VulkanDevice.hpp" +#include "resource.hpp" +#include "macros.h" + +namespace vke +{ + buffer_t::buffer_t(device_t* _device, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags _memoryPropertyFlags, VkDeviceSize size, void *data) + { + device = _device; + + infos.size = size; + infos.usage = usageFlags; + infos.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + + memoryPropertyFlags = _memoryPropertyFlags; + + VK_CHECK_RESULT(vkCreateBuffer(device->dev, &infos, nullptr, &buffer)); + + vkGetBufferMemoryRequirements(device->dev, buffer, &memReqs); + + VkMemoryAllocateInfo memAlloc = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO}; + memAlloc.allocationSize = memReqs.size; + memAlloc.memoryTypeIndex = device->getMemoryType(memReqs.memoryTypeBits, _memoryPropertyFlags); + + VK_CHECK_RESULT(vkAllocateMemory(device->dev, &memAlloc, nullptr, &deviceMemory)); + + size = memAlloc.allocationSize; + + // If a pointer to the buffer data has been passed, map the buffer and copy over the data + if (data != nullptr) + { + VK_CHECK_RESULT(map()); + memcpy(mapped, data, size); + unmap(); + } + + // Initialize a default descriptor that covers the whole buffer size + setupDescriptor(); + + // Attach the memory to the buffer object + VK_CHECK_RESULT(bind()); + } + buffer_t::~buffer_t() + { + unmap(); + + if (deviceMemory) + vkFreeMemory(device->dev, deviceMemory, nullptr); + if (buffer) + vkDestroyBuffer(device->dev, buffer, nullptr); + + } + + VkResult buffer_t::map(VkDeviceSize size, VkDeviceSize offset) + { + return vkMapMemory(device->dev, deviceMemory, offset, size, 0, &mapped); + } + void buffer_t::unmap() + { + if (mapped) + { + vkUnmapMemory(device->dev, deviceMemory); + mapped = nullptr; + } + } + + VkResult buffer_t::bind(VkDeviceSize offset) + { + return vkBindBufferMemory(device->dev, buffer, deviceMemory, offset); + } + + void buffer_t::setupDescriptor(VkDeviceSize size, VkDeviceSize offset) + { + descriptor.offset = offset; + descriptor.buffer = buffer; + descriptor.range = size; + } + + VkWriteDescriptorSet buffer_t::getWriteDescriptorSet(VkDescriptorSet ds, uint32_t binding, VkDescriptorType descriptorType) { + VkWriteDescriptorSet wds = {VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET}; + wds.dstSet = ds; + wds.descriptorType = descriptorType; + wds.dstBinding = binding; + wds.descriptorCount = 1; + wds.pBufferInfo = &descriptor; + return wds; + } + + /** + * Copies the specified data to the mapped buffer + * + * @param data Pointer to the data to copy + * @param size Size of the data to copy in machine units + * + */ + void buffer_t::copyTo(void* data, VkDeviceSize size) + { + assert(mapped); + memcpy(mapped, data, size); + } + + /** + * Flush a memory range of the buffer to make it visible to the device + * + * @note Only required for non-coherent memory + * + * @param size (Optional) Size of the memory range to flush. Pass VK_WHOLE_SIZE to flush the complete buffer range. + * @param offset (Optional) Byte offset from beginning + * + * @return VkResult of the flush call + */ + VkResult buffer_t::flush(VkDeviceSize size, VkDeviceSize offset) + { + VkMappedMemoryRange mappedRange = {}; + mappedRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; + mappedRange.memory = deviceMemory; + mappedRange.offset = offset; + mappedRange.size = size; + return vkFlushMappedMemoryRanges(device->dev, 1, &mappedRange); + } + + /** + * Invalidate a memory range of the buffer to make it visible to the host + * + * @note Only required for non-coherent memory + * + * @param size (Optional) Size of the memory range to invalidate. Pass VK_WHOLE_SIZE to invalidate the complete buffer range. + * @param offset (Optional) Byte offset from beginning + * + * @return VkResult of the invalidate call + */ + VkResult buffer_t::invalidate(VkDeviceSize size, VkDeviceSize offset) + { + VkMappedMemoryRange mappedRange = {VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE}; + mappedRange.memory = deviceMemory; + mappedRange.offset = offset; + mappedRange.size = size; + return vkInvalidateMappedMemoryRanges(device->dev, 1, &mappedRange); + } +} -- cgit v1.3.1-4-g156e