diff --git a/src/modules/graphics/vulkan/Buffer.cpp b/src/modules/graphics/vulkan/Buffer.cpp index b7affc80f..eade4fda3 100644 --- a/src/modules/graphics/vulkan/Buffer.cpp +++ b/src/modules/graphics/vulkan/Buffer.cpp @@ -26,11 +26,14 @@ namespace love { } Buffer::Buffer(VmaAllocator allocator, love::graphics::Graphics* gfx, const Settings& settings, const std::vector& 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; } diff --git a/src/modules/graphics/vulkan/Buffer.h b/src/modules/graphics/vulkan/Buffer.h index ac84e0456..854250006 100644 --- a/src/modules/graphics/vulkan/Buffer.h +++ b/src/modules/graphics/vulkan/Buffer.h @@ -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; diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index 07cc95734..4fd083a54 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -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); diff --git a/src/modules/graphics/vulkan/ShaderStage.cpp b/src/modules/graphics/vulkan/ShaderStage.cpp index fe9489b18..6b6b98724 100644 --- a/src/modules/graphics/vulkan/ShaderStage.cpp +++ b/src/modules/graphics/vulkan/ShaderStage.cpp @@ -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; } diff --git a/src/modules/graphics/vulkan/StreamBuffer.cpp b/src/modules/graphics/vulkan/StreamBuffer.cpp index 2c204bfc5..a1cd2e662 100644 --- a/src/modules/graphics/vulkan/StreamBuffer.cpp +++ b/src/modules/graphics/vulkan/StreamBuffer.cpp @@ -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; } diff --git a/src/modules/graphics/vulkan/StreamBuffer.h b/src/modules/graphics/vulkan/StreamBuffer.h index 2939cf10f..ab02966e7 100644 --- a/src/modules/graphics/vulkan/StreamBuffer.h +++ b/src/modules/graphics/vulkan/StreamBuffer.h @@ -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; diff --git a/src/modules/graphics/vulkan/Texture.cpp b/src/modules/graphics/vulkan/Texture.cpp index a67149ccc..8f26c6cbe 100644 --- a/src/modules/graphics/vulkan/Texture.cpp +++ b/src/modules/graphics/vulkan/Texture.cpp @@ -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; }