1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2019 Red Hat, Inc 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include <gtest/gtest.h> 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "nir.h" 27bf215546Sopenharmony_ci#include "nir_builder.h" 28bf215546Sopenharmony_ci#include "nir_serialize.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_cinamespace { 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ciclass nir_serialize_test : public ::testing::TestWithParam<int> { 33bf215546Sopenharmony_ciprotected: 34bf215546Sopenharmony_ci nir_serialize_test(); 35bf215546Sopenharmony_ci ~nir_serialize_test(); 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci void serialize(); 38bf215546Sopenharmony_ci nir_alu_instr *get_last_alu(nir_shader *); 39bf215546Sopenharmony_ci void ASSERT_SWIZZLE_EQ(nir_alu_instr *, nir_alu_instr *, unsigned count, unsigned src); 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ci nir_builder *b, _b; 42bf215546Sopenharmony_ci nir_shader *dup; 43bf215546Sopenharmony_ci const nir_shader_compiler_options options; 44bf215546Sopenharmony_ci}; 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_cinir_serialize_test::nir_serialize_test() 47bf215546Sopenharmony_ci: dup(NULL), options() 48bf215546Sopenharmony_ci{ 49bf215546Sopenharmony_ci glsl_type_singleton_init_or_ref(); 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci _b = nir_builder_init_simple_shader(MESA_SHADER_COMPUTE, &options, "serialize test"); 52bf215546Sopenharmony_ci b = &_b; 53bf215546Sopenharmony_ci} 54bf215546Sopenharmony_ci 55bf215546Sopenharmony_cinir_serialize_test::~nir_serialize_test() 56bf215546Sopenharmony_ci{ 57bf215546Sopenharmony_ci if (HasFailure()) { 58bf215546Sopenharmony_ci printf("\nShader from the failed test\n\n"); 59bf215546Sopenharmony_ci printf("original Shader:\n"); 60bf215546Sopenharmony_ci nir_print_shader(b->shader, stdout); 61bf215546Sopenharmony_ci printf("serialized Shader:\n"); 62bf215546Sopenharmony_ci nir_print_shader(dup, stdout); 63bf215546Sopenharmony_ci } 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci ralloc_free(b->shader); 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci glsl_type_singleton_decref(); 68bf215546Sopenharmony_ci} 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_civoid 71bf215546Sopenharmony_cinir_serialize_test::serialize() { 72bf215546Sopenharmony_ci struct blob blob; 73bf215546Sopenharmony_ci struct blob_reader reader; 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci blob_init(&blob); 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_ci nir_serialize(&blob, b->shader, false); 78bf215546Sopenharmony_ci blob_reader_init(&reader, blob.data, blob.size); 79bf215546Sopenharmony_ci nir_shader *cloned = nir_deserialize(b->shader, &options, &reader); 80bf215546Sopenharmony_ci blob_finish(&blob); 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci dup = cloned; 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci nir_validate_shader(b->shader, "original"); 85bf215546Sopenharmony_ci nir_validate_shader(b->shader, "cloned"); 86bf215546Sopenharmony_ci} 87bf215546Sopenharmony_ci 88bf215546Sopenharmony_cinir_alu_instr * 89bf215546Sopenharmony_cinir_serialize_test::get_last_alu(nir_shader *nir) 90bf215546Sopenharmony_ci{ 91bf215546Sopenharmony_ci nir_function_impl *impl = nir_shader_get_entrypoint(nir); 92bf215546Sopenharmony_ci return nir_instr_as_alu(nir_block_last_instr(nir_impl_last_block(impl))); 93bf215546Sopenharmony_ci} 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_civoid 96bf215546Sopenharmony_cinir_serialize_test::ASSERT_SWIZZLE_EQ(nir_alu_instr *a, nir_alu_instr *b, unsigned c, unsigned s) 97bf215546Sopenharmony_ci{ 98bf215546Sopenharmony_ci ASSERT_EQ(memcmp(a->src[s].swizzle, b->src[s].swizzle, c), 0); 99bf215546Sopenharmony_ci} 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ciclass nir_serialize_all_test : public nir_serialize_test {}; 102bf215546Sopenharmony_ciclass nir_serialize_all_but_one_test : public nir_serialize_test {}; 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci} // namespace 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci#if NIR_MAX_VEC_COMPONENTS == 16 107bf215546Sopenharmony_ci#define COMPONENTS 2, 3, 4, 8, 16 108bf215546Sopenharmony_ci#else 109bf215546Sopenharmony_ci#define COMPONENTS 2, 3, 4 110bf215546Sopenharmony_ci#endif 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ciINSTANTIATE_TEST_CASE_P( 114bf215546Sopenharmony_ci nir_serialize_all_test, 115bf215546Sopenharmony_ci nir_serialize_all_test, 116bf215546Sopenharmony_ci ::testing::Values(1, COMPONENTS) 117bf215546Sopenharmony_ci); 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ciINSTANTIATE_TEST_CASE_P( 120bf215546Sopenharmony_ci nir_serialize_all_but_one_test, 121bf215546Sopenharmony_ci nir_serialize_all_but_one_test, 122bf215546Sopenharmony_ci ::testing::Values(COMPONENTS) 123bf215546Sopenharmony_ci); 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ciTEST_P(nir_serialize_all_test, alu_single_value_src_swizzle) 126bf215546Sopenharmony_ci{ 127bf215546Sopenharmony_ci nir_ssa_def *zero = nir_imm_zero(b, GetParam(), 32); 128bf215546Sopenharmony_ci nir_ssa_def *fmax = nir_fmax(b, zero, zero); 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci nir_alu_instr *fmax_alu = nir_instr_as_alu(fmax->parent_instr); 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci memset(fmax_alu->src[0].swizzle, GetParam() - 1, NIR_MAX_VEC_COMPONENTS); 133bf215546Sopenharmony_ci memset(fmax_alu->src[1].swizzle, GetParam() - 1, NIR_MAX_VEC_COMPONENTS); 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci serialize(); 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci nir_alu_instr *fmax_alu_dup = get_last_alu(dup); 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci ASSERT_SWIZZLE_EQ(fmax_alu, fmax_alu_dup, GetParam(), 0); 140bf215546Sopenharmony_ci ASSERT_SWIZZLE_EQ(fmax_alu, fmax_alu_dup, GetParam(), 1); 141bf215546Sopenharmony_ci} 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ciTEST_P(nir_serialize_all_test, alu_vec) 144bf215546Sopenharmony_ci{ 145bf215546Sopenharmony_ci nir_ssa_def *undef = nir_ssa_undef(b, GetParam(), 32); 146bf215546Sopenharmony_ci nir_ssa_def *undefs[] = { 147bf215546Sopenharmony_ci undef, undef, undef, undef, 148bf215546Sopenharmony_ci undef, undef, undef, undef, 149bf215546Sopenharmony_ci undef, undef, undef, undef, 150bf215546Sopenharmony_ci undef, undef, undef, undef, 151bf215546Sopenharmony_ci }; 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci nir_ssa_def *vec = nir_vec(b, undefs, GetParam()); 154bf215546Sopenharmony_ci nir_alu_instr *vec_alu = nir_instr_as_alu(vec->parent_instr); 155bf215546Sopenharmony_ci for (int i = 0; i < GetParam(); i++) 156bf215546Sopenharmony_ci vec_alu->src[i].swizzle[0] = (GetParam() - 1) - i; 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci serialize(); 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci nir_alu_instr *vec_alu_dup = get_last_alu(dup); 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci ASSERT_SWIZZLE_EQ(vec_alu, vec_alu_dup, 1, 0); 163bf215546Sopenharmony_ci} 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ciTEST_P(nir_serialize_all_test, alu_two_components_full_swizzle) 166bf215546Sopenharmony_ci{ 167bf215546Sopenharmony_ci nir_ssa_def *undef = nir_ssa_undef(b, 2, 32); 168bf215546Sopenharmony_ci nir_ssa_def *fma = nir_ffma(b, undef, undef, undef); 169bf215546Sopenharmony_ci nir_alu_instr *fma_alu = nir_instr_as_alu(fma->parent_instr); 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci fma->num_components = GetParam(); 172bf215546Sopenharmony_ci fma_alu->dest.write_mask = (1 << GetParam()) - 1; 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci memset(fma_alu->src[0].swizzle, 1, GetParam()); 175bf215546Sopenharmony_ci memset(fma_alu->src[1].swizzle, 1, GetParam()); 176bf215546Sopenharmony_ci memset(fma_alu->src[2].swizzle, 1, GetParam()); 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci serialize(); 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci nir_alu_instr *fma_alu_dup = get_last_alu(dup); 181bf215546Sopenharmony_ci 182bf215546Sopenharmony_ci ASSERT_SWIZZLE_EQ(fma_alu, fma_alu_dup, GetParam(), 0); 183bf215546Sopenharmony_ci ASSERT_SWIZZLE_EQ(fma_alu, fma_alu_dup, GetParam(), 1); 184bf215546Sopenharmony_ci ASSERT_SWIZZLE_EQ(fma_alu, fma_alu_dup, GetParam(), 2); 185bf215546Sopenharmony_ci} 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_ciTEST_P(nir_serialize_all_but_one_test, alu_two_components_reg_two_swizzle) 188bf215546Sopenharmony_ci{ 189bf215546Sopenharmony_ci nir_ssa_def *undef = nir_ssa_undef(b, 2, 32); 190bf215546Sopenharmony_ci nir_ssa_def *fma = nir_ffma(b, undef, undef, undef); 191bf215546Sopenharmony_ci nir_alu_instr *fma_alu = nir_instr_as_alu(fma->parent_instr); 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci memset(fma_alu->src[0].swizzle, 1, GetParam()); 194bf215546Sopenharmony_ci memset(fma_alu->src[1].swizzle, 1, GetParam()); 195bf215546Sopenharmony_ci memset(fma_alu->src[2].swizzle, 1, GetParam()); 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci ASSERT_TRUE(nir_convert_from_ssa(b->shader, false)); 198bf215546Sopenharmony_ci 199bf215546Sopenharmony_ci fma_alu = get_last_alu(b->shader); 200bf215546Sopenharmony_ci ASSERT_FALSE(fma_alu->dest.dest.is_ssa); 201bf215546Sopenharmony_ci fma_alu->dest.dest.reg.reg->num_components = GetParam(); 202bf215546Sopenharmony_ci fma_alu->dest.write_mask = 1 | (1 << (GetParam() - 1)); 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci serialize(); 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci nir_alu_instr *fma_alu_dup = get_last_alu(dup); 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_ci ASSERT_EQ(fma_alu->src[0].swizzle[0], fma_alu_dup->src[0].swizzle[0]); 209bf215546Sopenharmony_ci ASSERT_EQ(fma_alu->src[0].swizzle[GetParam() - 1], fma_alu_dup->src[0].swizzle[GetParam() - 1]); 210bf215546Sopenharmony_ci ASSERT_EQ(fma_alu->src[1].swizzle[0], fma_alu_dup->src[1].swizzle[0]); 211bf215546Sopenharmony_ci ASSERT_EQ(fma_alu->src[1].swizzle[GetParam() - 1], fma_alu_dup->src[1].swizzle[GetParam() - 1]); 212bf215546Sopenharmony_ci ASSERT_EQ(fma_alu->src[2].swizzle[0], fma_alu_dup->src[2].swizzle[0]); 213bf215546Sopenharmony_ci ASSERT_EQ(fma_alu->src[2].swizzle[GetParam() - 1], fma_alu_dup->src[2].swizzle[GetParam() - 1]); 214bf215546Sopenharmony_ci} 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_ciTEST_P(nir_serialize_all_but_one_test, alu_full_width_reg_two_swizzle) 217bf215546Sopenharmony_ci{ 218bf215546Sopenharmony_ci nir_ssa_def *undef = nir_ssa_undef(b, GetParam(), 32); 219bf215546Sopenharmony_ci nir_ssa_def *fma = nir_ffma(b, undef, undef, undef); 220bf215546Sopenharmony_ci nir_alu_instr *fma_alu = nir_instr_as_alu(fma->parent_instr); 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_ci memset(fma_alu->src[0].swizzle, GetParam() - 1, GetParam()); 223bf215546Sopenharmony_ci memset(fma_alu->src[1].swizzle, GetParam() - 1, GetParam()); 224bf215546Sopenharmony_ci memset(fma_alu->src[2].swizzle, GetParam() - 1, GetParam()); 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci ASSERT_TRUE(nir_convert_from_ssa(b->shader, false)); 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci fma_alu = get_last_alu(b->shader); 229bf215546Sopenharmony_ci ASSERT_FALSE(fma_alu->dest.dest.is_ssa); 230bf215546Sopenharmony_ci fma_alu->dest.write_mask = 1 | (1 << (GetParam() - 1)); 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ci serialize(); 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci nir_alu_instr *fma_alu_dup = get_last_alu(dup); 235bf215546Sopenharmony_ci 236bf215546Sopenharmony_ci ASSERT_EQ(fma_alu->src[0].swizzle[0], fma_alu_dup->src[0].swizzle[0]); 237bf215546Sopenharmony_ci ASSERT_EQ(fma_alu->src[0].swizzle[GetParam() - 1], fma_alu_dup->src[0].swizzle[GetParam() - 1]); 238bf215546Sopenharmony_ci ASSERT_EQ(fma_alu->src[1].swizzle[0], fma_alu_dup->src[1].swizzle[0]); 239bf215546Sopenharmony_ci ASSERT_EQ(fma_alu->src[1].swizzle[GetParam() - 1], fma_alu_dup->src[1].swizzle[GetParam() - 1]); 240bf215546Sopenharmony_ci ASSERT_EQ(fma_alu->src[2].swizzle[0], fma_alu_dup->src[2].swizzle[0]); 241bf215546Sopenharmony_ci ASSERT_EQ(fma_alu->src[2].swizzle[GetParam() - 1], fma_alu_dup->src[2].swizzle[GetParam() - 1]); 242bf215546Sopenharmony_ci} 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ciTEST_P(nir_serialize_all_but_one_test, alu_two_component_reg_full_src) 245bf215546Sopenharmony_ci{ 246bf215546Sopenharmony_ci nir_ssa_def *undef = nir_ssa_undef(b, GetParam(), 32); 247bf215546Sopenharmony_ci nir_ssa_def *fma = nir_ffma(b, undef, undef, undef); 248bf215546Sopenharmony_ci nir_alu_instr *fma_alu = nir_instr_as_alu(fma->parent_instr); 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci memset(fma_alu->src[0].swizzle, 1, GetParam()); 251bf215546Sopenharmony_ci memset(fma_alu->src[1].swizzle, 1, GetParam()); 252bf215546Sopenharmony_ci memset(fma_alu->src[2].swizzle, 1, GetParam()); 253bf215546Sopenharmony_ci 254bf215546Sopenharmony_ci ASSERT_TRUE(nir_convert_from_ssa(b->shader, false)); 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci fma_alu = get_last_alu(b->shader); 257bf215546Sopenharmony_ci ASSERT_FALSE(fma_alu->dest.dest.is_ssa); 258bf215546Sopenharmony_ci fma_alu->dest.dest.reg.reg->num_components = 2; 259bf215546Sopenharmony_ci fma_alu->dest.write_mask = 0x3; 260bf215546Sopenharmony_ci 261bf215546Sopenharmony_ci serialize(); 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci nir_alu_instr *fma_alu_dup = get_last_alu(dup); 264bf215546Sopenharmony_ci 265bf215546Sopenharmony_ci ASSERT_SWIZZLE_EQ(fma_alu, fma_alu_dup, 2, 0); 266bf215546Sopenharmony_ci ASSERT_SWIZZLE_EQ(fma_alu, fma_alu_dup, 2, 1); 267bf215546Sopenharmony_ci ASSERT_SWIZZLE_EQ(fma_alu, fma_alu_dup, 2, 2); 268bf215546Sopenharmony_ci} 269bf215546Sopenharmony_ci 270bf215546Sopenharmony_ciTEST_P(nir_serialize_all_but_one_test, single_channel) 271bf215546Sopenharmony_ci{ 272bf215546Sopenharmony_ci nir_ssa_def *zero = nir_ssa_undef(b, GetParam(), 32); 273bf215546Sopenharmony_ci nir_ssa_def *vec = nir_channel(b, zero, GetParam() - 1); 274bf215546Sopenharmony_ci nir_alu_instr *vec_alu = nir_instr_as_alu(vec->parent_instr); 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_ci serialize(); 277bf215546Sopenharmony_ci 278bf215546Sopenharmony_ci nir_alu_instr *vec_alu_dup = get_last_alu(dup); 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci ASSERT_SWIZZLE_EQ(vec_alu, vec_alu_dup, 1, 0); 281bf215546Sopenharmony_ci} 282