Browse Source

use vma for streambuffer implementation

niki 3 years ago
parent
commit
e6f8b465bc

+ 21 - 5
src/modules/graphics/vulkan/Graphics.cpp

@@ -63,6 +63,7 @@ namespace love {
 					createSurface();
 					pickPhysicalDevice();
 					createLogicalDevice();
+					initVMA();
 					createSwapChain();
 					createImageViews();
 					createRenderPass();
@@ -217,9 +218,9 @@ namespace love {
 				{
 					// Initial sizes that should be good enough for most cases. It will
 					// resize to fit if needed, later.
-					batchedDrawState.vb[0] = new StreamBuffer(device, physicalDevice, BUFFERUSAGE_VERTEX, 1024 * 1024 * 1);
-					batchedDrawState.vb[1] = new StreamBuffer(device, physicalDevice, BUFFERUSAGE_VERTEX, 256 * 1024 * 1);
-					batchedDrawState.indexBuffer = new StreamBuffer(device, physicalDevice, BUFFERUSAGE_INDEX, sizeof(uint16) * LOVE_UINT16_MAX);
+					batchedDrawState.vb[0] = new StreamBuffer(vmaAllocator, BUFFERUSAGE_VERTEX, 1024 * 1024 * 1);
+					batchedDrawState.vb[1] = new StreamBuffer(vmaAllocator, BUFFERUSAGE_VERTEX, 256 * 1024 * 1);
+					batchedDrawState.indexBuffer = new StreamBuffer(vmaAllocator, BUFFERUSAGE_INDEX, sizeof(uint16) * LOVE_UINT16_MAX);
 				}
 
 				return true;
@@ -241,7 +242,7 @@ namespace love {
 
 			graphics::StreamBuffer* Graphics::newStreamBuffer(BufferUsage type, size_t size) { 
 				std::cout << "newStreamBuffer ";
-				return new StreamBuffer(device, physicalDevice, type, size); 
+				return new StreamBuffer(vmaAllocator, type, size);
 			}
 
 			// END IMPLEMENTATION OVERRIDDEN FUNCTIONS
@@ -492,6 +493,21 @@ namespace love {
 				vkGetDeviceQueue(device, indices.presentFamily.value(), 0, &presentQueue);
 			}
 
+			void Graphics::initVMA() {
+				VmaVulkanFunctions vulkanFunctions = {};
+				vulkanFunctions.vkGetInstanceProcAddr = &vkGetInstanceProcAddr;
+				vulkanFunctions.vkGetDeviceProcAddr = &vkGetDeviceProcAddr;
+
+				VmaAllocatorCreateInfo allocatorCreateInfo = {};
+				allocatorCreateInfo.vulkanApiVersion = VK_API_VERSION_1_2;
+				allocatorCreateInfo.physicalDevice = physicalDevice;
+				allocatorCreateInfo.device = device;
+				allocatorCreateInfo.instance = instance;
+				allocatorCreateInfo.pVulkanFunctions = &vulkanFunctions;
+
+				vmaCreateAllocator(&allocatorCreateInfo, &vmaAllocator);
+			}
+
 			void Graphics::createSurface() {
 				auto window = Module::getInstance<love::window::Window>(M_WINDOW);
 				const void* handle = window->getHandle();
@@ -739,7 +755,7 @@ namespace love {
 				VkDeviceSize bufferSize = sizeof(Shader::UniformBufferObject);
 				
 				for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
-					uniformBuffers.push_back(std::make_unique<StreamBuffer>(device, physicalDevice, BUFFERUSAGE_UNIFORM, bufferSize));
+					uniformBuffers.push_back(std::make_unique<StreamBuffer>(vmaAllocator, BUFFERUSAGE_UNIFORM, bufferSize));
 				}
 			}
 

+ 3 - 0
src/modules/graphics/vulkan/Graphics.h

@@ -6,6 +6,7 @@
 #include "ShaderStage.h"
 #include "Shader.h"
 #include <vulkan/vulkan.h>
+#include "vk_mem_alloc.h"
 
 #include <common/config.h>
 
@@ -108,6 +109,7 @@ namespace love {
 				int rateDeviceSuitability(VkPhysicalDevice device);
 				QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
 				void createLogicalDevice();
+				void initVMA();
 				void createSurface();
 				bool checkDeviceExtensionSupport(VkPhysicalDevice device);
 				SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device);
@@ -165,6 +167,7 @@ namespace love {
 				size_t currentFrame = 0;
 				uint32_t imageIndex;
 				bool framebufferResized = false;
+				VmaAllocator vmaAllocator;
 
 				friend class StreamBuffer;
 			};

+ 10 - 37
src/modules/graphics/vulkan/StreamBuffer.cpp

@@ -2,22 +2,10 @@
 #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;
@@ -28,47 +16,32 @@ namespace love {
 				}
 			}
 
-			StreamBuffer::StreamBuffer(VkDevice device, VkPhysicalDevice physicalDevice, BufferUsage mode, size_t size)
-				:	love::graphics::StreamBuffer(mode, size),
-					device(device) {
+			StreamBuffer::StreamBuffer(VmaAllocator allocator, BufferUsage mode, size_t size)
+				:	love::graphics::StreamBuffer(mode, size) {
 				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");
-				}
+				VmaAllocationCreateInfo allocCreateInfo = {};
+				allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
+				allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT;	// always mapped
 
-				vkBindBufferMemory(device, buffer, bufferMemory, 0);
+				vmaCreateBuffer(allocator, &bufferInfo, &allocCreateInfo, &buffer, &allocation, &allocInfo);
 			}
 
 			StreamBuffer::~StreamBuffer() {
-				//vkDestroyBuffer(device, buffer, nullptr);
-				//vkFreeMemory(device, bufferMemory, nullptr);
+				// vmaDestroyBuffer(allocator, buffer, allocation);
+				// vmaDestroyAllocator(allocator);
 			}
 
 			love::graphics::StreamBuffer::MapInfo StreamBuffer::map(size_t minsize) {
 				(void)minsize;
-				vkMapMemory(device, bufferMemory, 0, getSize(), 0, &mappedMemory);
-				return love::graphics::StreamBuffer::MapInfo((uint8*) mappedMemory, getSize());
+				return love::graphics::StreamBuffer::MapInfo((uint8*) allocInfo.pMappedData, getSize());
 			}
 
 			size_t StreamBuffer::unmap(size_t usedSize) {
-				vkUnmapMemory(device, bufferMemory);
 				return usedSize;
 			}
 

+ 6 - 4
src/modules/graphics/vulkan/StreamBuffer.h

@@ -4,13 +4,14 @@
 #include "modules/graphics/StreamBuffer.h"
 #include "vulkan/vulkan.h"
 
+#include "vk_mem_alloc.h"
 
 namespace love {
 	namespace graphics {
 		namespace vulkan {
 			class StreamBuffer : public love::graphics::StreamBuffer {
 			public:
-				StreamBuffer(VkDevice device, VkPhysicalDevice physicalDevice, BufferUsage mode, size_t size);
+				StreamBuffer(VmaAllocator allocator, BufferUsage mode, size_t size);
 				virtual ~StreamBuffer();
 
 				MapInfo map(size_t minsize) override;
@@ -22,13 +23,14 @@ namespace love {
 				}
 
 			private:
+				VmaAllocator allocator;
+				VmaAllocation allocation;
+				VmaAllocationInfo allocInfo;
 				VkDevice device;
 				VkBuffer buffer;
-				VkDeviceMemory bufferMemory;
-				void* mappedMemory;
 			};
 		}
 	}
 }
 
-#endif
+#endif

+ 2 - 2
src/modules/graphics/vulkan/Texture.h

@@ -11,8 +11,8 @@ namespace love {
 				void copyFromBuffer(Buffer* source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect& rect) override {};
 				void copyToBuffer(Buffer* dest, int slice, int mipmap, const Rect& rect, size_t destoffset, int destwidth, size_t size) override {};
 
-				ptrdiff_t getRenderTargetHandle() const override {};
-				ptrdiff_t getSamplerHandle() const override {};
+				ptrdiff_t getRenderTargetHandle() const override { return (ptrdiff_t)0; };
+				ptrdiff_t getSamplerHandle() const override { return (ptrdiff_t)0; };
 
 				void uploadByteData(PixelFormat pixelformat, const void* data, size_t size, int level, int slice, const Rect& r)  override {};