Location and Component Interface
This chapter is an overview of the Location and Component Assignment chapter to help give examples, especially around some of the more extreme edge cases.
The simplest way to think about a Location is that it is made up of four 32-bit Component.
This means a vec4/float4/uvec4/etc will fit perfectly in a single Location.
Multiple variables can be packed into the same Location if their Componens do not overlap.
Locations are used for both the Input and Output to interface between shaders stages when possible.
Advice for general users
For most people, this chapter is much deeper into edge cases compared who developers generally use the Location interface. For those developers, the simple advise to take away is:
-
Use less
Locationif possible. -
If you need many
Location, make sure you are under the limits.
Basic Example
Here is a basic example:
layout(location=0) in vec4 a;
layout(location=1, component = 0) in vec2 b;
layout(location=1, component = 2) in float c;
16-bit
16-bit values always consume a full 32-bit Component. So a vector with 16-bit elements will consume the same resources as a vector with 32-bit elements; they are not tightly packed.
layout(location=0) in f16vec3 a;
Crossing Location Boundaries
All 16-bit and 32-bit vectors must be inside a single Location, so the following is not allowed.
The last two elements would consume component = 4 and component = 5, which do not exist.
layout(location=0, component = 2) in vec4 a;
64-bit
64-bit are special as they can consume up to 2 Location, but they must only start at Component 0 or 2.
layout(location=0) in f64vec3 a;
Interleaving Components
The following attempt to have multiple variables alias the same component is not allowed.
layout(location=0) in vec2 in_a; // Components 0 and 1
layout(location=0, component=1) in float in_f; // Invalid: overlaps component 1
The following modification would make it legal as multiple variable can share a Location, just not a `Component
`
layout(location=0) in vec2 in_a;
// Change in_f to use component 2 instead
- layout(location=0, component=1) in float in_f;
+ layout(location=0, component=2) in float in_f;
Array
An element of an array will consume all every Component in a Location that it would consume as a non-arrayed value, with each subsequent element consuming the next available Location.
For example:
layout(location=0) in float a[3];
As seen, using a scalar or something such as a vec2/float2 will leave many Component slots unused.
It is not allowed to use any other Component in a Location that is being consumed by an array
layout(location=0) in float a[3];
layout(location=2, component=2) in float b;
float b is invalid because the array consumes all of Location 2.
|
Some shader stages, like geometry shaders, have an array around its interface matching, this array is disregarded for the above examples. |
Matrix
A matrix is viewed as an array, which consume all 4 components.
So something like
layout(location = 0) in mat3x2 a;
From a Location/Component point-of-view looks like
// N == 3
// Arrays consume whole Location
layout(location = 0) in vec2 a[3];
As stated above, arrays consume the whole Location so the following is not allowed.
layout(location = 0) in mat3x2 a;
layout(location = 2, component = 2) in float b;
float b is invalid because the implicit array of the matrix consumes all of Location 2.