nir/lower_tex: add lower_to_fragment_fetch_amd

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12214>
This commit is contained in:
Rhys Perry 2021-08-04 16:17:39 +01:00 committed by Marge Bot
parent 225fe37c14
commit f3723822a4
2 changed files with 82 additions and 0 deletions

View file

@ -5222,6 +5222,12 @@ typedef struct nir_lower_tex_options {
*/
bool lower_tg4_offsets;
/**
* Lower txf_ms to fragment_mask_fetch and fragment_fetch and samples_identical to
* fragment_mask_fetch.
*/
bool lower_to_fragment_fetch_amd;
/**
* To lower packed sampler return formats.
*

View file

@ -1191,6 +1191,70 @@ nir_lower_txs_cube_array(nir_builder *b, nir_tex_instr *tex)
nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, size, size->parent_instr);
}
static void
nir_lower_ms_txf_to_fragment_fetch(nir_builder *b, nir_tex_instr *tex)
{
lower_offset(b, tex);
b->cursor = nir_before_instr(&tex->instr);
/* Create FMASK fetch. */
assert(tex->texture_index == 0);
nir_tex_instr *fmask_fetch = nir_tex_instr_create(b->shader, tex->num_srcs - 1);
fmask_fetch->op = nir_texop_fragment_mask_fetch_amd;
fmask_fetch->coord_components = tex->coord_components;
fmask_fetch->sampler_dim = tex->sampler_dim;
fmask_fetch->is_array = tex->is_array;
fmask_fetch->texture_non_uniform = tex->texture_non_uniform;
fmask_fetch->dest_type = nir_type_uint32;
nir_ssa_dest_init(&fmask_fetch->instr, &fmask_fetch->dest, 1, 32, NULL);
fmask_fetch->num_srcs = 0;
for (unsigned i = 0; i < tex->num_srcs; i++) {
if (tex->src[i].src_type == nir_tex_src_ms_index)
continue;
nir_tex_src *src = &fmask_fetch->src[fmask_fetch->num_srcs++];
src->src = nir_src_for_ssa(tex->src[i].src.ssa);
src->src_type = tex->src[i].src_type;
}
nir_builder_instr_insert(b, &fmask_fetch->instr);
/* Obtain new sample index. */
int ms_index = nir_tex_instr_src_index(tex, nir_tex_src_ms_index);
assert(ms_index >= 0);
nir_src sample = tex->src[ms_index].src;
nir_ssa_def *new_sample = NULL;
if (nir_src_is_const(sample) && (nir_src_as_uint(sample) == 0 || nir_src_as_uint(sample) == 7)) {
if (nir_src_as_uint(sample) == 7)
new_sample = nir_ushr(b, &fmask_fetch->dest.ssa, nir_imm_int(b, 28));
else
new_sample = nir_iand_imm(b, &fmask_fetch->dest.ssa, 0xf);
} else {
new_sample = nir_ubitfield_extract(b, &fmask_fetch->dest.ssa,
nir_imul_imm(b, sample.ssa, 4), nir_imm_int(b, 4));
}
/* Update instruction. */
tex->op = nir_texop_fragment_fetch_amd;
nir_instr_rewrite_src_ssa(&tex->instr, &tex->src[ms_index].src, new_sample);
}
static void
nir_lower_samples_identical_to_fragment_fetch(nir_builder *b, nir_tex_instr *tex)
{
b->cursor = nir_after_instr(&tex->instr);
nir_tex_instr *fmask_fetch = nir_instr_as_tex(nir_instr_clone(b->shader, &tex->instr));
fmask_fetch->op = nir_texop_fragment_mask_fetch_amd;
fmask_fetch->dest_type = nir_type_uint32;
nir_ssa_dest_init(&fmask_fetch->instr, &fmask_fetch->dest, 1, 32, NULL);
nir_builder_instr_insert(b, &fmask_fetch->instr);
nir_ssa_def_rewrite_uses(&tex->dest.ssa, nir_ieq_imm(b, &fmask_fetch->dest.ssa, 0));
nir_instr_remove_v(&tex->instr);
}
static bool
nir_lower_tex_block(nir_block *block, nir_builder *b,
const nir_lower_tex_options *options,
@ -1400,6 +1464,18 @@ nir_lower_tex_block(nir_block *block, nir_builder *b,
progress |= lower_tg4_offsets(b, tex);
continue;
}
if (options->lower_to_fragment_fetch_amd && tex->op == nir_texop_txf_ms) {
nir_lower_ms_txf_to_fragment_fetch(b, tex);
progress = true;
continue;
}
if (options->lower_to_fragment_fetch_amd && tex->op == nir_texop_samples_identical) {
nir_lower_samples_identical_to_fragment_fetch(b, tex);
progress = true;
continue;
}
}
return progress;