v3d/compiler: Implement load_output

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33766>
This commit is contained in:
Ella Stanforth 2025-02-26 12:23:47 +00:00 committed by Marge Bot
parent de2a65ade6
commit 6023a46d02
5 changed files with 68 additions and 22 deletions

View file

@ -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',
)

View file

@ -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,

View file

@ -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);
}

View file

@ -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,

View file

@ -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) {