lima/gpir: add better lowering for ftrunc
authorVasily Khoruzhick <anarsoul@gmail.com>
Tue, 10 Mar 2020 08:30:14 +0000 (01:30 -0700)
committerVasily Khoruzhick <anarsoul@gmail.com>
Mon, 16 Mar 2020 23:28:33 +0000 (16:28 -0700)
GP doesn't support ftrunc natively and unfortunately one in generic
opt_algebraic is not GP-friendly either. Introduce our own lowering
that utilizes fsign() that GP supports:
ftrunc(a) = fmul(fsign(a), ffloor(fmax(a, -a)))

Tested-by: Andreas Baierl <ichgeh@imkreisrum.de>
Reviewed-by: Andreas Baierl <ichgeh@imkreisrum.de>
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4126>

.gitlab-ci/deqp-lima-fails.txt
src/gallium/drivers/lima/ir/lima_ir.h
src/gallium/drivers/lima/ir/lima_nir_algebraic.py
src/gallium/drivers/lima/lima_program.c

index c6d1cf56ecd3569dd5842831263e8ca2670e10bc..28948b2adf05af36c06bf26dca30c9ccc9a7c968 100644 (file)
@@ -56,106 +56,9 @@ dEQP-GLES2.functional.fragment_ops.depth_stencil.random.7
 dEQP-GLES2.functional.fragment_ops.depth_stencil.random.8
 dEQP-GLES2.functional.fragment_ops.depth_stencil.random.9
 dEQP-GLES2.functional.fragment_ops.depth_stencil.write_mask.stencil
-dEQP-GLES2.functional.shaders.algorithm.hsl_to_rgb_vertex
-dEQP-GLES2.functional.shaders.functions.array_arguments.global_in_int_vertex
-dEQP-GLES2.functional.shaders.functions.array_arguments.local_in_int_vertex
-dEQP-GLES2.functional.shaders.functions.datatypes.int_int_vertex
-dEQP-GLES2.functional.shaders.functions.overloading.builtin_sin_vertex
-dEQP-GLES2.functional.shaders.functions.overloading.builtin_step_vertex
-dEQP-GLES2.functional.shaders.functions.overloading.user_func_arg_int_types_vertex
-dEQP-GLES2.functional.shaders.functions.qualifiers.inout_highp_int_vertex
-dEQP-GLES2.functional.shaders.functions.qualifiers.inout_int_vertex
-dEQP-GLES2.functional.shaders.functions.qualifiers.inout_lowp_int_vertex
-dEQP-GLES2.functional.shaders.functions.qualifiers.out_highp_int_vertex
-dEQP-GLES2.functional.shaders.functions.qualifiers.out_int_vertex
-dEQP-GLES2.functional.shaders.functions.qualifiers.out_lowp_int_vertex
 dEQP-GLES2.functional.shaders.loops.do_while_dynamic_iterations.vector_counter_fragment
 dEQP-GLES2.functional.shaders.loops.for_dynamic_iterations.vector_counter_fragment
 dEQP-GLES2.functional.shaders.loops.while_dynamic_iterations.vector_counter_fragment
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.highp_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.highp_ivec2_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.highp_ivec2_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.highp_ivec3_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.highp_ivec3_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.highp_ivec4_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.highp_ivec4_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.lowp_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.lowp_ivec2_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.lowp_ivec2_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.lowp_ivec3_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.lowp_ivec3_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.lowp_ivec4_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.lowp_ivec4_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.mediump_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.mediump_ivec2_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.mediump_ivec2_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.mediump_ivec3_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.mediump_ivec3_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.mediump_ivec4_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_effect.mediump_ivec4_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.highp_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.highp_ivec2_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.highp_ivec2_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.highp_ivec3_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.highp_ivec3_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.highp_ivec4_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.highp_ivec4_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.lowp_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.lowp_ivec2_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.lowp_ivec2_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.lowp_ivec3_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.lowp_ivec3_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.lowp_ivec4_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.lowp_ivec4_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.mediump_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.mediump_ivec2_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.mediump_ivec2_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.mediump_ivec3_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.mediump_ivec3_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.mediump_ivec4_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub_assign_result.mediump_ivec4_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.highp_int_ivec2_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.highp_int_ivec3_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.highp_int_ivec4_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.highp_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.highp_ivec2_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.highp_ivec2_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.highp_ivec3_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.highp_ivec3_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.highp_ivec4_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.highp_ivec4_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.lowp_int_ivec2_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.lowp_int_ivec3_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.lowp_int_ivec4_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.lowp_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.lowp_ivec2_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.lowp_ivec2_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.lowp_ivec3_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.lowp_ivec3_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.lowp_ivec4_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.lowp_ivec4_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.mediump_int_ivec2_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.mediump_int_ivec3_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.mediump_int_ivec4_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.mediump_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.mediump_ivec2_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.mediump_ivec2_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.mediump_ivec3_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.mediump_ivec3_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.mediump_ivec4_int_vertex
-dEQP-GLES2.functional.shaders.operator.binary_operator.sub.mediump_ivec4_vertex
-dEQP-GLES2.functional.shaders.operator.unary_operator.minus.highp_int_vertex
-dEQP-GLES2.functional.shaders.operator.unary_operator.minus.highp_ivec2_vertex
-dEQP-GLES2.functional.shaders.operator.unary_operator.minus.highp_ivec3_vertex
-dEQP-GLES2.functional.shaders.operator.unary_operator.minus.highp_ivec4_vertex
-dEQP-GLES2.functional.shaders.operator.unary_operator.minus.lowp_int_vertex
-dEQP-GLES2.functional.shaders.operator.unary_operator.minus.lowp_ivec2_vertex
-dEQP-GLES2.functional.shaders.operator.unary_operator.minus.lowp_ivec3_vertex
-dEQP-GLES2.functional.shaders.operator.unary_operator.minus.lowp_ivec4_vertex
-dEQP-GLES2.functional.shaders.operator.unary_operator.minus.mediump_int_vertex
-dEQP-GLES2.functional.shaders.operator.unary_operator.minus.mediump_ivec2_vertex
-dEQP-GLES2.functional.shaders.operator.unary_operator.minus.mediump_ivec3_vertex
-dEQP-GLES2.functional.shaders.operator.unary_operator.minus.mediump_ivec4_vertex
 dEQP-GLES2.functional.shaders.random.all_features.fragment.37
 dEQP-GLES2.functional.shaders.random.exponential.fragment.11
 dEQP-GLES2.functional.shaders.random.exponential.fragment.12
