glsl: Mark a set of array elements as accessed using a list of array_deref_range
[mesa.git] / src / compiler / glsl / tests / array_refcount_test.cpp
1 /*
2 * Copyright © 2016 Intel Corporation
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
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23 #include <gtest/gtest.h>
24 #include "ir.h"
25 #include "ir_array_refcount.h"
26
27 class array_refcount_test : public ::testing::Test {
28 public:
29 virtual void SetUp();
30 virtual void TearDown();
31
32 void *mem_ctx;
33
34 /**
35 * glsl_type for a vec4[3][4][5].
36 *
37 * The exceptionally verbose name is picked because it matches the syntax
38 * of http://cdecl.org/.
39 */
40 const glsl_type *array_3_of_array_4_of_array_5_of_vec4;
41
42 /**
43 * Wrapper to access private member "bits" of ir_array_refcount_entry
44 *
45 * The test class is a friend to ir_array_refcount_entry, but the
46 * individual tests are not part of the class. Since the friendliness of
47 * the test class does not extend to the tests, provide a wrapper.
48 */
49 const BITSET_WORD *get_bits(const ir_array_refcount_entry &entry)
50 {
51 return entry.bits;
52 }
53
54 /**
55 * Wrapper to access private member "num_bits" of ir_array_refcount_entry
56 *
57 * The test class is a friend to ir_array_refcount_entry, but the
58 * individual tests are not part of the class. Since the friendliness of
59 * the test class does not extend to the tests, provide a wrapper.
60 */
61 unsigned get_num_bits(const ir_array_refcount_entry &entry)
62 {
63 return entry.num_bits;
64 }
65
66 /**
67 * Wrapper to access private member "array_depth" of ir_array_refcount_entry
68 *
69 * The test class is a friend to ir_array_refcount_entry, but the
70 * individual tests are not part of the class. Since the friendliness of
71 * the test class does not extend to the tests, provide a wrapper.
72 */
73 unsigned get_array_depth(const ir_array_refcount_entry &entry)
74 {
75 return entry.array_depth;
76 }
77 };
78
79 void
80 array_refcount_test::SetUp()
81 {
82 mem_ctx = ralloc_context(NULL);
83
84 /* The type of vec4 x[3][4][5]; */
85 const glsl_type *const array_5_of_vec4 =
86 glsl_type::get_array_instance(glsl_type::vec4_type, 5);
87 const glsl_type *const array_4_of_array_5_of_vec4 =
88 glsl_type::get_array_instance(array_5_of_vec4, 4);
89 array_3_of_array_4_of_array_5_of_vec4 =
90 glsl_type::get_array_instance(array_4_of_array_5_of_vec4, 3);
91 }
92
93 void
94 array_refcount_test::TearDown()
95 {
96 ralloc_free(mem_ctx);
97 mem_ctx = NULL;
98 }
99
100 TEST_F(array_refcount_test, ir_array_refcount_entry_initial_state_for_scalar)
101 {
102 ir_variable *const var =
103 new(mem_ctx) ir_variable(glsl_type::int_type, "a", ir_var_auto);
104
105 ir_array_refcount_entry entry(var);
106
107 ASSERT_NE((void *)0, get_bits(entry));
108 EXPECT_FALSE(entry.is_referenced);
109 EXPECT_EQ(1, get_num_bits(entry));
110 EXPECT_EQ(0, get_array_depth(entry));
111 EXPECT_FALSE(entry.is_linearized_index_referenced(0));
112 }
113
114 TEST_F(array_refcount_test, ir_array_refcount_entry_initial_state_for_vector)
115 {
116 ir_variable *const var =
117 new(mem_ctx) ir_variable(glsl_type::vec4_type, "a", ir_var_auto);
118
119 ir_array_refcount_entry entry(var);
120
121 ASSERT_NE((void *)0, get_bits(entry));
122 EXPECT_FALSE(entry.is_referenced);
123 EXPECT_EQ(1, get_num_bits(entry));
124 EXPECT_EQ(0, get_array_depth(entry));
125 EXPECT_FALSE(entry.is_linearized_index_referenced(0));
126 }
127
128 TEST_F(array_refcount_test, ir_array_refcount_entry_initial_state_for_matrix)
129 {
130 ir_variable *const var =
131 new(mem_ctx) ir_variable(glsl_type::mat4_type, "a", ir_var_auto);
132
133 ir_array_refcount_entry entry(var);
134
135 ASSERT_NE((void *)0, get_bits(entry));
136 EXPECT_FALSE(entry.is_referenced);
137 EXPECT_EQ(1, get_num_bits(entry));
138 EXPECT_EQ(0, get_array_depth(entry));
139 EXPECT_FALSE(entry.is_linearized_index_referenced(0));
140 }
141
142 TEST_F(array_refcount_test, ir_array_refcount_entry_initial_state_for_array)
143 {
144 ir_variable *const var =
145 new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4,
146 "a",
147 ir_var_auto);
148 const unsigned total_elements = var->type->arrays_of_arrays_size();
149
150 ir_array_refcount_entry entry(var);
151
152 ASSERT_NE((void *)0, get_bits(entry));
153 EXPECT_FALSE(entry.is_referenced);
154 EXPECT_EQ(total_elements, get_num_bits(entry));
155 EXPECT_EQ(3, get_array_depth(entry));
156
157 for (unsigned i = 0; i < total_elements; i++)
158 EXPECT_FALSE(entry.is_linearized_index_referenced(i)) << "index = " << i;
159 }
160
161 TEST_F(array_refcount_test, mark_array_elements_referenced_simple)
162 {
163 ir_variable *const var =
164 new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4,
165 "a",
166 ir_var_auto);
167 const unsigned total_elements = var->type->arrays_of_arrays_size();
168
169 ir_array_refcount_entry entry(var);
170
171 static const array_deref_range dr[] = {
172 { 0, 5 }, { 1, 4 }, { 2, 3 }
173 };
174 const unsigned accessed_element = 0 + (1 * 5) + (2 * 4 * 5);
175
176 entry.mark_array_elements_referenced(dr, 3);
177
178 for (unsigned i = 0; i < total_elements; i++)
179 EXPECT_EQ(i == accessed_element, entry.is_linearized_index_referenced(i));
180 }
181
182 TEST_F(array_refcount_test, mark_array_elements_referenced_whole_first_array)
183 {
184 ir_variable *const var =
185 new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4,
186 "a",
187 ir_var_auto);
188
189 ir_array_refcount_entry entry(var);
190
191 static const array_deref_range dr[] = {
192 { 0, 5 }, { 1, 4 }, { 3, 3 }
193 };
194
195 entry.mark_array_elements_referenced(dr, 3);
196
197 for (unsigned i = 0; i < 3; i++) {
198 for (unsigned j = 0; j < 4; j++) {
199 for (unsigned k = 0; k < 5; k++) {
200 const bool accessed = (j == 1) && (k == 0);
201 const unsigned linearized_index = k + (j * 5) + (i * 4 * 5);
202
203 EXPECT_EQ(accessed,
204 entry.is_linearized_index_referenced(linearized_index));
205 }
206 }
207 }
208 }
209
210 TEST_F(array_refcount_test, mark_array_elements_referenced_whole_second_array)
211 {
212 ir_variable *const var =
213 new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4,
214 "a",
215 ir_var_auto);
216
217 ir_array_refcount_entry entry(var);
218
219 static const array_deref_range dr[] = {
220 { 0, 5 }, { 4, 4 }, { 1, 3 }
221 };
222
223 entry.mark_array_elements_referenced(dr, 3);
224
225 for (unsigned i = 0; i < 3; i++) {
226 for (unsigned j = 0; j < 4; j++) {
227 for (unsigned k = 0; k < 5; k++) {
228 const bool accessed = (i == 1) && (k == 0);
229 const unsigned linearized_index = k + (j * 5) + (i * 4 * 5);
230
231 EXPECT_EQ(accessed,
232 entry.is_linearized_index_referenced(linearized_index));
233 }
234 }
235 }
236 }
237
238 TEST_F(array_refcount_test, mark_array_elements_referenced_whole_third_array)
239 {
240 ir_variable *const var =
241 new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4,
242 "a",
243 ir_var_auto);
244
245 ir_array_refcount_entry entry(var);
246
247 static const array_deref_range dr[] = {
248 { 5, 5 }, { 2, 4 }, { 1, 3 }
249 };
250
251 entry.mark_array_elements_referenced(dr, 3);
252
253 for (unsigned i = 0; i < 3; i++) {
254 for (unsigned j = 0; j < 4; j++) {
255 for (unsigned k = 0; k < 5; k++) {
256 const bool accessed = (i == 1) && (j == 2);
257 const unsigned linearized_index = k + (j * 5) + (i * 4 * 5);
258
259 EXPECT_EQ(accessed,
260 entry.is_linearized_index_referenced(linearized_index));
261 }
262 }
263 }
264 }
265
266 TEST_F(array_refcount_test, mark_array_elements_referenced_whole_first_and_third_arrays)
267 {
268 ir_variable *const var =
269 new(mem_ctx) ir_variable(array_3_of_array_4_of_array_5_of_vec4,
270 "a",
271 ir_var_auto);
272
273 ir_array_refcount_entry entry(var);
274
275 static const array_deref_range dr[] = {
276 { 5, 5 }, { 3, 4 }, { 3, 3 }
277 };
278
279 entry.mark_array_elements_referenced(dr, 3);
280
281 for (unsigned i = 0; i < 3; i++) {
282 for (unsigned j = 0; j < 4; j++) {
283 for (unsigned k = 0; k < 5; k++) {
284 const bool accessed = (j == 3);
285 const unsigned linearized_index = k + (j * 5) + (i * 4 * 5);
286
287 EXPECT_EQ(accessed,
288 entry.is_linearized_index_referenced(linearized_index));
289 }
290 }
291 }
292 }