1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2014-2015 Broadcom 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 DEALINGS 21bf215546Sopenharmony_ci * IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#ifndef NIR_BUILDER_H 25bf215546Sopenharmony_ci#define NIR_BUILDER_H 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include "nir_control_flow.h" 28bf215546Sopenharmony_ci#include "util/bitscan.h" 29bf215546Sopenharmony_ci#include "util/half_float.h" 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#ifdef __cplusplus 32bf215546Sopenharmony_ciextern "C" { 33bf215546Sopenharmony_ci#endif 34bf215546Sopenharmony_ci 35bf215546Sopenharmony_cistruct exec_list; 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_citypedef struct nir_builder { 38bf215546Sopenharmony_ci nir_cursor cursor; 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci /* Whether new ALU instructions will be marked "exact" */ 41bf215546Sopenharmony_ci bool exact; 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci /* Whether to run divergence analysis on inserted instructions (loop merge 44bf215546Sopenharmony_ci * and header phis are not updated). */ 45bf215546Sopenharmony_ci bool update_divergence; 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci nir_shader *shader; 48bf215546Sopenharmony_ci nir_function_impl *impl; 49bf215546Sopenharmony_ci} nir_builder; 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_civoid nir_builder_init(nir_builder *build, nir_function_impl *impl); 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_cinir_builder MUST_CHECK PRINTFLIKE(3, 4) 54bf215546Sopenharmony_cinir_builder_init_simple_shader(gl_shader_stage stage, 55bf215546Sopenharmony_ci const nir_shader_compiler_options *options, 56bf215546Sopenharmony_ci const char *name, ...); 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_citypedef bool (*nir_instr_pass_cb)(struct nir_builder *, nir_instr *, void *); 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_ci/** 61bf215546Sopenharmony_ci * Iterates over all the instructions in a NIR shader and calls the given pass 62bf215546Sopenharmony_ci * on them. 63bf215546Sopenharmony_ci * 64bf215546Sopenharmony_ci * The pass should return true if it modified the shader. In that case, only 65bf215546Sopenharmony_ci * the preserved metadata flags will be preserved in the function impl. 66bf215546Sopenharmony_ci * 67bf215546Sopenharmony_ci * The builder will be initialized to point at the function impl, but its 68bf215546Sopenharmony_ci * cursor is unset. 69bf215546Sopenharmony_ci */ 70bf215546Sopenharmony_cistatic inline bool 71bf215546Sopenharmony_cinir_shader_instructions_pass(nir_shader *shader, 72bf215546Sopenharmony_ci nir_instr_pass_cb pass, 73bf215546Sopenharmony_ci nir_metadata preserved, 74bf215546Sopenharmony_ci void *cb_data) 75bf215546Sopenharmony_ci{ 76bf215546Sopenharmony_ci bool progress = false; 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_ci nir_foreach_function(function, shader) { 79bf215546Sopenharmony_ci if (!function->impl) 80bf215546Sopenharmony_ci continue; 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci bool func_progress = false; 83bf215546Sopenharmony_ci nir_builder b; 84bf215546Sopenharmony_ci nir_builder_init(&b, function->impl); 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci nir_foreach_block_safe(block, function->impl) { 87bf215546Sopenharmony_ci nir_foreach_instr_safe(instr, block) { 88bf215546Sopenharmony_ci func_progress |= pass(&b, instr, cb_data); 89bf215546Sopenharmony_ci } 90bf215546Sopenharmony_ci } 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_ci if (func_progress) { 93bf215546Sopenharmony_ci nir_metadata_preserve(function->impl, preserved); 94bf215546Sopenharmony_ci progress = true; 95bf215546Sopenharmony_ci } else { 96bf215546Sopenharmony_ci nir_metadata_preserve(function->impl, nir_metadata_all); 97bf215546Sopenharmony_ci } 98bf215546Sopenharmony_ci } 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci return progress; 101bf215546Sopenharmony_ci} 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_civoid nir_builder_instr_insert(nir_builder *build, nir_instr *instr); 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_cistatic inline nir_instr * 106bf215546Sopenharmony_cinir_builder_last_instr(nir_builder *build) 107bf215546Sopenharmony_ci{ 108bf215546Sopenharmony_ci assert(build->cursor.option == nir_cursor_after_instr); 109bf215546Sopenharmony_ci return build->cursor.instr; 110bf215546Sopenharmony_ci} 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci/* General nir_build_alu() taking a variable arg count with NULLs for the rest. */ 113bf215546Sopenharmony_cinir_ssa_def * 114bf215546Sopenharmony_cinir_build_alu(nir_builder *build, nir_op op, nir_ssa_def *src0, 115bf215546Sopenharmony_ci nir_ssa_def *src1, nir_ssa_def *src2, nir_ssa_def *src3); 116bf215546Sopenharmony_ci 117bf215546Sopenharmony_ci/* Fixed-arg-count variants to reduce size of codegen. */ 118bf215546Sopenharmony_cinir_ssa_def * 119bf215546Sopenharmony_cinir_build_alu1(nir_builder *build, nir_op op, nir_ssa_def *src0); 120bf215546Sopenharmony_cinir_ssa_def * 121bf215546Sopenharmony_cinir_build_alu2(nir_builder *build, nir_op op, nir_ssa_def *src0, 122bf215546Sopenharmony_ci nir_ssa_def *src1); 123bf215546Sopenharmony_cinir_ssa_def * 124bf215546Sopenharmony_cinir_build_alu3(nir_builder *build, nir_op op, nir_ssa_def *src0, 125bf215546Sopenharmony_ci nir_ssa_def *src1, nir_ssa_def *src2); 126bf215546Sopenharmony_cinir_ssa_def * 127bf215546Sopenharmony_cinir_build_alu4(nir_builder *build, nir_op op, nir_ssa_def *src0, 128bf215546Sopenharmony_ci nir_ssa_def *src1, nir_ssa_def *src2, nir_ssa_def *src3); 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_cinir_ssa_def *nir_build_alu_src_arr(nir_builder *build, nir_op op, nir_ssa_def **srcs); 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_cinir_instr *nir_builder_last_instr(nir_builder *build); 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_civoid nir_builder_cf_insert(nir_builder *build, nir_cf_node *cf); 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_cibool nir_builder_is_inside_cf(nir_builder *build, nir_cf_node *cf_node); 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_cinir_if * 139bf215546Sopenharmony_cinir_push_if_src(nir_builder *build, nir_src condition); 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_cinir_if * 142bf215546Sopenharmony_cinir_push_if(nir_builder *build, nir_ssa_def *condition); 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_cinir_if * 145bf215546Sopenharmony_cinir_push_else(nir_builder *build, nir_if *nif); 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_civoid nir_pop_if(nir_builder *build, nir_if *nif); 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_cinir_ssa_def * 150bf215546Sopenharmony_cinir_if_phi(nir_builder *build, nir_ssa_def *then_def, nir_ssa_def *else_def); 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_cinir_loop * 153bf215546Sopenharmony_cinir_push_loop(nir_builder *build); 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_civoid nir_pop_loop(nir_builder *build, nir_loop *loop); 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_cistatic inline nir_ssa_def * 158bf215546Sopenharmony_cinir_ssa_undef(nir_builder *build, unsigned num_components, unsigned bit_size) 159bf215546Sopenharmony_ci{ 160bf215546Sopenharmony_ci nir_ssa_undef_instr *undef = 161bf215546Sopenharmony_ci nir_ssa_undef_instr_create(build->shader, num_components, bit_size); 162bf215546Sopenharmony_ci if (!undef) 163bf215546Sopenharmony_ci return NULL; 164bf215546Sopenharmony_ci 165bf215546Sopenharmony_ci nir_instr_insert(nir_before_cf_list(&build->impl->body), &undef->instr); 166bf215546Sopenharmony_ci if (build->update_divergence) 167bf215546Sopenharmony_ci nir_update_instr_divergence(build->shader, &undef->instr); 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci return &undef->def; 170bf215546Sopenharmony_ci} 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_cistatic inline nir_ssa_def * 173bf215546Sopenharmony_cinir_build_imm(nir_builder *build, unsigned num_components, 174bf215546Sopenharmony_ci unsigned bit_size, const nir_const_value *value) 175bf215546Sopenharmony_ci{ 176bf215546Sopenharmony_ci nir_load_const_instr *load_const = 177bf215546Sopenharmony_ci nir_load_const_instr_create(build->shader, num_components, bit_size); 178bf215546Sopenharmony_ci if (!load_const) 179bf215546Sopenharmony_ci return NULL; 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci memcpy(load_const->value, value, sizeof(nir_const_value) * num_components); 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci nir_builder_instr_insert(build, &load_const->instr); 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci return &load_const->def; 186bf215546Sopenharmony_ci} 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_cistatic inline nir_ssa_def * 189bf215546Sopenharmony_cinir_imm_zero(nir_builder *build, unsigned num_components, unsigned bit_size) 190bf215546Sopenharmony_ci{ 191bf215546Sopenharmony_ci nir_load_const_instr *load_const = 192bf215546Sopenharmony_ci nir_load_const_instr_create(build->shader, num_components, bit_size); 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci /* nir_load_const_instr_create uses rzalloc so it's already zero */ 195bf215546Sopenharmony_ci 196bf215546Sopenharmony_ci nir_builder_instr_insert(build, &load_const->instr); 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_ci return &load_const->def; 199bf215546Sopenharmony_ci} 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_cistatic inline nir_ssa_def * 202bf215546Sopenharmony_cinir_imm_boolN_t(nir_builder *build, bool x, unsigned bit_size) 203bf215546Sopenharmony_ci{ 204bf215546Sopenharmony_ci nir_const_value v = nir_const_value_for_bool(x, bit_size); 205bf215546Sopenharmony_ci return nir_build_imm(build, 1, bit_size, &v); 206bf215546Sopenharmony_ci} 207bf215546Sopenharmony_ci 208bf215546Sopenharmony_cistatic inline nir_ssa_def * 209bf215546Sopenharmony_cinir_imm_bool(nir_builder *build, bool x) 210bf215546Sopenharmony_ci{ 211bf215546Sopenharmony_ci return nir_imm_boolN_t(build, x, 1); 212bf215546Sopenharmony_ci} 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_cistatic inline nir_ssa_def * 215bf215546Sopenharmony_cinir_imm_true(nir_builder *build) 216bf215546Sopenharmony_ci{ 217bf215546Sopenharmony_ci return nir_imm_bool(build, true); 218bf215546Sopenharmony_ci} 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_cistatic inline nir_ssa_def * 221bf215546Sopenharmony_cinir_imm_false(nir_builder *build) 222bf215546Sopenharmony_ci{ 223bf215546Sopenharmony_ci return nir_imm_bool(build, false); 224bf215546Sopenharmony_ci} 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_cistatic inline nir_ssa_def * 227bf215546Sopenharmony_cinir_imm_floatN_t(nir_builder *build, double x, unsigned bit_size) 228bf215546Sopenharmony_ci{ 229bf215546Sopenharmony_ci nir_const_value v = nir_const_value_for_float(x, bit_size); 230bf215546Sopenharmony_ci return nir_build_imm(build, 1, bit_size, &v); 231bf215546Sopenharmony_ci} 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_cistatic inline nir_ssa_def * 234bf215546Sopenharmony_cinir_imm_float16(nir_builder *build, float x) 235bf215546Sopenharmony_ci{ 236bf215546Sopenharmony_ci return nir_imm_floatN_t(build, x, 16); 237bf215546Sopenharmony_ci} 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_cistatic inline nir_ssa_def * 240bf215546Sopenharmony_cinir_imm_float(nir_builder *build, float x) 241bf215546Sopenharmony_ci{ 242bf215546Sopenharmony_ci return nir_imm_floatN_t(build, x, 32); 243bf215546Sopenharmony_ci} 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_cistatic inline nir_ssa_def * 246bf215546Sopenharmony_cinir_imm_double(nir_builder *build, double x) 247bf215546Sopenharmony_ci{ 248bf215546Sopenharmony_ci return nir_imm_floatN_t(build, x, 64); 249bf215546Sopenharmony_ci} 250bf215546Sopenharmony_ci 251bf215546Sopenharmony_cistatic inline nir_ssa_def * 252bf215546Sopenharmony_cinir_imm_vec2(nir_builder *build, float x, float y) 253bf215546Sopenharmony_ci{ 254bf215546Sopenharmony_ci nir_const_value v[2] = { 255bf215546Sopenharmony_ci nir_const_value_for_float(x, 32), 256bf215546Sopenharmony_ci nir_const_value_for_float(y, 32), 257bf215546Sopenharmony_ci }; 258bf215546Sopenharmony_ci return nir_build_imm(build, 2, 32, v); 259bf215546Sopenharmony_ci} 260bf215546Sopenharmony_ci 261bf215546Sopenharmony_cistatic inline nir_ssa_def * 262bf215546Sopenharmony_cinir_imm_vec3(nir_builder *build, float x, float y, float z) 263bf215546Sopenharmony_ci{ 264bf215546Sopenharmony_ci nir_const_value v[3] = { 265bf215546Sopenharmony_ci nir_const_value_for_float(x, 32), 266bf215546Sopenharmony_ci nir_const_value_for_float(y, 32), 267bf215546Sopenharmony_ci nir_const_value_for_float(z, 32), 268bf215546Sopenharmony_ci }; 269bf215546Sopenharmony_ci return nir_build_imm(build, 3, 32, v); 270bf215546Sopenharmony_ci} 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_cistatic inline nir_ssa_def * 273bf215546Sopenharmony_cinir_imm_vec4(nir_builder *build, float x, float y, float z, float w) 274bf215546Sopenharmony_ci{ 275bf215546Sopenharmony_ci nir_const_value v[4] = { 276bf215546Sopenharmony_ci nir_const_value_for_float(x, 32), 277bf215546Sopenharmony_ci nir_const_value_for_float(y, 32), 278bf215546Sopenharmony_ci nir_const_value_for_float(z, 32), 279bf215546Sopenharmony_ci nir_const_value_for_float(w, 32), 280bf215546Sopenharmony_ci }; 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci return nir_build_imm(build, 4, 32, v); 283bf215546Sopenharmony_ci} 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_cistatic inline nir_ssa_def * 286bf215546Sopenharmony_cinir_imm_vec4_16(nir_builder *build, float x, float y, float z, float w) 287bf215546Sopenharmony_ci{ 288bf215546Sopenharmony_ci nir_const_value v[4] = { 289bf215546Sopenharmony_ci nir_const_value_for_float(x, 16), 290bf215546Sopenharmony_ci nir_const_value_for_float(y, 16), 291bf215546Sopenharmony_ci nir_const_value_for_float(z, 16), 292bf215546Sopenharmony_ci nir_const_value_for_float(w, 16), 293bf215546Sopenharmony_ci }; 294bf215546Sopenharmony_ci 295bf215546Sopenharmony_ci return nir_build_imm(build, 4, 16, v); 296bf215546Sopenharmony_ci} 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_cistatic inline nir_ssa_def * 299bf215546Sopenharmony_cinir_imm_intN_t(nir_builder *build, uint64_t x, unsigned bit_size) 300bf215546Sopenharmony_ci{ 301bf215546Sopenharmony_ci nir_const_value v = nir_const_value_for_raw_uint(x, bit_size); 302bf215546Sopenharmony_ci return nir_build_imm(build, 1, bit_size, &v); 303bf215546Sopenharmony_ci} 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_cistatic inline nir_ssa_def * 306bf215546Sopenharmony_cinir_imm_int(nir_builder *build, int x) 307bf215546Sopenharmony_ci{ 308bf215546Sopenharmony_ci return nir_imm_intN_t(build, x, 32); 309bf215546Sopenharmony_ci} 310bf215546Sopenharmony_ci 311bf215546Sopenharmony_cistatic inline nir_ssa_def * 312bf215546Sopenharmony_cinir_imm_int64(nir_builder *build, int64_t x) 313bf215546Sopenharmony_ci{ 314bf215546Sopenharmony_ci return nir_imm_intN_t(build, x, 64); 315bf215546Sopenharmony_ci} 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_cistatic inline nir_ssa_def * 318bf215546Sopenharmony_cinir_imm_ivec2(nir_builder *build, int x, int y) 319bf215546Sopenharmony_ci{ 320bf215546Sopenharmony_ci nir_const_value v[2] = { 321bf215546Sopenharmony_ci nir_const_value_for_int(x, 32), 322bf215546Sopenharmony_ci nir_const_value_for_int(y, 32), 323bf215546Sopenharmony_ci }; 324bf215546Sopenharmony_ci 325bf215546Sopenharmony_ci return nir_build_imm(build, 2, 32, v); 326bf215546Sopenharmony_ci} 327bf215546Sopenharmony_ci 328bf215546Sopenharmony_cistatic inline nir_ssa_def * 329bf215546Sopenharmony_cinir_imm_ivec3(nir_builder *build, int x, int y, int z) 330bf215546Sopenharmony_ci{ 331bf215546Sopenharmony_ci nir_const_value v[3] = { 332bf215546Sopenharmony_ci nir_const_value_for_int(x, 32), 333bf215546Sopenharmony_ci nir_const_value_for_int(y, 32), 334bf215546Sopenharmony_ci nir_const_value_for_int(z, 32), 335bf215546Sopenharmony_ci }; 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_ci return nir_build_imm(build, 3, 32, v); 338bf215546Sopenharmony_ci} 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_cistatic inline nir_ssa_def * 341bf215546Sopenharmony_cinir_imm_ivec4(nir_builder *build, int x, int y, int z, int w) 342bf215546Sopenharmony_ci{ 343bf215546Sopenharmony_ci nir_const_value v[4] = { 344bf215546Sopenharmony_ci nir_const_value_for_int(x, 32), 345bf215546Sopenharmony_ci nir_const_value_for_int(y, 32), 346bf215546Sopenharmony_ci nir_const_value_for_int(z, 32), 347bf215546Sopenharmony_ci nir_const_value_for_int(w, 32), 348bf215546Sopenharmony_ci }; 349bf215546Sopenharmony_ci 350bf215546Sopenharmony_ci return nir_build_imm(build, 4, 32, v); 351bf215546Sopenharmony_ci} 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_cinir_ssa_def * 354bf215546Sopenharmony_cinir_builder_alu_instr_finish_and_insert(nir_builder *build, nir_alu_instr *instr); 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_ci/* for the couple special cases with more than 4 src args: */ 357bf215546Sopenharmony_cinir_ssa_def * 358bf215546Sopenharmony_cinir_build_alu_src_arr(nir_builder *build, nir_op op, nir_ssa_def **srcs); 359bf215546Sopenharmony_ci 360bf215546Sopenharmony_ci/* Generic builder for system values. */ 361bf215546Sopenharmony_cinir_ssa_def * 362bf215546Sopenharmony_cinir_load_system_value(nir_builder *build, nir_intrinsic_op op, int index, 363bf215546Sopenharmony_ci unsigned num_components, unsigned bit_size); 364bf215546Sopenharmony_ci 365bf215546Sopenharmony_ci#include "nir_builder_opcodes.h" 366bf215546Sopenharmony_ci#undef nir_deref_mode_is 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_cistatic inline nir_ssa_def * 369bf215546Sopenharmony_cinir_vec(nir_builder *build, nir_ssa_def **comp, unsigned num_components) 370bf215546Sopenharmony_ci{ 371bf215546Sopenharmony_ci return nir_build_alu_src_arr(build, nir_op_vec(num_components), comp); 372bf215546Sopenharmony_ci} 373bf215546Sopenharmony_ci 374bf215546Sopenharmony_cinir_ssa_def * 375bf215546Sopenharmony_cinir_vec_scalars(nir_builder *build, nir_ssa_scalar *comp, unsigned num_components); 376bf215546Sopenharmony_ci 377bf215546Sopenharmony_cistatic inline nir_ssa_def * 378bf215546Sopenharmony_cinir_mov_alu(nir_builder *build, nir_alu_src src, unsigned num_components) 379bf215546Sopenharmony_ci{ 380bf215546Sopenharmony_ci assert(!src.abs && !src.negate); 381bf215546Sopenharmony_ci if (src.src.is_ssa && src.src.ssa->num_components == num_components) { 382bf215546Sopenharmony_ci bool any_swizzles = false; 383bf215546Sopenharmony_ci for (unsigned i = 0; i < num_components; i++) { 384bf215546Sopenharmony_ci if (src.swizzle[i] != i) 385bf215546Sopenharmony_ci any_swizzles = true; 386bf215546Sopenharmony_ci } 387bf215546Sopenharmony_ci if (!any_swizzles) 388bf215546Sopenharmony_ci return src.src.ssa; 389bf215546Sopenharmony_ci } 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_ci nir_alu_instr *mov = nir_alu_instr_create(build->shader, nir_op_mov); 392bf215546Sopenharmony_ci nir_ssa_dest_init(&mov->instr, &mov->dest.dest, num_components, 393bf215546Sopenharmony_ci nir_src_bit_size(src.src), NULL); 394bf215546Sopenharmony_ci mov->exact = build->exact; 395bf215546Sopenharmony_ci mov->dest.write_mask = (1 << num_components) - 1; 396bf215546Sopenharmony_ci mov->src[0] = src; 397bf215546Sopenharmony_ci nir_builder_instr_insert(build, &mov->instr); 398bf215546Sopenharmony_ci 399bf215546Sopenharmony_ci return &mov->dest.dest.ssa; 400bf215546Sopenharmony_ci} 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ci/** 403bf215546Sopenharmony_ci * Construct a mov that reswizzles the source's components. 404bf215546Sopenharmony_ci */ 405bf215546Sopenharmony_cistatic inline nir_ssa_def * 406bf215546Sopenharmony_cinir_swizzle(nir_builder *build, nir_ssa_def *src, const unsigned *swiz, 407bf215546Sopenharmony_ci unsigned num_components) 408bf215546Sopenharmony_ci{ 409bf215546Sopenharmony_ci assert(num_components <= NIR_MAX_VEC_COMPONENTS); 410bf215546Sopenharmony_ci nir_alu_src alu_src = { NIR_SRC_INIT }; 411bf215546Sopenharmony_ci alu_src.src = nir_src_for_ssa(src); 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_ci bool is_identity_swizzle = true; 414bf215546Sopenharmony_ci for (unsigned i = 0; i < num_components && i < NIR_MAX_VEC_COMPONENTS; i++) { 415bf215546Sopenharmony_ci if (swiz[i] != i) 416bf215546Sopenharmony_ci is_identity_swizzle = false; 417bf215546Sopenharmony_ci alu_src.swizzle[i] = swiz[i]; 418bf215546Sopenharmony_ci } 419bf215546Sopenharmony_ci 420bf215546Sopenharmony_ci if (num_components == src->num_components && is_identity_swizzle) 421bf215546Sopenharmony_ci return src; 422bf215546Sopenharmony_ci 423bf215546Sopenharmony_ci return nir_mov_alu(build, alu_src, num_components); 424bf215546Sopenharmony_ci} 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci/* Selects the right fdot given the number of components in each source. */ 427bf215546Sopenharmony_cistatic inline nir_ssa_def * 428bf215546Sopenharmony_cinir_fdot(nir_builder *build, nir_ssa_def *src0, nir_ssa_def *src1) 429bf215546Sopenharmony_ci{ 430bf215546Sopenharmony_ci assert(src0->num_components == src1->num_components); 431bf215546Sopenharmony_ci switch (src0->num_components) { 432bf215546Sopenharmony_ci case 1: return nir_fmul(build, src0, src1); 433bf215546Sopenharmony_ci case 2: return nir_fdot2(build, src0, src1); 434bf215546Sopenharmony_ci case 3: return nir_fdot3(build, src0, src1); 435bf215546Sopenharmony_ci case 4: return nir_fdot4(build, src0, src1); 436bf215546Sopenharmony_ci case 5: return nir_fdot5(build, src0, src1); 437bf215546Sopenharmony_ci case 8: return nir_fdot8(build, src0, src1); 438bf215546Sopenharmony_ci case 16: return nir_fdot16(build, src0, src1); 439bf215546Sopenharmony_ci default: 440bf215546Sopenharmony_ci unreachable("bad component size"); 441bf215546Sopenharmony_ci } 442bf215546Sopenharmony_ci 443bf215546Sopenharmony_ci return NULL; 444bf215546Sopenharmony_ci} 445bf215546Sopenharmony_ci 446bf215546Sopenharmony_cistatic inline nir_ssa_def * 447bf215546Sopenharmony_cinir_ball_iequal(nir_builder *b, nir_ssa_def *src0, nir_ssa_def *src1) 448bf215546Sopenharmony_ci{ 449bf215546Sopenharmony_ci switch (src0->num_components) { 450bf215546Sopenharmony_ci case 1: return nir_ieq(b, src0, src1); 451bf215546Sopenharmony_ci case 2: return nir_ball_iequal2(b, src0, src1); 452bf215546Sopenharmony_ci case 3: return nir_ball_iequal3(b, src0, src1); 453bf215546Sopenharmony_ci case 4: return nir_ball_iequal4(b, src0, src1); 454bf215546Sopenharmony_ci case 5: return nir_ball_iequal5(b, src0, src1); 455bf215546Sopenharmony_ci case 8: return nir_ball_iequal8(b, src0, src1); 456bf215546Sopenharmony_ci case 16: return nir_ball_iequal16(b, src0, src1); 457bf215546Sopenharmony_ci default: 458bf215546Sopenharmony_ci unreachable("bad component size"); 459bf215546Sopenharmony_ci } 460bf215546Sopenharmony_ci} 461bf215546Sopenharmony_ci 462bf215546Sopenharmony_cistatic inline nir_ssa_def * 463bf215546Sopenharmony_cinir_ball(nir_builder *b, nir_ssa_def *src) 464bf215546Sopenharmony_ci{ 465bf215546Sopenharmony_ci return nir_ball_iequal(b, src, nir_imm_true(b)); 466bf215546Sopenharmony_ci} 467bf215546Sopenharmony_ci 468bf215546Sopenharmony_cistatic inline nir_ssa_def * 469bf215546Sopenharmony_cinir_bany_inequal(nir_builder *b, nir_ssa_def *src0, nir_ssa_def *src1) 470bf215546Sopenharmony_ci{ 471bf215546Sopenharmony_ci switch (src0->num_components) { 472bf215546Sopenharmony_ci case 1: return nir_ine(b, src0, src1); 473bf215546Sopenharmony_ci case 2: return nir_bany_inequal2(b, src0, src1); 474bf215546Sopenharmony_ci case 3: return nir_bany_inequal3(b, src0, src1); 475bf215546Sopenharmony_ci case 4: return nir_bany_inequal4(b, src0, src1); 476bf215546Sopenharmony_ci case 5: return nir_bany_inequal5(b, src0, src1); 477bf215546Sopenharmony_ci case 8: return nir_bany_inequal8(b, src0, src1); 478bf215546Sopenharmony_ci case 16: return nir_bany_inequal16(b, src0, src1); 479bf215546Sopenharmony_ci default: 480bf215546Sopenharmony_ci unreachable("bad component size"); 481bf215546Sopenharmony_ci } 482bf215546Sopenharmony_ci} 483bf215546Sopenharmony_ci 484bf215546Sopenharmony_cistatic inline nir_ssa_def * 485bf215546Sopenharmony_cinir_bany(nir_builder *b, nir_ssa_def *src) 486bf215546Sopenharmony_ci{ 487bf215546Sopenharmony_ci return nir_bany_inequal(b, src, nir_imm_false(b)); 488bf215546Sopenharmony_ci} 489bf215546Sopenharmony_ci 490bf215546Sopenharmony_cistatic inline nir_ssa_def * 491bf215546Sopenharmony_cinir_channel(nir_builder *b, nir_ssa_def *def, unsigned c) 492bf215546Sopenharmony_ci{ 493bf215546Sopenharmony_ci return nir_swizzle(b, def, &c, 1); 494bf215546Sopenharmony_ci} 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_cistatic inline nir_ssa_def * 497bf215546Sopenharmony_cinir_channels(nir_builder *b, nir_ssa_def *def, nir_component_mask_t mask) 498bf215546Sopenharmony_ci{ 499bf215546Sopenharmony_ci unsigned num_channels = 0, swizzle[NIR_MAX_VEC_COMPONENTS] = { 0 }; 500bf215546Sopenharmony_ci 501bf215546Sopenharmony_ci for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) { 502bf215546Sopenharmony_ci if ((mask & (1 << i)) == 0) 503bf215546Sopenharmony_ci continue; 504bf215546Sopenharmony_ci swizzle[num_channels++] = i; 505bf215546Sopenharmony_ci } 506bf215546Sopenharmony_ci 507bf215546Sopenharmony_ci return nir_swizzle(b, def, swizzle, num_channels); 508bf215546Sopenharmony_ci} 509bf215546Sopenharmony_ci 510bf215546Sopenharmony_cistatic inline nir_ssa_def * 511bf215546Sopenharmony_ci_nir_select_from_array_helper(nir_builder *b, nir_ssa_def **arr, 512bf215546Sopenharmony_ci nir_ssa_def *idx, 513bf215546Sopenharmony_ci unsigned start, unsigned end) 514bf215546Sopenharmony_ci{ 515bf215546Sopenharmony_ci if (start == end - 1) { 516bf215546Sopenharmony_ci return arr[start]; 517bf215546Sopenharmony_ci } else { 518bf215546Sopenharmony_ci unsigned mid = start + (end - start) / 2; 519bf215546Sopenharmony_ci return nir_bcsel(b, nir_ilt(b, idx, nir_imm_intN_t(b, mid, idx->bit_size)), 520bf215546Sopenharmony_ci _nir_select_from_array_helper(b, arr, idx, start, mid), 521bf215546Sopenharmony_ci _nir_select_from_array_helper(b, arr, idx, mid, end)); 522bf215546Sopenharmony_ci } 523bf215546Sopenharmony_ci} 524bf215546Sopenharmony_ci 525bf215546Sopenharmony_cistatic inline nir_ssa_def * 526bf215546Sopenharmony_cinir_select_from_ssa_def_array(nir_builder *b, nir_ssa_def **arr, 527bf215546Sopenharmony_ci unsigned arr_len, nir_ssa_def *idx) 528bf215546Sopenharmony_ci{ 529bf215546Sopenharmony_ci return _nir_select_from_array_helper(b, arr, idx, 0, arr_len); 530bf215546Sopenharmony_ci} 531bf215546Sopenharmony_ci 532bf215546Sopenharmony_cistatic inline nir_ssa_def * 533bf215546Sopenharmony_cinir_vector_extract(nir_builder *b, nir_ssa_def *vec, nir_ssa_def *c) 534bf215546Sopenharmony_ci{ 535bf215546Sopenharmony_ci nir_src c_src = nir_src_for_ssa(c); 536bf215546Sopenharmony_ci if (nir_src_is_const(c_src)) { 537bf215546Sopenharmony_ci uint64_t c_const = nir_src_as_uint(c_src); 538bf215546Sopenharmony_ci if (c_const < vec->num_components) 539bf215546Sopenharmony_ci return nir_channel(b, vec, c_const); 540bf215546Sopenharmony_ci else 541bf215546Sopenharmony_ci return nir_ssa_undef(b, 1, vec->bit_size); 542bf215546Sopenharmony_ci } else { 543bf215546Sopenharmony_ci nir_ssa_def *comps[NIR_MAX_VEC_COMPONENTS]; 544bf215546Sopenharmony_ci for (unsigned i = 0; i < vec->num_components; i++) 545bf215546Sopenharmony_ci comps[i] = nir_channel(b, vec, i); 546bf215546Sopenharmony_ci return nir_select_from_ssa_def_array(b, comps, vec->num_components, c); 547bf215546Sopenharmony_ci } 548bf215546Sopenharmony_ci} 549bf215546Sopenharmony_ci 550bf215546Sopenharmony_ci/** Replaces the component of `vec` specified by `c` with `scalar` */ 551bf215546Sopenharmony_cistatic inline nir_ssa_def * 552bf215546Sopenharmony_cinir_vector_insert_imm(nir_builder *b, nir_ssa_def *vec, 553bf215546Sopenharmony_ci nir_ssa_def *scalar, unsigned c) 554bf215546Sopenharmony_ci{ 555bf215546Sopenharmony_ci assert(scalar->num_components == 1); 556bf215546Sopenharmony_ci assert(c < vec->num_components); 557bf215546Sopenharmony_ci 558bf215546Sopenharmony_ci nir_op vec_op = nir_op_vec(vec->num_components); 559bf215546Sopenharmony_ci nir_alu_instr *vec_instr = nir_alu_instr_create(b->shader, vec_op); 560bf215546Sopenharmony_ci 561bf215546Sopenharmony_ci for (unsigned i = 0; i < vec->num_components; i++) { 562bf215546Sopenharmony_ci if (i == c) { 563bf215546Sopenharmony_ci vec_instr->src[i].src = nir_src_for_ssa(scalar); 564bf215546Sopenharmony_ci vec_instr->src[i].swizzle[0] = 0; 565bf215546Sopenharmony_ci } else { 566bf215546Sopenharmony_ci vec_instr->src[i].src = nir_src_for_ssa(vec); 567bf215546Sopenharmony_ci vec_instr->src[i].swizzle[0] = i; 568bf215546Sopenharmony_ci } 569bf215546Sopenharmony_ci } 570bf215546Sopenharmony_ci 571bf215546Sopenharmony_ci return nir_builder_alu_instr_finish_and_insert(b, vec_instr); 572bf215546Sopenharmony_ci} 573bf215546Sopenharmony_ci 574bf215546Sopenharmony_ci/** Replaces the component of `vec` specified by `c` with `scalar` */ 575bf215546Sopenharmony_cistatic inline nir_ssa_def * 576bf215546Sopenharmony_cinir_vector_insert(nir_builder *b, nir_ssa_def *vec, nir_ssa_def *scalar, 577bf215546Sopenharmony_ci nir_ssa_def *c) 578bf215546Sopenharmony_ci{ 579bf215546Sopenharmony_ci assert(scalar->num_components == 1); 580bf215546Sopenharmony_ci assert(c->num_components == 1); 581bf215546Sopenharmony_ci 582bf215546Sopenharmony_ci nir_src c_src = nir_src_for_ssa(c); 583bf215546Sopenharmony_ci if (nir_src_is_const(c_src)) { 584bf215546Sopenharmony_ci uint64_t c_const = nir_src_as_uint(c_src); 585bf215546Sopenharmony_ci if (c_const < vec->num_components) 586bf215546Sopenharmony_ci return nir_vector_insert_imm(b, vec, scalar, c_const); 587bf215546Sopenharmony_ci else 588bf215546Sopenharmony_ci return vec; 589bf215546Sopenharmony_ci } else { 590bf215546Sopenharmony_ci nir_const_value per_comp_idx_const[NIR_MAX_VEC_COMPONENTS]; 591bf215546Sopenharmony_ci for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) 592bf215546Sopenharmony_ci per_comp_idx_const[i] = nir_const_value_for_int(i, c->bit_size); 593bf215546Sopenharmony_ci nir_ssa_def *per_comp_idx = 594bf215546Sopenharmony_ci nir_build_imm(b, vec->num_components, 595bf215546Sopenharmony_ci c->bit_size, per_comp_idx_const); 596bf215546Sopenharmony_ci 597bf215546Sopenharmony_ci /* nir_builder will automatically splat out scalars to vectors so an 598bf215546Sopenharmony_ci * insert is as simple as "if I'm the channel, replace me with the 599bf215546Sopenharmony_ci * scalar." 600bf215546Sopenharmony_ci */ 601bf215546Sopenharmony_ci return nir_bcsel(b, nir_ieq(b, c, per_comp_idx), scalar, vec); 602bf215546Sopenharmony_ci } 603bf215546Sopenharmony_ci} 604bf215546Sopenharmony_ci 605bf215546Sopenharmony_cistatic inline nir_ssa_def * 606bf215546Sopenharmony_cinir_i2i(nir_builder *build, nir_ssa_def *x, unsigned dest_bit_size) 607bf215546Sopenharmony_ci{ 608bf215546Sopenharmony_ci if (x->bit_size == dest_bit_size) 609bf215546Sopenharmony_ci return x; 610bf215546Sopenharmony_ci 611bf215546Sopenharmony_ci switch (dest_bit_size) { 612bf215546Sopenharmony_ci case 64: return nir_i2i64(build, x); 613bf215546Sopenharmony_ci case 32: return nir_i2i32(build, x); 614bf215546Sopenharmony_ci case 16: return nir_i2i16(build, x); 615bf215546Sopenharmony_ci case 8: return nir_i2i8(build, x); 616bf215546Sopenharmony_ci default: unreachable("Invalid bit size"); 617bf215546Sopenharmony_ci } 618bf215546Sopenharmony_ci} 619bf215546Sopenharmony_ci 620bf215546Sopenharmony_cistatic inline nir_ssa_def * 621bf215546Sopenharmony_cinir_u2u(nir_builder *build, nir_ssa_def *x, unsigned dest_bit_size) 622bf215546Sopenharmony_ci{ 623bf215546Sopenharmony_ci if (x->bit_size == dest_bit_size) 624bf215546Sopenharmony_ci return x; 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci switch (dest_bit_size) { 627bf215546Sopenharmony_ci case 64: return nir_u2u64(build, x); 628bf215546Sopenharmony_ci case 32: return nir_u2u32(build, x); 629bf215546Sopenharmony_ci case 16: return nir_u2u16(build, x); 630bf215546Sopenharmony_ci case 8: return nir_u2u8(build, x); 631bf215546Sopenharmony_ci default: unreachable("Invalid bit size"); 632bf215546Sopenharmony_ci } 633bf215546Sopenharmony_ci} 634bf215546Sopenharmony_ci 635bf215546Sopenharmony_cistatic inline nir_ssa_def * 636bf215546Sopenharmony_cinir_iadd_imm(nir_builder *build, nir_ssa_def *x, uint64_t y) 637bf215546Sopenharmony_ci{ 638bf215546Sopenharmony_ci assert(x->bit_size <= 64); 639bf215546Sopenharmony_ci y &= BITFIELD64_MASK(x->bit_size); 640bf215546Sopenharmony_ci 641bf215546Sopenharmony_ci if (y == 0) { 642bf215546Sopenharmony_ci return x; 643bf215546Sopenharmony_ci } else { 644bf215546Sopenharmony_ci return nir_iadd(build, x, nir_imm_intN_t(build, y, x->bit_size)); 645bf215546Sopenharmony_ci } 646bf215546Sopenharmony_ci} 647bf215546Sopenharmony_ci 648bf215546Sopenharmony_cistatic inline nir_ssa_def * 649bf215546Sopenharmony_cinir_iadd_imm_nuw(nir_builder *b, nir_ssa_def *x, uint64_t y) 650bf215546Sopenharmony_ci{ 651bf215546Sopenharmony_ci nir_ssa_def *d = nir_iadd_imm(b, x, y); 652bf215546Sopenharmony_ci if (d != x && d->parent_instr->type == nir_instr_type_alu) 653bf215546Sopenharmony_ci nir_instr_as_alu(d->parent_instr)->no_unsigned_wrap = true; 654bf215546Sopenharmony_ci return d; 655bf215546Sopenharmony_ci} 656bf215546Sopenharmony_ci 657bf215546Sopenharmony_cistatic inline nir_ssa_def * 658bf215546Sopenharmony_cinir_iadd_nuw(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y) 659bf215546Sopenharmony_ci{ 660bf215546Sopenharmony_ci nir_ssa_def *d = nir_iadd(b, x, y); 661bf215546Sopenharmony_ci nir_instr_as_alu(d->parent_instr)->no_unsigned_wrap = true; 662bf215546Sopenharmony_ci return d; 663bf215546Sopenharmony_ci} 664bf215546Sopenharmony_ci 665bf215546Sopenharmony_cistatic inline nir_ssa_def * 666bf215546Sopenharmony_cinir_ieq_imm(nir_builder *build, nir_ssa_def *x, uint64_t y) 667bf215546Sopenharmony_ci{ 668bf215546Sopenharmony_ci return nir_ieq(build, x, nir_imm_intN_t(build, y, x->bit_size)); 669bf215546Sopenharmony_ci} 670bf215546Sopenharmony_ci 671bf215546Sopenharmony_cistatic inline nir_ssa_def * 672bf215546Sopenharmony_cinir_ine_imm(nir_builder *build, nir_ssa_def *x, uint64_t y) 673bf215546Sopenharmony_ci{ 674bf215546Sopenharmony_ci return nir_ine(build, x, nir_imm_intN_t(build, y, x->bit_size)); 675bf215546Sopenharmony_ci} 676bf215546Sopenharmony_ci 677bf215546Sopenharmony_ci/* Use nir_iadd(x, -y) for reversing parameter ordering */ 678bf215546Sopenharmony_cistatic inline nir_ssa_def * 679bf215546Sopenharmony_cinir_isub_imm(nir_builder *build, uint64_t y, nir_ssa_def *x) 680bf215546Sopenharmony_ci{ 681bf215546Sopenharmony_ci return nir_isub(build, nir_imm_intN_t(build, y, x->bit_size), x); 682bf215546Sopenharmony_ci} 683bf215546Sopenharmony_ci 684bf215546Sopenharmony_cistatic inline nir_ssa_def * 685bf215546Sopenharmony_ci_nir_mul_imm(nir_builder *build, nir_ssa_def *x, uint64_t y, bool amul) 686bf215546Sopenharmony_ci{ 687bf215546Sopenharmony_ci assert(x->bit_size <= 64); 688bf215546Sopenharmony_ci y &= BITFIELD64_MASK(x->bit_size); 689bf215546Sopenharmony_ci 690bf215546Sopenharmony_ci if (y == 0) { 691bf215546Sopenharmony_ci return nir_imm_intN_t(build, 0, x->bit_size); 692bf215546Sopenharmony_ci } else if (y == 1) { 693bf215546Sopenharmony_ci return x; 694bf215546Sopenharmony_ci } else if (!build->shader->options->lower_bitops && 695bf215546Sopenharmony_ci util_is_power_of_two_or_zero64(y)) { 696bf215546Sopenharmony_ci return nir_ishl(build, x, nir_imm_int(build, ffsll(y) - 1)); 697bf215546Sopenharmony_ci } else if (amul) { 698bf215546Sopenharmony_ci return nir_amul(build, x, nir_imm_intN_t(build, y, x->bit_size)); 699bf215546Sopenharmony_ci } else { 700bf215546Sopenharmony_ci return nir_imul(build, x, nir_imm_intN_t(build, y, x->bit_size)); 701bf215546Sopenharmony_ci } 702bf215546Sopenharmony_ci} 703bf215546Sopenharmony_ci 704bf215546Sopenharmony_cistatic inline nir_ssa_def * 705bf215546Sopenharmony_cinir_imul_imm(nir_builder *build, nir_ssa_def *x, uint64_t y) 706bf215546Sopenharmony_ci{ 707bf215546Sopenharmony_ci return _nir_mul_imm(build, x, y, false); 708bf215546Sopenharmony_ci} 709bf215546Sopenharmony_ci 710bf215546Sopenharmony_cistatic inline nir_ssa_def * 711bf215546Sopenharmony_cinir_amul_imm(nir_builder *build, nir_ssa_def *x, uint64_t y) 712bf215546Sopenharmony_ci{ 713bf215546Sopenharmony_ci return _nir_mul_imm(build, x, y, true); 714bf215546Sopenharmony_ci} 715bf215546Sopenharmony_ci 716bf215546Sopenharmony_cistatic inline nir_ssa_def * 717bf215546Sopenharmony_cinir_fadd_imm(nir_builder *build, nir_ssa_def *x, double y) 718bf215546Sopenharmony_ci{ 719bf215546Sopenharmony_ci return nir_fadd(build, x, nir_imm_floatN_t(build, y, x->bit_size)); 720bf215546Sopenharmony_ci} 721bf215546Sopenharmony_ci 722bf215546Sopenharmony_cistatic inline nir_ssa_def * 723bf215546Sopenharmony_cinir_fmul_imm(nir_builder *build, nir_ssa_def *x, double y) 724bf215546Sopenharmony_ci{ 725bf215546Sopenharmony_ci return nir_fmul(build, x, nir_imm_floatN_t(build, y, x->bit_size)); 726bf215546Sopenharmony_ci} 727bf215546Sopenharmony_ci 728bf215546Sopenharmony_cistatic inline nir_ssa_def * 729bf215546Sopenharmony_cinir_iand_imm(nir_builder *build, nir_ssa_def *x, uint64_t y) 730bf215546Sopenharmony_ci{ 731bf215546Sopenharmony_ci assert(x->bit_size <= 64); 732bf215546Sopenharmony_ci y &= BITFIELD64_MASK(x->bit_size); 733bf215546Sopenharmony_ci 734bf215546Sopenharmony_ci if (y == 0) { 735bf215546Sopenharmony_ci return nir_imm_intN_t(build, 0, x->bit_size); 736bf215546Sopenharmony_ci } else if (y == BITFIELD64_MASK(x->bit_size)) { 737bf215546Sopenharmony_ci return x; 738bf215546Sopenharmony_ci } else { 739bf215546Sopenharmony_ci return nir_iand(build, x, nir_imm_intN_t(build, y, x->bit_size)); 740bf215546Sopenharmony_ci } 741bf215546Sopenharmony_ci} 742bf215546Sopenharmony_ci 743bf215546Sopenharmony_cistatic inline nir_ssa_def * 744bf215546Sopenharmony_cinir_test_mask(nir_builder *build, nir_ssa_def *x, uint64_t mask) 745bf215546Sopenharmony_ci{ 746bf215546Sopenharmony_ci assert(mask <= BITFIELD64_MASK(x->bit_size)); 747bf215546Sopenharmony_ci return nir_ine_imm(build, nir_iand_imm(build, x, mask), 0); 748bf215546Sopenharmony_ci} 749bf215546Sopenharmony_ci 750bf215546Sopenharmony_cistatic inline nir_ssa_def * 751bf215546Sopenharmony_cinir_ior_imm(nir_builder *build, nir_ssa_def *x, uint64_t y) 752bf215546Sopenharmony_ci{ 753bf215546Sopenharmony_ci assert(x->bit_size <= 64); 754bf215546Sopenharmony_ci y &= BITFIELD64_MASK(x->bit_size); 755bf215546Sopenharmony_ci 756bf215546Sopenharmony_ci if (y == 0) { 757bf215546Sopenharmony_ci return x; 758bf215546Sopenharmony_ci } else if (y == BITFIELD64_MASK(x->bit_size)) { 759bf215546Sopenharmony_ci return nir_imm_intN_t(build, y, x->bit_size); 760bf215546Sopenharmony_ci } else 761bf215546Sopenharmony_ci return nir_ior(build, x, nir_imm_intN_t(build, y, x->bit_size)); 762bf215546Sopenharmony_ci} 763bf215546Sopenharmony_ci 764bf215546Sopenharmony_cistatic inline nir_ssa_def * 765bf215546Sopenharmony_cinir_ishl_imm(nir_builder *build, nir_ssa_def *x, uint32_t y) 766bf215546Sopenharmony_ci{ 767bf215546Sopenharmony_ci if (y == 0) { 768bf215546Sopenharmony_ci return x; 769bf215546Sopenharmony_ci } else if (y >= x->bit_size) { 770bf215546Sopenharmony_ci return nir_imm_intN_t(build, 0, x->bit_size); 771bf215546Sopenharmony_ci } else { 772bf215546Sopenharmony_ci return nir_ishl(build, x, nir_imm_int(build, y)); 773bf215546Sopenharmony_ci } 774bf215546Sopenharmony_ci} 775bf215546Sopenharmony_ci 776bf215546Sopenharmony_cistatic inline nir_ssa_def * 777bf215546Sopenharmony_cinir_ishr_imm(nir_builder *build, nir_ssa_def *x, uint32_t y) 778bf215546Sopenharmony_ci{ 779bf215546Sopenharmony_ci if (y == 0) { 780bf215546Sopenharmony_ci return x; 781bf215546Sopenharmony_ci } else { 782bf215546Sopenharmony_ci return nir_ishr(build, x, nir_imm_int(build, y)); 783bf215546Sopenharmony_ci } 784bf215546Sopenharmony_ci} 785bf215546Sopenharmony_ci 786bf215546Sopenharmony_cistatic inline nir_ssa_def * 787bf215546Sopenharmony_cinir_ushr_imm(nir_builder *build, nir_ssa_def *x, uint32_t y) 788bf215546Sopenharmony_ci{ 789bf215546Sopenharmony_ci if (y == 0) { 790bf215546Sopenharmony_ci return x; 791bf215546Sopenharmony_ci } else { 792bf215546Sopenharmony_ci return nir_ushr(build, x, nir_imm_int(build, y)); 793bf215546Sopenharmony_ci } 794bf215546Sopenharmony_ci} 795bf215546Sopenharmony_ci 796bf215546Sopenharmony_cistatic inline nir_ssa_def * 797bf215546Sopenharmony_cinir_udiv_imm(nir_builder *build, nir_ssa_def *x, uint64_t y) 798bf215546Sopenharmony_ci{ 799bf215546Sopenharmony_ci assert(x->bit_size <= 64); 800bf215546Sopenharmony_ci y &= BITFIELD64_MASK(x->bit_size); 801bf215546Sopenharmony_ci 802bf215546Sopenharmony_ci if (y == 1) { 803bf215546Sopenharmony_ci return x; 804bf215546Sopenharmony_ci } else if (util_is_power_of_two_nonzero(y)) { 805bf215546Sopenharmony_ci return nir_ushr_imm(build, x, ffsll(y) - 1); 806bf215546Sopenharmony_ci } else { 807bf215546Sopenharmony_ci return nir_udiv(build, x, nir_imm_intN_t(build, y, x->bit_size)); 808bf215546Sopenharmony_ci } 809bf215546Sopenharmony_ci} 810bf215546Sopenharmony_ci 811bf215546Sopenharmony_cistatic inline nir_ssa_def * 812bf215546Sopenharmony_cinir_ibfe_imm(nir_builder *build, nir_ssa_def *x, uint32_t offset, uint32_t size) 813bf215546Sopenharmony_ci{ 814bf215546Sopenharmony_ci return nir_ibfe(build, x, nir_imm_int(build, offset), nir_imm_int(build, size)); 815bf215546Sopenharmony_ci} 816bf215546Sopenharmony_ci 817bf215546Sopenharmony_cistatic inline nir_ssa_def * 818bf215546Sopenharmony_cinir_ubfe_imm(nir_builder *build, nir_ssa_def *x, uint32_t offset, uint32_t size) 819bf215546Sopenharmony_ci{ 820bf215546Sopenharmony_ci return nir_ubfe(build, x, nir_imm_int(build, offset), nir_imm_int(build, size)); 821bf215546Sopenharmony_ci} 822bf215546Sopenharmony_ci 823bf215546Sopenharmony_cistatic inline nir_ssa_def * 824bf215546Sopenharmony_cinir_fclamp(nir_builder *b, 825bf215546Sopenharmony_ci nir_ssa_def *x, nir_ssa_def *min_val, nir_ssa_def *max_val) 826bf215546Sopenharmony_ci{ 827bf215546Sopenharmony_ci return nir_fmin(b, nir_fmax(b, x, min_val), max_val); 828bf215546Sopenharmony_ci} 829bf215546Sopenharmony_ci 830bf215546Sopenharmony_cistatic inline nir_ssa_def * 831bf215546Sopenharmony_cinir_iclamp(nir_builder *b, 832bf215546Sopenharmony_ci nir_ssa_def *x, nir_ssa_def *min_val, nir_ssa_def *max_val) 833bf215546Sopenharmony_ci{ 834bf215546Sopenharmony_ci return nir_imin(b, nir_imax(b, x, min_val), max_val); 835bf215546Sopenharmony_ci} 836bf215546Sopenharmony_ci 837bf215546Sopenharmony_cistatic inline nir_ssa_def * 838bf215546Sopenharmony_cinir_uclamp(nir_builder *b, 839bf215546Sopenharmony_ci nir_ssa_def *x, nir_ssa_def *min_val, nir_ssa_def *max_val) 840bf215546Sopenharmony_ci{ 841bf215546Sopenharmony_ci return nir_umin(b, nir_umax(b, x, min_val), max_val); 842bf215546Sopenharmony_ci} 843bf215546Sopenharmony_ci 844bf215546Sopenharmony_cistatic inline nir_ssa_def * 845bf215546Sopenharmony_cinir_ffma_imm12(nir_builder *build, nir_ssa_def *src0, double src1, double src2) 846bf215546Sopenharmony_ci{ 847bf215546Sopenharmony_ci if (build->shader->options->avoid_ternary_with_two_constants) 848bf215546Sopenharmony_ci return nir_fadd_imm(build, nir_fmul_imm(build, src0, src1), src2); 849bf215546Sopenharmony_ci else 850bf215546Sopenharmony_ci return nir_ffma(build, src0, nir_imm_floatN_t(build, src1, src0->bit_size), 851bf215546Sopenharmony_ci nir_imm_floatN_t(build, src2, src0->bit_size)); 852bf215546Sopenharmony_ci} 853bf215546Sopenharmony_ci 854bf215546Sopenharmony_cistatic inline nir_ssa_def * 855bf215546Sopenharmony_cinir_ffma_imm1(nir_builder *build, nir_ssa_def *src0, double src1, nir_ssa_def *src2) 856bf215546Sopenharmony_ci{ 857bf215546Sopenharmony_ci return nir_ffma(build, src0, nir_imm_floatN_t(build, src1, src0->bit_size), src2); 858bf215546Sopenharmony_ci} 859bf215546Sopenharmony_ci 860bf215546Sopenharmony_cistatic inline nir_ssa_def * 861bf215546Sopenharmony_cinir_ffma_imm2(nir_builder *build, nir_ssa_def *src0, nir_ssa_def *src1, double src2) 862bf215546Sopenharmony_ci{ 863bf215546Sopenharmony_ci return nir_ffma(build, src0, src1, nir_imm_floatN_t(build, src2, src0->bit_size)); 864bf215546Sopenharmony_ci} 865bf215546Sopenharmony_ci 866bf215546Sopenharmony_cistatic inline nir_ssa_def * 867bf215546Sopenharmony_cinir_a_minus_bc(nir_builder *build, nir_ssa_def *src0, nir_ssa_def *src1, 868bf215546Sopenharmony_ci nir_ssa_def *src2) 869bf215546Sopenharmony_ci{ 870bf215546Sopenharmony_ci return nir_ffma(build, nir_fneg(build, src1), src2, src0); 871bf215546Sopenharmony_ci} 872bf215546Sopenharmony_ci 873bf215546Sopenharmony_cistatic inline nir_ssa_def * 874bf215546Sopenharmony_cinir_pack_bits(nir_builder *b, nir_ssa_def *src, unsigned dest_bit_size) 875bf215546Sopenharmony_ci{ 876bf215546Sopenharmony_ci assert(src->num_components * src->bit_size == dest_bit_size); 877bf215546Sopenharmony_ci 878bf215546Sopenharmony_ci switch (dest_bit_size) { 879bf215546Sopenharmony_ci case 64: 880bf215546Sopenharmony_ci switch (src->bit_size) { 881bf215546Sopenharmony_ci case 32: return nir_pack_64_2x32(b, src); 882bf215546Sopenharmony_ci case 16: return nir_pack_64_4x16(b, src); 883bf215546Sopenharmony_ci default: break; 884bf215546Sopenharmony_ci } 885bf215546Sopenharmony_ci break; 886bf215546Sopenharmony_ci 887bf215546Sopenharmony_ci case 32: 888bf215546Sopenharmony_ci if (src->bit_size == 16) 889bf215546Sopenharmony_ci return nir_pack_32_2x16(b, src); 890bf215546Sopenharmony_ci break; 891bf215546Sopenharmony_ci 892bf215546Sopenharmony_ci default: 893bf215546Sopenharmony_ci break; 894bf215546Sopenharmony_ci } 895bf215546Sopenharmony_ci 896bf215546Sopenharmony_ci /* If we got here, we have no dedicated unpack opcode. */ 897bf215546Sopenharmony_ci nir_ssa_def *dest = nir_imm_intN_t(b, 0, dest_bit_size); 898bf215546Sopenharmony_ci for (unsigned i = 0; i < src->num_components; i++) { 899bf215546Sopenharmony_ci nir_ssa_def *val = nir_u2u(b, nir_channel(b, src, i), dest_bit_size); 900bf215546Sopenharmony_ci val = nir_ishl(b, val, nir_imm_int(b, i * src->bit_size)); 901bf215546Sopenharmony_ci dest = nir_ior(b, dest, val); 902bf215546Sopenharmony_ci } 903bf215546Sopenharmony_ci return dest; 904bf215546Sopenharmony_ci} 905bf215546Sopenharmony_ci 906bf215546Sopenharmony_cistatic inline nir_ssa_def * 907bf215546Sopenharmony_cinir_unpack_bits(nir_builder *b, nir_ssa_def *src, unsigned dest_bit_size) 908bf215546Sopenharmony_ci{ 909bf215546Sopenharmony_ci assert(src->num_components == 1); 910bf215546Sopenharmony_ci assert(src->bit_size > dest_bit_size); 911bf215546Sopenharmony_ci const unsigned dest_num_components = src->bit_size / dest_bit_size; 912bf215546Sopenharmony_ci assert(dest_num_components <= NIR_MAX_VEC_COMPONENTS); 913bf215546Sopenharmony_ci 914bf215546Sopenharmony_ci switch (src->bit_size) { 915bf215546Sopenharmony_ci case 64: 916bf215546Sopenharmony_ci switch (dest_bit_size) { 917bf215546Sopenharmony_ci case 32: return nir_unpack_64_2x32(b, src); 918bf215546Sopenharmony_ci case 16: return nir_unpack_64_4x16(b, src); 919bf215546Sopenharmony_ci default: break; 920bf215546Sopenharmony_ci } 921bf215546Sopenharmony_ci break; 922bf215546Sopenharmony_ci 923bf215546Sopenharmony_ci case 32: 924bf215546Sopenharmony_ci if (dest_bit_size == 16) 925bf215546Sopenharmony_ci return nir_unpack_32_2x16(b, src); 926bf215546Sopenharmony_ci break; 927bf215546Sopenharmony_ci 928bf215546Sopenharmony_ci default: 929bf215546Sopenharmony_ci break; 930bf215546Sopenharmony_ci } 931bf215546Sopenharmony_ci 932bf215546Sopenharmony_ci /* If we got here, we have no dedicated unpack opcode. */ 933bf215546Sopenharmony_ci nir_ssa_def *dest_comps[NIR_MAX_VEC_COMPONENTS]; 934bf215546Sopenharmony_ci for (unsigned i = 0; i < dest_num_components; i++) { 935bf215546Sopenharmony_ci nir_ssa_def *val = nir_ushr_imm(b, src, i * dest_bit_size); 936bf215546Sopenharmony_ci dest_comps[i] = nir_u2u(b, val, dest_bit_size); 937bf215546Sopenharmony_ci } 938bf215546Sopenharmony_ci return nir_vec(b, dest_comps, dest_num_components); 939bf215546Sopenharmony_ci} 940bf215546Sopenharmony_ci 941bf215546Sopenharmony_ci/** 942bf215546Sopenharmony_ci * Treats srcs as if it's one big blob of bits and extracts the range of bits 943bf215546Sopenharmony_ci * given by 944bf215546Sopenharmony_ci * 945bf215546Sopenharmony_ci * [first_bit, first_bit + dest_num_components * dest_bit_size) 946bf215546Sopenharmony_ci * 947bf215546Sopenharmony_ci * The range can have any alignment or size as long as it's an integer number 948bf215546Sopenharmony_ci * of destination components and fits inside the concatenated sources. 949bf215546Sopenharmony_ci * 950bf215546Sopenharmony_ci * TODO: The one caveat here is that we can't handle byte alignment if 64-bit 951bf215546Sopenharmony_ci * values are involved because that would require pack/unpack to/from a vec8 952bf215546Sopenharmony_ci * which NIR currently does not support. 953bf215546Sopenharmony_ci */ 954bf215546Sopenharmony_cistatic inline nir_ssa_def * 955bf215546Sopenharmony_cinir_extract_bits(nir_builder *b, nir_ssa_def **srcs, unsigned num_srcs, 956bf215546Sopenharmony_ci unsigned first_bit, 957bf215546Sopenharmony_ci unsigned dest_num_components, unsigned dest_bit_size) 958bf215546Sopenharmony_ci{ 959bf215546Sopenharmony_ci const unsigned num_bits = dest_num_components * dest_bit_size; 960bf215546Sopenharmony_ci 961bf215546Sopenharmony_ci /* Figure out the common bit size */ 962bf215546Sopenharmony_ci unsigned common_bit_size = dest_bit_size; 963bf215546Sopenharmony_ci for (unsigned i = 0; i < num_srcs; i++) 964bf215546Sopenharmony_ci common_bit_size = MIN2(common_bit_size, srcs[i]->bit_size); 965bf215546Sopenharmony_ci if (first_bit > 0) 966bf215546Sopenharmony_ci common_bit_size = MIN2(common_bit_size, (1u << (ffs(first_bit) - 1))); 967bf215546Sopenharmony_ci 968bf215546Sopenharmony_ci /* We don't want to have to deal with 1-bit values */ 969bf215546Sopenharmony_ci assert(common_bit_size >= 8); 970bf215546Sopenharmony_ci 971bf215546Sopenharmony_ci nir_ssa_def *common_comps[NIR_MAX_VEC_COMPONENTS * sizeof(uint64_t)]; 972bf215546Sopenharmony_ci assert(num_bits / common_bit_size <= ARRAY_SIZE(common_comps)); 973bf215546Sopenharmony_ci 974bf215546Sopenharmony_ci /* First, unpack to the common bit size and select the components from the 975bf215546Sopenharmony_ci * source. 976bf215546Sopenharmony_ci */ 977bf215546Sopenharmony_ci int src_idx = -1; 978bf215546Sopenharmony_ci unsigned src_start_bit = 0; 979bf215546Sopenharmony_ci unsigned src_end_bit = 0; 980bf215546Sopenharmony_ci for (unsigned i = 0; i < num_bits / common_bit_size; i++) { 981bf215546Sopenharmony_ci const unsigned bit = first_bit + (i * common_bit_size); 982bf215546Sopenharmony_ci while (bit >= src_end_bit) { 983bf215546Sopenharmony_ci src_idx++; 984bf215546Sopenharmony_ci assert(src_idx < (int) num_srcs); 985bf215546Sopenharmony_ci src_start_bit = src_end_bit; 986bf215546Sopenharmony_ci src_end_bit += srcs[src_idx]->bit_size * 987bf215546Sopenharmony_ci srcs[src_idx]->num_components; 988bf215546Sopenharmony_ci } 989bf215546Sopenharmony_ci assert(bit >= src_start_bit); 990bf215546Sopenharmony_ci assert(bit + common_bit_size <= src_end_bit); 991bf215546Sopenharmony_ci const unsigned rel_bit = bit - src_start_bit; 992bf215546Sopenharmony_ci const unsigned src_bit_size = srcs[src_idx]->bit_size; 993bf215546Sopenharmony_ci 994bf215546Sopenharmony_ci nir_ssa_def *comp = nir_channel(b, srcs[src_idx], 995bf215546Sopenharmony_ci rel_bit / src_bit_size); 996bf215546Sopenharmony_ci if (srcs[src_idx]->bit_size > common_bit_size) { 997bf215546Sopenharmony_ci nir_ssa_def *unpacked = nir_unpack_bits(b, comp, common_bit_size); 998bf215546Sopenharmony_ci comp = nir_channel(b, unpacked, (rel_bit % src_bit_size) / 999bf215546Sopenharmony_ci common_bit_size); 1000bf215546Sopenharmony_ci } 1001bf215546Sopenharmony_ci common_comps[i] = comp; 1002bf215546Sopenharmony_ci } 1003bf215546Sopenharmony_ci 1004bf215546Sopenharmony_ci /* Now, re-pack the destination if we have to */ 1005bf215546Sopenharmony_ci if (dest_bit_size > common_bit_size) { 1006bf215546Sopenharmony_ci unsigned common_per_dest = dest_bit_size / common_bit_size; 1007bf215546Sopenharmony_ci nir_ssa_def *dest_comps[NIR_MAX_VEC_COMPONENTS]; 1008bf215546Sopenharmony_ci for (unsigned i = 0; i < dest_num_components; i++) { 1009bf215546Sopenharmony_ci nir_ssa_def *unpacked = nir_vec(b, common_comps + i * common_per_dest, 1010bf215546Sopenharmony_ci common_per_dest); 1011bf215546Sopenharmony_ci dest_comps[i] = nir_pack_bits(b, unpacked, dest_bit_size); 1012bf215546Sopenharmony_ci } 1013bf215546Sopenharmony_ci return nir_vec(b, dest_comps, dest_num_components); 1014bf215546Sopenharmony_ci } else { 1015bf215546Sopenharmony_ci assert(dest_bit_size == common_bit_size); 1016bf215546Sopenharmony_ci return nir_vec(b, common_comps, dest_num_components); 1017bf215546Sopenharmony_ci } 1018bf215546Sopenharmony_ci} 1019bf215546Sopenharmony_ci 1020bf215546Sopenharmony_cistatic inline nir_ssa_def * 1021bf215546Sopenharmony_cinir_bitcast_vector(nir_builder *b, nir_ssa_def *src, unsigned dest_bit_size) 1022bf215546Sopenharmony_ci{ 1023bf215546Sopenharmony_ci assert((src->bit_size * src->num_components) % dest_bit_size == 0); 1024bf215546Sopenharmony_ci const unsigned dest_num_components = 1025bf215546Sopenharmony_ci (src->bit_size * src->num_components) / dest_bit_size; 1026bf215546Sopenharmony_ci assert(dest_num_components <= NIR_MAX_VEC_COMPONENTS); 1027bf215546Sopenharmony_ci 1028bf215546Sopenharmony_ci return nir_extract_bits(b, &src, 1, 0, dest_num_components, dest_bit_size); 1029bf215546Sopenharmony_ci} 1030bf215546Sopenharmony_ci 1031bf215546Sopenharmony_cistatic inline nir_ssa_def * 1032bf215546Sopenharmony_cinir_trim_vector(nir_builder *b, nir_ssa_def *src, unsigned num_components) 1033bf215546Sopenharmony_ci{ 1034bf215546Sopenharmony_ci assert(src->num_components >= num_components); 1035bf215546Sopenharmony_ci if (src->num_components == num_components) 1036bf215546Sopenharmony_ci return src; 1037bf215546Sopenharmony_ci 1038bf215546Sopenharmony_ci return nir_channels(b, src, nir_component_mask(num_components)); 1039bf215546Sopenharmony_ci} 1040bf215546Sopenharmony_ci 1041bf215546Sopenharmony_ci/** 1042bf215546Sopenharmony_ci * Pad a value to N components with undefs of matching bit size. 1043bf215546Sopenharmony_ci * If the value already contains >= num_components, it is returned without change. 1044bf215546Sopenharmony_ci */ 1045bf215546Sopenharmony_cistatic inline nir_ssa_def * 1046bf215546Sopenharmony_cinir_pad_vector(nir_builder *b, nir_ssa_def *src, unsigned num_components) 1047bf215546Sopenharmony_ci{ 1048bf215546Sopenharmony_ci assert(src->num_components <= num_components); 1049bf215546Sopenharmony_ci if (src->num_components == num_components) 1050bf215546Sopenharmony_ci return src; 1051bf215546Sopenharmony_ci 1052bf215546Sopenharmony_ci nir_ssa_scalar components[NIR_MAX_VEC_COMPONENTS]; 1053bf215546Sopenharmony_ci nir_ssa_scalar undef = nir_get_ssa_scalar(nir_ssa_undef(b, 1, src->bit_size), 0); 1054bf215546Sopenharmony_ci unsigned i = 0; 1055bf215546Sopenharmony_ci for (; i < src->num_components; i++) 1056bf215546Sopenharmony_ci components[i] = nir_get_ssa_scalar(src, i); 1057bf215546Sopenharmony_ci for (; i < num_components; i++) 1058bf215546Sopenharmony_ci components[i] = undef; 1059bf215546Sopenharmony_ci 1060bf215546Sopenharmony_ci return nir_vec_scalars(b, components, num_components); 1061bf215546Sopenharmony_ci} 1062bf215546Sopenharmony_ci 1063bf215546Sopenharmony_ci/** 1064bf215546Sopenharmony_ci * Pad a value to N components with copies of the given immediate of matching 1065bf215546Sopenharmony_ci * bit size. If the value already contains >= num_components, it is returned 1066bf215546Sopenharmony_ci * without change. 1067bf215546Sopenharmony_ci */ 1068bf215546Sopenharmony_cistatic inline nir_ssa_def * 1069bf215546Sopenharmony_cinir_pad_vector_imm_int(nir_builder *b, nir_ssa_def *src, uint64_t imm_val, 1070bf215546Sopenharmony_ci unsigned num_components) 1071bf215546Sopenharmony_ci{ 1072bf215546Sopenharmony_ci assert(src->num_components <= num_components); 1073bf215546Sopenharmony_ci if (src->num_components == num_components) 1074bf215546Sopenharmony_ci return src; 1075bf215546Sopenharmony_ci 1076bf215546Sopenharmony_ci nir_ssa_scalar components[NIR_MAX_VEC_COMPONENTS]; 1077bf215546Sopenharmony_ci nir_ssa_scalar imm = nir_get_ssa_scalar(nir_imm_intN_t(b, imm_val, src->bit_size), 0); 1078bf215546Sopenharmony_ci unsigned i = 0; 1079bf215546Sopenharmony_ci for (; i < src->num_components; i++) 1080bf215546Sopenharmony_ci components[i] = nir_get_ssa_scalar(src, i); 1081bf215546Sopenharmony_ci for (; i < num_components; i++) 1082bf215546Sopenharmony_ci components[i] = imm; 1083bf215546Sopenharmony_ci 1084bf215546Sopenharmony_ci return nir_vec_scalars(b, components, num_components); 1085bf215546Sopenharmony_ci} 1086bf215546Sopenharmony_ci 1087bf215546Sopenharmony_ci/** 1088bf215546Sopenharmony_ci * Pad a value to 4 components with undefs of matching bit size. 1089bf215546Sopenharmony_ci * If the value already contains >= 4 components, it is returned without change. 1090bf215546Sopenharmony_ci */ 1091bf215546Sopenharmony_cistatic inline nir_ssa_def * 1092bf215546Sopenharmony_cinir_pad_vec4(nir_builder *b, nir_ssa_def *src) 1093bf215546Sopenharmony_ci{ 1094bf215546Sopenharmony_ci return nir_pad_vector(b, src, 4); 1095bf215546Sopenharmony_ci} 1096bf215546Sopenharmony_ci 1097bf215546Sopenharmony_ci/** 1098bf215546Sopenharmony_ci * Resizes a vector by either trimming off components or adding undef 1099bf215546Sopenharmony_ci * components, as needed. Only use this helper if it's actually what you 1100bf215546Sopenharmony_ci * need. Prefer nir_pad_vector() or nir_trim_vector() instead if you know a 1101bf215546Sopenharmony_ci * priori which direction you're resizing. 1102bf215546Sopenharmony_ci */ 1103bf215546Sopenharmony_cistatic inline nir_ssa_def * 1104bf215546Sopenharmony_cinir_resize_vector(nir_builder *b, nir_ssa_def *src, unsigned num_components) 1105bf215546Sopenharmony_ci{ 1106bf215546Sopenharmony_ci if (src->num_components < num_components) 1107bf215546Sopenharmony_ci return nir_pad_vector(b, src, num_components); 1108bf215546Sopenharmony_ci else 1109bf215546Sopenharmony_ci return nir_trim_vector(b, src, num_components); 1110bf215546Sopenharmony_ci} 1111bf215546Sopenharmony_ci 1112bf215546Sopenharmony_cinir_ssa_def * 1113bf215546Sopenharmony_cinir_ssa_for_src(nir_builder *build, nir_src src, int num_components); 1114bf215546Sopenharmony_ci 1115bf215546Sopenharmony_cinir_ssa_def * 1116bf215546Sopenharmony_cinir_ssa_for_alu_src(nir_builder *build, nir_alu_instr *instr, unsigned srcn); 1117bf215546Sopenharmony_ci 1118bf215546Sopenharmony_cistatic inline unsigned 1119bf215546Sopenharmony_cinir_get_ptr_bitsize(nir_shader *shader) 1120bf215546Sopenharmony_ci{ 1121bf215546Sopenharmony_ci if (shader->info.stage == MESA_SHADER_KERNEL) 1122bf215546Sopenharmony_ci return shader->info.cs.ptr_size; 1123bf215546Sopenharmony_ci return 32; 1124bf215546Sopenharmony_ci} 1125bf215546Sopenharmony_ci 1126bf215546Sopenharmony_cistatic inline nir_deref_instr * 1127bf215546Sopenharmony_cinir_build_deref_var(nir_builder *build, nir_variable *var) 1128bf215546Sopenharmony_ci{ 1129bf215546Sopenharmony_ci nir_deref_instr *deref = 1130bf215546Sopenharmony_ci nir_deref_instr_create(build->shader, nir_deref_type_var); 1131bf215546Sopenharmony_ci 1132bf215546Sopenharmony_ci deref->modes = (nir_variable_mode)var->data.mode; 1133bf215546Sopenharmony_ci deref->type = var->type; 1134bf215546Sopenharmony_ci deref->var = var; 1135bf215546Sopenharmony_ci 1136bf215546Sopenharmony_ci nir_ssa_dest_init(&deref->instr, &deref->dest, 1, 1137bf215546Sopenharmony_ci nir_get_ptr_bitsize(build->shader), NULL); 1138bf215546Sopenharmony_ci 1139bf215546Sopenharmony_ci nir_builder_instr_insert(build, &deref->instr); 1140bf215546Sopenharmony_ci 1141bf215546Sopenharmony_ci return deref; 1142bf215546Sopenharmony_ci} 1143bf215546Sopenharmony_ci 1144bf215546Sopenharmony_cistatic inline nir_deref_instr * 1145bf215546Sopenharmony_cinir_build_deref_array(nir_builder *build, nir_deref_instr *parent, 1146bf215546Sopenharmony_ci nir_ssa_def *index) 1147bf215546Sopenharmony_ci{ 1148bf215546Sopenharmony_ci assert(glsl_type_is_array(parent->type) || 1149bf215546Sopenharmony_ci glsl_type_is_matrix(parent->type) || 1150bf215546Sopenharmony_ci glsl_type_is_vector(parent->type)); 1151bf215546Sopenharmony_ci 1152bf215546Sopenharmony_ci assert(index->bit_size == parent->dest.ssa.bit_size); 1153bf215546Sopenharmony_ci 1154bf215546Sopenharmony_ci nir_deref_instr *deref = 1155bf215546Sopenharmony_ci nir_deref_instr_create(build->shader, nir_deref_type_array); 1156bf215546Sopenharmony_ci 1157bf215546Sopenharmony_ci deref->modes = parent->modes; 1158bf215546Sopenharmony_ci deref->type = glsl_get_array_element(parent->type); 1159bf215546Sopenharmony_ci deref->parent = nir_src_for_ssa(&parent->dest.ssa); 1160bf215546Sopenharmony_ci deref->arr.index = nir_src_for_ssa(index); 1161bf215546Sopenharmony_ci 1162bf215546Sopenharmony_ci nir_ssa_dest_init(&deref->instr, &deref->dest, 1163bf215546Sopenharmony_ci parent->dest.ssa.num_components, 1164bf215546Sopenharmony_ci parent->dest.ssa.bit_size, NULL); 1165bf215546Sopenharmony_ci 1166bf215546Sopenharmony_ci nir_builder_instr_insert(build, &deref->instr); 1167bf215546Sopenharmony_ci 1168bf215546Sopenharmony_ci return deref; 1169bf215546Sopenharmony_ci} 1170bf215546Sopenharmony_ci 1171bf215546Sopenharmony_cistatic inline nir_deref_instr * 1172bf215546Sopenharmony_cinir_build_deref_array_imm(nir_builder *build, nir_deref_instr *parent, 1173bf215546Sopenharmony_ci int64_t index) 1174bf215546Sopenharmony_ci{ 1175bf215546Sopenharmony_ci assert(parent->dest.is_ssa); 1176bf215546Sopenharmony_ci nir_ssa_def *idx_ssa = nir_imm_intN_t(build, index, 1177bf215546Sopenharmony_ci parent->dest.ssa.bit_size); 1178bf215546Sopenharmony_ci 1179bf215546Sopenharmony_ci return nir_build_deref_array(build, parent, idx_ssa); 1180bf215546Sopenharmony_ci} 1181bf215546Sopenharmony_ci 1182bf215546Sopenharmony_cistatic inline nir_deref_instr * 1183bf215546Sopenharmony_cinir_build_deref_ptr_as_array(nir_builder *build, nir_deref_instr *parent, 1184bf215546Sopenharmony_ci nir_ssa_def *index) 1185bf215546Sopenharmony_ci{ 1186bf215546Sopenharmony_ci assert(parent->deref_type == nir_deref_type_array || 1187bf215546Sopenharmony_ci parent->deref_type == nir_deref_type_ptr_as_array || 1188bf215546Sopenharmony_ci parent->deref_type == nir_deref_type_cast); 1189bf215546Sopenharmony_ci 1190bf215546Sopenharmony_ci assert(index->bit_size == parent->dest.ssa.bit_size); 1191bf215546Sopenharmony_ci 1192bf215546Sopenharmony_ci nir_deref_instr *deref = 1193bf215546Sopenharmony_ci nir_deref_instr_create(build->shader, nir_deref_type_ptr_as_array); 1194bf215546Sopenharmony_ci 1195bf215546Sopenharmony_ci deref->modes = parent->modes; 1196bf215546Sopenharmony_ci deref->type = parent->type; 1197bf215546Sopenharmony_ci deref->parent = nir_src_for_ssa(&parent->dest.ssa); 1198bf215546Sopenharmony_ci deref->arr.index = nir_src_for_ssa(index); 1199bf215546Sopenharmony_ci 1200bf215546Sopenharmony_ci nir_ssa_dest_init(&deref->instr, &deref->dest, 1201bf215546Sopenharmony_ci parent->dest.ssa.num_components, 1202bf215546Sopenharmony_ci parent->dest.ssa.bit_size, NULL); 1203bf215546Sopenharmony_ci 1204bf215546Sopenharmony_ci nir_builder_instr_insert(build, &deref->instr); 1205bf215546Sopenharmony_ci 1206bf215546Sopenharmony_ci return deref; 1207bf215546Sopenharmony_ci} 1208bf215546Sopenharmony_ci 1209bf215546Sopenharmony_cistatic inline nir_deref_instr * 1210bf215546Sopenharmony_cinir_build_deref_array_wildcard(nir_builder *build, nir_deref_instr *parent) 1211bf215546Sopenharmony_ci{ 1212bf215546Sopenharmony_ci assert(glsl_type_is_array(parent->type) || 1213bf215546Sopenharmony_ci glsl_type_is_matrix(parent->type)); 1214bf215546Sopenharmony_ci 1215bf215546Sopenharmony_ci nir_deref_instr *deref = 1216bf215546Sopenharmony_ci nir_deref_instr_create(build->shader, nir_deref_type_array_wildcard); 1217bf215546Sopenharmony_ci 1218bf215546Sopenharmony_ci deref->modes = parent->modes; 1219bf215546Sopenharmony_ci deref->type = glsl_get_array_element(parent->type); 1220bf215546Sopenharmony_ci deref->parent = nir_src_for_ssa(&parent->dest.ssa); 1221bf215546Sopenharmony_ci 1222bf215546Sopenharmony_ci nir_ssa_dest_init(&deref->instr, &deref->dest, 1223bf215546Sopenharmony_ci parent->dest.ssa.num_components, 1224bf215546Sopenharmony_ci parent->dest.ssa.bit_size, NULL); 1225bf215546Sopenharmony_ci 1226bf215546Sopenharmony_ci nir_builder_instr_insert(build, &deref->instr); 1227bf215546Sopenharmony_ci 1228bf215546Sopenharmony_ci return deref; 1229bf215546Sopenharmony_ci} 1230bf215546Sopenharmony_ci 1231bf215546Sopenharmony_cistatic inline nir_deref_instr * 1232bf215546Sopenharmony_cinir_build_deref_struct(nir_builder *build, nir_deref_instr *parent, 1233bf215546Sopenharmony_ci unsigned index) 1234bf215546Sopenharmony_ci{ 1235bf215546Sopenharmony_ci assert(glsl_type_is_struct_or_ifc(parent->type)); 1236bf215546Sopenharmony_ci 1237bf215546Sopenharmony_ci nir_deref_instr *deref = 1238bf215546Sopenharmony_ci nir_deref_instr_create(build->shader, nir_deref_type_struct); 1239bf215546Sopenharmony_ci 1240bf215546Sopenharmony_ci deref->modes = parent->modes; 1241bf215546Sopenharmony_ci deref->type = glsl_get_struct_field(parent->type, index); 1242bf215546Sopenharmony_ci deref->parent = nir_src_for_ssa(&parent->dest.ssa); 1243bf215546Sopenharmony_ci deref->strct.index = index; 1244bf215546Sopenharmony_ci 1245bf215546Sopenharmony_ci nir_ssa_dest_init(&deref->instr, &deref->dest, 1246bf215546Sopenharmony_ci parent->dest.ssa.num_components, 1247bf215546Sopenharmony_ci parent->dest.ssa.bit_size, NULL); 1248bf215546Sopenharmony_ci 1249bf215546Sopenharmony_ci nir_builder_instr_insert(build, &deref->instr); 1250bf215546Sopenharmony_ci 1251bf215546Sopenharmony_ci return deref; 1252bf215546Sopenharmony_ci} 1253bf215546Sopenharmony_ci 1254bf215546Sopenharmony_cistatic inline nir_deref_instr * 1255bf215546Sopenharmony_cinir_build_deref_cast(nir_builder *build, nir_ssa_def *parent, 1256bf215546Sopenharmony_ci nir_variable_mode modes, const struct glsl_type *type, 1257bf215546Sopenharmony_ci unsigned ptr_stride) 1258bf215546Sopenharmony_ci{ 1259bf215546Sopenharmony_ci nir_deref_instr *deref = 1260bf215546Sopenharmony_ci nir_deref_instr_create(build->shader, nir_deref_type_cast); 1261bf215546Sopenharmony_ci 1262bf215546Sopenharmony_ci deref->modes = modes; 1263bf215546Sopenharmony_ci deref->type = type; 1264bf215546Sopenharmony_ci deref->parent = nir_src_for_ssa(parent); 1265bf215546Sopenharmony_ci deref->cast.ptr_stride = ptr_stride; 1266bf215546Sopenharmony_ci 1267bf215546Sopenharmony_ci nir_ssa_dest_init(&deref->instr, &deref->dest, 1268bf215546Sopenharmony_ci parent->num_components, parent->bit_size, NULL); 1269bf215546Sopenharmony_ci 1270bf215546Sopenharmony_ci nir_builder_instr_insert(build, &deref->instr); 1271bf215546Sopenharmony_ci 1272bf215546Sopenharmony_ci return deref; 1273bf215546Sopenharmony_ci} 1274bf215546Sopenharmony_ci 1275bf215546Sopenharmony_cistatic inline nir_deref_instr * 1276bf215546Sopenharmony_cinir_alignment_deref_cast(nir_builder *build, nir_deref_instr *parent, 1277bf215546Sopenharmony_ci uint32_t align_mul, uint32_t align_offset) 1278bf215546Sopenharmony_ci{ 1279bf215546Sopenharmony_ci nir_deref_instr *deref = 1280bf215546Sopenharmony_ci nir_deref_instr_create(build->shader, nir_deref_type_cast); 1281bf215546Sopenharmony_ci 1282bf215546Sopenharmony_ci deref->modes = parent->modes; 1283bf215546Sopenharmony_ci deref->type = parent->type; 1284bf215546Sopenharmony_ci deref->parent = nir_src_for_ssa(&parent->dest.ssa); 1285bf215546Sopenharmony_ci deref->cast.ptr_stride = nir_deref_instr_array_stride(deref); 1286bf215546Sopenharmony_ci deref->cast.align_mul = align_mul; 1287bf215546Sopenharmony_ci deref->cast.align_offset = align_offset; 1288bf215546Sopenharmony_ci 1289bf215546Sopenharmony_ci nir_ssa_dest_init(&deref->instr, &deref->dest, 1290bf215546Sopenharmony_ci parent->dest.ssa.num_components, 1291bf215546Sopenharmony_ci parent->dest.ssa.bit_size, NULL); 1292bf215546Sopenharmony_ci 1293bf215546Sopenharmony_ci nir_builder_instr_insert(build, &deref->instr); 1294bf215546Sopenharmony_ci 1295bf215546Sopenharmony_ci return deref; 1296bf215546Sopenharmony_ci} 1297bf215546Sopenharmony_ci 1298bf215546Sopenharmony_ci/** Returns a deref that follows another but starting from the given parent 1299bf215546Sopenharmony_ci * 1300bf215546Sopenharmony_ci * The new deref will be the same type and take the same array or struct index 1301bf215546Sopenharmony_ci * as the leader deref but it may have a different parent. This is very 1302bf215546Sopenharmony_ci * useful for walking deref paths. 1303bf215546Sopenharmony_ci */ 1304bf215546Sopenharmony_cistatic inline nir_deref_instr * 1305bf215546Sopenharmony_cinir_build_deref_follower(nir_builder *b, nir_deref_instr *parent, 1306bf215546Sopenharmony_ci nir_deref_instr *leader) 1307bf215546Sopenharmony_ci{ 1308bf215546Sopenharmony_ci /* If the derefs would have the same parent, don't make a new one */ 1309bf215546Sopenharmony_ci assert(leader->parent.is_ssa); 1310bf215546Sopenharmony_ci if (leader->parent.ssa == &parent->dest.ssa) 1311bf215546Sopenharmony_ci return leader; 1312bf215546Sopenharmony_ci 1313bf215546Sopenharmony_ci UNUSED nir_deref_instr *leader_parent = nir_src_as_deref(leader->parent); 1314bf215546Sopenharmony_ci 1315bf215546Sopenharmony_ci switch (leader->deref_type) { 1316bf215546Sopenharmony_ci case nir_deref_type_var: 1317bf215546Sopenharmony_ci unreachable("A var dereference cannot have a parent"); 1318bf215546Sopenharmony_ci break; 1319bf215546Sopenharmony_ci 1320bf215546Sopenharmony_ci case nir_deref_type_array: 1321bf215546Sopenharmony_ci case nir_deref_type_array_wildcard: 1322bf215546Sopenharmony_ci assert(glsl_type_is_matrix(parent->type) || 1323bf215546Sopenharmony_ci glsl_type_is_array(parent->type) || 1324bf215546Sopenharmony_ci (leader->deref_type == nir_deref_type_array && 1325bf215546Sopenharmony_ci glsl_type_is_vector(parent->type))); 1326bf215546Sopenharmony_ci assert(glsl_get_length(parent->type) == 1327bf215546Sopenharmony_ci glsl_get_length(leader_parent->type)); 1328bf215546Sopenharmony_ci 1329bf215546Sopenharmony_ci if (leader->deref_type == nir_deref_type_array) { 1330bf215546Sopenharmony_ci assert(leader->arr.index.is_ssa); 1331bf215546Sopenharmony_ci nir_ssa_def *index = nir_i2i(b, leader->arr.index.ssa, 1332bf215546Sopenharmony_ci parent->dest.ssa.bit_size); 1333bf215546Sopenharmony_ci return nir_build_deref_array(b, parent, index); 1334bf215546Sopenharmony_ci } else { 1335bf215546Sopenharmony_ci return nir_build_deref_array_wildcard(b, parent); 1336bf215546Sopenharmony_ci } 1337bf215546Sopenharmony_ci 1338bf215546Sopenharmony_ci case nir_deref_type_struct: 1339bf215546Sopenharmony_ci assert(glsl_type_is_struct_or_ifc(parent->type)); 1340bf215546Sopenharmony_ci assert(glsl_get_length(parent->type) == 1341bf215546Sopenharmony_ci glsl_get_length(leader_parent->type)); 1342bf215546Sopenharmony_ci 1343bf215546Sopenharmony_ci return nir_build_deref_struct(b, parent, leader->strct.index); 1344bf215546Sopenharmony_ci 1345bf215546Sopenharmony_ci default: 1346bf215546Sopenharmony_ci unreachable("Invalid deref instruction type"); 1347bf215546Sopenharmony_ci } 1348bf215546Sopenharmony_ci} 1349bf215546Sopenharmony_ci 1350bf215546Sopenharmony_cistatic inline nir_ssa_def * 1351bf215546Sopenharmony_cinir_load_reg(nir_builder *build, nir_register *reg) 1352bf215546Sopenharmony_ci{ 1353bf215546Sopenharmony_ci return nir_ssa_for_src(build, nir_src_for_reg(reg), reg->num_components); 1354bf215546Sopenharmony_ci} 1355bf215546Sopenharmony_ci 1356bf215546Sopenharmony_cistatic inline void 1357bf215546Sopenharmony_cinir_store_reg(nir_builder *build, nir_register *reg, 1358bf215546Sopenharmony_ci nir_ssa_def *def, nir_component_mask_t write_mask) 1359bf215546Sopenharmony_ci{ 1360bf215546Sopenharmony_ci assert(reg->num_components == def->num_components); 1361bf215546Sopenharmony_ci assert(reg->bit_size == def->bit_size); 1362bf215546Sopenharmony_ci 1363bf215546Sopenharmony_ci nir_alu_instr *mov = nir_alu_instr_create(build->shader, nir_op_mov); 1364bf215546Sopenharmony_ci mov->src[0].src = nir_src_for_ssa(def); 1365bf215546Sopenharmony_ci mov->dest.dest = nir_dest_for_reg(reg); 1366bf215546Sopenharmony_ci mov->dest.write_mask = write_mask & BITFIELD_MASK(reg->num_components); 1367bf215546Sopenharmony_ci nir_builder_instr_insert(build, &mov->instr); 1368bf215546Sopenharmony_ci} 1369bf215546Sopenharmony_ci 1370bf215546Sopenharmony_cistatic inline nir_ssa_def * 1371bf215546Sopenharmony_cinir_load_deref_with_access(nir_builder *build, nir_deref_instr *deref, 1372bf215546Sopenharmony_ci enum gl_access_qualifier access) 1373bf215546Sopenharmony_ci{ 1374bf215546Sopenharmony_ci return nir_build_load_deref(build, glsl_get_vector_elements(deref->type), 1375bf215546Sopenharmony_ci glsl_get_bit_size(deref->type), &deref->dest.ssa, 1376bf215546Sopenharmony_ci access); 1377bf215546Sopenharmony_ci} 1378bf215546Sopenharmony_ci 1379bf215546Sopenharmony_ci#undef nir_load_deref 1380bf215546Sopenharmony_cistatic inline nir_ssa_def * 1381bf215546Sopenharmony_cinir_load_deref(nir_builder *build, nir_deref_instr *deref) 1382bf215546Sopenharmony_ci{ 1383bf215546Sopenharmony_ci return nir_load_deref_with_access(build, deref, (enum gl_access_qualifier)0); 1384bf215546Sopenharmony_ci} 1385bf215546Sopenharmony_ci 1386bf215546Sopenharmony_cistatic inline void 1387bf215546Sopenharmony_cinir_store_deref_with_access(nir_builder *build, nir_deref_instr *deref, 1388bf215546Sopenharmony_ci nir_ssa_def *value, unsigned writemask, 1389bf215546Sopenharmony_ci enum gl_access_qualifier access) 1390bf215546Sopenharmony_ci{ 1391bf215546Sopenharmony_ci writemask &= (1u << value->num_components) - 1u; 1392bf215546Sopenharmony_ci nir_build_store_deref(build, &deref->dest.ssa, value, writemask, access); 1393bf215546Sopenharmony_ci} 1394bf215546Sopenharmony_ci 1395bf215546Sopenharmony_ci#undef nir_store_deref 1396bf215546Sopenharmony_cistatic inline void 1397bf215546Sopenharmony_cinir_store_deref(nir_builder *build, nir_deref_instr *deref, 1398bf215546Sopenharmony_ci nir_ssa_def *value, unsigned writemask) 1399bf215546Sopenharmony_ci{ 1400bf215546Sopenharmony_ci nir_store_deref_with_access(build, deref, value, writemask, 1401bf215546Sopenharmony_ci (enum gl_access_qualifier)0); 1402bf215546Sopenharmony_ci} 1403bf215546Sopenharmony_ci 1404bf215546Sopenharmony_cistatic inline void 1405bf215546Sopenharmony_cinir_copy_deref_with_access(nir_builder *build, nir_deref_instr *dest, 1406bf215546Sopenharmony_ci nir_deref_instr *src, 1407bf215546Sopenharmony_ci enum gl_access_qualifier dest_access, 1408bf215546Sopenharmony_ci enum gl_access_qualifier src_access) 1409bf215546Sopenharmony_ci{ 1410bf215546Sopenharmony_ci nir_build_copy_deref(build, &dest->dest.ssa, &src->dest.ssa, dest_access, src_access); 1411bf215546Sopenharmony_ci} 1412bf215546Sopenharmony_ci 1413bf215546Sopenharmony_ci#undef nir_copy_deref 1414bf215546Sopenharmony_cistatic inline void 1415bf215546Sopenharmony_cinir_copy_deref(nir_builder *build, nir_deref_instr *dest, nir_deref_instr *src) 1416bf215546Sopenharmony_ci{ 1417bf215546Sopenharmony_ci nir_copy_deref_with_access(build, dest, src, 1418bf215546Sopenharmony_ci (enum gl_access_qualifier) 0, 1419bf215546Sopenharmony_ci (enum gl_access_qualifier) 0); 1420bf215546Sopenharmony_ci} 1421bf215546Sopenharmony_ci 1422bf215546Sopenharmony_cistatic inline void 1423bf215546Sopenharmony_cinir_memcpy_deref_with_access(nir_builder *build, nir_deref_instr *dest, 1424bf215546Sopenharmony_ci nir_deref_instr *src, nir_ssa_def *size, 1425bf215546Sopenharmony_ci enum gl_access_qualifier dest_access, 1426bf215546Sopenharmony_ci enum gl_access_qualifier src_access) 1427bf215546Sopenharmony_ci{ 1428bf215546Sopenharmony_ci nir_build_memcpy_deref(build, &dest->dest.ssa, &src->dest.ssa, 1429bf215546Sopenharmony_ci size, dest_access, src_access); 1430bf215546Sopenharmony_ci} 1431bf215546Sopenharmony_ci 1432bf215546Sopenharmony_ci#undef nir_memcpy_deref 1433bf215546Sopenharmony_cistatic inline void 1434bf215546Sopenharmony_cinir_memcpy_deref(nir_builder *build, nir_deref_instr *dest, 1435bf215546Sopenharmony_ci nir_deref_instr *src, nir_ssa_def *size) 1436bf215546Sopenharmony_ci{ 1437bf215546Sopenharmony_ci nir_memcpy_deref_with_access(build, dest, src, size, 1438bf215546Sopenharmony_ci (enum gl_access_qualifier)0, 1439bf215546Sopenharmony_ci (enum gl_access_qualifier)0); 1440bf215546Sopenharmony_ci} 1441bf215546Sopenharmony_ci 1442bf215546Sopenharmony_cistatic inline nir_ssa_def * 1443bf215546Sopenharmony_cinir_load_var(nir_builder *build, nir_variable *var) 1444bf215546Sopenharmony_ci{ 1445bf215546Sopenharmony_ci return nir_load_deref(build, nir_build_deref_var(build, var)); 1446bf215546Sopenharmony_ci} 1447bf215546Sopenharmony_ci 1448bf215546Sopenharmony_cistatic inline void 1449bf215546Sopenharmony_cinir_store_var(nir_builder *build, nir_variable *var, nir_ssa_def *value, 1450bf215546Sopenharmony_ci unsigned writemask) 1451bf215546Sopenharmony_ci{ 1452bf215546Sopenharmony_ci nir_store_deref(build, nir_build_deref_var(build, var), value, writemask); 1453bf215546Sopenharmony_ci} 1454bf215546Sopenharmony_ci 1455bf215546Sopenharmony_cistatic inline void 1456bf215546Sopenharmony_cinir_copy_var(nir_builder *build, nir_variable *dest, nir_variable *src) 1457bf215546Sopenharmony_ci{ 1458bf215546Sopenharmony_ci nir_copy_deref(build, nir_build_deref_var(build, dest), 1459bf215546Sopenharmony_ci nir_build_deref_var(build, src)); 1460bf215546Sopenharmony_ci} 1461bf215546Sopenharmony_ci 1462bf215546Sopenharmony_cistatic inline nir_ssa_def * 1463bf215546Sopenharmony_cinir_load_array_var(nir_builder *build, nir_variable *var, nir_ssa_def *index) 1464bf215546Sopenharmony_ci{ 1465bf215546Sopenharmony_ci nir_deref_instr *deref = 1466bf215546Sopenharmony_ci nir_build_deref_array(build, nir_build_deref_var(build, var), index); 1467bf215546Sopenharmony_ci return nir_load_deref(build, deref); 1468bf215546Sopenharmony_ci} 1469bf215546Sopenharmony_ci 1470bf215546Sopenharmony_cistatic inline nir_ssa_def * 1471bf215546Sopenharmony_cinir_load_array_var_imm(nir_builder *build, nir_variable *var, int64_t index) 1472bf215546Sopenharmony_ci{ 1473bf215546Sopenharmony_ci nir_deref_instr *deref = 1474bf215546Sopenharmony_ci nir_build_deref_array_imm(build, nir_build_deref_var(build, var), index); 1475bf215546Sopenharmony_ci return nir_load_deref(build, deref); 1476bf215546Sopenharmony_ci} 1477bf215546Sopenharmony_ci 1478bf215546Sopenharmony_cistatic inline void 1479bf215546Sopenharmony_cinir_store_array_var(nir_builder *build, nir_variable *var, nir_ssa_def *index, 1480bf215546Sopenharmony_ci nir_ssa_def *value, unsigned writemask) 1481bf215546Sopenharmony_ci{ 1482bf215546Sopenharmony_ci nir_deref_instr *deref = 1483bf215546Sopenharmony_ci nir_build_deref_array(build, nir_build_deref_var(build, var), index); 1484bf215546Sopenharmony_ci nir_store_deref(build, deref, value, writemask); 1485bf215546Sopenharmony_ci} 1486bf215546Sopenharmony_ci 1487bf215546Sopenharmony_cistatic inline void 1488bf215546Sopenharmony_cinir_store_array_var_imm(nir_builder *build, nir_variable *var, int64_t index, 1489bf215546Sopenharmony_ci nir_ssa_def *value, unsigned writemask) 1490bf215546Sopenharmony_ci{ 1491bf215546Sopenharmony_ci nir_deref_instr *deref = 1492bf215546Sopenharmony_ci nir_build_deref_array_imm(build, nir_build_deref_var(build, var), index); 1493bf215546Sopenharmony_ci nir_store_deref(build, deref, value, writemask); 1494bf215546Sopenharmony_ci} 1495bf215546Sopenharmony_ci 1496bf215546Sopenharmony_ci#undef nir_load_global 1497bf215546Sopenharmony_cistatic inline nir_ssa_def * 1498bf215546Sopenharmony_cinir_load_global(nir_builder *build, nir_ssa_def *addr, unsigned align, 1499bf215546Sopenharmony_ci unsigned num_components, unsigned bit_size) 1500bf215546Sopenharmony_ci{ 1501bf215546Sopenharmony_ci nir_intrinsic_instr *load = 1502bf215546Sopenharmony_ci nir_intrinsic_instr_create(build->shader, nir_intrinsic_load_global); 1503bf215546Sopenharmony_ci load->num_components = num_components; 1504bf215546Sopenharmony_ci load->src[0] = nir_src_for_ssa(addr); 1505bf215546Sopenharmony_ci nir_intrinsic_set_align(load, align, 0); 1506bf215546Sopenharmony_ci nir_ssa_dest_init(&load->instr, &load->dest, 1507bf215546Sopenharmony_ci num_components, bit_size, NULL); 1508bf215546Sopenharmony_ci nir_builder_instr_insert(build, &load->instr); 1509bf215546Sopenharmony_ci return &load->dest.ssa; 1510bf215546Sopenharmony_ci} 1511bf215546Sopenharmony_ci 1512bf215546Sopenharmony_ci#undef nir_store_global 1513bf215546Sopenharmony_cistatic inline void 1514bf215546Sopenharmony_cinir_store_global(nir_builder *build, nir_ssa_def *addr, unsigned align, 1515bf215546Sopenharmony_ci nir_ssa_def *value, nir_component_mask_t write_mask) 1516bf215546Sopenharmony_ci{ 1517bf215546Sopenharmony_ci nir_intrinsic_instr *store = 1518bf215546Sopenharmony_ci nir_intrinsic_instr_create(build->shader, nir_intrinsic_store_global); 1519bf215546Sopenharmony_ci store->num_components = value->num_components; 1520bf215546Sopenharmony_ci store->src[0] = nir_src_for_ssa(value); 1521bf215546Sopenharmony_ci store->src[1] = nir_src_for_ssa(addr); 1522bf215546Sopenharmony_ci nir_intrinsic_set_write_mask(store, 1523bf215546Sopenharmony_ci write_mask & BITFIELD_MASK(value->num_components)); 1524bf215546Sopenharmony_ci nir_intrinsic_set_align(store, align, 0); 1525bf215546Sopenharmony_ci nir_builder_instr_insert(build, &store->instr); 1526bf215546Sopenharmony_ci} 1527bf215546Sopenharmony_ci 1528bf215546Sopenharmony_ci#undef nir_load_global_constant 1529bf215546Sopenharmony_cistatic inline nir_ssa_def * 1530bf215546Sopenharmony_cinir_load_global_constant(nir_builder *build, nir_ssa_def *addr, unsigned align, 1531bf215546Sopenharmony_ci unsigned num_components, unsigned bit_size) 1532bf215546Sopenharmony_ci{ 1533bf215546Sopenharmony_ci nir_intrinsic_instr *load = 1534bf215546Sopenharmony_ci nir_intrinsic_instr_create(build->shader, nir_intrinsic_load_global_constant); 1535bf215546Sopenharmony_ci load->num_components = num_components; 1536bf215546Sopenharmony_ci load->src[0] = nir_src_for_ssa(addr); 1537bf215546Sopenharmony_ci nir_intrinsic_set_align(load, align, 0); 1538bf215546Sopenharmony_ci nir_ssa_dest_init(&load->instr, &load->dest, 1539bf215546Sopenharmony_ci num_components, bit_size, NULL); 1540bf215546Sopenharmony_ci nir_builder_instr_insert(build, &load->instr); 1541bf215546Sopenharmony_ci return &load->dest.ssa; 1542bf215546Sopenharmony_ci} 1543bf215546Sopenharmony_ci 1544bf215546Sopenharmony_ci#undef nir_load_param 1545bf215546Sopenharmony_cistatic inline nir_ssa_def * 1546bf215546Sopenharmony_cinir_load_param(nir_builder *build, uint32_t param_idx) 1547bf215546Sopenharmony_ci{ 1548bf215546Sopenharmony_ci assert(param_idx < build->impl->function->num_params); 1549bf215546Sopenharmony_ci nir_parameter *param = &build->impl->function->params[param_idx]; 1550bf215546Sopenharmony_ci return nir_build_load_param(build, param->num_components, param->bit_size, param_idx); 1551bf215546Sopenharmony_ci} 1552bf215546Sopenharmony_ci 1553bf215546Sopenharmony_ci/* calculate a `(1 << value) - 1` in ssa without overflows */ 1554bf215546Sopenharmony_cistatic inline nir_ssa_def * 1555bf215546Sopenharmony_cinir_mask(nir_builder *b, nir_ssa_def *bits, unsigned dst_bit_size) 1556bf215546Sopenharmony_ci{ 1557bf215546Sopenharmony_ci return nir_ushr(b, nir_imm_intN_t(b, -1, dst_bit_size), 1558bf215546Sopenharmony_ci nir_isub_imm(b, dst_bit_size, nir_u2u32(b, bits))); 1559bf215546Sopenharmony_ci} 1560bf215546Sopenharmony_ci 1561bf215546Sopenharmony_cistatic inline nir_ssa_def * 1562bf215546Sopenharmony_cinir_f2b(nir_builder *build, nir_ssa_def *f) 1563bf215546Sopenharmony_ci{ 1564bf215546Sopenharmony_ci return nir_f2b1(build, f); 1565bf215546Sopenharmony_ci} 1566bf215546Sopenharmony_ci 1567bf215546Sopenharmony_cistatic inline nir_ssa_def * 1568bf215546Sopenharmony_cinir_i2b(nir_builder *build, nir_ssa_def *i) 1569bf215546Sopenharmony_ci{ 1570bf215546Sopenharmony_ci return nir_i2b1(build, i); 1571bf215546Sopenharmony_ci} 1572bf215546Sopenharmony_ci 1573bf215546Sopenharmony_cistatic inline nir_ssa_def * 1574bf215546Sopenharmony_cinir_b2f(nir_builder *build, nir_ssa_def *b, uint32_t bit_size) 1575bf215546Sopenharmony_ci{ 1576bf215546Sopenharmony_ci switch (bit_size) { 1577bf215546Sopenharmony_ci case 64: return nir_b2f64(build, b); 1578bf215546Sopenharmony_ci case 32: return nir_b2f32(build, b); 1579bf215546Sopenharmony_ci case 16: return nir_b2f16(build, b); 1580bf215546Sopenharmony_ci default: 1581bf215546Sopenharmony_ci unreachable("Invalid bit-size"); 1582bf215546Sopenharmony_ci }; 1583bf215546Sopenharmony_ci} 1584bf215546Sopenharmony_ci 1585bf215546Sopenharmony_cistatic inline nir_ssa_def * 1586bf215546Sopenharmony_cinir_b2i(nir_builder *build, nir_ssa_def *b, uint32_t bit_size) 1587bf215546Sopenharmony_ci{ 1588bf215546Sopenharmony_ci switch (bit_size) { 1589bf215546Sopenharmony_ci case 64: return nir_b2i64(build, b); 1590bf215546Sopenharmony_ci case 32: return nir_b2i32(build, b); 1591bf215546Sopenharmony_ci case 16: return nir_b2i16(build, b); 1592bf215546Sopenharmony_ci case 8: return nir_b2i8(build, b); 1593bf215546Sopenharmony_ci default: 1594bf215546Sopenharmony_ci unreachable("Invalid bit-size"); 1595bf215546Sopenharmony_ci }; 1596bf215546Sopenharmony_ci} 1597bf215546Sopenharmony_cistatic inline nir_ssa_def * 1598bf215546Sopenharmony_cinir_load_barycentric(nir_builder *build, nir_intrinsic_op op, 1599bf215546Sopenharmony_ci unsigned interp_mode) 1600bf215546Sopenharmony_ci{ 1601bf215546Sopenharmony_ci unsigned num_components = op == nir_intrinsic_load_barycentric_model ? 3 : 2; 1602bf215546Sopenharmony_ci nir_intrinsic_instr *bary = nir_intrinsic_instr_create(build->shader, op); 1603bf215546Sopenharmony_ci nir_ssa_dest_init(&bary->instr, &bary->dest, num_components, 32, NULL); 1604bf215546Sopenharmony_ci nir_intrinsic_set_interp_mode(bary, interp_mode); 1605bf215546Sopenharmony_ci nir_builder_instr_insert(build, &bary->instr); 1606bf215546Sopenharmony_ci return &bary->dest.ssa; 1607bf215546Sopenharmony_ci} 1608bf215546Sopenharmony_ci 1609bf215546Sopenharmony_cistatic inline void 1610bf215546Sopenharmony_cinir_jump(nir_builder *build, nir_jump_type jump_type) 1611bf215546Sopenharmony_ci{ 1612bf215546Sopenharmony_ci assert(jump_type != nir_jump_goto && jump_type != nir_jump_goto_if); 1613bf215546Sopenharmony_ci nir_jump_instr *jump = nir_jump_instr_create(build->shader, jump_type); 1614bf215546Sopenharmony_ci nir_builder_instr_insert(build, &jump->instr); 1615bf215546Sopenharmony_ci} 1616bf215546Sopenharmony_ci 1617bf215546Sopenharmony_cistatic inline void 1618bf215546Sopenharmony_cinir_goto(nir_builder *build, struct nir_block *target) 1619bf215546Sopenharmony_ci{ 1620bf215546Sopenharmony_ci assert(!build->impl->structured); 1621bf215546Sopenharmony_ci nir_jump_instr *jump = nir_jump_instr_create(build->shader, nir_jump_goto); 1622bf215546Sopenharmony_ci jump->target = target; 1623bf215546Sopenharmony_ci nir_builder_instr_insert(build, &jump->instr); 1624bf215546Sopenharmony_ci} 1625bf215546Sopenharmony_ci 1626bf215546Sopenharmony_cistatic inline void 1627bf215546Sopenharmony_cinir_goto_if(nir_builder *build, struct nir_block *target, nir_src cond, 1628bf215546Sopenharmony_ci struct nir_block *else_target) 1629bf215546Sopenharmony_ci{ 1630bf215546Sopenharmony_ci assert(!build->impl->structured); 1631bf215546Sopenharmony_ci nir_jump_instr *jump = nir_jump_instr_create(build->shader, nir_jump_goto_if); 1632bf215546Sopenharmony_ci jump->condition = cond; 1633bf215546Sopenharmony_ci jump->target = target; 1634bf215546Sopenharmony_ci jump->else_target = else_target; 1635bf215546Sopenharmony_ci nir_builder_instr_insert(build, &jump->instr); 1636bf215546Sopenharmony_ci} 1637bf215546Sopenharmony_ci 1638bf215546Sopenharmony_cinir_ssa_def * 1639bf215546Sopenharmony_cinir_compare_func(nir_builder *b, enum compare_func func, 1640bf215546Sopenharmony_ci nir_ssa_def *src0, nir_ssa_def *src1); 1641bf215546Sopenharmony_ci 1642bf215546Sopenharmony_cistatic inline void 1643bf215546Sopenharmony_cinir_scoped_memory_barrier(nir_builder *b, 1644bf215546Sopenharmony_ci nir_scope scope, 1645bf215546Sopenharmony_ci nir_memory_semantics semantics, 1646bf215546Sopenharmony_ci nir_variable_mode modes) 1647bf215546Sopenharmony_ci{ 1648bf215546Sopenharmony_ci nir_scoped_barrier(b, NIR_SCOPE_NONE, scope, semantics, modes); 1649bf215546Sopenharmony_ci} 1650bf215546Sopenharmony_ci 1651bf215546Sopenharmony_cinir_ssa_def * 1652bf215546Sopenharmony_cinir_type_convert(nir_builder *b, 1653bf215546Sopenharmony_ci nir_ssa_def *src, 1654bf215546Sopenharmony_ci nir_alu_type src_type, 1655bf215546Sopenharmony_ci nir_alu_type dest_type); 1656bf215546Sopenharmony_ci 1657bf215546Sopenharmony_ci 1658bf215546Sopenharmony_cistatic inline nir_ssa_def * 1659bf215546Sopenharmony_cinir_convert_to_bit_size(nir_builder *b, 1660bf215546Sopenharmony_ci nir_ssa_def *src, 1661bf215546Sopenharmony_ci nir_alu_type type, 1662bf215546Sopenharmony_ci unsigned bit_size) 1663bf215546Sopenharmony_ci{ 1664bf215546Sopenharmony_ci return nir_type_convert(b, src, type, (nir_alu_type) (type | bit_size)); 1665bf215546Sopenharmony_ci} 1666bf215546Sopenharmony_ci 1667bf215546Sopenharmony_cistatic inline nir_ssa_def * 1668bf215546Sopenharmony_cinir_i2iN(nir_builder *b, nir_ssa_def *src, unsigned bit_size) 1669bf215546Sopenharmony_ci{ 1670bf215546Sopenharmony_ci return nir_convert_to_bit_size(b, src, nir_type_int, bit_size); 1671bf215546Sopenharmony_ci} 1672bf215546Sopenharmony_ci 1673bf215546Sopenharmony_cistatic inline nir_ssa_def * 1674bf215546Sopenharmony_cinir_u2uN(nir_builder *b, nir_ssa_def *src, unsigned bit_size) 1675bf215546Sopenharmony_ci{ 1676bf215546Sopenharmony_ci return nir_convert_to_bit_size(b, src, nir_type_uint, bit_size); 1677bf215546Sopenharmony_ci} 1678bf215546Sopenharmony_ci 1679bf215546Sopenharmony_cistatic inline nir_ssa_def * 1680bf215546Sopenharmony_cinir_b2bN(nir_builder *b, nir_ssa_def *src, unsigned bit_size) 1681bf215546Sopenharmony_ci{ 1682bf215546Sopenharmony_ci return nir_convert_to_bit_size(b, src, nir_type_bool, bit_size); 1683bf215546Sopenharmony_ci} 1684bf215546Sopenharmony_ci 1685bf215546Sopenharmony_cistatic inline nir_ssa_def * 1686bf215546Sopenharmony_cinir_f2fN(nir_builder *b, nir_ssa_def *src, unsigned bit_size) 1687bf215546Sopenharmony_ci{ 1688bf215546Sopenharmony_ci return nir_convert_to_bit_size(b, src, nir_type_float, bit_size); 1689bf215546Sopenharmony_ci} 1690bf215546Sopenharmony_ci 1691bf215546Sopenharmony_cistatic inline nir_ssa_def * 1692bf215546Sopenharmony_cinir_i2fN(nir_builder *b, nir_ssa_def *src, unsigned bit_size) 1693bf215546Sopenharmony_ci{ 1694bf215546Sopenharmony_ci return nir_type_convert(b, src, nir_type_int, 1695bf215546Sopenharmony_ci (nir_alu_type) (nir_type_float | bit_size)); 1696bf215546Sopenharmony_ci} 1697bf215546Sopenharmony_ci 1698bf215546Sopenharmony_cistatic inline nir_ssa_def * 1699bf215546Sopenharmony_cinir_u2fN(nir_builder *b, nir_ssa_def *src, unsigned bit_size) 1700bf215546Sopenharmony_ci{ 1701bf215546Sopenharmony_ci return nir_type_convert(b, src, nir_type_uint, 1702bf215546Sopenharmony_ci (nir_alu_type) (nir_type_float | bit_size)); 1703bf215546Sopenharmony_ci} 1704bf215546Sopenharmony_ci 1705bf215546Sopenharmony_cistatic inline nir_ssa_def * 1706bf215546Sopenharmony_cinir_f2uN(nir_builder *b, nir_ssa_def *src, unsigned bit_size) 1707bf215546Sopenharmony_ci{ 1708bf215546Sopenharmony_ci return nir_type_convert(b, src, nir_type_float, 1709bf215546Sopenharmony_ci (nir_alu_type) (nir_type_uint | bit_size)); 1710bf215546Sopenharmony_ci} 1711bf215546Sopenharmony_ci 1712bf215546Sopenharmony_cistatic inline nir_ssa_def * 1713bf215546Sopenharmony_cinir_f2iN(nir_builder *b, nir_ssa_def *src, unsigned bit_size) 1714bf215546Sopenharmony_ci{ 1715bf215546Sopenharmony_ci return nir_type_convert(b, src, nir_type_float, 1716bf215546Sopenharmony_ci (nir_alu_type) (nir_type_int | bit_size)); 1717bf215546Sopenharmony_ci} 1718bf215546Sopenharmony_ci 1719bf215546Sopenharmony_cinir_ssa_def * 1720bf215546Sopenharmony_cinir_gen_rect_vertices(nir_builder *b, nir_ssa_def *z, nir_ssa_def *w); 1721bf215546Sopenharmony_ci 1722bf215546Sopenharmony_ci#ifdef __cplusplus 1723bf215546Sopenharmony_ci} /* extern "C" */ 1724bf215546Sopenharmony_ci#endif 1725bf215546Sopenharmony_ci 1726bf215546Sopenharmony_ci#endif /* NIR_BUILDER_H */ 1727