Fix hang when switching kart in selection screen for vulkan

This commit is contained in:
Benau 2022-09-03 12:04:44 +08:00
parent 784b77723c
commit d93b5d3b8d
6 changed files with 54 additions and 2 deletions

View File

@ -17,6 +17,7 @@ bool m_disable_npot_texture;
bool m_convert_irrlicht_mesh;
bool m_texture_compression;
bool m_vulkan_fullscreen_desktop;
bool m_enable_draw_call_cache;
std::unordered_set<std::string> m_ondemand_load_texture_paths;
float m_render_scale;
};

View File

@ -23,8 +23,9 @@ using namespace video;
namespace GE
{
class GEVulkanFBOTexture;
class GEVulkanDepthTexture;
class GEVulkanDrawCall;
class GEVulkanFBOTexture;
class GEVulkanMeshCache;
class GEVulkanTextureDescriptor;
enum GEVulkanSampler : unsigned
@ -359,6 +360,9 @@ namespace GE
void handleDeletedTextures();
void addRTTPolyCount(unsigned count) { m_rtt_polycount += count; }
SDL_Window* getSDLWindow() const { return m_window; }
void clearDrawCallsCache();
void addDrawCallToCache(std::unique_ptr<GEVulkanDrawCall>& dc);
std::unique_ptr<GEVulkanDrawCall> getDrawCallFromCache();
private:
struct SwapChainSupportDetails
{
@ -501,6 +505,8 @@ namespace GE
GEVulkanFBOTexture* m_separate_rtt_texture;
u32 m_rtt_polycount;
std::vector<std::unique_ptr<GEVulkanDrawCall> > m_draw_calls_cache;
void createInstance(SDL_Window* window);
void findPhysicalDevice();
bool checkDeviceExtensions(VkPhysicalDevice device);

View File

@ -12,6 +12,7 @@ GEConfig g_config =
false,
false,
true,
false,
{},
1.0f
};

View File

@ -2430,6 +2430,7 @@ void GEVulkanDriver::updateRenderScale(float value)
return;
waitIdle();
setDisableWaitIdle(true);
clearDrawCallsCache();
destroySwapChainRelated(false/*handle_surface*/);
getGEConfig()->m_render_scale = value;
createSwapChainRelated(false/*handle_surface*/);
@ -2442,6 +2443,29 @@ void GEVulkanDriver::updateRenderScale(float value)
setDisableWaitIdle(false);
} // updateRenderScale
// ----------------------------------------------------------------------------
void GEVulkanDriver::clearDrawCallsCache()
{
m_draw_calls_cache.clear();
} // clearDrawCallsCache
// ----------------------------------------------------------------------------
void GEVulkanDriver::addDrawCallToCache(std::unique_ptr<GEVulkanDrawCall>& dc)
{
if (getGEConfig()->m_enable_draw_call_cache)
m_draw_calls_cache.push_back(std::move(dc));
} // addDrawCallToCache
// ----------------------------------------------------------------------------
std::unique_ptr<GEVulkanDrawCall> GEVulkanDriver::getDrawCallFromCache()
{
if (!getGEConfig()->m_enable_draw_call_cache || m_draw_calls_cache.empty())
return std::unique_ptr<GEVulkanDrawCall>(new GEVulkanDrawCall);
auto dc = std::move(m_draw_calls_cache.back());
m_draw_calls_cache.pop_back();
return dc;
} // getDrawCallFromCache
}
namespace irr

View File

@ -286,12 +286,18 @@ irr::u32 GEVulkanSceneManager::registerNodeForRendering(
// ----------------------------------------------------------------------------
void GEVulkanSceneManager::addDrawCall(GEVulkanCameraSceneNode* cam)
{
m_draw_calls[cam] = std::unique_ptr<GEVulkanDrawCall>(new GEVulkanDrawCall);
GEVulkanDriver* gevk = static_cast<GEVulkanDriver*>(getVideoDriver());
m_draw_calls[cam] = gevk->getDrawCallFromCache();
} // addDrawCall
// ----------------------------------------------------------------------------
void GEVulkanSceneManager::removeDrawCall(GEVulkanCameraSceneNode* cam)
{
if (m_draw_calls.find(cam) == m_draw_calls.end())
return;
GEVulkanDriver* gevk = static_cast<GEVulkanDriver*>(getVideoDriver());
auto& dc = m_draw_calls.at(cam);
gevk->addDrawCallToCache(dc);
m_draw_calls.erase(cam);
} // removeDrawCall

View File

@ -48,6 +48,11 @@
#include <IGUIEnvironment.h>
#include <IGUIButton.h>
#ifndef SERVER_ONLY
#include <ge_main.hpp>
#include <ge_vulkan_driver.hpp>
#endif
using namespace GUIEngine;
using irr::core::stringw;
@ -335,6 +340,9 @@ void KartSelectionScreen::beforeAddingWidget()
void KartSelectionScreen::init()
{
#ifndef SERVER_ONLY
GE::getGEConfig()->m_enable_draw_call_cache = true;
#endif
m_instance_ptr = this;
Screen::init();
m_must_delete_on_back = false;
@ -441,6 +449,12 @@ void KartSelectionScreen::init()
void KartSelectionScreen::tearDown()
{
#ifndef SERVER_ONLY
GE::getGEConfig()->m_enable_draw_call_cache = false;
GE::GEVulkanDriver* gevk = GE::getVKDriver();
if (gevk)
gevk->clearDrawCallsCache();
#endif
#ifdef MOBILE_STK
if (m_multiplayer)
MessageQueue::discardStatic();