Allow onfly FSAA change under Vulkan

This commit is contained in:
Jupeyy 2022-04-26 20:09:47 +02:00
parent d815fdfa03
commit b23e60c077
7 changed files with 121 additions and 12 deletions

View file

@ -896,6 +896,8 @@ class CCommandProcessorFragment_Vulkan : public CCommandProcessorFragment_GLBase
int m_GlobalTextureLodBIAS;
uint32_t m_MultiSamplingCount = 1;
uint32_t m_NextMultiSamplingCount = std::numeric_limits<uint32_t>::max();
bool m_RecreateSwapChain = false;
bool m_SwapchainCreated = false;
bool m_RenderingPaused = false;
@ -1243,6 +1245,7 @@ protected:
m_aCommandCallbacks[CommandBufferCMDOff(CCommandBuffer::CMD_FINISH)] = {false, [](SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand *pBaseCommand) {}, [this](const CCommandBuffer::SCommand *pBaseCommand, SRenderCommandExecuteBuffer &ExecBuffer) { Cmd_Finish(static_cast<const CCommandBuffer::SCommand_Finish *>(pBaseCommand)); return true; }};
m_aCommandCallbacks[CommandBufferCMDOff(CCommandBuffer::CMD_VSYNC)] = {false, [](SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand *pBaseCommand) {}, [this](const CCommandBuffer::SCommand *pBaseCommand, SRenderCommandExecuteBuffer &ExecBuffer) { Cmd_VSync(static_cast<const CCommandBuffer::SCommand_VSync *>(pBaseCommand)); return true; }};
m_aCommandCallbacks[CommandBufferCMDOff(CCommandBuffer::CMD_MULTISAMPLING)] = {false, [](SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand *pBaseCommand) {}, [this](const CCommandBuffer::SCommand *pBaseCommand, SRenderCommandExecuteBuffer &ExecBuffer) { Cmd_MultiSampling(static_cast<const CCommandBuffer::SCommand_MultiSampling *>(pBaseCommand)); return true; }};
m_aCommandCallbacks[CommandBufferCMDOff(CCommandBuffer::CMD_TRY_SWAP_AND_SCREENSHOT)] = {false, [](SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand *pBaseCommand) {}, [this](const CCommandBuffer::SCommand *pBaseCommand, SRenderCommandExecuteBuffer &ExecBuffer) { Cmd_Screenshot(static_cast<const CCommandBuffer::SCommand_TrySwapAndScreenshot *>(pBaseCommand)); return true; }};
m_aCommandCallbacks[CommandBufferCMDOff(CCommandBuffer::CMD_UPDATE_VIEWPORT)] = {false, [this](SRenderCommandExecuteBuffer &ExecBuffer, const CCommandBuffer::SCommand *pBaseCommand) { Cmd_Update_Viewport_FillExecuteBuffer(ExecBuffer, static_cast<const CCommandBuffer::SCommand_Update_Viewport *>(pBaseCommand)); }, [this](const CCommandBuffer::SCommand *pBaseCommand, SRenderCommandExecuteBuffer &ExecBuffer) { Cmd_Update_Viewport(static_cast<const CCommandBuffer::SCommand_Update_Viewport *>(pBaseCommand)); return true; }};
@ -5345,6 +5348,14 @@ public:
if(m_SwapchainCreated)
CleanupVulkanSwapChain(false);
// set new multi sampling if it was requested
if(m_NextMultiSamplingCount != std::numeric_limits<uint32_t>::max())
{
m_MultiSamplingCount = m_NextMultiSamplingCount;
m_NextMultiSamplingCount = std::numeric_limits<uint32_t>::max();
}
if(!m_SwapchainCreated)
Ret = InitVulkanSwapChain(OldSwapChain);
@ -5765,19 +5776,38 @@ public:
return GetSampleCount() != VK_SAMPLE_COUNT_1_BIT;
}
VkSampleCountFlagBits GetMaxSampleCount()
{
if(m_MaxMultiSample & VK_SAMPLE_COUNT_64_BIT)
return VK_SAMPLE_COUNT_64_BIT;
else if(m_MaxMultiSample & VK_SAMPLE_COUNT_32_BIT)
return VK_SAMPLE_COUNT_32_BIT;
else if(m_MaxMultiSample & VK_SAMPLE_COUNT_16_BIT)
return VK_SAMPLE_COUNT_16_BIT;
else if(m_MaxMultiSample & VK_SAMPLE_COUNT_8_BIT)
return VK_SAMPLE_COUNT_8_BIT;
else if(m_MaxMultiSample & VK_SAMPLE_COUNT_4_BIT)
return VK_SAMPLE_COUNT_4_BIT;
else if(m_MaxMultiSample & VK_SAMPLE_COUNT_2_BIT)
return VK_SAMPLE_COUNT_2_BIT;
return VK_SAMPLE_COUNT_1_BIT;
}
VkSampleCountFlagBits GetSampleCount()
{
if(m_MultiSamplingCount >= 64 && m_MaxMultiSample & VK_SAMPLE_COUNT_64_BIT)
auto MaxSampleCount = GetMaxSampleCount();
if(m_MultiSamplingCount >= 64 && MaxSampleCount >= VK_SAMPLE_COUNT_64_BIT)
return VK_SAMPLE_COUNT_64_BIT;
else if(m_MultiSamplingCount >= 32 && m_MaxMultiSample & VK_SAMPLE_COUNT_32_BIT)
else if(m_MultiSamplingCount >= 32 && MaxSampleCount >= VK_SAMPLE_COUNT_32_BIT)
return VK_SAMPLE_COUNT_32_BIT;
else if(m_MultiSamplingCount >= 16 && m_MaxMultiSample & VK_SAMPLE_COUNT_16_BIT)
else if(m_MultiSamplingCount >= 16 && MaxSampleCount >= VK_SAMPLE_COUNT_16_BIT)
return VK_SAMPLE_COUNT_16_BIT;
else if(m_MultiSamplingCount >= 8 && m_MaxMultiSample & VK_SAMPLE_COUNT_8_BIT)
else if(m_MultiSamplingCount >= 8 && MaxSampleCount >= VK_SAMPLE_COUNT_8_BIT)
return VK_SAMPLE_COUNT_8_BIT;
else if(m_MultiSamplingCount >= 4 && m_MaxMultiSample & VK_SAMPLE_COUNT_4_BIT)
else if(m_MultiSamplingCount >= 4 && MaxSampleCount >= VK_SAMPLE_COUNT_4_BIT)
return VK_SAMPLE_COUNT_4_BIT;
else if(m_MultiSamplingCount >= 2 && m_MaxMultiSample & VK_SAMPLE_COUNT_2_BIT)
else if(m_MultiSamplingCount >= 2 && MaxSampleCount >= VK_SAMPLE_COUNT_2_BIT)
return VK_SAMPLE_COUNT_2_BIT;
return VK_SAMPLE_COUNT_1_BIT;
@ -6566,6 +6596,21 @@ public:
*pCommand->m_pRetOk = true;
}
void Cmd_MultiSampling(const CCommandBuffer::SCommand_MultiSampling *pCommand)
{
if(IsVerbose())
{
dbg_msg("vulkan", "queueing swap chain recreation because multi sampling was changed");
}
m_RecreateSwapChain = true;
uint32_t MSCount = (std::min(pCommand->m_RequestedMultiSamplingCount, (uint32_t)GetMaxSampleCount()) & 0xFFFFFFFE); // ignore the uneven bits
m_NextMultiSamplingCount = MSCount;
*pCommand->m_pRetMultiSamplingCount = MSCount;
*pCommand->m_pRetOk = true;
}
void Cmd_Finish(const CCommandBuffer::SCommand_Finish *pCommand)
{ // just ignore it with vulkan
}

