xref: /aosp_15_r20/external/mesa3d/src/panfrost/compiler/valhall/test/test-merge-flow.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright (C) 2022 Collabora, Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23 
24 #include "bi_builder.h"
25 #include "bi_test.h"
26 #include "va_compiler.h"
27 #include "valhall_enums.h"
28 
29 #include <gtest/gtest.h>
30 
31 #define CASE(test, expected)                                                   \
32    do {                                                                        \
33       bi_builder *A = bit_builder(mem_ctx);                                    \
34       bi_builder *B = bit_builder(mem_ctx);                                    \
35       {                                                                        \
36          bi_builder *b = A;                                                    \
37          A->shader->stage = MESA_SHADER_FRAGMENT;                              \
38          test;                                                                 \
39       }                                                                        \
40       va_merge_flow(A->shader);                                                \
41       {                                                                        \
42          bi_builder *b = B;                                                    \
43          B->shader->stage = MESA_SHADER_FRAGMENT;                              \
44          expected;                                                             \
45       }                                                                        \
46       ASSERT_SHADER_EQUAL(A->shader, B->shader);                               \
47    } while (0)
48 
49 #define NEGCASE(test) CASE(test, test)
50 
51 #define flow(f) bi_nop(b)->flow = VA_FLOW_##f
52 
53 class MergeFlow : public testing::Test {
54  protected:
MergeFlow()55    MergeFlow()
56    {
57       mem_ctx = ralloc_context(NULL);
58       atest = bi_fau(BIR_FAU_ATEST_PARAM, false);
59    }
60 
~MergeFlow()61    ~MergeFlow()
62    {
63       ralloc_free(mem_ctx);
64    }
65 
66    void *mem_ctx;
67    bi_instr *I;
68    bi_index atest;
69 };
70 
TEST_F(MergeFlow,End)71 TEST_F(MergeFlow, End)
72 {
73    CASE(
74       {
75          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
76          bi_blend_to(b, bi_register(0), bi_register(4), bi_register(5),
77                      bi_register(6), bi_register(7), bi_register(8),
78                      BI_REGISTER_FORMAT_AUTO, 4, 4);
79          flow(END);
80       },
81       {
82          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
83          I = bi_blend_to(b, bi_register(0), bi_register(4), bi_register(5),
84                          bi_register(6), bi_register(7), bi_register(8),
85                          BI_REGISTER_FORMAT_AUTO, 4, 4);
86          I->flow = VA_FLOW_END;
87       });
88 }
89 
TEST_F(MergeFlow,Reconverge)90 TEST_F(MergeFlow, Reconverge)
91 {
92    CASE(
93       {
94          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
95          bi_blend_to(b, bi_register(0), bi_register(4), bi_register(5),
96                      bi_register(6), bi_register(7), bi_register(8),
97                      BI_REGISTER_FORMAT_AUTO, 4, 4);
98          flow(RECONVERGE);
99       },
100       {
101          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
102          I = bi_blend_to(b, bi_register(0), bi_register(4), bi_register(5),
103                          bi_register(6), bi_register(7), bi_register(8),
104                          BI_REGISTER_FORMAT_AUTO, 4, 4);
105          I->flow = VA_FLOW_RECONVERGE;
106       });
107 }
108 
TEST_F(MergeFlow,TrivialWait)109 TEST_F(MergeFlow, TrivialWait)
110 {
111    CASE(
112       {
113          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
114          flow(WAIT0126);
115          bi_atest_to(b, bi_register(0), bi_register(4), bi_register(5), atest);
116       },
117       {
118          I = bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
119          I->flow = VA_FLOW_WAIT0126;
120          bi_atest_to(b, bi_register(0), bi_register(4), bi_register(5), atest);
121       });
122 }
123 
TEST_F(MergeFlow,LoadThenUnrelatedThenUse)124 TEST_F(MergeFlow, LoadThenUnrelatedThenUse)
125 {
126    CASE(
127       {
128          bi_ld_attr_imm_to(b, bi_register(16), bi_register(60), bi_register(61),
129                            BI_REGISTER_FORMAT_F32, BI_VECSIZE_V4, 1);
130          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
131          flow(WAIT0);
132          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(19));
133          flow(END);
134       },
135       {
136          bi_ld_attr_imm_to(b, bi_register(16), bi_register(60), bi_register(61),
137                            BI_REGISTER_FORMAT_F32, BI_VECSIZE_V4, 1);
138          I = bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
139          I->flow = VA_FLOW_WAIT0;
140          I = bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(19));
141          I->flow = VA_FLOW_END;
142       });
143 }
144 
TEST_F(MergeFlow,TrivialDiscard)145 TEST_F(MergeFlow, TrivialDiscard)
146 {
147    CASE(
148       {
149          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
150          bi_clper_i32_to(b, bi_register(0), bi_register(4), bi_register(8),
151                          BI_INACTIVE_RESULT_ZERO, BI_LANE_OP_NONE,
152                          BI_SUBGROUP_SUBGROUP4);
153          flow(DISCARD);
154          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
155          flow(END);
156       },
157       {
158          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
159          I = bi_clper_i32_to(b, bi_register(0), bi_register(4), bi_register(8),
160                              BI_INACTIVE_RESULT_ZERO, BI_LANE_OP_NONE,
161                              BI_SUBGROUP_SUBGROUP4);
162          I->flow = VA_FLOW_DISCARD;
163          I = bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
164          I->flow = VA_FLOW_END;
165       });
166 }
167 
TEST_F(MergeFlow,TrivialDiscardAtTheStart)168 TEST_F(MergeFlow, TrivialDiscardAtTheStart)
169 {
170    CASE(
171       {
172          flow(DISCARD);
173          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
174       },
175       {
176          I = bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
177          I->flow = VA_FLOW_DISCARD;
178       });
179 }
180 
TEST_F(MergeFlow,MoveDiscardPastWait)181 TEST_F(MergeFlow, MoveDiscardPastWait)
182 {
183    CASE(
184       {
185          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
186          bi_clper_i32_to(b, bi_register(0), bi_register(4), bi_register(8),
187                          BI_INACTIVE_RESULT_ZERO, BI_LANE_OP_NONE,
188                          BI_SUBGROUP_SUBGROUP4);
189          flow(DISCARD);
190          flow(WAIT0);
191          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
192       },
193       {
194          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
195          I = bi_clper_i32_to(b, bi_register(0), bi_register(4), bi_register(8),
196                              BI_INACTIVE_RESULT_ZERO, BI_LANE_OP_NONE,
197                              BI_SUBGROUP_SUBGROUP4);
198          I->flow = VA_FLOW_WAIT0;
199          I = bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
200          I->flow = VA_FLOW_DISCARD;
201       });
202 }
203 
TEST_F(MergeFlow,OccludedWaitsAndDiscard)204 TEST_F(MergeFlow, OccludedWaitsAndDiscard)
205 {
206    CASE(
207       {
208          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
209          bi_clper_i32_to(b, bi_register(0), bi_register(4), bi_register(8),
210                          BI_INACTIVE_RESULT_ZERO, BI_LANE_OP_NONE,
211                          BI_SUBGROUP_SUBGROUP4);
212          flow(WAIT0);
213          flow(DISCARD);
214          flow(WAIT2);
215          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
216       },
217       {
218          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
219          I = bi_clper_i32_to(b, bi_register(0), bi_register(4), bi_register(8),
220                              BI_INACTIVE_RESULT_ZERO, BI_LANE_OP_NONE,
221                              BI_SUBGROUP_SUBGROUP4);
222          I->flow = VA_FLOW_WAIT02;
223          I = bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
224          I->flow = VA_FLOW_DISCARD;
225       });
226 }
227 
TEST_F(MergeFlow,DeleteUselessWaits)228 TEST_F(MergeFlow, DeleteUselessWaits)
229 {
230    CASE(
231       {
232          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
233          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
234          flow(WAIT0);
235          flow(WAIT2);
236          flow(END);
237       },
238       {
239          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
240          I = bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
241          I->flow = VA_FLOW_END;
242       });
243 }
244 
TEST_F(MergeFlow,BlockFullOfUselessWaits)245 TEST_F(MergeFlow, BlockFullOfUselessWaits)
246 {
247    CASE(
248       {
249          flow(WAIT0);
250          flow(WAIT2);
251          flow(DISCARD);
252          flow(END);
253       },
254       { flow(END); });
255 }
256 
TEST_F(MergeFlow,WaitWithMessage)257 TEST_F(MergeFlow, WaitWithMessage)
258 {
259    CASE(
260       {
261          bi_ld_attr_imm_to(b, bi_register(16), bi_register(60), bi_register(61),
262                            BI_REGISTER_FORMAT_F32, BI_VECSIZE_V4, 1);
263          flow(WAIT0);
264       },
265       {
266          I = bi_ld_attr_imm_to(b, bi_register(16), bi_register(60),
267                                bi_register(61), BI_REGISTER_FORMAT_F32,
268                                BI_VECSIZE_V4, 1);
269          I->flow = VA_FLOW_WAIT0;
270       });
271 }
272 
TEST_F(MergeFlow,CantMoveWaitPastMessage)273 TEST_F(MergeFlow, CantMoveWaitPastMessage)
274 {
275    NEGCASE({
276       bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
277       I =
278          bi_ld_attr_imm_to(b, bi_register(16), bi_register(60), bi_register(61),
279                            BI_REGISTER_FORMAT_F32, BI_VECSIZE_V4, 1);
280 
281       /* Pretend it's blocked for some reason. This doesn't actually happen
282        * with the current algorithm, but it's good to handle the special
283        * cases correctly in case we change later on.
284        */
285       I->flow = VA_FLOW_DISCARD;
286       flow(WAIT0);
287    });
288 }
289 
TEST_F(MergeFlow,DeletePointlessDiscard)290 TEST_F(MergeFlow, DeletePointlessDiscard)
291 {
292    CASE(
293       {
294          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
295          bi_tex_single_to(
296             b, bi_register(0), bi_register(4), bi_register(8), bi_register(12),
297             false, BI_DIMENSION_2D, BI_REGISTER_FORMAT_F32, false, false,
298             BI_VA_LOD_MODE_COMPUTED_LOD, false, BI_WRITE_MASK_RGBA, 4);
299          flow(DISCARD);
300          flow(WAIT0);
301          flow(WAIT0126);
302          bi_atest_to(b, bi_register(0), bi_register(4), bi_register(5), atest);
303          flow(WAIT);
304          bi_blend_to(b, bi_register(0), bi_register(4), bi_register(5),
305                      bi_register(6), bi_register(7), bi_register(8),
306                      BI_REGISTER_FORMAT_AUTO, 4, 4);
307          flow(END);
308       },
309       {
310          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
311          I = bi_tex_single_to(
312             b, bi_register(0), bi_register(4), bi_register(8), bi_register(12),
313             false, BI_DIMENSION_2D, BI_REGISTER_FORMAT_F32, false, false,
314             BI_VA_LOD_MODE_COMPUTED_LOD, false, BI_WRITE_MASK_RGBA, 4);
315          I->flow = VA_FLOW_WAIT0126;
316          I = bi_atest_to(b, bi_register(0), bi_register(4), bi_register(5),
317                          atest);
318          I->flow = VA_FLOW_WAIT;
319          I = bi_blend_to(b, bi_register(0), bi_register(4), bi_register(5),
320                          bi_register(6), bi_register(7), bi_register(8),
321                          BI_REGISTER_FORMAT_AUTO, 4, 4);
322          I->flow = VA_FLOW_END;
323       });
324 }
325 
TEST_F(MergeFlow,PreserveTerminalBarriers)326 TEST_F(MergeFlow, PreserveTerminalBarriers)
327 {
328    CASE(
329       {
330          bi_barrier(b);
331          flow(WAIT);
332          flow(END);
333       },
334       {
335          bi_barrier(b)->flow = VA_FLOW_WAIT;
336          flow(END);
337       });
338 }
339