diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c index 10a51eb55e7..8c4df26b99a 100644 --- a/src/freedreno/ir3/ir3_compiler_nir.c +++ b/src/freedreno/ir3/ir3_compiler_nir.c @@ -847,6 +847,28 @@ static void emit_intrinsic_ssbo_size(struct ir3_context *ctx, nir_intrinsic_instr *intr, struct ir3_instruction **dst) { + if (ir3_bindless_resource(intr->src[0])) { + struct ir3_block *b = ctx->block; + struct ir3_instruction *ibo = ir3_ssbo_to_ibo(ctx, intr->src[0]); + struct ir3_instruction *resinfo = ir3_RESINFO(b, ibo, 0); + resinfo->cat6.iim_val = 1; + resinfo->cat6.d = 1; + resinfo->cat6.type = TYPE_U32; + resinfo->cat6.typed = false; + /* resinfo has no writemask and always writes out 3 components */ + resinfo->regs[0]->wrmask = MASK(3); + ir3_handle_bindless_cat6(resinfo, intr->src[0]); + struct ir3_instruction *resinfo_dst; + ir3_split_dest(b, &resinfo_dst, resinfo, 0, 1); + /* Unfortunately resinfo returns the array length, i.e. in dwords, + * while NIR expects us to return the size in bytes. + * + * TODO: fix this in NIR. + */ + *dst = ir3_SHL_B(b, resinfo_dst, 0, create_immed(b, 2), 0); + return; + } + /* SSBO size stored as a const starting at ssbo_sizes: */ const struct ir3_const_state *const_state = ir3_const_state(ctx->so); unsigned blk_idx = nir_src_as_uint(intr->src[0]); diff --git a/src/freedreno/ir3/ir3_nir.c b/src/freedreno/ir3/ir3_nir.c index c779a57f7c5..068191a903a 100644 --- a/src/freedreno/ir3/ir3_nir.c +++ b/src/freedreno/ir3/ir3_nir.c @@ -503,6 +503,8 @@ ir3_nir_scan_driver_consts(nir_shader *shader, switch (intr->intrinsic) { case nir_intrinsic_get_buffer_size: + if (ir3_bindless_resource(intr->src[0])) + break; idx = nir_src_as_uint(intr->src[0]); if (layout->ssbo_size.mask & (1 << idx)) break;