diff options
author | Jason Ekstrand <[email protected]> | 2015-04-10 14:46:22 -0700 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2015-04-22 18:10:40 -0700 |
commit | 7e1d21edbff772f6dfc727e0e09788d87e00e0f5 (patch) | |
tree | 17ccb04e9fe35f5ef405a91fd179f461dd03d0f2 /src/glsl/nir/nir.c | |
parent | ba887602022340c596a09534e61b6554e3aeb533 (diff) |
nir: Move get_const_initializer_load from vars_to_ssa to NIR core
Reviewed-by: Connor Abbott <[email protected]>
Diffstat (limited to 'src/glsl/nir/nir.c')
-rw-r--r-- | src/glsl/nir/nir.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/glsl/nir/nir.c b/src/glsl/nir/nir.c index c6e53612b2a..a7ee3613fcf 100644 --- a/src/glsl/nir/nir.c +++ b/src/glsl/nir/nir.c @@ -589,6 +589,66 @@ nir_copy_deref(void *mem_ctx, nir_deref *deref) return NULL; } +/* Returns a load_const instruction that represents the constant + * initializer for the given deref chain. The caller is responsible for + * ensuring that there actually is a constant initializer. + */ +nir_load_const_instr * +nir_deref_get_const_initializer_load(nir_shader *shader, nir_deref_var *deref) +{ + nir_constant *constant = deref->var->constant_initializer; + assert(constant); + + const nir_deref *tail = &deref->deref; + unsigned matrix_offset = 0; + while (tail->child) { + switch (tail->child->deref_type) { + case nir_deref_type_array: { + nir_deref_array *arr = nir_deref_as_array(tail->child); + assert(arr->deref_array_type == nir_deref_array_type_direct); + if (glsl_type_is_matrix(tail->type)) { + assert(arr->deref.child == NULL); + matrix_offset = arr->base_offset; + } else { + constant = constant->elements[arr->base_offset]; + } + break; + } + + case nir_deref_type_struct: { + constant = constant->elements[nir_deref_as_struct(tail->child)->index]; + break; + } + + default: + unreachable("Invalid deref child type"); + } + + tail = tail->child; + } + + nir_load_const_instr *load = + nir_load_const_instr_create(shader, glsl_get_vector_elements(tail->type)); + + matrix_offset *= load->def.num_components; + for (unsigned i = 0; i < load->def.num_components; i++) { + switch (glsl_get_base_type(tail->type)) { + case GLSL_TYPE_FLOAT: + case GLSL_TYPE_INT: + case GLSL_TYPE_UINT: + load->value.u[i] = constant->value.u[matrix_offset + i]; + break; + case GLSL_TYPE_BOOL: + load->value.u[i] = constant->value.b[matrix_offset + i] ? + NIR_TRUE : NIR_FALSE; + break; + default: + unreachable("Invalid immediate type"); + } + } + + return load; +} /** * \name Control flow modification |