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 R(x) bi_register(x) 32#define DR(x) bi_discard(R(x)) 33 34static void 35strip_discard(bi_context *ctx) 36{ 37 bi_foreach_instr_global(ctx, I) { 38 bi_foreach_src(I, s) 39 I->src[s].discard = false; 40 } 41} 42 43#define CASE(test) do { \ 44 void *mem_ctx = ralloc_context(NULL); \ 45 bi_builder *A = bit_builder(mem_ctx); \ 46 bi_builder *B = bit_builder(mem_ctx); \ 47 { \ 48 UNUSED bi_builder *b = A; \ 49 test; \ 50 } \ 51 strip_discard(A->shader); \ 52 va_mark_last(A->shader); \ 53 { \ 54 UNUSED bi_builder *b = B; \ 55 test; \ 56 } \ 57 ASSERT_SHADER_EQUAL(A->shader, B->shader); \ 58 ralloc_free(mem_ctx); \ 59} while(0) 60 61TEST(MarkLast, Simple) { 62 CASE(bi_fadd_f32_to(b, R(0), DR(0), DR(1))); 63 64 CASE({ 65 bi_fadd_f32_to(b, R(2), R(0), DR(1)); 66 bi_fadd_f32_to(b, R(0), DR(0), DR(2)); 67 }); 68} 69 70TEST(MarkLast, SameSourceAndDestination) { 71 CASE({ 72 bi_fadd_f32_to(b, R(0), DR(0), DR(0)); 73 bi_fadd_f32_to(b, R(0), DR(0), DR(0)); 74 bi_fadd_f32_to(b, R(0), DR(0), DR(0)); 75 }); 76} 77 78TEST(MarkLast, StagingReadBefore) { 79 CASE({ 80 bi_fadd_f32_to(b, R(9), R(2), DR(7)); 81 bi_st_tile(b, R(0), DR(4), DR(5), DR(6), BI_REGISTER_FORMAT_F32, BI_VECSIZE_V4); 82 }); 83} 84 85TEST(MarkLast, StagingReadAfter) { 86 CASE({ 87 bi_st_tile(b, R(0), DR(4), DR(5), DR(6), BI_REGISTER_FORMAT_F32, BI_VECSIZE_V4); 88 bi_fadd_f32_to(b, R(9), R(2), DR(7)); 89 }); 90} 91 92TEST(MarkLast, NonstagingSourceToAsync) { 93 CASE({ 94 bi_st_tile(b, R(0), R(4), R(5), DR(6), BI_REGISTER_FORMAT_F32, BI_VECSIZE_V4); 95 bi_fadd_f32_to(b, R(9), DR(4), DR(5)); 96 }); 97} 98 99TEST(MarkLast, Both64) { 100 CASE(bi_load_i32_to(b, R(0), DR(8), DR(9), BI_SEG_NONE, 0)); 101} 102 103TEST(MarkLast, Neither64ThenBoth) { 104 CASE({ 105 bi_load_i32_to(b, R(0), R(8), R(9), BI_SEG_NONE, 0); 106 bi_load_i32_to(b, R(1), DR(8), DR(9), BI_SEG_NONE, 8); 107 }); 108} 109 110TEST(MarkLast, Half64) { 111 CASE({ 112 bi_load_i32_to(b, R(0), R(8), R(9), BI_SEG_NONE, 0); 113 bi_fadd_f32_to(b, R(8), DR(8), DR(8)); 114 }); 115 116 CASE({ 117 bi_load_i32_to(b, R(0), R(8), R(9), BI_SEG_NONE, 0); 118 bi_fadd_f32_to(b, R(9), DR(9), DR(9)); 119 }); 120} 121 122TEST(MarkLast, RegisterBlendDescriptor) { 123 CASE({ 124 bi_blend_to(b, bi_null(), R(0), DR(60), DR(4), DR(5), bi_null(), 125 BI_REGISTER_FORMAT_F32, 4, 0); 126 }); 127 128 CASE({ 129 bi_blend_to(b, bi_null(), R(0), DR(60), R(4), R(5), bi_null(), 130 BI_REGISTER_FORMAT_F32, 4, 0); 131 bi_fadd_f32_to(b, R(4), DR(4), DR(7)); 132 }); 133 134 CASE({ 135 bi_blend_to(b, bi_null(), R(0), DR(60), R(4), R(5), bi_null(), 136 BI_REGISTER_FORMAT_F32, 4, 0); 137 bi_fadd_f32_to(b, R(4), DR(5), DR(7)); 138 }); 139} 140 141TEST(MarkLast, ControlFlowAllFeatures) { 142 /* A 143 * / \ 144 * B C 145 */ 146 CASE({ 147 bi_block *A = bi_start_block(&b->shader->blocks); 148 bi_block *B = bit_block(b->shader); 149 bi_block *C = bit_block(b->shader); 150 151 bi_block_add_successor(A, B); 152 bi_block_add_successor(A, C); 153 154 b->cursor = bi_after_block(A); 155 { 156 bi_instr *I = 157 bi_st_tile(b, R(10), DR(14), DR(15), DR(16), 158 BI_REGISTER_FORMAT_F32, BI_VECSIZE_V4); 159 I->slot = 2; 160 161 bi_load_i32_to(b, R(20), R(28), R(29), BI_SEG_NONE, 0); 162 163 bi_fadd_f32_to(b, R(0), DR(0), R(3)); 164 bi_fadd_f32_to(b, R(0), DR(0), R(7)); 165 bi_fma_f32_to(b, R(2), R(0), R(1), DR(4)); 166 } 167 168 b->cursor = bi_after_block(B); 169 { 170 bi_fadd_f32_to(b, R(2), DR(0), DR(2)); 171 bi_fadd_f32_to(b, R(2), DR(2), DR(3)); 172 bi_fadd_f32_to(b, R(2), DR(2), DR(7)); 173 bi_fadd_f32_to(b, R(2), DR(2), DR(29)); 174 } 175 176 b->cursor = bi_after_block(C); 177 { 178 bi_fadd_f32_to(b, R(2), DR(1), DR(2)); 179 bi_fadd_f32_to(b, R(2), DR(2), DR(7)); 180 181 bi_instr *I = bi_fadd_f32_to(b, R(2), DR(2), R(13)); 182 I->flow = VA_FLOW_WAIT2; 183 184 bi_fadd_f32_to(b, R(2), DR(2), DR(11)); 185 } 186 }); 187} 188