104 lines
2.9 KiB
C++
104 lines
2.9 KiB
C++
|
#include "xe_buffer.hpp"
|
||
|
|
||
|
#include <cassert>
|
||
|
#include <cstring>
|
||
|
|
||
|
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);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|