Skip to content

Commit a48b67e

Browse files
committed
framebuffer: Fix timeline semaphore leak and corruption on resize
During sequence reconfiguration (e.g., resolution change), the NvPerFrameDecodeImageSet::init() function was unconditionally creating new timeline semaphores without checking if they already existed. This caused two problems: 1. Memory leak: Old semaphores were never destroyed (the 8 allocations / 1456 bytes leak seen in debug builds) 2. Synchronization corruption: In-flight GPU work was still waiting on the OLD semaphore values, but the NEW semaphores started at initialValue=0. This caused device lost when using display presentation, because the swap chain consumer was using the corrupted timeline synchronization. Headless mode (--noPresent) was unaffected because timeline semaphores are not used for presentation synchronization in that path. Fix: Only create the timeline semaphores if they don't already exist. On reconfigure, reuse the existing semaphores to preserve in-flight synchronization state. Signed-off-by: Tony Zlatinski <tzlatinski@nvidia.com>
1 parent efb5ce7 commit a48b67e

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

vk_video_decoder/libs/VulkanVideoFrameBuffer/VulkanVideoFrameBuffer.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -944,19 +944,23 @@ int32_t NvPerFrameDecodeImageSet::init(const VulkanDeviceContext* vkDevCtx,
944944
}
945945
}
946946

947-
// Create timeline semaphores instead of binary semaphores
948-
VkSemaphoreTypeCreateInfo timelineCreateInfo = {};
949-
timelineCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
950-
timelineCreateInfo.pNext = nullptr;
951-
timelineCreateInfo.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;
952-
timelineCreateInfo.initialValue = 0ULL;
953-
954-
VkSemaphoreCreateInfo semInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &timelineCreateInfo };
955-
VkResult result = vkDevCtx->CreateSemaphore(*vkDevCtx, &semInfo, nullptr, &m_frameCompleteSemaphore);
956-
assert(result == VK_SUCCESS);
947+
// Create timeline semaphores instead of binary semaphores.
948+
// Only create if not already created - on reconfigure, we MUST reuse the existing
949+
// semaphores to avoid corrupting in-flight synchronization.
950+
if (m_frameCompleteSemaphore == VK_NULL_HANDLE) {
951+
VkSemaphoreTypeCreateInfo timelineCreateInfo = {};
952+
timelineCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO;
953+
timelineCreateInfo.pNext = nullptr;
954+
timelineCreateInfo.semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE;
955+
timelineCreateInfo.initialValue = 0ULL;
956+
957+
VkSemaphoreCreateInfo semInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, &timelineCreateInfo };
958+
VkResult result = vkDevCtx->CreateSemaphore(*vkDevCtx, &semInfo, nullptr, &m_frameCompleteSemaphore);
959+
assert(result == VK_SUCCESS);
957960

958-
result = vkDevCtx->CreateSemaphore(*vkDevCtx, &semInfo, nullptr, &m_consumerCompleteSemaphore);
959-
assert(result == VK_SUCCESS);
961+
result = vkDevCtx->CreateSemaphore(*vkDevCtx, &semInfo, nullptr, &m_consumerCompleteSemaphore);
962+
assert(result == VK_SUCCESS);
963+
}
960964

961965
m_videoProfile.InitFromProfile(pDecodeProfile);
962966

0 commit comments

Comments
 (0)