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