vulkan: fix some memory leaks

This commit is contained in:
niki
2022-07-11 01:13:50 +02:00
parent 7fe2a2d821
commit 0759e8d513
10 changed files with 103 additions and 21 deletions
+17 -4
View File
@@ -26,22 +26,35 @@ 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) {
: love::graphics::Buffer(gfx, settings, format, size, arraylength), usageFlags(settings.usageFlags), allocator(allocator) {
loadVolatile();
}
bool Buffer::loadVolatile() {
VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = size;
bufferInfo.usage = getVulkanUsageFlags(settings.usageFlags);
bufferInfo.size = getSize();
bufferInfo.usage = getVulkanUsageFlags(usageFlags);
VmaAllocationCreateInfo allocCreateInfo = {};
allocCreateInfo.usage = VMA_MEMORY_USAGE_AUTO;
allocCreateInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT;
vmaCreateBuffer(allocator, &bufferInfo, &allocCreateInfo, &buffer, &allocation, &allocInfo);
return true;
}
void Buffer::unloadVolatile() {
if (buffer == VK_NULL_HANDLE)
return;
vmaDestroyBuffer(allocator, buffer, allocation);
buffer = VK_NULL_HANDLE;
}
Buffer::~Buffer() {
// fixme
unloadVolatile();
}
void* Buffer::map(MapType map, size_t offset, size_t size) {
+8 -2
View File
@@ -1,16 +1,20 @@
#include "graphics/Buffer.h"
#include <vulkan/vulkan.h>
#include "vk_mem_alloc.h"
#include "graphics/Volatile.h"
namespace love {
namespace graphics {
namespace vulkan {
class Buffer : public love::graphics::Buffer {
class Buffer : public love::graphics::Buffer, public Volatile {
public:
Buffer(VmaAllocator allocator, love::graphics::Graphics* gfx, const Settings& settings, const std::vector<DataDeclaration>& format, const void* data, size_t size, size_t arraylength);
virtual ~Buffer();
virtual bool loadVolatile() override;
virtual void unloadVolatile() override;
void* map(MapType map, size_t offset, size_t size) override;
void unmap(size_t usedoffset, size_t usedsize) override;
bool fill(size_t offset, size_t size, const void* data) override;
@@ -25,9 +29,11 @@ namespace love {
private:
// todo use a staging buffer for improved performance
VkBuffer buffer;
VkBuffer buffer = VK_NULL_HANDLE;
VmaAllocator allocator;
VmaAllocation allocation;
VmaAllocationInfo allocInfo;
BufferUsageFlags usageFlags;
};
}
}
+9 -1
View File
@@ -302,6 +302,7 @@ namespace love {
std::cout << "unSetMode ";
created = false;
Volatile::unloadAll();
cleanup();
}
@@ -1280,6 +1281,7 @@ namespace love {
if (vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) {
throw love::Exception("failed to create pipeline layout");
}
graphicsPipelineLayouts.push_back(pipelineLayout);
VkGraphicsPipelineCreateInfo pipelineInfo{};
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
@@ -1485,12 +1487,18 @@ namespace love {
}
graphicsPipelines.clear();
currentGraphicsPipeline = VK_NULL_HANDLE;
// vkDestroyPipelineLayout(device, pipelineLayout, nullptr); FIXME
for (const auto pipelineLayout : graphicsPipelineLayouts) {
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
}
graphicsPipelineLayouts.clear();
vkDestroyRenderPass(device, renderPass, nullptr);
for (size_t i = 0; i < swapChainImageViews.size(); i++) {
vkDestroyImageView(device, swapChainImageViews[i], nullptr);
}
vkDestroySwapchainKHR(device, swapChain, nullptr);
for (auto p : uniformBufferMap) {
delete p.second;
}
uniformBufferMap.clear();
descriptorSetsMap.clear();
}
+1
View File
@@ -190,6 +190,7 @@ namespace love {
VkRenderPass renderPass = VK_NULL_HANDLE;
VkPipeline currentGraphicsPipeline = VK_NULL_HANDLE;
std::vector<std::pair<GraphicsPipelineConfiguration, VkPipeline>> graphicsPipelines; // FIXME improve performance by using a hash map
std::vector<VkPipelineLayout> graphicsPipelineLayouts;
std::vector<VkFramebuffer> swapChainFramBuffers;
VkCommandPool commandPool = VK_NULL_HANDLE;
std::vector<VkCommandBuffer> commandBuffers;
+16 -2
View File
@@ -185,7 +185,13 @@ namespace love {
}
ShaderStage::ShaderStage(love::graphics::Graphics* gfx, ShaderStageType stage, const std::string& glsl, bool gles, const std::string& cachekey)
: love::graphics::ShaderStage(gfx, stage, glsl, gles, cachekey) {
: love::graphics::ShaderStage(gfx, stage, glsl, gles, cachekey), gfx(gfx) {
loadVolatile();
}
bool ShaderStage::loadVolatile() {
auto stage = getStageType();
auto glsl = getSource();
auto code = compileShaderWithGlslang(glsl, stage);
VkShaderModuleCreateInfo createInfo{};
@@ -201,8 +207,16 @@ namespace love {
}
}
void ShaderStage::unloadVolatile() {
if (shaderModule == VK_NULL_HANDLE)
return;
vkDestroyShaderModule(device, shaderModule, nullptr);
shaderModule = VK_NULL_HANDLE;
}
ShaderStage::~ShaderStage() {
// vkDestroyShaderModule(device, shaderModule, nullptr);
unloadVolatile();
}
}
}
+7 -3
View File
@@ -8,11 +8,15 @@
namespace love {
namespace graphics {
namespace vulkan {
class ShaderStage final : public graphics::ShaderStage {
class ShaderStage final : public graphics::ShaderStage, public Volatile {
public:
ShaderStage(love::graphics::Graphics* gfx, ShaderStageType stage, const std::string& glsl, bool gles, const std::string& cachekey);
virtual ~ShaderStage();
virtual bool loadVolatile() override;
virtual void unloadVolatile() override;
VkShaderModule getShaderModule() const {
return shaderModule;
}
@@ -22,9 +26,9 @@ namespace love {
}
private:
VkShaderModule shaderModule;
VkShaderModule shaderModule = VK_NULL_HANDLE;
VkDevice device;
love::graphics::Graphics* gfx;
};
}
}
+15 -1
View File
@@ -18,6 +18,10 @@ namespace love {
StreamBuffer::StreamBuffer(VmaAllocator allocator, BufferUsage mode, size_t size)
: love::graphics::StreamBuffer(mode, size), allocator(allocator) {
loadVolatile();
}
bool StreamBuffer::loadVolatile() {
VkBufferCreateInfo bufferInfo{};
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.size = getSize();
@@ -31,10 +35,20 @@ namespace love {
vmaCreateBuffer(allocator, &bufferInfo, &allocCreateInfo, &buffer, &allocation, &allocInfo);
usedGPUMemory = 0;
return true;
}
void StreamBuffer::unloadVolatile() {
if (buffer == VK_NULL_HANDLE)
return;
vmaDestroyBuffer(allocator, buffer, allocation);
buffer = VK_NULL_HANDLE;
}
StreamBuffer::~StreamBuffer() {
// vmaDestroyBuffer(allocator, buffer, allocation);
unloadVolatile();
}
love::graphics::StreamBuffer::MapInfo StreamBuffer::map(size_t minsize) {
+7 -2
View File
@@ -1,6 +1,7 @@
#ifndef LOVE_GRAPHICS_VULKAN_STREAMBUFFER_H
#define LOVE_GRAPHICS_VULKAN_STREAMBUFFER_H
#include "graphics/Volatile.h"
#include "modules/graphics/StreamBuffer.h"
#include "vulkan/vulkan.h"
@@ -9,11 +10,15 @@
namespace love {
namespace graphics {
namespace vulkan {
class StreamBuffer : public love::graphics::StreamBuffer {
class StreamBuffer : public love::graphics::StreamBuffer, public graphics::Volatile {
public:
StreamBuffer(VmaAllocator allocator, BufferUsage mode, size_t size);
virtual ~StreamBuffer();
virtual bool loadVolatile() override;
virtual void unloadVolatile() override;
MapInfo map(size_t minsize) override;
size_t unmap(size_t usedSize) override;
void markUsed(size_t usedSize) override;
@@ -28,7 +33,7 @@ namespace love {
VmaAllocator allocator;
VmaAllocation allocation;
VmaAllocationInfo allocInfo;
VkBuffer buffer;
VkBuffer buffer = VK_NULL_HANDLE;
size_t usedGPUMemory;
};
+17 -4
View File
@@ -9,7 +9,11 @@ namespace love {
namespace graphics {
namespace vulkan {
Texture::Texture(love::graphics::Graphics* gfx, const Settings& settings, const Slices* data)
: love::graphics::Texture(gfx, settings, data), gfx(gfx) {
: love::graphics::Texture(gfx, settings, data), gfx(gfx), data(data) {
loadVolatile();
}
bool Texture::loadVolatile() {
allocator = vgfx->getVmaAllocator();
device = vgfx->getDevice();
@@ -59,10 +63,19 @@ namespace love {
createTextureSampler();
}
void Texture::unloadVolatile() {
if (textureImage == VK_NULL_HANDLE)
return;
vkDestroySampler(device, textureSampler, nullptr);
vkDestroyImageView(device, textureImageView, nullptr);
vmaDestroyImage(allocator, textureImage, nullptr);
textureImage = VK_NULL_HANDLE;
}
Texture::~Texture() {
// vkDestroySampler(device, textureSampler, nullptr);
// vkDestroyImageView(device, textureImageView, nullptr);
// vmaDestroyImage(allocator, textureImage, nullptr);
unloadVolatile();
}
void Texture::createTextureImageView() {
+6 -2
View File
@@ -12,11 +12,14 @@
namespace love {
namespace graphics {
namespace vulkan {
class Texture : public graphics::Texture {
class Texture : public graphics::Texture, public Volatile {
public:
Texture(love::graphics::Graphics* gfx, const Settings& settings, const Slices* data);
~Texture();
virtual bool loadVolatile() override;
virtual void unloadVolatile() override;
void copyFromBuffer(graphics::Buffer* source, size_t sourceoffset, int sourcewidth, size_t size, int slice, int mipmap, const Rect& rect) override { std::cout << "Texture::copyFromBuffer "; };
void copyToBuffer(graphics::Buffer* dest, int slice, int mipmap, const Rect& rect, size_t destoffset, int destwidth, size_t size) override { std::cout << "Texture::copyToBuffer "; };
@@ -41,10 +44,11 @@ namespace love {
graphics::Graphics* gfx;
VkDevice device;
VmaAllocator allocator;
VkImage textureImage;
VkImage textureImage = VK_NULL_HANDLE;
VmaAllocation textureImageAllocation;
VkImageView textureImageView;
VkSampler textureSampler;
const Slices* data;
};
}
}