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