我编写了一个Vulkan验证错误的最小可重现代码示例,该错误显然与交换链获取和命令缓冲区提交(see the full code example on 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]);
在队列提交时引发以下同步风险读后写入验证错误:
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)上.我不知道问题出在我的代码中还是在验证层代码中.
我要补充的是,如果我在VkSubmitInfo.pWaitDstStageMask
中将VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
替换为VK_PIPELINE_STAGE_ALL_COMMANDS_BIT
,错误就会消失(但随后我会收到性能警告).
我做错了什么?
我的配置:
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