• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 };
23 static 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 };
40 static 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 
49 static const nir_search_constant replace0_1 = {
50    { nir_search_value_constant, -1 },
51    nir_type_float, { 0x3fefffc115df6556 /* 0.99997 */ },
52 };
53 static 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 */
63 static 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 */
73 static 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 */
83 static 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 
93 static const struct transform brw_nir_apply_trig_workarounds_state2_xforms[] = {
94   { &search0, &replace0.value, 0 },
95 };
96 static const struct transform brw_nir_apply_trig_workarounds_state3_xforms[] = {
97   { &search1, &replace1.value, 0 },
98 };
99 
100 static 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 
131 const 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 
138 const 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 
145 bool
brw_nir_apply_trig_workarounds(nir_shader * shader)146 brw_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