View file

@ -231,6 +231,7 @@ bool CCommandProcessorFragment_SDL::RunCommand(const CCommandBuffer::SCommand *p
case CCommandBuffer::CMD_WINDOW_DESTROY_NTF: Cmd_WindowDestroyNtf(static_cast<const CCommandBuffer::SCommand_WindowDestroyNtf *>(pBaseCommand)); break;
case CCommandBuffer::CMD_SWAP: Cmd_Swap(static_cast<const CCommandBuffer::SCommand_Swap *>(pBaseCommand)); break;
case CCommandBuffer::CMD_VSYNC: Cmd_VSync(static_cast<const CCommandBuffer::SCommand_VSync *>(pBaseCommand)); break;
case CCommandBuffer::CMD_MULTISAMPLING: break;
case CMD_INIT: Cmd_Init(static_cast<const SCommand_Init *>(pBaseCommand)); break;
case CMD_SHUTDOWN: Cmd_Shutdown(static_cast<const SCommand_Shutdown *>(pBaseCommand)); break;
case CCommandProcessorFragment_GLBase::CMD_PRE_INIT: break;

View file

@ -2740,7 +2740,7 @@ bool CGraphics_Threaded::SetVSync(bool State)
if(!m_pCommandBuffer)
return true;
// add vsnc command
// add vsync command
bool RetOk = false;
CCommandBuffer::SCommand_VSync Cmd;
Cmd.m_VSync = State ? 1 : 0;
@ -2758,6 +2758,30 @@ bool CGraphics_Threaded::SetVSync(bool State)
return RetOk;
}
bool CGraphics_Threaded::SetMultiSampling(uint32_t ReqMultiSamplingCount, uint32_t &MultiSamplingCountBackend)
{
if(!m_pCommandBuffer)
return true;
// add multisampling command
bool RetOk = false;
CCommandBuffer::SCommand_MultiSampling Cmd;
Cmd.m_RequestedMultiSamplingCount = ReqMultiSamplingCount;
Cmd.m_pRetMultiSamplingCount = &MultiSamplingCountBackend;
Cmd.m_pRetOk = &RetOk;
if(!AddCmd(
Cmd, [] { return true; }, "failed to add multi sampling command"))
{
return false;
}
// kick the command buffer
KickCommandBuffer();
WaitForIdle();
return RetOk;
}
// synchronization
void CGraphics_Threaded::InsertSignal(CSemaphore *pSemaphore)
{

View file

@ -128,6 +128,7 @@ public:
CMD_FINISH,
// misc
CMD_MULTISAMPLING,
CMD_VSYNC,
CMD_TRY_SWAP_AND_SCREENSHOT,
CMD_UPDATE_VIEWPORT,
@ -508,6 +509,16 @@ public:
bool *m_pRetOk;
};
struct SCommand_MultiSampling : public SCommand
{
SCommand_MultiSampling() :
SCommand(CMD_MULTISAMPLING) {}
uint32_t m_RequestedMultiSamplingCount;
uint32_t *m_pRetMultiSamplingCount;
bool *m_pRetOk;
};
struct SCommand_Update_Viewport : public SCommand
{
SCommand_Update_Viewport() :
@ -1266,6 +1277,7 @@ public:
void TakeCustomScreenshot(const char *pFilename) override;
void Swap() override;
bool SetVSync(bool State) override;
bool SetMultiSampling(uint32_t ReqMultiSamplingCount, uint32_t &MultiSamplingCountBackend) override;
int GetVideoModes(CVideoMode *pModes, int MaxModes, int Screen) override;

View file

@ -256,6 +256,7 @@ public:
virtual void SetWindowParams(int FullscreenMode, bool IsBorderless, bool AllowResizing) = 0;
virtual bool SetWindowScreen(int Index) = 0;
virtual bool SetVSync(bool State) = 0;
virtual bool SetMultiSampling(uint32_t ReqMultiSamplingCount, uint32_t &MultiSamplingCountBackend) = 0;
virtual int GetWindowScreen() = 0;
virtual void Move(int x, int y) = 0;
virtual void Resize(int w, int h, int RefreshRate) = 0;

View file

@ -117,7 +117,7 @@ MACRO_CONFIG_INT(GfxColorDepth, gfx_color_depth, 24, 16, 24, CFGFLAG_SAVE | CFGF
MACRO_CONFIG_INT(GfxVsync, gfx_vsync, 0, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Vertical sync (may cause delay)")
MACRO_CONFIG_INT(GfxDisplayAllVideoModes, gfx_display_all_video_modes, 0, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Show all video modes")
MACRO_CONFIG_INT(GfxHighDetail, gfx_high_detail, 1, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT, "High detail")
MACRO_CONFIG_INT(GfxFsaaSamples, gfx_fsaa_samples, 0, 0, 16, CFGFLAG_SAVE | CFGFLAG_CLIENT, "FSAA Samples")
MACRO_CONFIG_INT(GfxFsaaSamples, gfx_fsaa_samples, 0, 0, 64, CFGFLAG_SAVE | CFGFLAG_CLIENT, "FSAA Samples")
MACRO_CONFIG_INT(GfxRefreshRate, gfx_refresh_rate, 0, 0, 10000, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Screen refresh rate")
MACRO_CONFIG_INT(GfxFinish, gfx_finish, 0, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT, "")
MACRO_CONFIG_INT(GfxBackgroundRender, gfx_backgroundrender, 1, 0, 1, CFGFLAG_SAVE | CFGFLAG_CLIENT, "Render graphics when window is in background")

View file

@ -1251,18 +1251,44 @@ void CMenus::RenderSettingsGraphics(CUIRect MainView)
}
}
bool MultiSamplingChanged = false;
MainView.HSplitTop(20.0f, &Button, &MainView);
str_format(aBuf, sizeof(aBuf), "%s (%s)", Localize("FSAA samples"), Localize("may cause delay"));
int GfxFsaaSamples_MouseButton = DoButton_CheckBox_Number(&g_Config.m_GfxFsaaSamples, aBuf, g_Config.m_GfxFsaaSamples, &Button);
int CurFSAA = g_Config.m_GfxFsaaSamples == 0 ? 1 : g_Config.m_GfxFsaaSamples;
if(GfxFsaaSamples_MouseButton == 1) // inc
{
g_Config.m_GfxFsaaSamples = (g_Config.m_GfxFsaaSamples + 1) % 17;
CheckSettings = true;
g_Config.m_GfxFsaaSamples = std::pow(2, (int)std::log2(CurFSAA) + 1);
if(g_Config.m_GfxFsaaSamples > 64)
g_Config.m_GfxFsaaSamples = 0;
MultiSamplingChanged = true;
}
else if(GfxFsaaSamples_MouseButton == 2) // dec
{
g_Config.m_GfxFsaaSamples = (g_Config.m_GfxFsaaSamples - 1 + 17) % 17;
CheckSettings = true;
if(CurFSAA == 1)
g_Config.m_GfxFsaaSamples = 64;
else if(CurFSAA == 2)
g_Config.m_GfxFsaaSamples = 0;
else
g_Config.m_GfxFsaaSamples = std::pow(2, (int)std::log2(CurFSAA) - 1);
MultiSamplingChanged = true;
}
uint32_t MultiSamplingCountBackend = 0;
if(MultiSamplingChanged)
{
if(Graphics()->SetMultiSampling(g_Config.m_GfxFsaaSamples, MultiSamplingCountBackend))
{
// try again with 0 if mouse click was increasing multi sampling
// else just accept the current value as is
if((uint32_t)g_Config.m_GfxFsaaSamples > MultiSamplingCountBackend && GfxFsaaSamples_MouseButton == 1)
Graphics()->SetMultiSampling(0, MultiSamplingCountBackend);
g_Config.m_GfxFsaaSamples = (int)MultiSamplingCountBackend;
}
else
{
CheckSettings = true;
}
}
MainView.HSplitTop(20.0f, &Button, &MainView);