case vtn_value_type_ssa:
return val->ssa;
- case vtn_value_type_pointer:
- /* This is needed for function parameters */
- return vtn_variable_load(b, val->pointer);
-
default:
unreachable("Invalid type for an SSA value");
}
vtn_type_copy(struct vtn_builder *b, struct vtn_type *src)
{
struct vtn_type *dest = ralloc(b, struct vtn_type);
- dest->type = src->type;
- dest->is_builtin = src->is_builtin;
- if (src->is_builtin)
- dest->builtin = src->builtin;
-
- if (!glsl_type_is_scalar(src->type)) {
- switch (glsl_get_base_type(src->type)) {
- case GLSL_TYPE_INT:
- case GLSL_TYPE_UINT:
- case GLSL_TYPE_INT64:
- case GLSL_TYPE_UINT64:
- case GLSL_TYPE_BOOL:
- case GLSL_TYPE_FLOAT:
- case GLSL_TYPE_DOUBLE:
- case GLSL_TYPE_ARRAY:
- dest->row_major = src->row_major;
- dest->stride = src->stride;
- dest->array_element = src->array_element;
- break;
+ *dest = *src;
- case GLSL_TYPE_STRUCT: {
- unsigned elems = glsl_get_length(src->type);
+ switch (src->base_type) {
+ case vtn_base_type_void:
+ case vtn_base_type_scalar:
+ case vtn_base_type_vector:
+ case vtn_base_type_matrix:
+ case vtn_base_type_array:
+ case vtn_base_type_pointer:
+ case vtn_base_type_image:
+ case vtn_base_type_sampler:
+ /* Nothing more to do */
+ break;
- dest->members = ralloc_array(b, struct vtn_type *, elems);
- memcpy(dest->members, src->members, elems * sizeof(struct vtn_type *));
+ case vtn_base_type_struct:
+ dest->members = ralloc_array(b, struct vtn_type *, src->length);
+ memcpy(dest->members, src->members,
+ src->length * sizeof(src->members[0]));
- dest->offsets = ralloc_array(b, unsigned, elems);
- memcpy(dest->offsets, src->offsets, elems * sizeof(unsigned));
- break;
- }
+ dest->offsets = ralloc_array(b, unsigned, src->length);
+ memcpy(dest->offsets, src->offsets,
+ src->length * sizeof(src->offsets[0]));
+ break;
- default:
- unreachable("unhandled type");
- }
+ case vtn_base_type_function:
+ dest->params = ralloc_array(b, struct vtn_type *, src->length);
+ memcpy(dest->params, src->params, src->length * sizeof(src->params[0]));
+ break;
}
return dest;
struct vtn_value *val = vtn_push_value(b, w[1], vtn_value_type_type);
val->type = rzalloc(b, struct vtn_type);
- val->type->is_builtin = false;
val->type->val = val;
switch (opcode) {
case SpvOpTypeVoid:
+ val->type->base_type = vtn_base_type_void;
val->type->type = glsl_void_type();
break;
case SpvOpTypeBool:
+ val->type->base_type = vtn_base_type_scalar;
val->type->type = glsl_bool_type();
break;
case SpvOpTypeInt: {
int bit_size = w[2];
const bool signedness = w[3];
+ val->type->base_type = vtn_base_type_scalar;
if (bit_size == 64)
val->type->type = (signedness ? glsl_int64_t_type() : glsl_uint64_t_type());
else
}
case SpvOpTypeFloat: {
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();
break;
}
unsigned elems = w[3];
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);
-
- /* Vectors implicitly have sizeof(base_type) stride. For now, this
- * is always 4 bytes. This will have to change if we want to start
- * supporting doubles or half-floats.
- */
val->type->stride = glsl_get_bit_size(base->type) / 8;
val->type->array_element = base;
break;
unsigned columns = w[3];
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),
glsl_get_vector_elements(base->type),
columns);
assert(!glsl_type_is_error(val->type->type));
+ val->type->length = columns;
val->type->array_element = base;
val->type->row_major = false;
val->type->stride = 0;
struct vtn_type *array_element =
vtn_value(b, w[2], vtn_value_type_type)->type;
- unsigned length;
if (opcode == SpvOpTypeRuntimeArray) {
/* A length of 0 is used to denote unsized arrays */
- length = 0;
+ val->type->length = 0;
} else {
- length =
+ val->type->length =
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->stride = 0;
break;
case SpvOpTypeStruct: {
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->offsets = ralloc_array(b, unsigned, num_fields);
}
case SpvOpTypeFunction: {
- const struct glsl_type *return_type =
- vtn_value(b, w[2], vtn_value_type_type)->type->type;
- NIR_VLA(struct glsl_function_param, params, count - 3);
- for (unsigned i = 0; i < count - 3; i++) {
- params[i].type = vtn_value(b, w[i + 3], vtn_value_type_type)->type->type;
+ val->type->base_type = vtn_base_type_function;
+ val->type->type = NULL;
- /* FIXME: */
- params[i].in = true;
- params[i].out = true;
+ val->type->return_type = vtn_value(b, w[2], vtn_value_type_type)->type;
+
+ const unsigned num_params = count - 3;
+ val->type->length = num_params;
+ val->type->params = ralloc_array(b, struct vtn_type *, num_params);
+ for (unsigned i = 0; i < count - 3; i++) {
+ val->type->params[i] =
+ vtn_value(b, w[i + 3], vtn_value_type_type)->type;
}
- val->type->type = glsl_function_type(return_type, params, count - 3);
break;
}
- case SpvOpTypePointer:
- /* FIXME: For now, we'll just do the really lame thing and return
- * the same type. The validator should ensure that the proper number
- * of dereferences happen
- */
- val->type = vtn_value(b, w[3], vtn_value_type_type)->type;
+ case SpvOpTypePointer: {
+ SpvStorageClass storage_class = w[2];
+ struct vtn_type *deref_type =
+ vtn_value(b, w[3], vtn_value_type_type)->type;
+
+ val->type->base_type = vtn_base_type_pointer;
+ val->type->type = NULL;
+ val->type->storage_class = storage_class;
+ val->type->deref = deref_type;
break;
+ }
case SpvOpTypeImage: {
+ val->type->base_type = vtn_base_type_image;
+
const struct glsl_type *sampled_type =
vtn_value(b, w[2], vtn_value_type_type)->type->type;
val->type->image_format = translate_image_format(format);
if (sampled == 1) {
+ val->type->sampled = true;
val->type->type = glsl_sampler_type(dim, is_shadow, is_array,
glsl_get_base_type(sampled_type));
} else if (sampled == 2) {
assert(!is_shadow);
+ val->type->sampled = false;
val->type->type = glsl_image_type(dim, is_array,
glsl_get_base_type(sampled_type));
} else {
* matters is that it's a sampler type as opposed to an integer type
* so the backend knows what to do.
*/
+ val->type->base_type = vtn_base_type_sampler;
val->type->type = glsl_bare_sampler_type();
break;
{
nir_constant *c = rzalloc(b, nir_constant);
+ /* For pointers and other typeless things, we have to return something but
+ * it doesn't matter what.
+ */
+ if (!type)
+ return c;
+
switch (glsl_get_base_type(type)) {
case GLSL_TYPE_INT:
case GLSL_TYPE_UINT:
intrin->src[2] = nir_src_for_ssa(vtn_ssa_value(b, w[3])->def);
break;
+ case SpvOpAtomicCompareExchange:
case SpvOpAtomicIIncrement:
case SpvOpAtomicIDecrement:
case SpvOpAtomicExchange: