Wait for GEVulkanCommandLoader to finish task before deleting textures

This commit is contained in:
Benau 2022-08-10 11:07:54 +08:00
parent ed4dcc24c6
commit c698d4a601
5 changed files with 38 additions and 3 deletions

View File

@ -340,7 +340,7 @@ namespace GE
unsigned getGraphicsQueueCount() const
{ return m_graphics_queue_count; }
std::unique_lock<std::mutex> getGraphicsQueue(VkQueue* queue) const;
void waitIdle();
void waitIdle(bool flush_command_loader = false);
void setDisableWaitIdle(bool val) { m_disable_wait_idle = val; }
IrrlichtDevice* getIrrlichtDevice() const { return m_irrlicht_device; }
GEVulkanDepthTexture* getDepthTexture() const { return m_depth_texture; }

View File

@ -6,6 +6,7 @@
#include <condition_variable>
#include <cstdio>
#include <deque>
#include <memory>
#include <mutex>
#include <thread>
@ -46,6 +47,7 @@ std::atomic_uint g_loader_count(0);
std::vector<VkCommandPool> g_command_pools;
std::vector<VkFence> g_command_fences;
std::vector<std::unique_ptr<std::atomic<bool> > > g_thread_idle;
} // GEVulkanCommandLoader
// ============================================================================
@ -84,6 +86,12 @@ void GEVulkanCommandLoader::init(GEVulkanDriver* vk)
}
}
for (unsigned i = 0; i < thread_count - 1; i++)
{
std::unique_ptr<std::atomic<bool> > idle;
idle.reset(new std::atomic<bool>(true));
g_thread_idle.push_back(std::move(idle));
}
g_loader_count.store(thread_count);
for (unsigned i = 0; i < thread_count - 1; i++)
{
@ -93,6 +101,7 @@ void GEVulkanCommandLoader::init(GEVulkanDriver* vk)
g_loader_id = i + 1;
while (true)
{
g_thread_idle[i]->store(true);
std::unique_lock<std::mutex> ul(g_loaders_mutex);
g_loaders_cv.wait(ul, []
{
@ -101,6 +110,7 @@ void GEVulkanCommandLoader::init(GEVulkanDriver* vk)
if (g_loader_count.load() == 0)
return;
g_thread_idle[i]->store(false);
std::function<void()> copied = g_threaded_commands.front();
g_threaded_commands.pop_front();
ul.unlock();
@ -132,6 +142,7 @@ void GEVulkanCommandLoader::destroy()
for (auto& f : g_threaded_commands)
f();
g_threaded_commands.clear();
g_thread_idle.clear();
for (VkCommandPool& pool : g_command_pools)
vkDestroyCommandPool(g_vk->getDevice(), pool, NULL);
@ -231,4 +242,23 @@ void GEVulkanCommandLoader::endSingleTimeCommands(VkCommandBuffer command_buffer
&command_buffer);
} // endSingleTimeCommands
// ----------------------------------------------------------------------------
void GEVulkanCommandLoader::waitIdle()
{
while (true)
{
std::lock_guard<std::mutex> lock(g_loaders_mutex);
if (g_threaded_commands.empty())
break;
}
unsigned i = 0;
while (i < g_thread_idle.size())
{
if (g_thread_idle[i]->load() == false)
continue;
i++;
}
} // waitIdle
}

View File

@ -33,6 +33,8 @@ VkCommandBuffer beginSingleTimeCommands();
// ----------------------------------------------------------------------------
void endSingleTimeCommands(VkCommandBuffer command_buffer,
VkQueueFlagBits bit = VK_QUEUE_GRAPHICS_BIT);
// ----------------------------------------------------------------------------
void waitIdle();
}; // GEVulkanCommandLoader
}

View File

@ -2191,7 +2191,7 @@ void GEVulkanDriver::createSwapChainRelated(bool handle_surface)
} // createSwapChainRelated
// ----------------------------------------------------------------------------
void GEVulkanDriver::waitIdle()
void GEVulkanDriver::waitIdle(bool flush_command_loader)
{
if (m_disable_wait_idle)
return;
@ -2201,6 +2201,9 @@ void GEVulkanDriver::waitIdle()
vkDeviceWaitIdle(m_vk->device);
for (std::mutex* m : m_graphics_queue_mutexes)
m->unlock();
if (flush_command_loader)
GEVulkanCommandLoader::waitIdle();
} // waitIdle
// ----------------------------------------------------------------------------

View File

@ -39,7 +39,7 @@ STKTexManager::~STKTexManager()
GE::GEVulkanDriver* gevd = GE::getVKDriver();
if (gevd)
{
gevd->waitIdle();
gevd->waitIdle(/*flush_command_loader*/true);
gevd->setDisableWaitIdle(true);
}
#endif