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