#include "xe_buffer.hpp" #include #include namespace xe { VkDeviceSize XeBuffer::getAlignment(VkDeviceSize instanceSize, VkDeviceSize minOffsetAlignment) { if (minOffsetAlignment > 0) { return (instanceSize + minOffsetAlignment - 1) & ~(minOffsetAlignment - 1); } return instanceSize; } XeBuffer::XeBuffer( XeDevice &device, VkDeviceSize instanceSize, uint32_t instanceCount, VkBufferUsageFlags usageFlags, VkMemoryPropertyFlags memoryPropertyFlags, VkDeviceSize minOffsetAlignment) : xeDevice{device}, instanceSize{instanceSize}, instanceCount{instanceCount}, usageFlags{usageFlags}, memoryPropertyFlags{memoryPropertyFlags} { alignmentSize = getAlignment(instanceSize, minOffsetAlignment); bufferSize = alignmentSize * instanceCount; device.createBuffer(bufferSize, usageFlags, memoryPropertyFlags, buffer, memory); } XeBuffer::~XeBuffer() { unmap(); vkDestroyBuffer(xeDevice.device(), buffer, nullptr); vkFreeMemory(xeDevice.device(), memory, nullptr); } VkResult XeBuffer::map(VkDeviceSize size, VkDeviceSize offset) { assert(buffer && memory && "Called map on buffer before create"); return vkMapMemory(xeDevice.device(), memory, offset, size, 0, &mapped); } void XeBuffer::unmap() { if (mapped) { vkUnmapMemory(xeDevice.device(), memory); mapped = nullptr; } } void XeBuffer::writeToBuffer(void *data, VkDeviceSize size, VkDeviceSize offset) { assert(mapped && "Cannot copy to unmapped buffer"); if (size == VK_WHOLE_SIZE) { memcpy(mapped, data, bufferSize); } else { char *memOffset = (char *)mapped; memOffset += offset; memcpy(memOffset, data, size); } } VkResult XeBuffer::flush(VkDeviceSize size, VkDeviceSize offset) { VkMappedMemoryRange mappedRange = {}; mappedRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; mappedRange.memory = memory; mappedRange.offset = offset; mappedRange.size = size; return vkFlushMappedMemoryRanges(xeDevice.device(), 1, &mappedRange); } VkResult XeBuffer::invalidate(VkDeviceSize size, VkDeviceSize offset) { VkMappedMemoryRange mappedRange = {}; mappedRange.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; mappedRange.memory = memory; mappedRange.offset = offset; mappedRange.size = size; return vkInvalidateMappedMemoryRanges(xeDevice.device(), 1, &mappedRange); } VkDescriptorBufferInfo XeBuffer::descriptorInfo(VkDeviceSize size, VkDeviceSize offset) { return VkDescriptorBufferInfo{ buffer, offset, size, }; } void XeBuffer::writeToIndex(void *data, int index) { writeToBuffer(data, instanceSize, index * alignmentSize); } VkResult XeBuffer::flushIndex(int index) { return flush(alignmentSize, index * alignmentSize); } VkDescriptorBufferInfo XeBuffer::descriptorInfoForIndex(int index) { return descriptorInfo(alignmentSize, index * alignmentSize); } VkResult XeBuffer::invalidateIndex(int index) { return invalidate(alignmentSize, index * alignmentSize); } }