summaryrefslogtreecommitdiff
path: root/engine/xe_buffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engine/xe_buffer.cpp')
-rw-r--r--engine/xe_buffer.cpp103
1 files changed, 103 insertions, 0 deletions
diff --git a/engine/xe_buffer.cpp b/engine/xe_buffer.cpp
new file mode 100644
index 0000000..0c0006f
--- /dev/null
+++ b/engine/xe_buffer.cpp
@@ -0,0 +1,103 @@
+#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);
+}
+
+}
+