• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2019 Red Hat, Inc
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 
24 #include <gtest/gtest.h>
25 
26 #include "nir.h"
27 #include "nir_builder.h"
28 #include "nir_serialize.h"
29 
30 namespace {
31 
32 class nir_serialize_test : public ::testing::TestWithParam<int> {
33 protected:
34    nir_serialize_test();
35    ~nir_serialize_test();
36 
37    void serialize();
38    nir_alu_instr *get_last_alu(nir_shader *);
39    void ASSERT_SWIZZLE_EQ(nir_alu_instr *, nir_alu_instr *, unsigned count, unsigned src);
40 
41    void *mem_ctx;
42    nir_builder *b;
43    nir_shader *dup;
44    const nir_shader_compiler_options options;
45 };
46 
nir_serialize_test()47 nir_serialize_test::nir_serialize_test()
48 :  options()
49 {
50    glsl_type_singleton_init_or_ref();
51 
52    mem_ctx = ralloc_context(NULL);
53 
54    b = rzalloc(mem_ctx, nir_builder);
55    nir_builder_init_simple_shader(b, mem_ctx, MESA_SHADER_COMPUTE, &options);
56 }
57 
~nir_serialize_test()58 nir_serialize_test::~nir_serialize_test()
59 {
60    if (HasFailure()) {
61       printf("\nShader from the failed test\n\n");
62       printf("original Shader:\n");
63       nir_print_shader(b->shader, stdout);
64       printf("serialized Shader:\n");
65       nir_print_shader(dup, stdout);
66    }
67 
68    ralloc_free(mem_ctx);
69 
70    glsl_type_singleton_decref();
71 }
72 
73 void
serialize()74 nir_serialize_test::serialize() {
75    struct blob blob;
76    struct blob_reader reader;
77 
78    blob_init(&blob);
79 
80    nir_serialize(&blob, b->shader, false);
81    blob_reader_init(&reader, blob.data, blob.size);
82    nir_shader *cloned = nir_deserialize(mem_ctx, &options, &reader);
83    blob_finish(&blob);
84 
85    dup = cloned;
86 
87    nir_validate_shader(b->shader, "original");
88    nir_validate_shader(b->shader, "cloned");
89 }
90 
91 nir_alu_instr *
get_last_alu(nir_shader * nir)92 nir_serialize_test::get_last_alu(nir_shader *nir)
93 {
94    nir_function_impl *impl = nir_shader_get_entrypoint(nir);
95    return nir_instr_as_alu(nir_block_last_instr(nir_impl_last_block(impl)));
96 }
97 
98 void
ASSERT_SWIZZLE_EQ(nir_alu_instr * a,nir_alu_instr * b,unsigned c,unsigned s)99 nir_serialize_test::ASSERT_SWIZZLE_EQ(nir_alu_instr *a, nir_alu_instr *b, unsigned c, unsigned s)
100 {
101    ASSERT_EQ(memcmp(a->src[s].swizzle, b->src[s].swizzle, c), 0);
102 }
103 
104 class nir_serialize_all_test : public nir_serialize_test {};
105 class nir_serialize_all_but_one_test : public nir_serialize_test {};
106 
107 } // namespace
108 
109 #if NIR_MAX_VEC_COMPONENTS == 16
110 #define COMPONENTS 2, 3, 4, 8, 16
111 #else
112 #define COMPONENTS 2, 3, 4
113 #endif
114 
115 
116 INSTANTIATE_TEST_CASE_P(
117    nir_serialize_all_test,
118    nir_serialize_all_test,
119    ::testing::Values(1, COMPONENTS)
120 );
121 
122 INSTANTIATE_TEST_CASE_P(
123    nir_serialize_all_but_one_test,
124    nir_serialize_all_but_one_test,
125    ::testing::Values(COMPONENTS)
126 );
127 
TEST_P(nir_serialize_all_test,alu_single_value_src_swizzle)128 TEST_P(nir_serialize_all_test, alu_single_value_src_swizzle)
129 {
130    nir_ssa_def *zero = nir_imm_zero(b, GetParam(), 32);
131    nir_ssa_def *fmax = nir_fmax(b, zero, zero);
132 
133    nir_alu_instr *fmax_alu = nir_instr_as_alu(fmax->parent_instr);
134 
135    memset(fmax_alu->src[0].swizzle, GetParam() - 1, NIR_MAX_VEC_COMPONENTS);
136    memset(fmax_alu->src[1].swizzle, GetParam() - 1, NIR_MAX_VEC_COMPONENTS);
137 
138    serialize();
139 
140    nir_alu_instr *fmax_alu_dup = get_last_alu(dup);
141 
142    ASSERT_SWIZZLE_EQ(fmax_alu, fmax_alu_dup, GetParam(), 0);
143    ASSERT_SWIZZLE_EQ(fmax_alu, fmax_alu_dup, GetParam(), 1);
144 }
145 
TEST_P(nir_serialize_all_test,alu_vec)146 TEST_P(nir_serialize_all_test, alu_vec)
147 {
148    nir_ssa_def *undef = nir_ssa_undef(b, GetParam(), 32);
149    nir_ssa_def *undefs[] = {
150       undef, undef, undef, undef,
151       undef, undef, undef, undef,
152       undef, undef, undef, undef,
153       undef, undef, undef, undef,
154    };
155 
156    nir_ssa_def *vec = nir_vec(b, undefs, GetParam());
157    nir_alu_instr *vec_alu = nir_instr_as_alu(vec->parent_instr);
158    for (int i = 0; i < GetParam(); i++)
159       vec_alu->src[i].swizzle[0] = (GetParam() - 1) - i;
160 
161    serialize();
162 
163    nir_alu_instr *vec_alu_dup = get_last_alu(dup);
164 
165    ASSERT_SWIZZLE_EQ(vec_alu, vec_alu_dup, 1, 0);
166 }
167 
TEST_P(nir_serialize_all_test,alu_two_components_full_swizzle)168 TEST_P(nir_serialize_all_test, alu_two_components_full_swizzle)
169 {
170    nir_ssa_def *undef = nir_ssa_undef(b, 2, 32);
171    nir_ssa_def *fma = nir_ffma(b, undef, undef, undef);
172    nir_alu_instr *fma_alu = nir_instr_as_alu(fma->parent_instr);
173 
174    fma->num_components = GetParam();
175    fma_alu->dest.write_mask = (1 << GetParam()) - 1;
176 
177    memset(fma_alu->src[0].swizzle, 1, GetParam());
178    memset(fma_alu->src[1].swizzle, 1, GetParam());
179    memset(fma_alu->src[2].swizzle, 1, GetParam());
180 
181    serialize();
182 
183    nir_alu_instr *fma_alu_dup = get_last_alu(dup);
184 
185    ASSERT_SWIZZLE_EQ(fma_alu, fma_alu_dup, GetParam(), 0);
186    ASSERT_SWIZZLE_EQ(fma_alu, fma_alu_dup, GetParam(), 1);
187    ASSERT_SWIZZLE_EQ(fma_alu, fma_alu_dup, GetParam(), 2);
188 }
189 
TEST_P(nir_serialize_all_but_one_test,alu_two_components_reg_two_swizzle)190 TEST_P(nir_serialize_all_but_one_test, alu_two_components_reg_two_swizzle)
191 {
192    nir_ssa_def *undef = nir_ssa_undef(b, 2, 32);
193    nir_ssa_def *fma = nir_ffma(b, undef, undef, undef);
194    nir_alu_instr *fma_alu = nir_instr_as_alu(fma->parent_instr);
195 
196    memset(fma_alu->src[0].swizzle, 1, GetParam());
197    memset(fma_alu->src[1].swizzle, 1, GetParam());
198    memset(fma_alu->src[2].swizzle, 1, GetParam());
199 
200    ASSERT_TRUE(nir_convert_from_ssa(b->shader, false));
201 
202    fma_alu = get_last_alu(b->shader);
203    ASSERT_FALSE(fma_alu->dest.dest.is_ssa);
204    fma_alu->dest.dest.reg.reg->num_components = GetParam();
205    fma_alu->dest.write_mask = 1 | (1 << (GetParam() - 1));
206 
207    serialize();
208 
209    nir_alu_instr *fma_alu_dup = get_last_alu(dup);
210 
211    ASSERT_EQ(fma_alu->src[0].swizzle[0], fma_alu_dup->src[0].swizzle[0]);
212    ASSERT_EQ(fma_alu->src[0].swizzle[GetParam() - 1], fma_alu_dup->src[0].swizzle[GetParam() - 1]);
213    ASSERT_EQ(fma_alu->src[1].swizzle[0], fma_alu_dup->src[1].swizzle[0]);
214    ASSERT_EQ(fma_alu->src[1].swizzle[GetParam() - 1], fma_alu_dup->src[1].swizzle[GetParam() - 1]);
215    ASSERT_EQ(fma_alu->src[2].swizzle[0], fma_alu_dup->src[2].swizzle[0]);
216    ASSERT_EQ(fma_alu->src[2].swizzle[GetParam() - 1], fma_alu_dup->src[2].swizzle[GetParam() - 1]);
217 }
218 
TEST_P(nir_serialize_all_but_one_test,alu_full_width_reg_two_swizzle)219 TEST_P(nir_serialize_all_but_one_test, alu_full_width_reg_two_swizzle)
220 {
221    nir_ssa_def *undef = nir_ssa_undef(b, GetParam(), 32);
222    nir_ssa_def *fma = nir_ffma(b, undef, undef, undef);
223    nir_alu_instr *fma_alu = nir_instr_as_alu(fma->parent_instr);
224 
225    memset(fma_alu->src[0].swizzle, GetParam() - 1, GetParam());
226    memset(fma_alu->src[1].swizzle, GetParam() - 1, GetParam());
227    memset(fma_alu->src[2].swizzle, GetParam() - 1, GetParam());
228 
229    ASSERT_TRUE(nir_convert_from_ssa(b->shader, false));
230 
231    fma_alu = get_last_alu(b->shader);
232    ASSERT_FALSE(fma_alu->dest.dest.is_ssa);
233    fma_alu->dest.write_mask = 1 | (1 << (GetParam() - 1));
234 
235    serialize();
236 
237    nir_alu_instr *fma_alu_dup = get_last_alu(dup);
238 
239    ASSERT_EQ(fma_alu->src[0].swizzle[0], fma_alu_dup->src[0].swizzle[0]);
240    ASSERT_EQ(fma_alu->src[0].swizzle[GetParam() - 1], fma_alu_dup->src[0].swizzle[GetParam() - 1]);
241    ASSERT_EQ(fma_alu->src[1].swizzle[0], fma_alu_dup->src[1].swizzle[0]);
242    ASSERT_EQ(fma_alu->src[1].swizzle[GetParam() - 1], fma_alu_dup->src[1].swizzle[GetParam() - 1]);
243    ASSERT_EQ(fma_alu->src[2].swizzle[0], fma_alu_dup->src[2].swizzle[0]);
244    ASSERT_EQ(fma_alu->src[2].swizzle[GetParam() - 1], fma_alu_dup->src[2].swizzle[GetParam() - 1]);
245 }
246 
TEST_P(nir_serialize_all_but_one_test,alu_two_component_reg_full_src)247 TEST_P(nir_serialize_all_but_one_test, alu_two_component_reg_full_src)
248 {
249    nir_ssa_def *undef = nir_ssa_undef(b, GetParam(), 32);
250    nir_ssa_def *fma = nir_ffma(b, undef, undef, undef);
251    nir_alu_instr *fma_alu = nir_instr_as_alu(fma->parent_instr);
252 
253    memset(fma_alu->src[0].swizzle, 1, GetParam());
254    memset(fma_alu->src[1].swizzle, 1, GetParam());
255    memset(fma_alu->src[2].swizzle, 1, GetParam());
256 
257    ASSERT_TRUE(nir_convert_from_ssa(b->shader, false));
258 
259    fma_alu = get_last_alu(b->shader);
260    ASSERT_FALSE(fma_alu->dest.dest.is_ssa);
261    fma_alu->dest.dest.reg.reg->num_components = 2;
262    fma_alu->dest.write_mask = 0x3;
263 
264    serialize();
265 
266    nir_alu_instr *fma_alu_dup = get_last_alu(dup);
267 
268    ASSERT_SWIZZLE_EQ(fma_alu, fma_alu_dup, 2, 0);
269    ASSERT_SWIZZLE_EQ(fma_alu, fma_alu_dup, 2, 1);
270    ASSERT_SWIZZLE_EQ(fma_alu, fma_alu_dup, 2, 2);
271 }
272 
TEST_P(nir_serialize_all_but_one_test,single_channel)273 TEST_P(nir_serialize_all_but_one_test, single_channel)
274 {
275    nir_ssa_def *zero = nir_ssa_undef(b, GetParam(), 32);
276    nir_ssa_def *vec = nir_channel(b, zero, GetParam() - 1);
277    nir_alu_instr *vec_alu = nir_instr_as_alu(vec->parent_instr);
278 
279    serialize();
280 
281    nir_alu_instr *vec_alu_dup = get_last_alu(dup);
282 
283    ASSERT_SWIZZLE_EQ(vec_alu, vec_alu_dup, 1, 0);
284 }
285