mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-21 18:00:13 +01:00
intel/fs: Add a lowering pass for linear interpolation.
On gen11, instead of using a PLN instruction, we convert FS_OPCODE_LINTERP to 2 or 4 multiply adds. That is done in the fs_generator code. This patch adds a lowering pass that does the same thing at the fs_visitor. It also drops the usage of NF types, since we don't need the extra precision and it lets us skip the accumulator. With all that, some optimizations will still be run on the generated code, and we should get better scheduling. v2: Update comment about saturation and conditional mod (Matt) Reviewed-by: Matt Turner <mattst88@gmail.com>
This commit is contained in:
parent
c0504569ea
commit
9ea90aae1e
2 changed files with 47 additions and 0 deletions
|
|
@ -3876,6 +3876,47 @@ fs_visitor::lower_load_payload()
|
||||||
return progress;
|
return progress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
fs_visitor::lower_linterp()
|
||||||
|
{
|
||||||
|
bool progress = false;
|
||||||
|
|
||||||
|
if (devinfo->gen < 11)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
foreach_block_and_inst_safe(block, fs_inst, inst, cfg) {
|
||||||
|
const fs_builder ibld(this, block, inst);
|
||||||
|
|
||||||
|
if (inst->opcode != FS_OPCODE_LINTERP)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fs_reg dwP = component(inst->src[1], 0);
|
||||||
|
fs_reg dwQ = component(inst->src[1], 1);
|
||||||
|
fs_reg dwR = component(inst->src[1], 3);
|
||||||
|
for (unsigned i = 0; i < DIV_ROUND_UP(dispatch_width, 8); i++) {
|
||||||
|
const fs_builder hbld(ibld.half(i));
|
||||||
|
fs_reg dst = half(inst->dst, i);
|
||||||
|
fs_reg delta_xy = offset(inst->src[0], ibld, i);
|
||||||
|
hbld.MAD(dst, dwR, half(delta_xy, 0), dwP);
|
||||||
|
fs_inst *mad = hbld.MAD(dst, dst, half(delta_xy, 1), dwQ);
|
||||||
|
|
||||||
|
/* Propagate conditional mod and saturate from the original
|
||||||
|
* instruction to the second MAD instruction.
|
||||||
|
*/
|
||||||
|
set_saturate(inst->saturate, mad);
|
||||||
|
set_condmod(inst->conditional_mod, mad);
|
||||||
|
}
|
||||||
|
|
||||||
|
inst->remove(block);
|
||||||
|
progress = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (progress)
|
||||||
|
invalidate_live_intervals();
|
||||||
|
|
||||||
|
return progress;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
fs_visitor::lower_integer_multiplication()
|
fs_visitor::lower_integer_multiplication()
|
||||||
{
|
{
|
||||||
|
|
@ -7070,6 +7111,11 @@ fs_visitor::optimize()
|
||||||
OPT(compact_virtual_grfs);
|
OPT(compact_virtual_grfs);
|
||||||
} while (progress);
|
} while (progress);
|
||||||
|
|
||||||
|
if (OPT(lower_linterp)) {
|
||||||
|
OPT(opt_copy_propagation);
|
||||||
|
OPT(dead_code_eliminate);
|
||||||
|
}
|
||||||
|
|
||||||
/* Do this after cmod propagation has had every possible opportunity to
|
/* Do this after cmod propagation has had every possible opportunity to
|
||||||
* propagate results into SEL instructions.
|
* propagate results into SEL instructions.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,7 @@ public:
|
||||||
bool lower_pack();
|
bool lower_pack();
|
||||||
bool lower_regioning();
|
bool lower_regioning();
|
||||||
bool lower_logical_sends();
|
bool lower_logical_sends();
|
||||||
|
bool lower_linterp();
|
||||||
bool lower_integer_multiplication();
|
bool lower_integer_multiplication();
|
||||||
bool lower_minmax();
|
bool lower_minmax();
|
||||||
bool lower_simd_width();
|
bool lower_simd_width();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue