Created
August 29, 2019 19:25
-
-
Save anarsoul/cb8caafe22006340b5557f134275f094 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources | |
index edf1b936ac1..094cc94c32f 100644 | |
--- a/src/compiler/Makefile.sources | |
+++ b/src/compiler/Makefile.sources | |
@@ -244,6 +244,7 @@ NIR_FILES = \ | |
nir/nir_lower_clip.c \ | |
nir/nir_lower_clip_cull_distance_arrays.c \ | |
nir/nir_lower_constant_initializers.c \ | |
+ nir/nir_lower_csel_to_sccsel.c \ | |
nir/nir_lower_double_ops.c \ | |
nir/nir_lower_drawpixels.c \ | |
nir/nir_lower_fb_read.c \ | |
diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build | |
index 04e4f729902..58e369b5774 100644 | |
--- a/src/compiler/nir/meson.build | |
+++ b/src/compiler/nir/meson.build | |
@@ -123,6 +123,7 @@ files_libnir = files( | |
'nir_lower_clip.c', | |
'nir_lower_clip_cull_distance_arrays.c', | |
'nir_lower_constant_initializers.c', | |
+ 'nir_lower_csel_to_sccsel.c', | |
'nir_lower_double_ops.c', | |
'nir_lower_drawpixels.c', | |
'nir_lower_fb_read.c', | |
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h | |
index 5149a0e8c01..3a891c1e9d8 100644 | |
--- a/src/compiler/nir/nir.h | |
+++ b/src/compiler/nir/nir.h | |
@@ -3433,6 +3433,8 @@ bool nir_lower_vars_to_scratch(nir_shader *shader, | |
int size_threshold, | |
glsl_type_size_align_func size_align); | |
+bool nir_lower_csel_to_sccsel(nir_shader *shader); | |
+ | |
void nir_shader_gather_info(nir_shader *shader, nir_function_impl *entrypoint); | |
void nir_gather_ssa_types(nir_function_impl *impl, | |
diff --git a/src/compiler/nir/nir_gather_ssa_types.c b/src/compiler/nir/nir_gather_ssa_types.c | |
index a1a7df0ca45..ea7ecbd0185 100644 | |
--- a/src/compiler/nir/nir_gather_ssa_types.c | |
+++ b/src/compiler/nir/nir_gather_ssa_types.c | |
@@ -119,7 +119,9 @@ nir_gather_ssa_types(nir_function_impl *impl, | |
break; | |
case nir_op_bcsel: | |
+ case nir_op_bsccsel: | |
case nir_op_b32csel: | |
+ case nir_op_b32sccsel: | |
set_type(alu->src[0].src.ssa->index, nir_type_bool, | |
float_types, int_types, &progress); | |
copy_types(alu->src[1].src, &alu->dest.dest, | |
diff --git a/src/compiler/nir/nir_lower_bool_to_float.c b/src/compiler/nir/nir_lower_bool_to_float.c | |
index c07121f6d88..3eeebde80fe 100644 | |
--- a/src/compiler/nir/nir_lower_bool_to_float.c | |
+++ b/src/compiler/nir/nir_lower_bool_to_float.c | |
@@ -92,6 +92,7 @@ lower_alu_instr(nir_builder *b, nir_alu_instr *alu) | |
case nir_op_bany_inequal4: alu->op = nir_op_fany_nequal4; break; | |
case nir_op_bcsel: alu->op = nir_op_fcsel; break; | |
+ case nir_op_bsccsel: alu->op = nir_op_fsccsel; break; | |
case nir_op_iand: alu->op = nir_op_fmul; break; | |
case nir_op_ixor: alu->op = nir_op_sne; break; | |
diff --git a/src/compiler/nir/nir_lower_bool_to_int32.c b/src/compiler/nir/nir_lower_bool_to_int32.c | |
index e331de488a3..8697114fd3b 100644 | |
--- a/src/compiler/nir/nir_lower_bool_to_int32.c | |
+++ b/src/compiler/nir/nir_lower_bool_to_int32.c | |
@@ -88,6 +88,7 @@ lower_alu_instr(nir_alu_instr *alu) | |
case nir_op_bany_inequal4: alu->op = nir_op_b32any_inequal4; break; | |
case nir_op_bcsel: alu->op = nir_op_b32csel; break; | |
+ case nir_op_bsccsel: alu->op = nir_op_b32sccsel; break; | |
default: | |
assert(alu->dest.dest.ssa.bit_size > 1); | |
diff --git a/src/compiler/nir/nir_lower_csel_to_sccsel.c b/src/compiler/nir/nir_lower_csel_to_sccsel.c | |
new file mode 100644 | |
index 00000000000..20e1bc447a5 | |
--- /dev/null | |
+++ b/src/compiler/nir/nir_lower_csel_to_sccsel.c | |
@@ -0,0 +1,86 @@ | |
+/* | |
+ * Copyright (C) 2019 Vasily Khoruzhick | |
+ * | |
+ * Permission is hereby granted, free of charge, to any person obtaining a | |
+ * copy of this software and associated documentation files (the "Software"), | |
+ * to deal in the Software without restriction, including without limitation | |
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
+ * and/or sell copies of the Software, and to permit persons to whom the | |
+ * Software is furnished to do so, subject to the following conditions: | |
+ * | |
+ * The above copyright notice and this permission notice (including the next | |
+ * paragraph) shall be included in all copies or substantial portions of the | |
+ * Software. | |
+ * | |
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
+ * IN THE SOFTWARE. | |
+ */ | |
+ | |
+#include "nir.h" | |
+#include "nir_builder.h" | |
+ | |
+static bool | |
+lower_csel_to_sccsel(nir_alu_instr *alu) | |
+{ | |
+ int num_components = nir_dest_num_components(alu->dest.dest); | |
+ | |
+ uint8_t swizzle = alu->src[0].swizzle[0]; | |
+ for (int i = 1; i < num_components; i++) | |
+ if (alu->src[0].swizzle[i] != swizzle) | |
+ return false; | |
+ | |
+ switch (alu->op) { | |
+ case nir_op_b32csel: | |
+ alu->op = nir_op_b32sccsel; | |
+ break; | |
+ case nir_op_bcsel: | |
+ alu->op = nir_op_bsccsel; | |
+ break; | |
+ case nir_op_fcsel: | |
+ alu->op = nir_op_fsccsel; | |
+ break; | |
+ default: | |
+ return false; | |
+ } | |
+ | |
+ return true; | |
+} | |
+ | |
+/* Lower {f,b,b32}csel to {f,b,b32}sccsel if condition is scalar */ | |
+bool | |
+nir_lower_csel_to_sccsel(nir_shader *shader) | |
+{ | |
+ bool progress = false; | |
+ nir_foreach_function(func, shader) { | |
+ if (!func->impl) | |
+ continue; | |
+ | |
+ nir_foreach_block(block, func->impl) { | |
+ nir_foreach_instr_safe(instr, block) { | |
+ if (instr->type != nir_instr_type_alu) | |
+ continue; | |
+ | |
+ nir_alu_instr *alu = nir_instr_as_alu(instr); | |
+ switch (alu->op) { | |
+ case nir_op_fcsel: | |
+ case nir_op_bcsel: | |
+ case nir_op_b32csel: | |
+ progress = lower_csel_to_sccsel(alu) || progress; | |
+ break; | |
+ default: | |
+ break; | |
+ } | |
+ } | |
+ } | |
+ | |
+ nir_metadata_preserve(func->impl, nir_metadata_block_index | | |
+ nir_metadata_dominance); | |
+ } | |
+ | |
+ return progress; | |
+} | |
diff --git a/src/compiler/nir/nir_lower_int_to_float.c b/src/compiler/nir/nir_lower_int_to_float.c | |
index d1e77daf1fe..a3243b78712 100644 | |
--- a/src/compiler/nir/nir_lower_int_to_float.c | |
+++ b/src/compiler/nir/nir_lower_int_to_float.c | |
@@ -57,6 +57,7 @@ lower_alu_instr(nir_builder *b, nir_alu_instr *alu) | |
case nir_op_vec3: | |
case nir_op_vec4: | |
case nir_op_bcsel: | |
+ case nir_op_bsccsel: | |
/* These we expect to have integers but the opcode doesn't change */ | |
break; | |
diff --git a/src/compiler/nir/nir_opcodes.py b/src/compiler/nir/nir_opcodes.py | |
index 3020da98264..66259a6e832 100644 | |
--- a/src/compiler/nir/nir_opcodes.py | |
+++ b/src/compiler/nir/nir_opcodes.py | |
@@ -837,6 +837,9 @@ triop("flrp", tfloat, "", "src0 * (1 - src2) + src1 * src2") | |
triop("fcsel", tfloat32, "", "(src0 != 0.0f) ? src1 : src2") | |
+# Similar to fcsel, but with scalar condition | |
+triop("fsccsel", tfloat32, "", "(src0 != 0.0f) ? src1 : src2") | |
+ | |
# 3 way min/max/med | |
triop("fmin3", tfloat, "", "fminf(src0, fminf(src1, src2))") | |
triop("imin3", tint, "", "MIN2(src0, MIN2(src1, src2))") | |
@@ -852,8 +855,12 @@ triop("umed3", tuint, "", "MAX2(MIN2(MAX2(src0, src1), src2), MIN2(src0, src1))" | |
opcode("bcsel", 0, tuint, [0, 0, 0], | |
[tbool1, tuint, tuint], False, "", "src0 ? src1 : src2") | |
+opcode("bsccsel", 0, tuint, [0, 0, 0], | |
+ [tbool1, tuint, tuint], False, "", "src0 ? src1 : src2") | |
opcode("b32csel", 0, tuint, [0, 0, 0], | |
[tbool32, tuint, tuint], False, "", "src0 ? src1 : src2") | |
+opcode("b32sccsel", 0, tuint, [0, 0, 0], | |
+ [tbool32, tuint, tuint], False, "", "src0 ? src1 : src2") | |
# SM5 bfi assembly | |
triop("bfi", tuint32, "", """ | |
diff --git a/src/gallium/drivers/lima/ir/pp/nir.c b/src/gallium/drivers/lima/ir/pp/nir.c | |
index 9af1a8e65b0..bcf1311c33e 100644 | |
--- a/src/gallium/drivers/lima/ir/pp/nir.c | |
+++ b/src/gallium/drivers/lima/ir/pp/nir.c | |
@@ -196,6 +196,7 @@ static int nir_to_ppir_opcodes[nir_num_opcodes] = { | |
[nir_op_sne] = ppir_op_ne, | |
[nir_op_fne] = ppir_op_ne, | |
[nir_op_fcsel] = ppir_op_select, | |
+ [nir_op_fsccsel] = ppir_op_select, | |
[nir_op_inot] = ppir_op_not, | |
[nir_op_ftrunc] = ppir_op_trunc, | |
[nir_op_fsat] = ppir_op_sat, | |
diff --git a/src/gallium/drivers/lima/lima_program.c b/src/gallium/drivers/lima/lima_program.c | |
index b9c4cbc4d5f..3a174ef3653 100644 | |
--- a/src/gallium/drivers/lima/lima_program.c | |
+++ b/src/gallium/drivers/lima/lima_program.c | |
@@ -178,6 +178,7 @@ lima_program_optimize_fs_nir(struct nir_shader *s) | |
progress = false; | |
NIR_PASS_V(s, nir_lower_vars_to_ssa); | |
+ NIR_PASS(progress, s, nir_lower_csel_to_sccsel); | |
NIR_PASS(progress, s, nir_lower_alu_to_scalar, alu_lower); | |
NIR_PASS(progress, s, nir_lower_phis_to_scalar); | |
NIR_PASS(progress, s, nir_copy_prop); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment