From 4d7fe75001b8dbda47507f465c25adcc6849d762 Mon Sep 17 00:00:00 2001 From: niki Date: Sun, 16 Jan 2022 02:58:11 +0100 Subject: [PATCH] add vulkan streambuffer implementation --- CMakeLists.txt | 2 + src/modules/graphics/vulkan/StreamBuffer.cpp | 72 ++++++++++++++++++++ src/modules/graphics/vulkan/StreamBuffer.h | 33 +++++++++ 3 files changed, 107 insertions(+) create mode 100644 src/modules/graphics/vulkan/StreamBuffer.cpp create mode 100644 src/modules/graphics/vulkan/StreamBuffer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index aeb0d1b99..44cbb6dc6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -578,6 +578,8 @@ set(LOVE_SRC_MODULE_GRAPHICS_VULKAN src/modules/graphics/vulkan/Shader.cpp src/modules/graphics/vulkan/ShaderStage.h src/modules/graphics/vulkan/ShaderStage.cpp + src/modules/graphics/vulkan/StreamBuffer.h + src/modules/graphics/vulkan/StreamBuffer.cpp src/modules/graphics/vulkan/Buffer.h src/modules/graphics/vulkan/Buffer.cpp ) diff --git a/src/modules/graphics/vulkan/StreamBuffer.cpp b/src/modules/graphics/vulkan/StreamBuffer.cpp new file mode 100644 index 000000000..5c6fd360b --- /dev/null +++ b/src/modules/graphics/vulkan/StreamBuffer.cpp @@ -0,0 +1,72 @@ +#include "StreamBuffer.h" +#include "vulkan/vulkan.h" + + +namespace love { + namespace graphics { + namespace vulkan { + static uint32_t findMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFtiler, VkMemoryPropertyFlags properties) { + VkPhysicalDeviceMemoryProperties memProperties; + vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties); + + for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) { + if ((typeFtiler & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) { + return i; + } + } + + throw love::Exception("failed to find suitable memory type"); + } + + static VkBufferUsageFlags getUsageFlags(BufferUsage mode) { + switch (mode) { + case BUFFERUSAGE_VERTEX: return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + case BUFFERUSAGE_INDEX: return VK_BUFFER_USAGE_INDEX_BUFFER_BIT; + default: + throw love::Exception("unsupported BufferUsage mode"); + } + } + + StreamBuffer::StreamBuffer(VkDevice device, VkPhysicalDevice physicalDevice, BufferUsage mode, size_t size) + : love::graphics::StreamBuffer(mode, size), + device(device) { + VkBufferCreateInfo bufferInfo{}; + bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bufferInfo.size = getSize(); + bufferInfo.usage = getUsageFlags(mode); + bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + + if (vkCreateBuffer(device, &bufferInfo, nullptr, &buffer) != VK_SUCCESS) { + throw love::Exception("failed to create buffer"); + } + + VkMemoryRequirements memRequirements; + vkGetBufferMemoryRequirements(device, buffer, &memRequirements); + + VkMemoryAllocateInfo allocInfo{}; + allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + allocInfo.allocationSize = memRequirements.size; + allocInfo.memoryTypeIndex = findMemoryType(physicalDevice, memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + + if (vkAllocateMemory(device, &allocInfo, nullptr, &bufferMemory) != VK_SUCCESS) { + throw love::Exception("failed to allocate vertex buffer memory"); + } + + vkBindBufferMemory(device, buffer, bufferMemory, 0); + } + + love::graphics::StreamBuffer::MapInfo StreamBuffer::map(size_t minsize) { + vkMapMemory(device, bufferMemory, 0, getSize(), 0, &mappedMemory); + return love::graphics::StreamBuffer::MapInfo((uint8*) mappedMemory, getSize()); + } + + size_t StreamBuffer::unmap(size_t usedSize) { + vkUnmapMemory(device, bufferMemory); + } + + void StreamBuffer::markUsed(size_t usedSize) { + (void)usedSize; + } + } + } +} diff --git a/src/modules/graphics/vulkan/StreamBuffer.h b/src/modules/graphics/vulkan/StreamBuffer.h new file mode 100644 index 000000000..d3a23e1b5 --- /dev/null +++ b/src/modules/graphics/vulkan/StreamBuffer.h @@ -0,0 +1,33 @@ +#ifndef LOVE_GRAPHICS_VULKAN_STREAMBUFFER_H +#define LOVE_GRAPHICS_VULKAN_STREAMBUFFER_H + +#include "modules/graphics/StreamBuffer.h" +#include "vulkan/vulkan.h" + + +namespace love { + namespace graphics { + namespace vulkan { + class StreamBuffer : public love::graphics::StreamBuffer { + public: + StreamBuffer(VkDevice device, VkPhysicalDevice physicalDevice, BufferUsage mode, size_t size); + + MapInfo map(size_t minsize) override; + size_t unmap(size_t usedSize) override; + void markUsed(size_t usedSize) override; + + ptrdiff_t getHandle() const override { + return 0; + } + + private: + VkDevice device; + VkBuffer buffer; + VkDeviceMemory bufferMemory; + void* mappedMemory; + }; + } + } +} + +#endif \ No newline at end of file