簡體   English   中英

Vulkan 隊列等待無法發出信號的信號量

[英]Vulkan queue waiting on semaphore that can't be signaled

似乎我有一段時間的無效代碼,但驗證層保持沉默。 將我的 sdk 更新到最新版本后,我開始收到此錯誤:

Message ID name: VUID-vkQueuePresentKHR-pWaitSemaphores-03268
Message: [ VUID-vkQueuePresentKHR-pWaitSemaphores-03268 ] Object: 0x55b4b87478f0 (Name = Selected logical device : Type = 3) | VkQueue 0x55b4b8224020[Main queue] is waiting on VkSemaphore 0x110000000011[Render Finished Semaphore: 0] that has no way to be signaled. The Vulkan spec states: All elements of the pWaitSemaphores member of pPresentInfo must reference a semaphore signal operation that has been submitted for execution and any semaphore signal operations on which it depends (if any) must have also been submitted for execution. (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkQueuePresentKHR-pWaitSemaphores-03268)
Severity: VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT

這發生在我的主繪制循環內,它是我代碼中唯一的驗證層錯誤。 如果我從不調用負責表面呈現的代碼。 我沒有錯誤。

我確定我做錯的地方在這里:

void DisplayTarget::StartPass(uint target_num, bool should_clear,
    VulkanImage* external_depth)
{
    auto device = h_interface->GetDevice();

    auto result = device.acquireNextImageKHR(
        *swap_chain,
        std::numeric_limits<uint64_t>::max(),
        *img_available_sems[current_frame],
        nullptr,
        &active_image_index);

    if(result != vk::Result::eSuccess)
        Log::RecordLog("Failed to acquire image");
}

vk::Result DisplayTarget::EndPass()
{
    auto device         = h_interface->GetDevice();
    auto cmd_buff       = h_interface->GetCmdBuffer();
    auto graphics_queue = h_interface->GetQueue();

    device.waitForFences(
        1,
        &*in_flight_fences[current_frame],
        VK_TRUE,
        std::numeric_limits<uint64_t>::max());

    vk::Semaphore wait_semaphores[]      = {*img_available_sems[current_frame]};
    vk::PipelineStageFlags wait_stages[] = {
        vk::PipelineStageFlagBits::eColorAttachmentOutput};
    vk::Semaphore signal_semaphores[] = {*render_finished_sems[current_frame]};
    vk::SubmitInfo submit_info(
        1, wait_semaphores, wait_stages, 1, &cmd_buff, 1, signal_semaphores);

    device.resetFences(1, &*in_flight_fences[current_frame]);

    auto result =
        graphics_queue.submit(1, &submit_info, *in_flight_fences[current_frame]);
    if(result != vk::Result::eSuccess)
        Log::RecordLog("Failed to submit draw command buffer!");

    graphics_queue.waitIdle();
    device.waitIdle();

    vk::SwapchainKHR swap_chains[] = {*swap_chain};
    vk::PresentInfoKHR present_info = {};
    present_info.waitSemaphoreCount = 1;
    present_info.pWaitSemaphores = signal_semaphores;
    present_info.swapchainCount = 1;
    present_info.pSwapchains = swap_chains;
    present_info.pImageIndices = &active_image_index;

    result = graphics_queue.presentKHR(&present_info);

    current_frame = (current_frame + 1) % MAX_FRAMES_IN_FLIGHT;

    return result;
}

目前它們被連續調用:

display.StartPass();        
display.EndPass();

為了使事情正常進行,我嘗試將這兩個函數的部分注釋掉或更改調用的順序,但錯誤仍然存在或我得到不同的驗證錯誤。

我還嘗試直接向信號量發出信號:

vk::SemaphoreSignalInfo semaphore_info = {};
semaphore_info.semaphore = *render_finished_sems[current_frame];
semaphore_info.value = 0;
device.signalSemaphore(semaphore_info);

但我所做的只是導致分段錯誤

錯誤是操作的順序。 這是錯誤的:

graphics_queue.waitIdle();
device.waitIdle();

vk::SwapchainKHR swap_chains[] = {*swap_chain};
vk::PresentInfoKHR present_info = {};
present_info.waitSemaphoreCount = 1;
present_info.pWaitSemaphores = signal_semaphores;
present_info.swapchainCount = 1;
present_info.pSwapchains = swap_chains;
present_info.pImageIndices = &active_image_index;

result = graphics_queue.presentKHR(&present_info);

current_frame = (current_frame + 1) % MAX_FRAMES_IN_FLIGHT;

這是正確的用法:

vk::SwapchainKHR swap_chains[] = {*swap_chain};
vk::PresentInfoKHR present_info = {};
present_info.waitSemaphoreCount = 1;
present_info.pWaitSemaphores = signal_semaphores;
present_info.swapchainCount = 1;
present_info.pSwapchains = swap_chains;
present_info.pImageIndices = &active_image_index;

result = graphics_queue.presentKHR(&present_info);

current_frame = (current_frame + 1) % MAX_FRAMES_IN_FLIGHT;

graphics_queue.waitIdle();
device.waitIdle();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM