Вулкан: Зачем нам проверять размер окна после VkQueuePresentKHR - PullRequest
1 голос
/ 20 января 2020

Я следую учебному пособию по вулканскому языку, в настоящее время я участвую в воссоздании цепочки обмена.

https://vulkan-tutorial.com/Drawing_a_triangle/Swap_chain_recreation

Предполагается, что изменение размера выполняется явно путем установки логическая переменная framebufferResized в true, если вызывается метод обратного вызова изменения размера окна. Затем, если размер окна изменился, мы воссоздаем цепочку обмена в методе drawFrame, который вызывается каждый кадр. Что-то вроде ниже.

VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex);
...
result = vkQueuePresentKHR(presentQueue, &presentInfo);
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized) {
    framebufferResized = false;
    recreateSwapChain();
}

Это утверждение, которое я запутал в учебнике: «Важно сделать это после vkQueuePresentKHR, чтобы гарантировать, что семафоры находятся в согласованном состоянии, в противном случае сигнальный семафор никогда не будет должным образом ожидаться после «. Я предполагаю, что "this" - это проверка на логическое значение framebufferResized и последующее воссозданиеSwapChain (). Семафоры - это просто семафоры, которые гарантируют, что мы успешно получим изображение, прежде чем рисовать на нем, а затем успешно рисовать на нем, прежде чем представить его. Поэтому для меня не имеет смысла, о чем говорит автор.

1 Ответ

3 голосов
/ 20 января 2020

Предположительно, "сигнал" относится к vkAcquire, а воссоздание цепочки обмена защищено чем-то вроде vkDeviceWaitIdle. И, по-видимому, автор обеспокоен VK_SUBOPTIMAL и хочет воссоздать swapchain в этом случае.

Но vkDeviceWaitIdle не охватывает ожидающий семафор из vkAcquire, что подтверждается здесь: https://github.com/KhronosGroup/Vulkan-Docs/issues/1059.

Это означает, что семафор должен сначала ожидать vkQueueSubmit. Только тогда семафор может быть перехвачен командой vk*WaitIdle, и только после этого он будет уничтожен действительным образом.

...