1/* 2 * Copyright (c) 2020 Etnaviv Project 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, sub license, 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 12 * next paragraph) shall be included in all copies or substantial portions 13 * of the 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 NON-INFRINGEMENT. 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 * Authors: 24 * Christian Gmeiner <christian.gmeiner@gmail.com> 25 */ 26 27#include <gtest/gtest.h> 28 29#include "nir.h" 30#include "nir_builder.h" 31 32extern "C" { 33 /* we really do not want to include etnaviv_nir.h as it makes it 34 * harder to get this test compiling. as we are only working with 35 * nir we do not need any etnaviv specifc stuff here. */ 36 37 extern bool 38 etna_nir_lower_ubo_to_uniform(nir_shader *shader); 39} 40 41class nir_lower_ubo_test : public ::testing::Test { 42protected: 43 nir_lower_ubo_test(); 44 ~nir_lower_ubo_test(); 45 46 nir_intrinsic_instr *intrinsic(nir_intrinsic_op op); 47 unsigned count_intrinsic(nir_intrinsic_op op); 48 49 nir_builder b; 50}; 51 52nir_lower_ubo_test::nir_lower_ubo_test() 53{ 54 glsl_type_singleton_init_or_ref(); 55 56 static const nir_shader_compiler_options options = { }; 57 b = nir_builder_init_simple_shader(MESA_SHADER_VERTEX, &options, "ubo lowering tests"); 58} 59 60nir_lower_ubo_test::~nir_lower_ubo_test() 61{ 62 if (HasFailure()) { 63 printf("\nShader from the failed test:\n\n"); 64 nir_print_shader(b.shader, stdout); 65 } 66 67 ralloc_free(b.shader); 68 69 glsl_type_singleton_decref(); 70} 71 72nir_intrinsic_instr * 73nir_lower_ubo_test::intrinsic(nir_intrinsic_op op) 74{ 75 nir_foreach_block(block, b.impl) { 76 nir_foreach_instr(instr, block) { 77 if (instr->type != nir_instr_type_intrinsic) 78 continue; 79 80 nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); 81 if (intr->intrinsic == op) 82 return intr; 83 } 84 } 85 return NULL; 86} 87 88unsigned 89nir_lower_ubo_test::count_intrinsic(nir_intrinsic_op op) 90{ 91 unsigned count = 0; 92 93 nir_foreach_block(block, b.impl) { 94 nir_foreach_instr(instr, block) { 95 if (instr->type != nir_instr_type_intrinsic) 96 continue; 97 98 nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); 99 if (intr->intrinsic == op) 100 count++; 101 } 102 } 103 return count; 104} 105 106TEST_F(nir_lower_ubo_test, nothing_to_lower) 107{ 108 nir_ssa_def *offset = nir_imm_int(&b, 4); 109 110 nir_load_uniform(&b, 1, 32, offset); 111 112 nir_validate_shader(b.shader, NULL); 113 114 ASSERT_FALSE(etna_nir_lower_ubo_to_uniform(b.shader)); 115 nir_validate_shader(b.shader, NULL); 116 117 ASSERT_EQ(count_intrinsic(nir_intrinsic_load_ubo), 0); 118 ASSERT_EQ(count_intrinsic(nir_intrinsic_load_uniform), 1); 119} 120 121TEST_F(nir_lower_ubo_test, basic) 122{ 123 nir_ssa_def *offset = nir_imm_int(&b, 4); 124 nir_load_uniform(&b, 1, 32, offset); 125 126 nir_lower_uniforms_to_ubo(b.shader, false, false); 127 nir_opt_constant_folding(b.shader); 128 129 ASSERT_TRUE(etna_nir_lower_ubo_to_uniform(b.shader)); 130 nir_validate_shader(b.shader, NULL); 131 nir_opt_constant_folding(b.shader); 132 133 nir_intrinsic_instr *load_uniform = intrinsic(nir_intrinsic_load_uniform); 134 ASSERT_EQ(nir_src_as_uint(load_uniform->src[0]), 4); 135 ASSERT_EQ(intrinsic(nir_intrinsic_load_ubo), nullptr); 136} 137 138TEST_F(nir_lower_ubo_test, index_not_null) 139{ 140 nir_ssa_def *index = nir_imm_int(&b, 1); 141 nir_ssa_def *offset = nir_imm_int(&b, 4); 142 143 nir_load_ubo(&b, 1, 32, index, offset, .align_mul = 16, .align_offset = 0, .range_base = 0, .range = 8); 144 145 nir_validate_shader(b.shader, NULL); 146 147 ASSERT_FALSE(etna_nir_lower_ubo_to_uniform(b.shader)); 148 ASSERT_EQ(count_intrinsic(nir_intrinsic_load_ubo), 1); 149 ASSERT_EQ(count_intrinsic(nir_intrinsic_load_uniform), 0); 150} 151 152TEST_F(nir_lower_ubo_test, indirect_index) 153{ 154 nir_ssa_def *one = nir_imm_int(&b, 1); 155 nir_ssa_def *index = nir_fadd(&b, one, one); 156 nir_ssa_def *offset = nir_imm_int(&b, 4); 157 158 nir_load_ubo(&b, 1, 32, index, offset, .align_mul = 16, .align_offset = 0, .range_base = 0, .range = 8); 159 160 nir_validate_shader(b.shader, NULL); 161 162 ASSERT_FALSE(etna_nir_lower_ubo_to_uniform(b.shader)); 163 nir_validate_shader(b.shader, NULL); 164 165 ASSERT_EQ(count_intrinsic(nir_intrinsic_load_ubo), 1); 166 ASSERT_EQ(count_intrinsic(nir_intrinsic_load_uniform), 0); 167} 168 169TEST_F(nir_lower_ubo_test, indirect_offset) 170{ 171 nir_ssa_def *one = nir_imm_int(&b, 1); 172 nir_ssa_def *index = nir_imm_int(&b, 0); 173 nir_ssa_def *offset = nir_fadd(&b, one, one); 174 175 nir_load_ubo(&b, 1, 32, index, offset, .align_mul = 16, .align_offset = 0, .range_base = 0, .range = 8); 176 177 nir_validate_shader(b.shader, NULL); 178 179 ASSERT_FALSE(etna_nir_lower_ubo_to_uniform(b.shader)); 180 nir_validate_shader(b.shader, NULL); 181 182 ASSERT_EQ(count_intrinsic(nir_intrinsic_load_ubo), 1); 183 ASSERT_EQ(count_intrinsic(nir_intrinsic_load_uniform), 0); 184} 185