错误说 vulkan 队列正在等待无法发出信号的信号量(实际上会发出信号)

error says vulkan queue waiting on semaphore that has no way to be signaled (actually will be signaled)

我看过这两个类似的问题:

  1. vkQueuePresentKHR validation bug

第一个是由信号量A发出信号并等待信号量B引起的;第二个是present before submit造成的。但是,我的情况完全不同。程序运行时,验证层会抛出错误:

--> Validation Error: [ VUID-vkQueuePresentKHR-pWaitSemaphores-03268 ]
Object 0: handle = 0x14e37396870, name = queueGCT, type = VK_OBJECT_TYPE_QUEUE;
Object 1: handle = 0x2b424a0000000034, name = swapchainWrittenSemaphore:1, type = VK_OBJECT_TYPE_SEMAPHORE; |
MessageID = 0x251f8f7a |
vkQueuePresentKHR: Queue VkQueue 0x14e37396870[queueGCT] is waiting on
pWaitSemaphores[0] (VkSemaphore 0x2b424a0000000034[swapchainWrittenSemaphore:1]) that has no way to be signaled.

根据消息,错误很可能是由永远不会发出信号的信号量引起的。然而,这是 weird.In 我的情况,交换链创建了 3 个条目并具有 3 个双数对(readSemaphore[0,1,2] 和 writeSemaphore[0,1,2])。我的程序是这样的:

// Main loop
while (!glfwWindowShouldClose(...)) {
    // ...
    prepareFrame();
    // create command buffer and record commands ...
    vkBeginCommandBuffer(cmdBuf, &beginInfo);
    // -- ray tracing...
    // -- post processing...
    vkEndCommandBuffer(cmdBuf);
    submitFrame();
}

在 prepareFrame() 中,交换链 vkAcquireNextImageKHR 并在准备完成时发出信号 readSemaphore[cur_loop % 3]

在 submitFrame() 中,程序首先 vkQueueSubmit 等待 readSemaphore[cur_loop % 3] 并在队列完成时发出 writeSemaphore[cur_loop %3] 信号。然后是等待 writeSemaphore[cur_loop %3] 的程序 vkQueuePresentKHR。代码可以在 nvpro_core 的 swapchain_vk.h/cpp 和 appbase_vk.h/cpp.

中找到

只有当循环经过第2(或第3)次且触发点为submitFrame()::present()::vkQueuePresentKHR()时才会触发错误。这很奇怪,因为第一个循环和第二个/第三个循环做同样的事情但是第一个循环没有问题。我调试了代码,发现 vkQueuePresentKHR() 中的 waitSemaphore writtenSemphore[1]enter image description here 应该已经被 submitFrame() 中的 vkQueueSubmit() 发出信号。

在 visual studio 调试器中,semaphoreWrite = 0x2b424a0000000034written = 0x2b424a0000000034。图片可以参考here:

vkQueueSubmitsemaphoreWrite 发出信号,vkQueuePresentKHR 等待 written。它们是相同的信号量。

最奇怪的是,这个错误似乎与我的光线追踪着色器代码有关。当我在主循环中评论光线追踪过程时,程序运行良好。如果保留光线跟踪程序,简单的着色器代码(如在输出图像处生成 uv 坐标)不会造成问题,而计算命中距离会造成问题。

// writing uv coordinate, works fine
// ---------------------------------
// ray generation
void main()
{
  const ivec2 resolution = imageSize(image);
  const ivec2 pixel = ivec2(gl_LaunchIDEXT.xy);
  if((pixel.x >= resolution.x) || (pixel.y >= resolution.y))
  {
    return;
  }
  vec4 color = vec4(pixel.x / float(resolution.x),
                    pixel.y / float(resolution.y),
                    0.0, 0.0);
  imageStore(image, pixel, color);
}
// close hit
void main() {}
// writing depth, works fine
// ---------------------------------
// ray generation
traceRayEXT(topLevelAS,     // acceleration structure
              rayFlags,       // rayFlags
              0xFF,           // cullMask
              0,              // sbtRecordOffset
              0,              // sbtRecordStride
              0,              // missIndex
              origin.xyz,     // ray origin
              tMin,           // ray min range
              direction.xyz,  // ray direction
              tMax,           // ray max range
              0               // payload (location = 0)
  );

  imageStore(image, ivec2(gl_LaunchIDEXT.xy), vec4(payload.radiance, 1.0));
// close hit
void main() {
    payload.radiance = vec3(gl_HitTEXT);
}

但是稍作调整,就会出现错误:

// close hit
void main() {
    payload.radiance = vec3(gl_HitTEXT/100.0);
    // or any other operation to gl_HitTEXT
    // or
    // float x = gl_HitTEXT * 2;
    // payload.radiance = vec3(x);
}

有人能帮帮我吗?提前致谢!

一些代码here

已解决。最后发现在创建shader binding的时候只有ray generation shader加入了shader组table。也就是说,缺少接近命中着色器和光线未命中着色器。