
Render Pipelines design in C++ - llorens-marti
http://www.marti.works/render-pipelines-desing-in-c/
======
banachtarski
This is a somewhat simplified version of what you will see in a AAA graphics
engine (pretty much all of them have abstractions around draw passes/stages
and pipelines). The weakness in the approach here I think is that it won't
handle temporally aliased things particularly well and also, I've found that
actually render pipelines are more of a pipe"tree" with dependent objects
becoming inputs for more than one pass for various things. Then you throw in
multithreading into the mix and start to understand why a simplistic API like
this gets complicated really fast in real world settings.

------
jerianasmith
There is nothing new in Abstraction of passes and pipelines. We need to think
about practical complications also.

------
foota
I would be curious to see what anyone with more than my armchair experience in
graphics thinks of this.

~~~
dreta
This post is an example of armchair programming, so your armchair experience
is more than enough.

On a more serious note, it's software architecture done on paper. Any
experienced programmer will tell you it's close to worthless. You don't have
to be a graphics expert. Abstraction of passes and pipelines isn't anything
new, it even bled into the modern APIs like Vulkan. This post is just some
inexperienced programmer's vague description of how he or she would like
things to work in theory. It's not worth a discussion.

~~~
zimorodek
I think the pipelines in this posts mean something different. As Vulkan/Metal
pipelines refer to the GPU rendering pipeline with vertex, fragment shaders,
tesselation etc not a sequence of passes.

------
moron4hire
> This way we can describe that the Camera will have a relation of 1:1 with a
> Render Pipeline.

If all you're making are smartphone games, this might work [1]. But for more
complex scenarios, this sort of thing would be a non-starter. You ideally need
to support N:1, Cameras to Pipelines. Not just for N=2 for VR, but N=3 for
VR+spectator mode, and N=4+ for projection mapping to surfaces as well.

[1] I say "might" because smartphones are getting more powerful and will
probably very soon (as in 2 to 3 years, i.e. about when such a new project
would be usable) be decent VR platforms.

------
adrift
Doesn't this approach incur a lot of cache misses?

~~~
golergka
Why? All these data structures are mostly just handles to the actual data,
which lines in the GPU memory.

------
buzzybee
The concept in this blogpost anticipates a more general architecture. Graphics
pipelines are a good fit for dataflow programming, such as FBP [0] or reactive
[1]. When you use those styles, the pipeline architecture is more flexible,
more straightforward to run concurrently, while the coding challenge turns
into one of how to allocate and address different assets, address different
_types_ of assets, create and address temporary data, and describe the node
graph connecting these things together.

The practical complication in rendering can be stated like this: combine
assets A and B and parameter P to make asset C, then (subsequently) combine
asset C with asset D and parameter J to make output O. Some of the
assets/parameters change with each frame rendered, others are entirely static,
and oversight over GPU time and memory usage is needed, so you have to
consider which things are loaded when. Then, while in production, a design
change necessitates that a new parameter be added somewhere, and it turns out
that you have to reorder which things are processed first and add a custom
codepath because one of your target GPUs doesn't support the feature you need
without a hack.

[0] [https://en.wikipedia.org/wiki/Flow-
based_programming](https://en.wikipedia.org/wiki/Flow-based_programming) [1]
[https://en.wikipedia.org/wiki/Reactive_programming](https://en.wikipedia.org/wiki/Reactive_programming)

~~~
amelius
Why not simply use a software cache (memoization, [1]) to prevent doing things
more often than necessary?

[1]
[https://en.wikipedia.org/wiki/Memoization](https://en.wikipedia.org/wiki/Memoization)

~~~
MaulingMonkey
All kinds of caches are used in graphics programming. The devil is in the
details: Does a generic memoization strategy help you decide when to re-render
a shadowmap based on the updating of entities within range of said shadowmap?
And when you decide technically incorrect, stale results, are still 'good
enough' (based on the duration they've been stale, distance from the camera,
size of the resulting shadows, etc.) how do you represent that? How do you
decide when shadowmaps can been reused between multiple perspectives? How much
can you calculate offline, before the game is even run? If you squint really
hard you might be able to couch some of this in memoization terms - but how,
exactly, is that helping?

Memory is tight - GPU memory might be a few gigs, and your artists _will_ fill
the space. Time is tight - 16ms/frame _max_ if you're targeting a smooth
60fps, and even higher framerates (and tighter time budgets) are recommended
to e.g. reduce nausea for VR. You know exactly how long you need some
resources, they are large (over 100MB for a single set of 4k gbuffers), and
spilling active data out of the cache can be disastrously slow, or lose
necessary information you cannot recreate.

At some point you'll get rather hands on and start micromanaging a lot of this
stuff - it's much simpler to write, debug, and optimize a lot of this if you
implement it 'by hand', than to design, write, debug, and optimize an
algorithm trying to handle a perfectly generic answer/solution to all these
problems.

