1 #include "ir3_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@32') => ('fsin', ('fsub', ('fmul', 6.2831853, ('ffract', ('fadd', ('fmul', 0.15915494, 'x'), 0.5))), 3.14159265))
11  *    ('fcos', 'x@32') => ('fcos', ('fsub', ('fmul', 6.2831853, ('ffract', ('fadd', ('fmul', 0.15915494, 'x'), 0.5))), 3.14159265))
12  */
13 
14 
15    static const nir_search_variable search0_0 = {
16    { nir_search_value_variable, 32 },
17    0, /* x */
18    false,
19    nir_type_invalid,
20    NULL,
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, 32 },
25    false, false,
26    -1, 0,
27    nir_op_fsin,
28    { &search0_0.value },
29    NULL,
30 };
31 
32    static const nir_search_constant replace0_0_0_0 = {
33    { nir_search_value_constant, 32 },
34    nir_type_float, { 0x401921fb53c8d4f1 /* 6.2831853 */ },
35 };
36 
37 static const nir_search_constant replace0_0_0_1_0_0_0 = {
38    { nir_search_value_constant, 32 },
39    nir_type_float, { 0x3fc45f306725feed /* 0.15915494 */ },
40 };
41 
42 /* replace0_0_0_1_0_0_1 -> search0_0 in the cache */
43 static const nir_search_expression replace0_0_0_1_0_0 = {
44    { nir_search_value_expression, 32 },
45    false, false,
46    2, 1,
47    nir_op_fmul,
48    { &replace0_0_0_1_0_0_0.value, &search0_0.value },
49    NULL,
50 };
51 
52 static const nir_search_constant replace0_0_0_1_0_1 = {
53    { nir_search_value_constant, 32 },
54    nir_type_float, { 0x3fe0000000000000 /* 0.5 */ },
55 };
56 static const nir_search_expression replace0_0_0_1_0 = {
57    { nir_search_value_expression, 32 },
58    false, false,
59    1, 2,
60    nir_op_fadd,
61    { &replace0_0_0_1_0_0.value, &replace0_0_0_1_0_1.value },
62    NULL,
63 };
64 static const nir_search_expression replace0_0_0_1 = {
65    { nir_search_value_expression, 32 },
66    false, false,
67    -1, 2,
68    nir_op_ffract,
69    { &replace0_0_0_1_0.value },
70    NULL,
71 };
72 static const nir_search_expression replace0_0_0 = {
73    { nir_search_value_expression, 32 },
74    false, false,
75    0, 3,
76    nir_op_fmul,
77    { &replace0_0_0_0.value, &replace0_0_0_1.value },
78    NULL,
79 };
80 
81 static const nir_search_constant replace0_0_1 = {
82    { nir_search_value_constant, 32 },
83    nir_type_float, { 0x400921fb53c8d4f1 /* 3.14159265 */ },
84 };
85 static const nir_search_expression replace0_0 = {
86    { nir_search_value_expression, 32 },
87    false, false,
88    -1, 3,
89    nir_op_fsub,
90    { &replace0_0_0.value, &replace0_0_1.value },
91    NULL,
92 };
93 static const nir_search_expression replace0 = {
94    { nir_search_value_expression, 32 },
95    false, false,
96    -1, 3,
97    nir_op_fsin,
98    { &replace0_0.value },
99    NULL,
100 };
101 
102    /* search1_0 -> search0_0 in the cache */
103 static const nir_search_expression search1 = {
104    { nir_search_value_expression, 32 },
105    false, false,
106    -1, 0,
107    nir_op_fcos,
108    { &search0_0.value },
109    NULL,
110 };
111 
112    /* replace1_0_0_0 -> replace0_0_0_0 in the cache */
113 
114 /* replace1_0_0_1_0_0_0 -> replace0_0_0_1_0_0_0 in the cache */
115 
116 /* replace1_0_0_1_0_0_1 -> search0_0 in the cache */
117 /* replace1_0_0_1_0_0 -> replace0_0_0_1_0_0 in the cache */
118 
119 /* replace1_0_0_1_0_1 -> replace0_0_0_1_0_1 in the cache */
120 /* replace1_0_0_1_0 -> replace0_0_0_1_0 in the cache */
121 /* replace1_0_0_1 -> replace0_0_0_1 in the cache */
122 /* replace1_0_0 -> replace0_0_0 in the cache */
123 
124 /* replace1_0_1 -> replace0_0_1 in the cache */
125 /* replace1_0 -> replace0_0 in the cache */
126 static const nir_search_expression replace1 = {
127    { nir_search_value_expression, 32 },
128    false, false,
129    -1, 3,
130    nir_op_fcos,
131    { &replace0_0.value },
132    NULL,
133 };
134 
135 
136 static const struct transform ir3_nir_apply_trig_workarounds_state2_xforms[] = {
137   { &search0, &replace0.value, 0 },
138 };
139 static const struct transform ir3_nir_apply_trig_workarounds_state3_xforms[] = {
140   { &search1, &replace1.value, 0 },
141 };
142 
143 static const struct per_op_table ir3_nir_apply_trig_workarounds_table[nir_num_search_ops] = {
144    [nir_op_fsin] = {
145       .filter = (uint16_t []) {
146          0,
147          0,
148          0,
149          0,
150       },
151 
152       .num_filtered_states = 1,
153       .table = (uint16_t []) {
154 
155          2,
156       },
157    },
158    [nir_op_fcos] = {
159       .filter = (uint16_t []) {
160          0,
161          0,
162          0,
163          0,
164       },
165 
166       .num_filtered_states = 1,
167       .table = (uint16_t []) {
168 
169          3,
170       },
171    },
172 };
173 
174 const struct transform *ir3_nir_apply_trig_workarounds_transforms[] = {
175    NULL,
176    NULL,
177    ir3_nir_apply_trig_workarounds_state2_xforms,
178    ir3_nir_apply_trig_workarounds_state3_xforms,
179 };
180 
181 const uint16_t ir3_nir_apply_trig_workarounds_transform_counts[] = {
182    0,
183    0,
184    (uint16_t)ARRAY_SIZE(ir3_nir_apply_trig_workarounds_state2_xforms),
185    (uint16_t)ARRAY_SIZE(ir3_nir_apply_trig_workarounds_state3_xforms),
186 };
187 
188 bool
ir3_nir_apply_trig_workarounds(nir_shader * shader)189 ir3_nir_apply_trig_workarounds(nir_shader *shader)
190 {
191    bool progress = false;
192    bool condition_flags[1];
193    const nir_shader_compiler_options *options = shader->options;
194    const shader_info *info = &shader->info;
195    (void) options;
196    (void) info;
197 
198    condition_flags[0] = true;
199 
200    nir_foreach_function(function, shader) {
201       if (function->impl) {
202          progress |= nir_algebraic_impl(function->impl, condition_flags,
203                                         ir3_nir_apply_trig_workarounds_transforms,
204                                         ir3_nir_apply_trig_workarounds_transform_counts,
205                                         ir3_nir_apply_trig_workarounds_table);
206       }
207    }
208 
209    return progress;
210 }
211 
212