1b8e80941Smrg/* 2b8e80941Smrg * Copyright © 2014-2015 Broadcom 3b8e80941Smrg * 4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5b8e80941Smrg * copy of this software and associated documentation files (the "Software"), 6b8e80941Smrg * to deal in the Software without restriction, including without limitation 7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the 9b8e80941Smrg * Software is furnished to do so, subject to the following conditions: 10b8e80941Smrg * 11b8e80941Smrg * The above copyright notice and this permission notice (including the next 12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the 13b8e80941Smrg * Software. 14b8e80941Smrg * 15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21b8e80941Smrg * IN THE SOFTWARE. 22b8e80941Smrg */ 23b8e80941Smrg 24b8e80941Smrg#ifndef NIR_BUILDER_H 25b8e80941Smrg#define NIR_BUILDER_H 26b8e80941Smrg 27b8e80941Smrg#include "nir_control_flow.h" 28b8e80941Smrg#include "util/bitscan.h" 29b8e80941Smrg#include "util/half_float.h" 30b8e80941Smrg 31b8e80941Smrgstruct exec_list; 32b8e80941Smrg 33b8e80941Smrgtypedef struct nir_builder { 34b8e80941Smrg nir_cursor cursor; 35b8e80941Smrg 36b8e80941Smrg /* Whether new ALU instructions will be marked "exact" */ 37b8e80941Smrg bool exact; 38b8e80941Smrg 39b8e80941Smrg nir_shader *shader; 40b8e80941Smrg nir_function_impl *impl; 41b8e80941Smrg} nir_builder; 42b8e80941Smrg 43b8e80941Smrgstatic inline void 44b8e80941Smrgnir_builder_init(nir_builder *build, nir_function_impl *impl) 45b8e80941Smrg{ 46b8e80941Smrg memset(build, 0, sizeof(*build)); 47b8e80941Smrg build->exact = false; 48b8e80941Smrg build->impl = impl; 49b8e80941Smrg build->shader = impl->function->shader; 50b8e80941Smrg} 51b8e80941Smrg 52b8e80941Smrgstatic inline void 53b8e80941Smrgnir_builder_init_simple_shader(nir_builder *build, void *mem_ctx, 54b8e80941Smrg gl_shader_stage stage, 55b8e80941Smrg const nir_shader_compiler_options *options) 56b8e80941Smrg{ 57b8e80941Smrg build->shader = nir_shader_create(mem_ctx, stage, options, NULL); 58b8e80941Smrg nir_function *func = nir_function_create(build->shader, "main"); 59b8e80941Smrg func->is_entrypoint = true; 60b8e80941Smrg build->exact = false; 61b8e80941Smrg build->impl = nir_function_impl_create(func); 62b8e80941Smrg build->cursor = nir_after_cf_list(&build->impl->body); 63b8e80941Smrg} 64b8e80941Smrg 65b8e80941Smrgstatic inline void 66b8e80941Smrgnir_builder_instr_insert(nir_builder *build, nir_instr *instr) 67b8e80941Smrg{ 68b8e80941Smrg nir_instr_insert(build->cursor, instr); 69b8e80941Smrg 70b8e80941Smrg /* Move the cursor forward. */ 71b8e80941Smrg build->cursor = nir_after_instr(instr); 72b8e80941Smrg} 73b8e80941Smrg 74b8e80941Smrgstatic inline nir_instr * 75b8e80941Smrgnir_builder_last_instr(nir_builder *build) 76b8e80941Smrg{ 77b8e80941Smrg assert(build->cursor.option == nir_cursor_after_instr); 78b8e80941Smrg return build->cursor.instr; 79b8e80941Smrg} 80b8e80941Smrg 81b8e80941Smrgstatic inline void 82b8e80941Smrgnir_builder_cf_insert(nir_builder *build, nir_cf_node *cf) 83b8e80941Smrg{ 84b8e80941Smrg nir_cf_node_insert(build->cursor, cf); 85b8e80941Smrg} 86b8e80941Smrg 87b8e80941Smrgstatic inline bool 88b8e80941Smrgnir_builder_is_inside_cf(nir_builder *build, nir_cf_node *cf_node) 89b8e80941Smrg{ 90b8e80941Smrg nir_block *block = nir_cursor_current_block(build->cursor); 91b8e80941Smrg for (nir_cf_node *n = &block->cf_node; n; n = n->parent) { 92b8e80941Smrg if (n == cf_node) 93b8e80941Smrg return true; 94b8e80941Smrg } 95b8e80941Smrg return false; 96b8e80941Smrg} 97b8e80941Smrg 98b8e80941Smrgstatic inline nir_if * 99b8e80941Smrgnir_push_if(nir_builder *build, nir_ssa_def *condition) 100b8e80941Smrg{ 101b8e80941Smrg nir_if *nif = nir_if_create(build->shader); 102b8e80941Smrg nif->condition = nir_src_for_ssa(condition); 103b8e80941Smrg nir_builder_cf_insert(build, &nif->cf_node); 104b8e80941Smrg build->cursor = nir_before_cf_list(&nif->then_list); 105b8e80941Smrg return nif; 106b8e80941Smrg} 107b8e80941Smrg 108b8e80941Smrgstatic inline nir_if * 109b8e80941Smrgnir_push_else(nir_builder *build, nir_if *nif) 110b8e80941Smrg{ 111b8e80941Smrg if (nif) { 112b8e80941Smrg assert(nir_builder_is_inside_cf(build, &nif->cf_node)); 113b8e80941Smrg } else { 114b8e80941Smrg nir_block *block = nir_cursor_current_block(build->cursor); 115b8e80941Smrg nif = nir_cf_node_as_if(block->cf_node.parent); 116b8e80941Smrg } 117b8e80941Smrg build->cursor = nir_before_cf_list(&nif->else_list); 118b8e80941Smrg return nif; 119b8e80941Smrg} 120b8e80941Smrg 121b8e80941Smrgstatic inline void 122b8e80941Smrgnir_pop_if(nir_builder *build, nir_if *nif) 123b8e80941Smrg{ 124b8e80941Smrg if (nif) { 125b8e80941Smrg assert(nir_builder_is_inside_cf(build, &nif->cf_node)); 126b8e80941Smrg } else { 127b8e80941Smrg nir_block *block = nir_cursor_current_block(build->cursor); 128b8e80941Smrg nif = nir_cf_node_as_if(block->cf_node.parent); 129b8e80941Smrg } 130b8e80941Smrg build->cursor = nir_after_cf_node(&nif->cf_node); 131b8e80941Smrg} 132b8e80941Smrg 133b8e80941Smrgstatic inline nir_ssa_def * 134b8e80941Smrgnir_if_phi(nir_builder *build, nir_ssa_def *then_def, nir_ssa_def *else_def) 135b8e80941Smrg{ 136b8e80941Smrg nir_block *block = nir_cursor_current_block(build->cursor); 137b8e80941Smrg nir_if *nif = nir_cf_node_as_if(nir_cf_node_prev(&block->cf_node)); 138b8e80941Smrg 139b8e80941Smrg nir_phi_instr *phi = nir_phi_instr_create(build->shader); 140b8e80941Smrg 141b8e80941Smrg nir_phi_src *src = ralloc(phi, nir_phi_src); 142b8e80941Smrg src->pred = nir_if_last_then_block(nif); 143b8e80941Smrg src->src = nir_src_for_ssa(then_def); 144b8e80941Smrg exec_list_push_tail(&phi->srcs, &src->node); 145b8e80941Smrg 146b8e80941Smrg src = ralloc(phi, nir_phi_src); 147b8e80941Smrg src->pred = nir_if_last_else_block(nif); 148b8e80941Smrg src->src = nir_src_for_ssa(else_def); 149b8e80941Smrg exec_list_push_tail(&phi->srcs, &src->node); 150b8e80941Smrg 151b8e80941Smrg assert(then_def->num_components == else_def->num_components); 152b8e80941Smrg assert(then_def->bit_size == else_def->bit_size); 153b8e80941Smrg nir_ssa_dest_init(&phi->instr, &phi->dest, 154b8e80941Smrg then_def->num_components, then_def->bit_size, NULL); 155b8e80941Smrg 156b8e80941Smrg nir_builder_instr_insert(build, &phi->instr); 157b8e80941Smrg 158b8e80941Smrg return &phi->dest.ssa; 159b8e80941Smrg} 160b8e80941Smrg 161b8e80941Smrgstatic inline nir_loop * 162b8e80941Smrgnir_push_loop(nir_builder *build) 163b8e80941Smrg{ 164b8e80941Smrg nir_loop *loop = nir_loop_create(build->shader); 165b8e80941Smrg nir_builder_cf_insert(build, &loop->cf_node); 166b8e80941Smrg build->cursor = nir_before_cf_list(&loop->body); 167b8e80941Smrg return loop; 168b8e80941Smrg} 169b8e80941Smrg 170b8e80941Smrgstatic inline void 171b8e80941Smrgnir_pop_loop(nir_builder *build, nir_loop *loop) 172b8e80941Smrg{ 173b8e80941Smrg if (loop) { 174b8e80941Smrg assert(nir_builder_is_inside_cf(build, &loop->cf_node)); 175b8e80941Smrg } else { 176b8e80941Smrg nir_block *block = nir_cursor_current_block(build->cursor); 177b8e80941Smrg loop = nir_cf_node_as_loop(block->cf_node.parent); 178b8e80941Smrg } 179b8e80941Smrg build->cursor = nir_after_cf_node(&loop->cf_node); 180b8e80941Smrg} 181b8e80941Smrg 182b8e80941Smrgstatic inline nir_ssa_def * 183b8e80941Smrgnir_ssa_undef(nir_builder *build, unsigned num_components, unsigned bit_size) 184b8e80941Smrg{ 185b8e80941Smrg nir_ssa_undef_instr *undef = 186b8e80941Smrg nir_ssa_undef_instr_create(build->shader, num_components, bit_size); 187b8e80941Smrg if (!undef) 188b8e80941Smrg return NULL; 189b8e80941Smrg 190b8e80941Smrg nir_instr_insert(nir_before_cf_list(&build->impl->body), &undef->instr); 191b8e80941Smrg 192b8e80941Smrg return &undef->def; 193b8e80941Smrg} 194b8e80941Smrg 195b8e80941Smrgstatic inline nir_ssa_def * 196b8e80941Smrgnir_build_imm(nir_builder *build, unsigned num_components, 197b8e80941Smrg unsigned bit_size, const nir_const_value *value) 198b8e80941Smrg{ 199b8e80941Smrg nir_load_const_instr *load_const = 200b8e80941Smrg nir_load_const_instr_create(build->shader, num_components, bit_size); 201b8e80941Smrg if (!load_const) 202b8e80941Smrg return NULL; 203b8e80941Smrg 204b8e80941Smrg memcpy(load_const->value, value, sizeof(nir_const_value) * num_components); 205b8e80941Smrg 206b8e80941Smrg nir_builder_instr_insert(build, &load_const->instr); 207b8e80941Smrg 208b8e80941Smrg return &load_const->def; 209b8e80941Smrg} 210b8e80941Smrg 211b8e80941Smrgstatic inline nir_ssa_def * 212b8e80941Smrgnir_imm_zero(nir_builder *build, unsigned num_components, unsigned bit_size) 213b8e80941Smrg{ 214b8e80941Smrg nir_load_const_instr *load_const = 215b8e80941Smrg nir_load_const_instr_create(build->shader, num_components, bit_size); 216b8e80941Smrg 217b8e80941Smrg /* nir_load_const_instr_create uses rzalloc so it's already zero */ 218b8e80941Smrg 219b8e80941Smrg nir_builder_instr_insert(build, &load_const->instr); 220b8e80941Smrg 221b8e80941Smrg return &load_const->def; 222b8e80941Smrg} 223b8e80941Smrg 224b8e80941Smrgstatic inline nir_ssa_def * 225b8e80941Smrgnir_imm_bool(nir_builder *build, bool x) 226b8e80941Smrg{ 227b8e80941Smrg nir_const_value v; 228b8e80941Smrg 229b8e80941Smrg memset(&v, 0, sizeof(v)); 230b8e80941Smrg v.b = x; 231b8e80941Smrg 232b8e80941Smrg return nir_build_imm(build, 1, 1, &v); 233b8e80941Smrg} 234b8e80941Smrg 235b8e80941Smrgstatic inline nir_ssa_def * 236b8e80941Smrgnir_imm_true(nir_builder *build) 237b8e80941Smrg{ 238b8e80941Smrg return nir_imm_bool(build, true); 239b8e80941Smrg} 240b8e80941Smrg 241b8e80941Smrgstatic inline nir_ssa_def * 242b8e80941Smrgnir_imm_false(nir_builder *build) 243b8e80941Smrg{ 244b8e80941Smrg return nir_imm_bool(build, false); 245b8e80941Smrg} 246b8e80941Smrg 247b8e80941Smrgstatic inline nir_ssa_def * 248b8e80941Smrgnir_imm_float16(nir_builder *build, float x) 249b8e80941Smrg{ 250b8e80941Smrg nir_const_value v; 251b8e80941Smrg 252b8e80941Smrg memset(&v, 0, sizeof(v)); 253b8e80941Smrg v.u16 = _mesa_float_to_half(x); 254b8e80941Smrg 255b8e80941Smrg return nir_build_imm(build, 1, 16, &v); 256b8e80941Smrg} 257b8e80941Smrg 258b8e80941Smrgstatic inline nir_ssa_def * 259b8e80941Smrgnir_imm_float(nir_builder *build, float x) 260b8e80941Smrg{ 261b8e80941Smrg nir_const_value v; 262b8e80941Smrg 263b8e80941Smrg memset(&v, 0, sizeof(v)); 264b8e80941Smrg v.f32 = x; 265b8e80941Smrg 266b8e80941Smrg return nir_build_imm(build, 1, 32, &v); 267b8e80941Smrg} 268b8e80941Smrg 269b8e80941Smrgstatic inline nir_ssa_def * 270b8e80941Smrgnir_imm_double(nir_builder *build, double x) 271b8e80941Smrg{ 272b8e80941Smrg nir_const_value v; 273b8e80941Smrg 274b8e80941Smrg memset(&v, 0, sizeof(v)); 275b8e80941Smrg v.f64 = x; 276b8e80941Smrg 277b8e80941Smrg return nir_build_imm(build, 1, 64, &v); 278b8e80941Smrg} 279b8e80941Smrg 280b8e80941Smrgstatic inline nir_ssa_def * 281b8e80941Smrgnir_imm_floatN_t(nir_builder *build, double x, unsigned bit_size) 282b8e80941Smrg{ 283b8e80941Smrg switch (bit_size) { 284b8e80941Smrg case 16: 285b8e80941Smrg return nir_imm_float16(build, x); 286b8e80941Smrg case 32: 287b8e80941Smrg return nir_imm_float(build, x); 288b8e80941Smrg case 64: 289b8e80941Smrg return nir_imm_double(build, x); 290b8e80941Smrg } 291b8e80941Smrg 292b8e80941Smrg unreachable("unknown float immediate bit size"); 293b8e80941Smrg} 294b8e80941Smrg 295b8e80941Smrgstatic inline nir_ssa_def * 296b8e80941Smrgnir_imm_vec2(nir_builder *build, float x, float y) 297b8e80941Smrg{ 298b8e80941Smrg nir_const_value v[2]; 299b8e80941Smrg 300b8e80941Smrg memset(v, 0, sizeof(v)); 301b8e80941Smrg v[0].f32 = x; 302b8e80941Smrg v[1].f32 = y; 303b8e80941Smrg 304b8e80941Smrg return nir_build_imm(build, 2, 32, v); 305b8e80941Smrg} 306b8e80941Smrg 307b8e80941Smrgstatic inline nir_ssa_def * 308b8e80941Smrgnir_imm_vec4(nir_builder *build, float x, float y, float z, float w) 309b8e80941Smrg{ 310b8e80941Smrg nir_const_value v[4]; 311b8e80941Smrg 312b8e80941Smrg memset(v, 0, sizeof(v)); 313b8e80941Smrg v[0].f32 = x; 314b8e80941Smrg v[1].f32 = y; 315b8e80941Smrg v[2].f32 = z; 316b8e80941Smrg v[3].f32 = w; 317b8e80941Smrg 318b8e80941Smrg return nir_build_imm(build, 4, 32, v); 319b8e80941Smrg} 320b8e80941Smrg 321b8e80941Smrgstatic inline nir_ssa_def * 322b8e80941Smrgnir_imm_ivec2(nir_builder *build, int x, int y) 323b8e80941Smrg{ 324b8e80941Smrg nir_const_value v[2]; 325b8e80941Smrg 326b8e80941Smrg memset(v, 0, sizeof(v)); 327b8e80941Smrg v[0].i32 = x; 328b8e80941Smrg v[1].i32 = y; 329b8e80941Smrg 330b8e80941Smrg return nir_build_imm(build, 2, 32, v); 331b8e80941Smrg} 332b8e80941Smrg 333b8e80941Smrgstatic inline nir_ssa_def * 334b8e80941Smrgnir_imm_int(nir_builder *build, int x) 335b8e80941Smrg{ 336b8e80941Smrg nir_const_value v; 337b8e80941Smrg 338b8e80941Smrg memset(&v, 0, sizeof(v)); 339b8e80941Smrg v.i32 = x; 340b8e80941Smrg 341b8e80941Smrg return nir_build_imm(build, 1, 32, &v); 342b8e80941Smrg} 343b8e80941Smrg 344b8e80941Smrgstatic inline nir_ssa_def * 345b8e80941Smrgnir_imm_int64(nir_builder *build, int64_t x) 346b8e80941Smrg{ 347b8e80941Smrg nir_const_value v; 348b8e80941Smrg 349b8e80941Smrg memset(&v, 0, sizeof(v)); 350b8e80941Smrg v.i64 = x; 351b8e80941Smrg 352b8e80941Smrg return nir_build_imm(build, 1, 64, &v); 353b8e80941Smrg} 354b8e80941Smrg 355b8e80941Smrgstatic inline nir_ssa_def * 356b8e80941Smrgnir_imm_intN_t(nir_builder *build, uint64_t x, unsigned bit_size) 357b8e80941Smrg{ 358b8e80941Smrg nir_const_value v; 359b8e80941Smrg 360b8e80941Smrg memset(&v, 0, sizeof(v)); 361b8e80941Smrg assert(bit_size <= 64); 362b8e80941Smrg if (bit_size == 1) 363b8e80941Smrg v.b = x & 1; 364b8e80941Smrg else 365b8e80941Smrg v.i64 = x & (~0ull >> (64 - bit_size)); 366b8e80941Smrg 367b8e80941Smrg return nir_build_imm(build, 1, bit_size, &v); 368b8e80941Smrg} 369b8e80941Smrg 370b8e80941Smrgstatic inline nir_ssa_def * 371b8e80941Smrgnir_imm_ivec4(nir_builder *build, int x, int y, int z, int w) 372b8e80941Smrg{ 373b8e80941Smrg nir_const_value v[4]; 374b8e80941Smrg 375b8e80941Smrg memset(v, 0, sizeof(v)); 376b8e80941Smrg v[0].i32 = x; 377b8e80941Smrg v[1].i32 = y; 378b8e80941Smrg v[2].i32 = z; 379b8e80941Smrg v[3].i32 = w; 380b8e80941Smrg 381b8e80941Smrg return nir_build_imm(build, 4, 32, v); 382b8e80941Smrg} 383b8e80941Smrg 384b8e80941Smrgstatic inline nir_ssa_def * 385b8e80941Smrgnir_imm_boolN_t(nir_builder *build, bool x, unsigned bit_size) 386b8e80941Smrg{ 387b8e80941Smrg /* We use a 0/-1 convention for all booleans regardless of size */ 388b8e80941Smrg return nir_imm_intN_t(build, -(int)x, bit_size); 389b8e80941Smrg} 390b8e80941Smrg 391b8e80941Smrgstatic inline nir_ssa_def * 392b8e80941Smrgnir_builder_alu_instr_finish_and_insert(nir_builder *build, nir_alu_instr *instr) 393b8e80941Smrg{ 394b8e80941Smrg const nir_op_info *op_info = &nir_op_infos[instr->op]; 395b8e80941Smrg 396b8e80941Smrg instr->exact = build->exact; 397b8e80941Smrg 398b8e80941Smrg /* Guess the number of components the destination temporary should have 399b8e80941Smrg * based on our input sizes, if it's not fixed for the op. 400b8e80941Smrg */ 401b8e80941Smrg unsigned num_components = op_info->output_size; 402b8e80941Smrg if (num_components == 0) { 403b8e80941Smrg for (unsigned i = 0; i < op_info->num_inputs; i++) { 404b8e80941Smrg if (op_info->input_sizes[i] == 0) 405b8e80941Smrg num_components = MAX2(num_components, 406b8e80941Smrg instr->src[i].src.ssa->num_components); 407b8e80941Smrg } 408b8e80941Smrg } 409b8e80941Smrg assert(num_components != 0); 410b8e80941Smrg 411b8e80941Smrg /* Figure out the bitwidth based on the source bitwidth if the instruction 412b8e80941Smrg * is variable-width. 413b8e80941Smrg */ 414b8e80941Smrg unsigned bit_size = nir_alu_type_get_type_size(op_info->output_type); 415b8e80941Smrg if (bit_size == 0) { 416b8e80941Smrg for (unsigned i = 0; i < op_info->num_inputs; i++) { 417b8e80941Smrg unsigned src_bit_size = instr->src[i].src.ssa->bit_size; 418b8e80941Smrg if (nir_alu_type_get_type_size(op_info->input_types[i]) == 0) { 419b8e80941Smrg if (bit_size) 420b8e80941Smrg assert(src_bit_size == bit_size); 421b8e80941Smrg else 422b8e80941Smrg bit_size = src_bit_size; 423b8e80941Smrg } else { 424b8e80941Smrg assert(src_bit_size == 425b8e80941Smrg nir_alu_type_get_type_size(op_info->input_types[i])); 426b8e80941Smrg } 427b8e80941Smrg } 428b8e80941Smrg } 429b8e80941Smrg 430b8e80941Smrg /* When in doubt, assume 32. */ 431b8e80941Smrg if (bit_size == 0) 432b8e80941Smrg bit_size = 32; 433b8e80941Smrg 434b8e80941Smrg /* Make sure we don't swizzle from outside of our source vector (like if a 435b8e80941Smrg * scalar value was passed into a multiply with a vector). 436b8e80941Smrg */ 437b8e80941Smrg for (unsigned i = 0; i < op_info->num_inputs; i++) { 438b8e80941Smrg for (unsigned j = instr->src[i].src.ssa->num_components; 439b8e80941Smrg j < NIR_MAX_VEC_COMPONENTS; j++) { 440b8e80941Smrg instr->src[i].swizzle[j] = instr->src[i].src.ssa->num_components - 1; 441b8e80941Smrg } 442b8e80941Smrg } 443b8e80941Smrg 444b8e80941Smrg nir_ssa_dest_init(&instr->instr, &instr->dest.dest, num_components, 445b8e80941Smrg bit_size, NULL); 446b8e80941Smrg instr->dest.write_mask = (1 << num_components) - 1; 447b8e80941Smrg 448b8e80941Smrg nir_builder_instr_insert(build, &instr->instr); 449b8e80941Smrg 450b8e80941Smrg return &instr->dest.dest.ssa; 451b8e80941Smrg} 452b8e80941Smrg 453b8e80941Smrgstatic inline nir_ssa_def * 454b8e80941Smrgnir_build_alu(nir_builder *build, nir_op op, nir_ssa_def *src0, 455b8e80941Smrg nir_ssa_def *src1, nir_ssa_def *src2, nir_ssa_def *src3) 456b8e80941Smrg{ 457b8e80941Smrg nir_alu_instr *instr = nir_alu_instr_create(build->shader, op); 458b8e80941Smrg if (!instr) 459b8e80941Smrg return NULL; 460b8e80941Smrg 461b8e80941Smrg instr->src[0].src = nir_src_for_ssa(src0); 462b8e80941Smrg if (src1) 463b8e80941Smrg instr->src[1].src = nir_src_for_ssa(src1); 464b8e80941Smrg if (src2) 465b8e80941Smrg instr->src[2].src = nir_src_for_ssa(src2); 466b8e80941Smrg if (src3) 467b8e80941Smrg instr->src[3].src = nir_src_for_ssa(src3); 468b8e80941Smrg 469b8e80941Smrg return nir_builder_alu_instr_finish_and_insert(build, instr); 470b8e80941Smrg} 471b8e80941Smrg 472b8e80941Smrg/* for the couple special cases with more than 4 src args: */ 473b8e80941Smrgstatic inline nir_ssa_def * 474b8e80941Smrgnir_build_alu_src_arr(nir_builder *build, nir_op op, nir_ssa_def **srcs) 475b8e80941Smrg{ 476b8e80941Smrg const nir_op_info *op_info = &nir_op_infos[op]; 477b8e80941Smrg nir_alu_instr *instr = nir_alu_instr_create(build->shader, op); 478b8e80941Smrg if (!instr) 479b8e80941Smrg return NULL; 480b8e80941Smrg 481b8e80941Smrg for (unsigned i = 0; i < op_info->num_inputs; i++) 482b8e80941Smrg instr->src[i].src = nir_src_for_ssa(srcs[i]); 483b8e80941Smrg 484b8e80941Smrg return nir_builder_alu_instr_finish_and_insert(build, instr); 485b8e80941Smrg} 486b8e80941Smrg 487b8e80941Smrg#include "nir_builder_opcodes.h" 488b8e80941Smrg 489b8e80941Smrgstatic inline nir_ssa_def * 490b8e80941Smrgnir_vec(nir_builder *build, nir_ssa_def **comp, unsigned num_components) 491b8e80941Smrg{ 492b8e80941Smrg return nir_build_alu_src_arr(build, nir_op_vec(num_components), comp); 493b8e80941Smrg} 494b8e80941Smrg 495b8e80941Smrg/** 496b8e80941Smrg * Similar to nir_fmov, but takes a nir_alu_src instead of a nir_ssa_def. 497b8e80941Smrg */ 498b8e80941Smrgstatic inline nir_ssa_def * 499b8e80941Smrgnir_fmov_alu(nir_builder *build, nir_alu_src src, unsigned num_components) 500b8e80941Smrg{ 501b8e80941Smrg nir_alu_instr *mov = nir_alu_instr_create(build->shader, nir_op_fmov); 502b8e80941Smrg nir_ssa_dest_init(&mov->instr, &mov->dest.dest, num_components, 503b8e80941Smrg nir_src_bit_size(src.src), NULL); 504b8e80941Smrg mov->exact = build->exact; 505b8e80941Smrg mov->dest.write_mask = (1 << num_components) - 1; 506b8e80941Smrg mov->src[0] = src; 507b8e80941Smrg nir_builder_instr_insert(build, &mov->instr); 508b8e80941Smrg 509b8e80941Smrg return &mov->dest.dest.ssa; 510b8e80941Smrg} 511b8e80941Smrg 512b8e80941Smrgstatic inline nir_ssa_def * 513b8e80941Smrgnir_imov_alu(nir_builder *build, nir_alu_src src, unsigned num_components) 514b8e80941Smrg{ 515b8e80941Smrg nir_alu_instr *mov = nir_alu_instr_create(build->shader, nir_op_imov); 516b8e80941Smrg nir_ssa_dest_init(&mov->instr, &mov->dest.dest, num_components, 517b8e80941Smrg nir_src_bit_size(src.src), NULL); 518b8e80941Smrg mov->exact = build->exact; 519b8e80941Smrg mov->dest.write_mask = (1 << num_components) - 1; 520b8e80941Smrg mov->src[0] = src; 521b8e80941Smrg nir_builder_instr_insert(build, &mov->instr); 522b8e80941Smrg 523b8e80941Smrg return &mov->dest.dest.ssa; 524b8e80941Smrg} 525b8e80941Smrg 526b8e80941Smrg/** 527b8e80941Smrg * Construct an fmov or imov that reswizzles the source's components. 528b8e80941Smrg */ 529b8e80941Smrgstatic inline nir_ssa_def * 530b8e80941Smrgnir_swizzle(nir_builder *build, nir_ssa_def *src, const unsigned *swiz, 531b8e80941Smrg unsigned num_components, bool use_fmov) 532b8e80941Smrg{ 533b8e80941Smrg assert(num_components <= NIR_MAX_VEC_COMPONENTS); 534b8e80941Smrg nir_alu_src alu_src = { NIR_SRC_INIT }; 535b8e80941Smrg alu_src.src = nir_src_for_ssa(src); 536b8e80941Smrg 537b8e80941Smrg bool is_identity_swizzle = true; 538b8e80941Smrg for (unsigned i = 0; i < num_components && i < NIR_MAX_VEC_COMPONENTS; i++) { 539b8e80941Smrg if (swiz[i] != i) 540b8e80941Smrg is_identity_swizzle = false; 541b8e80941Smrg alu_src.swizzle[i] = swiz[i]; 542b8e80941Smrg } 543b8e80941Smrg 544b8e80941Smrg if (num_components == src->num_components && is_identity_swizzle) 545b8e80941Smrg return src; 546b8e80941Smrg 547b8e80941Smrg return use_fmov ? nir_fmov_alu(build, alu_src, num_components) : 548b8e80941Smrg nir_imov_alu(build, alu_src, num_components); 549b8e80941Smrg} 550b8e80941Smrg 551b8e80941Smrg/* Selects the right fdot given the number of components in each source. */ 552b8e80941Smrgstatic inline nir_ssa_def * 553b8e80941Smrgnir_fdot(nir_builder *build, nir_ssa_def *src0, nir_ssa_def *src1) 554b8e80941Smrg{ 555b8e80941Smrg assert(src0->num_components == src1->num_components); 556b8e80941Smrg switch (src0->num_components) { 557b8e80941Smrg case 1: return nir_fmul(build, src0, src1); 558b8e80941Smrg case 2: return nir_fdot2(build, src0, src1); 559b8e80941Smrg case 3: return nir_fdot3(build, src0, src1); 560b8e80941Smrg case 4: return nir_fdot4(build, src0, src1); 561b8e80941Smrg default: 562b8e80941Smrg unreachable("bad component size"); 563b8e80941Smrg } 564b8e80941Smrg 565b8e80941Smrg return NULL; 566b8e80941Smrg} 567b8e80941Smrg 568b8e80941Smrgstatic inline nir_ssa_def * 569b8e80941Smrgnir_bany_inequal(nir_builder *b, nir_ssa_def *src0, nir_ssa_def *src1) 570b8e80941Smrg{ 571b8e80941Smrg switch (src0->num_components) { 572b8e80941Smrg case 1: return nir_ine(b, src0, src1); 573b8e80941Smrg case 2: return nir_bany_inequal2(b, src0, src1); 574b8e80941Smrg case 3: return nir_bany_inequal3(b, src0, src1); 575b8e80941Smrg case 4: return nir_bany_inequal4(b, src0, src1); 576b8e80941Smrg default: 577b8e80941Smrg unreachable("bad component size"); 578b8e80941Smrg } 579b8e80941Smrg} 580b8e80941Smrg 581b8e80941Smrgstatic inline nir_ssa_def * 582b8e80941Smrgnir_bany(nir_builder *b, nir_ssa_def *src) 583b8e80941Smrg{ 584b8e80941Smrg return nir_bany_inequal(b, src, nir_imm_false(b)); 585b8e80941Smrg} 586b8e80941Smrg 587b8e80941Smrgstatic inline nir_ssa_def * 588b8e80941Smrgnir_channel(nir_builder *b, nir_ssa_def *def, unsigned c) 589b8e80941Smrg{ 590b8e80941Smrg return nir_swizzle(b, def, &c, 1, false); 591b8e80941Smrg} 592b8e80941Smrg 593b8e80941Smrgstatic inline nir_ssa_def * 594b8e80941Smrgnir_channels(nir_builder *b, nir_ssa_def *def, nir_component_mask_t mask) 595b8e80941Smrg{ 596b8e80941Smrg unsigned num_channels = 0, swizzle[NIR_MAX_VEC_COMPONENTS] = { 0 }; 597b8e80941Smrg 598b8e80941Smrg for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) { 599b8e80941Smrg if ((mask & (1 << i)) == 0) 600b8e80941Smrg continue; 601b8e80941Smrg swizzle[num_channels++] = i; 602b8e80941Smrg } 603b8e80941Smrg 604b8e80941Smrg return nir_swizzle(b, def, swizzle, num_channels, false); 605b8e80941Smrg} 606b8e80941Smrg 607b8e80941Smrgstatic inline nir_ssa_def * 608b8e80941Smrg_nir_vector_extract_helper(nir_builder *b, nir_ssa_def *vec, nir_ssa_def *c, 609b8e80941Smrg unsigned start, unsigned end) 610b8e80941Smrg{ 611b8e80941Smrg if (start == end - 1) { 612b8e80941Smrg return nir_channel(b, vec, start); 613b8e80941Smrg } else { 614b8e80941Smrg unsigned mid = start + (end - start) / 2; 615b8e80941Smrg return nir_bcsel(b, nir_ilt(b, c, nir_imm_int(b, mid)), 616b8e80941Smrg _nir_vector_extract_helper(b, vec, c, start, mid), 617b8e80941Smrg _nir_vector_extract_helper(b, vec, c, mid, end)); 618b8e80941Smrg } 619b8e80941Smrg} 620b8e80941Smrg 621b8e80941Smrgstatic inline nir_ssa_def * 622b8e80941Smrgnir_vector_extract(nir_builder *b, nir_ssa_def *vec, nir_ssa_def *c) 623b8e80941Smrg{ 624b8e80941Smrg nir_src c_src = nir_src_for_ssa(c); 625b8e80941Smrg if (nir_src_is_const(c_src)) { 626b8e80941Smrg unsigned c_const = nir_src_as_uint(c_src); 627b8e80941Smrg if (c_const < vec->num_components) 628b8e80941Smrg return nir_channel(b, vec, c_const); 629b8e80941Smrg else 630b8e80941Smrg return nir_ssa_undef(b, 1, vec->bit_size); 631b8e80941Smrg } else { 632b8e80941Smrg return _nir_vector_extract_helper(b, vec, c, 0, vec->num_components); 633b8e80941Smrg } 634b8e80941Smrg} 635b8e80941Smrg 636b8e80941Smrgstatic inline nir_ssa_def * 637b8e80941Smrgnir_i2i(nir_builder *build, nir_ssa_def *x, unsigned dest_bit_size) 638b8e80941Smrg{ 639b8e80941Smrg if (x->bit_size == dest_bit_size) 640b8e80941Smrg return x; 641b8e80941Smrg 642b8e80941Smrg switch (dest_bit_size) { 643b8e80941Smrg case 64: return nir_i2i64(build, x); 644b8e80941Smrg case 32: return nir_i2i32(build, x); 645b8e80941Smrg case 16: return nir_i2i16(build, x); 646b8e80941Smrg case 8: return nir_i2i8(build, x); 647b8e80941Smrg default: unreachable("Invalid bit size"); 648b8e80941Smrg } 649b8e80941Smrg} 650b8e80941Smrg 651b8e80941Smrgstatic inline nir_ssa_def * 652b8e80941Smrgnir_u2u(nir_builder *build, nir_ssa_def *x, unsigned dest_bit_size) 653b8e80941Smrg{ 654b8e80941Smrg if (x->bit_size == dest_bit_size) 655b8e80941Smrg return x; 656b8e80941Smrg 657b8e80941Smrg switch (dest_bit_size) { 658b8e80941Smrg case 64: return nir_u2u64(build, x); 659b8e80941Smrg case 32: return nir_u2u32(build, x); 660b8e80941Smrg case 16: return nir_u2u16(build, x); 661b8e80941Smrg case 8: return nir_u2u8(build, x); 662b8e80941Smrg default: unreachable("Invalid bit size"); 663b8e80941Smrg } 664b8e80941Smrg} 665b8e80941Smrg 666b8e80941Smrgstatic inline nir_ssa_def * 667b8e80941Smrgnir_iadd_imm(nir_builder *build, nir_ssa_def *x, uint64_t y) 668b8e80941Smrg{ 669b8e80941Smrg assert(x->bit_size <= 64); 670b8e80941Smrg if (x->bit_size < 64) 671b8e80941Smrg y &= (1ull << x->bit_size) - 1; 672b8e80941Smrg 673b8e80941Smrg if (y == 0) { 674b8e80941Smrg return x; 675b8e80941Smrg } else { 676b8e80941Smrg return nir_iadd(build, x, nir_imm_intN_t(build, y, x->bit_size)); 677b8e80941Smrg } 678b8e80941Smrg} 679b8e80941Smrg 680b8e80941Smrgstatic inline nir_ssa_def * 681b8e80941Smrgnir_imul_imm(nir_builder *build, nir_ssa_def *x, uint64_t y) 682b8e80941Smrg{ 683b8e80941Smrg assert(x->bit_size <= 64); 684b8e80941Smrg if (x->bit_size < 64) 685b8e80941Smrg y &= (1ull << x->bit_size) - 1; 686b8e80941Smrg 687b8e80941Smrg if (y == 0) { 688b8e80941Smrg return nir_imm_intN_t(build, 0, x->bit_size); 689b8e80941Smrg } else if (y == 1) { 690b8e80941Smrg return x; 691b8e80941Smrg } else if (util_is_power_of_two_or_zero64(y)) { 692b8e80941Smrg return nir_ishl(build, x, nir_imm_int(build, ffsll(y) - 1)); 693b8e80941Smrg } else { 694b8e80941Smrg return nir_imul(build, x, nir_imm_intN_t(build, y, x->bit_size)); 695b8e80941Smrg } 696b8e80941Smrg} 697b8e80941Smrg 698b8e80941Smrgstatic inline nir_ssa_def * 699b8e80941Smrgnir_fadd_imm(nir_builder *build, nir_ssa_def *x, double y) 700b8e80941Smrg{ 701b8e80941Smrg return nir_fadd(build, x, nir_imm_floatN_t(build, y, x->bit_size)); 702b8e80941Smrg} 703b8e80941Smrg 704b8e80941Smrgstatic inline nir_ssa_def * 705b8e80941Smrgnir_fmul_imm(nir_builder *build, nir_ssa_def *x, double y) 706b8e80941Smrg{ 707b8e80941Smrg return nir_fmul(build, x, nir_imm_floatN_t(build, y, x->bit_size)); 708b8e80941Smrg} 709b8e80941Smrg 710b8e80941Smrgstatic inline nir_ssa_def * 711b8e80941Smrgnir_pack_bits(nir_builder *b, nir_ssa_def *src, unsigned dest_bit_size) 712b8e80941Smrg{ 713b8e80941Smrg assert(src->num_components * src->bit_size == dest_bit_size); 714b8e80941Smrg 715b8e80941Smrg switch (dest_bit_size) { 716b8e80941Smrg case 64: 717b8e80941Smrg switch (src->bit_size) { 718b8e80941Smrg case 32: return nir_pack_64_2x32(b, src); 719b8e80941Smrg case 16: return nir_pack_64_4x16(b, src); 720b8e80941Smrg default: break; 721b8e80941Smrg } 722b8e80941Smrg break; 723b8e80941Smrg 724b8e80941Smrg case 32: 725b8e80941Smrg if (src->bit_size == 16) 726b8e80941Smrg return nir_pack_32_2x16(b, src); 727b8e80941Smrg break; 728b8e80941Smrg 729b8e80941Smrg default: 730b8e80941Smrg break; 731b8e80941Smrg } 732b8e80941Smrg 733b8e80941Smrg /* If we got here, we have no dedicated unpack opcode. */ 734b8e80941Smrg nir_ssa_def *dest = nir_imm_intN_t(b, 0, dest_bit_size); 735b8e80941Smrg for (unsigned i = 0; i < src->num_components; i++) { 736b8e80941Smrg nir_ssa_def *val = nir_u2u(b, nir_channel(b, src, i), dest_bit_size); 737b8e80941Smrg val = nir_ishl(b, val, nir_imm_int(b, i * src->bit_size)); 738b8e80941Smrg dest = nir_ior(b, dest, val); 739b8e80941Smrg } 740b8e80941Smrg return dest; 741b8e80941Smrg} 742b8e80941Smrg 743b8e80941Smrgstatic inline nir_ssa_def * 744b8e80941Smrgnir_unpack_bits(nir_builder *b, nir_ssa_def *src, unsigned dest_bit_size) 745b8e80941Smrg{ 746b8e80941Smrg assert(src->num_components == 1); 747b8e80941Smrg assert(src->bit_size > dest_bit_size); 748b8e80941Smrg const unsigned dest_num_components = src->bit_size / dest_bit_size; 749b8e80941Smrg assert(dest_num_components <= NIR_MAX_VEC_COMPONENTS); 750b8e80941Smrg 751b8e80941Smrg switch (src->bit_size) { 752b8e80941Smrg case 64: 753b8e80941Smrg switch (dest_bit_size) { 754b8e80941Smrg case 32: return nir_unpack_64_2x32(b, src); 755b8e80941Smrg case 16: return nir_unpack_64_4x16(b, src); 756b8e80941Smrg default: break; 757b8e80941Smrg } 758b8e80941Smrg break; 759b8e80941Smrg 760b8e80941Smrg case 32: 761b8e80941Smrg if (dest_bit_size == 16) 762b8e80941Smrg return nir_unpack_32_2x16(b, src); 763b8e80941Smrg break; 764b8e80941Smrg 765b8e80941Smrg default: 766b8e80941Smrg break; 767b8e80941Smrg } 768b8e80941Smrg 769b8e80941Smrg /* If we got here, we have no dedicated unpack opcode. */ 770b8e80941Smrg nir_ssa_def *dest_comps[NIR_MAX_VEC_COMPONENTS]; 771b8e80941Smrg for (unsigned i = 0; i < dest_num_components; i++) { 772b8e80941Smrg nir_ssa_def *val = nir_ushr(b, src, nir_imm_int(b, i * dest_bit_size)); 773b8e80941Smrg dest_comps[i] = nir_u2u(b, val, dest_bit_size); 774b8e80941Smrg } 775b8e80941Smrg return nir_vec(b, dest_comps, dest_num_components); 776b8e80941Smrg} 777b8e80941Smrg 778b8e80941Smrgstatic inline nir_ssa_def * 779b8e80941Smrgnir_bitcast_vector(nir_builder *b, nir_ssa_def *src, unsigned dest_bit_size) 780b8e80941Smrg{ 781b8e80941Smrg assert((src->bit_size * src->num_components) % dest_bit_size == 0); 782b8e80941Smrg const unsigned dest_num_components = 783b8e80941Smrg (src->bit_size * src->num_components) / dest_bit_size; 784b8e80941Smrg assert(dest_num_components <= NIR_MAX_VEC_COMPONENTS); 785b8e80941Smrg 786b8e80941Smrg if (src->bit_size > dest_bit_size) { 787b8e80941Smrg assert(src->bit_size % dest_bit_size == 0); 788b8e80941Smrg if (src->num_components == 1) { 789b8e80941Smrg return nir_unpack_bits(b, src, dest_bit_size); 790b8e80941Smrg } else { 791b8e80941Smrg const unsigned divisor = src->bit_size / dest_bit_size; 792b8e80941Smrg assert(src->num_components * divisor == dest_num_components); 793b8e80941Smrg nir_ssa_def *dest[NIR_MAX_VEC_COMPONENTS]; 794b8e80941Smrg for (unsigned i = 0; i < src->num_components; i++) { 795b8e80941Smrg nir_ssa_def *unpacked = 796b8e80941Smrg nir_unpack_bits(b, nir_channel(b, src, i), dest_bit_size); 797b8e80941Smrg assert(unpacked->num_components == divisor); 798b8e80941Smrg for (unsigned j = 0; j < divisor; j++) 799b8e80941Smrg dest[i * divisor + j] = nir_channel(b, unpacked, j); 800b8e80941Smrg } 801b8e80941Smrg return nir_vec(b, dest, dest_num_components); 802b8e80941Smrg } 803b8e80941Smrg } else if (src->bit_size < dest_bit_size) { 804b8e80941Smrg assert(dest_bit_size % src->bit_size == 0); 805b8e80941Smrg if (dest_num_components == 1) { 806b8e80941Smrg return nir_pack_bits(b, src, dest_bit_size); 807b8e80941Smrg } else { 808b8e80941Smrg const unsigned divisor = dest_bit_size / src->bit_size; 809b8e80941Smrg assert(src->num_components == dest_num_components * divisor); 810b8e80941Smrg nir_ssa_def *dest[NIR_MAX_VEC_COMPONENTS]; 811b8e80941Smrg for (unsigned i = 0; i < dest_num_components; i++) { 812b8e80941Smrg nir_component_mask_t src_mask = 813b8e80941Smrg ((1 << divisor) - 1) << (i * divisor); 814b8e80941Smrg dest[i] = nir_pack_bits(b, nir_channels(b, src, src_mask), 815b8e80941Smrg dest_bit_size); 816b8e80941Smrg } 817b8e80941Smrg return nir_vec(b, dest, dest_num_components); 818b8e80941Smrg } 819b8e80941Smrg } else { 820b8e80941Smrg assert(src->bit_size == dest_bit_size); 821b8e80941Smrg return src; 822b8e80941Smrg } 823b8e80941Smrg} 824b8e80941Smrg 825b8e80941Smrg/** 826b8e80941Smrg * Turns a nir_src into a nir_ssa_def * so it can be passed to 827b8e80941Smrg * nir_build_alu()-based builder calls. 828b8e80941Smrg * 829b8e80941Smrg * See nir_ssa_for_alu_src() for alu instructions. 830b8e80941Smrg */ 831b8e80941Smrgstatic inline nir_ssa_def * 832b8e80941Smrgnir_ssa_for_src(nir_builder *build, nir_src src, int num_components) 833b8e80941Smrg{ 834b8e80941Smrg if (src.is_ssa && src.ssa->num_components == num_components) 835b8e80941Smrg return src.ssa; 836b8e80941Smrg 837b8e80941Smrg nir_alu_src alu = { NIR_SRC_INIT }; 838b8e80941Smrg alu.src = src; 839b8e80941Smrg for (int j = 0; j < 4; j++) 840b8e80941Smrg alu.swizzle[j] = j; 841b8e80941Smrg 842b8e80941Smrg return nir_imov_alu(build, alu, num_components); 843b8e80941Smrg} 844b8e80941Smrg 845b8e80941Smrg/** 846b8e80941Smrg * Similar to nir_ssa_for_src(), but for alu srcs, respecting the 847b8e80941Smrg * nir_alu_src's swizzle. 848b8e80941Smrg */ 849b8e80941Smrgstatic inline nir_ssa_def * 850b8e80941Smrgnir_ssa_for_alu_src(nir_builder *build, nir_alu_instr *instr, unsigned srcn) 851b8e80941Smrg{ 852b8e80941Smrg static uint8_t trivial_swizzle[NIR_MAX_VEC_COMPONENTS]; 853b8e80941Smrg for (int i = 0; i < NIR_MAX_VEC_COMPONENTS; ++i) 854b8e80941Smrg trivial_swizzle[i] = i; 855b8e80941Smrg nir_alu_src *src = &instr->src[srcn]; 856b8e80941Smrg unsigned num_components = nir_ssa_alu_instr_src_components(instr, srcn); 857b8e80941Smrg 858b8e80941Smrg if (src->src.is_ssa && (src->src.ssa->num_components == num_components) && 859b8e80941Smrg !src->abs && !src->negate && 860b8e80941Smrg (memcmp(src->swizzle, trivial_swizzle, num_components) == 0)) 861b8e80941Smrg return src->src.ssa; 862b8e80941Smrg 863b8e80941Smrg return nir_imov_alu(build, *src, num_components); 864b8e80941Smrg} 865b8e80941Smrg 866b8e80941Smrgstatic inline unsigned 867b8e80941Smrgnir_get_ptr_bitsize(nir_builder *build) 868b8e80941Smrg{ 869b8e80941Smrg if (build->shader->info.stage == MESA_SHADER_KERNEL) 870b8e80941Smrg return build->shader->info.cs.ptr_size; 871b8e80941Smrg return 32; 872b8e80941Smrg} 873b8e80941Smrg 874b8e80941Smrgstatic inline nir_deref_instr * 875b8e80941Smrgnir_build_deref_var(nir_builder *build, nir_variable *var) 876b8e80941Smrg{ 877b8e80941Smrg nir_deref_instr *deref = 878b8e80941Smrg nir_deref_instr_create(build->shader, nir_deref_type_var); 879b8e80941Smrg 880b8e80941Smrg deref->mode = var->data.mode; 881b8e80941Smrg deref->type = var->type; 882b8e80941Smrg deref->var = var; 883b8e80941Smrg 884b8e80941Smrg nir_ssa_dest_init(&deref->instr, &deref->dest, 1, 885b8e80941Smrg nir_get_ptr_bitsize(build), NULL); 886b8e80941Smrg 887b8e80941Smrg nir_builder_instr_insert(build, &deref->instr); 888b8e80941Smrg 889b8e80941Smrg return deref; 890b8e80941Smrg} 891b8e80941Smrg 892b8e80941Smrgstatic inline nir_deref_instr * 893b8e80941Smrgnir_build_deref_array(nir_builder *build, nir_deref_instr *parent, 894b8e80941Smrg nir_ssa_def *index) 895b8e80941Smrg{ 896b8e80941Smrg assert(glsl_type_is_array(parent->type) || 897b8e80941Smrg glsl_type_is_matrix(parent->type) || 898b8e80941Smrg glsl_type_is_vector(parent->type)); 899b8e80941Smrg 900b8e80941Smrg assert(index->bit_size == parent->dest.ssa.bit_size); 901b8e80941Smrg 902b8e80941Smrg nir_deref_instr *deref = 903b8e80941Smrg nir_deref_instr_create(build->shader, nir_deref_type_array); 904b8e80941Smrg 905b8e80941Smrg deref->mode = parent->mode; 906b8e80941Smrg deref->type = glsl_get_array_element(parent->type); 907b8e80941Smrg deref->parent = nir_src_for_ssa(&parent->dest.ssa); 908b8e80941Smrg deref->arr.index = nir_src_for_ssa(index); 909b8e80941Smrg 910b8e80941Smrg nir_ssa_dest_init(&deref->instr, &deref->dest, 911b8e80941Smrg parent->dest.ssa.num_components, 912b8e80941Smrg parent->dest.ssa.bit_size, NULL); 913b8e80941Smrg 914b8e80941Smrg nir_builder_instr_insert(build, &deref->instr); 915b8e80941Smrg 916b8e80941Smrg return deref; 917b8e80941Smrg} 918b8e80941Smrg 919b8e80941Smrgstatic inline nir_deref_instr * 920b8e80941Smrgnir_build_deref_array_imm(nir_builder *build, nir_deref_instr *parent, 921b8e80941Smrg int64_t index) 922b8e80941Smrg{ 923b8e80941Smrg assert(parent->dest.is_ssa); 924b8e80941Smrg nir_ssa_def *idx_ssa = nir_imm_intN_t(build, index, 925b8e80941Smrg parent->dest.ssa.bit_size); 926b8e80941Smrg 927b8e80941Smrg return nir_build_deref_array(build, parent, idx_ssa); 928b8e80941Smrg} 929b8e80941Smrg 930b8e80941Smrgstatic inline nir_deref_instr * 931b8e80941Smrgnir_build_deref_ptr_as_array(nir_builder *build, nir_deref_instr *parent, 932b8e80941Smrg nir_ssa_def *index) 933b8e80941Smrg{ 934b8e80941Smrg assert(parent->deref_type == nir_deref_type_array || 935b8e80941Smrg parent->deref_type == nir_deref_type_ptr_as_array || 936b8e80941Smrg parent->deref_type == nir_deref_type_cast); 937b8e80941Smrg 938b8e80941Smrg assert(index->bit_size == parent->dest.ssa.bit_size); 939b8e80941Smrg 940b8e80941Smrg nir_deref_instr *deref = 941b8e80941Smrg nir_deref_instr_create(build->shader, nir_deref_type_ptr_as_array); 942b8e80941Smrg 943b8e80941Smrg deref->mode = parent->mode; 944b8e80941Smrg deref->type = parent->type; 945b8e80941Smrg deref->parent = nir_src_for_ssa(&parent->dest.ssa); 946b8e80941Smrg deref->arr.index = nir_src_for_ssa(index); 947b8e80941Smrg 948b8e80941Smrg nir_ssa_dest_init(&deref->instr, &deref->dest, 949b8e80941Smrg parent->dest.ssa.num_components, 950b8e80941Smrg parent->dest.ssa.bit_size, NULL); 951b8e80941Smrg 952b8e80941Smrg nir_builder_instr_insert(build, &deref->instr); 953b8e80941Smrg 954b8e80941Smrg return deref; 955b8e80941Smrg} 956b8e80941Smrg 957b8e80941Smrgstatic inline nir_deref_instr * 958b8e80941Smrgnir_build_deref_array_wildcard(nir_builder *build, nir_deref_instr *parent) 959b8e80941Smrg{ 960b8e80941Smrg assert(glsl_type_is_array(parent->type) || 961b8e80941Smrg glsl_type_is_matrix(parent->type)); 962b8e80941Smrg 963b8e80941Smrg nir_deref_instr *deref = 964b8e80941Smrg nir_deref_instr_create(build->shader, nir_deref_type_array_wildcard); 965b8e80941Smrg 966b8e80941Smrg deref->mode = parent->mode; 967b8e80941Smrg deref->type = glsl_get_array_element(parent->type); 968b8e80941Smrg deref->parent = nir_src_for_ssa(&parent->dest.ssa); 969b8e80941Smrg 970b8e80941Smrg nir_ssa_dest_init(&deref->instr, &deref->dest, 971b8e80941Smrg parent->dest.ssa.num_components, 972b8e80941Smrg parent->dest.ssa.bit_size, NULL); 973b8e80941Smrg 974b8e80941Smrg nir_builder_instr_insert(build, &deref->instr); 975b8e80941Smrg 976b8e80941Smrg return deref; 977b8e80941Smrg} 978b8e80941Smrg 979b8e80941Smrgstatic inline nir_deref_instr * 980b8e80941Smrgnir_build_deref_struct(nir_builder *build, nir_deref_instr *parent, 981b8e80941Smrg unsigned index) 982b8e80941Smrg{ 983b8e80941Smrg assert(glsl_type_is_struct_or_ifc(parent->type)); 984b8e80941Smrg 985b8e80941Smrg nir_deref_instr *deref = 986b8e80941Smrg nir_deref_instr_create(build->shader, nir_deref_type_struct); 987b8e80941Smrg 988b8e80941Smrg deref->mode = parent->mode; 989b8e80941Smrg deref->type = glsl_get_struct_field(parent->type, index); 990b8e80941Smrg deref->parent = nir_src_for_ssa(&parent->dest.ssa); 991b8e80941Smrg deref->strct.index = index; 992b8e80941Smrg 993b8e80941Smrg nir_ssa_dest_init(&deref->instr, &deref->dest, 994b8e80941Smrg parent->dest.ssa.num_components, 995b8e80941Smrg parent->dest.ssa.bit_size, NULL); 996b8e80941Smrg 997b8e80941Smrg nir_builder_instr_insert(build, &deref->instr); 998b8e80941Smrg 999b8e80941Smrg return deref; 1000b8e80941Smrg} 1001b8e80941Smrg 1002b8e80941Smrgstatic inline nir_deref_instr * 1003b8e80941Smrgnir_build_deref_cast(nir_builder *build, nir_ssa_def *parent, 1004b8e80941Smrg nir_variable_mode mode, const struct glsl_type *type, 1005b8e80941Smrg unsigned ptr_stride) 1006b8e80941Smrg{ 1007b8e80941Smrg nir_deref_instr *deref = 1008b8e80941Smrg nir_deref_instr_create(build->shader, nir_deref_type_cast); 1009b8e80941Smrg 1010b8e80941Smrg deref->mode = mode; 1011b8e80941Smrg deref->type = type; 1012b8e80941Smrg deref->parent = nir_src_for_ssa(parent); 1013b8e80941Smrg deref->cast.ptr_stride = ptr_stride; 1014b8e80941Smrg 1015b8e80941Smrg nir_ssa_dest_init(&deref->instr, &deref->dest, 1016b8e80941Smrg parent->num_components, parent->bit_size, NULL); 1017b8e80941Smrg 1018b8e80941Smrg nir_builder_instr_insert(build, &deref->instr); 1019b8e80941Smrg 1020b8e80941Smrg return deref; 1021b8e80941Smrg} 1022b8e80941Smrg 1023b8e80941Smrg/** Returns a deref that follows another but starting from the given parent 1024b8e80941Smrg * 1025b8e80941Smrg * The new deref will be the same type and take the same array or struct index 1026b8e80941Smrg * as the leader deref but it may have a different parent. This is very 1027b8e80941Smrg * useful for walking deref paths. 1028b8e80941Smrg */ 1029b8e80941Smrgstatic inline nir_deref_instr * 1030b8e80941Smrgnir_build_deref_follower(nir_builder *b, nir_deref_instr *parent, 1031b8e80941Smrg nir_deref_instr *leader) 1032b8e80941Smrg{ 1033b8e80941Smrg /* If the derefs would have the same parent, don't make a new one */ 1034b8e80941Smrg assert(leader->parent.is_ssa); 1035b8e80941Smrg if (leader->parent.ssa == &parent->dest.ssa) 1036b8e80941Smrg return leader; 1037b8e80941Smrg 1038b8e80941Smrg UNUSED nir_deref_instr *leader_parent = nir_src_as_deref(leader->parent); 1039b8e80941Smrg 1040b8e80941Smrg switch (leader->deref_type) { 1041b8e80941Smrg case nir_deref_type_var: 1042b8e80941Smrg unreachable("A var dereference cannot have a parent"); 1043b8e80941Smrg break; 1044b8e80941Smrg 1045b8e80941Smrg case nir_deref_type_array: 1046b8e80941Smrg case nir_deref_type_array_wildcard: 1047b8e80941Smrg assert(glsl_type_is_matrix(parent->type) || 1048b8e80941Smrg glsl_type_is_array(parent->type) || 1049b8e80941Smrg (leader->deref_type == nir_deref_type_array && 1050b8e80941Smrg glsl_type_is_vector(parent->type))); 1051b8e80941Smrg assert(glsl_get_length(parent->type) == 1052b8e80941Smrg glsl_get_length(leader_parent->type)); 1053b8e80941Smrg 1054b8e80941Smrg if (leader->deref_type == nir_deref_type_array) { 1055b8e80941Smrg assert(leader->arr.index.is_ssa); 1056b8e80941Smrg nir_ssa_def *index = nir_i2i(b, leader->arr.index.ssa, 1057b8e80941Smrg parent->dest.ssa.bit_size); 1058b8e80941Smrg return nir_build_deref_array(b, parent, index); 1059b8e80941Smrg } else { 1060b8e80941Smrg return nir_build_deref_array_wildcard(b, parent); 1061b8e80941Smrg } 1062b8e80941Smrg 1063b8e80941Smrg case nir_deref_type_struct: 1064b8e80941Smrg assert(glsl_type_is_struct_or_ifc(parent->type)); 1065b8e80941Smrg assert(glsl_get_length(parent->type) == 1066b8e80941Smrg glsl_get_length(leader_parent->type)); 1067b8e80941Smrg 1068b8e80941Smrg return nir_build_deref_struct(b, parent, leader->strct.index); 1069b8e80941Smrg 1070b8e80941Smrg default: 1071b8e80941Smrg unreachable("Invalid deref instruction type"); 1072b8e80941Smrg } 1073b8e80941Smrg} 1074b8e80941Smrg 1075b8e80941Smrgstatic inline nir_ssa_def * 1076b8e80941Smrgnir_load_reg(nir_builder *build, nir_register *reg) 1077b8e80941Smrg{ 1078b8e80941Smrg return nir_ssa_for_src(build, nir_src_for_reg(reg), reg->num_components); 1079b8e80941Smrg} 1080b8e80941Smrg 1081b8e80941Smrgstatic inline nir_ssa_def * 1082b8e80941Smrgnir_load_deref_with_access(nir_builder *build, nir_deref_instr *deref, 1083b8e80941Smrg enum gl_access_qualifier access) 1084b8e80941Smrg{ 1085b8e80941Smrg nir_intrinsic_instr *load = 1086b8e80941Smrg nir_intrinsic_instr_create(build->shader, nir_intrinsic_load_deref); 1087b8e80941Smrg load->num_components = glsl_get_vector_elements(deref->type); 1088b8e80941Smrg load->src[0] = nir_src_for_ssa(&deref->dest.ssa); 1089b8e80941Smrg nir_ssa_dest_init(&load->instr, &load->dest, load->num_components, 1090b8e80941Smrg glsl_get_bit_size(deref->type), NULL); 1091b8e80941Smrg nir_intrinsic_set_access(load, access); 1092b8e80941Smrg nir_builder_instr_insert(build, &load->instr); 1093b8e80941Smrg return &load->dest.ssa; 1094b8e80941Smrg} 1095b8e80941Smrg 1096b8e80941Smrgstatic inline nir_ssa_def * 1097b8e80941Smrgnir_load_deref(nir_builder *build, nir_deref_instr *deref) 1098b8e80941Smrg{ 1099b8e80941Smrg return nir_load_deref_with_access(build, deref, (enum gl_access_qualifier)0); 1100b8e80941Smrg} 1101b8e80941Smrg 1102b8e80941Smrgstatic inline void 1103b8e80941Smrgnir_store_deref_with_access(nir_builder *build, nir_deref_instr *deref, 1104b8e80941Smrg nir_ssa_def *value, unsigned writemask, 1105b8e80941Smrg enum gl_access_qualifier access) 1106b8e80941Smrg{ 1107b8e80941Smrg nir_intrinsic_instr *store = 1108b8e80941Smrg nir_intrinsic_instr_create(build->shader, nir_intrinsic_store_deref); 1109b8e80941Smrg store->num_components = glsl_get_vector_elements(deref->type); 1110b8e80941Smrg store->src[0] = nir_src_for_ssa(&deref->dest.ssa); 1111b8e80941Smrg store->src[1] = nir_src_for_ssa(value); 1112b8e80941Smrg nir_intrinsic_set_write_mask(store, 1113b8e80941Smrg writemask & ((1 << store->num_components) - 1)); 1114b8e80941Smrg nir_intrinsic_set_access(store, access); 1115b8e80941Smrg nir_builder_instr_insert(build, &store->instr); 1116b8e80941Smrg} 1117b8e80941Smrg 1118b8e80941Smrgstatic inline void 1119b8e80941Smrgnir_store_deref(nir_builder *build, nir_deref_instr *deref, 1120b8e80941Smrg nir_ssa_def *value, unsigned writemask) 1121b8e80941Smrg{ 1122b8e80941Smrg nir_store_deref_with_access(build, deref, value, writemask, 1123b8e80941Smrg (enum gl_access_qualifier)0); 1124b8e80941Smrg} 1125b8e80941Smrg 1126b8e80941Smrgstatic inline void 1127b8e80941Smrgnir_copy_deref_with_access(nir_builder *build, nir_deref_instr *dest, 1128b8e80941Smrg nir_deref_instr *src, 1129b8e80941Smrg enum gl_access_qualifier dest_access, 1130b8e80941Smrg enum gl_access_qualifier src_access) 1131b8e80941Smrg{ 1132b8e80941Smrg nir_intrinsic_instr *copy = 1133b8e80941Smrg nir_intrinsic_instr_create(build->shader, nir_intrinsic_copy_deref); 1134b8e80941Smrg copy->src[0] = nir_src_for_ssa(&dest->dest.ssa); 1135b8e80941Smrg copy->src[1] = nir_src_for_ssa(&src->dest.ssa); 1136b8e80941Smrg nir_intrinsic_set_dst_access(copy, dest_access); 1137b8e80941Smrg nir_intrinsic_set_src_access(copy, src_access); 1138b8e80941Smrg nir_builder_instr_insert(build, ©->instr); 1139b8e80941Smrg} 1140b8e80941Smrg 1141b8e80941Smrgstatic inline void 1142b8e80941Smrgnir_copy_deref(nir_builder *build, nir_deref_instr *dest, nir_deref_instr *src) 1143b8e80941Smrg{ 1144b8e80941Smrg nir_copy_deref_with_access(build, dest, src, 1145b8e80941Smrg (enum gl_access_qualifier) 0, 1146b8e80941Smrg (enum gl_access_qualifier) 0); 1147b8e80941Smrg} 1148b8e80941Smrg 1149b8e80941Smrgstatic inline nir_ssa_def * 1150b8e80941Smrgnir_load_var(nir_builder *build, nir_variable *var) 1151b8e80941Smrg{ 1152b8e80941Smrg return nir_load_deref(build, nir_build_deref_var(build, var)); 1153b8e80941Smrg} 1154b8e80941Smrg 1155b8e80941Smrgstatic inline void 1156b8e80941Smrgnir_store_var(nir_builder *build, nir_variable *var, nir_ssa_def *value, 1157b8e80941Smrg unsigned writemask) 1158b8e80941Smrg{ 1159b8e80941Smrg nir_store_deref(build, nir_build_deref_var(build, var), value, writemask); 1160b8e80941Smrg} 1161b8e80941Smrg 1162b8e80941Smrgstatic inline void 1163b8e80941Smrgnir_copy_var(nir_builder *build, nir_variable *dest, nir_variable *src) 1164b8e80941Smrg{ 1165b8e80941Smrg nir_copy_deref(build, nir_build_deref_var(build, dest), 1166b8e80941Smrg nir_build_deref_var(build, src)); 1167b8e80941Smrg} 1168b8e80941Smrg 1169b8e80941Smrgstatic inline nir_ssa_def * 1170b8e80941Smrgnir_load_param(nir_builder *build, uint32_t param_idx) 1171b8e80941Smrg{ 1172b8e80941Smrg assert(param_idx < build->impl->function->num_params); 1173b8e80941Smrg nir_parameter *param = &build->impl->function->params[param_idx]; 1174b8e80941Smrg 1175b8e80941Smrg nir_intrinsic_instr *load = 1176b8e80941Smrg nir_intrinsic_instr_create(build->shader, nir_intrinsic_load_param); 1177b8e80941Smrg nir_intrinsic_set_param_idx(load, param_idx); 1178b8e80941Smrg load->num_components = param->num_components; 1179b8e80941Smrg nir_ssa_dest_init(&load->instr, &load->dest, 1180b8e80941Smrg param->num_components, param->bit_size, NULL); 1181b8e80941Smrg nir_builder_instr_insert(build, &load->instr); 1182b8e80941Smrg return &load->dest.ssa; 1183b8e80941Smrg} 1184b8e80941Smrg 1185b8e80941Smrg#include "nir_builder_opcodes.h" 1186b8e80941Smrg 1187b8e80941Smrgstatic inline nir_ssa_def * 1188b8e80941Smrgnir_f2b(nir_builder *build, nir_ssa_def *f) 1189b8e80941Smrg{ 1190b8e80941Smrg return nir_f2b1(build, f); 1191b8e80941Smrg} 1192b8e80941Smrg 1193b8e80941Smrgstatic inline nir_ssa_def * 1194b8e80941Smrgnir_i2b(nir_builder *build, nir_ssa_def *i) 1195b8e80941Smrg{ 1196b8e80941Smrg return nir_i2b1(build, i); 1197b8e80941Smrg} 1198b8e80941Smrg 1199b8e80941Smrgstatic inline nir_ssa_def * 1200b8e80941Smrgnir_b2f(nir_builder *build, nir_ssa_def *b, uint32_t bit_size) 1201b8e80941Smrg{ 1202b8e80941Smrg switch (bit_size) { 1203b8e80941Smrg case 64: return nir_b2f64(build, b); 1204b8e80941Smrg case 32: return nir_b2f32(build, b); 1205b8e80941Smrg case 16: return nir_b2f16(build, b); 1206b8e80941Smrg default: 1207b8e80941Smrg unreachable("Invalid bit-size"); 1208b8e80941Smrg }; 1209b8e80941Smrg} 1210b8e80941Smrg 1211b8e80941Smrgstatic inline nir_ssa_def * 1212b8e80941Smrgnir_load_barycentric(nir_builder *build, nir_intrinsic_op op, 1213b8e80941Smrg unsigned interp_mode) 1214b8e80941Smrg{ 1215b8e80941Smrg nir_intrinsic_instr *bary = nir_intrinsic_instr_create(build->shader, op); 1216b8e80941Smrg nir_ssa_dest_init(&bary->instr, &bary->dest, 2, 32, NULL); 1217b8e80941Smrg nir_intrinsic_set_interp_mode(bary, interp_mode); 1218b8e80941Smrg nir_builder_instr_insert(build, &bary->instr); 1219b8e80941Smrg return &bary->dest.ssa; 1220b8e80941Smrg} 1221b8e80941Smrg 1222b8e80941Smrgstatic inline void 1223b8e80941Smrgnir_jump(nir_builder *build, nir_jump_type jump_type) 1224b8e80941Smrg{ 1225b8e80941Smrg nir_jump_instr *jump = nir_jump_instr_create(build->shader, jump_type); 1226b8e80941Smrg nir_builder_instr_insert(build, &jump->instr); 1227b8e80941Smrg} 1228b8e80941Smrg 1229b8e80941Smrgstatic inline nir_ssa_def * 1230b8e80941Smrgnir_compare_func(nir_builder *b, enum compare_func func, 1231b8e80941Smrg nir_ssa_def *src0, nir_ssa_def *src1) 1232b8e80941Smrg{ 1233b8e80941Smrg switch (func) { 1234b8e80941Smrg case COMPARE_FUNC_NEVER: 1235b8e80941Smrg return nir_imm_int(b, 0); 1236b8e80941Smrg case COMPARE_FUNC_ALWAYS: 1237b8e80941Smrg return nir_imm_int(b, ~0); 1238b8e80941Smrg case COMPARE_FUNC_EQUAL: 1239b8e80941Smrg return nir_feq(b, src0, src1); 1240b8e80941Smrg case COMPARE_FUNC_NOTEQUAL: 1241b8e80941Smrg return nir_fne(b, src0, src1); 1242b8e80941Smrg case COMPARE_FUNC_GREATER: 1243b8e80941Smrg return nir_flt(b, src1, src0); 1244b8e80941Smrg case COMPARE_FUNC_GEQUAL: 1245b8e80941Smrg return nir_fge(b, src0, src1); 1246b8e80941Smrg case COMPARE_FUNC_LESS: 1247b8e80941Smrg return nir_flt(b, src0, src1); 1248b8e80941Smrg case COMPARE_FUNC_LEQUAL: 1249b8e80941Smrg return nir_fge(b, src1, src0); 1250b8e80941Smrg } 1251b8e80941Smrg unreachable("bad compare func"); 1252b8e80941Smrg} 1253b8e80941Smrg 1254b8e80941Smrg#endif /* NIR_BUILDER_H */ 1255