summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2015-04-29 18:14:11 -0700
committerJason Ekstrand <[email protected]>2015-05-16 11:16:32 -0700
commitb2db85d8e4593f7b13e4550159f1d940d9d87a80 (patch)
tree0a62c7fa80c8c252ba73ff2b7a08bf381eb12dd6 /src
parent3f83579664b5ff9ec292fb94da6b3bb8b949868b (diff)
nir/spirv: Add support for constants
Diffstat (limited to 'src')
-rw-r--r--src/glsl/nir/spirv_to_nir.c68
1 files changed, 67 insertions, 1 deletions
diff --git a/src/glsl/nir/spirv_to_nir.c b/src/glsl/nir/spirv_to_nir.c
index da85abebe15..1e4c4439883 100644
--- a/src/glsl/nir/spirv_to_nir.c
+++ b/src/glsl/nir/spirv_to_nir.c
@@ -37,6 +37,7 @@ enum vtn_value_type {
vtn_value_type_string,
vtn_value_type_decoration_group,
vtn_value_type_type,
+ vtn_value_type_constant,
vtn_value_type_ssa,
vtn_value_type_deref,
};
@@ -49,6 +50,7 @@ struct vtn_value {
void *ptr;
char *str;
const struct glsl_type *type;
+ nir_constant *constant;
nir_ssa_def *ssa;
nir_deref_var *deref;
};
@@ -84,6 +86,15 @@ vtn_push_value(struct vtn_builder *b, uint32_t value_id,
return &b->values[value_id];
}
+static struct vtn_value *
+vtn_value(struct vtn_builder *b, uint32_t value_id,
+ enum vtn_value_type value_type)
+{
+ assert(value_id < b->value_id_bound);
+ assert(b->values[value_id].value_type == value_type);
+ return &b->values[value_id];
+}
+
static char *
vtn_string_literal(struct vtn_builder *b, const uint32_t *words,
unsigned word_count)
@@ -275,7 +286,62 @@ static void
vtn_handle_constant(struct vtn_builder *b, SpvOp opcode,
const uint32_t *w, unsigned count)
{
- unreachable("Unhandled opcode");
+ const struct glsl_type *type = vtn_value(b, w[1], vtn_value_type_type)->type;
+ nir_constant *constant = ralloc(b, nir_constant);
+ switch (opcode) {
+ case SpvOpConstantTrue:
+ assert(type == glsl_bool_type());
+ constant->value.u[0] = NIR_TRUE;
+ break;
+ case SpvOpConstantFalse:
+ assert(type == glsl_bool_type());
+ constant->value.u[0] = NIR_FALSE;
+ break;
+ case SpvOpConstant:
+ assert(glsl_type_is_scalar(type));
+ constant->value.u[0] = w[3];
+ break;
+ case SpvOpConstantComposite: {
+ unsigned elem_count = count - 3;
+ nir_constant **elems = ralloc_array(b, nir_constant *, elem_count);
+ for (unsigned i = 0; i < elem_count; i++)
+ elems[i] = vtn_value(b, w[i + 3], vtn_value_type_constant)->constant;
+
+ switch (glsl_get_base_type(type)) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_FLOAT:
+ case GLSL_TYPE_BOOL:
+ if (glsl_type_is_matrix(type)) {
+ unsigned rows = glsl_get_vector_elements(type);
+ assert(glsl_get_matrix_columns(type) == elem_count);
+ for (unsigned i = 0; i < elem_count; i++)
+ for (unsigned j = 0; j < rows; j++)
+ constant->value.u[rows * i + j] = elems[i]->value.u[j];
+ } else {
+ assert(glsl_type_is_vector(type));
+ assert(glsl_get_vector_elements(type) == elem_count);
+ for (unsigned i = 0; i < elem_count; i++)
+ constant->value.u[i] = elems[i]->value.u[0];
+ }
+ ralloc_free(elems);
+ break;
+
+ case GLSL_TYPE_STRUCT:
+ case GLSL_TYPE_ARRAY:
+ constant->elements = elems;
+ break;
+
+ default:
+ unreachable("Unsupported type for constants");
+ }
+ break;
+ }
+
+ default:
+ unreachable("Unhandled opcode");
+ }
+ vtn_push_value(b, w[2], vtn_value_type_constant)->constant = constant;
}
static void