KhronosGroup / MoltenVK

MoltenVK is a Vulkan Portability implementation. It layers a subset of the high-performance, industry-standard Vulkan graphics and compute API over Apple's Metal graphics framework, enabling Vulkan applications to run on macOS, iOS and tvOS.
Apache License 2.0
4.74k stars 418 forks source link

vertexBindingDescriptionCount of 0 fails on MoltenVK but succeeds on nVidia Vulkan #1340

Open buzmeg opened 3 years ago

buzmeg commented 3 years ago

It's not clear to me if this is a bug or not, but I have tripped over this for the second time and I thought I should point it out. Even if it's not a bug, you may want to fix it as it trips up beginners.

Some tutorials use the vertex shader to provide coordinates as an intermediate step rather than going through all the vertex buffer boilerplate. See: Intel's Vulkan Tutorial 03 for example: https://software.intel.com/content/www/us/en/develop/articles/api-without-secrets-introduction-to-vulkan-part-3.html

They set the vertexBindingDescriptionCount and the vertexAttributeDescriptionCount to 0 but still send in a non-zero value to vertexCount on vkCmdDraw. This way, the shader increments gl_VertexIndex even though it doesn't send in any vertex data.

I can confirm that this works on nVidia on Windows 10 for Vulkan 1.2.141 and fails on MoltenVK on OS X 10.14.6 for Vulkan 1.2.170. I presume it works on Intel Vulkan given that Intel wrote the tutorials. I have no idea about AMD.

I tripped over this many moons ago, but just sort of blew it off that I screwed something up. I had a junior engineer trip over it again, so I took the time to get to the bottom of the problem this time.

Thanks.

billhollings commented 3 years ago

What is the problem you are encountering?

MoltenVK supports both vertexBindingDescriptionCount and vertexAttributeDescriptionCount being zero. In fact, the Cube demo that is packaged with MoltenVK works the way you describe. That demo completely zeros the entire content of VkPipelineVertexInputStateCreateInfo.

I am also able to run the Tutorial03 project you identify on macOS without any trouble (other than porting the project and UI handling to the macOS platform).

buzmeg commented 3 years ago

Really? As soon as I set those to 0 on MoltenVK I get no calls going into the vertex shader. It took me quite a bit of head scratching to run that down with my junior engineer. I can revert the repo and those are the only changes and it switches between works and fails. Fortunately, I had a second pair of eyes with me and it failed on his laptop as well as mine so I know I wasn't hallucinating. :)

Maybe it's specific to something Metal is doing underneath on 10.14.6 on our 13" MacBook Pro Retinas (circa 2015)? Shrug.

Close as "Can't Reproduce". If you verify that this works, then it's absolutely not worth wasting the time on to run down something that is apparently specific to our setups. This is especially true since it would only hit a beginner and as soon as you begin doing "real" work it becomes irrelevant.

I'm likely to have a junior engineer going through a similar exercise next year. By then we should have M1-based hardware. If this pops up again, I'll run it down in detail and file another report. I can also set things up beforehand in such a way that we'll have a sharable test case if it gets hit.

My apologies for the noise.

billhollings commented 3 years ago

As soon as I set those to 0 on MoltenVK

As a quick test, can you try running the Cube demo app that comes with MoltenVK, and respond with the results, please? If it is a problem with MoltenVK on some environment, it would be helpful to know.

You can also look at the code in cube.c to check that it's zeroing those values in the same way you are.

buzmeg commented 3 years ago

The cube app does work on my machine.

Two differences that I immediately note:

1) The cube code is sending uniform buffers--I do not. This may provoke the system into sending vertex index data as well.

2) The cube code completely zeros the VkPipelineVertexInputStateCreateInfo via memset and only sets the sType field. I populate the VkPipelineVertexInputStateCreateInfo as though I were going to send real vertex data, but then only set the two count fields to zero. So, my pVertexBindingDescriptions and pVertexAttributeDescriptions fields are non-null. I don't see how that would affect things if the counts are zero, but ... maybe?