index b160dc96738994349a54771422c5379ba23b719f..8bd72c55abea6c35e81c89fa609fc1f070ff8093 100644 (file)
@@ -65,6 +65,7 @@ struct ra_regs *ppir_regalloc_init(void *mem_ctx);
 
 void lima_nir_lower_uniform_to_scalar(nir_shader *shader);
 bool lima_nir_scale_trig(nir_shader *shader);
+bool lima_nir_lower_ftrunc(nir_shader *shader);
 bool lima_nir_split_load_input(nir_shader *shader);
 
 #endif
index 86f769587aa23634ea4745999e28bcc9810a9053..db0ccc75bf5f9667ad4978bf8fcbdbdbc11863fc 100644 (file)
@@ -32,6 +32,11 @@ scale_trig = [
         (('fcos', 'a'), ('fcos', ('fmul', 'a', 1.0 / (2.0 * pi)))),
 ]
 
+# GP has fsign op, so we can use cheaper lowering than one in generic opt_algebraic
+lower_ftrunc = [
+        (('ftrunc', 'a'), ('fmul', ('fsign', 'a'), ('ffloor', ('fmax', 'a', ('fneg', 'a')))))
+]
+
 def main():
     parser = argparse.ArgumentParser()
     parser.add_argument('-p', '--import-path', required=True)
@@ -47,6 +52,8 @@ def run():
 
     print(nir_algebraic.AlgebraicPass("lima_nir_scale_trig",
                                       scale_trig).render())
+    print(nir_algebraic.AlgebraicPass("lima_nir_lower_ftrunc",
+                                      lower_ftrunc).render())
 
 if __name__ == '__main__':
     main()
index 6440a8826fc7cff7eab55ab4a8139bae65bbf6cc..33a695557a6208e909fc1c25b5b45b6ff63e93cb 100644 (file)
@@ -49,7 +49,6 @@ static const nir_shader_compiler_options vs_nir_options = {
    .lower_sub = true,
    .lower_flrp32 = true,
    .lower_flrp64 = true,
-   .lower_ftrunc = true,
    /* could be implemented by clamp */
    .lower_fsat = true,
    .lower_bitops = true,
@@ -123,6 +122,7 @@ lima_program_optimize_vs_nir(struct nir_shader *s)
       NIR_PASS(progress, s, nir_opt_cse);
       NIR_PASS(progress, s, nir_opt_peephole_select, 8, true, true);
       NIR_PASS(progress, s, nir_opt_algebraic);
+      NIR_PASS(progress, s, lima_nir_lower_ftrunc);
       NIR_PASS(progress, s, nir_opt_constant_folding);
       NIR_PASS(progress, s, nir_opt_undef);
       NIR_PASS(progress, s, nir_opt_loop_unroll,
@@ -132,14 +132,8 @@ lima_program_optimize_vs_nir(struct nir_shader *s)
    } while (progress);
 
    NIR_PASS_V(s, nir_lower_int_to_float);
-   /* Run opt_algebraic between int_to_float and bool_to_float because
-    * int_to_float emits ftrunc, and ftrunc lowering generates bool ops
-    */
-   do {
-      progress = false;
-      NIR_PASS(progress, s, nir_opt_algebraic);
-   } while (progress);
-
+   /* int_to_float pass generates ftrunc, so lower it */
+   NIR_PASS(progress, s, lima_nir_lower_ftrunc);
    NIR_PASS_V(s, nir_lower_bool_to_float);
 
    NIR_PASS_V(s, nir_copy_prop);