(video/vulkan) Avoid caching stale mapped GPU texture as frame data

At best, this results in junk on screen, at worst we could crash.

It's not a perfect fix, there's still a scenario where this breaks: when
fast forwarding is enabled, and we swap from vsync-off to vsync-on when
pausing/rendering the menu, the swap chain (and textures) gets
recreated, and the frame data is completely lost.

There isn't much we can do about this without more intrusive changes,
such as preserving the textures inbetween swap chain reinits.
This commit is contained in:
Stenzek 2021-05-10 21:18:31 -07:00
parent 92e795aa28
commit c9aaf598bb

View File

@ -57,6 +57,8 @@
static void vulkan_set_viewport(void *data, unsigned viewport_width,
unsigned viewport_height, bool force_full, bool allow_rotate);
static bool vulkan_is_mapped_swapchain_texture_ptr(const vk_t* vk,
const void* ptr);
#ifdef HAVE_OVERLAY
static void vulkan_overlay_free(vk_t *vk);
@ -682,6 +684,12 @@ static void vulkan_deinit_textures(vk_t *vk)
{
unsigned i;
/* Avoid memcpying from a destroyed/unmapped texture later on. */
const void* cached_frame;
video_driver_cached_frame_get(&cached_frame, NULL, NULL, NULL);
if (vulkan_is_mapped_swapchain_texture_ptr(vk, cached_frame))
video_driver_set_cached_frame_ptr(NULL);
vulkan_deinit_samplers(vk);
for (i = 0; i < vk->num_swapchain_images; i++)
@ -2391,6 +2399,18 @@ static bool vulkan_get_current_sw_framebuffer(void *data,
return true;
}
static bool vulkan_is_mapped_swapchain_texture_ptr(const vk_t* vk,
const void* ptr)
{
for (unsigned i = 0; i < vk->num_swapchain_images; i++)
{
if (ptr == vk->swapchain[i].texture.mapped)
return true;
}
return false;
}
static bool vulkan_get_hw_render_interface(void *data,
const struct retro_hw_render_interface **iface)
{