1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright (C) 2022 Collabora, Ltd.
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21bf215546Sopenharmony_ci * SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci#include "bi_test.h"
25bf215546Sopenharmony_ci#include "bi_builder.h"
26bf215546Sopenharmony_ci#include "va_compiler.h"
27bf215546Sopenharmony_ci#include "valhall_enums.h"
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_ci#include <gtest/gtest.h>
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_cistatic void
32bf215546Sopenharmony_cistrip_nops(bi_context *ctx)
33bf215546Sopenharmony_ci{
34bf215546Sopenharmony_ci   bi_foreach_instr_global_safe(ctx, I) {
35bf215546Sopenharmony_ci      if (I->op == BI_OPCODE_NOP)
36bf215546Sopenharmony_ci         bi_remove_instruction(I);
37bf215546Sopenharmony_ci   }
38bf215546Sopenharmony_ci}
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_ci#define CASE(shader_stage, test) do { \
41bf215546Sopenharmony_ci   bi_builder *A = bit_builder(mem_ctx); \
42bf215546Sopenharmony_ci   bi_builder *B = bit_builder(mem_ctx); \
43bf215546Sopenharmony_ci   { \
44bf215546Sopenharmony_ci      UNUSED bi_builder *b = A; \
45bf215546Sopenharmony_ci      A->shader->stage = MESA_SHADER_ ## shader_stage; \
46bf215546Sopenharmony_ci      test; \
47bf215546Sopenharmony_ci   } \
48bf215546Sopenharmony_ci   strip_nops(A->shader); \
49bf215546Sopenharmony_ci   va_insert_flow_control_nops(A->shader); \
50bf215546Sopenharmony_ci   { \
51bf215546Sopenharmony_ci      UNUSED bi_builder *b = B; \
52bf215546Sopenharmony_ci      B->shader->stage = MESA_SHADER_ ## shader_stage; \
53bf215546Sopenharmony_ci      test; \
54bf215546Sopenharmony_ci   } \
55bf215546Sopenharmony_ci   ASSERT_SHADER_EQUAL(A->shader, B->shader); \
56bf215546Sopenharmony_ci} while(0)
57bf215546Sopenharmony_ci
58bf215546Sopenharmony_ci#define flow(f) bi_nop(b)->flow = VA_FLOW_ ## f
59bf215546Sopenharmony_ci
60bf215546Sopenharmony_ciclass InsertFlow : public testing::Test {
61bf215546Sopenharmony_ciprotected:
62bf215546Sopenharmony_ci   InsertFlow() {
63bf215546Sopenharmony_ci      mem_ctx = ralloc_context(NULL);
64bf215546Sopenharmony_ci   }
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci   ~InsertFlow() {
67bf215546Sopenharmony_ci      ralloc_free(mem_ctx);
68bf215546Sopenharmony_ci   }
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_ci   void *mem_ctx;
71bf215546Sopenharmony_ci};
72bf215546Sopenharmony_ci
73bf215546Sopenharmony_ciTEST_F(InsertFlow, PreserveEmptyShader) {
74bf215546Sopenharmony_ci   CASE(FRAGMENT, {});
75bf215546Sopenharmony_ci}
76bf215546Sopenharmony_ci
77bf215546Sopenharmony_ciTEST_F(InsertFlow, TilebufferWait7) {
78bf215546Sopenharmony_ci   CASE(FRAGMENT, {
79bf215546Sopenharmony_ci        flow(DISCARD);
80bf215546Sopenharmony_ci        bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
81bf215546Sopenharmony_ci        flow(WAIT);
82bf215546Sopenharmony_ci        bi_blend_to(b, bi_register(0), bi_register(4), bi_register(5),
83bf215546Sopenharmony_ci                    bi_register(6), bi_register(7), bi_register(8),
84bf215546Sopenharmony_ci                    BI_REGISTER_FORMAT_AUTO, 4, 4);
85bf215546Sopenharmony_ci        flow(END);
86bf215546Sopenharmony_ci   });
87bf215546Sopenharmony_ci
88bf215546Sopenharmony_ci   CASE(FRAGMENT, {
89bf215546Sopenharmony_ci        flow(DISCARD);
90bf215546Sopenharmony_ci        bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
91bf215546Sopenharmony_ci        flow(WAIT);
92bf215546Sopenharmony_ci        bi_st_tile(b, bi_register(0), bi_register(4), bi_register(5),
93bf215546Sopenharmony_ci                    bi_register(6), BI_REGISTER_FORMAT_AUTO, BI_VECSIZE_V4);
94bf215546Sopenharmony_ci        flow(END);
95bf215546Sopenharmony_ci   });
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ci   CASE(FRAGMENT, {
98bf215546Sopenharmony_ci        flow(DISCARD);
99bf215546Sopenharmony_ci        bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
100bf215546Sopenharmony_ci        flow(WAIT);
101bf215546Sopenharmony_ci        bi_ld_tile_to(b, bi_register(0), bi_register(4), bi_register(5),
102bf215546Sopenharmony_ci                    bi_register(6), BI_REGISTER_FORMAT_AUTO, BI_VECSIZE_V4);
103bf215546Sopenharmony_ci        flow(END);
104bf215546Sopenharmony_ci   });
105bf215546Sopenharmony_ci}
106bf215546Sopenharmony_ci
107bf215546Sopenharmony_ciTEST_F(InsertFlow, AtestWait6AndWait0After) {
108bf215546Sopenharmony_ci   CASE(FRAGMENT, {
109bf215546Sopenharmony_ci        flow(DISCARD);
110bf215546Sopenharmony_ci        bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
111bf215546Sopenharmony_ci        flow(WAIT0126);
112bf215546Sopenharmony_ci        bi_atest_to(b, bi_register(0), bi_register(4), bi_register(5));
113bf215546Sopenharmony_ci        flow(WAIT0);
114bf215546Sopenharmony_ci        flow(END);
115bf215546Sopenharmony_ci   });
116bf215546Sopenharmony_ci}
117bf215546Sopenharmony_ci
118bf215546Sopenharmony_ciTEST_F(InsertFlow, ZSEmitWait6) {
119bf215546Sopenharmony_ci   CASE(FRAGMENT, {
120bf215546Sopenharmony_ci        flow(DISCARD);
121bf215546Sopenharmony_ci        bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
122bf215546Sopenharmony_ci        flow(WAIT0126);
123bf215546Sopenharmony_ci        bi_zs_emit_to(b, bi_register(0), bi_register(4), bi_register(5),
124bf215546Sopenharmony_ci                      bi_register(6), true, true);
125bf215546Sopenharmony_ci        flow(END);
126bf215546Sopenharmony_ci   });
127bf215546Sopenharmony_ci}
128bf215546Sopenharmony_ci
129bf215546Sopenharmony_ciTEST_F(InsertFlow, LoadThenUnrelatedThenUse) {
130bf215546Sopenharmony_ci   CASE(VERTEX, {
131bf215546Sopenharmony_ci         bi_ld_attr_imm_to(b, bi_register(16), bi_register(60), bi_register(61),
132bf215546Sopenharmony_ci                           BI_REGISTER_FORMAT_F32, BI_VECSIZE_V4, 1);
133bf215546Sopenharmony_ci         bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
134bf215546Sopenharmony_ci         flow(WAIT0);
135bf215546Sopenharmony_ci         bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(19));
136bf215546Sopenharmony_ci         flow(END);
137bf215546Sopenharmony_ci   });
138bf215546Sopenharmony_ci}
139bf215546Sopenharmony_ci
140bf215546Sopenharmony_ciTEST_F(InsertFlow, SingleLdVar) {
141bf215546Sopenharmony_ci   CASE(FRAGMENT, {
142bf215546Sopenharmony_ci         flow(DISCARD);
143bf215546Sopenharmony_ci         bi_ld_var_buf_imm_f16_to(b, bi_register(2), bi_register(61),
144bf215546Sopenharmony_ci                                 BI_REGISTER_FORMAT_F16, BI_SAMPLE_CENTER,
145bf215546Sopenharmony_ci                                 BI_SOURCE_FORMAT_F16,
146bf215546Sopenharmony_ci                                 BI_UPDATE_RETRIEVE, BI_VECSIZE_V4, 0);
147bf215546Sopenharmony_ci         flow(WAIT0);
148bf215546Sopenharmony_ci         flow(END);
149bf215546Sopenharmony_ci   });
150bf215546Sopenharmony_ci}
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_ciTEST_F(InsertFlow, SerializeLdVars) {
153bf215546Sopenharmony_ci   CASE(FRAGMENT, {
154bf215546Sopenharmony_ci         flow(DISCARD);
155bf215546Sopenharmony_ci         bi_ld_var_buf_imm_f16_to(b, bi_register(16), bi_register(61),
156bf215546Sopenharmony_ci                                 BI_REGISTER_FORMAT_F16, BI_SAMPLE_CENTER,
157bf215546Sopenharmony_ci                                 BI_SOURCE_FORMAT_F16,
158bf215546Sopenharmony_ci                                 BI_UPDATE_STORE, BI_VECSIZE_V4, 0);
159bf215546Sopenharmony_ci         bi_ld_var_buf_imm_f16_to(b, bi_register(2), bi_register(61),
160bf215546Sopenharmony_ci                                 BI_REGISTER_FORMAT_F16, BI_SAMPLE_CENTER,
161bf215546Sopenharmony_ci                                 BI_SOURCE_FORMAT_F16,
162bf215546Sopenharmony_ci                                 BI_UPDATE_RETRIEVE, BI_VECSIZE_V4, 0);
163bf215546Sopenharmony_ci         flow(WAIT0);
164bf215546Sopenharmony_ci         bi_ld_var_buf_imm_f16_to(b, bi_register(8), bi_register(61),
165bf215546Sopenharmony_ci                                 BI_REGISTER_FORMAT_F16, BI_SAMPLE_CENTER,
166bf215546Sopenharmony_ci                                 BI_SOURCE_FORMAT_F16,
167bf215546Sopenharmony_ci                                 BI_UPDATE_STORE, BI_VECSIZE_V4, 1);
168bf215546Sopenharmony_ci         flow(WAIT0);
169bf215546Sopenharmony_ci         flow(END);
170bf215546Sopenharmony_ci   });
171bf215546Sopenharmony_ci}
172bf215546Sopenharmony_ci
173bf215546Sopenharmony_ciTEST_F(InsertFlow, Clper) {
174bf215546Sopenharmony_ci   CASE(FRAGMENT, {
175bf215546Sopenharmony_ci         bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
176bf215546Sopenharmony_ci         bi_clper_i32_to(b, bi_register(0), bi_register(4), bi_register(8),
177bf215546Sopenharmony_ci                         BI_INACTIVE_RESULT_ZERO, BI_LANE_OP_NONE,
178bf215546Sopenharmony_ci                         BI_SUBGROUP_SUBGROUP4);
179bf215546Sopenharmony_ci         flow(DISCARD);
180bf215546Sopenharmony_ci         bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
181bf215546Sopenharmony_ci         flow(END);
182bf215546Sopenharmony_ci   });
183bf215546Sopenharmony_ci}
184bf215546Sopenharmony_ci
185bf215546Sopenharmony_ciTEST_F(InsertFlow, TextureImplicit) {
186bf215546Sopenharmony_ci   CASE(FRAGMENT, {
187bf215546Sopenharmony_ci         bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
188bf215546Sopenharmony_ci         bi_tex_single_to(b, bi_register(0), bi_register(4), bi_register(8),
189bf215546Sopenharmony_ci                          bi_register(12), false, BI_DIMENSION_2D,
190bf215546Sopenharmony_ci                          BI_REGISTER_FORMAT_F32, false, false,
191bf215546Sopenharmony_ci                          BI_VA_LOD_MODE_COMPUTED_LOD, BI_WRITE_MASK_RGBA, 4);
192bf215546Sopenharmony_ci         flow(DISCARD);
193bf215546Sopenharmony_ci         flow(WAIT0);
194bf215546Sopenharmony_ci         bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
195bf215546Sopenharmony_ci         flow(END);
196bf215546Sopenharmony_ci   });
197bf215546Sopenharmony_ci}
198bf215546Sopenharmony_ci
199bf215546Sopenharmony_ciTEST_F(InsertFlow, TextureExplicit) {
200bf215546Sopenharmony_ci   CASE(FRAGMENT, {
201bf215546Sopenharmony_ci         flow(DISCARD);
202bf215546Sopenharmony_ci         bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
203bf215546Sopenharmony_ci         bi_tex_single_to(b, bi_register(0), bi_register(4), bi_register(8),
204bf215546Sopenharmony_ci                          bi_register(12), false, BI_DIMENSION_2D,
205bf215546Sopenharmony_ci                          BI_REGISTER_FORMAT_F32, false, false,
206bf215546Sopenharmony_ci                          BI_VA_LOD_MODE_ZERO_LOD, BI_WRITE_MASK_RGBA, 4);
207bf215546Sopenharmony_ci         flow(WAIT0);
208bf215546Sopenharmony_ci         bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
209bf215546Sopenharmony_ci         flow(END);
210bf215546Sopenharmony_ci   });
211bf215546Sopenharmony_ci}
212bf215546Sopenharmony_ci
213bf215546Sopenharmony_ci/*      A
214bf215546Sopenharmony_ci *     / \
215bf215546Sopenharmony_ci *    B   C
216bf215546Sopenharmony_ci *     \ /
217bf215546Sopenharmony_ci *      D
218bf215546Sopenharmony_ci */
219bf215546Sopenharmony_ciTEST_F(InsertFlow, DiamondCFG) {
220bf215546Sopenharmony_ci   CASE(FRAGMENT, {
221bf215546Sopenharmony_ci         bi_block *A = bi_start_block(&b->shader->blocks);
222bf215546Sopenharmony_ci         bi_block *B = bit_block(b->shader);
223bf215546Sopenharmony_ci         bi_block *C = bit_block(b->shader);
224bf215546Sopenharmony_ci         bi_block *D = bit_block(b->shader);
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_ci         bi_block_add_successor(A, B);
227bf215546Sopenharmony_ci         bi_block_add_successor(A, C);
228bf215546Sopenharmony_ci
229bf215546Sopenharmony_ci         bi_block_add_successor(B, D);
230bf215546Sopenharmony_ci         bi_block_add_successor(C, D);
231bf215546Sopenharmony_ci
232bf215546Sopenharmony_ci         /* B uses helper invocations, no other block does.
233bf215546Sopenharmony_ci          *
234bf215546Sopenharmony_ci          * That means B and C need to discard helpers.
235bf215546Sopenharmony_ci          */
236bf215546Sopenharmony_ci         b->cursor = bi_after_block(B);
237bf215546Sopenharmony_ci         bi_clper_i32_to(b, bi_register(0), bi_register(4), bi_register(8),
238bf215546Sopenharmony_ci               BI_INACTIVE_RESULT_ZERO, BI_LANE_OP_NONE,
239bf215546Sopenharmony_ci               BI_SUBGROUP_SUBGROUP4);
240bf215546Sopenharmony_ci         flow(DISCARD);
241bf215546Sopenharmony_ci         flow(RECONVERGE);
242bf215546Sopenharmony_ci
243bf215546Sopenharmony_ci         b->cursor = bi_after_block(C);
244bf215546Sopenharmony_ci         flow(DISCARD);
245bf215546Sopenharmony_ci         bi_fadd_f32_to(b, bi_register(0), bi_register(0), bi_register(0));
246bf215546Sopenharmony_ci         flow(RECONVERGE);
247bf215546Sopenharmony_ci
248bf215546Sopenharmony_ci         b->cursor = bi_after_block(D);
249bf215546Sopenharmony_ci         flow(END);
250bf215546Sopenharmony_ci   });
251bf215546Sopenharmony_ci}
252bf215546Sopenharmony_ci
253bf215546Sopenharmony_ciTEST_F(InsertFlow, BarrierBug) {
254bf215546Sopenharmony_ci   CASE(KERNEL, {
255bf215546Sopenharmony_ci         bi_instr *I = bi_store_i32(b, bi_register(0), bi_register(2), bi_register(4), BI_SEG_NONE, 0);
256bf215546Sopenharmony_ci         I->slot = 2;
257bf215546Sopenharmony_ci
258bf215546Sopenharmony_ci         bi_fadd_f32_to(b, bi_register(10), bi_register(10), bi_register(10));
259bf215546Sopenharmony_ci         flow(WAIT2);
260bf215546Sopenharmony_ci         bi_barrier(b);
261bf215546Sopenharmony_ci         flow(WAIT);
262bf215546Sopenharmony_ci         flow(END);
263bf215546Sopenharmony_ci   });
264bf215546Sopenharmony_ci}
265