diff --git a/docs/NOTES_render_pipeline.md b/docs/NOTES_render_pipeline.md new file mode 100644 index 0000000..9c56c66 --- /dev/null +++ b/docs/NOTES_render_pipeline.md @@ -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. + + +