"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;
}
const struct spirv_to_nir_options spirv_options = {
.environment = NIR_SPIRV_OPENGL,
.frag_coord_is_sysval = ctx->Const.GLSLFragCoordIsSysVal,
+ .use_deref_buffer_array_length = true,
.caps = ctx->Const.SpirVCapabilities,
.ubo_addr_format = nir_address_format_32bit_index_offset,
.ssbo_addr_format = nir_address_format_32bit_index_offset,