From e95b9ac9a8a9591fb9dd29b0db9ca2b6a10962a7 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Tue, 17 May 2022 13:37:10 -0400 Subject: [PATCH] zink: handle nir_intrinsic_sparse_residency_code_and mechanics without glsl array lowering, this intrinsic can creep in for tg4 ops, which complicates everything. instead, rewrite these ops as residency+iand, and then rewrite the existing residency ops to match v2 (idr): Add missing size parameter to nir_is_sparse_texels_resident calls. Reviewed-by: Ian Romanick Part-of: --- src/gallium/drivers/zink/zink_compiler.c | 64 ++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index 52e6ad94101..1aabcc87a55 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -2821,12 +2821,47 @@ scan_nir(struct zink_screen *screen, nir_shader *shader, struct zink_shader *zs) } } +static bool +is_residency_code(nir_ssa_def *src) +{ + nir_instr *parent = src->parent_instr; + while (1) { + if (parent->type == nir_instr_type_intrinsic) { + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(parent); + assert(intr->intrinsic == nir_intrinsic_is_sparse_texels_resident); + return false; + } + if (parent->type == nir_instr_type_tex) + return true; + assert(parent->type == nir_instr_type_alu); + nir_alu_instr *alu = nir_instr_as_alu(parent); + parent = alu->src[0].src.ssa->parent_instr; + } +} + static bool lower_sparse_instr(nir_builder *b, nir_instr *in, void *data) { if (in->type != nir_instr_type_intrinsic) return false; nir_intrinsic_instr *instr = nir_instr_as_intrinsic(in); + if (instr->intrinsic == nir_intrinsic_sparse_residency_code_and) { + b->cursor = nir_before_instr(&instr->instr); + nir_ssa_def *src0; + if (is_residency_code(instr->src[0].ssa)) + src0 = nir_is_sparse_texels_resident(b, 1, instr->src[0].ssa); + else + src0 = instr->src[0].ssa; + nir_ssa_def *src1; + if (is_residency_code(instr->src[1].ssa)) + src1 = nir_is_sparse_texels_resident(b, 1, instr->src[1].ssa); + else + src1 = instr->src[1].ssa; + nir_ssa_def *def = nir_iand(b, src0, src1); + nir_ssa_def_rewrite_uses_after(&instr->dest.ssa, def, in); + nir_instr_remove(in); + return true; + } if (instr->intrinsic != nir_intrinsic_is_sparse_texels_resident) return false; @@ -2836,10 +2871,31 @@ lower_sparse_instr(nir_builder *b, nir_instr *in, void *data) */ b->cursor = nir_before_instr(&instr->instr); nir_instr *parent = instr->src[0].ssa->parent_instr; - assert(parent->type == nir_instr_type_alu); - nir_alu_instr *alu = nir_instr_as_alu(parent); - nir_ssa_def_rewrite_uses_after(instr->src[0].ssa, nir_channel(b, alu->src[0].src.ssa, 0), parent); - nir_instr_remove(parent); + if (is_residency_code(instr->src[0].ssa)) { + assert(parent->type == nir_instr_type_alu); + nir_alu_instr *alu = nir_instr_as_alu(parent); + nir_ssa_def_rewrite_uses_after(instr->src[0].ssa, nir_channel(b, alu->src[0].src.ssa, 0), parent); + nir_instr_remove(parent); + } else { + nir_ssa_def *src; + if (parent->type == nir_instr_type_intrinsic) { + nir_intrinsic_instr *intr = nir_instr_as_intrinsic(parent); + assert(intr->intrinsic == nir_intrinsic_is_sparse_texels_resident); + src = intr->src[0].ssa; + } else { + assert(parent->type == nir_instr_type_alu); + nir_alu_instr *alu = nir_instr_as_alu(parent); + src = alu->src[0].src.ssa; + } + if (instr->dest.ssa.bit_size != 32) { + if (instr->dest.ssa.bit_size == 1) + src = nir_ieq_imm(b, src, 1); + else + src = nir_u2uN(b, src, instr->dest.ssa.bit_size); + } + nir_ssa_def_rewrite_uses(&instr->dest.ssa, src); + nir_instr_remove(in); + } return true; }