panfrost/midgard: Lower source modifiers for ints
On Midgard, float ops support standard source modifiers (abs/neg) and destination modifiers (sat/pos/round). Integer ops do not support these, however. To cope, we use native NIR source modifiers for floats, but lower them away to iabs/ineg for integers, implementing those ops simultaneously to avoid regressions. Fixes the integer tests in dEQP-GLES2.functional.shaders.operator.unary_operator.minus.* Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
This commit is contained in:
parent
3208c9d9a2
commit
effe6fb08d
|
@ -142,6 +142,7 @@ midgard_is_integer_op(int op)
|
||||||
//case midgard_alu_op_f2i:
|
//case midgard_alu_op_f2i:
|
||||||
//case midgard_alu_op_f2u:
|
//case midgard_alu_op_f2u:
|
||||||
case midgard_alu_op_ieq:
|
case midgard_alu_op_ieq:
|
||||||
|
case midgard_alu_op_iabs:
|
||||||
case midgard_alu_op_ine:
|
case midgard_alu_op_ine:
|
||||||
case midgard_alu_op_ilt:
|
case midgard_alu_op_ilt:
|
||||||
case midgard_alu_op_ile:
|
case midgard_alu_op_ile:
|
||||||
|
@ -209,6 +210,7 @@ static unsigned alu_opcode_props[256] = {
|
||||||
|
|
||||||
/* Incredibly, iadd can run on vmul, etc */
|
/* Incredibly, iadd can run on vmul, etc */
|
||||||
[midgard_alu_op_iadd] = UNITS_MOST,
|
[midgard_alu_op_iadd] = UNITS_MOST,
|
||||||
|
[midgard_alu_op_iabs] = UNITS_MOST,
|
||||||
[midgard_alu_op_isub] = UNITS_MOST,
|
[midgard_alu_op_isub] = UNITS_MOST,
|
||||||
[midgard_alu_op_imul] = UNITS_MOST,
|
[midgard_alu_op_imul] = UNITS_MOST,
|
||||||
[midgard_alu_op_imov] = UNITS_MOST | QUIRK_FLIPPED_R24,
|
[midgard_alu_op_imov] = UNITS_MOST | QUIRK_FLIPPED_R24,
|
||||||
|
|
|
@ -748,9 +748,13 @@ optimise_nir(nir_shader *nir)
|
||||||
} while (progress);
|
} while (progress);
|
||||||
|
|
||||||
NIR_PASS(progress, nir, nir_opt_algebraic_late);
|
NIR_PASS(progress, nir, nir_opt_algebraic_late);
|
||||||
|
NIR_PASS(progress, nir, midgard_nir_lower_algebraic_late);
|
||||||
|
|
||||||
/* Lower mods */
|
/* Lower mods for float ops only. Integer ops don't support modifiers
|
||||||
NIR_PASS(progress, nir, nir_lower_to_source_mods, nir_lower_all_source_mods);
|
* (saturate doesn't make sense on integers, neg/abs require dedicated
|
||||||
|
* instructions) */
|
||||||
|
|
||||||
|
NIR_PASS(progress, nir, nir_lower_to_source_mods, nir_lower_float_source_mods);
|
||||||
NIR_PASS(progress, nir, nir_copy_prop);
|
NIR_PASS(progress, nir, nir_copy_prop);
|
||||||
NIR_PASS(progress, nir, nir_opt_dce);
|
NIR_PASS(progress, nir, nir_opt_dce);
|
||||||
|
|
||||||
|
@ -975,6 +979,7 @@ emit_alu(compiler_context *ctx, nir_alu_instr *instr)
|
||||||
ALU_CASE(iadd, iadd);
|
ALU_CASE(iadd, iadd);
|
||||||
ALU_CASE(isub, isub);
|
ALU_CASE(isub, isub);
|
||||||
ALU_CASE(imul, imul);
|
ALU_CASE(imul, imul);
|
||||||
|
ALU_CASE(iabs, iabs);
|
||||||
|
|
||||||
/* XXX: Use fmov, not imov, since imov was causing major
|
/* XXX: Use fmov, not imov, since imov was causing major
|
||||||
* issues with texture precision? XXX research */
|
* issues with texture precision? XXX research */
|
||||||
|
|
|
@ -2,4 +2,5 @@
|
||||||
#include "nir.h"
|
#include "nir.h"
|
||||||
|
|
||||||
bool midgard_nir_lower_algebraic(nir_shader *shader);
|
bool midgard_nir_lower_algebraic(nir_shader *shader);
|
||||||
|
bool midgard_nir_lower_algebraic_late(nir_shader *shader);
|
||||||
bool midgard_nir_scale_trig(nir_shader *shader);
|
bool midgard_nir_scale_trig(nir_shader *shader);
|
||||||
|
|
|
@ -39,6 +39,15 @@ algebraic = [
|
||||||
(('fsign', a), ('bcsel', ('fge', a, 0), 1.0, -1.0)),
|
(('fsign', a), ('bcsel', ('fge', a, 0), 1.0, -1.0)),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
algebraic_late = [
|
||||||
|
# ineg must be lowered late, but only for integers; floats will try to
|
||||||
|
# have modifiers attached... hence why this has to be here rather than
|
||||||
|
# a more standard lower_negate approach
|
||||||
|
|
||||||
|
(('ineg', a), ('isub', 0, a)),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
# Midgard scales fsin/fcos arguments by pi.
|
# Midgard scales fsin/fcos arguments by pi.
|
||||||
# Pass must be run only once, after the main loop
|
# Pass must be run only once, after the main loop
|
||||||
|
|
||||||
|
@ -62,6 +71,9 @@ def run():
|
||||||
print(nir_algebraic.AlgebraicPass("midgard_nir_lower_algebraic",
|
print(nir_algebraic.AlgebraicPass("midgard_nir_lower_algebraic",
|
||||||
algebraic).render())
|
algebraic).render())
|
||||||
|
|
||||||
|
print(nir_algebraic.AlgebraicPass("midgard_nir_lower_algebraic_late",
|
||||||
|
algebraic_late).render())
|
||||||
|
|
||||||
print(nir_algebraic.AlgebraicPass("midgard_nir_scale_trig",
|
print(nir_algebraic.AlgebraicPass("midgard_nir_scale_trig",
|
||||||
scale_trig).render())
|
scale_trig).render())
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue