From: Caio Marcelo de Oliveira Filho Date: Thu, 21 Mar 2019 20:26:48 +0000 (-0700) Subject: spirv: Use interface type for block and buffer block X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9d0ae777dd68dad682dcc7768726996639ae2684;p=mesa.git spirv: Use interface type for block and buffer block Also handle GLSL_TYPE_INTERFACE the same way we do GLSL_TYPE_STRUCT in various places. Motivated by ARB_gl_spirv work, that will take advantage of the interface types when handling NIR coming from SPIR-V. Reviewed-by: Jason Ekstrand --- diff --git a/src/compiler/spirv/spirv_to_nir.c b/src/compiler/spirv/spirv_to_nir.c index 8ae9674fe91..77f49b50563 100644 --- a/src/compiler/spirv/spirv_to_nir.c +++ b/src/compiler/spirv/spirv_to_nir.c @@ -907,6 +907,21 @@ struct_member_matrix_stride_cb(struct vtn_builder *b, ctx->fields[member].type = ctx->type->members[member]->type; } +static void +struct_block_decoration_cb(struct vtn_builder *b, + struct vtn_value *val, int member, + const struct vtn_decoration *dec, void *ctx) +{ + if (member != -1) + return; + + struct vtn_type *type = val->type; + if (dec->decoration == SpvDecorationBlock) + type->block = true; + else if (dec->decoration == SpvDecorationBufferBlock) + type->buffer_block = true; +} + static void type_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member, @@ -928,11 +943,11 @@ type_decoration_cb(struct vtn_builder *b, break; case SpvDecorationBlock: vtn_assert(type->base_type == vtn_base_type_struct); - type->block = true; + vtn_assert(type->block); break; case SpvDecorationBufferBlock: vtn_assert(type->base_type == vtn_base_type_struct); - type->buffer_block = true; + vtn_assert(type->buffer_block); break; case SpvDecorationGLSLShared: case SpvDecorationGLSLPacked: @@ -1291,9 +1306,21 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode, vtn_foreach_decoration(b, val, struct_member_decoration_cb, &ctx); vtn_foreach_decoration(b, val, struct_member_matrix_stride_cb, &ctx); - const char *name = val->name ? val->name : "struct"; + vtn_foreach_decoration(b, val, struct_block_decoration_cb, NULL); - val->type->type = glsl_struct_type(fields, num_fields, name, false); + const char *name = val->name; + + if (val->type->block || val->type->buffer_block) { + /* Packing will be ignored since types coming from SPIR-V are + * explicitly laid out. + */ + val->type->type = glsl_interface_type(fields, num_fields, + /* packing */ 0, false, + name ? name : "block"); + } else { + val->type->type = glsl_struct_type(fields, num_fields, + name ? name : "struct", false); + } break; } @@ -2069,6 +2096,7 @@ vtn_create_ssa_value(struct vtn_builder *b, const struct glsl_type *type) child_type = glsl_get_array_element(type); break; case GLSL_TYPE_STRUCT: + case GLSL_TYPE_INTERFACE: child_type = glsl_get_struct_field(type, i); break; default: diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index 782ad08d321..b121a2c2988 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -490,6 +490,7 @@ vtn_ssa_offset_pointer_dereference(struct vtn_builder *b, break; } + case GLSL_TYPE_INTERFACE: case GLSL_TYPE_STRUCT: { vtn_assert(deref_chain->link[idx].mode == vtn_access_mode_literal); unsigned member = deref_chain->link[idx].id; @@ -934,6 +935,7 @@ _vtn_block_load_store(struct vtn_builder *b, nir_intrinsic_op op, bool load, return; } + case GLSL_TYPE_INTERFACE: case GLSL_TYPE_STRUCT: { unsigned elems = glsl_get_length(type->type); for (unsigned i = 0; i < elems; i++) { @@ -1058,6 +1060,7 @@ _vtn_variable_load_store(struct vtn_builder *b, bool load, } /* Fall through */ + case GLSL_TYPE_INTERFACE: case GLSL_TYPE_ARRAY: case GLSL_TYPE_STRUCT: { unsigned elems = glsl_get_length(ptr->type->type); @@ -1140,6 +1143,7 @@ _vtn_variable_copy(struct vtn_builder *b, struct vtn_pointer *dest, vtn_variable_store(b, vtn_variable_load(b, src), dest); return; + case GLSL_TYPE_INTERFACE: case GLSL_TYPE_ARRAY: case GLSL_TYPE_STRUCT: { struct vtn_access_chain chain = {