vkCmdBindShadersEXT call causes all rendering (including render pass clear) to fail when called with non-null shaders

OS: Windows 10 (10.0.19045 Build 19045)
Driver: Windows 531.54 (Vulkan Beta Driver)
GPU: GeForce GTX 970

I’ve been trying to write the first triangle program using shader objects (+ dynamic rendering), however reducing the rendering code to the following already fails despite all functions returning VK_SUCCESS:

VkShaderInfoEXT ShaderInfos[] = 
{
    {
        .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,
        .pNext = NULL,
        .flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT,
        .stage = VK_SHADER_STAGE_VERTEX_BIT,
        .nextStage = VK_SHADER_STAGE_FRAGMENT_BIT,
        .codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT,
        .codeSize = VS.Size,
        .pCode = VS.Data,
        .pName = "main",
        .setLayoutCount = 0,
        .pSetLayouts = NULL,
        .pushConstantRangeCount = 0,
        .pPushConstantRanges = NULL,
        .pSpecializationInfo = NULL,
    },
    {
        .sType = VK_STRUCTURE_TYPE_SHADER_CREATE_INFO_EXT,
        .pNext = NULL,
        .flags = VK_SHADER_CREATE_LINK_STAGE_BIT_EXT,
        .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
        .nextStage = 0,
        .codeType = VK_SHADER_CODE_TYPE_SPIRV_EXT,
        .codeSize = FS.Size,
        .pCode = FS.Data,
        .pName = "main",
        .setLayoutCount = 0,
        .pSetLayouts = NULL,
        .pushConstantRangeCount = 0,
        .pPushConstantRanges = NULL,
        .pSpecializationInfo = NULL,
    },
};
VkShaderEXT Shaders[2] = {0}
if (vkCreateShadersEXT(Device, 2, ShaderInfos, Shaders) == VK_SUCCESS)
{
    vkBeginCommandBuffer(Cmd, ...);
    vkCmdPipelineBarrier2(Cmd, ...); // Transitions render target to COLOR_ATTACHMENT_OPTIMAL
    vkCmdBeginRendering(Cmd, ...);

    VkShaderStageFlagBits Stages[] = { VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT };
    #if 1
    // This path results in a constant black image and a stutter on the vkQueueSubmit call
    vkCmdBindShadersEXT(Cmd, 2, Stages, Shaders);
    #else
    // This path results in an image with the clear color specified in through the VkRenderingInfo parameter of vkCmdBeginRendering - as expected
    vkCmdBindShadersEXT(Cmd, 2, Stage, NULL);
    #endif

    vkCmdEndRendering(Cmd);
    vkEndCommandBuffer(Cmd);
}

Since the code works as expected without the vkCmdBindShadersEXT call, I’ve omitted most of the function parameters/structures for brevity, but I can also provide those if need be.
As you can see there’s no actual rendering happening here, no draw commands. Binding the shaders alone causes the rendering to fail and results in a black image and a stutter on the vkQueueSubmit call. There are no crashes however, the application completes successfully.
I’ve also tried:

  • Setting all the required state as described in section 9.1.5. of the Vulkan 1.3.246 spec and issuing a draw command. The result was also a black image in this case.
  • Setting up a VK_EXT_debug_utils debug messenger to see if any errors would be caught that way, but it only provided an informative message about the driver path at the beginning of the program; no messages during runtime.

Obviously the validation layer can’t verify whether the usage of VK_EXT_shader_object is correct, as this extension is not yet part of the Vulkan SDK, but it also doesn’t complain about any other issues, so I’m assuming that the code unrelated to this extension is correct.

So my question would be, is there anything wrong with the above code? Are shader objects supposed to work with the current beta driver for simple(r) use cases?

Hello @m.botond7 and welcome to the NVIDIA developer forums.

This question is a bit too hot off the press and specific for me, so I try t get some expert eyes on it.

But my assumption would be that if this is a fresh release and just entered our driver, it might be that you found a bug for a corner cases like setting up a command buffer without actual draw calls.

I hope to get feedback soon.

This was quick!

I received confirmation that this might indeed still be related to the Beta-state. Improvements are on the way.

We do pass the Khronos conformance tests, which means your case is probably not covered by them yet either.

What would help us to identify the issue would ideally be a minimal repro app for the problem. And I got passed on some more questions and we would appreciate it if you could take the time to answer them:

  • Do you use a dedicated queue or present on your graphics queue?
  • Do you use advanced features like VRR / HDR / Stereo?
  • Do you use multiple swapchains?
  • What would be your application’s frame-rate like normally (without vkWaitForPresentKHR)?

Thank you!

vk_eso.zip (10.7 KB)

Thank you very much for the reply!

I’ve attached a repro, hopefully it’s minimal enough. This repro/example doesn’t present the image; instead it copies it to CPU visible memory and writes it to a file. So to answer the questions:

  • Neither, as explained above.
  • No advanced features, the rendering is done to a R8G8B8A8_UNORM texture.
  • There are no swapchains in the repro.
  • N/A, the “hitch” I mentioned in the original post referred to stepping over the vkQueueSubmit call in the debugger. It took perceivably more time when the command buffer contained the vkCmdBindShadersEXT call. I’m assuming this could just be the driver compiling the shaders at that point though.

Note that I’ve basically had the same issue in a project that did do presentation. There, after the vkCmdBindShadersEXT call the application kept presenting the image from the previous frame where vkCmdBindShadersEXT was not called. In that case there was a similar hitch, after which it returned to the usual 144hz frame-rate.

Thank you again, hopefully this will be of some help in finding the issue!

Hi again!

My apologies, I think I mixed your question up with a different, unrelated one. Thank you for still answering my previous questions even though they might not have made much sense in the context :-)

Which means I still need to find some Vulkan expert help with this, but the repro app will still be very helpful! Thank you for that!

Again, sorry for the mix up.

This issue seems to have been fixed as of driver version 531.83 - possibly earlier.

1 Like

Thank you for updating! Much appreciated.

I was still combing through our internal issue tracker to find mention of this.

I hope you can now continue with your project!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.