diff options
author | Jordan Justen <[email protected]> | 2016-01-11 21:53:35 -0800 |
---|---|---|
committer | Jordan Justen <[email protected]> | 2016-01-13 23:34:45 -0800 |
commit | 8ce2b0e1405b3d6d3590dcd3ce1ac2d04d228ad4 (patch) | |
tree | 3dc81a556675e3f2e2a5426fd3acdb14f9b0ef7e | |
parent | 4507d8a57af7df679fc0e7b56f4441519ff7e3d4 (diff) |
nir/spirv: Add support for ArrayLength op
Signed-off-by: Jordan Justen <[email protected]>
-rw-r--r-- | src/glsl/nir/spirv/spirv_to_nir.c | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/src/glsl/nir/spirv/spirv_to_nir.c b/src/glsl/nir/spirv/spirv_to_nir.c index ca9781d263d..4462c9f5a80 100644 --- a/src/glsl/nir/spirv/spirv_to_nir.c +++ b/src/glsl/nir/spirv/spirv_to_nir.c @@ -2188,8 +2188,39 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode, break; } + case SpvOpArrayLength: { + struct vtn_value *v_deref = vtn_value(b, w[3], vtn_value_type_deref); + struct vtn_type *type = v_deref->deref_type; + const uint32_t offset = type->offsets[w[4]]; + const uint32_t stride = type->members[w[4]]->stride; + nir_deref *n_deref = &v_deref->deref->deref; + nir_ssa_def *index = + get_vulkan_resource_index(b, &n_deref, &type); + nir_intrinsic_instr *instr = + nir_intrinsic_instr_create(b->nb.shader, + nir_intrinsic_get_buffer_size); + instr->src[0] = nir_src_for_ssa(index); + nir_ssa_dest_init(&instr->instr, &instr->dest, 1, NULL); + nir_builder_instr_insert(&b->nb, &instr->instr); + nir_ssa_def *buf_size = &instr->dest.ssa; + + /* array_length = max(buffer_size - offset, 0) / stride */ + nir_ssa_def *array_length = + nir_idiv(&b->nb, + nir_imax(&b->nb, + nir_isub(&b->nb, + buf_size, + nir_imm_int(&b->nb, offset)), + nir_imm_int(&b->nb, 0u)), + nir_imm_int(&b->nb, stride)); + + struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_ssa); + val->ssa = vtn_create_ssa_value(b, glsl_uint_type()); + val->ssa->def = array_length; + break; + } + case SpvOpCopyMemorySized: - case SpvOpArrayLength: default: unreachable("Unhandled opcode"); } |