+static unsigned
+count_uniform_storage_slots(const struct glsl_type *type)
+{
+ /* gl_uniform_storage can cope with one level of array, so if the
+ * type is a composite type or an array where each element occupies
+ * more than one slot than we need to recursively process it.
+ */
+ if (glsl_type_is_struct(type)) {
+ unsigned location_count = 0;
+
+ for (unsigned i = 0; i < glsl_get_length(type); i++) {
+ const struct glsl_type *field_type = glsl_get_struct_field(type, i);
+
+ location_count += count_uniform_storage_slots(field_type);
+ }
+
+ return location_count;
+ }
+
+ if (glsl_type_is_array(type)) {
+ const struct glsl_type *element_type = glsl_get_array_element(type);
+
+ if (glsl_type_is_array(element_type) ||
+ glsl_type_is_struct(element_type)) {
+ unsigned element_count = count_uniform_storage_slots(element_type);
+ return element_count * glsl_get_length(type);
+ }
+ }
+
+ return 1;
+}
+