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 <jason@jlekstrand.net>
This commit is contained in:
@@ -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:
|
||||
|
@@ -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 = {
|
||||
|
Reference in New Issue
Block a user