Overv / VulkanTutorial

Tutorial for the Vulkan graphics and compute API
https://vulkan-tutorial.com
Creative Commons Attribution Share Alike 4.0 International
3.06k stars 510 forks source link

Re-record command buffers every frame #202

Closed charles-lunarg closed 2 years ago

charles-lunarg commented 3 years ago

While I understand that this tutorial is a beginners introduction into the API, many people work through it and then try to use it as the base for their endeavors in Vulkan. The issue is that outside of extremely basic tasks, it is difficult to use pre-recorded command buffers. Culling, adding & removing things to render every frame, as well as managing which swapchain image to render to are significantly simpler when you re-record every frame. I've seen countless beginners who've finished this tutorial series then are lost on how to implement features because of the lack of command buffer recording each frame.

What I propose is to rewrite the tutorial to re-record command buffers every frame instead of baking them ahead of time.

Obviously this is a very big undertaking. I am creating the issue to indicate that its something I consider a problem, and that if I created a PR which reworked the tutorials, it would be accepted (with as many revisions as necessary of course).

abnercoimbre commented 3 years ago

Wouldn't it be less work to add a bonus chapter?

We could extend the viking room program to project a 2D quad that's a Vulkan logo. This would be done in a new command buffer that can re-record. We then have fun with the logo by transforming it through push constants: a concept people have asked about anyway.

This would also show people how to manage separate buffers. Alternatively, we keep a single primary buffer and set it to VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS, and render the viking room and Vulkan logo through their respective secondary command buffers.

charles-lunarg commented 3 years ago

While easier to do, I think it is less useful. In my opinion re-recording command buffers is such a common thing to need that it only makes sense to introduce it as the first way to use command buffers. Why use what I consider an anti-pattern as the first example when the actual pattern is in my opinion not any more difficult to do in the first place?

The reason I consider it an anti-pattern is that the architectural complexity needed to only record when necessary is much more significant than the actual perf cost of recording command buffers along side the difficulty in implementation compared to simply re-recording every frame. Especially when frustum culling and dynamic scenes come into play. I assert that most people see 'we will pre-record the command buffers' and then think that all applications do this. An additional chapter at the end would clarify that, but I don't think everyone will read that and it also seems a bit counter intuitive to initially say 'do this' then much later on say 'don't do this, do that instead'.

A stop-gap solution would be correcting the text on the 'Overview' page to mention something along the lines of "re-recording every frame is common practice, but initially for simplicity we are going to pre-record them", then in the Command Buffer chapter reiterate that statement.

abnercoimbre commented 3 years ago

The stop-gap solution might be really nice. Beginners I've seen online know they should be able to re-record into buffers somehow. I've seen concerns skew more toward "speed hits" or whether it is indeed an okay thing to do. Pinging @Overv to get his thoughts?

I hear you that we want sane defaults for intro material. That said, it should be fine to show you can record commands once and continuously submit them afterwards. We both know an important part of Vulkan development is teasing out which set of commands could belong in one kind of buffer versus another, as managing multiple buffers in applications is also common practice.

Overv commented 3 years ago

I agree that the tutorial should show patterns that are as practically applicable in real projects as possible, and I think that the approach with secondary command buffers offers a nice balance there.

We could show that command buffers in general are infinitely reusable by having a secondary command buffer that actually draws the model, and show the continuous rerecording of the primary buffer with different render pass parameters for every frame. People can then easily extrapolate this to scenarios with many more secondary command buffers that may themselves be rerecorded at will.

I also agree with @charles-lunarg to restructure the tutorial to teach this method from the very beginning and would gladly accept pull requests to bring about these changes (especially since I'm very time constrained myself right now).

charles-lunarg commented 3 years ago

I think it is good to have some part of the tutorial cover secondary command buffers and best usage, it is best left for later on in the tutorials and not in the main chapter. It would be well placed to put in a 'best practices for dynamic scenes' like described here. https://github.com/Overv/VulkanTutorial/issues/153

I do think it needs to be explicitly stated what secondary command buffers are and aren't useful for. Post processing commands and parallel command buffer recording are a clear target. Recording a secondary command buffers per model on the other hand is an anti pattern and most likely stems from the thought that command buffer recording is incredibly expensive and should be avoided at all costs.

Thinking more generally, the many 'traps' I see people falling into with vulkan are simply not measuring. They see X construct, imagine Y about it, and conclude Z without question. Its difficult to teach someone how to do that though, and I'm not sure how you would even approach writing a chapter on such a subject. But that's a topic for a different issue.

I greatly appreciate the go ahead to begin writing. I will try to work on them in the near future, but well, I'm not lacking things to do myself. If you have any tips, suggestions, or things to watch out for when writing, that would be very helpful.

abnercoimbre commented 3 years ago

I've implied in my last comment (last paragraph) that Vulkan is about learning about what's possible. Introducing language like "this is an anti-pattern" or being overly-parental would be against the spirit of the API. You don't seem to disagree:

Thinking more generally, the many 'traps' I see people falling into with vulkan are simply not measuring. They see X construct, imagine Y about it, and conclude Z without question.

Everyone benefits with the least amount of effort by adding an extra chapter on dynamic scenes. In fact, you want to encourage the skill of re-architecting parts of a codebase as needed. Then like you said, just ensure early chapters emphasize that re-recording buffers is not only common but expected.

It seems @Overv is not against you re-working the tutorial, but I wanted to air my concerns. If you do go ahead with this, I'll keep an eye out and try to be helpful either way.

charles-lunarg commented 3 years ago

That's a very fair point, and I may have been a little overzealous in my language to describe re-recording. Saying 'there is only one way to do X' is both wrong and unhelpful. I agree about benefiting everyone with more chapters on dynamic scenes and showing the concepts needed for them. Seems that I now have 2+ chapters to write. :)

charles-lunarg commented 2 years ago

I have (finally) gotten a working PR/branch up that addresses the issue. It is in the KhronosGroup fork of the repo, which will act as a staging branch for a larger number of planned and in progress changes. Your comments and criticisms are welcome :) https://github.com/KhronosGroup/VulkanTutorial/pull/1