101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2014-2015 Broadcom 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2101e04c3fSmrg * IN THE SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg 2401e04c3fSmrg#ifndef NIR_BUILDER_H 2501e04c3fSmrg#define NIR_BUILDER_H 2601e04c3fSmrg 2701e04c3fSmrg#include "nir_control_flow.h" 287e102996Smaya#include "util/bitscan.h" 2901e04c3fSmrg#include "util/half_float.h" 3001e04c3fSmrg 3101e04c3fSmrgstruct exec_list; 3201e04c3fSmrg 3301e04c3fSmrgtypedef struct nir_builder { 3401e04c3fSmrg nir_cursor cursor; 3501e04c3fSmrg 3601e04c3fSmrg /* Whether new ALU instructions will be marked "exact" */ 3701e04c3fSmrg bool exact; 3801e04c3fSmrg 397ec681f3Smrg /* Whether to run divergence analysis on inserted instructions (loop merge 407ec681f3Smrg * and header phis are not updated). */ 417ec681f3Smrg bool update_divergence; 427ec681f3Smrg 4301e04c3fSmrg nir_shader *shader; 4401e04c3fSmrg nir_function_impl *impl; 4501e04c3fSmrg} nir_builder; 4601e04c3fSmrg 4701e04c3fSmrgstatic inline void 4801e04c3fSmrgnir_builder_init(nir_builder *build, nir_function_impl *impl) 4901e04c3fSmrg{ 5001e04c3fSmrg memset(build, 0, sizeof(*build)); 5101e04c3fSmrg build->exact = false; 5201e04c3fSmrg build->impl = impl; 5301e04c3fSmrg build->shader = impl->function->shader; 5401e04c3fSmrg} 5501e04c3fSmrg 567ec681f3Smrgstatic inline nir_builder MUST_CHECK PRINTFLIKE(3, 4) 577ec681f3Smrgnir_builder_init_simple_shader(gl_shader_stage stage, 587ec681f3Smrg const nir_shader_compiler_options *options, 597ec681f3Smrg const char *name, ...) 6001e04c3fSmrg{ 617ec681f3Smrg nir_builder b; 627ec681f3Smrg 637ec681f3Smrg memset(&b, 0, sizeof(b)); 647ec681f3Smrg b.shader = nir_shader_create(NULL, stage, options, NULL); 657ec681f3Smrg 667ec681f3Smrg if (name) { 677ec681f3Smrg va_list args; 687ec681f3Smrg va_start(args, name); 697ec681f3Smrg b.shader->info.name = ralloc_vasprintf(b.shader, name, args); 707ec681f3Smrg va_end(args); 717ec681f3Smrg } 727ec681f3Smrg 737ec681f3Smrg nir_function *func = nir_function_create(b.shader, "main"); 747e102996Smaya func->is_entrypoint = true; 757ec681f3Smrg b.exact = false; 767ec681f3Smrg b.impl = nir_function_impl_create(func); 777ec681f3Smrg b.cursor = nir_after_cf_list(&b.impl->body); 787ec681f3Smrg 797ec681f3Smrg return b; 807ec681f3Smrg} 817ec681f3Smrg 827ec681f3Smrgtypedef bool (*nir_instr_pass_cb)(struct nir_builder *, nir_instr *, void *); 837ec681f3Smrg 847ec681f3Smrg/** 857ec681f3Smrg * Iterates over all the instructions in a NIR shader and calls the given pass 867ec681f3Smrg * on them. 877ec681f3Smrg * 887ec681f3Smrg * The pass should return true if it modified the shader. In that case, only 897ec681f3Smrg * the preserved metadata flags will be preserved in the function impl. 907ec681f3Smrg * 917ec681f3Smrg * The builder will be initialized to point at the function impl, but its 927ec681f3Smrg * cursor is unset. 937ec681f3Smrg */ 947ec681f3Smrgstatic inline bool 957ec681f3Smrgnir_shader_instructions_pass(nir_shader *shader, 967ec681f3Smrg nir_instr_pass_cb pass, 977ec681f3Smrg nir_metadata preserved, 987ec681f3Smrg void *cb_data) 997ec681f3Smrg{ 1007ec681f3Smrg bool progress = false; 1017ec681f3Smrg 1027ec681f3Smrg nir_foreach_function(function, shader) { 1037ec681f3Smrg if (!function->impl) 1047ec681f3Smrg continue; 1057ec681f3Smrg 1067ec681f3Smrg bool func_progress = false; 1077ec681f3Smrg nir_builder b; 1087ec681f3Smrg nir_builder_init(&b, function->impl); 1097ec681f3Smrg 1107ec681f3Smrg nir_foreach_block_safe(block, function->impl) { 1117ec681f3Smrg nir_foreach_instr_safe(instr, block) { 1127ec681f3Smrg func_progress |= pass(&b, instr, cb_data); 1137ec681f3Smrg } 1147ec681f3Smrg } 1157ec681f3Smrg 1167ec681f3Smrg if (func_progress) { 1177ec681f3Smrg nir_metadata_preserve(function->impl, preserved); 1187ec681f3Smrg progress = true; 1197ec681f3Smrg } else { 1207ec681f3Smrg nir_metadata_preserve(function->impl, nir_metadata_all); 1217ec681f3Smrg } 1227ec681f3Smrg } 1237ec681f3Smrg 1247ec681f3Smrg return progress; 12501e04c3fSmrg} 12601e04c3fSmrg 12701e04c3fSmrgstatic inline void 12801e04c3fSmrgnir_builder_instr_insert(nir_builder *build, nir_instr *instr) 12901e04c3fSmrg{ 13001e04c3fSmrg nir_instr_insert(build->cursor, instr); 13101e04c3fSmrg 1327ec681f3Smrg if (build->update_divergence) 1337ec681f3Smrg nir_update_instr_divergence(build->shader, instr); 1347ec681f3Smrg 13501e04c3fSmrg /* Move the cursor forward. */ 13601e04c3fSmrg build->cursor = nir_after_instr(instr); 13701e04c3fSmrg} 13801e04c3fSmrg 13901e04c3fSmrgstatic inline nir_instr * 14001e04c3fSmrgnir_builder_last_instr(nir_builder *build) 14101e04c3fSmrg{ 14201e04c3fSmrg assert(build->cursor.option == nir_cursor_after_instr); 14301e04c3fSmrg return build->cursor.instr; 14401e04c3fSmrg} 14501e04c3fSmrg 14601e04c3fSmrgstatic inline void 14701e04c3fSmrgnir_builder_cf_insert(nir_builder *build, nir_cf_node *cf) 14801e04c3fSmrg{ 14901e04c3fSmrg nir_cf_node_insert(build->cursor, cf); 15001e04c3fSmrg} 15101e04c3fSmrg 15201e04c3fSmrgstatic inline bool 15301e04c3fSmrgnir_builder_is_inside_cf(nir_builder *build, nir_cf_node *cf_node) 15401e04c3fSmrg{ 15501e04c3fSmrg nir_block *block = nir_cursor_current_block(build->cursor); 15601e04c3fSmrg for (nir_cf_node *n = &block->cf_node; n; n = n->parent) { 15701e04c3fSmrg if (n == cf_node) 15801e04c3fSmrg return true; 15901e04c3fSmrg } 16001e04c3fSmrg return false; 16101e04c3fSmrg} 16201e04c3fSmrg 16301e04c3fSmrgstatic inline nir_if * 1647ec681f3Smrgnir_push_if_src(nir_builder *build, nir_src condition) 16501e04c3fSmrg{ 16601e04c3fSmrg nir_if *nif = nir_if_create(build->shader); 1677ec681f3Smrg nif->condition = condition; 16801e04c3fSmrg nir_builder_cf_insert(build, &nif->cf_node); 16901e04c3fSmrg build->cursor = nir_before_cf_list(&nif->then_list); 17001e04c3fSmrg return nif; 17101e04c3fSmrg} 17201e04c3fSmrg 1737ec681f3Smrgstatic inline nir_if * 1747ec681f3Smrgnir_push_if(nir_builder *build, nir_ssa_def *condition) 1757ec681f3Smrg{ 1767ec681f3Smrg return nir_push_if_src(build, nir_src_for_ssa(condition)); 1777ec681f3Smrg} 1787ec681f3Smrg 17901e04c3fSmrgstatic inline nir_if * 18001e04c3fSmrgnir_push_else(nir_builder *build, nir_if *nif) 18101e04c3fSmrg{ 18201e04c3fSmrg if (nif) { 18301e04c3fSmrg assert(nir_builder_is_inside_cf(build, &nif->cf_node)); 18401e04c3fSmrg } else { 18501e04c3fSmrg nir_block *block = nir_cursor_current_block(build->cursor); 18601e04c3fSmrg nif = nir_cf_node_as_if(block->cf_node.parent); 18701e04c3fSmrg } 18801e04c3fSmrg build->cursor = nir_before_cf_list(&nif->else_list); 18901e04c3fSmrg return nif; 19001e04c3fSmrg} 19101e04c3fSmrg 19201e04c3fSmrgstatic inline void 19301e04c3fSmrgnir_pop_if(nir_builder *build, nir_if *nif) 19401e04c3fSmrg{ 19501e04c3fSmrg if (nif) { 19601e04c3fSmrg assert(nir_builder_is_inside_cf(build, &nif->cf_node)); 19701e04c3fSmrg } else { 19801e04c3fSmrg nir_block *block = nir_cursor_current_block(build->cursor); 19901e04c3fSmrg nif = nir_cf_node_as_if(block->cf_node.parent); 20001e04c3fSmrg } 20101e04c3fSmrg build->cursor = nir_after_cf_node(&nif->cf_node); 20201e04c3fSmrg} 20301e04c3fSmrg 20401e04c3fSmrgstatic inline nir_ssa_def * 20501e04c3fSmrgnir_if_phi(nir_builder *build, nir_ssa_def *then_def, nir_ssa_def *else_def) 20601e04c3fSmrg{ 20701e04c3fSmrg nir_block *block = nir_cursor_current_block(build->cursor); 20801e04c3fSmrg nir_if *nif = nir_cf_node_as_if(nir_cf_node_prev(&block->cf_node)); 20901e04c3fSmrg 21001e04c3fSmrg nir_phi_instr *phi = nir_phi_instr_create(build->shader); 2117ec681f3Smrg nir_phi_instr_add_src(phi, nir_if_last_then_block(nif), nir_src_for_ssa(then_def)); 2127ec681f3Smrg nir_phi_instr_add_src(phi, nir_if_last_else_block(nif), nir_src_for_ssa(else_def)); 21301e04c3fSmrg 21401e04c3fSmrg assert(then_def->num_components == else_def->num_components); 21501e04c3fSmrg assert(then_def->bit_size == else_def->bit_size); 21601e04c3fSmrg nir_ssa_dest_init(&phi->instr, &phi->dest, 21701e04c3fSmrg then_def->num_components, then_def->bit_size, NULL); 21801e04c3fSmrg 21901e04c3fSmrg nir_builder_instr_insert(build, &phi->instr); 22001e04c3fSmrg 22101e04c3fSmrg return &phi->dest.ssa; 22201e04c3fSmrg} 22301e04c3fSmrg 22401e04c3fSmrgstatic inline nir_loop * 22501e04c3fSmrgnir_push_loop(nir_builder *build) 22601e04c3fSmrg{ 22701e04c3fSmrg nir_loop *loop = nir_loop_create(build->shader); 22801e04c3fSmrg nir_builder_cf_insert(build, &loop->cf_node); 22901e04c3fSmrg build->cursor = nir_before_cf_list(&loop->body); 23001e04c3fSmrg return loop; 23101e04c3fSmrg} 23201e04c3fSmrg 23301e04c3fSmrgstatic inline void 23401e04c3fSmrgnir_pop_loop(nir_builder *build, nir_loop *loop) 23501e04c3fSmrg{ 23601e04c3fSmrg if (loop) { 23701e04c3fSmrg assert(nir_builder_is_inside_cf(build, &loop->cf_node)); 23801e04c3fSmrg } else { 23901e04c3fSmrg nir_block *block = nir_cursor_current_block(build->cursor); 24001e04c3fSmrg loop = nir_cf_node_as_loop(block->cf_node.parent); 24101e04c3fSmrg } 24201e04c3fSmrg build->cursor = nir_after_cf_node(&loop->cf_node); 24301e04c3fSmrg} 24401e04c3fSmrg 24501e04c3fSmrgstatic inline nir_ssa_def * 24601e04c3fSmrgnir_ssa_undef(nir_builder *build, unsigned num_components, unsigned bit_size) 24701e04c3fSmrg{ 24801e04c3fSmrg nir_ssa_undef_instr *undef = 24901e04c3fSmrg nir_ssa_undef_instr_create(build->shader, num_components, bit_size); 25001e04c3fSmrg if (!undef) 25101e04c3fSmrg return NULL; 25201e04c3fSmrg 25301e04c3fSmrg nir_instr_insert(nir_before_cf_list(&build->impl->body), &undef->instr); 2547ec681f3Smrg if (build->update_divergence) 2557ec681f3Smrg nir_update_instr_divergence(build->shader, &undef->instr); 25601e04c3fSmrg 25701e04c3fSmrg return &undef->def; 25801e04c3fSmrg} 25901e04c3fSmrg 26001e04c3fSmrgstatic inline nir_ssa_def * 26101e04c3fSmrgnir_build_imm(nir_builder *build, unsigned num_components, 2627e102996Smaya unsigned bit_size, const nir_const_value *value) 26301e04c3fSmrg{ 26401e04c3fSmrg nir_load_const_instr *load_const = 26501e04c3fSmrg nir_load_const_instr_create(build->shader, num_components, bit_size); 26601e04c3fSmrg if (!load_const) 26701e04c3fSmrg return NULL; 26801e04c3fSmrg 2697e102996Smaya memcpy(load_const->value, value, sizeof(nir_const_value) * num_components); 2707e102996Smaya 2717e102996Smaya nir_builder_instr_insert(build, &load_const->instr); 2727e102996Smaya 2737e102996Smaya return &load_const->def; 2747e102996Smaya} 2757e102996Smaya 2767e102996Smayastatic inline nir_ssa_def * 2777e102996Smayanir_imm_zero(nir_builder *build, unsigned num_components, unsigned bit_size) 2787e102996Smaya{ 2797e102996Smaya nir_load_const_instr *load_const = 2807e102996Smaya nir_load_const_instr_create(build->shader, num_components, bit_size); 2817e102996Smaya 2827e102996Smaya /* nir_load_const_instr_create uses rzalloc so it's already zero */ 28301e04c3fSmrg 28401e04c3fSmrg nir_builder_instr_insert(build, &load_const->instr); 28501e04c3fSmrg 28601e04c3fSmrg return &load_const->def; 28701e04c3fSmrg} 28801e04c3fSmrg 28901e04c3fSmrgstatic inline nir_ssa_def * 2907ec681f3Smrgnir_imm_boolN_t(nir_builder *build, bool x, unsigned bit_size) 29101e04c3fSmrg{ 2927ec681f3Smrg nir_const_value v = nir_const_value_for_bool(x, bit_size); 2937ec681f3Smrg return nir_build_imm(build, 1, bit_size, &v); 2947ec681f3Smrg} 29501e04c3fSmrg 2967ec681f3Smrgstatic inline nir_ssa_def * 2977ec681f3Smrgnir_imm_bool(nir_builder *build, bool x) 2987ec681f3Smrg{ 2997ec681f3Smrg return nir_imm_boolN_t(build, x, 1); 30001e04c3fSmrg} 30101e04c3fSmrg 30201e04c3fSmrgstatic inline nir_ssa_def * 30301e04c3fSmrgnir_imm_true(nir_builder *build) 30401e04c3fSmrg{ 30501e04c3fSmrg return nir_imm_bool(build, true); 30601e04c3fSmrg} 30701e04c3fSmrg 30801e04c3fSmrgstatic inline nir_ssa_def * 30901e04c3fSmrgnir_imm_false(nir_builder *build) 31001e04c3fSmrg{ 31101e04c3fSmrg return nir_imm_bool(build, false); 31201e04c3fSmrg} 31301e04c3fSmrg 31401e04c3fSmrgstatic inline nir_ssa_def * 3157ec681f3Smrgnir_imm_floatN_t(nir_builder *build, double x, unsigned bit_size) 31601e04c3fSmrg{ 3177ec681f3Smrg nir_const_value v = nir_const_value_for_float(x, bit_size); 3187ec681f3Smrg return nir_build_imm(build, 1, bit_size, &v); 3197ec681f3Smrg} 32001e04c3fSmrg 3217ec681f3Smrgstatic inline nir_ssa_def * 3227ec681f3Smrgnir_imm_float16(nir_builder *build, float x) 3237ec681f3Smrg{ 3247ec681f3Smrg return nir_imm_floatN_t(build, x, 16); 32501e04c3fSmrg} 32601e04c3fSmrg 32701e04c3fSmrgstatic inline nir_ssa_def * 32801e04c3fSmrgnir_imm_float(nir_builder *build, float x) 32901e04c3fSmrg{ 3307ec681f3Smrg return nir_imm_floatN_t(build, x, 32); 33101e04c3fSmrg} 33201e04c3fSmrg 33301e04c3fSmrgstatic inline nir_ssa_def * 33401e04c3fSmrgnir_imm_double(nir_builder *build, double x) 33501e04c3fSmrg{ 3367ec681f3Smrg return nir_imm_floatN_t(build, x, 64); 33701e04c3fSmrg} 33801e04c3fSmrg 33901e04c3fSmrgstatic inline nir_ssa_def * 3407ec681f3Smrgnir_imm_vec2(nir_builder *build, float x, float y) 34101e04c3fSmrg{ 3427ec681f3Smrg nir_const_value v[2] = { 3437ec681f3Smrg nir_const_value_for_float(x, 32), 3447ec681f3Smrg nir_const_value_for_float(y, 32), 3457ec681f3Smrg }; 3467ec681f3Smrg return nir_build_imm(build, 2, 32, v); 34701e04c3fSmrg} 34801e04c3fSmrg 3497e102996Smayastatic inline nir_ssa_def * 3507ec681f3Smrgnir_imm_vec3(nir_builder *build, float x, float y, float z) 3517e102996Smaya{ 3527ec681f3Smrg nir_const_value v[3] = { 3537ec681f3Smrg nir_const_value_for_float(x, 32), 3547ec681f3Smrg nir_const_value_for_float(y, 32), 3557ec681f3Smrg nir_const_value_for_float(z, 32), 3567ec681f3Smrg }; 3577ec681f3Smrg return nir_build_imm(build, 3, 32, v); 3587e102996Smaya} 3597e102996Smaya 36001e04c3fSmrgstatic inline nir_ssa_def * 36101e04c3fSmrgnir_imm_vec4(nir_builder *build, float x, float y, float z, float w) 36201e04c3fSmrg{ 3637ec681f3Smrg nir_const_value v[4] = { 3647ec681f3Smrg nir_const_value_for_float(x, 32), 3657ec681f3Smrg nir_const_value_for_float(y, 32), 3667ec681f3Smrg nir_const_value_for_float(z, 32), 3677ec681f3Smrg nir_const_value_for_float(w, 32), 3687ec681f3Smrg }; 36901e04c3fSmrg 37001e04c3fSmrg return nir_build_imm(build, 4, 32, v); 37101e04c3fSmrg} 37201e04c3fSmrg 37301e04c3fSmrgstatic inline nir_ssa_def * 3747ec681f3Smrgnir_imm_vec4_16(nir_builder *build, float x, float y, float z, float w) 37501e04c3fSmrg{ 3767ec681f3Smrg nir_const_value v[4] = { 3777ec681f3Smrg nir_const_value_for_float(x, 16), 3787ec681f3Smrg nir_const_value_for_float(y, 16), 3797ec681f3Smrg nir_const_value_for_float(z, 16), 3807ec681f3Smrg nir_const_value_for_float(w, 16), 3817ec681f3Smrg }; 38201e04c3fSmrg 3837ec681f3Smrg return nir_build_imm(build, 4, 16, v); 3847ec681f3Smrg} 38501e04c3fSmrg 3867ec681f3Smrgstatic inline nir_ssa_def * 3877ec681f3Smrgnir_imm_intN_t(nir_builder *build, uint64_t x, unsigned bit_size) 3887ec681f3Smrg{ 3897ec681f3Smrg nir_const_value v = nir_const_value_for_raw_uint(x, bit_size); 3907ec681f3Smrg return nir_build_imm(build, 1, bit_size, &v); 39101e04c3fSmrg} 39201e04c3fSmrg 39301e04c3fSmrgstatic inline nir_ssa_def * 39401e04c3fSmrgnir_imm_int(nir_builder *build, int x) 39501e04c3fSmrg{ 3967ec681f3Smrg return nir_imm_intN_t(build, x, 32); 39701e04c3fSmrg} 39801e04c3fSmrg 39901e04c3fSmrgstatic inline nir_ssa_def * 40001e04c3fSmrgnir_imm_int64(nir_builder *build, int64_t x) 40101e04c3fSmrg{ 4027ec681f3Smrg return nir_imm_intN_t(build, x, 64); 40301e04c3fSmrg} 40401e04c3fSmrg 40501e04c3fSmrgstatic inline nir_ssa_def * 4067ec681f3Smrgnir_imm_ivec2(nir_builder *build, int x, int y) 40701e04c3fSmrg{ 4087ec681f3Smrg nir_const_value v[2] = { 4097ec681f3Smrg nir_const_value_for_int(x, 32), 4107ec681f3Smrg nir_const_value_for_int(y, 32), 4117ec681f3Smrg }; 41201e04c3fSmrg 4137ec681f3Smrg return nir_build_imm(build, 2, 32, v); 41401e04c3fSmrg} 41501e04c3fSmrg 41601e04c3fSmrgstatic inline nir_ssa_def * 4177ec681f3Smrgnir_imm_ivec3(nir_builder *build, int x, int y, int z) 41801e04c3fSmrg{ 4197ec681f3Smrg nir_const_value v[3] = { 4207ec681f3Smrg nir_const_value_for_int(x, 32), 4217ec681f3Smrg nir_const_value_for_int(y, 32), 4227ec681f3Smrg nir_const_value_for_int(z, 32), 4237ec681f3Smrg }; 42401e04c3fSmrg 4257ec681f3Smrg return nir_build_imm(build, 3, 32, v); 42601e04c3fSmrg} 42701e04c3fSmrg 42801e04c3fSmrgstatic inline nir_ssa_def * 4297ec681f3Smrgnir_imm_ivec4(nir_builder *build, int x, int y, int z, int w) 43001e04c3fSmrg{ 4317ec681f3Smrg nir_const_value v[4] = { 4327ec681f3Smrg nir_const_value_for_int(x, 32), 4337ec681f3Smrg nir_const_value_for_int(y, 32), 4347ec681f3Smrg nir_const_value_for_int(z, 32), 4357ec681f3Smrg nir_const_value_for_int(w, 32), 4367ec681f3Smrg }; 4377ec681f3Smrg 4387ec681f3Smrg return nir_build_imm(build, 4, 32, v); 4397e102996Smaya} 44001e04c3fSmrg 4417e102996Smayastatic inline nir_ssa_def * 4427e102996Smayanir_builder_alu_instr_finish_and_insert(nir_builder *build, nir_alu_instr *instr) 4437e102996Smaya{ 4447e102996Smaya const nir_op_info *op_info = &nir_op_infos[instr->op]; 44501e04c3fSmrg 4467e102996Smaya instr->exact = build->exact; 44701e04c3fSmrg 44801e04c3fSmrg /* Guess the number of components the destination temporary should have 44901e04c3fSmrg * based on our input sizes, if it's not fixed for the op. 45001e04c3fSmrg */ 45101e04c3fSmrg unsigned num_components = op_info->output_size; 45201e04c3fSmrg if (num_components == 0) { 45301e04c3fSmrg for (unsigned i = 0; i < op_info->num_inputs; i++) { 45401e04c3fSmrg if (op_info->input_sizes[i] == 0) 45501e04c3fSmrg num_components = MAX2(num_components, 45601e04c3fSmrg instr->src[i].src.ssa->num_components); 45701e04c3fSmrg } 45801e04c3fSmrg } 45901e04c3fSmrg assert(num_components != 0); 46001e04c3fSmrg 46101e04c3fSmrg /* Figure out the bitwidth based on the source bitwidth if the instruction 46201e04c3fSmrg * is variable-width. 46301e04c3fSmrg */ 46401e04c3fSmrg unsigned bit_size = nir_alu_type_get_type_size(op_info->output_type); 46501e04c3fSmrg if (bit_size == 0) { 46601e04c3fSmrg for (unsigned i = 0; i < op_info->num_inputs; i++) { 46701e04c3fSmrg unsigned src_bit_size = instr->src[i].src.ssa->bit_size; 46801e04c3fSmrg if (nir_alu_type_get_type_size(op_info->input_types[i]) == 0) { 46901e04c3fSmrg if (bit_size) 47001e04c3fSmrg assert(src_bit_size == bit_size); 47101e04c3fSmrg else 47201e04c3fSmrg bit_size = src_bit_size; 47301e04c3fSmrg } else { 47401e04c3fSmrg assert(src_bit_size == 47501e04c3fSmrg nir_alu_type_get_type_size(op_info->input_types[i])); 47601e04c3fSmrg } 47701e04c3fSmrg } 47801e04c3fSmrg } 47901e04c3fSmrg 48001e04c3fSmrg /* When in doubt, assume 32. */ 48101e04c3fSmrg if (bit_size == 0) 48201e04c3fSmrg bit_size = 32; 48301e04c3fSmrg 48401e04c3fSmrg /* Make sure we don't swizzle from outside of our source vector (like if a 48501e04c3fSmrg * scalar value was passed into a multiply with a vector). 48601e04c3fSmrg */ 48701e04c3fSmrg for (unsigned i = 0; i < op_info->num_inputs; i++) { 48801e04c3fSmrg for (unsigned j = instr->src[i].src.ssa->num_components; 48901e04c3fSmrg j < NIR_MAX_VEC_COMPONENTS; j++) { 49001e04c3fSmrg instr->src[i].swizzle[j] = instr->src[i].src.ssa->num_components - 1; 49101e04c3fSmrg } 49201e04c3fSmrg } 49301e04c3fSmrg 49401e04c3fSmrg nir_ssa_dest_init(&instr->instr, &instr->dest.dest, num_components, 49501e04c3fSmrg bit_size, NULL); 49601e04c3fSmrg instr->dest.write_mask = (1 << num_components) - 1; 49701e04c3fSmrg 49801e04c3fSmrg nir_builder_instr_insert(build, &instr->instr); 49901e04c3fSmrg 50001e04c3fSmrg return &instr->dest.dest.ssa; 50101e04c3fSmrg} 50201e04c3fSmrg 5037e102996Smayastatic inline nir_ssa_def * 5047e102996Smayanir_build_alu(nir_builder *build, nir_op op, nir_ssa_def *src0, 5057e102996Smaya nir_ssa_def *src1, nir_ssa_def *src2, nir_ssa_def *src3) 5067e102996Smaya{ 5077e102996Smaya nir_alu_instr *instr = nir_alu_instr_create(build->shader, op); 5087e102996Smaya if (!instr) 5097e102996Smaya return NULL; 5107e102996Smaya 5117e102996Smaya instr->src[0].src = nir_src_for_ssa(src0); 5127e102996Smaya if (src1) 5137e102996Smaya instr->src[1].src = nir_src_for_ssa(src1); 5147e102996Smaya if (src2) 5157e102996Smaya instr->src[2].src = nir_src_for_ssa(src2); 5167e102996Smaya if (src3) 5177e102996Smaya instr->src[3].src = nir_src_for_ssa(src3); 5187e102996Smaya 5197e102996Smaya return nir_builder_alu_instr_finish_and_insert(build, instr); 5207e102996Smaya} 5217e102996Smaya 5227e102996Smaya/* for the couple special cases with more than 4 src args: */ 5237e102996Smayastatic inline nir_ssa_def * 5247e102996Smayanir_build_alu_src_arr(nir_builder *build, nir_op op, nir_ssa_def **srcs) 5257e102996Smaya{ 5267e102996Smaya const nir_op_info *op_info = &nir_op_infos[op]; 5277e102996Smaya nir_alu_instr *instr = nir_alu_instr_create(build->shader, op); 5287e102996Smaya if (!instr) 5297e102996Smaya return NULL; 5307e102996Smaya 5317e102996Smaya for (unsigned i = 0; i < op_info->num_inputs; i++) 5327e102996Smaya instr->src[i].src = nir_src_for_ssa(srcs[i]); 5337e102996Smaya 5347e102996Smaya return nir_builder_alu_instr_finish_and_insert(build, instr); 5357e102996Smaya} 5367e102996Smaya 5377ec681f3Smrg/* Generic builder for system values. */ 5387ec681f3Smrgstatic inline nir_ssa_def * 5397ec681f3Smrgnir_load_system_value(nir_builder *build, nir_intrinsic_op op, int index, 5407ec681f3Smrg unsigned num_components, unsigned bit_size) 5417ec681f3Smrg{ 5427ec681f3Smrg nir_intrinsic_instr *load = nir_intrinsic_instr_create(build->shader, op); 5437ec681f3Smrg if (nir_intrinsic_infos[op].dest_components > 0) 5447ec681f3Smrg assert(num_components == nir_intrinsic_infos[op].dest_components); 5457ec681f3Smrg else 5467ec681f3Smrg load->num_components = num_components; 5477ec681f3Smrg load->const_index[0] = index; 5487ec681f3Smrg 5497ec681f3Smrg nir_ssa_dest_init(&load->instr, &load->dest, 5507ec681f3Smrg num_components, bit_size, NULL); 5517ec681f3Smrg nir_builder_instr_insert(build, &load->instr); 5527ec681f3Smrg return &load->dest.ssa; 5537ec681f3Smrg} 5547ec681f3Smrg 55501e04c3fSmrg#include "nir_builder_opcodes.h" 5567ec681f3Smrg#undef nir_deref_mode_is 55701e04c3fSmrg 55801e04c3fSmrgstatic inline nir_ssa_def * 55901e04c3fSmrgnir_vec(nir_builder *build, nir_ssa_def **comp, unsigned num_components) 56001e04c3fSmrg{ 5617e102996Smaya return nir_build_alu_src_arr(build, nir_op_vec(num_components), comp); 56201e04c3fSmrg} 56301e04c3fSmrg 56401e04c3fSmrgstatic inline nir_ssa_def * 5657ec681f3Smrgnir_mov_alu(nir_builder *build, nir_alu_src src, unsigned num_components) 5667ec681f3Smrg{ 5677ec681f3Smrg assert(!src.abs && !src.negate); 5687ec681f3Smrg if (src.src.is_ssa && src.src.ssa->num_components == num_components) { 5697ec681f3Smrg bool any_swizzles = false; 5707ec681f3Smrg for (unsigned i = 0; i < num_components; i++) { 5717ec681f3Smrg if (src.swizzle[i] != i) 5727ec681f3Smrg any_swizzles = true; 5737ec681f3Smrg } 5747ec681f3Smrg if (!any_swizzles) 5757ec681f3Smrg return src.src.ssa; 5767ec681f3Smrg } 57701e04c3fSmrg 5787ec681f3Smrg nir_alu_instr *mov = nir_alu_instr_create(build->shader, nir_op_mov); 57901e04c3fSmrg nir_ssa_dest_init(&mov->instr, &mov->dest.dest, num_components, 58001e04c3fSmrg nir_src_bit_size(src.src), NULL); 58101e04c3fSmrg mov->exact = build->exact; 58201e04c3fSmrg mov->dest.write_mask = (1 << num_components) - 1; 58301e04c3fSmrg mov->src[0] = src; 58401e04c3fSmrg nir_builder_instr_insert(build, &mov->instr); 58501e04c3fSmrg 58601e04c3fSmrg return &mov->dest.dest.ssa; 58701e04c3fSmrg} 58801e04c3fSmrg 58901e04c3fSmrg/** 5907ec681f3Smrg * Construct a mov that reswizzles the source's components. 59101e04c3fSmrg */ 59201e04c3fSmrgstatic inline nir_ssa_def * 59301e04c3fSmrgnir_swizzle(nir_builder *build, nir_ssa_def *src, const unsigned *swiz, 5947ec681f3Smrg unsigned num_components) 59501e04c3fSmrg{ 59601e04c3fSmrg assert(num_components <= NIR_MAX_VEC_COMPONENTS); 59701e04c3fSmrg nir_alu_src alu_src = { NIR_SRC_INIT }; 59801e04c3fSmrg alu_src.src = nir_src_for_ssa(src); 5997e102996Smaya 6007e102996Smaya bool is_identity_swizzle = true; 6017e102996Smaya for (unsigned i = 0; i < num_components && i < NIR_MAX_VEC_COMPONENTS; i++) { 6027e102996Smaya if (swiz[i] != i) 6037e102996Smaya is_identity_swizzle = false; 60401e04c3fSmrg alu_src.swizzle[i] = swiz[i]; 6057e102996Smaya } 6067e102996Smaya 6077e102996Smaya if (num_components == src->num_components && is_identity_swizzle) 6087e102996Smaya return src; 60901e04c3fSmrg 6107ec681f3Smrg return nir_mov_alu(build, alu_src, num_components); 61101e04c3fSmrg} 61201e04c3fSmrg 61301e04c3fSmrg/* Selects the right fdot given the number of components in each source. */ 61401e04c3fSmrgstatic inline nir_ssa_def * 61501e04c3fSmrgnir_fdot(nir_builder *build, nir_ssa_def *src0, nir_ssa_def *src1) 61601e04c3fSmrg{ 61701e04c3fSmrg assert(src0->num_components == src1->num_components); 61801e04c3fSmrg switch (src0->num_components) { 61901e04c3fSmrg case 1: return nir_fmul(build, src0, src1); 62001e04c3fSmrg case 2: return nir_fdot2(build, src0, src1); 62101e04c3fSmrg case 3: return nir_fdot3(build, src0, src1); 62201e04c3fSmrg case 4: return nir_fdot4(build, src0, src1); 6237ec681f3Smrg case 5: return nir_fdot5(build, src0, src1); 6247ec681f3Smrg case 8: return nir_fdot8(build, src0, src1); 6257ec681f3Smrg case 16: return nir_fdot16(build, src0, src1); 62601e04c3fSmrg default: 62701e04c3fSmrg unreachable("bad component size"); 62801e04c3fSmrg } 62901e04c3fSmrg 63001e04c3fSmrg return NULL; 63101e04c3fSmrg} 63201e04c3fSmrg 6337ec681f3Smrgstatic inline nir_ssa_def * 6347ec681f3Smrgnir_ball_iequal(nir_builder *b, nir_ssa_def *src0, nir_ssa_def *src1) 6357ec681f3Smrg{ 6367ec681f3Smrg switch (src0->num_components) { 6377ec681f3Smrg case 1: return nir_ieq(b, src0, src1); 6387ec681f3Smrg case 2: return nir_ball_iequal2(b, src0, src1); 6397ec681f3Smrg case 3: return nir_ball_iequal3(b, src0, src1); 6407ec681f3Smrg case 4: return nir_ball_iequal4(b, src0, src1); 6417ec681f3Smrg case 5: return nir_ball_iequal5(b, src0, src1); 6427ec681f3Smrg case 8: return nir_ball_iequal8(b, src0, src1); 6437ec681f3Smrg case 16: return nir_ball_iequal16(b, src0, src1); 6447ec681f3Smrg default: 6457ec681f3Smrg unreachable("bad component size"); 6467ec681f3Smrg } 6477ec681f3Smrg} 6487ec681f3Smrg 6497ec681f3Smrgstatic inline nir_ssa_def * 6507ec681f3Smrgnir_ball(nir_builder *b, nir_ssa_def *src) 6517ec681f3Smrg{ 6527ec681f3Smrg return nir_ball_iequal(b, src, nir_imm_true(b)); 6537ec681f3Smrg} 6547ec681f3Smrg 65501e04c3fSmrgstatic inline nir_ssa_def * 65601e04c3fSmrgnir_bany_inequal(nir_builder *b, nir_ssa_def *src0, nir_ssa_def *src1) 65701e04c3fSmrg{ 65801e04c3fSmrg switch (src0->num_components) { 65901e04c3fSmrg case 1: return nir_ine(b, src0, src1); 66001e04c3fSmrg case 2: return nir_bany_inequal2(b, src0, src1); 66101e04c3fSmrg case 3: return nir_bany_inequal3(b, src0, src1); 66201e04c3fSmrg case 4: return nir_bany_inequal4(b, src0, src1); 6637ec681f3Smrg case 5: return nir_bany_inequal5(b, src0, src1); 6647ec681f3Smrg case 8: return nir_bany_inequal8(b, src0, src1); 6657ec681f3Smrg case 16: return nir_bany_inequal16(b, src0, src1); 66601e04c3fSmrg default: 66701e04c3fSmrg unreachable("bad component size"); 66801e04c3fSmrg } 66901e04c3fSmrg} 67001e04c3fSmrg 67101e04c3fSmrgstatic inline nir_ssa_def * 67201e04c3fSmrgnir_bany(nir_builder *b, nir_ssa_def *src) 67301e04c3fSmrg{ 67401e04c3fSmrg return nir_bany_inequal(b, src, nir_imm_false(b)); 67501e04c3fSmrg} 67601e04c3fSmrg 67701e04c3fSmrgstatic inline nir_ssa_def * 67801e04c3fSmrgnir_channel(nir_builder *b, nir_ssa_def *def, unsigned c) 67901e04c3fSmrg{ 6807ec681f3Smrg return nir_swizzle(b, def, &c, 1); 68101e04c3fSmrg} 68201e04c3fSmrg 68301e04c3fSmrgstatic inline nir_ssa_def * 68401e04c3fSmrgnir_channels(nir_builder *b, nir_ssa_def *def, nir_component_mask_t mask) 68501e04c3fSmrg{ 68601e04c3fSmrg unsigned num_channels = 0, swizzle[NIR_MAX_VEC_COMPONENTS] = { 0 }; 68701e04c3fSmrg 68801e04c3fSmrg for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) { 68901e04c3fSmrg if ((mask & (1 << i)) == 0) 69001e04c3fSmrg continue; 69101e04c3fSmrg swizzle[num_channels++] = i; 69201e04c3fSmrg } 69301e04c3fSmrg 6947ec681f3Smrg return nir_swizzle(b, def, swizzle, num_channels); 69501e04c3fSmrg} 69601e04c3fSmrg 6977e102996Smayastatic inline nir_ssa_def * 6987ec681f3Smrg_nir_select_from_array_helper(nir_builder *b, nir_ssa_def **arr, 6997ec681f3Smrg nir_ssa_def *idx, 7007ec681f3Smrg unsigned start, unsigned end) 7017e102996Smaya{ 7027e102996Smaya if (start == end - 1) { 7037ec681f3Smrg return arr[start]; 7047e102996Smaya } else { 7057e102996Smaya unsigned mid = start + (end - start) / 2; 7067ec681f3Smrg return nir_bcsel(b, nir_ilt(b, idx, nir_imm_intN_t(b, mid, idx->bit_size)), 7077ec681f3Smrg _nir_select_from_array_helper(b, arr, idx, start, mid), 7087ec681f3Smrg _nir_select_from_array_helper(b, arr, idx, mid, end)); 7097e102996Smaya } 7107e102996Smaya} 7117e102996Smaya 7127ec681f3Smrgstatic inline nir_ssa_def * 7137ec681f3Smrgnir_select_from_ssa_def_array(nir_builder *b, nir_ssa_def **arr, 7147ec681f3Smrg unsigned arr_len, nir_ssa_def *idx) 7157ec681f3Smrg{ 7167ec681f3Smrg return _nir_select_from_array_helper(b, arr, idx, 0, arr_len); 7177ec681f3Smrg} 7187ec681f3Smrg 7197e102996Smayastatic inline nir_ssa_def * 7207e102996Smayanir_vector_extract(nir_builder *b, nir_ssa_def *vec, nir_ssa_def *c) 7217e102996Smaya{ 7227e102996Smaya nir_src c_src = nir_src_for_ssa(c); 7237e102996Smaya if (nir_src_is_const(c_src)) { 7247ec681f3Smrg uint64_t c_const = nir_src_as_uint(c_src); 7257e102996Smaya if (c_const < vec->num_components) 7267e102996Smaya return nir_channel(b, vec, c_const); 7277e102996Smaya else 7287e102996Smaya return nir_ssa_undef(b, 1, vec->bit_size); 7297e102996Smaya } else { 7307ec681f3Smrg nir_ssa_def *comps[NIR_MAX_VEC_COMPONENTS]; 7317ec681f3Smrg for (unsigned i = 0; i < vec->num_components; i++) 7327ec681f3Smrg comps[i] = nir_channel(b, vec, i); 7337ec681f3Smrg return nir_select_from_ssa_def_array(b, comps, vec->num_components, c); 7347ec681f3Smrg } 7357ec681f3Smrg} 7367ec681f3Smrg 7377ec681f3Smrg/** Replaces the component of `vec` specified by `c` with `scalar` */ 7387ec681f3Smrgstatic inline nir_ssa_def * 7397ec681f3Smrgnir_vector_insert_imm(nir_builder *b, nir_ssa_def *vec, 7407ec681f3Smrg nir_ssa_def *scalar, unsigned c) 7417ec681f3Smrg{ 7427ec681f3Smrg assert(scalar->num_components == 1); 7437ec681f3Smrg assert(c < vec->num_components); 7447ec681f3Smrg 7457ec681f3Smrg nir_op vec_op = nir_op_vec(vec->num_components); 7467ec681f3Smrg nir_alu_instr *vec_instr = nir_alu_instr_create(b->shader, vec_op); 7477ec681f3Smrg 7487ec681f3Smrg for (unsigned i = 0; i < vec->num_components; i++) { 7497ec681f3Smrg if (i == c) { 7507ec681f3Smrg vec_instr->src[i].src = nir_src_for_ssa(scalar); 7517ec681f3Smrg vec_instr->src[i].swizzle[0] = 0; 7527ec681f3Smrg } else { 7537ec681f3Smrg vec_instr->src[i].src = nir_src_for_ssa(vec); 7547ec681f3Smrg vec_instr->src[i].swizzle[0] = i; 7557ec681f3Smrg } 7567ec681f3Smrg } 7577ec681f3Smrg 7587ec681f3Smrg return nir_builder_alu_instr_finish_and_insert(b, vec_instr); 7597ec681f3Smrg} 7607ec681f3Smrg 7617ec681f3Smrg/** Replaces the component of `vec` specified by `c` with `scalar` */ 7627ec681f3Smrgstatic inline nir_ssa_def * 7637ec681f3Smrgnir_vector_insert(nir_builder *b, nir_ssa_def *vec, nir_ssa_def *scalar, 7647ec681f3Smrg nir_ssa_def *c) 7657ec681f3Smrg{ 7667ec681f3Smrg assert(scalar->num_components == 1); 7677ec681f3Smrg assert(c->num_components == 1); 7687ec681f3Smrg 7697ec681f3Smrg nir_src c_src = nir_src_for_ssa(c); 7707ec681f3Smrg if (nir_src_is_const(c_src)) { 7717ec681f3Smrg uint64_t c_const = nir_src_as_uint(c_src); 7727ec681f3Smrg if (c_const < vec->num_components) 7737ec681f3Smrg return nir_vector_insert_imm(b, vec, scalar, c_const); 7747ec681f3Smrg else 7757ec681f3Smrg return vec; 7767ec681f3Smrg } else { 7777ec681f3Smrg nir_const_value per_comp_idx_const[NIR_MAX_VEC_COMPONENTS]; 7787ec681f3Smrg for (unsigned i = 0; i < NIR_MAX_VEC_COMPONENTS; i++) 7797ec681f3Smrg per_comp_idx_const[i] = nir_const_value_for_int(i, c->bit_size); 7807ec681f3Smrg nir_ssa_def *per_comp_idx = 7817ec681f3Smrg nir_build_imm(b, vec->num_components, 7827ec681f3Smrg c->bit_size, per_comp_idx_const); 7837ec681f3Smrg 7847ec681f3Smrg /* nir_builder will automatically splat out scalars to vectors so an 7857ec681f3Smrg * insert is as simple as "if I'm the channel, replace me with the 7867ec681f3Smrg * scalar." 7877ec681f3Smrg */ 7887ec681f3Smrg return nir_bcsel(b, nir_ieq(b, c, per_comp_idx), scalar, vec); 7897e102996Smaya } 7907e102996Smaya} 7917e102996Smaya 7927e102996Smayastatic inline nir_ssa_def * 7937e102996Smayanir_i2i(nir_builder *build, nir_ssa_def *x, unsigned dest_bit_size) 7947e102996Smaya{ 7957e102996Smaya if (x->bit_size == dest_bit_size) 7967e102996Smaya return x; 7977e102996Smaya 7987e102996Smaya switch (dest_bit_size) { 7997e102996Smaya case 64: return nir_i2i64(build, x); 8007e102996Smaya case 32: return nir_i2i32(build, x); 8017e102996Smaya case 16: return nir_i2i16(build, x); 8027e102996Smaya case 8: return nir_i2i8(build, x); 8037e102996Smaya default: unreachable("Invalid bit size"); 8047e102996Smaya } 8057e102996Smaya} 8067e102996Smaya 8077e102996Smayastatic inline nir_ssa_def * 8087e102996Smayanir_u2u(nir_builder *build, nir_ssa_def *x, unsigned dest_bit_size) 8097e102996Smaya{ 8107e102996Smaya if (x->bit_size == dest_bit_size) 8117e102996Smaya return x; 8127e102996Smaya 8137e102996Smaya switch (dest_bit_size) { 8147e102996Smaya case 64: return nir_u2u64(build, x); 8157e102996Smaya case 32: return nir_u2u32(build, x); 8167e102996Smaya case 16: return nir_u2u16(build, x); 8177e102996Smaya case 8: return nir_u2u8(build, x); 8187e102996Smaya default: unreachable("Invalid bit size"); 8197e102996Smaya } 8207e102996Smaya} 8217e102996Smaya 8227e102996Smayastatic inline nir_ssa_def * 8237e102996Smayanir_iadd_imm(nir_builder *build, nir_ssa_def *x, uint64_t y) 8247e102996Smaya{ 8257e102996Smaya assert(x->bit_size <= 64); 8267ec681f3Smrg y &= BITFIELD64_MASK(x->bit_size); 8277e102996Smaya 8287e102996Smaya if (y == 0) { 8297e102996Smaya return x; 8307e102996Smaya } else { 8317e102996Smaya return nir_iadd(build, x, nir_imm_intN_t(build, y, x->bit_size)); 8327e102996Smaya } 8337e102996Smaya} 8347e102996Smaya 8357e102996Smayastatic inline nir_ssa_def * 8367ec681f3Smrgnir_iadd_imm_nuw(nir_builder *b, nir_ssa_def *x, uint64_t y) 8377ec681f3Smrg{ 8387ec681f3Smrg nir_ssa_def *d = nir_iadd_imm(b, x, y); 8397ec681f3Smrg if (d != x && d->parent_instr->type == nir_instr_type_alu) 8407ec681f3Smrg nir_instr_as_alu(d->parent_instr)->no_unsigned_wrap = true; 8417ec681f3Smrg return d; 8427ec681f3Smrg} 8437ec681f3Smrg 8447ec681f3Smrgstatic inline nir_ssa_def * 8457ec681f3Smrgnir_iadd_nuw(nir_builder *b, nir_ssa_def *x, nir_ssa_def *y) 8467ec681f3Smrg{ 8477ec681f3Smrg nir_ssa_def *d = nir_iadd(b, x, y); 8487ec681f3Smrg nir_instr_as_alu(d->parent_instr)->no_unsigned_wrap = true; 8497ec681f3Smrg return d; 8507ec681f3Smrg} 8517ec681f3Smrg 8527ec681f3Smrgstatic inline nir_ssa_def * 8537ec681f3Smrgnir_ieq_imm(nir_builder *build, nir_ssa_def *x, uint64_t y) 8547ec681f3Smrg{ 8557ec681f3Smrg return nir_ieq(build, x, nir_imm_intN_t(build, y, x->bit_size)); 8567ec681f3Smrg} 8577ec681f3Smrg 8587ec681f3Smrg/* Use nir_iadd(x, -y) for reversing parameter ordering */ 8597ec681f3Smrgstatic inline nir_ssa_def * 8607ec681f3Smrgnir_isub_imm(nir_builder *build, uint64_t y, nir_ssa_def *x) 8617ec681f3Smrg{ 8627ec681f3Smrg return nir_isub(build, nir_imm_intN_t(build, y, x->bit_size), x); 8637ec681f3Smrg} 8647ec681f3Smrg 8657ec681f3Smrgstatic inline nir_ssa_def * 8667ec681f3Smrg_nir_mul_imm(nir_builder *build, nir_ssa_def *x, uint64_t y, bool amul) 8677e102996Smaya{ 8687e102996Smaya assert(x->bit_size <= 64); 8697ec681f3Smrg y &= BITFIELD64_MASK(x->bit_size); 8707e102996Smaya 8717e102996Smaya if (y == 0) { 8727e102996Smaya return nir_imm_intN_t(build, 0, x->bit_size); 8737e102996Smaya } else if (y == 1) { 8747e102996Smaya return x; 8757ec681f3Smrg } else if (!build->shader->options->lower_bitops && 8767ec681f3Smrg util_is_power_of_two_or_zero64(y)) { 8777e102996Smaya return nir_ishl(build, x, nir_imm_int(build, ffsll(y) - 1)); 8787ec681f3Smrg } else if (amul) { 8797ec681f3Smrg return nir_amul(build, x, nir_imm_intN_t(build, y, x->bit_size)); 8807e102996Smaya } else { 8817e102996Smaya return nir_imul(build, x, nir_imm_intN_t(build, y, x->bit_size)); 8827e102996Smaya } 8837e102996Smaya} 8847e102996Smaya 8857ec681f3Smrgstatic inline nir_ssa_def * 8867ec681f3Smrgnir_imul_imm(nir_builder *build, nir_ssa_def *x, uint64_t y) 8877ec681f3Smrg{ 8887ec681f3Smrg return _nir_mul_imm(build, x, y, false); 8897ec681f3Smrg} 8907ec681f3Smrg 8917ec681f3Smrgstatic inline nir_ssa_def * 8927ec681f3Smrgnir_amul_imm(nir_builder *build, nir_ssa_def *x, uint64_t y) 8937ec681f3Smrg{ 8947ec681f3Smrg return _nir_mul_imm(build, x, y, true); 8957ec681f3Smrg} 8967ec681f3Smrg 8977e102996Smayastatic inline nir_ssa_def * 8987e102996Smayanir_fadd_imm(nir_builder *build, nir_ssa_def *x, double y) 8997e102996Smaya{ 9007e102996Smaya return nir_fadd(build, x, nir_imm_floatN_t(build, y, x->bit_size)); 9017e102996Smaya} 9027e102996Smaya 9037e102996Smayastatic inline nir_ssa_def * 9047e102996Smayanir_fmul_imm(nir_builder *build, nir_ssa_def *x, double y) 9057e102996Smaya{ 9067e102996Smaya return nir_fmul(build, x, nir_imm_floatN_t(build, y, x->bit_size)); 9077e102996Smaya} 9087e102996Smaya 9097ec681f3Smrgstatic inline nir_ssa_def * 9107ec681f3Smrgnir_iand_imm(nir_builder *build, nir_ssa_def *x, uint64_t y) 9117ec681f3Smrg{ 9127ec681f3Smrg assert(x->bit_size <= 64); 9137ec681f3Smrg y &= BITFIELD64_MASK(x->bit_size); 9147ec681f3Smrg 9157ec681f3Smrg if (y == 0) { 9167ec681f3Smrg return nir_imm_intN_t(build, 0, x->bit_size); 9177ec681f3Smrg } else if (y == BITFIELD64_MASK(x->bit_size)) { 9187ec681f3Smrg return x; 9197ec681f3Smrg } else { 9207ec681f3Smrg return nir_iand(build, x, nir_imm_intN_t(build, y, x->bit_size)); 9217ec681f3Smrg } 9227ec681f3Smrg} 9237ec681f3Smrg 9247ec681f3Smrgstatic inline nir_ssa_def * 9257ec681f3Smrgnir_ishr_imm(nir_builder *build, nir_ssa_def *x, uint32_t y) 9267ec681f3Smrg{ 9277ec681f3Smrg if (y == 0) { 9287ec681f3Smrg return x; 9297ec681f3Smrg } else { 9307ec681f3Smrg return nir_ishr(build, x, nir_imm_int(build, y)); 9317ec681f3Smrg } 9327ec681f3Smrg} 9337ec681f3Smrg 9347ec681f3Smrgstatic inline nir_ssa_def * 9357ec681f3Smrgnir_ushr_imm(nir_builder *build, nir_ssa_def *x, uint32_t y) 9367ec681f3Smrg{ 9377ec681f3Smrg if (y == 0) { 9387ec681f3Smrg return x; 9397ec681f3Smrg } else { 9407ec681f3Smrg return nir_ushr(build, x, nir_imm_int(build, y)); 9417ec681f3Smrg } 9427ec681f3Smrg} 9437ec681f3Smrg 9447ec681f3Smrgstatic inline nir_ssa_def * 9457ec681f3Smrgnir_udiv_imm(nir_builder *build, nir_ssa_def *x, uint64_t y) 9467ec681f3Smrg{ 9477ec681f3Smrg assert(x->bit_size <= 64); 9487ec681f3Smrg y &= BITFIELD64_MASK(x->bit_size); 9497ec681f3Smrg 9507ec681f3Smrg if (y == 1) { 9517ec681f3Smrg return x; 9527ec681f3Smrg } else if (util_is_power_of_two_nonzero(y)) { 9537ec681f3Smrg return nir_ushr_imm(build, x, ffsll(y) - 1); 9547ec681f3Smrg } else { 9557ec681f3Smrg return nir_udiv(build, x, nir_imm_intN_t(build, y, x->bit_size)); 9567ec681f3Smrg } 9577ec681f3Smrg} 9587ec681f3Smrg 9597ec681f3Smrgstatic inline nir_ssa_def * 9607ec681f3Smrgnir_fclamp(nir_builder *b, 9617ec681f3Smrg nir_ssa_def *x, nir_ssa_def *min_val, nir_ssa_def *max_val) 9627ec681f3Smrg{ 9637ec681f3Smrg return nir_fmin(b, nir_fmax(b, x, min_val), max_val); 9647ec681f3Smrg} 9657ec681f3Smrg 9667ec681f3Smrgstatic inline nir_ssa_def * 9677ec681f3Smrgnir_iclamp(nir_builder *b, 9687ec681f3Smrg nir_ssa_def *x, nir_ssa_def *min_val, nir_ssa_def *max_val) 9697ec681f3Smrg{ 9707ec681f3Smrg return nir_imin(b, nir_imax(b, x, min_val), max_val); 9717ec681f3Smrg} 9727ec681f3Smrg 9737ec681f3Smrgstatic inline nir_ssa_def * 9747ec681f3Smrgnir_uclamp(nir_builder *b, 9757ec681f3Smrg nir_ssa_def *x, nir_ssa_def *min_val, nir_ssa_def *max_val) 9767ec681f3Smrg{ 9777ec681f3Smrg return nir_umin(b, nir_umax(b, x, min_val), max_val); 9787ec681f3Smrg} 9797ec681f3Smrg 9807ec681f3Smrgstatic inline nir_ssa_def * 9817ec681f3Smrgnir_ffma_imm12(nir_builder *build, nir_ssa_def *src0, double src1, double src2) 9827ec681f3Smrg{ 9837ec681f3Smrg if (build->shader->options->avoid_ternary_with_two_constants) 9847ec681f3Smrg return nir_fadd_imm(build, nir_fmul_imm(build, src0, src1), src2); 9857ec681f3Smrg else 9867ec681f3Smrg return nir_ffma(build, src0, nir_imm_floatN_t(build, src1, src0->bit_size), 9877ec681f3Smrg nir_imm_floatN_t(build, src2, src0->bit_size)); 9887ec681f3Smrg} 9897ec681f3Smrg 9907ec681f3Smrgstatic inline nir_ssa_def * 9917ec681f3Smrgnir_ffma_imm1(nir_builder *build, nir_ssa_def *src0, double src1, nir_ssa_def *src2) 9927ec681f3Smrg{ 9937ec681f3Smrg return nir_ffma(build, src0, nir_imm_floatN_t(build, src1, src0->bit_size), src2); 9947ec681f3Smrg} 9957ec681f3Smrg 9967ec681f3Smrgstatic inline nir_ssa_def * 9977ec681f3Smrgnir_ffma_imm2(nir_builder *build, nir_ssa_def *src0, nir_ssa_def *src1, double src2) 9987ec681f3Smrg{ 9997ec681f3Smrg return nir_ffma(build, src0, src1, nir_imm_floatN_t(build, src2, src0->bit_size)); 10007ec681f3Smrg} 10017ec681f3Smrg 10027ec681f3Smrgstatic inline nir_ssa_def * 10037ec681f3Smrgnir_a_minus_bc(nir_builder *build, nir_ssa_def *src0, nir_ssa_def *src1, 10047ec681f3Smrg nir_ssa_def *src2) 10057ec681f3Smrg{ 10067ec681f3Smrg return nir_ffma(build, nir_fneg(build, src1), src2, src0); 10077ec681f3Smrg} 10087ec681f3Smrg 10097e102996Smayastatic inline nir_ssa_def * 10107e102996Smayanir_pack_bits(nir_builder *b, nir_ssa_def *src, unsigned dest_bit_size) 10117e102996Smaya{ 10127e102996Smaya assert(src->num_components * src->bit_size == dest_bit_size); 10137e102996Smaya 10147e102996Smaya switch (dest_bit_size) { 10157e102996Smaya case 64: 10167e102996Smaya switch (src->bit_size) { 10177e102996Smaya case 32: return nir_pack_64_2x32(b, src); 10187e102996Smaya case 16: return nir_pack_64_4x16(b, src); 10197e102996Smaya default: break; 10207e102996Smaya } 10217e102996Smaya break; 10227e102996Smaya 10237e102996Smaya case 32: 10247e102996Smaya if (src->bit_size == 16) 10257e102996Smaya return nir_pack_32_2x16(b, src); 10267e102996Smaya break; 10277e102996Smaya 10287e102996Smaya default: 10297e102996Smaya break; 10307e102996Smaya } 10317e102996Smaya 10327e102996Smaya /* If we got here, we have no dedicated unpack opcode. */ 10337e102996Smaya nir_ssa_def *dest = nir_imm_intN_t(b, 0, dest_bit_size); 10347e102996Smaya for (unsigned i = 0; i < src->num_components; i++) { 10357e102996Smaya nir_ssa_def *val = nir_u2u(b, nir_channel(b, src, i), dest_bit_size); 10367e102996Smaya val = nir_ishl(b, val, nir_imm_int(b, i * src->bit_size)); 10377e102996Smaya dest = nir_ior(b, dest, val); 10387e102996Smaya } 10397e102996Smaya return dest; 10407e102996Smaya} 10417e102996Smaya 10427e102996Smayastatic inline nir_ssa_def * 10437e102996Smayanir_unpack_bits(nir_builder *b, nir_ssa_def *src, unsigned dest_bit_size) 10447e102996Smaya{ 10457e102996Smaya assert(src->num_components == 1); 10467e102996Smaya assert(src->bit_size > dest_bit_size); 10477e102996Smaya const unsigned dest_num_components = src->bit_size / dest_bit_size; 10487e102996Smaya assert(dest_num_components <= NIR_MAX_VEC_COMPONENTS); 10497e102996Smaya 10507e102996Smaya switch (src->bit_size) { 10517e102996Smaya case 64: 10527e102996Smaya switch (dest_bit_size) { 10537e102996Smaya case 32: return nir_unpack_64_2x32(b, src); 10547e102996Smaya case 16: return nir_unpack_64_4x16(b, src); 10557e102996Smaya default: break; 10567e102996Smaya } 10577e102996Smaya break; 10587e102996Smaya 10597e102996Smaya case 32: 10607e102996Smaya if (dest_bit_size == 16) 10617e102996Smaya return nir_unpack_32_2x16(b, src); 10627e102996Smaya break; 10637e102996Smaya 10647e102996Smaya default: 10657e102996Smaya break; 10667e102996Smaya } 10677e102996Smaya 10687e102996Smaya /* If we got here, we have no dedicated unpack opcode. */ 10697e102996Smaya nir_ssa_def *dest_comps[NIR_MAX_VEC_COMPONENTS]; 10707e102996Smaya for (unsigned i = 0; i < dest_num_components; i++) { 10717ec681f3Smrg nir_ssa_def *val = nir_ushr_imm(b, src, i * dest_bit_size); 10727e102996Smaya dest_comps[i] = nir_u2u(b, val, dest_bit_size); 10737e102996Smaya } 10747e102996Smaya return nir_vec(b, dest_comps, dest_num_components); 10757e102996Smaya} 10767e102996Smaya 10777ec681f3Smrg/** 10787ec681f3Smrg * Treats srcs as if it's one big blob of bits and extracts the range of bits 10797ec681f3Smrg * given by 10807ec681f3Smrg * 10817ec681f3Smrg * [first_bit, first_bit + dest_num_components * dest_bit_size) 10827ec681f3Smrg * 10837ec681f3Smrg * The range can have any alignment or size as long as it's an integer number 10847ec681f3Smrg * of destination components and fits inside the concatenated sources. 10857ec681f3Smrg * 10867ec681f3Smrg * TODO: The one caveat here is that we can't handle byte alignment if 64-bit 10877ec681f3Smrg * values are involved because that would require pack/unpack to/from a vec8 10887ec681f3Smrg * which NIR currently does not support. 10897ec681f3Smrg */ 10907ec681f3Smrgstatic inline nir_ssa_def * 10917ec681f3Smrgnir_extract_bits(nir_builder *b, nir_ssa_def **srcs, unsigned num_srcs, 10927ec681f3Smrg unsigned first_bit, 10937ec681f3Smrg unsigned dest_num_components, unsigned dest_bit_size) 10947ec681f3Smrg{ 10957ec681f3Smrg const unsigned num_bits = dest_num_components * dest_bit_size; 10967ec681f3Smrg 10977ec681f3Smrg /* Figure out the common bit size */ 10987ec681f3Smrg unsigned common_bit_size = dest_bit_size; 10997ec681f3Smrg for (unsigned i = 0; i < num_srcs; i++) 11007ec681f3Smrg common_bit_size = MIN2(common_bit_size, srcs[i]->bit_size); 11017ec681f3Smrg if (first_bit > 0) 11027ec681f3Smrg common_bit_size = MIN2(common_bit_size, (1u << (ffs(first_bit) - 1))); 11037ec681f3Smrg 11047ec681f3Smrg /* We don't want to have to deal with 1-bit values */ 11057ec681f3Smrg assert(common_bit_size >= 8); 11067ec681f3Smrg 11077ec681f3Smrg nir_ssa_def *common_comps[NIR_MAX_VEC_COMPONENTS * sizeof(uint64_t)]; 11087ec681f3Smrg assert(num_bits / common_bit_size <= ARRAY_SIZE(common_comps)); 11097ec681f3Smrg 11107ec681f3Smrg /* First, unpack to the common bit size and select the components from the 11117ec681f3Smrg * source. 11127ec681f3Smrg */ 11137ec681f3Smrg int src_idx = -1; 11147ec681f3Smrg unsigned src_start_bit = 0; 11157ec681f3Smrg unsigned src_end_bit = 0; 11167ec681f3Smrg for (unsigned i = 0; i < num_bits / common_bit_size; i++) { 11177ec681f3Smrg const unsigned bit = first_bit + (i * common_bit_size); 11187ec681f3Smrg while (bit >= src_end_bit) { 11197ec681f3Smrg src_idx++; 11207ec681f3Smrg assert(src_idx < (int) num_srcs); 11217ec681f3Smrg src_start_bit = src_end_bit; 11227ec681f3Smrg src_end_bit += srcs[src_idx]->bit_size * 11237ec681f3Smrg srcs[src_idx]->num_components; 11247ec681f3Smrg } 11257ec681f3Smrg assert(bit >= src_start_bit); 11267ec681f3Smrg assert(bit + common_bit_size <= src_end_bit); 11277ec681f3Smrg const unsigned rel_bit = bit - src_start_bit; 11287ec681f3Smrg const unsigned src_bit_size = srcs[src_idx]->bit_size; 11297ec681f3Smrg 11307ec681f3Smrg nir_ssa_def *comp = nir_channel(b, srcs[src_idx], 11317ec681f3Smrg rel_bit / src_bit_size); 11327ec681f3Smrg if (srcs[src_idx]->bit_size > common_bit_size) { 11337ec681f3Smrg nir_ssa_def *unpacked = nir_unpack_bits(b, comp, common_bit_size); 11347ec681f3Smrg comp = nir_channel(b, unpacked, (rel_bit % src_bit_size) / 11357ec681f3Smrg common_bit_size); 11367ec681f3Smrg } 11377ec681f3Smrg common_comps[i] = comp; 11387ec681f3Smrg } 11397ec681f3Smrg 11407ec681f3Smrg /* Now, re-pack the destination if we have to */ 11417ec681f3Smrg if (dest_bit_size > common_bit_size) { 11427ec681f3Smrg unsigned common_per_dest = dest_bit_size / common_bit_size; 11437ec681f3Smrg nir_ssa_def *dest_comps[NIR_MAX_VEC_COMPONENTS]; 11447ec681f3Smrg for (unsigned i = 0; i < dest_num_components; i++) { 11457ec681f3Smrg nir_ssa_def *unpacked = nir_vec(b, common_comps + i * common_per_dest, 11467ec681f3Smrg common_per_dest); 11477ec681f3Smrg dest_comps[i] = nir_pack_bits(b, unpacked, dest_bit_size); 11487ec681f3Smrg } 11497ec681f3Smrg return nir_vec(b, dest_comps, dest_num_components); 11507ec681f3Smrg } else { 11517ec681f3Smrg assert(dest_bit_size == common_bit_size); 11527ec681f3Smrg return nir_vec(b, common_comps, dest_num_components); 11537ec681f3Smrg } 11547ec681f3Smrg} 11557ec681f3Smrg 11567e102996Smayastatic inline nir_ssa_def * 11577e102996Smayanir_bitcast_vector(nir_builder *b, nir_ssa_def *src, unsigned dest_bit_size) 11587e102996Smaya{ 11597e102996Smaya assert((src->bit_size * src->num_components) % dest_bit_size == 0); 11607e102996Smaya const unsigned dest_num_components = 11617e102996Smaya (src->bit_size * src->num_components) / dest_bit_size; 11627e102996Smaya assert(dest_num_components <= NIR_MAX_VEC_COMPONENTS); 11637e102996Smaya 11647ec681f3Smrg return nir_extract_bits(b, &src, 1, 0, dest_num_components, dest_bit_size); 11657ec681f3Smrg} 11667ec681f3Smrg 11677ec681f3Smrg/** 11687ec681f3Smrg * Pad a value to N components with undefs of matching bit size. 11697ec681f3Smrg * If the value already contains >= num_components, it is returned without change. 11707ec681f3Smrg */ 11717ec681f3Smrgstatic inline nir_ssa_def * 11727ec681f3Smrgnir_pad_vector(nir_builder *b, nir_ssa_def *src, unsigned num_components) 11737ec681f3Smrg{ 11747ec681f3Smrg assert(src->num_components <= num_components); 11757ec681f3Smrg if (src->num_components == num_components) 11767e102996Smaya return src; 11777ec681f3Smrg 11787ec681f3Smrg nir_ssa_def *components[NIR_MAX_VEC_COMPONENTS]; 11797ec681f3Smrg nir_ssa_def *undef = nir_ssa_undef(b, 1, src->bit_size); 11807ec681f3Smrg unsigned i = 0; 11817ec681f3Smrg for (; i < src->num_components; i++) 11827ec681f3Smrg components[i] = nir_channel(b, src, i); 11837ec681f3Smrg for (; i < num_components; i++) 11847ec681f3Smrg components[i] = undef; 11857ec681f3Smrg 11867ec681f3Smrg return nir_vec(b, components, num_components); 11877ec681f3Smrg} 11887ec681f3Smrg 11897ec681f3Smrg/** 11907ec681f3Smrg * Pad a value to N components with copies of the given immediate of matching 11917ec681f3Smrg * bit size. If the value already contains >= num_components, it is returned 11927ec681f3Smrg * without change. 11937ec681f3Smrg */ 11947ec681f3Smrgstatic inline nir_ssa_def * 11957ec681f3Smrgnir_pad_vector_imm_int(nir_builder *b, nir_ssa_def *src, uint64_t imm_val, 11967ec681f3Smrg unsigned num_components) 11977ec681f3Smrg{ 11987ec681f3Smrg assert(src->num_components <= num_components); 11997ec681f3Smrg if (src->num_components == num_components) 12007ec681f3Smrg return src; 12017ec681f3Smrg 12027ec681f3Smrg nir_ssa_def *components[NIR_MAX_VEC_COMPONENTS]; 12037ec681f3Smrg nir_ssa_def *imm = nir_imm_intN_t(b, imm_val, src->bit_size); 12047ec681f3Smrg unsigned i = 0; 12057ec681f3Smrg for (; i < src->num_components; i++) 12067ec681f3Smrg components[i] = nir_channel(b, src, i); 12077ec681f3Smrg for (; i < num_components; i++) 12087ec681f3Smrg components[i] = imm; 12097ec681f3Smrg 12107ec681f3Smrg return nir_vec(b, components, num_components); 12117ec681f3Smrg} 12127ec681f3Smrg 12137ec681f3Smrg/** 12147ec681f3Smrg * Pad a value to 4 components with undefs of matching bit size. 12157ec681f3Smrg * If the value already contains >= 4 components, it is returned without change. 12167ec681f3Smrg */ 12177ec681f3Smrgstatic inline nir_ssa_def * 12187ec681f3Smrgnir_pad_vec4(nir_builder *b, nir_ssa_def *src) 12197ec681f3Smrg{ 12207ec681f3Smrg return nir_pad_vector(b, src, 4); 12217e102996Smaya} 12227e102996Smaya 122301e04c3fSmrg/** 122401e04c3fSmrg * Turns a nir_src into a nir_ssa_def * so it can be passed to 122501e04c3fSmrg * nir_build_alu()-based builder calls. 122601e04c3fSmrg * 122701e04c3fSmrg * See nir_ssa_for_alu_src() for alu instructions. 122801e04c3fSmrg */ 122901e04c3fSmrgstatic inline nir_ssa_def * 123001e04c3fSmrgnir_ssa_for_src(nir_builder *build, nir_src src, int num_components) 123101e04c3fSmrg{ 123201e04c3fSmrg if (src.is_ssa && src.ssa->num_components == num_components) 123301e04c3fSmrg return src.ssa; 123401e04c3fSmrg 12357ec681f3Smrg assert((unsigned)num_components <= nir_src_num_components(src)); 12367ec681f3Smrg 123701e04c3fSmrg nir_alu_src alu = { NIR_SRC_INIT }; 123801e04c3fSmrg alu.src = src; 12397ec681f3Smrg for (int j = 0; j < NIR_MAX_VEC_COMPONENTS; j++) 124001e04c3fSmrg alu.swizzle[j] = j; 124101e04c3fSmrg 12427ec681f3Smrg return nir_mov_alu(build, alu, num_components); 124301e04c3fSmrg} 124401e04c3fSmrg 124501e04c3fSmrg/** 124601e04c3fSmrg * Similar to nir_ssa_for_src(), but for alu srcs, respecting the 124701e04c3fSmrg * nir_alu_src's swizzle. 124801e04c3fSmrg */ 124901e04c3fSmrgstatic inline nir_ssa_def * 125001e04c3fSmrgnir_ssa_for_alu_src(nir_builder *build, nir_alu_instr *instr, unsigned srcn) 125101e04c3fSmrg{ 12527ec681f3Smrg if (nir_alu_src_is_trivial_ssa(instr, srcn)) 12537ec681f3Smrg return instr->src[srcn].src.ssa; 12547ec681f3Smrg 125501e04c3fSmrg nir_alu_src *src = &instr->src[srcn]; 125601e04c3fSmrg unsigned num_components = nir_ssa_alu_instr_src_components(instr, srcn); 12577ec681f3Smrg return nir_mov_alu(build, *src, num_components); 125801e04c3fSmrg} 125901e04c3fSmrg 12607e102996Smayastatic inline unsigned 12617ec681f3Smrgnir_get_ptr_bitsize(nir_shader *shader) 12627e102996Smaya{ 12637ec681f3Smrg if (shader->info.stage == MESA_SHADER_KERNEL) 12647ec681f3Smrg return shader->info.cs.ptr_size; 12657e102996Smaya return 32; 12667e102996Smaya} 12677e102996Smaya 126801e04c3fSmrgstatic inline nir_deref_instr * 126901e04c3fSmrgnir_build_deref_var(nir_builder *build, nir_variable *var) 127001e04c3fSmrg{ 127101e04c3fSmrg nir_deref_instr *deref = 127201e04c3fSmrg nir_deref_instr_create(build->shader, nir_deref_type_var); 127301e04c3fSmrg 12747ec681f3Smrg deref->modes = (nir_variable_mode)var->data.mode; 127501e04c3fSmrg deref->type = var->type; 127601e04c3fSmrg deref->var = var; 127701e04c3fSmrg 12787e102996Smaya nir_ssa_dest_init(&deref->instr, &deref->dest, 1, 12797ec681f3Smrg nir_get_ptr_bitsize(build->shader), NULL); 128001e04c3fSmrg 128101e04c3fSmrg nir_builder_instr_insert(build, &deref->instr); 128201e04c3fSmrg 128301e04c3fSmrg return deref; 128401e04c3fSmrg} 128501e04c3fSmrg 128601e04c3fSmrgstatic inline nir_deref_instr * 128701e04c3fSmrgnir_build_deref_array(nir_builder *build, nir_deref_instr *parent, 128801e04c3fSmrg nir_ssa_def *index) 128901e04c3fSmrg{ 129001e04c3fSmrg assert(glsl_type_is_array(parent->type) || 129101e04c3fSmrg glsl_type_is_matrix(parent->type) || 129201e04c3fSmrg glsl_type_is_vector(parent->type)); 129301e04c3fSmrg 12947e102996Smaya assert(index->bit_size == parent->dest.ssa.bit_size); 12957e102996Smaya 129601e04c3fSmrg nir_deref_instr *deref = 129701e04c3fSmrg nir_deref_instr_create(build->shader, nir_deref_type_array); 129801e04c3fSmrg 12997ec681f3Smrg deref->modes = parent->modes; 130001e04c3fSmrg deref->type = glsl_get_array_element(parent->type); 130101e04c3fSmrg deref->parent = nir_src_for_ssa(&parent->dest.ssa); 130201e04c3fSmrg deref->arr.index = nir_src_for_ssa(index); 130301e04c3fSmrg 130401e04c3fSmrg nir_ssa_dest_init(&deref->instr, &deref->dest, 130501e04c3fSmrg parent->dest.ssa.num_components, 130601e04c3fSmrg parent->dest.ssa.bit_size, NULL); 130701e04c3fSmrg 130801e04c3fSmrg nir_builder_instr_insert(build, &deref->instr); 130901e04c3fSmrg 131001e04c3fSmrg return deref; 131101e04c3fSmrg} 131201e04c3fSmrg 13137e102996Smayastatic inline nir_deref_instr * 13147e102996Smayanir_build_deref_array_imm(nir_builder *build, nir_deref_instr *parent, 13157e102996Smaya int64_t index) 13167e102996Smaya{ 13177e102996Smaya assert(parent->dest.is_ssa); 13187e102996Smaya nir_ssa_def *idx_ssa = nir_imm_intN_t(build, index, 13197e102996Smaya parent->dest.ssa.bit_size); 13207e102996Smaya 13217e102996Smaya return nir_build_deref_array(build, parent, idx_ssa); 13227e102996Smaya} 13237e102996Smaya 13247e102996Smayastatic inline nir_deref_instr * 13257e102996Smayanir_build_deref_ptr_as_array(nir_builder *build, nir_deref_instr *parent, 13267e102996Smaya nir_ssa_def *index) 13277e102996Smaya{ 13287e102996Smaya assert(parent->deref_type == nir_deref_type_array || 13297e102996Smaya parent->deref_type == nir_deref_type_ptr_as_array || 13307e102996Smaya parent->deref_type == nir_deref_type_cast); 13317e102996Smaya 13327e102996Smaya assert(index->bit_size == parent->dest.ssa.bit_size); 13337e102996Smaya 13347e102996Smaya nir_deref_instr *deref = 13357e102996Smaya nir_deref_instr_create(build->shader, nir_deref_type_ptr_as_array); 13367e102996Smaya 13377ec681f3Smrg deref->modes = parent->modes; 13387e102996Smaya deref->type = parent->type; 13397e102996Smaya deref->parent = nir_src_for_ssa(&parent->dest.ssa); 13407e102996Smaya deref->arr.index = nir_src_for_ssa(index); 13417e102996Smaya 13427e102996Smaya nir_ssa_dest_init(&deref->instr, &deref->dest, 13437e102996Smaya parent->dest.ssa.num_components, 13447e102996Smaya parent->dest.ssa.bit_size, NULL); 13457e102996Smaya 13467e102996Smaya nir_builder_instr_insert(build, &deref->instr); 13477e102996Smaya 13487e102996Smaya return deref; 13497e102996Smaya} 13507e102996Smaya 135101e04c3fSmrgstatic inline nir_deref_instr * 135201e04c3fSmrgnir_build_deref_array_wildcard(nir_builder *build, nir_deref_instr *parent) 135301e04c3fSmrg{ 135401e04c3fSmrg assert(glsl_type_is_array(parent->type) || 135501e04c3fSmrg glsl_type_is_matrix(parent->type)); 135601e04c3fSmrg 135701e04c3fSmrg nir_deref_instr *deref = 135801e04c3fSmrg nir_deref_instr_create(build->shader, nir_deref_type_array_wildcard); 135901e04c3fSmrg 13607ec681f3Smrg deref->modes = parent->modes; 136101e04c3fSmrg deref->type = glsl_get_array_element(parent->type); 136201e04c3fSmrg deref->parent = nir_src_for_ssa(&parent->dest.ssa); 136301e04c3fSmrg 136401e04c3fSmrg nir_ssa_dest_init(&deref->instr, &deref->dest, 136501e04c3fSmrg parent->dest.ssa.num_components, 136601e04c3fSmrg parent->dest.ssa.bit_size, NULL); 136701e04c3fSmrg 136801e04c3fSmrg nir_builder_instr_insert(build, &deref->instr); 136901e04c3fSmrg 137001e04c3fSmrg return deref; 137101e04c3fSmrg} 137201e04c3fSmrg 137301e04c3fSmrgstatic inline nir_deref_instr * 137401e04c3fSmrgnir_build_deref_struct(nir_builder *build, nir_deref_instr *parent, 137501e04c3fSmrg unsigned index) 137601e04c3fSmrg{ 13777e102996Smaya assert(glsl_type_is_struct_or_ifc(parent->type)); 137801e04c3fSmrg 137901e04c3fSmrg nir_deref_instr *deref = 138001e04c3fSmrg nir_deref_instr_create(build->shader, nir_deref_type_struct); 138101e04c3fSmrg 13827ec681f3Smrg deref->modes = parent->modes; 138301e04c3fSmrg deref->type = glsl_get_struct_field(parent->type, index); 138401e04c3fSmrg deref->parent = nir_src_for_ssa(&parent->dest.ssa); 138501e04c3fSmrg deref->strct.index = index; 138601e04c3fSmrg 138701e04c3fSmrg nir_ssa_dest_init(&deref->instr, &deref->dest, 138801e04c3fSmrg parent->dest.ssa.num_components, 138901e04c3fSmrg parent->dest.ssa.bit_size, NULL); 139001e04c3fSmrg 139101e04c3fSmrg nir_builder_instr_insert(build, &deref->instr); 139201e04c3fSmrg 139301e04c3fSmrg return deref; 139401e04c3fSmrg} 139501e04c3fSmrg 139601e04c3fSmrgstatic inline nir_deref_instr * 139701e04c3fSmrgnir_build_deref_cast(nir_builder *build, nir_ssa_def *parent, 13987ec681f3Smrg nir_variable_mode modes, const struct glsl_type *type, 13997e102996Smaya unsigned ptr_stride) 140001e04c3fSmrg{ 140101e04c3fSmrg nir_deref_instr *deref = 140201e04c3fSmrg nir_deref_instr_create(build->shader, nir_deref_type_cast); 140301e04c3fSmrg 14047ec681f3Smrg deref->modes = modes; 140501e04c3fSmrg deref->type = type; 140601e04c3fSmrg deref->parent = nir_src_for_ssa(parent); 14077e102996Smaya deref->cast.ptr_stride = ptr_stride; 140801e04c3fSmrg 140901e04c3fSmrg nir_ssa_dest_init(&deref->instr, &deref->dest, 141001e04c3fSmrg parent->num_components, parent->bit_size, NULL); 141101e04c3fSmrg 141201e04c3fSmrg nir_builder_instr_insert(build, &deref->instr); 141301e04c3fSmrg 141401e04c3fSmrg return deref; 141501e04c3fSmrg} 141601e04c3fSmrg 14177ec681f3Smrgstatic inline nir_deref_instr * 14187ec681f3Smrgnir_alignment_deref_cast(nir_builder *build, nir_deref_instr *parent, 14197ec681f3Smrg uint32_t align_mul, uint32_t align_offset) 14207ec681f3Smrg{ 14217ec681f3Smrg nir_deref_instr *deref = 14227ec681f3Smrg nir_deref_instr_create(build->shader, nir_deref_type_cast); 14237ec681f3Smrg 14247ec681f3Smrg deref->modes = parent->modes; 14257ec681f3Smrg deref->type = parent->type; 14267ec681f3Smrg deref->parent = nir_src_for_ssa(&parent->dest.ssa); 14277ec681f3Smrg deref->cast.ptr_stride = nir_deref_instr_array_stride(deref); 14287ec681f3Smrg deref->cast.align_mul = align_mul; 14297ec681f3Smrg deref->cast.align_offset = align_offset; 14307ec681f3Smrg 14317ec681f3Smrg nir_ssa_dest_init(&deref->instr, &deref->dest, 14327ec681f3Smrg parent->dest.ssa.num_components, 14337ec681f3Smrg parent->dest.ssa.bit_size, NULL); 14347ec681f3Smrg 14357ec681f3Smrg nir_builder_instr_insert(build, &deref->instr); 14367ec681f3Smrg 14377ec681f3Smrg return deref; 14387ec681f3Smrg} 14397ec681f3Smrg 144001e04c3fSmrg/** Returns a deref that follows another but starting from the given parent 144101e04c3fSmrg * 144201e04c3fSmrg * The new deref will be the same type and take the same array or struct index 144301e04c3fSmrg * as the leader deref but it may have a different parent. This is very 144401e04c3fSmrg * useful for walking deref paths. 144501e04c3fSmrg */ 144601e04c3fSmrgstatic inline nir_deref_instr * 144701e04c3fSmrgnir_build_deref_follower(nir_builder *b, nir_deref_instr *parent, 144801e04c3fSmrg nir_deref_instr *leader) 144901e04c3fSmrg{ 145001e04c3fSmrg /* If the derefs would have the same parent, don't make a new one */ 145101e04c3fSmrg assert(leader->parent.is_ssa); 145201e04c3fSmrg if (leader->parent.ssa == &parent->dest.ssa) 145301e04c3fSmrg return leader; 145401e04c3fSmrg 145501e04c3fSmrg UNUSED nir_deref_instr *leader_parent = nir_src_as_deref(leader->parent); 145601e04c3fSmrg 145701e04c3fSmrg switch (leader->deref_type) { 145801e04c3fSmrg case nir_deref_type_var: 145901e04c3fSmrg unreachable("A var dereference cannot have a parent"); 146001e04c3fSmrg break; 146101e04c3fSmrg 146201e04c3fSmrg case nir_deref_type_array: 146301e04c3fSmrg case nir_deref_type_array_wildcard: 146401e04c3fSmrg assert(glsl_type_is_matrix(parent->type) || 14657e102996Smaya glsl_type_is_array(parent->type) || 14667e102996Smaya (leader->deref_type == nir_deref_type_array && 14677e102996Smaya glsl_type_is_vector(parent->type))); 146801e04c3fSmrg assert(glsl_get_length(parent->type) == 146901e04c3fSmrg glsl_get_length(leader_parent->type)); 147001e04c3fSmrg 147101e04c3fSmrg if (leader->deref_type == nir_deref_type_array) { 147201e04c3fSmrg assert(leader->arr.index.is_ssa); 14737e102996Smaya nir_ssa_def *index = nir_i2i(b, leader->arr.index.ssa, 14747e102996Smaya parent->dest.ssa.bit_size); 14757e102996Smaya return nir_build_deref_array(b, parent, index); 147601e04c3fSmrg } else { 147701e04c3fSmrg return nir_build_deref_array_wildcard(b, parent); 147801e04c3fSmrg } 147901e04c3fSmrg 148001e04c3fSmrg case nir_deref_type_struct: 14817e102996Smaya assert(glsl_type_is_struct_or_ifc(parent->type)); 148201e04c3fSmrg assert(glsl_get_length(parent->type) == 148301e04c3fSmrg glsl_get_length(leader_parent->type)); 148401e04c3fSmrg 148501e04c3fSmrg return nir_build_deref_struct(b, parent, leader->strct.index); 148601e04c3fSmrg 148701e04c3fSmrg default: 148801e04c3fSmrg unreachable("Invalid deref instruction type"); 148901e04c3fSmrg } 149001e04c3fSmrg} 149101e04c3fSmrg 149201e04c3fSmrgstatic inline nir_ssa_def * 149301e04c3fSmrgnir_load_reg(nir_builder *build, nir_register *reg) 149401e04c3fSmrg{ 149501e04c3fSmrg return nir_ssa_for_src(build, nir_src_for_reg(reg), reg->num_components); 149601e04c3fSmrg} 149701e04c3fSmrg 14987ec681f3Smrgstatic inline void 14997ec681f3Smrgnir_store_reg(nir_builder *build, nir_register *reg, 15007ec681f3Smrg nir_ssa_def *def, nir_component_mask_t write_mask) 15017ec681f3Smrg{ 15027ec681f3Smrg assert(reg->num_components == def->num_components); 15037ec681f3Smrg assert(reg->bit_size == def->bit_size); 15047ec681f3Smrg 15057ec681f3Smrg nir_alu_instr *mov = nir_alu_instr_create(build->shader, nir_op_mov); 15067ec681f3Smrg mov->src[0].src = nir_src_for_ssa(def); 15077ec681f3Smrg mov->dest.dest = nir_dest_for_reg(reg); 15087ec681f3Smrg mov->dest.write_mask = write_mask & BITFIELD_MASK(reg->num_components); 15097ec681f3Smrg nir_builder_instr_insert(build, &mov->instr); 15107ec681f3Smrg} 15117ec681f3Smrg 151201e04c3fSmrgstatic inline nir_ssa_def * 15137e102996Smayanir_load_deref_with_access(nir_builder *build, nir_deref_instr *deref, 15147e102996Smaya enum gl_access_qualifier access) 151501e04c3fSmrg{ 15167ec681f3Smrg return nir_build_load_deref(build, glsl_get_vector_elements(deref->type), 15177ec681f3Smrg glsl_get_bit_size(deref->type), &deref->dest.ssa, 15187ec681f3Smrg access); 151901e04c3fSmrg} 152001e04c3fSmrg 15217ec681f3Smrg#undef nir_load_deref 15227e102996Smayastatic inline nir_ssa_def * 15237e102996Smayanir_load_deref(nir_builder *build, nir_deref_instr *deref) 15247e102996Smaya{ 15257e102996Smaya return nir_load_deref_with_access(build, deref, (enum gl_access_qualifier)0); 15267e102996Smaya} 15277e102996Smaya 152801e04c3fSmrgstatic inline void 15297e102996Smayanir_store_deref_with_access(nir_builder *build, nir_deref_instr *deref, 15307e102996Smaya nir_ssa_def *value, unsigned writemask, 15317e102996Smaya enum gl_access_qualifier access) 153201e04c3fSmrg{ 15337ec681f3Smrg writemask &= (1u << value->num_components) - 1u; 15347ec681f3Smrg nir_build_store_deref(build, &deref->dest.ssa, value, writemask, access); 153501e04c3fSmrg} 153601e04c3fSmrg 15377ec681f3Smrg#undef nir_store_deref 153801e04c3fSmrgstatic inline void 15397e102996Smayanir_store_deref(nir_builder *build, nir_deref_instr *deref, 15407e102996Smaya nir_ssa_def *value, unsigned writemask) 15417e102996Smaya{ 15427e102996Smaya nir_store_deref_with_access(build, deref, value, writemask, 15437e102996Smaya (enum gl_access_qualifier)0); 15447e102996Smaya} 15457e102996Smaya 15467e102996Smayastatic inline void 15477e102996Smayanir_copy_deref_with_access(nir_builder *build, nir_deref_instr *dest, 15487e102996Smaya nir_deref_instr *src, 15497e102996Smaya enum gl_access_qualifier dest_access, 15507e102996Smaya enum gl_access_qualifier src_access) 155101e04c3fSmrg{ 15527ec681f3Smrg nir_build_copy_deref(build, &dest->dest.ssa, &src->dest.ssa, dest_access, src_access); 155301e04c3fSmrg} 155401e04c3fSmrg 15557ec681f3Smrg#undef nir_copy_deref 15567e102996Smayastatic inline void 15577e102996Smayanir_copy_deref(nir_builder *build, nir_deref_instr *dest, nir_deref_instr *src) 15587e102996Smaya{ 15597e102996Smaya nir_copy_deref_with_access(build, dest, src, 15607e102996Smaya (enum gl_access_qualifier) 0, 15617e102996Smaya (enum gl_access_qualifier) 0); 15627e102996Smaya} 15637e102996Smaya 15647ec681f3Smrgstatic inline void 15657ec681f3Smrgnir_memcpy_deref_with_access(nir_builder *build, nir_deref_instr *dest, 15667ec681f3Smrg nir_deref_instr *src, nir_ssa_def *size, 15677ec681f3Smrg enum gl_access_qualifier dest_access, 15687ec681f3Smrg enum gl_access_qualifier src_access) 15697ec681f3Smrg{ 15707ec681f3Smrg nir_build_memcpy_deref(build, &dest->dest.ssa, &src->dest.ssa, 15717ec681f3Smrg size, dest_access, src_access); 15727ec681f3Smrg} 15737ec681f3Smrg 15747ec681f3Smrg#undef nir_memcpy_deref 15757ec681f3Smrgstatic inline void 15767ec681f3Smrgnir_memcpy_deref(nir_builder *build, nir_deref_instr *dest, 15777ec681f3Smrg nir_deref_instr *src, nir_ssa_def *size) 15787ec681f3Smrg{ 15797ec681f3Smrg nir_memcpy_deref_with_access(build, dest, src, size, 15807ec681f3Smrg (enum gl_access_qualifier)0, 15817ec681f3Smrg (enum gl_access_qualifier)0); 15827ec681f3Smrg} 15837ec681f3Smrg 158401e04c3fSmrgstatic inline nir_ssa_def * 158501e04c3fSmrgnir_load_var(nir_builder *build, nir_variable *var) 158601e04c3fSmrg{ 158701e04c3fSmrg return nir_load_deref(build, nir_build_deref_var(build, var)); 158801e04c3fSmrg} 158901e04c3fSmrg 159001e04c3fSmrgstatic inline void 159101e04c3fSmrgnir_store_var(nir_builder *build, nir_variable *var, nir_ssa_def *value, 159201e04c3fSmrg unsigned writemask) 159301e04c3fSmrg{ 159401e04c3fSmrg nir_store_deref(build, nir_build_deref_var(build, var), value, writemask); 159501e04c3fSmrg} 159601e04c3fSmrg 159701e04c3fSmrgstatic inline void 159801e04c3fSmrgnir_copy_var(nir_builder *build, nir_variable *dest, nir_variable *src) 159901e04c3fSmrg{ 160001e04c3fSmrg nir_copy_deref(build, nir_build_deref_var(build, dest), 160101e04c3fSmrg nir_build_deref_var(build, src)); 160201e04c3fSmrg} 160301e04c3fSmrg 16047ec681f3Smrg#undef nir_load_global 160501e04c3fSmrgstatic inline nir_ssa_def * 16067ec681f3Smrgnir_load_global(nir_builder *build, nir_ssa_def *addr, unsigned align, 16077ec681f3Smrg unsigned num_components, unsigned bit_size) 160801e04c3fSmrg{ 16097ec681f3Smrg nir_intrinsic_instr *load = 16107ec681f3Smrg nir_intrinsic_instr_create(build->shader, nir_intrinsic_load_global); 16117ec681f3Smrg load->num_components = num_components; 16127ec681f3Smrg load->src[0] = nir_src_for_ssa(addr); 16137ec681f3Smrg nir_intrinsic_set_align(load, align, 0); 16147ec681f3Smrg nir_ssa_dest_init(&load->instr, &load->dest, 16157ec681f3Smrg num_components, bit_size, NULL); 16167ec681f3Smrg nir_builder_instr_insert(build, &load->instr); 16177ec681f3Smrg return &load->dest.ssa; 16187ec681f3Smrg} 16197ec681f3Smrg 16207ec681f3Smrg#undef nir_store_global 16217ec681f3Smrgstatic inline void 16227ec681f3Smrgnir_store_global(nir_builder *build, nir_ssa_def *addr, unsigned align, 16237ec681f3Smrg nir_ssa_def *value, nir_component_mask_t write_mask) 16247ec681f3Smrg{ 16257ec681f3Smrg nir_intrinsic_instr *store = 16267ec681f3Smrg nir_intrinsic_instr_create(build->shader, nir_intrinsic_store_global); 16277ec681f3Smrg store->num_components = value->num_components; 16287ec681f3Smrg store->src[0] = nir_src_for_ssa(value); 16297ec681f3Smrg store->src[1] = nir_src_for_ssa(addr); 16307ec681f3Smrg nir_intrinsic_set_write_mask(store, 16317ec681f3Smrg write_mask & BITFIELD_MASK(value->num_components)); 16327ec681f3Smrg nir_intrinsic_set_align(store, align, 0); 16337ec681f3Smrg nir_builder_instr_insert(build, &store->instr); 16347ec681f3Smrg} 163501e04c3fSmrg 16367ec681f3Smrg#undef nir_load_global_constant 16377ec681f3Smrgstatic inline nir_ssa_def * 16387ec681f3Smrgnir_load_global_constant(nir_builder *build, nir_ssa_def *addr, unsigned align, 16397ec681f3Smrg unsigned num_components, unsigned bit_size) 16407ec681f3Smrg{ 164101e04c3fSmrg nir_intrinsic_instr *load = 16427ec681f3Smrg nir_intrinsic_instr_create(build->shader, nir_intrinsic_load_global_constant); 16437ec681f3Smrg load->num_components = num_components; 16447ec681f3Smrg load->src[0] = nir_src_for_ssa(addr); 16457ec681f3Smrg nir_intrinsic_set_align(load, align, 0); 164601e04c3fSmrg nir_ssa_dest_init(&load->instr, &load->dest, 16477ec681f3Smrg num_components, bit_size, NULL); 164801e04c3fSmrg nir_builder_instr_insert(build, &load->instr); 164901e04c3fSmrg return &load->dest.ssa; 165001e04c3fSmrg} 165101e04c3fSmrg 16527ec681f3Smrg#undef nir_load_param 16537ec681f3Smrgstatic inline nir_ssa_def * 16547ec681f3Smrgnir_load_param(nir_builder *build, uint32_t param_idx) 16557ec681f3Smrg{ 16567ec681f3Smrg assert(param_idx < build->impl->function->num_params); 16577ec681f3Smrg nir_parameter *param = &build->impl->function->params[param_idx]; 16587ec681f3Smrg return nir_build_load_param(build, param->num_components, param->bit_size, param_idx); 16597ec681f3Smrg} 16607ec681f3Smrg 16617ec681f3Smrg/** 16627ec681f3Smrg * This function takes an I/O intrinsic like load/store_input, 16637ec681f3Smrg * and emits a sequence that calculates the full offset of that instruction, 16647ec681f3Smrg * including a stride to the base and component offsets. 16657ec681f3Smrg */ 16667ec681f3Smrgstatic inline nir_ssa_def * 16677ec681f3Smrgnir_build_calc_io_offset(nir_builder *b, 16687ec681f3Smrg nir_intrinsic_instr *intrin, 16697ec681f3Smrg nir_ssa_def *base_stride, 16707ec681f3Smrg unsigned component_stride) 16717ec681f3Smrg{ 16727ec681f3Smrg /* base is the driver_location, which is in slots (1 slot = 4x4 bytes) */ 16737ec681f3Smrg nir_ssa_def *base_op = nir_imul_imm(b, base_stride, nir_intrinsic_base(intrin)); 16747ec681f3Smrg 16757ec681f3Smrg /* offset should be interpreted in relation to the base, 16767ec681f3Smrg * so the instruction effectively reads/writes another input/output 16777ec681f3Smrg * when it has an offset 16787ec681f3Smrg */ 16797ec681f3Smrg nir_ssa_def *offset_op = nir_imul(b, base_stride, nir_ssa_for_src(b, *nir_get_io_offset_src(intrin), 1)); 16807ec681f3Smrg 16817ec681f3Smrg /* component is in bytes */ 16827ec681f3Smrg unsigned const_op = nir_intrinsic_component(intrin) * component_stride; 16837ec681f3Smrg 16847ec681f3Smrg return nir_iadd_imm_nuw(b, nir_iadd_nuw(b, base_op, offset_op), const_op); 16857ec681f3Smrg} 16867ec681f3Smrg 16877ec681f3Smrg/* calculate a `(1 << value) - 1` in ssa without overflows */ 16887ec681f3Smrgstatic inline nir_ssa_def * 16897ec681f3Smrgnir_mask(nir_builder *b, nir_ssa_def *bits, unsigned dst_bit_size) 16907ec681f3Smrg{ 16917ec681f3Smrg return nir_ushr(b, nir_imm_intN_t(b, -1, dst_bit_size), 16927ec681f3Smrg nir_isub_imm(b, dst_bit_size, nir_u2u32(b, bits))); 16937ec681f3Smrg} 169401e04c3fSmrg 16957e102996Smayastatic inline nir_ssa_def * 16967e102996Smayanir_f2b(nir_builder *build, nir_ssa_def *f) 16977e102996Smaya{ 16987e102996Smaya return nir_f2b1(build, f); 16997e102996Smaya} 17007e102996Smaya 17017e102996Smayastatic inline nir_ssa_def * 17027e102996Smayanir_i2b(nir_builder *build, nir_ssa_def *i) 17037e102996Smaya{ 17047e102996Smaya return nir_i2b1(build, i); 17057e102996Smaya} 17067e102996Smaya 17077e102996Smayastatic inline nir_ssa_def * 17087e102996Smayanir_b2f(nir_builder *build, nir_ssa_def *b, uint32_t bit_size) 17097e102996Smaya{ 17107e102996Smaya switch (bit_size) { 17117e102996Smaya case 64: return nir_b2f64(build, b); 17127e102996Smaya case 32: return nir_b2f32(build, b); 17137e102996Smaya case 16: return nir_b2f16(build, b); 17147e102996Smaya default: 17157e102996Smaya unreachable("Invalid bit-size"); 17167e102996Smaya }; 17177e102996Smaya} 17187e102996Smaya 17197ec681f3Smrgstatic inline nir_ssa_def * 17207ec681f3Smrgnir_b2i(nir_builder *build, nir_ssa_def *b, uint32_t bit_size) 17217ec681f3Smrg{ 17227ec681f3Smrg switch (bit_size) { 17237ec681f3Smrg case 64: return nir_b2i64(build, b); 17247ec681f3Smrg case 32: return nir_b2i32(build, b); 17257ec681f3Smrg case 16: return nir_b2i16(build, b); 17267ec681f3Smrg case 8: return nir_b2i8(build, b); 17277ec681f3Smrg default: 17287ec681f3Smrg unreachable("Invalid bit-size"); 17297ec681f3Smrg }; 17307ec681f3Smrg} 173101e04c3fSmrgstatic inline nir_ssa_def * 173201e04c3fSmrgnir_load_barycentric(nir_builder *build, nir_intrinsic_op op, 173301e04c3fSmrg unsigned interp_mode) 173401e04c3fSmrg{ 17357ec681f3Smrg unsigned num_components = op == nir_intrinsic_load_barycentric_model ? 3 : 2; 173601e04c3fSmrg nir_intrinsic_instr *bary = nir_intrinsic_instr_create(build->shader, op); 17377ec681f3Smrg nir_ssa_dest_init(&bary->instr, &bary->dest, num_components, 32, NULL); 173801e04c3fSmrg nir_intrinsic_set_interp_mode(bary, interp_mode); 173901e04c3fSmrg nir_builder_instr_insert(build, &bary->instr); 174001e04c3fSmrg return &bary->dest.ssa; 174101e04c3fSmrg} 174201e04c3fSmrg 174301e04c3fSmrgstatic inline void 174401e04c3fSmrgnir_jump(nir_builder *build, nir_jump_type jump_type) 174501e04c3fSmrg{ 17467ec681f3Smrg assert(jump_type != nir_jump_goto && jump_type != nir_jump_goto_if); 174701e04c3fSmrg nir_jump_instr *jump = nir_jump_instr_create(build->shader, jump_type); 174801e04c3fSmrg nir_builder_instr_insert(build, &jump->instr); 174901e04c3fSmrg} 175001e04c3fSmrg 17517ec681f3Smrgstatic inline void 17527ec681f3Smrgnir_goto(nir_builder *build, struct nir_block *target) 17537ec681f3Smrg{ 17547ec681f3Smrg assert(!build->impl->structured); 17557ec681f3Smrg nir_jump_instr *jump = nir_jump_instr_create(build->shader, nir_jump_goto); 17567ec681f3Smrg jump->target = target; 17577ec681f3Smrg nir_builder_instr_insert(build, &jump->instr); 17587ec681f3Smrg} 17597ec681f3Smrg 17607ec681f3Smrgstatic inline void 17617ec681f3Smrgnir_goto_if(nir_builder *build, struct nir_block *target, nir_src cond, 17627ec681f3Smrg struct nir_block *else_target) 17637ec681f3Smrg{ 17647ec681f3Smrg assert(!build->impl->structured); 17657ec681f3Smrg nir_jump_instr *jump = nir_jump_instr_create(build->shader, nir_jump_goto_if); 17667ec681f3Smrg jump->condition = cond; 17677ec681f3Smrg jump->target = target; 17687ec681f3Smrg jump->else_target = else_target; 17697ec681f3Smrg nir_builder_instr_insert(build, &jump->instr); 17707ec681f3Smrg} 17717ec681f3Smrg 177201e04c3fSmrgstatic inline nir_ssa_def * 177301e04c3fSmrgnir_compare_func(nir_builder *b, enum compare_func func, 177401e04c3fSmrg nir_ssa_def *src0, nir_ssa_def *src1) 177501e04c3fSmrg{ 177601e04c3fSmrg switch (func) { 177701e04c3fSmrg case COMPARE_FUNC_NEVER: 177801e04c3fSmrg return nir_imm_int(b, 0); 177901e04c3fSmrg case COMPARE_FUNC_ALWAYS: 178001e04c3fSmrg return nir_imm_int(b, ~0); 178101e04c3fSmrg case COMPARE_FUNC_EQUAL: 178201e04c3fSmrg return nir_feq(b, src0, src1); 178301e04c3fSmrg case COMPARE_FUNC_NOTEQUAL: 17847ec681f3Smrg return nir_fneu(b, src0, src1); 178501e04c3fSmrg case COMPARE_FUNC_GREATER: 178601e04c3fSmrg return nir_flt(b, src1, src0); 178701e04c3fSmrg case COMPARE_FUNC_GEQUAL: 178801e04c3fSmrg return nir_fge(b, src0, src1); 178901e04c3fSmrg case COMPARE_FUNC_LESS: 179001e04c3fSmrg return nir_flt(b, src0, src1); 179101e04c3fSmrg case COMPARE_FUNC_LEQUAL: 179201e04c3fSmrg return nir_fge(b, src1, src0); 179301e04c3fSmrg } 179401e04c3fSmrg unreachable("bad compare func"); 179501e04c3fSmrg} 179601e04c3fSmrg 17977ec681f3Smrgstatic inline void 17987ec681f3Smrgnir_scoped_memory_barrier(nir_builder *b, 17997ec681f3Smrg nir_scope scope, 18007ec681f3Smrg nir_memory_semantics semantics, 18017ec681f3Smrg nir_variable_mode modes) 18027ec681f3Smrg{ 18037ec681f3Smrg nir_scoped_barrier(b, NIR_SCOPE_NONE, scope, semantics, modes); 18047ec681f3Smrg} 18057ec681f3Smrg 18067ec681f3Smrgstatic inline nir_ssa_def * 18077ec681f3Smrgnir_type_convert(nir_builder *b, 18087ec681f3Smrg nir_ssa_def *src, 18097ec681f3Smrg nir_alu_type src_type, 18107ec681f3Smrg nir_alu_type dest_type) 18117ec681f3Smrg{ 18127ec681f3Smrg assert(nir_alu_type_get_type_size(src_type) == 0 || 18137ec681f3Smrg nir_alu_type_get_type_size(src_type) == src->bit_size); 18147ec681f3Smrg 18157ec681f3Smrg src_type = (nir_alu_type) (src_type | src->bit_size); 18167ec681f3Smrg 18177ec681f3Smrg nir_op opcode = 18187ec681f3Smrg nir_type_conversion_op(src_type, dest_type, nir_rounding_mode_undef); 18197ec681f3Smrg 18207ec681f3Smrg return nir_build_alu(b, opcode, src, NULL, NULL, NULL); 18217ec681f3Smrg} 18227ec681f3Smrg 18237ec681f3Smrgstatic inline nir_ssa_def * 18247ec681f3Smrgnir_convert_to_bit_size(nir_builder *b, 18257ec681f3Smrg nir_ssa_def *src, 18267ec681f3Smrg nir_alu_type type, 18277ec681f3Smrg unsigned bit_size) 18287ec681f3Smrg{ 18297ec681f3Smrg return nir_type_convert(b, src, type, (nir_alu_type) (type | bit_size)); 18307ec681f3Smrg} 18317ec681f3Smrg 18327ec681f3Smrgstatic inline nir_ssa_def * 18337ec681f3Smrgnir_i2iN(nir_builder *b, nir_ssa_def *src, unsigned bit_size) 18347ec681f3Smrg{ 18357ec681f3Smrg return nir_convert_to_bit_size(b, src, nir_type_int, bit_size); 18367ec681f3Smrg} 18377ec681f3Smrg 18387ec681f3Smrgstatic inline nir_ssa_def * 18397ec681f3Smrgnir_u2uN(nir_builder *b, nir_ssa_def *src, unsigned bit_size) 18407ec681f3Smrg{ 18417ec681f3Smrg return nir_convert_to_bit_size(b, src, nir_type_uint, bit_size); 18427ec681f3Smrg} 18437ec681f3Smrg 18447ec681f3Smrgstatic inline nir_ssa_def * 18457ec681f3Smrgnir_b2bN(nir_builder *b, nir_ssa_def *src, unsigned bit_size) 18467ec681f3Smrg{ 18477ec681f3Smrg return nir_convert_to_bit_size(b, src, nir_type_bool, bit_size); 18487ec681f3Smrg} 18497ec681f3Smrg 18507ec681f3Smrgstatic inline nir_ssa_def * 18517ec681f3Smrgnir_f2fN(nir_builder *b, nir_ssa_def *src, unsigned bit_size) 18527ec681f3Smrg{ 18537ec681f3Smrg return nir_convert_to_bit_size(b, src, nir_type_float, bit_size); 18547ec681f3Smrg} 18557ec681f3Smrg 18567ec681f3Smrgstatic inline nir_ssa_def * 18577ec681f3Smrgnir_i2fN(nir_builder *b, nir_ssa_def *src, unsigned bit_size) 18587ec681f3Smrg{ 18597ec681f3Smrg return nir_type_convert(b, src, nir_type_int, 18607ec681f3Smrg (nir_alu_type) (nir_type_float | bit_size)); 18617ec681f3Smrg} 18627ec681f3Smrg 18637ec681f3Smrgstatic inline nir_ssa_def * 18647ec681f3Smrgnir_u2fN(nir_builder *b, nir_ssa_def *src, unsigned bit_size) 18657ec681f3Smrg{ 18667ec681f3Smrg return nir_type_convert(b, src, nir_type_uint, 18677ec681f3Smrg (nir_alu_type) (nir_type_float | bit_size)); 18687ec681f3Smrg} 18697ec681f3Smrg 18707ec681f3Smrgstatic inline nir_ssa_def * 18717ec681f3Smrgnir_f2uN(nir_builder *b, nir_ssa_def *src, unsigned bit_size) 18727ec681f3Smrg{ 18737ec681f3Smrg return nir_type_convert(b, src, nir_type_float, 18747ec681f3Smrg (nir_alu_type) (nir_type_uint | bit_size)); 18757ec681f3Smrg} 18767ec681f3Smrg 18777ec681f3Smrgstatic inline nir_ssa_def * 18787ec681f3Smrgnir_f2iN(nir_builder *b, nir_ssa_def *src, unsigned bit_size) 18797ec681f3Smrg{ 18807ec681f3Smrg return nir_type_convert(b, src, nir_type_float, 18817ec681f3Smrg (nir_alu_type) (nir_type_int | bit_size)); 18827ec681f3Smrg} 18837ec681f3Smrg 188401e04c3fSmrg#endif /* NIR_BUILDER_H */ 1885