Fix validation warnings when running vkDeviceWaitIdle

This commit is contained in:
Benau 2022-04-18 13:46:59 +08:00
parent 5d23d8d790
commit b0421569d0
6 changed files with 70 additions and 14 deletions

View File

@ -329,6 +329,8 @@ namespace GE
unsigned getGraphicsQueueCount() const
{ return m_graphics_queue_count; }
std::unique_lock<std::mutex> getGraphicsQueue(VkQueue* queue) const;
void waitIdle();
void setDisableWaitIdle(bool val) { m_disable_wait_idle = val; }
private:
struct SwapChainSupportDetails
{
@ -443,6 +445,7 @@ namespace GE
video::ITexture* m_transparent_texture;
SDL_Window* m_window;
bool m_disable_wait_idle;
void createInstance(SDL_Window* window);
void findPhysicalDevice();

View File

@ -470,6 +470,7 @@ GEVulkanDriver::GEVulkanDriver(const SIrrlichtCreationParameters& params,
m_pre_rotation_matrix = core::matrix4(core::matrix4::EM4CONST_IDENTITY);
m_window = window;
m_disable_wait_idle = false;
g_schedule_pausing_rendering.store(false);
g_paused_rendering.store(false);
g_device_created.store(true);
@ -1937,7 +1938,7 @@ void GEVulkanDriver::unpauseRendering()
// ----------------------------------------------------------------------------
void GEVulkanDriver::destroySwapChainRelated(bool handle_surface)
{
vkDeviceWaitIdle(m_vk->device);
waitIdle();
for (VkFramebuffer& framebuffer : m_vk->swap_chain_framebuffers)
vkDestroyFramebuffer(m_vk->device, framebuffer, NULL);
m_vk->swap_chain_framebuffers.clear();
@ -1961,7 +1962,7 @@ void GEVulkanDriver::destroySwapChainRelated(bool handle_surface)
// ----------------------------------------------------------------------------
void GEVulkanDriver::createSwapChainRelated(bool handle_surface)
{
vkDeviceWaitIdle(m_vk->device);
waitIdle();
if (handle_surface)
{
if (SDL_Vulkan_CreateSurface(m_window, m_vk->instance, &m_vk->surface) == SDL_FALSE)
@ -1974,6 +1975,19 @@ void GEVulkanDriver::createSwapChainRelated(bool handle_surface)
createFramebuffers();
} // createSwapChainRelated
// ----------------------------------------------------------------------------
void GEVulkanDriver::waitIdle()
{
if (m_disable_wait_idle)
return;
// Host access to all VkQueue objects created from device must be externally synchronized
for (std::mutex* m : m_graphics_queue_mutexes)
m->lock();
vkDeviceWaitIdle(m_vk->device);
for (std::mutex* m : m_graphics_queue_mutexes)
m->unlock();
} // waitIdle
}
namespace irr

View File

@ -190,7 +190,7 @@ void GEVulkanDynamicBuffer::destroyPerFrame(unsigned frame)
// ----------------------------------------------------------------------------
void GEVulkanDynamicBuffer::destroy()
{
vkDeviceWaitIdle(getVKDriver()->getDevice());
getVKDriver()->waitIdle();
for (unsigned i = 0; i < GEVulkanDriver::getMaxFrameInFlight(); i++)
destroyPerFrame(i);
} // destroy

View File

@ -82,7 +82,10 @@ GEVulkanTexture::~GEVulkanTexture()
m_image_view_lock.lock();
m_image_view_lock.unlock();
vkDeviceWaitIdle(m_vulkan_device);
if (m_image_view != VK_NULL_HANDLE || m_image != VK_NULL_HANDLE ||
m_image_memory != VK_NULL_HANDLE)
getVKDriver()->waitIdle();
clearVulkanData();
} // ~GEVulkanTexture
@ -589,7 +592,10 @@ void GEVulkanTexture::reload()
m_image_view_lock.lock();
m_image_view_lock.unlock();
vkDeviceWaitIdle(m_vulkan_device);
if (m_image_view != VK_NULL_HANDLE || m_image != VK_NULL_HANDLE ||
m_image_memory != VK_NULL_HANDLE)
getVKDriver()->waitIdle();
if (!m_disable_reload)
{
m_size_lock.lock();

View File

@ -27,13 +27,29 @@
#include <algorithm>
#ifndef SERVER_ONLY
#include <ge_main.hpp>
#include <ge_vulkan_driver.hpp>
#include <ge_texture.hpp>
#endif
// ----------------------------------------------------------------------------
STKTexManager::~STKTexManager()
{
#ifndef SERVER_ONLY
GE::GEVulkanDriver* gevd = GE::getVKDriver();
if (gevd)
{
gevd->waitIdle();
gevd->setDisableWaitIdle(true);
}
#endif
removeTexture(NULL/*texture*/, true/*remove_all*/);
#ifndef SERVER_ONLY
if (gevd)
gevd->setDisableWaitIdle(false);
#endif
} // ~STKTexManager
// ----------------------------------------------------------------------------
@ -227,3 +243,28 @@ bool STKTexManager::hasTexture(const std::string& path)
}
return false;
} // hasTexture
// ----------------------------------------------------------------------------
void STKTexManager::reloadAllTextures()
{
#ifndef SERVER_ONLY
GE::GEVulkanDriver* gevd = GE::getVKDriver();
if (gevd)
{
gevd->waitIdle();
gevd->setDisableWaitIdle(true);
}
#endif
for (auto p : m_all_textures)
{
if (p.second == NULL)
continue;
p.second->reload();
}
#ifndef SERVER_ONLY
if (gevd)
gevd->setDisableWaitIdle(false);
#endif
} // reloadAllTextures

View File

@ -65,15 +65,7 @@ public:
// ------------------------------------------------------------------------
int dumpTextureUsage();
// ------------------------------------------------------------------------
void reloadAllTextures()
{
for (auto p : m_all_textures)
{
if (p.second == NULL)
continue;
p.second->reload();
}
}
void reloadAllTextures();
// ------------------------------------------------------------------------
/** Returns the currently defined texture error message, which is used
* by event_handler.cpp to print additional info about irrlicht