vulkan: fix clean up

We now don't do any more greedy waiting when destroying vulkan objects.
This commit is contained in:
niki
2022-07-29 22:59:15 +02:00
parent 524e011133
commit 1096b76054
6 changed files with 36 additions and 27 deletions
+6 -4
View File
@@ -55,10 +55,12 @@ namespace love {
Graphics* vgfx = (Graphics*)gfx; Graphics* vgfx = (Graphics*)gfx;
auto device = vgfx->getDevice(); auto device = vgfx->getDevice();
// FIXME: objects for deletion should probably be put on a queue vgfx->queueCleanUp(
// instead of greedy waiting here. [device=device, allocator=allocator, buffer=buffer, allocation=allocation](){
vkDeviceWaitIdle(device); vkDeviceWaitIdle(device);
vmaDestroyBuffer(allocator, buffer, allocation); vmaDestroyBuffer(allocator, buffer, allocation);
});
buffer = VK_NULL_HANDLE; buffer = VK_NULL_HANDLE;
} }
+4
View File
@@ -556,6 +556,10 @@ namespace love {
cleanUpFunctions.at(currentFrame).push_back(std::move(cleanUp)); cleanUpFunctions.at(currentFrame).push_back(std::move(cleanUp));
} }
void Graphics::queueCleanUp(std::function<void()> cleanUp) {
cleanUpFunctions.at(currentFrame).push_back(std::move(cleanUp));
}
VkCommandBuffer Graphics::beginSingleTimeCommands() { VkCommandBuffer Graphics::beginSingleTimeCommands() {
VkCommandBufferAllocateInfo allocInfo{}; VkCommandBufferAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
+2
View File
@@ -114,7 +114,9 @@ namespace love {
GraphicsReadback* newReadbackInternal(ReadbackMethod method, love::graphics::Buffer* buffer, size_t offset, size_t size, data::ByteData* dest, size_t destoffset) override { return nullptr; }; GraphicsReadback* newReadbackInternal(ReadbackMethod method, love::graphics::Buffer* buffer, size_t offset, size_t size, data::ByteData* dest, size_t destoffset) override { return nullptr; };
GraphicsReadback* newReadbackInternal(ReadbackMethod method, love::graphics::Texture* texture, int slice, int mipmap, const Rect& rect, image::ImageData* dest, int destx, int desty) { return nullptr; } GraphicsReadback* newReadbackInternal(ReadbackMethod method, love::graphics::Texture* texture, int slice, int mipmap, const Rect& rect, image::ImageData* dest, int destx, int desty) { return nullptr; }
// fixme: better naming for these two functions?
void executeCommand(std::function<void(VkCommandBuffer)> command, std::function<void()> cleanUp); void executeCommand(std::function<void(VkCommandBuffer)> command, std::function<void()> cleanUp);
void queueCleanUp(std::function<void()> cleanUp);
VkCommandBuffer beginSingleTimeCommands(); VkCommandBuffer beginSingleTimeCommands();
void endSingleTimeCommands(VkCommandBuffer); void endSingleTimeCommands(VkCommandBuffer);
+9 -10
View File
@@ -167,19 +167,18 @@ namespace love {
} }
auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS); auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
auto device = gfx->getDevice(); gfx->queueCleanUp([shaderModules = std::move(shaderModules), device = device, descriptorSetLayout = descriptorSetLayout, pipelineLayout = pipelineLayout](){
// fixme: we shouldn't do a greedy wait here. for (const auto shaderModule : shaderModules) {
vkDeviceWaitIdle(device); vkDestroyShaderModule(device, shaderModule, nullptr);
for (const auto shaderModule : shaderModules) { }
vkDestroyShaderModule(device, shaderModule, nullptr); vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
} vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
shaderModules.clear(); });
shaderStages.clear();
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
for (const auto streamBuffer : streamBuffers) { for (const auto streamBuffer : streamBuffers) {
delete streamBuffer; delete streamBuffer;
} }
shaderModules.clear();
shaderStages.clear();
streamBuffers.clear(); streamBuffers.clear();
} }
+4 -7
View File
@@ -46,13 +46,10 @@ namespace love {
if (buffer == VK_NULL_HANDLE) if (buffer == VK_NULL_HANDLE)
return; return;
Graphics* vgfx = (Graphics*)gfx; auto vgfx = (Graphics*)gfx;
auto device = vgfx->getDevice(); vgfx->queueCleanUp([allocator=allocator, buffer=buffer, allocation=allocation](){
vmaDestroyBuffer(allocator, buffer, allocation);
// 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; buffer = VK_NULL_HANDLE;
} }
+11 -6
View File
@@ -74,12 +74,17 @@ namespace love {
if (textureImage == VK_NULL_HANDLE) if (textureImage == VK_NULL_HANDLE)
return; return;
// FIXME: objects for deletion should probably be put on a queue vgfx->queueCleanUp([
// instead of greedy waiting here. device = device,
vkDeviceWaitIdle(device); textureSampler = textureSampler,
vkDestroySampler(device, textureSampler, nullptr); textureImageView = textureImageView,
vkDestroyImageView(device, textureImageView, nullptr); allocator = allocator,
vmaDestroyImage(allocator, textureImage, textureImageAllocation); textureImage = textureImage,
textureImageAllocation = textureImageAllocation] () {
vkDestroySampler(device, textureSampler, nullptr);
vkDestroyImageView(device, textureImageView, nullptr);
vmaDestroyImage(allocator, textureImage, textureImageAllocation);
});
textureImage = VK_NULL_HANDLE; textureImage = VK_NULL_HANDLE;
} }