diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py index d40e02260eb..660fb3c850e 100644 --- a/src/compiler/nir/nir_intrinsics.py +++ b/src/compiler/nir/nir_intrinsics.py @@ -1548,8 +1548,11 @@ intrinsic("load_frag_coord_zw_pan", [2], dest_comp=1, indices=[COMPONENT], flags # src[] = { sampler_index } load("sampler_lod_parameters_pan", [1], flags=[CAN_ELIMINATE, CAN_REORDER]) -# Like load_output but using a specified render target conversion descriptor -load("converted_output_pan", [1], indices=[DEST_TYPE, IO_SEMANTICS], flags=[CAN_ELIMINATE]) +# Like load_output but using a specified render target and conversion descriptor +# src[] = { target, conversion } +# target must be in the [0..7] range when io_semantics.location is FRAG_RESULT_DATA0 +# and is ignored otherwise +load("converted_output_pan", [1, 1], indices=[DEST_TYPE, IO_SEMANTICS], flags=[CAN_ELIMINATE]) # Load the render target conversion descriptor for a given render target given # in the BASE index. Converts to a type with size given by the source type. diff --git a/src/panfrost/compiler/bifrost_compile.c b/src/panfrost/compiler/bifrost_compile.c index c3ce16d3481..dbc74270546 100644 --- a/src/panfrost/compiler/bifrost_compile.c +++ b/src/panfrost/compiler/bifrost_compile.c @@ -1797,18 +1797,33 @@ bi_emit_ld_tile(bi_builder *b, nir_intrinsic_instr *instr) { bi_index dest = bi_def_index(&instr->def); nir_alu_type T = nir_intrinsic_dest_type(instr); + nir_io_semantics sem = nir_intrinsic_io_semantics(instr); + bool is_zs = + sem.location == FRAG_RESULT_DEPTH || sem.location == FRAG_RESULT_STENCIL; enum bi_register_format regfmt = bi_reg_fmt_for_nir(T); unsigned size = instr->def.bit_size; unsigned nr = instr->num_components; + unsigned target = 0; - /* Get the render target */ - nir_io_semantics sem = nir_intrinsic_io_semantics(instr); - unsigned loc = sem.location; - assert(loc >= FRAG_RESULT_DATA0); - unsigned rt = (loc - FRAG_RESULT_DATA0); + if (sem.location == FRAG_RESULT_DEPTH) { + target = 255; + } else if (sem.location == FRAG_RESULT_STENCIL) { + target = 254; + } else if (nir_src_is_const(instr->src[0])) { + target = nir_src_as_uint(instr->src[0]); + assert(target < 8); + } + + bi_index pi = bi_pixel_indices(b, target); + + if (!is_zs && !nir_src_is_const(instr->src[0])) + pi = bi_lshift_or(b, 32, bi_src_index(&instr->src[0]), pi, bi_imm_u8(8)); + + bi_instr *I = bi_ld_tile_to(b, dest, pi, bi_coverage(b), + bi_src_index(&instr->src[1]), regfmt, nr - 1); + if (is_zs) + I->z_stencil = true; - bi_ld_tile_to(b, dest, bi_pixel_indices(b, rt), bi_coverage(b), - bi_src_index(&instr->src[0]), regfmt, nr - 1); bi_emit_cached_split(b, dest, size * nr); } @@ -5498,8 +5513,8 @@ bi_lower_load_output(nir_builder *b, nir_intrinsic_instr *intr, b, .base = rt, .src_type = nir_intrinsic_dest_type(intr)); nir_def *lowered = nir_load_converted_output_pan( - b, intr->def.num_components, intr->def.bit_size, conversion, - .dest_type = nir_intrinsic_dest_type(intr), + b, intr->def.num_components, intr->def.bit_size, nir_imm_int(b, rt), + conversion, .dest_type = nir_intrinsic_dest_type(intr), .io_semantics = nir_intrinsic_io_semantics(intr)); nir_def_rewrite_uses(&intr->def, lowered);