use vma for streambuffer implementation

This commit is contained in:
niki
2022-05-04 15:41:50 +02:00
parent 74c0c192f7
commit e6f8b465bc
5 changed files with 42 additions and 48 deletions
+21 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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");
}
VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT; // always mapped
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);
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
View File
@@ -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
View File
@@ -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 {};