From: Jason Ekstrand Date: Fri, 24 Jul 2020 15:46:20 +0000 (-0500) Subject: spirv: Do more complex unwrapping in get_nir_type X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=commitdiff_plain;h=4816f6f8d88f4f9004416b8cebccdddbe24ca95b spirv: Do more complex unwrapping in get_nir_type The OpenGL flavor of SPIR-V allows for samplers inside structs. This means that our simple array-of-array handling isn't sufficient and we need something substantially more complex for generating NIR types. Fixes: 14a12b771d0 "spirv: Rework our handling of images and samplers" Reviewed-by: Caio Marcelo de Oliveira Filho Part-of: --- diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index 96c0c0767db..4c621534996 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -787,13 +787,55 @@ vtn_type_get_nir_type(struct vtn_builder *b, struct vtn_type *type, } if (mode == vtn_variable_mode_uniform) { - struct vtn_type *tail = vtn_type_without_array(type); - if (tail->base_type == vtn_base_type_image) { - return wrap_type_in_array(tail->glsl_image, type->type); - } else if (tail->base_type == vtn_base_type_sampler) { - return wrap_type_in_array(glsl_bare_sampler_type(), type->type); - } else if (tail->base_type == vtn_base_type_sampled_image) { - return wrap_type_in_array(tail->image->glsl_image, type->type); + switch (type->base_type) { + case vtn_base_type_array: { + const struct glsl_type *elem_type = + vtn_type_get_nir_type(b, type->array_element, mode); + + return glsl_array_type(elem_type, type->length, + glsl_get_explicit_stride(type->type)); + } + + case vtn_base_type_struct: { + bool need_new_struct = false; + const uint32_t num_fields = type->length; + NIR_VLA(struct glsl_struct_field, fields, num_fields); + for (unsigned i = 0; i < num_fields; i++) { + fields[i] = *glsl_get_struct_field_data(type->type, i); + const struct glsl_type *field_nir_type = + vtn_type_get_nir_type(b, type->members[i], mode); + if (fields[i].type != field_nir_type) { + fields[i].type = field_nir_type; + need_new_struct = true; + } + } + if (need_new_struct) { + if (glsl_type_is_interface(type->type)) { + return glsl_interface_type(fields, num_fields, + /* packing */ 0, false, + glsl_get_type_name(type->type)); + } else { + return glsl_struct_type(fields, num_fields, + glsl_get_type_name(type->type), + glsl_struct_type_is_packed(type->type)); + } + } else { + /* No changes, just pass it on */ + return type->type; + } + } + + case vtn_base_type_image: + return type->glsl_image; + + case vtn_base_type_sampler: + return glsl_bare_sampler_type(); + + case vtn_base_type_sampled_image: + return type->image->glsl_image; + + default: + return type->type; } }