nir/spirv: Beef up the type system a bit
This adds a vtn concept of base_type as well as a couple of other fields. This lets us be a tiny bit more efficient in some cases but, more importantly, it will eventually let us express things the GLSL type system can't. Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
This commit is contained in:

committed by
Jason Ekstrand

parent
ad4519696d
commit
96f2439858
@@ -415,34 +415,29 @@ vtn_type_copy(struct vtn_builder *b, struct vtn_type *src)
|
|||||||
struct vtn_type *dest = ralloc(b, struct vtn_type);
|
struct vtn_type *dest = ralloc(b, struct vtn_type);
|
||||||
*dest = *src;
|
*dest = *src;
|
||||||
|
|
||||||
if (!glsl_type_is_scalar(src->type)) {
|
switch (src->base_type) {
|
||||||
switch (glsl_get_base_type(src->type)) {
|
case vtn_base_type_void:
|
||||||
case GLSL_TYPE_INT:
|
case vtn_base_type_scalar:
|
||||||
case GLSL_TYPE_UINT:
|
case vtn_base_type_vector:
|
||||||
case GLSL_TYPE_INT64:
|
case vtn_base_type_matrix:
|
||||||
case GLSL_TYPE_UINT64:
|
case vtn_base_type_array:
|
||||||
case GLSL_TYPE_BOOL:
|
case vtn_base_type_image:
|
||||||
case GLSL_TYPE_FLOAT:
|
case vtn_base_type_sampler:
|
||||||
case GLSL_TYPE_DOUBLE:
|
case vtn_base_type_function:
|
||||||
case GLSL_TYPE_ARRAY:
|
/* Nothing more to do */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GLSL_TYPE_STRUCT: {
|
case vtn_base_type_struct:
|
||||||
unsigned elems = glsl_get_length(src->type);
|
dest->members = ralloc_array(b, struct vtn_type *, src->length);
|
||||||
|
memcpy(dest->members, src->members,
|
||||||
|
src->length * sizeof(src->members[0]));
|
||||||
|
|
||||||
dest->members = ralloc_array(b, struct vtn_type *, elems);
|
dest->offsets = ralloc_array(b, unsigned, src->length);
|
||||||
memcpy(dest->members, src->members, elems * sizeof(struct vtn_type *));
|
memcpy(dest->offsets, src->offsets,
|
||||||
|
src->length * sizeof(src->offsets[0]));
|
||||||
dest->offsets = ralloc_array(b, unsigned, elems);
|
|
||||||
memcpy(dest->offsets, src->offsets, elems * sizeof(unsigned));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
|
||||||
unreachable("unhandled type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -732,14 +727,17 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
|
|||||||
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case SpvOpTypeVoid:
|
case SpvOpTypeVoid:
|
||||||
|
val->type->base_type = vtn_base_type_void;
|
||||||
val->type->type = glsl_void_type();
|
val->type->type = glsl_void_type();
|
||||||
break;
|
break;
|
||||||
case SpvOpTypeBool:
|
case SpvOpTypeBool:
|
||||||
|
val->type->base_type = vtn_base_type_scalar;
|
||||||
val->type->type = glsl_bool_type();
|
val->type->type = glsl_bool_type();
|
||||||
break;
|
break;
|
||||||
case SpvOpTypeInt: {
|
case SpvOpTypeInt: {
|
||||||
int bit_size = w[2];
|
int bit_size = w[2];
|
||||||
const bool signedness = w[3];
|
const bool signedness = w[3];
|
||||||
|
val->type->base_type = vtn_base_type_scalar;
|
||||||
if (bit_size == 64)
|
if (bit_size == 64)
|
||||||
val->type->type = (signedness ? glsl_int64_t_type() : glsl_uint64_t_type());
|
val->type->type = (signedness ? glsl_int64_t_type() : glsl_uint64_t_type());
|
||||||
else
|
else
|
||||||
@@ -748,6 +746,7 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
|
|||||||
}
|
}
|
||||||
case SpvOpTypeFloat: {
|
case SpvOpTypeFloat: {
|
||||||
int bit_size = w[2];
|
int bit_size = w[2];
|
||||||
|
val->type->base_type = vtn_base_type_scalar;
|
||||||
val->type->type = bit_size == 64 ? glsl_double_type() : glsl_float_type();
|
val->type->type = bit_size == 64 ? glsl_double_type() : glsl_float_type();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -757,6 +756,7 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
|
|||||||
unsigned elems = w[3];
|
unsigned elems = w[3];
|
||||||
|
|
||||||
assert(glsl_type_is_scalar(base->type));
|
assert(glsl_type_is_scalar(base->type));
|
||||||
|
val->type->base_type = vtn_base_type_vector;
|
||||||
val->type->type = glsl_vector_type(glsl_get_base_type(base->type), elems);
|
val->type->type = glsl_vector_type(glsl_get_base_type(base->type), elems);
|
||||||
|
|
||||||
/* Vectors implicitly have sizeof(base_type) stride. For now, this
|
/* Vectors implicitly have sizeof(base_type) stride. For now, this
|
||||||
@@ -773,10 +773,12 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
|
|||||||
unsigned columns = w[3];
|
unsigned columns = w[3];
|
||||||
|
|
||||||
assert(glsl_type_is_vector(base->type));
|
assert(glsl_type_is_vector(base->type));
|
||||||
|
val->type->base_type = vtn_base_type_matrix;
|
||||||
val->type->type = glsl_matrix_type(glsl_get_base_type(base->type),
|
val->type->type = glsl_matrix_type(glsl_get_base_type(base->type),
|
||||||
glsl_get_vector_elements(base->type),
|
glsl_get_vector_elements(base->type),
|
||||||
columns);
|
columns);
|
||||||
assert(!glsl_type_is_error(val->type->type));
|
assert(!glsl_type_is_error(val->type->type));
|
||||||
|
val->type->length = columns;
|
||||||
val->type->array_element = base;
|
val->type->array_element = base;
|
||||||
val->type->row_major = false;
|
val->type->row_major = false;
|
||||||
val->type->stride = 0;
|
val->type->stride = 0;
|
||||||
@@ -788,16 +790,16 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
|
|||||||
struct vtn_type *array_element =
|
struct vtn_type *array_element =
|
||||||
vtn_value(b, w[2], vtn_value_type_type)->type;
|
vtn_value(b, w[2], vtn_value_type_type)->type;
|
||||||
|
|
||||||
unsigned length;
|
|
||||||
if (opcode == SpvOpTypeRuntimeArray) {
|
if (opcode == SpvOpTypeRuntimeArray) {
|
||||||
/* A length of 0 is used to denote unsized arrays */
|
/* A length of 0 is used to denote unsized arrays */
|
||||||
length = 0;
|
val->type->length = 0;
|
||||||
} else {
|
} else {
|
||||||
length =
|
val->type->length =
|
||||||
vtn_value(b, w[3], vtn_value_type_constant)->constant->values[0].u32[0];
|
vtn_value(b, w[3], vtn_value_type_constant)->constant->values[0].u32[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
val->type->type = glsl_array_type(array_element->type, length);
|
val->type->base_type = vtn_base_type_array;
|
||||||
|
val->type->type = glsl_array_type(array_element->type, val->type->length);
|
||||||
val->type->array_element = array_element;
|
val->type->array_element = array_element;
|
||||||
val->type->stride = 0;
|
val->type->stride = 0;
|
||||||
break;
|
break;
|
||||||
@@ -805,6 +807,8 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
|
|||||||
|
|
||||||
case SpvOpTypeStruct: {
|
case SpvOpTypeStruct: {
|
||||||
unsigned num_fields = count - 2;
|
unsigned num_fields = count - 2;
|
||||||
|
val->type->base_type = vtn_base_type_struct;
|
||||||
|
val->type->length = num_fields;
|
||||||
val->type->members = ralloc_array(b, struct vtn_type *, num_fields);
|
val->type->members = ralloc_array(b, struct vtn_type *, num_fields);
|
||||||
val->type->offsets = ralloc_array(b, unsigned, num_fields);
|
val->type->offsets = ralloc_array(b, unsigned, num_fields);
|
||||||
|
|
||||||
@@ -835,6 +839,8 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SpvOpTypeFunction: {
|
case SpvOpTypeFunction: {
|
||||||
|
val->type->base_type = vtn_base_type_function;
|
||||||
|
|
||||||
const struct glsl_type *return_type =
|
const struct glsl_type *return_type =
|
||||||
vtn_value(b, w[2], vtn_value_type_type)->type->type;
|
vtn_value(b, w[2], vtn_value_type_type)->type->type;
|
||||||
NIR_VLA(struct glsl_function_param, params, count - 3);
|
NIR_VLA(struct glsl_function_param, params, count - 3);
|
||||||
@@ -858,6 +864,8 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SpvOpTypeImage: {
|
case SpvOpTypeImage: {
|
||||||
|
val->type->base_type = vtn_base_type_image;
|
||||||
|
|
||||||
const struct glsl_type *sampled_type =
|
const struct glsl_type *sampled_type =
|
||||||
vtn_value(b, w[2], vtn_value_type_type)->type->type;
|
vtn_value(b, w[2], vtn_value_type_type)->type->type;
|
||||||
|
|
||||||
@@ -899,10 +907,12 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
|
|||||||
val->type->image_format = translate_image_format(format);
|
val->type->image_format = translate_image_format(format);
|
||||||
|
|
||||||
if (sampled == 1) {
|
if (sampled == 1) {
|
||||||
|
val->type->sampled = true;
|
||||||
val->type->type = glsl_sampler_type(dim, is_shadow, is_array,
|
val->type->type = glsl_sampler_type(dim, is_shadow, is_array,
|
||||||
glsl_get_base_type(sampled_type));
|
glsl_get_base_type(sampled_type));
|
||||||
} else if (sampled == 2) {
|
} else if (sampled == 2) {
|
||||||
assert(!is_shadow);
|
assert(!is_shadow);
|
||||||
|
val->type->sampled = false;
|
||||||
val->type->type = glsl_image_type(dim, is_array,
|
val->type->type = glsl_image_type(dim, is_array,
|
||||||
glsl_get_base_type(sampled_type));
|
glsl_get_base_type(sampled_type));
|
||||||
} else {
|
} else {
|
||||||
@@ -921,6 +931,7 @@ vtn_handle_type(struct vtn_builder *b, SpvOp opcode,
|
|||||||
* matters is that it's a sampler type as opposed to an integer type
|
* matters is that it's a sampler type as opposed to an integer type
|
||||||
* so the backend knows what to do.
|
* so the backend knows what to do.
|
||||||
*/
|
*/
|
||||||
|
val->type->base_type = vtn_base_type_sampler;
|
||||||
val->type->type = glsl_bare_sampler_type();
|
val->type->type = glsl_bare_sampler_type();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@@ -196,12 +196,29 @@ struct vtn_ssa_value {
|
|||||||
const struct glsl_type *type;
|
const struct glsl_type *type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum vtn_base_type {
|
||||||
|
vtn_base_type_void,
|
||||||
|
vtn_base_type_scalar,
|
||||||
|
vtn_base_type_vector,
|
||||||
|
vtn_base_type_matrix,
|
||||||
|
vtn_base_type_array,
|
||||||
|
vtn_base_type_struct,
|
||||||
|
vtn_base_type_image,
|
||||||
|
vtn_base_type_sampler,
|
||||||
|
vtn_base_type_function,
|
||||||
|
};
|
||||||
|
|
||||||
struct vtn_type {
|
struct vtn_type {
|
||||||
|
enum vtn_base_type base_type;
|
||||||
|
|
||||||
const struct glsl_type *type;
|
const struct glsl_type *type;
|
||||||
|
|
||||||
/* The value that declares this type. Used for finding decorations */
|
/* The value that declares this type. Used for finding decorations */
|
||||||
struct vtn_value *val;
|
struct vtn_value *val;
|
||||||
|
|
||||||
|
/* Specifies the length of complex types. */
|
||||||
|
unsigned length;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
/* Members for scalar, vector, and array-like types */
|
/* Members for scalar, vector, and array-like types */
|
||||||
struct {
|
struct {
|
||||||
@@ -245,6 +262,9 @@ struct vtn_type {
|
|||||||
|
|
||||||
/* Members for image types */
|
/* Members for image types */
|
||||||
struct {
|
struct {
|
||||||
|
/* For images, indicates whether it's sampled or storage */
|
||||||
|
bool sampled;
|
||||||
|
|
||||||
/* Image format for image_load_store type images */
|
/* Image format for image_load_store type images */
|
||||||
unsigned image_format;
|
unsigned image_format;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user