2
votes

So I am reading the vulkan book now and got a problem about the push Constant and ubo update.

After I set up all the pipeline and descriptor stuff. Basically I just need the copy the buffer to the UBO buffer such as memcpy then I am done. Basically I can understand the issue about the whole pipeline needs to wait for this "buffer" ready then change it's content. So it will be slow.

On the other hand, when I use push constant, there is no such a problem. Although it's small (say 256 bytes big).

So far so good.

However, on the second thought, I find that if I am updating the UBO, I don't need to change the command buffer, or re-record it, I can submit the old CB since it's still the same. Then if I want to update by using Push Constant, I have to reset the CB and record it again then submit it.

So won't this be an issue? How to make sure which one is faster?

Thanks.

1
"How to make sure which one is faster?" Profile it. - Nicol Bolas
Also - look for optimization guides for the GPU vendors you care about, they normally have good recommendations here. - solidpixel
just wondering if there is a quick answer, it should all behave same, to different GPUs right - caxieyou110
There's a quick answer if you go for the intended usage. But you are asking us to make an engineering tradeoff of performances that are at best vendor specific, and at worst depends on the current GPU\CPU pressure. Push constants are same or better than updating memory backed resources, where all other things are the same. That's all we know, and can responsibly say. - krOoze

1 Answers

3
votes

Lots of people get confused on this issue, because the Vulkan Tutorial pre-records commands and Vulkan Guide re-record commands every frame.

When people say to use push constants for per-frame changing data like transform matrices and time data, there's the implicit assumption that you are recording command buffer per frame. Push constants essentially hitch a ride with the rest of your commands when submitted, which is also how they avoid synchronization and cache flushing to operate.

Now, in a lot of scenarios, re-recording command buffers can be easier and not significantly more costly than re-use. And indeed, re-using command buffers when things change can be a real pain to manage. Command buffers are meant to be fast to record. Still, the Vulkan tutorial went with pre-recording everything, which is also a valid approach though potentially harder to maintain at scale.

At the time the tutorial was created, the Vulkan Tutorial was essentially one of the only resources available to learn vulkan in a structured manner. Even though command buffers are quick to record, pre-recording command buffers eliminates even more CPU overhead and exemplifies Vulkan's "Never be draw call limited again" mantra to eliminating CPU overhead in graphics applications.

As for the speed comparison, you'll have to benchmark, but I would not necessarily choose one or the other for "speed" reasons. If you pre-record, you don't want to re-orient your entire rendering architecture just to take advantage of push constants. If you don't pre-record, there's no reason not to use push constants, they are just straight up easier to deal with.

It seems like currently you are pre-recording. I would not bother with push constants at all for this kind of data. I would also not focus on these kinds of issues until you get more familiar with vulkan, as it is very easy to get caught in the weeds with optimization in vulkan, strategies for optimization are no where near as uniform as in the CPU space.