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