diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index 7ce110947c3..da4d8d76b8e 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -3564,26 +3564,39 @@ is_residency_code(nir_def *src) } } +static bool +lower_sparse_and_instr(nir_builder *b, nir_intrinsic_instr *instr, void *data) +{ + if (instr->intrinsic != nir_intrinsic_sparse_residency_code_and) + return false; + + b->cursor = nir_before_instr(&instr->instr); + nir_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_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_def *def = nir_iand(b, src0, src1); + nir_def_rewrite_uses_after(&instr->def, def, &instr->instr); + nir_instr_remove(&instr->instr); + return true; +} + +static bool +lower_sparse_and(nir_shader *shader) +{ + return nir_shader_intrinsics_pass(shader, lower_sparse_and_instr, + nir_metadata_dominance, NULL); +} + static bool lower_sparse_instr(nir_builder *b, nir_intrinsic_instr *instr, void *data) { - if (instr->intrinsic == nir_intrinsic_sparse_residency_code_and) { - b->cursor = nir_before_instr(&instr->instr); - nir_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_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_def *def = nir_iand(b, src0, src1); - nir_def_rewrite_uses_after(&instr->def, def, &instr->instr); - nir_instr_remove(&instr->instr); - return true; - } if (instr->intrinsic != nir_intrinsic_is_sparse_texels_resident) return false; @@ -5475,6 +5488,7 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir) NIR_PASS_V(nir, lower_basevertex); NIR_PASS_V(nir, lower_baseinstance); + NIR_PASS_V(nir, lower_sparse_and); NIR_PASS_V(nir, split_bitfields); NIR_PASS_V(nir, nir_lower_frexp); /* TODO: Use the spirv instructions for this. */