## Structure Layout in WGSL
<!--
How to expose layout control of host-shareable structures in WGSL.
Relevant issues:
  - https://github.com/gpuweb/gpuweb/issues/166 - initial
  - https://github.com/gpuweb/gpuweb/issues/561 - offsets
  - https://github.com/gpuweb/gpuweb/issues/621 - layout
  - https://github.com/gpuweb/gpuweb/pull/1339 - spans
Supplementary materials:
  - https://github.com/microsoft/DirectXShaderCompiler/wiki/Buffer-Packing
  - https://www.khronos.org/opengl/wiki/Interface_Block_(GLSL) (Memory Layout)

Background:
Uniform buffers have more strict alignment requirements than storage buffers.
SPIR-V requires each struct member to be decorated with an "offset" qualifier.
GLSL requires the structs to be decorated with "std140", "std430", or other layouts.
-->

[Offset decorations]: We need to have a separate "offset" decorator on each member.
  - <Verbose>: sprinkling offsets is mostly mechanical, but still tedious. Each offset
    depends on the type of the current field as well as the previous offset.

<!-- What about offsets being explicit? It's not obvious that this actually makes thing simpler.
You'd still need the offsets from both sides, and to compare them. --!>

[Span decorations]: We need to have a "span" decorator on the fields with types that
  occupy more space in the texture than the type size is.
  - <Context>: it's easy to miss the fact that a span of a field actually depends on
    the type of the next field, since a type dictates the alignment.

<Automation>: given knowledge of where a structure is used (uniform vs storage buffers),
  figuring out the structure layout is mechanical. We shouldn't require the user to do
  this by hand if we are going to be computing it ourselves.
  +> [Span decorations]
  +> [Layout decoration]

<Padding>: if the user needs extra padding, they can insert it themselves.
  Most users don't need extra padding, so inventing language tools to address this need
  is too heavy-handed.
  +> <Automation>
  + <Rich types>: Where necessary, we can introduce the types with different layout.
    For example, a `vec3w` would take as much space as `vec4`.

[Layout decoration]: We just need a decoration on the struct itself. Based on the layout,
  we can compute the layout of the fields.
  + <Easy validation>: once you see a structure with a concrete layout, it's clear
    whether this structure can be used in uniform or storage buffers.

<!-- What about proliferation of different layout types, e.g. "relaxed" and "scalar"?
My understanding is that if we add any of those, we'd still have to specify what requirements
they have on spans/offsets, so the constraints are in place. The question becomes more of
whether the constraints are explicit or implicit. --!>

[Unified layout]: We should define one and only layout enforced in all host-shareable structs.
  - <Storage>: Storage buffers can use a more tight layout, and for many users this makes
    a solid difference in performance.
Argument Map cluster_1 Structure Layout in WGSL n0 Offset decorations We need to have a separate "offset" decorator on each member. n1 Span decorations We need to have a "span" decorator on the fields with types that occupy more space in the texture than the type size is. n2 Layout decoration We just need a decoration on the struct itself. Based on the layout, we can compute the layout of the fields. n3 Unified layout We should define one and only layout enforced in all host-shareable structs. n4 Verbose sprinkling offsets is mostly mechanical, but still tedious. Each offset depends on the type of the current field as well as the previous offset. n4->n0 n5 Context it's easy to miss the fact that a span of a field actually depends on the type of the next field, since a type dictates the alignment. n5->n1 n6 Automation given knowledge of where a structure is used (uniform vs storage buffers), figuring out the structure layout is mechanical. We shouldn't require the user to do this by hand if we are going to be computing it ourselves. n6->n1 n6->n2 n7 Padding if the user needs extra padding, they can insert it themselves. Most users don't need extra padding, so inventing language tools to address this need is too heavy-handed. n7->n6 n8 Rich types Where necessary, we can introduce the types with different layout. For example, a `vec3w` would take as much space as `vec4`. n8->n7 n9 Easy validation once you see a structure with a concrete layout, it's clear whether this structure can be used in uniform or storage buffers. n9->n2 n10 Storage Storage buffers can use a more tight layout, and for many users this makes a solid difference in performance. n10->n3