Na minha aplicação, as camadas de validação do Vulkan reclamaram que as cercas e os semáforos não podiam ser destruídos, pois ainda estavam em uso.
A mensagem era "um tanto estranha", como afirmava, por exemplo
Erro de validação: [VUID-vkDestroyFence-fence-01120] | IDdamensagem = 0x5d296248 | vkDestroyFence(): fence não pode ser chamado no VkFence 0xcb3ee80000000007[] que está atualmente em uso pelo VkFence 0xcb3ee80000000007[]
(basicamente me dizendo que a cerca estaria "em uso por si só"), mas presumo que seja uma forma mais estranha de formatar a mensagem e não tem um significado "mais profundo". Essencialmente, a cerca ainda está em uso.
Exatamente a mesma mensagem foi lançada para "todas" as minhas cercas e semáforos binários instalados (uma cerca, dois semáforos, apenas uma fila foi usada para "tudo").
Depois de alguma depuração, descobri que isso só acontecia se a limpeza não verificasse a cerca para os comandos enviados nem esperasse que a fila ficasse ociosa.
Tanto esperar pela cerca ou simplesmente esperar pela fila era suficiente.
Mas isso não poderia ser um “puro problema de tempo” de fazer a destruição enquanto os problemas de comando ainda estavam em execução, já que tanto o envio quanto a destruição do comando foram acionados manualmente com um atraso muito além do bem e do mal para uma GPU.
Os comandos enviados tiveram que ser "feitos há muito tempo" quando ocorreu a destruição (não sou "tão rápido"...😂).
Eu então descobri que simplesmente verificar o status da cerca via vkGetFenceStatus() resolveu o problema, ou seja, um vkGetFenceStatus() feito antes da destruição fez com que a camada de validação ficasse silenciosa.
Isso parece indicar que há alguma avaliação "preguiçosa" feita na GPU para não encerrar os comandos enviados, desde que a CPU "não solicite" direta ou indiretamente por meio de verificação em cima do muro ou aguardando a fila ficar ociosa.
Me lembro um pouco do gato de Schrödinger, que só morre se você olhar...
Esse comportamento é esperado?
Não encontrei nada na documentação oficial sobre isso?!
As camadas de validação não são “a GPU”; eles são códigos externos que você usa para garantir que está usando a API Vulkan corretamente.
A API diz que você não pode destruir uma cerca enquanto ela estiver em uso. Isso significa que, para que sua chamada de destruição seja válida, seu código deve saber que a cerca não está mais em uso.
Dessa forma, a camada de validação é programada para que você precise fazer algo para indicar que seu código sabe que a cerca não está mais em uso. E fazer outras coisas por algum período de tempo, não é? Você acredita que gastou tempo de CPU suficiente para que a GPU concluísse esse lote. Mas você não sabe que está terminado.
E é com isso que a camada de validação se preocupa. Ele quer que seu código esteja certamente correto, e não provavelmente correto.
Dessa forma, a camada de validação exige que você faça algo com a API Vulkan que sincronize com a conclusão do lote que contém a cerca. Verificar o status da cerca é uma dessas coisas e geralmente é a que você deve usar.