1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2014-2015 Broadcom 3bf215546Sopenharmony_ci * Copyright © 2021 Google 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 14bf215546Sopenharmony_ci * Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22bf215546Sopenharmony_ci * IN THE SOFTWARE. 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci#include "nir_builder.h" 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_civoid 28bf215546Sopenharmony_cinir_builder_init(nir_builder *build, nir_function_impl *impl) 29bf215546Sopenharmony_ci{ 30bf215546Sopenharmony_ci memset(build, 0, sizeof(*build)); 31bf215546Sopenharmony_ci build->exact = false; 32bf215546Sopenharmony_ci build->impl = impl; 33bf215546Sopenharmony_ci build->shader = impl->function->shader; 34bf215546Sopenharmony_ci} 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_cinir_builder MUST_CHECK PRINTFLIKE(3, 4) 37bf215546Sopenharmony_cinir_builder_init_simple_shader(gl_shader_stage stage, 38bf215546Sopenharmony_ci const nir_shader_compiler_options *options, 39bf215546Sopenharmony_ci const char *name, ...) 40bf215546Sopenharmony_ci{ 41bf215546Sopenharmony_ci nir_builder b; 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci memset(&b, 0, sizeof(b)); 44bf215546Sopenharmony_ci b.shader = nir_shader_create(NULL, stage, options, NULL); 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci if (name) { 47bf215546Sopenharmony_ci va_list args; 48bf215546Sopenharmony_ci va_start(args, name); 49bf215546Sopenharmony_ci b.shader->info.name = ralloc_vasprintf(b.shader, name, args); 50bf215546Sopenharmony_ci va_end(args); 51bf215546Sopenharmony_ci } 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_ci nir_function *func = nir_function_create(b.shader, "main"); 54bf215546Sopenharmony_ci func->is_entrypoint = true; 55bf215546Sopenharmony_ci b.exact = false; 56bf215546Sopenharmony_ci b.impl = nir_function_impl_create(func); 57bf215546Sopenharmony_ci b.cursor = nir_after_cf_list(&b.impl->body); 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci /* Simple shaders are typically internal, e.g. blit shaders */ 60bf215546Sopenharmony_ci b.shader->info.internal = true; 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci return b; 63bf215546Sopenharmony_ci} 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_cinir_ssa_def * 66bf215546Sopenharmony_cinir_builder_alu_instr_finish_and_insert(nir_builder *build, nir_alu_instr *instr) 67bf215546Sopenharmony_ci{ 68bf215546Sopenharmony_ci const nir_op_info *op_info = &nir_op_infos[instr->op]; 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci instr->exact = build->exact; 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_ci /* Guess the number of components the destination temporary should have 73bf215546Sopenharmony_ci * based on our input sizes, if it's not fixed for the op. 74bf215546Sopenharmony_ci */ 75bf215546Sopenharmony_ci unsigned num_components = op_info->output_size; 76bf215546Sopenharmony_ci if (num_components == 0) { 77bf215546Sopenharmony_ci for (unsigned i = 0; i < op_info->num_inputs; i++) { 78bf215546Sopenharmony_ci if (op_info->input_sizes[i] == 0) 79bf215546Sopenharmony_ci num_components = MAX2(num_components, 80bf215546Sopenharmony_ci instr->src[i].src.ssa->num_components); 81bf215546Sopenharmony_ci } 82bf215546Sopenharmony_ci } 83bf215546Sopenharmony_ci assert(num_components != 0); 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_ci /* Figure out the bitwidth based on the source bitwidth if the instruction 86bf215546Sopenharmony_ci * is variable-width. 87bf215546Sopenharmony_ci */ 88bf215546Sopenharmony_ci unsigned bit_size = nir_alu_type_get_type_size(op_info->output_type); 89bf215546Sopenharmony_ci if (bit_size == 0) { 90bf215546Sopenharmony_ci for (unsigned i = 0; i < op_info->num_inputs; i++) { 91bf215546Sopenharmony_ci unsigned src_bit_size = instr->src[i].src.ssa->bit_size; 92bf215546Sopenharmony_ci if (nir_alu_type_get_type_size(op_info->input_types[i]) == 0) { 93bf215546Sopenharmony_ci if (bit_size) 94bf215546Sopenharmony_ci assert(src_bit_size == bit_size); 95bf215546Sopenharmony_ci else 96bf215546Sopenharmony_ci bit_size = src_bit_size; 97bf215546Sopenharmony_ci } else { 98bf215546Sopenharmony_ci assert(src_bit_size == 99bf215546Sopenharmony_ci nir_alu_type_get_type_size(op_info->input_types[i])); 100bf215546Sopenharmony_ci } 101bf215546Sopenharmony_ci } 102bf215546Sopenharmony_ci } 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci /* When in doubt, assume 32. */ 105bf215546Sopenharmony_ci if (bit_size == 0) 106bf215546Sopenharmony_ci bit_size = 32; 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_ci /* Make sure we don't swizzle from outside of our source vector (like if a 109bf215546Sopenharmony_ci * scalar value was passed into a multiply with a vector). 110bf215546Sopenharmony_ci */ 111bf215546Sopenharmony_ci for (unsigned i = 0; i < op_info->num_inputs; i++) { 112bf215546Sopenharmony_ci for (unsigned j = instr->src[i].src.ssa->num_components; 113bf215546Sopenharmony_ci j < NIR_MAX_VEC_COMPONENTS; j++) { 114bf215546Sopenharmony_ci instr->src[i].swizzle[j] = instr->src[i].src.ssa->num_components - 1; 115bf215546Sopenharmony_ci } 116bf215546Sopenharmony_ci } 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci nir_ssa_dest_init(&instr->instr, &instr->dest.dest, num_components, 119bf215546Sopenharmony_ci bit_size, NULL); 120bf215546Sopenharmony_ci instr->dest.write_mask = (1 << num_components) - 1; 121bf215546Sopenharmony_ci 122bf215546Sopenharmony_ci nir_builder_instr_insert(build, &instr->instr); 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci return &instr->dest.dest.ssa; 125bf215546Sopenharmony_ci} 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_cinir_ssa_def * 128bf215546Sopenharmony_cinir_build_alu(nir_builder *build, nir_op op, nir_ssa_def *src0, 129bf215546Sopenharmony_ci nir_ssa_def *src1, nir_ssa_def *src2, nir_ssa_def *src3) 130bf215546Sopenharmony_ci{ 131bf215546Sopenharmony_ci nir_alu_instr *instr = nir_alu_instr_create(build->shader, op); 132bf215546Sopenharmony_ci if (!instr) 133bf215546Sopenharmony_ci return NULL; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci instr->src[0].src = nir_src_for_ssa(src0); 136bf215546Sopenharmony_ci if (src1) 137bf215546Sopenharmony_ci instr->src[1].src = nir_src_for_ssa(src1); 138bf215546Sopenharmony_ci if (src2) 139bf215546Sopenharmony_ci instr->src[2].src = nir_src_for_ssa(src2); 140bf215546Sopenharmony_ci if (src3) 141bf215546Sopenharmony_ci instr->src[3].src = nir_src_for_ssa(src3); 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci return nir_builder_alu_instr_finish_and_insert(build, instr); 144bf215546Sopenharmony_ci} 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_cinir_ssa_def * 147bf215546Sopenharmony_cinir_build_alu1(nir_builder *build, nir_op op, nir_ssa_def *src0) 148bf215546Sopenharmony_ci{ 149bf215546Sopenharmony_ci nir_alu_instr *instr = nir_alu_instr_create(build->shader, op); 150bf215546Sopenharmony_ci if (!instr) 151bf215546Sopenharmony_ci return NULL; 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci instr->src[0].src = nir_src_for_ssa(src0); 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci return nir_builder_alu_instr_finish_and_insert(build, instr); 156bf215546Sopenharmony_ci} 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_cinir_ssa_def * 159bf215546Sopenharmony_cinir_build_alu2(nir_builder *build, nir_op op, nir_ssa_def *src0, 160bf215546Sopenharmony_ci nir_ssa_def *src1) 161bf215546Sopenharmony_ci{ 162bf215546Sopenharmony_ci nir_alu_instr *instr = nir_alu_instr_create(build->shader, op); 163bf215546Sopenharmony_ci if (!instr) 164bf215546Sopenharmony_ci return NULL; 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci instr->src[0].src = nir_src_for_ssa(src0); 167bf215546Sopenharmony_ci instr->src[1].src = nir_src_for_ssa(src1); 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_ci return nir_builder_alu_instr_finish_and_insert(build, instr); 170bf215546Sopenharmony_ci} 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_cinir_ssa_def * 173bf215546Sopenharmony_cinir_build_alu3(nir_builder *build, nir_op op, nir_ssa_def *src0, 174bf215546Sopenharmony_ci nir_ssa_def *src1, nir_ssa_def *src2) 175bf215546Sopenharmony_ci{ 176bf215546Sopenharmony_ci nir_alu_instr *instr = nir_alu_instr_create(build->shader, op); 177bf215546Sopenharmony_ci if (!instr) 178bf215546Sopenharmony_ci return NULL; 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci instr->src[0].src = nir_src_for_ssa(src0); 181bf215546Sopenharmony_ci instr->src[1].src = nir_src_for_ssa(src1); 182bf215546Sopenharmony_ci instr->src[2].src = nir_src_for_ssa(src2); 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci return nir_builder_alu_instr_finish_and_insert(build, instr); 185bf215546Sopenharmony_ci} 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_cinir_ssa_def * 188bf215546Sopenharmony_cinir_build_alu4(nir_builder *build, nir_op op, nir_ssa_def *src0, 189bf215546Sopenharmony_ci nir_ssa_def *src1, nir_ssa_def *src2, nir_ssa_def *src3) 190bf215546Sopenharmony_ci{ 191bf215546Sopenharmony_ci nir_alu_instr *instr = nir_alu_instr_create(build->shader, op); 192bf215546Sopenharmony_ci if (!instr) 193bf215546Sopenharmony_ci return NULL; 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci instr->src[0].src = nir_src_for_ssa(src0); 196bf215546Sopenharmony_ci instr->src[1].src = nir_src_for_ssa(src1); 197bf215546Sopenharmony_ci instr->src[2].src = nir_src_for_ssa(src2); 198bf215546Sopenharmony_ci instr->src[3].src = nir_src_for_ssa(src3); 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci return nir_builder_alu_instr_finish_and_insert(build, instr); 201bf215546Sopenharmony_ci} 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci/* for the couple special cases with more than 4 src args: */ 204bf215546Sopenharmony_cinir_ssa_def * 205bf215546Sopenharmony_cinir_build_alu_src_arr(nir_builder *build, nir_op op, nir_ssa_def **srcs) 206bf215546Sopenharmony_ci{ 207bf215546Sopenharmony_ci const nir_op_info *op_info = &nir_op_infos[op]; 208bf215546Sopenharmony_ci nir_alu_instr *instr = nir_alu_instr_create(build->shader, op); 209bf215546Sopenharmony_ci if (!instr) 210bf215546Sopenharmony_ci return NULL; 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_ci for (unsigned i = 0; i < op_info->num_inputs; i++) 213bf215546Sopenharmony_ci instr->src[i].src = nir_src_for_ssa(srcs[i]); 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_ci return nir_builder_alu_instr_finish_and_insert(build, instr); 216bf215546Sopenharmony_ci} 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_cinir_ssa_def * 219bf215546Sopenharmony_cinir_vec_scalars(nir_builder *build, nir_ssa_scalar *comp, unsigned num_components) 220bf215546Sopenharmony_ci{ 221bf215546Sopenharmony_ci nir_op op = nir_op_vec(num_components); 222bf215546Sopenharmony_ci nir_alu_instr *instr = nir_alu_instr_create(build->shader, op); 223bf215546Sopenharmony_ci if (!instr) 224bf215546Sopenharmony_ci return NULL; 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci for (unsigned i = 0; i < num_components; i++) { 227bf215546Sopenharmony_ci instr->src[i].src = nir_src_for_ssa(comp[i].def); 228bf215546Sopenharmony_ci instr->src[i].swizzle[0] = comp[i].comp; 229bf215546Sopenharmony_ci } 230bf215546Sopenharmony_ci instr->exact = build->exact; 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ci /* Note: not reusing nir_builder_alu_instr_finish_and_insert() because it 233bf215546Sopenharmony_ci * can't re-guess the num_components when num_components == 1 (nir_op_mov). 234bf215546Sopenharmony_ci */ 235bf215546Sopenharmony_ci nir_ssa_dest_init(&instr->instr, &instr->dest.dest, num_components, 236bf215546Sopenharmony_ci comp[0].def->bit_size, NULL); 237bf215546Sopenharmony_ci instr->dest.write_mask = (1 << num_components) - 1; 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci nir_builder_instr_insert(build, &instr->instr); 240bf215546Sopenharmony_ci 241bf215546Sopenharmony_ci return &instr->dest.dest.ssa; 242bf215546Sopenharmony_ci} 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci/** 245bf215546Sopenharmony_ci * Turns a nir_src into a nir_ssa_def * so it can be passed to 246bf215546Sopenharmony_ci * nir_build_alu()-based builder calls. 247bf215546Sopenharmony_ci * 248bf215546Sopenharmony_ci * See nir_ssa_for_alu_src() for alu instructions. 249bf215546Sopenharmony_ci */ 250bf215546Sopenharmony_cinir_ssa_def * 251bf215546Sopenharmony_cinir_ssa_for_src(nir_builder *build, nir_src src, int num_components) 252bf215546Sopenharmony_ci{ 253bf215546Sopenharmony_ci if (src.is_ssa && src.ssa->num_components == num_components) 254bf215546Sopenharmony_ci return src.ssa; 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci assert((unsigned)num_components <= nir_src_num_components(src)); 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci nir_alu_src alu = { NIR_SRC_INIT }; 259bf215546Sopenharmony_ci alu.src = src; 260bf215546Sopenharmony_ci for (int j = 0; j < NIR_MAX_VEC_COMPONENTS; j++) 261bf215546Sopenharmony_ci alu.swizzle[j] = j; 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci return nir_mov_alu(build, alu, num_components); 264bf215546Sopenharmony_ci} 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci/** 267bf215546Sopenharmony_ci * Similar to nir_ssa_for_src(), but for alu srcs, respecting the 268bf215546Sopenharmony_ci * nir_alu_src's swizzle. 269bf215546Sopenharmony_ci */ 270bf215546Sopenharmony_cinir_ssa_def * 271bf215546Sopenharmony_cinir_ssa_for_alu_src(nir_builder *build, nir_alu_instr *instr, unsigned srcn) 272bf215546Sopenharmony_ci{ 273bf215546Sopenharmony_ci if (nir_alu_src_is_trivial_ssa(instr, srcn)) 274bf215546Sopenharmony_ci return instr->src[srcn].src.ssa; 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_ci nir_alu_src *src = &instr->src[srcn]; 277bf215546Sopenharmony_ci unsigned num_components = nir_ssa_alu_instr_src_components(instr, srcn); 278bf215546Sopenharmony_ci return nir_mov_alu(build, *src, num_components); 279bf215546Sopenharmony_ci} 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_ci/* Generic builder for system values. */ 282bf215546Sopenharmony_cinir_ssa_def * 283bf215546Sopenharmony_cinir_load_system_value(nir_builder *build, nir_intrinsic_op op, int index, 284bf215546Sopenharmony_ci unsigned num_components, unsigned bit_size) 285bf215546Sopenharmony_ci{ 286bf215546Sopenharmony_ci nir_intrinsic_instr *load = nir_intrinsic_instr_create(build->shader, op); 287bf215546Sopenharmony_ci if (nir_intrinsic_infos[op].dest_components > 0) 288bf215546Sopenharmony_ci assert(num_components == nir_intrinsic_infos[op].dest_components); 289bf215546Sopenharmony_ci else 290bf215546Sopenharmony_ci load->num_components = num_components; 291bf215546Sopenharmony_ci load->const_index[0] = index; 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci nir_ssa_dest_init(&load->instr, &load->dest, 294bf215546Sopenharmony_ci num_components, bit_size, NULL); 295bf215546Sopenharmony_ci nir_builder_instr_insert(build, &load->instr); 296bf215546Sopenharmony_ci return &load->dest.ssa; 297bf215546Sopenharmony_ci} 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_civoid 300bf215546Sopenharmony_cinir_builder_instr_insert(nir_builder *build, nir_instr *instr) 301bf215546Sopenharmony_ci{ 302bf215546Sopenharmony_ci nir_instr_insert(build->cursor, instr); 303bf215546Sopenharmony_ci 304bf215546Sopenharmony_ci if (build->update_divergence) 305bf215546Sopenharmony_ci nir_update_instr_divergence(build->shader, instr); 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_ci /* Move the cursor forward. */ 308bf215546Sopenharmony_ci build->cursor = nir_after_instr(instr); 309bf215546Sopenharmony_ci} 310bf215546Sopenharmony_ci 311bf215546Sopenharmony_civoid 312bf215546Sopenharmony_cinir_builder_cf_insert(nir_builder *build, nir_cf_node *cf) 313bf215546Sopenharmony_ci{ 314bf215546Sopenharmony_ci nir_cf_node_insert(build->cursor, cf); 315bf215546Sopenharmony_ci} 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_cibool 318bf215546Sopenharmony_cinir_builder_is_inside_cf(nir_builder *build, nir_cf_node *cf_node) 319bf215546Sopenharmony_ci{ 320bf215546Sopenharmony_ci nir_block *block = nir_cursor_current_block(build->cursor); 321bf215546Sopenharmony_ci for (nir_cf_node *n = &block->cf_node; n; n = n->parent) { 322bf215546Sopenharmony_ci if (n == cf_node) 323bf215546Sopenharmony_ci return true; 324bf215546Sopenharmony_ci } 325bf215546Sopenharmony_ci return false; 326bf215546Sopenharmony_ci} 327bf215546Sopenharmony_ci 328bf215546Sopenharmony_cinir_if * 329bf215546Sopenharmony_cinir_push_if_src(nir_builder *build, nir_src condition) 330bf215546Sopenharmony_ci{ 331bf215546Sopenharmony_ci nir_if *nif = nir_if_create(build->shader); 332bf215546Sopenharmony_ci nif->condition = condition; 333bf215546Sopenharmony_ci nir_builder_cf_insert(build, &nif->cf_node); 334bf215546Sopenharmony_ci build->cursor = nir_before_cf_list(&nif->then_list); 335bf215546Sopenharmony_ci return nif; 336bf215546Sopenharmony_ci} 337bf215546Sopenharmony_ci 338bf215546Sopenharmony_cinir_if * 339bf215546Sopenharmony_cinir_push_if(nir_builder *build, nir_ssa_def *condition) 340bf215546Sopenharmony_ci{ 341bf215546Sopenharmony_ci return nir_push_if_src(build, nir_src_for_ssa(condition)); 342bf215546Sopenharmony_ci} 343bf215546Sopenharmony_ci 344bf215546Sopenharmony_cinir_if * 345bf215546Sopenharmony_cinir_push_else(nir_builder *build, nir_if *nif) 346bf215546Sopenharmony_ci{ 347bf215546Sopenharmony_ci if (nif) { 348bf215546Sopenharmony_ci assert(nir_builder_is_inside_cf(build, &nif->cf_node)); 349bf215546Sopenharmony_ci } else { 350bf215546Sopenharmony_ci nir_block *block = nir_cursor_current_block(build->cursor); 351bf215546Sopenharmony_ci nif = nir_cf_node_as_if(block->cf_node.parent); 352bf215546Sopenharmony_ci } 353bf215546Sopenharmony_ci build->cursor = nir_before_cf_list(&nif->else_list); 354bf215546Sopenharmony_ci return nif; 355bf215546Sopenharmony_ci} 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_civoid 358bf215546Sopenharmony_cinir_pop_if(nir_builder *build, nir_if *nif) 359bf215546Sopenharmony_ci{ 360bf215546Sopenharmony_ci if (nif) { 361bf215546Sopenharmony_ci assert(nir_builder_is_inside_cf(build, &nif->cf_node)); 362bf215546Sopenharmony_ci } else { 363bf215546Sopenharmony_ci nir_block *block = nir_cursor_current_block(build->cursor); 364bf215546Sopenharmony_ci nif = nir_cf_node_as_if(block->cf_node.parent); 365bf215546Sopenharmony_ci } 366bf215546Sopenharmony_ci build->cursor = nir_after_cf_node(&nif->cf_node); 367bf215546Sopenharmony_ci} 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_cinir_ssa_def * 370bf215546Sopenharmony_cinir_if_phi(nir_builder *build, nir_ssa_def *then_def, nir_ssa_def *else_def) 371bf215546Sopenharmony_ci{ 372bf215546Sopenharmony_ci nir_block *block = nir_cursor_current_block(build->cursor); 373bf215546Sopenharmony_ci nir_if *nif = nir_cf_node_as_if(nir_cf_node_prev(&block->cf_node)); 374bf215546Sopenharmony_ci 375bf215546Sopenharmony_ci nir_phi_instr *phi = nir_phi_instr_create(build->shader); 376bf215546Sopenharmony_ci nir_phi_instr_add_src(phi, nir_if_last_then_block(nif), nir_src_for_ssa(then_def)); 377bf215546Sopenharmony_ci nir_phi_instr_add_src(phi, nir_if_last_else_block(nif), nir_src_for_ssa(else_def)); 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci assert(then_def->num_components == else_def->num_components); 380bf215546Sopenharmony_ci assert(then_def->bit_size == else_def->bit_size); 381bf215546Sopenharmony_ci nir_ssa_dest_init(&phi->instr, &phi->dest, 382bf215546Sopenharmony_ci then_def->num_components, then_def->bit_size, NULL); 383bf215546Sopenharmony_ci 384bf215546Sopenharmony_ci nir_builder_instr_insert(build, &phi->instr); 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci return &phi->dest.ssa; 387bf215546Sopenharmony_ci} 388bf215546Sopenharmony_ci 389bf215546Sopenharmony_cinir_loop * 390bf215546Sopenharmony_cinir_push_loop(nir_builder *build) 391bf215546Sopenharmony_ci{ 392bf215546Sopenharmony_ci nir_loop *loop = nir_loop_create(build->shader); 393bf215546Sopenharmony_ci nir_builder_cf_insert(build, &loop->cf_node); 394bf215546Sopenharmony_ci build->cursor = nir_before_cf_list(&loop->body); 395bf215546Sopenharmony_ci return loop; 396bf215546Sopenharmony_ci} 397bf215546Sopenharmony_ci 398bf215546Sopenharmony_civoid 399bf215546Sopenharmony_cinir_pop_loop(nir_builder *build, nir_loop *loop) 400bf215546Sopenharmony_ci{ 401bf215546Sopenharmony_ci if (loop) { 402bf215546Sopenharmony_ci assert(nir_builder_is_inside_cf(build, &loop->cf_node)); 403bf215546Sopenharmony_ci } else { 404bf215546Sopenharmony_ci nir_block *block = nir_cursor_current_block(build->cursor); 405bf215546Sopenharmony_ci loop = nir_cf_node_as_loop(block->cf_node.parent); 406bf215546Sopenharmony_ci } 407bf215546Sopenharmony_ci build->cursor = nir_after_cf_node(&loop->cf_node); 408bf215546Sopenharmony_ci} 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_cinir_ssa_def * 411bf215546Sopenharmony_cinir_compare_func(nir_builder *b, enum compare_func func, 412bf215546Sopenharmony_ci nir_ssa_def *src0, nir_ssa_def *src1) 413bf215546Sopenharmony_ci{ 414bf215546Sopenharmony_ci switch (func) { 415bf215546Sopenharmony_ci case COMPARE_FUNC_NEVER: 416bf215546Sopenharmony_ci return nir_imm_int(b, 0); 417bf215546Sopenharmony_ci case COMPARE_FUNC_ALWAYS: 418bf215546Sopenharmony_ci return nir_imm_int(b, ~0); 419bf215546Sopenharmony_ci case COMPARE_FUNC_EQUAL: 420bf215546Sopenharmony_ci return nir_feq(b, src0, src1); 421bf215546Sopenharmony_ci case COMPARE_FUNC_NOTEQUAL: 422bf215546Sopenharmony_ci return nir_fneu(b, src0, src1); 423bf215546Sopenharmony_ci case COMPARE_FUNC_GREATER: 424bf215546Sopenharmony_ci return nir_flt(b, src1, src0); 425bf215546Sopenharmony_ci case COMPARE_FUNC_GEQUAL: 426bf215546Sopenharmony_ci return nir_fge(b, src0, src1); 427bf215546Sopenharmony_ci case COMPARE_FUNC_LESS: 428bf215546Sopenharmony_ci return nir_flt(b, src0, src1); 429bf215546Sopenharmony_ci case COMPARE_FUNC_LEQUAL: 430bf215546Sopenharmony_ci return nir_fge(b, src1, src0); 431bf215546Sopenharmony_ci } 432bf215546Sopenharmony_ci unreachable("bad compare func"); 433bf215546Sopenharmony_ci} 434bf215546Sopenharmony_ci 435bf215546Sopenharmony_cinir_ssa_def * 436bf215546Sopenharmony_cinir_type_convert(nir_builder *b, 437bf215546Sopenharmony_ci nir_ssa_def *src, 438bf215546Sopenharmony_ci nir_alu_type src_type, 439bf215546Sopenharmony_ci nir_alu_type dest_type) 440bf215546Sopenharmony_ci{ 441bf215546Sopenharmony_ci assert(nir_alu_type_get_type_size(src_type) == 0 || 442bf215546Sopenharmony_ci nir_alu_type_get_type_size(src_type) == src->bit_size); 443bf215546Sopenharmony_ci 444bf215546Sopenharmony_ci src_type = (nir_alu_type) (src_type | src->bit_size); 445bf215546Sopenharmony_ci 446bf215546Sopenharmony_ci nir_op opcode = 447bf215546Sopenharmony_ci nir_type_conversion_op(src_type, dest_type, nir_rounding_mode_undef); 448bf215546Sopenharmony_ci 449bf215546Sopenharmony_ci return nir_build_alu(b, opcode, src, NULL, NULL, NULL); 450bf215546Sopenharmony_ci} 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_cinir_ssa_def * 453bf215546Sopenharmony_cinir_gen_rect_vertices(nir_builder *b, nir_ssa_def *z, nir_ssa_def *w) 454bf215546Sopenharmony_ci{ 455bf215546Sopenharmony_ci if (!z) 456bf215546Sopenharmony_ci z = nir_imm_float(b, 0.0); 457bf215546Sopenharmony_ci if (!w) 458bf215546Sopenharmony_ci w = nir_imm_float(b, 1.0); 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_ci nir_ssa_def *vertex_id; 461bf215546Sopenharmony_ci if (b->shader->options->vertex_id_zero_based) 462bf215546Sopenharmony_ci vertex_id = nir_load_vertex_id_zero_base(b); 463bf215546Sopenharmony_ci else 464bf215546Sopenharmony_ci vertex_id = nir_load_vertex_id(b); 465bf215546Sopenharmony_ci 466bf215546Sopenharmony_ci /* vertex 0: -1.0, -1.0 467bf215546Sopenharmony_ci * vertex 1: -1.0, 1.0 468bf215546Sopenharmony_ci * vertex 2: 1.0, -1.0 469bf215546Sopenharmony_ci * vertex 3: 1.0, 1.0 470bf215546Sopenharmony_ci * 471bf215546Sopenharmony_ci * so: 472bf215546Sopenharmony_ci * 473bf215546Sopenharmony_ci * channel 0 is vertex_id < 2 ? -1.0 : 1.0 474bf215546Sopenharmony_ci * channel 1 is vertex_id & 1 ? 1.0 : -1.0 475bf215546Sopenharmony_ci */ 476bf215546Sopenharmony_ci 477bf215546Sopenharmony_ci nir_ssa_def *c0cmp = nir_ilt(b, vertex_id, nir_imm_int(b, 2)); 478bf215546Sopenharmony_ci nir_ssa_def *c1cmp = nir_test_mask(b, vertex_id, 1); 479bf215546Sopenharmony_ci 480bf215546Sopenharmony_ci nir_ssa_def *comp[4]; 481bf215546Sopenharmony_ci comp[0] = nir_bcsel(b, c0cmp, nir_imm_float(b, -1.0), nir_imm_float(b, 1.0)); 482bf215546Sopenharmony_ci comp[1] = nir_bcsel(b, c1cmp, nir_imm_float(b, 1.0), nir_imm_float(b, -1.0)); 483bf215546Sopenharmony_ci comp[2] = z; 484bf215546Sopenharmony_ci comp[3] = w; 485bf215546Sopenharmony_ci 486bf215546Sopenharmony_ci return nir_vec(b, comp, 4); 487bf215546Sopenharmony_ci} 488