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_convert_irrlicht_mesh;
bool m_texture_compression; bool m_texture_compression;
bool m_vulkan_fullscreen_desktop; bool m_vulkan_fullscreen_desktop;
bool m_enable_draw_call_cache;
std::unordered_set<std::string> m_ondemand_load_texture_paths; std::unordered_set<std::string> m_ondemand_load_texture_paths;
float m_render_scale; float m_render_scale;
}; };

View File

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

View File

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

View File

@ -2430,6 +2430,7 @@ void GEVulkanDriver::updateRenderScale(float value)
return; return;
waitIdle(); waitIdle();
setDisableWaitIdle(true); setDisableWaitIdle(true);
clearDrawCallsCache();
destroySwapChainRelated(false/*handle_surface*/); destroySwapChainRelated(false/*handle_surface*/);
getGEConfig()->m_render_scale = value; getGEConfig()->m_render_scale = value;
createSwapChainRelated(false/*handle_surface*/); createSwapChainRelated(false/*handle_surface*/);
@ -2442,6 +2443,29 @@ void GEVulkanDriver::updateRenderScale(float value)
setDisableWaitIdle(false); setDisableWaitIdle(false);
} // updateRenderScale } // 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 namespace irr

View File

@ -286,12 +286,18 @@ irr::u32 GEVulkanSceneManager::registerNodeForRendering(
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void GEVulkanSceneManager::addDrawCall(GEVulkanCameraSceneNode* cam) 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 } // addDrawCall
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void GEVulkanSceneManager::removeDrawCall(GEVulkanCameraSceneNode* cam) 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); m_draw_calls.erase(cam);
} // removeDrawCall } // removeDrawCall

View File

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