diff options
Diffstat (limited to 'src/compiler/spirv/vtn_variables.c')
-rw-r--r-- | src/compiler/spirv/vtn_variables.c | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index 4cb1832d404..6cccb540090 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -2449,30 +2449,46 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode, "OpArrayLength must reference the last memeber of the " "structure and that must be an array"); - const uint32_t offset = ptr->type->offsets[field]; - const uint32_t stride = ptr->type->members[field]->stride; - - if (!ptr->block_index) { + if (b->options->use_deref_buffer_array_length) { struct vtn_access_chain chain = { - .length = 0, + .length = 1, + .link = { + { .mode = vtn_access_mode_literal, .id = field }, + } }; - ptr = vtn_pointer_dereference(b, ptr, &chain); - vtn_assert(ptr->block_index); - } + struct vtn_pointer *array = vtn_pointer_dereference(b, ptr, &chain); - nir_ssa_def *buf_size = nir_get_ssbo_size(&b->nb, ptr->block_index); + nir_ssa_def *array_length = + nir_build_deref_buffer_array_length(&b->nb, 32, + vtn_pointer_to_ssa(b, array)); - /* 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)); + vtn_push_nir_ssa(b, w[2], array_length); + } else { + const uint32_t offset = ptr->type->offsets[field]; + const uint32_t stride = ptr->type->members[field]->stride; + + if (!ptr->block_index) { + struct vtn_access_chain chain = { + .length = 0, + }; + ptr = vtn_pointer_dereference(b, ptr, &chain); + vtn_assert(ptr->block_index); + } + + nir_ssa_def *buf_size = nir_get_ssbo_size(&b->nb, ptr->block_index); - vtn_push_nir_ssa(b, w[2], array_length); + /* 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)); + + vtn_push_nir_ssa(b, w[2], array_length); + } break; } |