• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_test.h"
25 #include "bi_builder.h"
26 #include "va_compiler.h"
27 #include "valhall_enums.h"
28 
29 #include <gtest/gtest.h>
30 
31 #define CASE(test, expected) do { \
32    bi_builder *A = bit_builder(mem_ctx); \
33    bi_builder *B = bit_builder(mem_ctx); \
34    { \
35       bi_builder *b = A; \
36       A->shader->stage = MESA_SHADER_FRAGMENT; \
37       test; \
38    } \
39    va_merge_flow(A->shader); \
40    { \
41       bi_builder *b = B; \
42       B->shader->stage = MESA_SHADER_FRAGMENT; \
43       expected; \
44    } \
45    ASSERT_SHADER_EQUAL(A->shader, B->shader); \
46 } while(0)
47 
48 #define NEGCASE(test) CASE(test, test)
49 
50 #define flow(f) bi_nop(b)->flow = VA_FLOW_ ## f
51 
52 class MergeFlow : public testing::Test {
53 protected:
MergeFlow()54    MergeFlow() {
55       mem_ctx = ralloc_context(NULL);
56    }
57 
~MergeFlow()58    ~MergeFlow() {
59       ralloc_free(mem_ctx);
60    }
61 
62    void *mem_ctx;
63    bi_instr *I;
64 };
65 
TEST_F(MergeFlow,End)66 TEST_F(MergeFlow, End) {
67    CASE({
68         bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
69         bi_blend_to(b, bi_register(0), bi_register(4), bi_register(5),
70                     bi_register(6), bi_register(7), bi_register(8),
71                     BI_REGISTER_FORMAT_AUTO, 4, 4);
72         flow(END);
73    },
74    {
75         bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
76         I = 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         I->flow = VA_FLOW_END;
80    });
81 }
82 
TEST_F(MergeFlow,Reconverge)83 TEST_F(MergeFlow, Reconverge) {
84    CASE({
85         bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
86         bi_blend_to(b, bi_register(0), bi_register(4), bi_register(5),
87                     bi_register(6), bi_register(7), bi_register(8),
88                     BI_REGISTER_FORMAT_AUTO, 4, 4);
89         flow(RECONVERGE);
90    },
91    {
92         bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
93         I = bi_blend_to(b, bi_register(0), bi_register(4), bi_register(5),
94                         bi_register(6), bi_register(7), bi_register(8),
95                         BI_REGISTER_FORMAT_AUTO, 4, 4);
96         I->flow = VA_FLOW_RECONVERGE;
97    });
98 }
99 
TEST_F(MergeFlow,TrivialWait)100 TEST_F(MergeFlow, TrivialWait) {
101    CASE({
102         bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
103         flow(WAIT0126);
104         bi_atest_to(b, bi_register(0), bi_register(4), bi_register(5));
105    },
106    {
107         I = bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
108         I->flow = VA_FLOW_WAIT0126;
109         bi_atest_to(b, bi_register(0), bi_register(4), bi_register(5));
110    });
111 }
112 
TEST_F(MergeFlow,LoadThenUnrelatedThenUse)113 TEST_F(MergeFlow, LoadThenUnrelatedThenUse) {
114    CASE({
115          bi_ld_attr_imm_to(b, bi_register(16), bi_register(60), bi_register(61),
116                            BI_REGISTER_FORMAT_F32, BI_VECSIZE_V4, 1);
117          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
118          flow(WAIT0);
119          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(19));
120          flow(END);
121    },
122    {
123          bi_ld_attr_imm_to(b, bi_register(16), bi_register(60), bi_register(61),
124                            BI_REGISTER_FORMAT_F32, BI_VECSIZE_V4, 1);
125          I = bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
126          I->flow = VA_FLOW_WAIT0;
127          I = bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(19));
128          I->flow = VA_FLOW_END;
129    });
130 }
131 
TEST_F(MergeFlow,TrivialDiscard)132 TEST_F(MergeFlow, TrivialDiscard) {
133    CASE({
134          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
135          bi_clper_i32_to(b, bi_register(0), bi_register(4), bi_register(8),
136                          BI_INACTIVE_RESULT_ZERO, BI_LANE_OP_NONE,
137                          BI_SUBGROUP_SUBGROUP4);
138          flow(DISCARD);
139          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
140          flow(END);
141    },
142    {
143          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
144          I = bi_clper_i32_to(b, bi_register(0), bi_register(4), bi_register(8),
145                          BI_INACTIVE_RESULT_ZERO, BI_LANE_OP_NONE,
146                          BI_SUBGROUP_SUBGROUP4);
147          I->flow = VA_FLOW_DISCARD;
148          I = bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
149          I->flow = VA_FLOW_END;
150    });
151 }
152 
TEST_F(MergeFlow,TrivialDiscardAtTheStart)153 TEST_F(MergeFlow, TrivialDiscardAtTheStart) {
154    CASE({
155          flow(DISCARD);
156          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
157    },
158    {
159          I = bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
160          I->flow = VA_FLOW_DISCARD;
161    });
162 }
163 
TEST_F(MergeFlow,MoveDiscardPastWait)164 TEST_F(MergeFlow, MoveDiscardPastWait) {
165    CASE({
166          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
167          bi_clper_i32_to(b, bi_register(0), bi_register(4), bi_register(8),
168                          BI_INACTIVE_RESULT_ZERO, BI_LANE_OP_NONE,
169                          BI_SUBGROUP_SUBGROUP4);
170          flow(DISCARD);
171          flow(WAIT0);
172          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
173    },
174    {
175          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
176          I = bi_clper_i32_to(b, bi_register(0), bi_register(4), bi_register(8),
177                          BI_INACTIVE_RESULT_ZERO, BI_LANE_OP_NONE,
178                          BI_SUBGROUP_SUBGROUP4);
179          I->flow = VA_FLOW_WAIT0;
180          I = bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
181          I->flow = VA_FLOW_DISCARD;
182    });
183 }
184 
TEST_F(MergeFlow,OccludedWaitsAndDiscard)185 TEST_F(MergeFlow, OccludedWaitsAndDiscard) {
186    CASE({
187          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
188          bi_clper_i32_to(b, bi_register(0), bi_register(4), bi_register(8),
189                          BI_INACTIVE_RESULT_ZERO, BI_LANE_OP_NONE,
190                          BI_SUBGROUP_SUBGROUP4);
191          flow(WAIT0);
192          flow(DISCARD);
193          flow(WAIT2);
194          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
195    },
196    {
197          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
198          I = bi_clper_i32_to(b, bi_register(0), bi_register(4), bi_register(8),
199                          BI_INACTIVE_RESULT_ZERO, BI_LANE_OP_NONE,
200                          BI_SUBGROUP_SUBGROUP4);
201          I->flow = VA_FLOW_WAIT02;
202          I = bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
203          I->flow = VA_FLOW_DISCARD;
204    });
205 }
206 
TEST_F(MergeFlow,DeleteUselessWaits)207 TEST_F(MergeFlow, DeleteUselessWaits) {
208    CASE({
209          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
210          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
211          flow(WAIT0);
212          flow(WAIT2);
213          flow(END);
214    },
215    {
216          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
217          I = bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
218          I->flow = VA_FLOW_END;
219    });
220 }
221 
TEST_F(MergeFlow,BlockFullOfUselessWaits)222 TEST_F(MergeFlow, BlockFullOfUselessWaits) {
223    CASE({
224          flow(WAIT0);
225          flow(WAIT2);
226          flow(DISCARD);
227          flow(END);
228    },
229    {
230          flow(END);
231    });
232 }
233 
TEST_F(MergeFlow,WaitWithMessage)234 TEST_F(MergeFlow, WaitWithMessage) {
235    CASE({
236          bi_ld_attr_imm_to(b, bi_register(16), bi_register(60), bi_register(61),
237                            BI_REGISTER_FORMAT_F32, BI_VECSIZE_V4, 1);
238          flow(WAIT0);
239    },
240    {
241          I = bi_ld_attr_imm_to(b, bi_register(16), bi_register(60), bi_register(61),
242                                BI_REGISTER_FORMAT_F32, BI_VECSIZE_V4, 1);
243          I->flow = VA_FLOW_WAIT0;
244    });
245 }
246 
TEST_F(MergeFlow,CantMoveWaitPastMessage)247 TEST_F(MergeFlow, CantMoveWaitPastMessage) {
248    NEGCASE({
249          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
250          I = bi_ld_attr_imm_to(b, bi_register(16), bi_register(60), bi_register(61),
251                            BI_REGISTER_FORMAT_F32, BI_VECSIZE_V4, 1);
252 
253          /* Pretend it's blocked for some reason. This doesn't actually happen
254           * with the current algorithm, but it's good to handle the special
255           * cases correctly in case we change later on.
256           */
257          I->flow = VA_FLOW_DISCARD;
258          flow(WAIT0);
259    });
260 }
261 
TEST_F(MergeFlow,DeletePointlessDiscard)262 TEST_F(MergeFlow, DeletePointlessDiscard) {
263    CASE({
264          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
265          bi_tex_single_to(b, bi_register(0), bi_register(4), bi_register(8),
266                           bi_register(12), false, BI_DIMENSION_2D,
267                           BI_REGISTER_FORMAT_F32, false, false,
268                           BI_VA_LOD_MODE_COMPUTED_LOD, BI_WRITE_MASK_RGBA, 4);
269          flow(DISCARD);
270          flow(WAIT0);
271          flow(WAIT0126);
272          bi_atest_to(b, bi_register(0), bi_register(4), bi_register(5));
273          flow(WAIT);
274          bi_blend_to(b, bi_register(0), bi_register(4), bi_register(5),
275                      bi_register(6), bi_register(7), bi_register(8),
276                      BI_REGISTER_FORMAT_AUTO, 4, 4);
277          flow(END);
278    },
279    {
280          bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
281          I = bi_tex_single_to(b, bi_register(0), bi_register(4), bi_register(8),
282                           bi_register(12), false, BI_DIMENSION_2D,
283                           BI_REGISTER_FORMAT_F32, false, false,
284                           BI_VA_LOD_MODE_COMPUTED_LOD, BI_WRITE_MASK_RGBA, 4);
285          I->flow = VA_FLOW_WAIT0126;
286          I = bi_atest_to(b, bi_register(0), bi_register(4), bi_register(5));
287          I->flow = VA_FLOW_WAIT;
288          I = bi_blend_to(b, bi_register(0), bi_register(4), bi_register(5),
289                          bi_register(6), bi_register(7), bi_register(8),
290                          BI_REGISTER_FORMAT_AUTO, 4, 4);
291          I->flow = VA_FLOW_END;
292    });
293 }
294 
TEST_F(MergeFlow,PreserveTerminalBarriers)295 TEST_F(MergeFlow, PreserveTerminalBarriers) {
296    CASE({
297          bi_barrier(b);
298          flow(WAIT);
299          flow(END);
300    },
301    {
302          bi_barrier(b)->flow = VA_FLOW_WAIT;
303          flow(END);
304    });
305 }
306