Search code examples
graphicssynchronizationsemaphorevulkanraytracing

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


I have read these two similar questions:

  1. Vulkan queue waiting on semaphore that has no way to be signaled
  2. vkQueuePresentKHR validation bug

The first one is caused by signaling semaphore A and waiting on semaphore B; The second one is caused by present before submit. However, my case is quite different. When the program runs, the validation layer will throw error:

--> 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.

According to the message, the error is most likely caused by a semaphore that will never be signaled. However, this is weird.In my case, the swapchain creates 3 entries and has 3 somaphore pairs (readSemaphore[0,1,2] and writeSemaphore[0,1,2]). My program is like:

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

In the prepareFrame(), the swapchain vkAcquireNextImageKHR and will signal readSemaphore[cur_loop % 3] when preparing is done.

In the submitFrame(), the program first vkQueueSubmit which waits on readSemaphore[cur_loop % 3] and will signal writeSemaphore[cur_loop %3] when queue is done. Then the program vkQueuePresentKHR which waits on writeSemaphore[cur_loop %3]. The code can be found in nvpro_core's swapchain_vk.h/cpp and appbase_vk.h/cpp.

The error will only be trigered When the loop goes through the 2nd (or 3rd) time and the triger point is submitFrame()::present()::vkQueuePresentKHR(). It is weird because the 1st loop and 2nd/3rd loop do the same thing but there is no problem with the 1st loop. I debugged the code and found that the waitSemaphore writtenSemphore[1]enter image description here in vkQueuePresentKHR() should have been signaled by vkQueueSubmit() in submitFrame().

In visual studio debugger, semaphoreWrite = 0x2b424a0000000034 and written = 0x2b424a0000000034. The image can referred here:

vkQueueSubmit signals semaphoreWrite and vkQueuePresentKHR waits on written. They are the same semaphore.

The strangest thing is that this bug seems to be related to my raytracing shader code. When I comment the raytracing procedure in main loop, the program runs fine. If the raytracing procedure is preserved, simple shader code like generating a uv coordinate at the output image will not cause problem, while computing hit distance will.

// 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);
}

However, made a small adjustment, the error will occur:

// 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);
}

Could anyone please help me? Thanks in advance!

Some code here.


Solution

  • Solved. Finally, I found that only ray generation shader was added to the shader group when creating shader binding table. That is, close hit shader and ray miss shader were missing.