mirror of
https://github.com/love2d/love.git
synced 2026-08-14 10:13:46 +02:00
use vma for streambuffer implementation
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user