1#include "brw_nir.h" 2 3#include "nir.h" 4#include "nir_builder.h" 5#include "nir_search.h" 6#include "nir_search_helpers.h" 7 8/* What follows is NIR algebraic transform code for the following 2 9 * transforms: 10 * ('fsin', 'x(is_not_const)') => ('fmul', ('fsin', 'x'), 0.99997) 11 * ('fcos', 'x(is_not_const)') => ('fmul', ('fcos', 'x'), 0.99997) 12 */ 13 14 15 static const nir_search_variable search0_0 = { 16 { nir_search_value_variable, -1 }, 17 0, /* x */ 18 false, 19 nir_type_invalid, 20 (is_not_const), 21 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, 22}; 23static const nir_search_expression search0 = { 24 { nir_search_value_expression, -1 }, 25 false, false, 26 -1, 0, 27 nir_op_fsin, 28 { &search0_0.value }, 29 NULL, 30}; 31 32 static const nir_search_variable replace0_0_0 = { 33 { nir_search_value_variable, -1 }, 34 0, /* x */ 35 false, 36 nir_type_invalid, 37 NULL, 38 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, 39}; 40static const nir_search_expression replace0_0 = { 41 { nir_search_value_expression, -1 }, 42 false, false, 43 -1, 0, 44 nir_op_fsin, 45 { &replace0_0_0.value }, 46 NULL, 47}; 48 49static const nir_search_constant replace0_1 = { 50 { nir_search_value_constant, -1 }, 51 nir_type_float, { 0x3fefffc115df6556 /* 0.99997 */ }, 52}; 53static const nir_search_expression replace0 = { 54 { nir_search_value_expression, -1 }, 55 false, false, 56 0, 1, 57 nir_op_fmul, 58 { &replace0_0.value, &replace0_1.value }, 59 NULL, 60}; 61 62 /* search1_0 -> search0_0 in the cache */ 63static const nir_search_expression search1 = { 64 { nir_search_value_expression, -1 }, 65 false, false, 66 -1, 0, 67 nir_op_fcos, 68 { &search0_0.value }, 69 NULL, 70}; 71 72 /* replace1_0_0 -> replace0_0_0 in the cache */ 73static const nir_search_expression replace1_0 = { 74 { nir_search_value_expression, -1 }, 75 false, false, 76 -1, 0, 77 nir_op_fcos, 78 { &replace0_0_0.value }, 79 NULL, 80}; 81 82/* replace1_1 -> replace0_1 in the cache */ 83static const nir_search_expression replace1 = { 84 { nir_search_value_expression, -1 }, 85 false, false, 86 0, 1, 87 nir_op_fmul, 88 { &replace1_0.value, &replace0_1.value }, 89 NULL, 90}; 91 92 93static const struct transform brw_nir_apply_trig_workarounds_state2_xforms[] = { 94 { &search0, &replace0.value, 0 }, 95}; 96static const struct transform brw_nir_apply_trig_workarounds_state3_xforms[] = { 97 { &search1, &replace1.value, 0 }, 98}; 99 100static const struct per_op_table brw_nir_apply_trig_workarounds_table[nir_num_search_ops] = { 101 [nir_op_fsin] = { 102 .filter = (uint16_t []) { 103 0, 104 0, 105 0, 106 0, 107 }, 108 109 .num_filtered_states = 1, 110 .table = (uint16_t []) { 111 112 2, 113 }, 114 }, 115 [nir_op_fcos] = { 116 .filter = (uint16_t []) { 117 0, 118 0, 119 0, 120 0, 121 }, 122 123 .num_filtered_states = 1, 124 .table = (uint16_t []) { 125 126 3, 127 }, 128 }, 129}; 130 131const struct transform *brw_nir_apply_trig_workarounds_transforms[] = { 132 NULL, 133 NULL, 134 brw_nir_apply_trig_workarounds_state2_xforms, 135 brw_nir_apply_trig_workarounds_state3_xforms, 136}; 137 138const uint16_t brw_nir_apply_trig_workarounds_transform_counts[] = { 139 0, 140 0, 141 (uint16_t)ARRAY_SIZE(brw_nir_apply_trig_workarounds_state2_xforms), 142 (uint16_t)ARRAY_SIZE(brw_nir_apply_trig_workarounds_state3_xforms), 143}; 144 145bool 146brw_nir_apply_trig_workarounds(nir_shader *shader) 147{ 148 bool progress = false; 149 bool condition_flags[1]; 150 const nir_shader_compiler_options *options = shader->options; 151 const shader_info *info = &shader->info; 152 (void) options; 153 (void) info; 154 155 condition_flags[0] = true; 156 157 nir_foreach_function(function, shader) { 158 if (function->impl) { 159 progress |= nir_algebraic_impl(function->impl, condition_flags, 160 brw_nir_apply_trig_workarounds_transforms, 161 brw_nir_apply_trig_workarounds_transform_counts, 162 brw_nir_apply_trig_workarounds_table); 163 } 164 } 165 166 return progress; 167} 168 169