nir_builder.h revision 01e04c3f
1/* 2 * Copyright © 2014-2015 Broadcom 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#ifndef NIR_BUILDER_H 25#define NIR_BUILDER_H 26 27#include "nir_control_flow.h" 28#include "util/half_float.h" 29 30struct exec_list; 31 32typedef struct nir_builder { 33 nir_cursor cursor; 34 35 /* Whether new ALU instructions will be marked "exact" */ 36 bool exact; 37 38 nir_shader *shader; 39 nir_function_impl *impl; 40} nir_builder; 41 42static inline void 43nir_builder_init(nir_builder *build, nir_function_impl *impl) 44{ 45 memset(build, 0, sizeof(*build)); 46 build->exact = false; 47 build->impl = impl; 48 build->shader = impl->function->shader; 49} 50 51static inline void 52nir_builder_init_simple_shader(nir_builder *build, void *mem_ctx, 53 gl_shader_stage stage, 54 const nir_shader_compiler_options *options) 55{ 56 build->shader = nir_shader_create(mem_ctx, stage, options, NULL); 57 nir_function *func = nir_function_create(build->shader, "main"); 58 build->exact = false; 59 build->impl = nir_function_impl_create(func); 60 build->cursor = nir_after_cf_list(&build->impl->body); 61} 62 63static inline void 64nir_builder_instr_insert(nir_builder *build, nir_instr *instr) 65{ 66 nir_instr_insert(build->cursor, instr); 67 68 /* Move the cursor forward. */ 69 build->cursor = nir_after_instr(instr); 70} 71 72static inline nir_instr * 73nir_builder_last_instr(nir_builder *build) 74{ 75 assert(build->cursor.option == nir_cursor_after_instr); 76 return build->cursor.instr; 77} 78 79static inline void 80nir_builder_cf_insert(nir_builder *build, nir_cf_node *cf) 81{ 82 nir_cf_node_insert(build->cursor, cf); 83} 84 85static inline bool 86nir_builder_is_inside_cf(nir_builder *build, nir_cf_node *cf_node) 87{ 88 nir_block *block = nir_cursor_current_block(build->cursor); 89 for (nir_cf_node *n = &block->cf_node; n; n = n->parent) { 90 if (n == cf_node) 91 return true; 92 } 93 return false; 94} 95 96static inline nir_if * 97nir_push_if(nir_builder *build, nir_ssa_def *condition) 98{ 99 nir_if *nif = nir_if_create(build->shader); 100 nif->condition = nir_src_for_ssa(condition); 101 nir_builder_cf_insert(build, &nif->cf_node); 102 build->cursor = nir_before_cf_list(&nif->then_list); 103 return nif; 104} 105 106static inline nir_if * 107nir_push_else(nir_builder *build, nir_if *nif) 108{ 109 if (nif) { 110 assert(nir_builder_is_inside_cf(build, &nif->cf_node)); 111 } else { 112 nir_block *block = nir_cursor_current_block(build->cursor); 113 nif = nir_cf_node_as_if(block->cf_node.parent); 114 } 115 build->cursor = nir_before_cf_list(&nif->else_list); 116 return nif; 117} 118 119static inline void 120nir_pop_if(nir_builder *build, nir_if *nif) 121{ 122 if (nif) { 123 assert(nir_builder_is_inside_cf(build, &nif->cf_node)); 124 } else { 125 nir_block *block = nir_cursor_current_block(build->cursor); 126 nif = nir_cf_node_as_if(block->cf_node.parent); 127 } 128 build->cursor = nir_after_cf_node(&nif->cf_node); 129} 130 131static inline nir_ssa_def * 132nir_if_phi(nir_builder *build, nir_ssa_def *then_def, nir_ssa_def *else_def) 133{ 134 nir_block *block = nir_cursor_current_block(build->cursor); 135 nir_if *nif = nir_cf_node_as_if(nir_cf_node_prev(&block->cf_node)); 136 137 nir_phi_instr *phi = nir_phi_instr_create(build->shader); 138 139 nir_phi_src *src = ralloc(phi, nir_phi_src); 140 src->pred = nir_if_last_then_block(nif); 141 src->src = nir_src_for_ssa(then_def); 142 exec_list_push_tail(&phi->srcs, &src->node); 143 144 src = ralloc(phi, nir_phi_src); 145 src->pred = nir_if_last_else_block(nif); 146 src->src = nir_src_for_ssa(else_def); 147 exec_list_push_tail(&phi->srcs, &src->node); 148 149 assert(then_def->num_components == else_def->num_components); 150 assert(then_def->bit_size == else_def->bit_size); 151 nir_ssa_dest_init(&phi->instr, &phi->dest, 152 then_def->num_components, then_def->bit_size, NULL); 153 154 nir_builder_instr_insert(build, &phi->instr); 155 156 return &phi->dest.ssa; 157} 158 159static inline nir_loop * 160nir_push_loop(nir_builder *build) 161{ 162 nir_loop *loop = nir_loop_create(build->shader); 163 nir_builder_cf_insert(build, &loop->cf_node); 164 build->cursor = nir_before_cf_list(&loop->body); 165 return loop; 166} 167 168static inline void 169nir_pop_loop(nir_builder *build, nir_loop *loop) 170{ 171 if (loop) { 172 assert(nir_builder_is_inside_cf(build, &loop->cf_node)); 173 } else { 174 nir_block *block = nir_cursor_current_block(build->cursor); 175 loop = nir_cf_node_as_loop(block->cf_node.parent); 176 } 177 build->cursor = nir_after_cf_node(&loop->cf_node); 178} 179 180static inline nir_ssa_def * 181nir_ssa_undef(nir_builder *build, unsigned num_components, unsigned bit_size) 182{ 183 nir_ssa_undef_instr *undef = 184 nir_ssa_undef_instr_create(build->shader, num_components, bit_size); 185 if (!undef) 186 return NULL; 187 188 nir_instr_insert(nir_before_cf_list(&build->impl->body), &undef->instr); 189 190 return &undef->def; 191} 192 193static inline nir_ssa_def * 194nir_build_imm(nir_builder *build, unsigned num_components, 195 unsigned bit_size, nir_const_value value) 196{ 197 nir_load_const_instr *load_const = 198 nir_load_const_instr_create(build->shader, num_components, bit_size); 199 if (!load_const) 200 return NULL; 201 202 load_const->value = value; 203 204 nir_builder_instr_insert(build, &load_const->instr); 205 206 return &load_const->def; 207} 208 209static inline nir_ssa_def * 210nir_imm_bool(nir_builder *build, bool x) 211{ 212 nir_const_value v; 213 214 memset(&v, 0, sizeof(v)); 215 v.u32[0] = x ? NIR_TRUE : NIR_FALSE; 216 217 return nir_build_imm(build, 1, 32, v); 218} 219 220static inline nir_ssa_def * 221nir_imm_true(nir_builder *build) 222{ 223 return nir_imm_bool(build, true); 224} 225 226static inline nir_ssa_def * 227nir_imm_false(nir_builder *build) 228{ 229 return nir_imm_bool(build, false); 230} 231 232static inline nir_ssa_def * 233nir_imm_float16(nir_builder *build, float x) 234{ 235 nir_const_value v; 236 237 memset(&v, 0, sizeof(v)); 238 v.u16[0] = _mesa_float_to_half(x); 239 240 return nir_build_imm(build, 1, 16, v); 241} 242 243static inline nir_ssa_def * 244nir_imm_float(nir_builder *build, float x) 245{ 246 nir_const_value v; 247 248 memset(&v, 0, sizeof(v)); 249 v.f32[0] = x; 250 251 return nir_build_imm(build, 1, 32, v); 252} 253 254static inline nir_ssa_def * 255nir_imm_double(nir_builder *build, double x) 256{ 257 nir_const_value v; 258 259 memset(&v, 0, sizeof(v)); 260 v.f64[0] = x; 261 262 return nir_build_imm(build, 1, 64, v); 263} 264 265static inline nir_ssa_def * 266nir_imm_floatN_t(nir_builder *build, double x, unsigned bit_size) 267{ 268 switch (bit_size) { 269 case 16: 270 return nir_imm_float16(build, x); 271 case 32: 272 return nir_imm_float(build, x); 273 case 64: 274 return nir_imm_double(build, x); 275 } 276 277 unreachable("unknown float immediate bit size"); 278} 279 280static inline nir_ssa_def * 281nir_imm_vec4(nir_builder *build, float x, float y, float z, float w) 282{ 283 nir_const_value v; 284 285 memset(&v, 0, sizeof(v)); 286 v.f32[0] = x; 287 v.f32[1] = y; 288 v.f32[2] = z; 289 v.f32[3] = w; 290 291 return nir_build_imm(build, 4, 32, v); 292} 293 294static inline nir_ssa_def * 295nir_imm_ivec2(nir_builder *build, int x, int y) 296{ 297 nir_const_value v; 298 299 memset(&v, 0, sizeof(v)); 300 v.i32[0] = x; 301 v.i32[1] = y; 302 303 return nir_build_imm(build, 2, 32, v); 304} 305 306static inline nir_ssa_def * 307nir_imm_int(nir_builder *build, int x) 308{ 309 nir_const_value v; 310 311 memset(&v, 0, sizeof(v)); 312 v.i32[0] = x; 313 314 return nir_build_imm(build, 1, 32, v); 315} 316 317static inline nir_ssa_def * 318nir_imm_int64(nir_builder *build, int64_t x) 319{ 320 nir_const_value v; 321 322 memset(&v, 0, sizeof(v)); 323 v.i64[0] = x; 324 325 return nir_build_imm(build, 1, 64, v); 326} 327 328static inline nir_ssa_def * 329nir_imm_intN_t(nir_builder *build, uint64_t x, unsigned bit_size) 330{ 331 nir_const_value v; 332 333 memset(&v, 0, sizeof(v)); 334 assert(bit_size <= 64); 335 v.i64[0] = x & (~0ull >> (64 - bit_size)); 336 337 return nir_build_imm(build, 1, bit_size, v); 338} 339 340static inline nir_ssa_def * 341nir_imm_ivec4(nir_builder *build, int x, int y, int z, int w) 342{ 343 nir_const_value v; 344 345 memset(&v, 0, sizeof(v)); 346 v.i32[0] = x; 347 v.i32[1] = y; 348 v.i32[2] = z; 349 v.i32[3] = w; 350 351 return nir_build_imm(build, 4, 32, v); 352} 353 354static inline nir_ssa_def * 355nir_build_alu(nir_builder *build, nir_op op, nir_ssa_def *src0, 356 nir_ssa_def *src1, nir_ssa_def *src2, nir_ssa_def *src3) 357{ 358 const nir_op_info *op_info = &nir_op_infos[op]; 359 nir_alu_instr *instr = nir_alu_instr_create(build->shader, op); 360 if (!instr) 361 return NULL; 362 363 instr->exact = build->exact; 364 365 instr->src[0].src = nir_src_for_ssa(src0); 366 if (src1) 367 instr->src[1].src = nir_src_for_ssa(src1); 368 if (src2) 369 instr->src[2].src = nir_src_for_ssa(src2); 370 if (src3) 371 instr->src[3].src = nir_src_for_ssa(src3); 372 373 /* Guess the number of components the destination temporary should have 374 * based on our input sizes, if it's not fixed for the op. 375 */ 376 unsigned num_components = op_info->output_size; 377 if (num_components == 0) { 378 for (unsigned i = 0; i < op_info->num_inputs; i++) { 379 if (op_info->input_sizes[i] == 0) 380 num_components = MAX2(num_components, 381 instr->src[i].src.ssa->num_components); 382 } 383 } 384 assert(num_components != 0); 385 386 /* Figure out the bitwidth based on the source bitwidth if the instruction 387 * is variable-width. 388 */ 389 unsigned bit_size = nir_alu_type_get_type_size(op_info->output_type); 390 if (bit_size == 0) { 391 for (unsigned i = 0; i < op_info->num_inputs; i++) { 392 unsigned src_bit_size = instr->src[i].src.ssa->bit_size; 393 if (nir_alu_type_get_type_size(op_info->input_types[i]) == 0) { 394 if (bit_size) 395 assert(src_bit_size == bit_size); 396 else 397 bit_size = src_bit_size; 398 } else { 399 assert(src_bit_size == 400 nir_alu_type_get_type_size(op_info->input_types[i])); 401 } 402 } 403 } 404 405 /* When in doubt, assume 32. */ 406 if (bit_size == 0) 407 bit_size = 32; 408 409 /* Make sure we don't swizzle from outside of our source vector (like if a 410 * scalar value was passed into a multiply with a vector). 411 */ 412 for (unsigned i = 0; i < op_info->num_inputs; i++) { 413 for (unsigned j = instr->src[i].src.ssa->num_components; 414 j < NIR_MAX_VEC_COMPONENTS; j++) { 415 instr->src[i].swizzle[j] = instr->src[i].src.ssa->num_components - 1; 416 } 417 } 418 419 nir_ssa_dest_init(&instr->instr, &instr->dest.dest, num_components, 420 bit_size, NULL); 421 instr->dest.write_mask = (1 << num_components) - 1; 422 423 nir_builder_instr_insert(build, &instr->instr); 424 425 return &instr->dest.dest.ssa; 426} 427 428#include "nir_builder_opcodes.h" 429 430static inline nir_ssa_def * 431nir_vec(nir_builder *build, nir_ssa_def **comp, unsigned num_components) 432{ 433 switch (num_components) { 434 case 4: 435 return nir_vec4(build, comp[0], comp[1], comp[2], comp[3]); 436 case 3: 437 return nir_vec3(build, comp[0], comp[1], comp[2]); 438 case 2: 439 return nir_vec2(build, comp[0], comp[1]); 440 case 1: 441 return comp[0]; 442 default: 443 unreachable("bad component count"); 444 return NULL; 445 } 446} 447 448/** 449 * Similar to nir_fmov, but takes a nir_alu_src instead of a nir_ssa_def. 450 */ 451static inline nir_ssa_def * 452nir_fmov_alu(nir_builder *build, nir_alu_src src, unsigned num_components) 453{ 454 nir_alu_instr *mov = nir_alu_instr_create(build->shader, nir_op_fmov); 455 nir_ssa_dest_init(&mov->instr, &mov->dest.dest, num_components, 456 nir_src_bit_size(src.src), NULL); 457 mov->exact = build->exact; 458 mov->dest.write_mask = (1 << num_components) - 1; 459 mov->src[0] = src; 460 nir_builder_instr_insert(build, &mov->instr); 461 462 return &mov->dest.dest.ssa; 463} 464 465static inline nir_ssa_def * 466nir_imov_alu(nir_builder *build, nir_alu_src src, unsigned num_components) 467{ 468 nir_alu_instr *mov = nir_alu_instr_create(build->shader, nir_op_imov); 469 nir_ssa_dest_init(&mov->instr, &mov->dest.dest, num_components, 470 nir_src_bit_size(src.src), NULL); 471 mov->exact = build->exact; 472 mov->dest.write_mask = (1 << num_components) - 1; 473 mov->src[0] = src; 474 nir_builder_instr_insert(build, &mov->instr); 475 476 return &mov->dest.dest.ssa; 477} 478 479/** 480 * Construct an fmov or imov that reswizzles the source's components. 481 */ 482static inline nir_ssa_def * 483nir_swizzle(nir_builder *build, nir_ssa_def *src, const unsigned *swiz, 484 unsigned num_components, bool use_fmov) 485{ 486 assert(num_components <= NIR_MAX_VEC_COMPONENTS); 487 nir_alu_src alu_src = { NIR_SRC_INIT }; 488 alu_src.src = nir_src_for_ssa(src); 489 for (unsigned i = 0; i < num_components && i < NIR_MAX_VEC_COMPONENTS; i++) 490 alu_src.swizzle[i] = swiz[i]; 491 492 return use_fmov ? nir_fmov_alu(build, alu_src, num_components) : 493 nir_imov_alu(build, alu_src, num_components); 494} 495 496/* Selects the right fdot given the number of components in each source. */ 497static inline nir_ssa_def * 498nir_fdot(nir_builder *build, nir_ssa_def *src0, nir_ssa_def *src1) 499{ 500 assert(src0->num_components == src1->num_components); 501 switch (src0->num_components) { 502 case 1: return nir_fmul(build, src0, src1); 503 case 2: return nir_fdot2(build, src0, src1); 504 case 3: return nir_fdot3(build, src0, src1); 505 case 4: return nir_fdot4(build, src0, src1); 506 default: 507 unreachable("bad component size"); 508 } 509 510 return NULL; 511} 512 513static inline nir_ssa_def * 514nir_bany_inequal(nir_builder *b, nir_ssa_def *src0, nir_ssa_def *src1) 515{ 516 switch (src0->num_components) { 517 case 1: return nir_ine(b, src0, src1); 518 case 2: return nir_bany_inequal2(b, src0, src1); 519 case 3: return nir_bany_inequal3(b, src0, src1); 520 case 4: return nir_bany_inequal4(b, src0, src1); 521 default: 522 unreachable("bad component size"); 523 } 524} 525 526static inline nir_ssa_def * 527nir_bany(nir_builder *b, nir_ssa_def *src) 528{ 529 return nir_bany_inequal(b, src, nir_imm_false(b)); 530} 531 532static inline nir_ssa_def * 533nir_channel(nir_builder *b, nir_ssa_def *def, unsigned c) 534{ 535 return nir_swizzle(b, def, &c, 1, false); 536} 537 538static inline nir_ssa_def * 539nir_channels(nir_builder *b, nir_ssa_def *def, nir_component_mask_t mask) 540{ 541 unsigned num_channels = 0, swizzle[NIR_MAX_VEC_COMPONENTS] = { 0 }; 542 543 for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) { 544 if ((mask & (1 << i)) == 0) 545 continue; 546 swizzle[num_channels++] = i; 547 } 548 549 return nir_swizzle(b, def, swizzle, num_channels, false); 550} 551 552/** 553 * Turns a nir_src into a nir_ssa_def * so it can be passed to 554 * nir_build_alu()-based builder calls. 555 * 556 * See nir_ssa_for_alu_src() for alu instructions. 557 */ 558static inline nir_ssa_def * 559nir_ssa_for_src(nir_builder *build, nir_src src, int num_components) 560{ 561 if (src.is_ssa && src.ssa->num_components == num_components) 562 return src.ssa; 563 564 nir_alu_src alu = { NIR_SRC_INIT }; 565 alu.src = src; 566 for (int j = 0; j < 4; j++) 567 alu.swizzle[j] = j; 568 569 return nir_imov_alu(build, alu, num_components); 570} 571 572/** 573 * Similar to nir_ssa_for_src(), but for alu srcs, respecting the 574 * nir_alu_src's swizzle. 575 */ 576static inline nir_ssa_def * 577nir_ssa_for_alu_src(nir_builder *build, nir_alu_instr *instr, unsigned srcn) 578{ 579 static uint8_t trivial_swizzle[NIR_MAX_VEC_COMPONENTS]; 580 for (int i = 0; i < NIR_MAX_VEC_COMPONENTS; ++i) 581 trivial_swizzle[i] = i; 582 nir_alu_src *src = &instr->src[srcn]; 583 unsigned num_components = nir_ssa_alu_instr_src_components(instr, srcn); 584 585 if (src->src.is_ssa && (src->src.ssa->num_components == num_components) && 586 !src->abs && !src->negate && 587 (memcmp(src->swizzle, trivial_swizzle, num_components) == 0)) 588 return src->src.ssa; 589 590 return nir_imov_alu(build, *src, num_components); 591} 592 593static inline nir_deref_instr * 594nir_build_deref_var(nir_builder *build, nir_variable *var) 595{ 596 nir_deref_instr *deref = 597 nir_deref_instr_create(build->shader, nir_deref_type_var); 598 599 deref->mode = var->data.mode; 600 deref->type = var->type; 601 deref->var = var; 602 603 nir_ssa_dest_init(&deref->instr, &deref->dest, 1, 32, NULL); 604 605 nir_builder_instr_insert(build, &deref->instr); 606 607 return deref; 608} 609 610static inline nir_deref_instr * 611nir_build_deref_array(nir_builder *build, nir_deref_instr *parent, 612 nir_ssa_def *index) 613{ 614 assert(glsl_type_is_array(parent->type) || 615 glsl_type_is_matrix(parent->type) || 616 glsl_type_is_vector(parent->type)); 617 618 nir_deref_instr *deref = 619 nir_deref_instr_create(build->shader, nir_deref_type_array); 620 621 deref->mode = parent->mode; 622 deref->type = glsl_get_array_element(parent->type); 623 deref->parent = nir_src_for_ssa(&parent->dest.ssa); 624 deref->arr.index = nir_src_for_ssa(index); 625 626 nir_ssa_dest_init(&deref->instr, &deref->dest, 627 parent->dest.ssa.num_components, 628 parent->dest.ssa.bit_size, NULL); 629 630 nir_builder_instr_insert(build, &deref->instr); 631 632 return deref; 633} 634 635static inline nir_deref_instr * 636nir_build_deref_array_wildcard(nir_builder *build, nir_deref_instr *parent) 637{ 638 assert(glsl_type_is_array(parent->type) || 639 glsl_type_is_matrix(parent->type)); 640 641 nir_deref_instr *deref = 642 nir_deref_instr_create(build->shader, nir_deref_type_array_wildcard); 643 644 deref->mode = parent->mode; 645 deref->type = glsl_get_array_element(parent->type); 646 deref->parent = nir_src_for_ssa(&parent->dest.ssa); 647 648 nir_ssa_dest_init(&deref->instr, &deref->dest, 649 parent->dest.ssa.num_components, 650 parent->dest.ssa.bit_size, NULL); 651 652 nir_builder_instr_insert(build, &deref->instr); 653 654 return deref; 655} 656 657static inline nir_deref_instr * 658nir_build_deref_struct(nir_builder *build, nir_deref_instr *parent, 659 unsigned index) 660{ 661 assert(glsl_type_is_struct(parent->type)); 662 663 nir_deref_instr *deref = 664 nir_deref_instr_create(build->shader, nir_deref_type_struct); 665 666 deref->mode = parent->mode; 667 deref->type = glsl_get_struct_field(parent->type, index); 668 deref->parent = nir_src_for_ssa(&parent->dest.ssa); 669 deref->strct.index = index; 670 671 nir_ssa_dest_init(&deref->instr, &deref->dest, 672 parent->dest.ssa.num_components, 673 parent->dest.ssa.bit_size, NULL); 674 675 nir_builder_instr_insert(build, &deref->instr); 676 677 return deref; 678} 679 680static inline nir_deref_instr * 681nir_build_deref_cast(nir_builder *build, nir_ssa_def *parent, 682 nir_variable_mode mode, const struct glsl_type *type) 683{ 684 nir_deref_instr *deref = 685 nir_deref_instr_create(build->shader, nir_deref_type_cast); 686 687 deref->mode = mode; 688 deref->type = type; 689 deref->parent = nir_src_for_ssa(parent); 690 691 nir_ssa_dest_init(&deref->instr, &deref->dest, 692 parent->num_components, parent->bit_size, NULL); 693 694 nir_builder_instr_insert(build, &deref->instr); 695 696 return deref; 697} 698 699/** Returns a deref that follows another but starting from the given parent 700 * 701 * The new deref will be the same type and take the same array or struct index 702 * as the leader deref but it may have a different parent. This is very 703 * useful for walking deref paths. 704 */ 705static inline nir_deref_instr * 706nir_build_deref_follower(nir_builder *b, nir_deref_instr *parent, 707 nir_deref_instr *leader) 708{ 709 /* If the derefs would have the same parent, don't make a new one */ 710 assert(leader->parent.is_ssa); 711 if (leader->parent.ssa == &parent->dest.ssa) 712 return leader; 713 714 UNUSED nir_deref_instr *leader_parent = nir_src_as_deref(leader->parent); 715 716 switch (leader->deref_type) { 717 case nir_deref_type_var: 718 unreachable("A var dereference cannot have a parent"); 719 break; 720 721 case nir_deref_type_array: 722 case nir_deref_type_array_wildcard: 723 assert(glsl_type_is_matrix(parent->type) || 724 glsl_type_is_array(parent->type)); 725 assert(glsl_get_length(parent->type) == 726 glsl_get_length(leader_parent->type)); 727 728 if (leader->deref_type == nir_deref_type_array) { 729 assert(leader->arr.index.is_ssa); 730 return nir_build_deref_array(b, parent, leader->arr.index.ssa); 731 } else { 732 return nir_build_deref_array_wildcard(b, parent); 733 } 734 735 case nir_deref_type_struct: 736 assert(glsl_type_is_struct(parent->type)); 737 assert(glsl_get_length(parent->type) == 738 glsl_get_length(leader_parent->type)); 739 740 return nir_build_deref_struct(b, parent, leader->strct.index); 741 742 default: 743 unreachable("Invalid deref instruction type"); 744 } 745} 746 747static inline nir_ssa_def * 748nir_load_reg(nir_builder *build, nir_register *reg) 749{ 750 return nir_ssa_for_src(build, nir_src_for_reg(reg), reg->num_components); 751} 752 753static inline nir_ssa_def * 754nir_load_deref(nir_builder *build, nir_deref_instr *deref) 755{ 756 nir_intrinsic_instr *load = 757 nir_intrinsic_instr_create(build->shader, nir_intrinsic_load_deref); 758 load->num_components = glsl_get_vector_elements(deref->type); 759 load->src[0] = nir_src_for_ssa(&deref->dest.ssa); 760 nir_ssa_dest_init(&load->instr, &load->dest, load->num_components, 761 glsl_get_bit_size(deref->type), NULL); 762 nir_builder_instr_insert(build, &load->instr); 763 return &load->dest.ssa; 764} 765 766static inline void 767nir_store_deref(nir_builder *build, nir_deref_instr *deref, 768 nir_ssa_def *value, unsigned writemask) 769{ 770 nir_intrinsic_instr *store = 771 nir_intrinsic_instr_create(build->shader, nir_intrinsic_store_deref); 772 store->num_components = glsl_get_vector_elements(deref->type); 773 store->src[0] = nir_src_for_ssa(&deref->dest.ssa); 774 store->src[1] = nir_src_for_ssa(value); 775 nir_intrinsic_set_write_mask(store, 776 writemask & ((1 << store->num_components) - 1)); 777 nir_builder_instr_insert(build, &store->instr); 778} 779 780static inline void 781nir_copy_deref(nir_builder *build, nir_deref_instr *dest, nir_deref_instr *src) 782{ 783 nir_intrinsic_instr *copy = 784 nir_intrinsic_instr_create(build->shader, nir_intrinsic_copy_deref); 785 copy->src[0] = nir_src_for_ssa(&dest->dest.ssa); 786 copy->src[1] = nir_src_for_ssa(&src->dest.ssa); 787 nir_builder_instr_insert(build, ©->instr); 788} 789 790static inline nir_ssa_def * 791nir_load_var(nir_builder *build, nir_variable *var) 792{ 793 return nir_load_deref(build, nir_build_deref_var(build, var)); 794} 795 796static inline void 797nir_store_var(nir_builder *build, nir_variable *var, nir_ssa_def *value, 798 unsigned writemask) 799{ 800 nir_store_deref(build, nir_build_deref_var(build, var), value, writemask); 801} 802 803static inline void 804nir_copy_var(nir_builder *build, nir_variable *dest, nir_variable *src) 805{ 806 nir_copy_deref(build, nir_build_deref_var(build, dest), 807 nir_build_deref_var(build, src)); 808} 809 810static inline nir_ssa_def * 811nir_load_param(nir_builder *build, uint32_t param_idx) 812{ 813 assert(param_idx < build->impl->function->num_params); 814 nir_parameter *param = &build->impl->function->params[param_idx]; 815 816 nir_intrinsic_instr *load = 817 nir_intrinsic_instr_create(build->shader, nir_intrinsic_load_param); 818 nir_intrinsic_set_param_idx(load, param_idx); 819 load->num_components = param->num_components; 820 nir_ssa_dest_init(&load->instr, &load->dest, 821 param->num_components, param->bit_size, NULL); 822 nir_builder_instr_insert(build, &load->instr); 823 return &load->dest.ssa; 824} 825 826#include "nir_builder_opcodes.h" 827 828static inline nir_ssa_def * 829nir_load_barycentric(nir_builder *build, nir_intrinsic_op op, 830 unsigned interp_mode) 831{ 832 nir_intrinsic_instr *bary = nir_intrinsic_instr_create(build->shader, op); 833 nir_ssa_dest_init(&bary->instr, &bary->dest, 2, 32, NULL); 834 nir_intrinsic_set_interp_mode(bary, interp_mode); 835 nir_builder_instr_insert(build, &bary->instr); 836 return &bary->dest.ssa; 837} 838 839static inline void 840nir_jump(nir_builder *build, nir_jump_type jump_type) 841{ 842 nir_jump_instr *jump = nir_jump_instr_create(build->shader, jump_type); 843 nir_builder_instr_insert(build, &jump->instr); 844} 845 846static inline nir_ssa_def * 847nir_compare_func(nir_builder *b, enum compare_func func, 848 nir_ssa_def *src0, nir_ssa_def *src1) 849{ 850 switch (func) { 851 case COMPARE_FUNC_NEVER: 852 return nir_imm_int(b, 0); 853 case COMPARE_FUNC_ALWAYS: 854 return nir_imm_int(b, ~0); 855 case COMPARE_FUNC_EQUAL: 856 return nir_feq(b, src0, src1); 857 case COMPARE_FUNC_NOTEQUAL: 858 return nir_fne(b, src0, src1); 859 case COMPARE_FUNC_GREATER: 860 return nir_flt(b, src1, src0); 861 case COMPARE_FUNC_GEQUAL: 862 return nir_fge(b, src0, src1); 863 case COMPARE_FUNC_LESS: 864 return nir_flt(b, src0, src1); 865 case COMPARE_FUNC_LEQUAL: 866 return nir_fge(b, src1, src0); 867 } 868 unreachable("bad compare func"); 869} 870 871#endif /* NIR_BUILDER_H */ 872