diff --git a/src/broadcom/compiler/meson.build b/src/broadcom/compiler/meson.build index 55a9ad5b939..2a58a6cad20 100644 --- a/src/broadcom/compiler/meson.build +++ b/src/broadcom/compiler/meson.build @@ -24,6 +24,7 @@ libbroadcom_compiler_files = files( 'v3d_nir_lower_logic_ops.c', 'v3d_nir_lower_scratch.c', 'v3d_nir_lower_txf_ms.c', + 'v3d_nir_lower_load_output.c', 'v3d_packing.c', ) diff --git a/src/broadcom/compiler/v3d_compiler.h b/src/broadcom/compiler/v3d_compiler.h index 49ac9245013..d4a61e92d91 100644 --- a/src/broadcom/compiler/v3d_compiler.h +++ b/src/broadcom/compiler/v3d_compiler.h @@ -1211,6 +1211,9 @@ bool v3d_nir_lower_image_load_store(nir_shader *s, struct v3d_compile *c); bool v3d_nir_lower_global_2x32(nir_shader *s); bool v3d_nir_lower_load_store_bitsize(nir_shader *s); bool v3d_nir_lower_algebraic(struct nir_shader *shader, const struct v3d_compile *c); +bool v3d_nir_lower_load_output(nir_shader *s, struct v3d_compile *c); + +nir_def *v3d_nir_get_tlb_color(nir_builder *b, struct v3d_compile *c, int rt, int sample); void v3d_vir_emit_tex(struct v3d_compile *c, nir_tex_instr *instr); void v3d_vir_emit_image_load_store(struct v3d_compile *c, diff --git a/src/broadcom/compiler/v3d_nir_lower_load_output.c b/src/broadcom/compiler/v3d_nir_lower_load_output.c new file mode 100644 index 00000000000..596399f647b --- /dev/null +++ b/src/broadcom/compiler/v3d_nir_lower_load_output.c @@ -0,0 +1,63 @@ + +#include "util/format/u_format.h" +#include "compiler/nir/nir_builder.h" +#include "v3d_compiler.h" + +nir_def * +v3d_nir_get_tlb_color(nir_builder *b, struct v3d_compile *c, int rt, int sample) +{ + uint32_t num_components = + util_format_get_nr_components(c->fs_key->color_fmt[rt].format); + + nir_def *color[4]; + for (int i = 0; i < num_components; i++) { + color[i] = + nir_load_tlb_color_brcm(b, 1, 32, + nir_imm_int(b, rt), + .base = sample, + .component = i); + } + return nir_pad_vec4(b, nir_vec(b, color, num_components)); +} + +static bool +lower_load_output(nir_builder *b, nir_intrinsic_instr *intr, void *data) +{ + if (intr->intrinsic != nir_intrinsic_load_output) + return false; + + b->cursor = nir_before_instr(&intr->instr); + + struct v3d_compile *c = data; + + nir_io_semantics sem = nir_intrinsic_io_semantics(intr); + unsigned rt = sem.location - FRAG_RESULT_DATA0; + + unsigned num_samples = c->fs_key->msaa ? V3D_MAX_SAMPLES : 1; + assert(num_samples > 0); + + nir_def *sample_id = num_samples > 1 ? nir_load_sample_id(b) : NULL; + nir_def *out = v3d_nir_get_tlb_color(b, c, rt, 0); + + /* If msaa, run through every sample and, if it matches the current sample + * id, use it. + */ + + for (unsigned i = 1; i < num_samples; i++) { + nir_def *is_cur_sample = nir_ieq_imm(b, sample_id, i); + nir_def *val = v3d_nir_get_tlb_color(b, c, rt, i); + out = nir_bcsel(b, is_cur_sample, val, out); + } + + nir_def_replace(&intr->def, out); + + return true; +} + +bool +v3d_nir_lower_load_output(nir_shader *s, struct v3d_compile *c) +{ + return nir_shader_intrinsics_pass(s, lower_load_output, + nir_metadata_control_flow, + c); +} diff --git a/src/broadcom/compiler/v3d_nir_lower_logic_ops.c b/src/broadcom/compiler/v3d_nir_lower_logic_ops.c index 8decc59f786..c2eaa5aad72 100644 --- a/src/broadcom/compiler/v3d_nir_lower_logic_ops.c +++ b/src/broadcom/compiler/v3d_nir_lower_logic_ops.c @@ -201,28 +201,6 @@ v3d_get_format_swizzle_for_rt(struct v3d_compile *c, int rt) } } -static nir_def * -v3d_nir_get_tlb_color(nir_builder *b, struct v3d_compile *c, int rt, int sample) -{ - uint32_t num_components = - util_format_get_nr_components(c->fs_key->color_fmt[rt].format); - - nir_def *color[4]; - for (int i = 0; i < 4; i++) { - if (i < num_components) { - color[i] = - nir_load_tlb_color_brcm(b, 1, 32, - nir_imm_int(b, rt), - .base = sample, - .component = i); - } else { - /* These will be DCEd */ - color[i] = nir_imm_int(b, 0); - } - } - return nir_vec4(b, color[0], color[1], color[2], color[3]); -} - static nir_def * v3d_emit_logic_op_raw(struct v3d_compile *c, nir_builder *b, nir_def **src_chans, nir_def **dst_chans, diff --git a/src/broadcom/compiler/vir.c b/src/broadcom/compiler/vir.c index 632719eec0d..687062bf765 100644 --- a/src/broadcom/compiler/vir.c +++ b/src/broadcom/compiler/vir.c @@ -1136,6 +1136,7 @@ v3d_nir_lower_fs_early(struct v3d_compile *c) if (c->fs_key->int_color_rb || c->fs_key->uint_color_rb) v3d_fixup_fs_output_types(c); + NIR_PASS(_, c->s, v3d_nir_lower_load_output, c); NIR_PASS(_, c->s, v3d_nir_lower_logic_ops, c); if (c->fs_key->line_smoothing) {