[Mesa-dev] [PATCH] nir/xfb: Properly align 64-bit values
apinheiro
apinheiro at igalia.com
Wed Feb 13 14:03:40 UTC 2019
I vaguely remember glslang doing something similar when computing
offsets. This, and other xfb corner cases, were the reason I
thought/concluded it would made sense to let glslang (or any other
frontend) to do the offset assignment also for structs, so SPIR-V
consuming drivers didn't need to handle all that mess, and could just
expect to everything having his offset/stride assigned. In any case, we
also found that doing that can be problematic, and Im just rambling...
The patch LGTM:
Reviewed-by: Alejandro Piñeiro <apinheiro at igalia.com>
On 12/2/19 20:22, Jason Ekstrand wrote:
> Fixes: 19064b8c "nir: Add a pass for gathering transform feedback info"
> Cc: Alejandro Piñeiro <apinheiro at igalia.com>
> ---
> src/compiler/nir/nir_gather_xfb_info.c | 44 ++++++++++++++++++++++++++
> 1 file changed, 44 insertions(+)
>
> diff --git a/src/compiler/nir/nir_gather_xfb_info.c b/src/compiler/nir/nir_gather_xfb_info.c
> index 96f0ece5e75..fb736dfeb17 100644
> --- a/src/compiler/nir/nir_gather_xfb_info.c
> +++ b/src/compiler/nir/nir_gather_xfb_info.c
> @@ -72,6 +72,50 @@ add_var_xfb_outputs(nir_xfb_info *xfb,
> assert(var->data.location_frac + comp_slots <= 8);
> uint8_t comp_mask = ((1 << comp_slots) - 1) << var->data.location_frac;
>
> + /* From version 4.60 of the GLSL spec:
> + *
> + * "Variables and block members qualified with xfb_offset can be
> + * scalars, vectors, matrices, structures, and (sized) arrays of
> + * these. The offset must be a multiple of the size of the first
> + * component of the first qualified variable or block member, or a
> + * compile-time error results. Further, if applied to an aggregate
> + * containing a double, the offset must also be a multiple of 8, and
> + * the space taken in the buffer will be a multiple of 8. The given
> + * offset applies to the first component of the first member of the
> + * qualified entity. Then, within the qualified entity, subsequent
> + * components are each assigned, in order, to the next available
> + * offset aligned to a multiple of that component's size. Aggregate
> + * types are flattened down to the component level to get this
> + * sequence of components."
> + *
> + * We need to align each element to the component size in order to get
> + * the correct layout. We do this at the component level and don't try
> + * to align entire aggregate types such as structs because of the last
> + * sentence which says that aggregate types are treated as flattened to
> + * components. In other words, if we have
> + *
> + * struct A {
> + * int a;
> + * double b;
> + * };
> + *
> + * struct B {
> + * int b
> + * A a;
> + * };
> + *
> + * layout (...) out B o;
> + *
> + * then we treat it as if struct A was embedded struct B and o.a.b has
> + * an offset of 8. If we tried to apply the alignment rule to nested
> + * structs and didn't flatten, o.a would have an offset of 8 because it
> + * contains a double and o.a.b would then have an offset of 16.
> + * However, thanks to the above GLSL rule, o.b and o.a.a are tightly
> + * packed and there is no gap.
> + */
> + if (glsl_type_is_64bit(type))
> + *offset = ALIGN_POT(*offset, 8);
> +
> assert(attrib_slots <= 2);
> for (unsigned s = 0; s < attrib_slots; s++) {
> nir_xfb_output_info *output = &xfb->outputs[xfb->output_count++];
More information about the mesa-dev
mailing list