Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tutorial for reducing pipeline compilation stutters. #10007

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

DarioSamo
Copy link

Tutorial for the new functionality added by godotengine/godot#90400.

Doesn't need to be merged until the PR is merged.

The tutorial is aimed at users familiar with the engine but it should not require them to be rendering experts. Suggestions on what content to include and adjusting the grammar are welcome.

@DarioSamo DarioSamo force-pushed the pipelines branch 4 times, most recently from fadba0b to 851309d Compare September 26, 2024 18:54
@skyace65 skyace65 added enhancement area:manual Issues and PRs related to the Manual/Tutorials section of the documentation waiting on PR merge PR's that can't be merged until a engine PR is merged first topic:shaders labels Sep 27, 2024
@skyace65 skyace65 added this to the 4.4 milestone Sep 27, 2024
Copy link
Member

@clayjohn clayjohn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! I left a few suggestions to add more detail and improve grammar. This is going to be very helpful for users

tutorials/performance/pipeline_compilations.rst Outdated Show resolved Hide resolved
tutorials/performance/pipeline_compilations.rst Outdated Show resolved Hide resolved

Before **Godot 4.4**, there was no solution to pipeline compilation other than generating them when an object shows up inside the camera's view, leading to the infamous *shader stutter* or hitches that only occur during the first playthrough. With **Godot 4.4**, new mechanisms have been introduced to mitigate stutters from pipeline compilation.

- **Ubershaders**: Godot makes use of specialization constants, a feature that allows the driver to optimize a pipeline's code around a set of parameters such as lighting, shadow quality, etc. Ubershaders are able to read these constants while rendering, which means Godot can pre-compile a pipeline ahead of time and compile the optimized version on the background during gameplay. This reduces the amount of pipelines that need to be created significantly.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **Ubershaders**: Godot makes use of specialization constants, a feature that allows the driver to optimize a pipeline's code around a set of parameters such as lighting, shadow quality, etc. Ubershaders are able to read these constants while rendering, which means Godot can pre-compile a pipeline ahead of time and compile the optimized version on the background during gameplay. This reduces the amount of pipelines that need to be created significantly.
- **Ubershaders**: Godot makes use of specialization constants, a feature that allows the driver to optimize a pipeline's code around a set of parameters such as lighting, shadow quality, etc. Specialization constants are used to optimize a shader by limiting unnecessary features. Changing a specialization constant requires recompiling the pipeline. Ubershaders are special version of the shader are able to change these constants while rendering, which means Godot can pre-compile just one pipeline ahead of time and compile the more optimized versions on the background during gameplay. This reduces the amount of pipelines that need to be created significantly.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ubershaders are special version of the shader are able to change these constants while rendering, which means Godot can pre-compile just one pipeline ahead of time and compile the more optimized versions on the background during gameplay.

This one seems to introduce a grammar error, could you provide the corrected version?

tutorials/performance/pipeline_compilations.rst Outdated Show resolved Hide resolved
- **Canvas**: Compiled when drawing a 2D node. The engine does not currently feature pre-compilation for 2D elements and the stutters will show up when the node is drawn for the first time.
- **Mesh**: Compiled as part of loading a 3D mesh and identifying what pipelines can be pre-compiled from its properties. These can lead to stutters if a mesh is loaded from the game loop, but they can be mitigated if the mesh is loaded by using a background thread. **Modifiers that are part of nodes such as material overrides can't be compiled on this step**.
- **Surface**: Compiled when a frame is about to be drawn and 3D objects were instanced on the scene tree for the first time. This can also include compilation for nodes that aren't even visible on the scene tree. The stutter will occur only on the first frame the node is added to the scene, which won't result in an obvious stutter if it happens right after a loading screen.
- **Draw**: Compiled on demand when a 3D object needs to be drawn and an ubershader was not pre-compiled ahead of time. The engine is unable to pre-compile this pipeline due to triggering a case that hasn't been covered yet or a modification that was done to the engine's code. Leads to stutters during gameplay. This is identical to Godot versions before **4.4**.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I read this correctly. This should always be 0 for users right?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, anything landing here is usually something we should address if possible. But since pre-compilation is not an automatic matter at the moment from a code maintenance point of view, it's a good metric to keep an eye on during development or for people who fork the engine and make their modifications to the renderer.

tutorials/performance/pipeline_compilations.rst Outdated Show resolved Hide resolved
tutorials/performance/pipeline_compilations.rst Outdated Show resolved Hide resolved
tutorials/performance/pipeline_compilations.rst Outdated Show resolved Hide resolved
tutorials/performance/pipeline_compilations.rst Outdated Show resolved Hide resolved

Pipeline compilation, also commonly known as shader compilation, is an expensive operation required by the engine to be able to draw any kind of content with the GPU.

In more precise terms, *Shader Compilation* involves the translation of the GLSL code that Godot generates into an intermediate format that can be shared across systems (such as SPIR-V when using Vulkan). However, this format can't be used by the GPU directly. *Pipeline Compilation* is the step the GPU driver performs where it'll convert the intermediate shader format (the result from shader compilation) to something the GPU can actually use for rendering. Drivers usually keep a cache of pipelines stored somewhere in the system to avoid repeating the process every time a game is run. This cache is usually deleted when the driver is updated.
Copy link
Contributor

@tetrapod00 tetrapod00 Sep 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section might be made more clear by explicitly listing out the shader compilation stages, ideally with some graphic:
VisualShader/StandardMaterial (this generates GDShader as an intermediate step in some cases, right?) -> GDShader (Godot Shading Language) -> GLSL -> intermediate format (SPIR-V) -> pipeline.

As is, this assumes some knowledge of the shader compilation process (the fact that Godot compiles to GLSL as an intermediate step isn't commonly referenced throughout the rest of the docs, IIRC).

Copy link
Contributor

@tetrapod00 tetrapod00 Sep 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like this
ShaderCompilationSteps

(I'm not sure if all this is accurate, and labelling just the single step as "shader compilation" may be misleading")
(I also don't know what the best way to make such a diagram for the docs is, I just used drawio to throw this together)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it! Can I include this graph as is? Or do we need to handle it in some way to take transparency or background into account?

@tetrapod00
Copy link
Contributor

We might want to link to this page from https://docs.godotengine.org/en/stable/tutorials/rendering/jitter_stutter.html.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:manual Issues and PRs related to the Manual/Tutorials section of the documentation enhancement topic:shaders waiting on PR merge PR's that can't be merged until a engine PR is merged first
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants