交换链获取和命令缓冲区提交时出现 SYNC-HAZARD-WRITE-AFTER-READ 错误

问题描述 投票:0回答:1

我编写了一个 Vulkan 验证错误的最小可重现代码示例,该错误显然与交换链获取和命令缓冲区提交之间的同步相关(请参阅 Gist 上的完整代码示例)

示例 C 代码应该只使用 GLFW 创建一个黑色窗口,并在单帧后立即返回。

相关部分在这里(我删除了栅栏以简化代码,无论有或没有它们,错误都是相同的):

    VkSemaphore imageAvailableSemaphore = createSemaphore(device);
    VkSemaphore renderFinishedSemaphore = createSemaphore(device);

    uint32_t imageIndex;
    vkAcquireNextImageKHR(
        device, swapChain, UINT64_MAX, imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex);

    VkSemaphore waitSemaphores[] = {imageAvailableSemaphore};
    VkSemaphore signalSemaphores[] = {renderFinishedSemaphore};
    VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};

    VkSubmitInfo submitInfo = {};
    submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
    submitInfo.waitSemaphoreCount = 1;
    submitInfo.pWaitSemaphores = waitSemaphores;
    submitInfo.pWaitDstStageMask = waitStages;
    submitInfo.signalSemaphoreCount = 1;
    submitInfo.pSignalSemaphores = signalSemaphores;
    submitInfo.commandBufferCount = 1;
    submitInfo.pCommandBuffers = &commandBuffers[imageIndex];

    VkQueue graphicsQueue;
    vkGetDeviceQueue(device, queueFamilyIndex, 0, &graphicsQueue);
    vkQueueSubmit(graphicsQueue, 1, &submitInfo, NULL);

命令缓冲区只是:

        vkBeginCommandBuffer(commandBuffers[i], &beginInfo);
        vkCmdBeginRenderPass(commandBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
        vkCmdEndRenderPass(commandBuffers[i]);
        vkEndCommandBuffer(commandBuffers[i]);

队列提交时会引发以下 SYNC-HAZARD-WRITE-AFTER-READ 验证错误:

    validation layer: Validation Error: [ SYNC-HAZARD-WRITE-AFTER-READ ] Object 0: handle =
    0x5599afbbf520, type = VK_OBJECT_TYPE_QUEUE; | MessageID = 0x376bc9df | vkQueueSubmit(): Hazard
    WRITE_AFTER_READ for entry 0, VkCommandBuffer 0x5599b202e960[], Submitted access info
    (submitted_usage: SYNC_IMAGE_LAYOUT_TRANSITION, command: vkCmdBeginRenderPass, seq_no: 1,
    renderpass: VkRenderPass 0xcad092000000000d[], reset_no: 1). Access info (prior_usage:
    SYNC_PRESENT_ENGINE_SYNCVAL_PRESENT_ACQUIRE_READ_SYNCVAL, read_barriers:
    VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT|VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT, ,
    batch_tag: 1, vkAcquireNextImageKHR aquire_tag:1: VkSwapchainKHR 0xf443490000000006[],
    image_index: 0image: VkImage 0xcb3ee80000000007[]).

此错误仅发生在特定配置上(具有最新 LunarG SDK v1.3.275 的 Linux)。我不知道问题是出在我的代码中还是验证层代码中。

我应该补充一点,如果我将

VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
中的
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT
替换为
VkSubmitInfo.pWaitDstStageMask
,错误就会消失(但随后我会收到性能警告)。

我做错了什么?

我的配置:

Ubuntu 22.04
LunarG SDK version 1.3.275
Vulkan Instance Version: 1.3.275
NVIDIA GeForce RTX 2070 SUPER
NVIDIA-SMI 535.129.03
Driver Version: 535.129.03
CUDA Version: 12.2
c gpu nvidia glfw vulkan
1个回答
0
投票

我认为验证层 GitHub 中的这个讨论解释了这个问题以及如何解决它。

讨论的重要部分是:

应该有额外的执行依赖 COLOR_ATTACHMENT_OUTPUT 阶段,否则可以开始图像转换 在图像获取操作完成之前。目的地阶段已设定 到 COLOR_ATTACHMENT_OUTPUT,这保证了从 光栅化将等待。但图像布局发生转换 之前,通过将源阶段设置为 COLOR_ATTACHMENT_OUTPUT,我们 使用信号量等待操作创建执行依赖关系(我们链接 与 pWaitDstStageMask 也指定 COLOR_ATTACHMENT_OUTPUT )。

我实际上重现了您的问题,并添加了一个障碍来添加如上所述的依赖项,并且验证消息不再出现。这可能与您的情况不完全相同,但似乎有可能。

© www.soinside.com 2019 - 2024. All rights reserved.