1 /* -*- mesa-c++ -*-
2 *
3 * Copyright (c) 2021 Collabora LTD
4 *
5 * Author: Gert Wollny <gert.wollny@collabora.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * on the rights to use, copy, modify, merge, publish, distribute, sub
11 * license, and/or sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28 #include "../sfn_virtualvalues.h"
29 #include "../sfn_alu_defines.h"
30 #include "../sfn_debug.h"
31
32 #include "gtest/gtest.h"
33
34 using namespace r600;
35
36 class ValueTest : public ::testing::Test
37 {
SetUp()38 void SetUp() override {
39 init_pool();
40 }
41
TearDown()42 void TearDown() override {
43 release_pool();
44 }
45 };
46
47
48
TEST_F(ValueTest,gpr_register_fully_pinned)49 TEST_F(ValueTest, gpr_register_fully_pinned)
50 {
51 Register reg(1, 2, pin_fully);
52
53 EXPECT_EQ(reg.sel(), 1);
54 EXPECT_EQ(reg.chan(), 2);
55 EXPECT_EQ(reg.pin(), pin_fully);
56 EXPECT_FALSE(reg.is_virtual());
57
58 Register reg2(3, 1, pin_fully);
59
60 EXPECT_EQ(reg2.sel(), 3);
61 EXPECT_EQ(reg2.chan(), 1);
62 EXPECT_EQ(reg2.pin(), pin_fully);
63 EXPECT_FALSE(reg2.is_virtual());
64 }
65
66 #ifdef __cpp_exceptions
TEST_F(ValueTest,virtual_register_must_not_be_pinned_to_sel)67 TEST_F(ValueTest, virtual_register_must_not_be_pinned_to_sel)
68 {
69 EXPECT_THROW(Register(1024, 1, pin_fully), std::invalid_argument);
70 }
71 #endif
72
TEST_F(ValueTest,virtual_register_not_pinned)73 TEST_F(ValueTest, virtual_register_not_pinned)
74 {
75 Register reg(1024, 1, pin_none);
76
77 EXPECT_EQ(reg.sel(), 1024);
78 EXPECT_EQ(reg.chan(), 1);
79 EXPECT_EQ(reg.pin(), pin_none);
80 EXPECT_TRUE(reg.is_virtual());
81
82 Register reg2(1025, 2, pin_none);
83
84 EXPECT_EQ(reg2.sel(), 1025);
85 EXPECT_EQ(reg2.chan(), 2);
86 EXPECT_EQ(reg2.pin(), pin_none);
87 EXPECT_TRUE(reg2.is_virtual());
88 }
89
TEST_F(ValueTest,uniform_value)90 TEST_F(ValueTest, uniform_value)
91 {
92 UniformValue reg0(512, 1);
93
94 EXPECT_EQ(reg0.sel(), 512);
95 EXPECT_EQ(reg0.chan(), 1);
96 EXPECT_EQ(reg0.kcache_bank(), 0);
97 EXPECT_FALSE(reg0.buf_addr());
98 EXPECT_FALSE(reg0.is_virtual());
99
100 UniformValue reg1(513, 2, 1);
101
102 EXPECT_EQ(reg1.sel(), 513);
103 EXPECT_EQ(reg1.chan(), 2);
104 EXPECT_EQ(reg1.kcache_bank(), 1);
105 EXPECT_FALSE(reg1.buf_addr());
106 EXPECT_FALSE(reg1.is_virtual());
107
108 auto addr = new Register( 1024, 0, pin_none);
109 ASSERT_TRUE(addr);
110
111 UniformValue reg_with_buffer_addr(513, 0, addr);
112
113 EXPECT_EQ(reg_with_buffer_addr.sel(), 513);
114 EXPECT_EQ(reg_with_buffer_addr.chan(), 0);
115 EXPECT_EQ(reg_with_buffer_addr.pin(), pin_none);
116 EXPECT_EQ(reg_with_buffer_addr.kcache_bank(), 0);
117 EXPECT_FALSE(reg_with_buffer_addr.is_virtual());
118 ASSERT_TRUE(reg_with_buffer_addr.buf_addr());
119
120 auto baddr = reg_with_buffer_addr.buf_addr();
121 EXPECT_EQ(baddr->sel(), 1024);
122 EXPECT_EQ(baddr->chan(), 0);
123 EXPECT_EQ(baddr->pin(), pin_none);
124 EXPECT_TRUE(baddr->is_virtual());
125 }
126
TEST_F(ValueTest,literal_value)127 TEST_F(ValueTest, literal_value)
128 {
129 LiteralConstant literal(12);
130 EXPECT_EQ(literal.sel(), ALU_SRC_LITERAL);
131 EXPECT_EQ(literal.chan(), -1);
132 EXPECT_EQ(literal.value(), 12);
133 EXPECT_FALSE(literal.is_virtual());
134
135 LiteralConstant literal2(2);
136 EXPECT_EQ(literal2.sel(), ALU_SRC_LITERAL);
137 EXPECT_EQ(literal2.chan(), -1);
138 EXPECT_EQ(literal2.value(), 2);
139 EXPECT_FALSE(literal2.is_virtual());
140 }
141
TEST_F(ValueTest,inline_constant)142 TEST_F(ValueTest, inline_constant)
143 {
144 InlineConstant c0(ALU_SRC_1);
145
146 EXPECT_EQ(c0.sel(), ALU_SRC_1);
147 EXPECT_EQ(c0.chan(), 0);
148 EXPECT_FALSE(c0.is_virtual());
149
150 InlineConstant c1(ALU_SRC_M_1_INT);
151 EXPECT_EQ(c1.sel(), ALU_SRC_M_1_INT);
152 EXPECT_EQ(c1.chan(), 0);
153 EXPECT_FALSE(c1.is_virtual());
154
155 InlineConstant c2(ALU_SRC_PV, 1);
156 EXPECT_EQ(c2.sel(), ALU_SRC_PV);
157 EXPECT_EQ(c2.chan(), 1);
158 EXPECT_FALSE(c2.is_virtual());
159 }
160
TEST_F(ValueTest,array)161 TEST_F(ValueTest, array)
162 {
163 LocalArray array(1024, 2, 12);
164
165 EXPECT_EQ(array.size(), 12);
166 EXPECT_EQ(array.nchannels(), 2);
167
168 auto elm0 = array.element(0, nullptr, 0);
169 ASSERT_TRUE(elm0);
170
171 EXPECT_EQ(elm0->sel(), 1024);
172 EXPECT_EQ(elm0->chan(), 0);
173 EXPECT_EQ(elm0->pin(), pin_array);
174
175 EXPECT_FALSE(elm0->get_addr());
176
177 auto elm1 = array.element(8, nullptr, 1);
178 ASSERT_TRUE(elm1);
179
180 EXPECT_EQ(elm1->sel(), 1024 + 8);
181 EXPECT_EQ(elm1->chan(), 1);
182 EXPECT_EQ(elm1->pin(), pin_array);
183 EXPECT_FALSE(elm1->get_addr());
184
185 auto addr = new Register( 2000, 0, pin_none);
186 ASSERT_TRUE(addr);
187
188 auto elm_indirect = array.element(0, addr, 1);
189 ASSERT_TRUE(elm_indirect);
190
191 auto elm_addr = elm_indirect->get_addr();
192 ASSERT_TRUE(elm_addr);
193
194 EXPECT_EQ(elm_indirect->sel(), 1024);
195 EXPECT_EQ(elm_indirect->chan(), 1);
196 EXPECT_EQ(elm_indirect->pin(), pin_array);
197
198 EXPECT_EQ(elm_addr->sel(), 2000);
199 EXPECT_EQ(elm_addr->chan(), 0);
200 EXPECT_EQ(elm_addr->pin(), pin_none);
201
202 // A constant addr should resolve directly
203 auto addr2 = new LiteralConstant( 3);
204 ASSERT_TRUE(addr2);
205
206 auto elm_direct = array.element(0, addr2, 0);
207 auto elm_direct_addr = elm_direct->get_addr();
208 EXPECT_FALSE(elm_direct_addr);
209
210 EXPECT_EQ(elm_direct->sel(), 1027);
211 EXPECT_EQ(elm_direct->chan(), 0);
212 EXPECT_EQ(elm_direct->pin(), pin_array);
213
214 #ifdef __cpp_exceptions
215 EXPECT_THROW(array.element(12, nullptr, 0), std::invalid_argument);
216 EXPECT_THROW(array.element(3, nullptr, 2), std::invalid_argument);
217
218 auto addr3 = new LiteralConstant( 12);
219 ASSERT_TRUE(addr3);
220 EXPECT_THROW(array.element(0, addr3, 0), std::invalid_argument);
221 #endif
222 }
223
TEST_F(ValueTest,reg_from_string)224 TEST_F(ValueTest, reg_from_string)
225 {
226 Register reg(1000, 0, pin_none);
227 auto fs = Register::from_string("R1000.x");
228 EXPECT_EQ(*fs, reg);
229
230 EXPECT_EQ(*Register::from_string("R1001.y"), Register(1001, 1, pin_none));
231 EXPECT_EQ(*Register::from_string("R1.z@fully"), Register(1, 2, pin_fully));
232 EXPECT_EQ(*Register::from_string("R1000.y@chan"), Register(1000, 1, pin_chan));
233 EXPECT_EQ(*Register::from_string("R1000.y@free"), Register(1000, 1, pin_free));
234
235
236 EXPECT_EQ(*VirtualValue::from_string("L[0x1]"), LiteralConstant(1));
237 EXPECT_EQ(*VirtualValue::from_string("L[0x2]"), LiteralConstant(2));
238 EXPECT_EQ(*VirtualValue::from_string("L[0xA]"), LiteralConstant(10));
239
240 EXPECT_EQ(*VirtualValue::from_string("I[0]"), InlineConstant(ALU_SRC_0));
241 EXPECT_EQ(*VirtualValue::from_string("I[HW_WAVE_ID]"), InlineConstant(ALU_SRC_HW_WAVE_ID));
242
243
244 }
245