Module luminance::pipeline[][src]

Expand description

Graphics pipelines.

Graphics pipelines are the means used to describe — and hence perform — renders. They provide a way to describe how resources should be shared and used to produce a single pixel frame.

Pipelines and graphs

luminance has a very particular way of doing graphics. It represents a typical graphics pipeline via a typed graph that is embedded into your code. Graphs are used to create a dependency between resources your GPU needs to have in order to perform a render. It might be weird at first but you’ll see how simple and easy it actually is. If you want to perform a simple draw call of a triangle, you need several resources:

  • A Tess that represents the triangle — assuming you don’t cheat with an attributeless render ;). It holds three vertices.
  • A shader Program, for shading the triangle with a constant color, for short and simple.
  • A Framebuffer, to accept and hold the actual render.
  • A RenderState, to state how the render should be performed.
  • And finally, a PipelineState, which allows even more customization on how the pipeline runs.

The terminology used in luminance is as follows: a graphics pipeline is a graph in which nodes are called gates. A gate represents a particular resource exposed as a shared scarce resource for child, nested nodes. For instance, you can share framebuffer in a PipelineGate: all nodes that are children of that framebuffer node will then be able to render into that framebuffer.

This design is well-typed: when you enter a given gate, the set of operations and children nodes you can create is directly dependent on the parent node.

PipelineGate and Pipeline

A PipelineGate is the gate allowing to share a Framebuffer.

A PipelineGate represents a whole graphics pipeline as seen as just above. It is created by a GraphicsContext when you ask to create a pipeline gate. A PipelineGate is typically destroyed at the end of the current frame, but that’s not a general rule.

Such an object gives you access, via the PipelineGate::pipeline, to two other objects:

A Pipeline is a special object you can use to handle some specific scarce resources, such as textures and _shader data. Those are treated a bit specifically on the backend, so you have to use the Pipeline interface to deal with them. Those scarce resources can be shared at different depth in the graphics pipeline, which is the reason why they are exposed via this Pipeline object, that you can pass down the graph.

Creating a PipelineGate requires two resources: a Framebuffer to render to, and a PipelineState, allowing to customize how the pipeline will perform renders at runtime. This gate will then do a couple of things on the backend, depending mainly on the PipelineState you pass. For instance, framebuffer clearing, sRGB conversion or scissor test is done at that level.

ShadingGate

A ShadingGate is the gate allowing to share a shader Program.

When you enter a PipelineGate, you’re handed a ShadingGate. A ShadingGate is an object that allows you to create shader nodes in the graphics pipeline. You have no other way to go deeper in the graph.

A shader Program is typically an object you create at initialization or at specific moment in time (i.e. you don’t create them on each frame, that would be super costly) that tells the GPU how vertices should be transformed; how primitives should be moved and generated, how tessellation occurs and how fragment (i.e. pixels) are computed / shaded — hence the name.

At that level (i.e. in that closure), you are given three objects:

The ProgramInterface is the only way for you to access your uniform interface. More on this in the dedicated section. It also provides you with the ProgramInterface::query method, that allows you to perform dynamic uniform lookup.

Once you have entered this gate, you know that everything nested will be shaded with the shared shader Program.

RenderGate

A RenderGate is the gate allowing to prepare renders by sharing RenderState.

A RenderGate is the second to last gate you will be handling. It allows you to create render state nodes in your graph, creating a new level for you to render tessellations with an obvious, final gate: the TessGate.

The kind of object that node manipulates is RenderState. A RenderState — a bit like for PipelineGate with PipelineState — enables to customize how a render of a specific set of objects (i.e. tessellations) will occur. It’s a bit more specific to renders than pipelines and will allow customizing aspects like blending, depth test, backface culling, etc.

TessGate

A TessGate is the final gate, allowing to share Tess.

The TessGate is the final gate you use in a graphics pipeline. It’s used to create tessellation nodes. Those are used to render actual Tess. You cannot go any deeper in the graph at that stage.

TessGates don’t immediately use Tess as inputs. They use TessView. That type is a simple immutable view into a Tess. It can be obtained from a Tess via the View trait or built explicitly.

Structs

A GPU pipeline handle.

Top-most node in a graphics pipeline.

Various customization options for pipelines.

Output of a PipelineGate.

Opaque shader data binding.

Opaque texture binding.

Enums

Possible errors that might occur in a graphics Pipeline.

The viewport being part of the PipelineState.