Add some thoughts about the future render pipeline
This commit is contained in:
parent
fc08ab08d4
commit
1d8051747e
63
docs/NOTES_render_pipeline.md
Normal file
63
docs/NOTES_render_pipeline.md
Normal file
@ -0,0 +1,63 @@
|
||||
# Render Pipeline
|
||||
|
||||
## Frame Graph
|
||||
|
||||
We use [KHR_dynamic_rendering](https://lesleylai.info/en/vk-khr-dynamic-rendering/) for vulkan.
|
||||
DX12 render passes are basically equivalent to this.
|
||||
|
||||
Nevertheless, we need to define which render targets we need and when each RT will be written and read from.
|
||||
This is because we
|
||||
1. Need to allocate render targets and
|
||||
2. Want to parallelize independent parts of the frame.
|
||||
|
||||
Two API concepts:
|
||||
1. **Render Targets**: Contain format info and sizes. For vulkan, these get "compiled" to a VkImage(View) and a Rect for the render area
|
||||
2. **Passes**: Contain the information necessary for VkRenderingInfoKHR structs and their DX12/Metal/... equivalents.
|
||||
|
||||
A render target should actually contain N copies of the image, where N is the max. number of frames in flight. (Usually 2 or 3).
|
||||
Multiple render targets with the same format could be aliased, if they are never accessed concurrently, to save VRAM.
|
||||
|
||||
A **frame-graph** is then:
|
||||
- A set of render targets. Each render target gets an unique name by which it can be referenced.
|
||||
- A ordered list of passes. The passes are - logically - executed in the order given, but may be scheduled concurrently, if this yields the same results.
|
||||
|
||||
To determine the possibilities of concurrent execution and aliasing, each pass needs to list the render targets it accesses.
|
||||
|
||||
|
||||
## Interfacing with the scene
|
||||
|
||||
The update thread computes a scene representation that is made available to the render thread.
|
||||
This should contain a list of objects that, potentially (sans culling) need to be rendered.
|
||||
|
||||
Each object has a material.
|
||||
A material contains a effect, which lists the passes during which the object needs to be rendered
|
||||
and shader pipelines for each of these passes (sets of shaders + fixed state + meta information about uniforms etc.).
|
||||
It could also define the expected vertex layout for rendered meshes.
|
||||
|
||||
This information enables us to provide each pass of the frame graph with a list of objects that need to be rendered by that pass.
|
||||
It also allows us to skip passes without any input objects, except when the passes are marked as "execute always" (for example a tone-mapping pass).
|
||||
|
||||
The material also binds effect properties to "real" values.
|
||||
For example an effect could expose a property like "albedo-map" and the material would bind this to a particular resource.
|
||||
|
||||
## Interfacing with the resource system
|
||||
|
||||
Effects can be loaded from resources (we already have a parser for PSOs and a shader compiler).
|
||||
These would now be tied to a particular frame-graph (set of passes).
|
||||
|
||||
We could also load frame-graph information from resources, but how do we provide the logic for that pass?
|
||||
**Idea:** Have the game "bind" a struct like the following to a pass:
|
||||
|
||||
```
|
||||
/* rt_pass is some kind of identifier/handle for the pass)
|
||||
struct rt_pass_functions_s {
|
||||
void (*pass_prepare)(rt_pass pass);
|
||||
void (*pass_execute)(rt_pass pass, rt_render_object_list objects);
|
||||
void (*pass_finalize)(rt_pass pass);
|
||||
}
|
||||
```
|
||||
|
||||
The runtime (or a separate library?) can provide some default pass-implementations for this.
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user