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