Restart Vulkan renderer at EndFrame instead of BeginFrame
This brings yquake2 closer to vkQuake2 regarding renderer restarts when the swapchain is out of date, among other situations that trigger a Vulkan renderer restart. Basically, the current behavior has the problem that when the renderer is restarted at the beginning of the frame, the models are lost and we end up with "ERROR: Mod_PointInLeaf: bad model" when attempting to render anything after that restart. To solve this, we move the restart logic to EndFrame and add a twist to it: we use a vid_refresh variable to signal the server that the client needs re-registration before starting the next frame cleanly, which will trigger the registration logic to prepare the models again.
This commit is contained in:
parent
11bcb785d0
commit
e362e0280e
|
@ -152,6 +152,7 @@ extern cvar_t *vk_pixel_size;
|
|||
extern cvar_t *r_fixsurfsky;
|
||||
|
||||
extern cvar_t *vid_fullscreen;
|
||||
extern cvar_t *vid_refresh;
|
||||
extern cvar_t *vid_gamma;
|
||||
|
||||
extern int c_visible_lightmaps;
|
||||
|
|
|
@ -1664,6 +1664,7 @@ void QVk_Restart(void)
|
|||
if (!QVk_Init())
|
||||
ri.Sys_Error(ERR_FATAL, "Unable to restart Vulkan renderer");
|
||||
QVk_PostInit();
|
||||
vid_refresh->modified = true;
|
||||
}
|
||||
|
||||
void QVk_PostInit(void)
|
||||
|
@ -2097,7 +2098,8 @@ VkResult QVk_EndFrame(qboolean force)
|
|||
{
|
||||
// continue only if QVk_BeginFrame() had been previously issued
|
||||
if (!vk_frameStarted)
|
||||
return VK_NOT_READY;
|
||||
return VK_SUCCESS;
|
||||
|
||||
// this may happen if Sys_Error is issued mid-frame, so we need to properly advance the draw pipeline
|
||||
if (force)
|
||||
{
|
||||
|
|
|
@ -130,6 +130,7 @@ cvar_t *vk_nolerp_list;
|
|||
cvar_t *r_fixsurfsky;
|
||||
|
||||
cvar_t *vid_fullscreen;
|
||||
cvar_t *vid_refresh;
|
||||
cvar_t *vid_gamma;
|
||||
static cvar_t *viewsize;
|
||||
|
||||
|
@ -1194,6 +1195,7 @@ R_Register( void )
|
|||
ri.Cvar_Set("r_msaa_samples", "0");
|
||||
|
||||
vid_fullscreen = ri.Cvar_Get("vid_fullscreen", "0", CVAR_ARCHIVE);
|
||||
vid_refresh = ri.Cvar_Get("vid_refresh", "0", CVAR_NOSET);
|
||||
vid_gamma = ri.Cvar_Get("vid_gamma", "1.0", CVAR_ARCHIVE);
|
||||
viewsize = ri.Cvar_Get("viewsize", "100", CVAR_ARCHIVE);
|
||||
|
||||
|
@ -1376,7 +1378,8 @@ RE_BeginFrame( float camera_separation )
|
|||
world_rendered = false;
|
||||
|
||||
// if ri.Sys_Error() had been issued mid-frame, we might end up here without properly submitting the image, so call QVk_EndFrame to be safe
|
||||
QVk_EndFrame(true);
|
||||
if (QVk_EndFrame(true) != VK_SUCCESS)
|
||||
vk_restartNeeded = true;
|
||||
|
||||
/*
|
||||
** change modes if necessary
|
||||
|
@ -1407,21 +1410,10 @@ RE_BeginFrame( float camera_separation )
|
|||
}
|
||||
}
|
||||
|
||||
if (vk_restartNeeded)
|
||||
{
|
||||
QVk_Restart();
|
||||
vk_restartNeeded = false;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
VkResult swapChainValid = QVk_BeginFrame(&vk_viewport, &vk_scissor);
|
||||
if (swapChainValid == VK_SUCCESS)
|
||||
break;
|
||||
QVk_Restart();
|
||||
}
|
||||
|
||||
QVk_BeginRenderpass(RP_WORLD);
|
||||
if (QVk_BeginFrame(&vk_viewport, &vk_scissor) != VK_SUCCESS)
|
||||
vk_restartNeeded = true;
|
||||
else
|
||||
QVk_BeginRenderpass(RP_WORLD);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1432,9 +1424,17 @@ RE_EndFrame
|
|||
static void
|
||||
RE_EndFrame( void )
|
||||
{
|
||||
QVk_EndFrame(false);
|
||||
if (QVk_EndFrame(false) != VK_SUCCESS)
|
||||
vk_restartNeeded = true;
|
||||
|
||||
// world has not rendered yet
|
||||
world_rendered = false;
|
||||
|
||||
if (vk_restartNeeded)
|
||||
{
|
||||
QVk_Restart();
|
||||
vk_restartNeeded = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -286,6 +286,7 @@ VID_GetModeInfo(int *width, int *height, int mode)
|
|||
// Global console variables.
|
||||
cvar_t *vid_gamma;
|
||||
cvar_t *vid_fullscreen;
|
||||
cvar_t *vid_refresh;
|
||||
cvar_t *vid_renderer;
|
||||
|
||||
// Global video state, used throughout the client.
|
||||
|
@ -489,6 +490,12 @@ VID_CheckChanges(void)
|
|||
// Unblock the client.
|
||||
cls.disable_screen = false;
|
||||
}
|
||||
|
||||
if (vid_refresh->modified)
|
||||
{
|
||||
vid_refresh->modified = false;
|
||||
cl.refresh_prepped = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -500,6 +507,7 @@ VID_Init(void)
|
|||
// Console variables
|
||||
vid_gamma = Cvar_Get("vid_gamma", "1.0", CVAR_ARCHIVE);
|
||||
vid_fullscreen = Cvar_Get("vid_fullscreen", "0", CVAR_ARCHIVE);
|
||||
vid_refresh = Cvar_Get("vid_refresh", "0", CVAR_NOSET);
|
||||
vid_renderer = Cvar_Get("vid_renderer", "gl1", CVAR_ARCHIVE);
|
||||
|
||||
// Commands
|
||||
|
|
Loading…
Reference in New Issue