Ensure that the vk renderer isn't init or shutdown twice.

The ref_vk renderer was written for vkQ2 which has differend renderer
<-> client semantics. In YQ2 we can end up initializing or shutting the
renderer down several times. Not by the client, but by the client not
knowing of the renderer has already initialized / shutdown it's internal
state. This is fatal, leading to ressource leaks, crashes and other fun.

Introduce a new global variable `vk_initialize` and use it to track if
we're initialized or not.
This commit is contained in:
Yamagi 2021-04-23 11:07:36 +02:00
parent 2ccc80a1c6
commit 3cf786e158
3 changed files with 27 additions and 0 deletions

View file

@ -255,6 +255,8 @@ extern qvktexture_t vk_colorbufferWarp;
extern qboolean vk_frameStarted;
// Indicates if the renderer needs to be restarted.
extern qboolean vk_restartNeeded;
// is QVk initialized?
extern qboolean vk_initialized;
// function pointers
extern PFN_vkCreateDebugUtilsMessengerEXT qvkCreateDebugUtilsMessengerEXT;

View file

@ -125,6 +125,8 @@ static int vk_activeStagingBuffer = 0;
qboolean vk_frameStarted = false;
// the renderer needs to be restarted.
qboolean vk_restartNeeded = false;
// is QVk initialized?
qboolean vk_initialized = false;
// render pipelines
qvkpipeline_t vk_drawTexQuadPipeline[RP_COUNT] = {
@ -1517,6 +1519,11 @@ static void DestroyStagingBuffer(qvkstagingbuffer_t *dstBuffer)
*/
void QVk_Shutdown( void )
{
if (!vk_initialized)
{
return;
}
if (vk_instance != VK_NULL_HANDLE)
{
R_Printf(PRINT_ALL, "Shutting down Vulkan\n");
@ -1652,6 +1659,11 @@ void QVk_SetWindow(SDL_Window *window)
void QVk_WaitAndShutdownAll (void)
{
if (!vk_initialized)
{
return;
}
if (vk_device.logical != VK_NULL_HANDLE)
{
vkDeviceWaitIdle(vk_device.logical);
@ -1662,6 +1674,8 @@ void QVk_WaitAndShutdownAll (void)
Vk_ShutdownImages();
Mesh_Free();
QVk_Shutdown();
vk_initialized = false;
}
void QVk_Restart(void)
@ -2037,6 +2051,8 @@ qboolean QVk_Init(void)
VK_OBJECT_TYPE_DESCRIPTOR_SET, "Descriptor Set: World Color Buffer");
QVk_DebugSetObjectName((uint64_t)vk_colorbufferWarp.descriptorSet,
VK_OBJECT_TYPE_DESCRIPTOR_SET, "Descriptor Set: Warp Postprocess Color Buffer");
vk_initialized = true;
return true;
}

View file

@ -1376,6 +1376,15 @@ RE_BeginFrame( float camera_separation )
// world has not rendered yet
world_rendered = false;
/* VK hasn't been initialized yet. I'm pretty sure that
we can't get here without having called QVk_Init(),
but better save than sorry. */
if (!vk_initialized)
{
vk_frameStarted = false;
return;
}
// 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
if (QVk_EndFrame(true) != VK_SUCCESS)
vk_restartNeeded = true;