ir3_handle_bindless_cat6(resinfo, intr->src[0]);
if (ctx->compiler->gen >= 6) {
- 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);
+ ir3_split_dest(b, dst, resinfo, 0, 1);
} else {
/* On a5xx, resinfo returns the low 16 bits of ssbo size in .x and the high 16 bits in .y */
struct ir3_instruction *resinfo_dst[2];
}
}
+static bool
+ir3_nir_lower_ssbo_size_filter(const nir_instr *instr, const void *data)
+{
+ return instr->type == nir_instr_type_intrinsic &&
+ nir_instr_as_intrinsic(instr)->intrinsic ==
+ nir_intrinsic_get_ssbo_size;
+}
+
+static nir_ssa_def *
+ir3_nir_lower_ssbo_size_instr(nir_builder *b, nir_instr *instr, void *data)
+{
+ nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
+ return nir_ishl(b, &intr->dest.ssa, nir_imm_int(b, 2));
+}
+
+/**
+ * The resinfo opcode we have for getting the SSBO size on a6xx returns a number
+ * of dwords, while the NIR intrinsic coming in is a number of bytes. Switch
+ * things so the NIR intrinsic in our backend means dwords.
+ */
+static bool
+ir3_nir_lower_ssbo_size(nir_shader *s)
+{
+ return nir_shader_lower_instructions(s, ir3_nir_lower_ssbo_size_filter,
+ ir3_nir_lower_ssbo_size_instr, NULL);
+}
+
void
ir3_nir_lower_io_to_temporaries(nir_shader *s)
{
NIR_PASS_V(s, nir_lower_image, &lower_image_opts);
NIR_PASS_V(s, nir_lower_idiv, &idiv_options); /* idiv generated by cube lowering */
+ if (compiler->gen >= 6)
+ OPT_V(s, ir3_nir_lower_ssbo_size);
+
ir3_optimize_loop(compiler, s);
}