nir: Allow to skip integer ops in nir_lower_to_source_mods

Some hardware supports source mods only for float operations. Make it
possible to skip lowering to source mods in these cases.

v2: use option flags instead of a boolean (Jason Ekstrand)

Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
This commit is contained in:
Gert Wollny
2018-11-12 09:17:34 +01:00
committed by Gert Wollny
parent b4380cb070
commit 4bba280937
3 changed files with 58 additions and 32 deletions

View File

@@ -3017,7 +3017,15 @@ typedef struct nir_lower_bitmap_options {
void nir_lower_bitmap(nir_shader *shader, const nir_lower_bitmap_options *options); void nir_lower_bitmap(nir_shader *shader, const nir_lower_bitmap_options *options);
bool nir_lower_atomics_to_ssbo(nir_shader *shader, unsigned ssbo_offset); bool nir_lower_atomics_to_ssbo(nir_shader *shader, unsigned ssbo_offset);
bool nir_lower_to_source_mods(nir_shader *shader);
typedef enum {
nir_lower_int_source_mods = 1 << 0,
nir_lower_float_source_mods = 1 << 1,
nir_lower_all_source_mods = (1 << 2) - 1
} nir_lower_to_source_mods_flags;
bool nir_lower_to_source_mods(nir_shader *shader, nir_lower_to_source_mods_flags options);
bool nir_lower_gs_intrinsics(nir_shader *shader); bool nir_lower_gs_intrinsics(nir_shader *shader);

View File

@@ -34,7 +34,8 @@
*/ */
static bool static bool
nir_lower_to_source_mods_block(nir_block *block) nir_lower_to_source_mods_block(nir_block *block,
nir_lower_to_source_mods_flags options)
{ {
bool progress = false; bool progress = false;
@@ -58,10 +59,14 @@ nir_lower_to_source_mods_block(nir_block *block)
switch (nir_alu_type_get_base_type(nir_op_infos[alu->op].input_types[i])) { switch (nir_alu_type_get_base_type(nir_op_infos[alu->op].input_types[i])) {
case nir_type_float: case nir_type_float:
if (!(options & nir_lower_float_source_mods))
continue;
if (parent->op != nir_op_fmov) if (parent->op != nir_op_fmov)
continue; continue;
break; break;
case nir_type_int: case nir_type_int:
if (!(options & nir_lower_int_source_mods))
continue;
if (parent->op != nir_op_imov) if (parent->op != nir_op_imov)
continue; continue;
break; break;
@@ -97,33 +102,41 @@ nir_lower_to_source_mods_block(nir_block *block)
progress = true; progress = true;
} }
switch (alu->op) { if (options & nir_lower_float_source_mods) {
case nir_op_fsat: switch (alu->op) {
alu->op = nir_op_fmov; case nir_op_fsat:
alu->dest.saturate = true; alu->op = nir_op_fmov;
break; alu->dest.saturate = true;
case nir_op_ineg: break;
alu->op = nir_op_imov; case nir_op_fneg:
alu->src[0].negate = !alu->src[0].negate; alu->op = nir_op_fmov;
break; alu->src[0].negate = !alu->src[0].negate;
case nir_op_fneg: break;
alu->op = nir_op_fmov; case nir_op_fabs:
alu->src[0].negate = !alu->src[0].negate; alu->op = nir_op_fmov;
break; alu->src[0].abs = true;
case nir_op_iabs: alu->src[0].negate = false;
alu->op = nir_op_imov; break;
alu->src[0].abs = true; default:
alu->src[0].negate = false; break;
break; }
case nir_op_fabs:
alu->op = nir_op_fmov;
alu->src[0].abs = true;
alu->src[0].negate = false;
break;
default:
break;
} }
if (options & nir_lower_int_source_mods) {
switch (alu->op) {
case nir_op_ineg:
alu->op = nir_op_imov;
alu->src[0].negate = !alu->src[0].negate;
break;
case nir_op_iabs:
alu->op = nir_op_imov;
alu->src[0].abs = true;
alu->src[0].negate = false;
break;
default:
break;
}
}
/* We've covered sources. Now we're going to try and saturate the /* We've covered sources. Now we're going to try and saturate the
* destination if we can. * destination if we can.
*/ */
@@ -136,6 +149,9 @@ nir_lower_to_source_mods_block(nir_block *block)
nir_type_float) nir_type_float)
continue; continue;
if (!(options & nir_lower_float_source_mods))
continue;
if (!list_empty(&alu->dest.dest.ssa.if_uses)) if (!list_empty(&alu->dest.dest.ssa.if_uses))
continue; continue;
@@ -185,12 +201,13 @@ nir_lower_to_source_mods_block(nir_block *block)
} }
static bool static bool
nir_lower_to_source_mods_impl(nir_function_impl *impl) nir_lower_to_source_mods_impl(nir_function_impl *impl,
nir_lower_to_source_mods_flags options)
{ {
bool progress = false; bool progress = false;
nir_foreach_block(block, impl) { nir_foreach_block(block, impl) {
progress |= nir_lower_to_source_mods_block(block); progress |= nir_lower_to_source_mods_block(block, options);
} }
if (progress) if (progress)
@@ -201,13 +218,14 @@ nir_lower_to_source_mods_impl(nir_function_impl *impl)
} }
bool bool
nir_lower_to_source_mods(nir_shader *shader) nir_lower_to_source_mods(nir_shader *shader,
nir_lower_to_source_mods_flags options)
{ {
bool progress = false; bool progress = false;
nir_foreach_function(function, shader) { nir_foreach_function(function, shader) {
if (function->impl) { if (function->impl) {
progress |= nir_lower_to_source_mods_impl(function->impl); progress |= nir_lower_to_source_mods_impl(function->impl, options);
} }
} }

View File

@@ -796,7 +796,7 @@ brw_postprocess_nir(nir_shader *nir, const struct brw_compiler *compiler,
OPT(nir_opt_algebraic_late); OPT(nir_opt_algebraic_late);
OPT(nir_lower_to_source_mods); OPT(nir_lower_to_source_mods, nir_lower_all_source_mods);
OPT(nir_copy_prop); OPT(nir_copy_prop);
OPT(nir_opt_dce); OPT(nir_opt_dce);
OPT(nir_opt_move_comparisons); OPT(nir_opt_move_comparisons);