vulkan: fix all memory leaks

Now now errors regarding resource management appear in the debug output / validation layers.
This commit is contained in:
niki
2022-07-11 13:58:35 +02:00
parent c5327bfc4f
commit 9d04ec0030
7 changed files with 42 additions and 13 deletions
+10 -1
View File
@@ -26,11 +26,14 @@ namespace love {
}
Buffer::Buffer(VmaAllocator allocator, love::graphics::Graphics* gfx, const Settings& settings, const std::vector<DataDeclaration>& format, const void* data, size_t size, size_t arraylength)
: love::graphics::Buffer(gfx, settings, format, size, arraylength), usageFlags(settings.usageFlags), allocator(allocator) {
: love::graphics::Buffer(gfx, settings, format, size, arraylength), usageFlags(settings.usageFlags), allocator(allocator), gfx(gfx) {
loadVolatile();
}
bool Buffer::loadVolatile() {
Graphics* vgfx = (Graphics*)gfx;
allocator = vgfx->getVmaAllocator();
VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = getSize();
@@ -49,6 +52,12 @@ namespace love {
if (buffer == VK_NULL_HANDLE)
return;
Graphics* vgfx = (Graphics*)gfx;
auto device = vgfx->getDevice();
// FIXME: objects for deletion should probably be put on a queue
// instead of greedy waiting here.
vkDeviceWaitIdle(device);
vmaDestroyBuffer(allocator, buffer, allocation);
buffer = VK_NULL_HANDLE;
}
+1
View File
@@ -30,6 +30,7 @@ namespace love {
private:
// todo use a staging buffer for improved performance
VkBuffer buffer = VK_NULL_HANDLE;
love::graphics::Graphics* gfx;
VmaAllocator allocator;
VmaAllocation allocation;
VmaAllocationInfo allocInfo;
+9 -7
View File
@@ -234,12 +234,12 @@ namespace love {
batchedDrawBuffers.emplace_back();
// Initial sizes that should be good enough for most cases. It will
// resize to fit if needed, later.
batchedDrawBuffers[i].vertexBuffer1 = new StreamBuffer(vmaAllocator, BUFFERUSAGE_VERTEX, 1024 * 1024 * 1);
batchedDrawBuffers[i].vertexBuffer2 = new StreamBuffer(vmaAllocator, BUFFERUSAGE_VERTEX, 256 * 1024 * 1);
batchedDrawBuffers[i].indexBuffer = new StreamBuffer(vmaAllocator, BUFFERUSAGE_INDEX, sizeof(uint16) * LOVE_UINT16_MAX);
batchedDrawBuffers[i].vertexBuffer1 = new StreamBuffer(this, BUFFERUSAGE_VERTEX, 1024 * 1024 * 1);
batchedDrawBuffers[i].vertexBuffer2 = new StreamBuffer(this, BUFFERUSAGE_VERTEX, 256 * 1024 * 1);
batchedDrawBuffers[i].indexBuffer = new StreamBuffer(this, BUFFERUSAGE_INDEX, sizeof(uint16) * LOVE_UINT16_MAX);
// sometimes the VertexColor is not set, so we manually adjust it to white color
batchedDrawBuffers[i].constantColorBuffer = new StreamBuffer(vmaAllocator, BUFFERUSAGE_VERTEX, sizeof(whiteColor));
batchedDrawBuffers[i].constantColorBuffer = new StreamBuffer(this, BUFFERUSAGE_VERTEX, sizeof(whiteColor));
auto mapInfo = batchedDrawBuffers[i].constantColorBuffer->map(sizeof(whiteColor));
memcpy(mapInfo.data, whiteColor, sizeof(whiteColor));
batchedDrawBuffers[i].constantColorBuffer->unmap(sizeof(whiteColor));
@@ -302,6 +302,7 @@ namespace love {
std::cout << "unSetMode ";
created = false;
vkDeviceWaitIdle(device);
Volatile::unloadAll();
cleanup();
}
@@ -374,7 +375,7 @@ namespace love {
graphics::StreamBuffer* Graphics::newStreamBuffer(BufferUsage type, size_t size) {
std::cout << "newStreamBuffer ";
return new StreamBuffer(vmaAllocator, type, size);
return new StreamBuffer(this, type, size);
}
Matrix4 Graphics::computeDeviceProjection(const Matrix4& projection, bool rendertotexture) const {
@@ -1135,6 +1136,8 @@ namespace love {
// do we need to use a constant VertexColor?
if (!usesColor) {
// FIXME: is there a case where gaps happen between buffer bindings?
// then this doesn't work. We might need to enable null buffers again.
const auto constantColorBufferBinding = highestBufferBinding + 1;
VkVertexInputBindingDescription bindingDescription{};
@@ -1456,10 +1459,9 @@ namespace love {
}
void Graphics::cleanup() {
vkDeviceWaitIdle(device);
cleanupSwapChain();
vmaDestroyAllocator(vmaAllocator);
batchedDrawBuffers.clear();
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
vkDestroySemaphore(device, renderFinishedSemaphores[i], nullptr);
@@ -213,6 +213,9 @@ namespace love {
if (shaderModule == VK_NULL_HANDLE)
return;
// FIXME: objects for deletion should probably be put on a queue
// instead of greedy waiting here.
vkDeviceWaitIdle(device);
vkDestroyShaderModule(device, shaderModule, nullptr);
shaderModule = VK_NULL_HANDLE;
}
+12 -3
View File
@@ -1,6 +1,6 @@
#include "StreamBuffer.h"
#include "vulkan/vulkan.h"
#include "Graphics.h"
namespace love {
@@ -16,12 +16,15 @@ namespace love {
}
}
StreamBuffer::StreamBuffer(VmaAllocator allocator, BufferUsage mode, size_t size)
: love::graphics::StreamBuffer(mode, size), allocator(allocator) {
StreamBuffer::StreamBuffer(graphics::Graphics* gfx, BufferUsage mode, size_t size)
: love::graphics::StreamBuffer(mode, size), gfx(gfx) {
loadVolatile();
}
bool StreamBuffer::loadVolatile() {
Graphics* vgfx = (Graphics*)gfx;
allocator = vgfx->getVmaAllocator();
VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = getSize();
@@ -43,6 +46,12 @@ namespace love {
if (buffer == VK_NULL_HANDLE)
return;
Graphics* vgfx = (Graphics*)gfx;
auto device = vgfx->getDevice();
// FIXME: objects for deletion should probably be put on a queue
// instead of greedy waiting here.
vkDeviceWaitIdle(device);
vmaDestroyBuffer(allocator, buffer, allocation);
buffer = VK_NULL_HANDLE;
}
+3 -1
View File
@@ -4,6 +4,7 @@
#include "graphics/Volatile.h"
#include "modules/graphics/StreamBuffer.h"
#include "vulkan/vulkan.h"
#include "graphics/Graphics.h"
#include "vk_mem_alloc.h"
@@ -12,7 +13,7 @@ namespace love {
namespace vulkan {
class StreamBuffer : public love::graphics::StreamBuffer, public graphics::Volatile {
public:
StreamBuffer(VmaAllocator allocator, BufferUsage mode, size_t size);
StreamBuffer(graphics::Graphics* gfx, BufferUsage mode, size_t size);
virtual ~StreamBuffer();
virtual bool loadVolatile() override;
@@ -30,6 +31,7 @@ namespace love {
}
private:
graphics::Graphics* gfx;
VmaAllocator allocator;
VmaAllocation allocation;
VmaAllocationInfo allocInfo;
+4 -1
View File
@@ -69,9 +69,12 @@ namespace love {
if (textureImage == VK_NULL_HANDLE)
return;
// FIXME: objects for deletion should probably be put on a queue
// instead of greedy waiting here.
vkDeviceWaitIdle(device);
vkDestroySampler(device, textureSampler, nullptr);
vkDestroyImageView(device, textureImageView, nullptr);
vmaDestroyImage(allocator, textureImage, nullptr);
vmaDestroyImage(allocator, textureImage, textureImageAllocation);
textureImage = VK_NULL_HANDLE;
}