[Mesa-dev] [PATCH] spirv/nir: adjust location assignment for the case of arrays of blocks

Timothy Arceri tarceri at itsqueeze.com
Thu Dec 13 23:54:58 UTC 2018



On 13/12/18 11:11 pm, Alejandro PiƱeiro wrote:
> This is needed due how the types get rearranged after the struct
> splitting.
> 
> So for example, this array of blocks:
> 
>    layout(location = 0) out block {
>      vec4 v;
>      vec3 v2;
>    } x[2];
> 
> Would be splitted on two nir variables with the following types:
>    * vec4 v[2]
>    * vec3 v2[2]
> 
> So we need to take into account the length of the array to avoid
> locations overlaps one with the other.
> ---
> 
> 
> Hi Jason,
> 
> again, sending in advance patches, just in case you are working on the
> same.
> 
> I was able to fix the location overlapping without all those crazy
> ideas about lowering array of blocks into individual blocks, by just
> adjusting the locations as this patch shows.
> 
> FWIW, the resulting locations are equivalent to those that we get with
> GLSL IR, that results on a similar splitting.
> 
> With this change I got the following working:
>     * SPIR-V simple arrays of blocks input/outputs
> 
>     * The arrays of blocks inputs/outputs + interpolator qualifiers
>       test I mentioned to you last week [1] when run its SPIR-V
>       equivalent.
> 
>     * SPIR-V xfb tests using arrays of blocks, where the xfb offset are
>       assigned to all block members.
> 
>     * SPIR-V xfb tests using arrays of blocks, where the xfb offset is
>       assigned to just one member, so just that member is captured,
>       although as many times as the array length (yes! afaiu by spec
>       that needs to work)
> 
> So now, the only pending thing is a cleanup and send the series to
> review. Specifically, I think that this series can be put on top of
> current master instead of the arb_gl_spirv. Will try that and send a
> final series this week or early next week.
> 
> BR
> 
> 
> [1] https://github.com/Igalia/piglit/blob/master/tests/spec/glsl-1.50/execution/interface-block-interpolation-array.shader_test
> 
> 
> 
>   src/compiler/spirv/vtn_variables.c | 14 +++++++++++++-
>   1 file changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c
> index a8f2fdfa534..87386cee42f 100644
> --- a/src/compiler/spirv/vtn_variables.c
> +++ b/src/compiler/spirv/vtn_variables.c
> @@ -1672,6 +1672,14 @@ add_missing_member_locations(struct vtn_variable *var,
>         glsl_get_length(glsl_without_array(var->type->type));
>      int location = var->base_location;
>   
> +   /* To know if it is a interface block we can't ask directly for
> +    * var->type->block because on the case of arrays of blocks, block is set
> +    * on the array_element.
> +    */
> +   bool is_array_block = var->var->interface_type != NULL &&
> +      glsl_type_is_array(var->type->type);
> +   int adjustment = is_array_block ? glsl_get_length(var->type->type) : 1;
> +

I think you probably want to use glsl_get_aoa_size() here instead of 
glsl_get_length() ?

>      for (unsigned i = 0; i < length; i++) {
>         /* From the Vulkan spec:
>          *
> @@ -1702,8 +1710,12 @@ add_missing_member_locations(struct vtn_variable *var,
>         const struct glsl_type *member_type =
>            glsl_get_struct_field(glsl_without_array(var->type->type), i);
>   
> +      /* For arrays of interface blocks we can't just add the attribute slots
> +       * of a member type due how the splitting would rearrange the types, so
> +       * we need to adjust for the array length in that case.
> +       */
>         location +=
> -         glsl_count_attribute_slots(member_type, is_vertex_input);
> +         glsl_count_attribute_slots(member_type, is_vertex_input) * adjustment;
>      }
>   }
>   
> 


More information about the mesa-dev mailing list