Browse Source

add vulkan streambuffer implementation

niki 3 years ago
parent
commit
4d7fe75001

+ 2 - 0
CMakeLists.txt

@@ -578,6 +578,8 @@ set(LOVE_SRC_MODULE_GRAPHICS_VULKAN
 	src/modules/graphics/vulkan/Shader.cpp
 	src/modules/graphics/vulkan/Shader.cpp
 	src/modules/graphics/vulkan/ShaderStage.h
 	src/modules/graphics/vulkan/ShaderStage.h
 	src/modules/graphics/vulkan/ShaderStage.cpp
 	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.h
 	src/modules/graphics/vulkan/Buffer.cpp
 	src/modules/graphics/vulkan/Buffer.cpp
 )
 )

+ 72 - 0
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;
+			}
+		}
+	}
+}

+ 33 - 0
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