Это конкретный c вопрос о барьерной синхронизации в отношении отправки в буфер команд и очистки ресурсов, которые требуются для буферов команд (например, используемых буферов и изображений).
Предположим, что все в одной очереди и в кадре три кадра.
Я выполняю следующие операции:
Create Render-CmdBfr[0..2], Fence[0..2]
...
Create StagingBuffer
Create Image
Create Init-CmdBfr
Record `copy StagingBuffer to Image` into Init-CmdBuffer
Record `barrier ALL_COMMANDS ALL_COMMANDS MEMORY_WRITE MEMORY_READ` into Init-CmdBuffer
Submit Init-CmdBuffer without any semaphore or fence
...
// Frame #1
Submit Render-CmdBfr[0] -> signal Fence[0]
// Frame #2
Submit Render-CmdBfr[1] -> signal Fence[1]
// Frame #3
Submit Render-CmdBfr[2] -> signal Fence[2]
// Frame #4
Wait for Fence[0] -> submit Render-CmdBfr[0] -> signal Fence[0]
Delete Init-CmdBfr
Delete Image
Delete StagingBuffer
// Frame #5
Wait for Fence[1] -> submit Render-CmdBfr[1] -> signal Fence[1]
// Frame #6
Wait for Fence[2] -> submit Render-CmdBfr[2] -> signal Fence[2]
... continue forever ...
В проблемной части c удаляется Init-CmdBfr
, Image
и StagingBuffer
. Или на самом деле, это не проблема c, поскольку приложение работает просто отлично. Но уровень проверки жалуется:
Vk-обратный вызов с Id [0 | VUID-vkFreeCommandBuffers-pCommandBuffers-00047] и сообщением [Попытка освободить VkCommandBuffer 0x20e61cff060 [], который используется. В Vulkan spe c говорится: все элементы pCommandBuffers не должны находиться в состоянии ожидания (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID -vkFreeCommandBuffers-pCommandBuffers-00047)]
Также появляются новые сообщения Например:
Vk-обратный вызов с Id [0 | VUID-vkDestroyBuffer-buffer-00922] и Message [Невозможно освободить VkBuffer 0xe6bc0400000000a1 [], который используется буфером команд. Vulkan spe c гласит: Все отправленные команды, которые ссылаются на буфер, либо напрямую, либо через VkBufferView, должны завершить выполнение (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID -vkDestroyBuffer-buffer-00922)]
Спецификация c утверждает, что буфер команд может быть удален только после того, как он покинул состояние ожидания. По моему barrier ALL_COMMANDS ALL_COMMANDS MEMORY_WRITE MEMORY_READ
и полному циклу Fence[0]
сигнала и ожидания, это должно быть дано в кадре № 4, по моему мнению.
Мой первый вопрос: я прав насчет этого предположения? И подходит ли мой подход?
Мой второй вопрос: если я прав и мой подход в порядке, как я могу предотвратить появление жалоб на слои проверки?
Я думаю, что Слои валидации просто не знают о барьере и жалуются, потому что могло случиться так, что я не создал барьер. Действительно, когда я добавляю семафор к представлению Init-CmdBfr
(то есть Submit Init-CmdBuffer and signal Init-Semaphore
), слои проверки больше не жалуются. Но семафор на самом деле не нужен, на мой взгляд. Можно ли это сделать без него?
Обновление:
Заменили все Semaphore[i]
на Fence[i]
, чтобы лучше проиллюстрировать мою проблему. (Предыдущий пример привел к некоторой путанице, извините.)