diff options
author | Jason Ekstrand <[email protected]> | 2015-04-29 18:14:11 -0700 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2015-05-16 11:16:32 -0700 |
commit | b2db85d8e4593f7b13e4550159f1d940d9d87a80 (patch) | |
tree | 0a62c7fa80c8c252ba73ff2b7a08bf381eb12dd6 /src | |
parent | 3f83579664b5ff9ec292fb94da6b3bb8b949868b (diff) |
nir/spirv: Add support for constants
Diffstat (limited to 'src')
-rw-r--r-- | src/glsl/nir/spirv_to_nir.c | 68 |
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 |