1 /* 2 * Copyright 2014-2015 Broadcom 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24 #ifndef NIR_BUILDER_H 25 #define NIR_BUILDER_H 26 27 #include "nir_control_flow.h" 28 29 struct exec_list; 30 31 typedef struct nir_builder { 32 nir_cursor cursor; 33 34 /* Whether new ALU instructions will be marked "exact" */ 35 bool exact; 36 37 nir_shader *shader; 38 nir_function_impl *impl; 39 } nir_builder; 40 41 static inline void 42 nir_builder_init(nir_builder *build, nir_function_impl *impl) 43 { 44 memset(build, 0, sizeof(*build)); 45 build->exact = false; 46 build->impl = impl; 47 build->shader = impl->function->shader; 48 } 49 50 static inline void 51 nir_builder_init_simple_shader(nir_builder *build, void *mem_ctx, 52 gl_shader_stage stage, 53 const nir_shader_compiler_options *options) 54 { 55 build->shader = nir_shader_create(mem_ctx, stage, options, NULL); 56 nir_function *func = nir_function_create(build->shader, "main"); 57 build->exact = false; 58 build->impl = nir_function_impl_create(func); 59 build->cursor = nir_after_cf_list(&build->impl->body); 60 } 61 62 static inline void 63 nir_builder_instr_insert(nir_builder *build, nir_instr *instr) 64 { 65 nir_instr_insert(build->cursor, instr); 66 67 /* Move the cursor forward. */ 68 build->cursor = nir_after_instr(instr); 69 } 70 71 static inline nir_instr * 72 nir_builder_last_instr(nir_builder *build) 73 { 74 assert(build->cursor.option == nir_cursor_after_instr); 75 return build->cursor.instr; 76 } 77 78 static inline void 79 nir_builder_cf_insert(nir_builder *build, nir_cf_node *cf) 80 { 81 nir_cf_node_insert(build->cursor, cf); 82 } 83 84 static inline nir_ssa_def * 85 nir_ssa_undef(nir_builder *build, unsigned num_components, unsigned bit_size) 86 { 87 nir_ssa_undef_instr *undef = 88 nir_ssa_undef_instr_create(build->shader, num_components, bit_size); 89 if (!undef) 90 return NULL; 91 92 nir_instr_insert(nir_before_cf_list(&build->impl->body), &undef->instr); 93 94 return &undef->def; 95 } 96 97 static inline nir_ssa_def * 98 nir_build_imm(nir_builder *build, unsigned num_components, 99 unsigned bit_size, nir_const_value value) 100 { 101 nir_load_const_instr *load_const = 102 nir_load_const_instr_create(build->shader, num_components, bit_size); 103 if (!load_const) 104 return NULL; 105 106 load_const->value = value; 107 108 nir_builder_instr_insert(build, &load_const->instr); 109 110 return &load_const->def; 111 } 112 113 static inline nir_ssa_def * 114 nir_imm_float(nir_builder *build, float x) 115 { 116 nir_const_value v; 117 118 memset(&v, 0, sizeof(v)); 119 v.f32[0] = x; 120 121 return nir_build_imm(build, 1, 32, v); 122 } 123 124 static inline nir_ssa_def * 125 nir_imm_double(nir_builder *build, double x) 126 { 127 nir_const_value v; 128 129 memset(&v, 0, sizeof(v)); 130 v.f64[0] = x; 131 132 return nir_build_imm(build, 1, 64, v); 133 } 134 135 static inline nir_ssa_def * 136 nir_imm_vec4(nir_builder *build, float x, float y, float z, float w) 137 { 138 nir_const_value v; 139 140 memset(&v, 0, sizeof(v)); 141 v.f32[0] = x; 142 v.f32[1] = y; 143 v.f32[2] = z; 144 v.f32[3] = w; 145 146 return nir_build_imm(build, 4, 32, v); 147 } 148 149 static inline nir_ssa_def * 150 nir_imm_int(nir_builder *build, int x) 151 { 152 nir_const_value v; 153 154 memset(&v, 0, sizeof(v)); 155 v.i32[0] = x; 156 157 return nir_build_imm(build, 1, 32, v); 158 } 159 160 static inline nir_ssa_def * 161 nir_imm_ivec4(nir_builder *build, int x, int y, int z, int w) 162 { 163 nir_const_value v; 164 165 memset(&v, 0, sizeof(v)); 166 v.i32[0] = x; 167 v.i32[1] = y; 168 v.i32[2] = z; 169 v.i32[3] = w; 170 171 return nir_build_imm(build, 4, 32, v); 172 } 173 174 static inline nir_ssa_def * 175 nir_build_alu(nir_builder *build, nir_op op, nir_ssa_def *src0, 176 nir_ssa_def *src1, nir_ssa_def *src2, nir_ssa_def *src3) 177 { 178 const nir_op_info *op_info = &nir_op_infos[op]; 179 nir_alu_instr *instr = nir_alu_instr_create(build->shader, op); 180 if (!instr) 181 return NULL; 182 183 instr->exact = build->exact; 184 185 instr->src[0].src = nir_src_for_ssa(src0); 186 if (src1) 187 instr->src[1].src = nir_src_for_ssa(src1); 188 if (src2) 189 instr->src[2].src = nir_src_for_ssa(src2); 190 if (src3) 191 instr->src[3].src = nir_src_for_ssa(src3); 192 193 /* Guess the number of components the destination temporary should have 194 * based on our input sizes, if it's not fixed for the op. 195 */ 196 unsigned num_components = op_info->output_size; 197 if (num_components == 0) { 198 for (unsigned i = 0; i < op_info->num_inputs; i++) { 199 if (op_info->input_sizes[i] == 0) 200 num_components = MAX2(num_components, 201 instr->src[i].src.ssa->num_components); 202 } 203 } 204 assert(num_components != 0); 205 206 /* Figure out the bitwidth based on the source bitwidth if the instruction 207 * is variable-width. 208 */ 209 unsigned bit_size = nir_alu_type_get_type_size(op_info->output_type); 210 if (bit_size == 0) { 211 for (unsigned i = 0; i < op_info->num_inputs; i++) { 212 unsigned src_bit_size = instr->src[i].src.ssa->bit_size; 213 if (nir_alu_type_get_type_size(op_info->input_types[i]) == 0) { 214 if (bit_size) 215 assert(src_bit_size == bit_size); 216 else 217 bit_size = src_bit_size; 218 } else { 219 assert(src_bit_size == 220 nir_alu_type_get_type_size(op_info->input_types[i])); 221 } 222 } 223 } 224 225 /* Make sure we don't swizzle from outside of our source vector (like if a 226 * scalar value was passed into a multiply with a vector). 227 */ 228 for (unsigned i = 0; i < op_info->num_inputs; i++) { 229 for (unsigned j = instr->src[i].src.ssa->num_components; j < 4; j++) { 230 instr->src[i].swizzle[j] = instr->src[i].src.ssa->num_components - 1; 231 } 232 } 233 234 nir_ssa_dest_init(&instr->instr, &instr->dest.dest, num_components, 235 bit_size, NULL); 236 instr->dest.write_mask = (1 << num_components) - 1; 237 238 nir_builder_instr_insert(build, &instr->instr); 239 240 return &instr->dest.dest.ssa; 241 } 242 243 #include "nir_builder_opcodes.h" 244 245 static inline nir_ssa_def * 246 nir_vec(nir_builder *build, nir_ssa_def **comp, unsigned num_components) 247 { 248 switch (num_components) { 249 case 4: 250 return nir_vec4(build, comp[0], comp[1], comp[2], comp[3]); 251 case 3: 252 return nir_vec3(build, comp[0], comp[1], comp[2]); 253 case 2: 254 return nir_vec2(build, comp[0], comp[1]); 255 case 1: 256 return comp[0]; 257 default: 258 unreachable("bad component count"); 259 return NULL; 260 } 261 } 262 263 /** 264 * Similar to nir_fmov, but takes a nir_alu_src instead of a nir_ssa_def. 265 */ 266 static inline nir_ssa_def * 267 nir_fmov_alu(nir_builder *build, nir_alu_src src, unsigned num_components) 268 { 269 nir_alu_instr *mov = nir_alu_instr_create(build->shader, nir_op_fmov); 270 nir_ssa_dest_init(&mov->instr, &mov->dest.dest, num_components, 271 nir_src_bit_size(src.src), NULL); 272 mov->exact = build->exact; 273 mov->dest.write_mask = (1 << num_components) - 1; 274 mov->src[0] = src; 275 nir_builder_instr_insert(build, &mov->instr); 276 277 return &mov->dest.dest.ssa; 278 } 279 280 static inline nir_ssa_def * 281 nir_imov_alu(nir_builder *build, nir_alu_src src, unsigned num_components) 282 { 283 nir_alu_instr *mov = nir_alu_instr_create(build->shader, nir_op_imov); 284 nir_ssa_dest_init(&mov->instr, &mov->dest.dest, num_components, 285 nir_src_bit_size(src.src), NULL); 286 mov->exact = build->exact; 287 mov->dest.write_mask = (1 << num_components) - 1; 288 mov->src[0] = src; 289 nir_builder_instr_insert(build, &mov->instr); 290 291 return &mov->dest.dest.ssa; 292 } 293 294 /** 295 * Construct an fmov or imov that reswizzles the source's components. 296 */ 297 static inline nir_ssa_def * 298 nir_swizzle(nir_builder *build, nir_ssa_def *src, const unsigned swiz[4], 299 unsigned num_components, bool use_fmov) 300 { 301 nir_alu_src alu_src = { NIR_SRC_INIT }; 302 alu_src.src = nir_src_for_ssa(src); 303 for (unsigned i = 0; i < num_components; i++) 304 alu_src.swizzle[i] = swiz[i]; 305 306 return use_fmov ? nir_fmov_alu(build, alu_src, num_components) : 307 nir_imov_alu(build, alu_src, num_components); 308 } 309 310 /* Selects the right fdot given the number of components in each source. */ 311 static inline nir_ssa_def * 312 nir_fdot(nir_builder *build, nir_ssa_def *src0, nir_ssa_def *src1) 313 { 314 assert(src0->num_components == src1->num_components); 315 switch (src0->num_components) { 316 case 1: return nir_fmul(build, src0, src1); 317 case 2: return nir_fdot2(build, src0, src1); 318 case 3: return nir_fdot3(build, src0, src1); 319 case 4: return nir_fdot4(build, src0, src1); 320 default: 321 unreachable("bad component size"); 322 } 323 324 return NULL; 325 } 326 327 static inline nir_ssa_def * 328 nir_bany_inequal(nir_builder *b, nir_ssa_def *src0, nir_ssa_def *src1) 329 { 330 switch (src0->num_components) { 331 case 1: return nir_ine(b, src0, src1); 332 case 2: return nir_bany_inequal2(b, src0, src1); 333 case 3: return nir_bany_inequal3(b, src0, src1); 334 case 4: return nir_bany_inequal4(b, src0, src1); 335 default: 336 unreachable("bad component size"); 337 } 338 } 339 340 static inline nir_ssa_def * 341 nir_bany(nir_builder *b, nir_ssa_def *src) 342 { 343 return nir_bany_inequal(b, src, nir_imm_int(b, 0)); 344 } 345 346 static inline nir_ssa_def * 347 nir_channel(nir_builder *b, nir_ssa_def *def, unsigned c) 348 { 349 unsigned swizzle[4] = {c, c, c, c}; 350 return nir_swizzle(b, def, swizzle, 1, false); 351 } 352 353 static inline nir_ssa_def * 354 nir_channels(nir_builder *b, nir_ssa_def *def, unsigned mask) 355 { 356 unsigned num_channels = 0, swizzle[4] = { 0, 0, 0, 0 }; 357 358 for (unsigned i = 0; i < 4; i++) { 359 if ((mask & (1 << i)) == 0) 360 continue; 361 swizzle[num_channels++] = i; 362 } 363 364 return nir_swizzle(b, def, swizzle, num_channels, false); 365 } 366 367 /** 368 * Turns a nir_src into a nir_ssa_def * so it can be passed to 369 * nir_build_alu()-based builder calls. 370 * 371 * See nir_ssa_for_alu_src() for alu instructions. 372 */ 373 static inline nir_ssa_def * 374 nir_ssa_for_src(nir_builder *build, nir_src src, int num_components) 375 { 376 if (src.is_ssa && src.ssa->num_components == num_components) 377 return src.ssa; 378 379 nir_alu_src alu = { NIR_SRC_INIT }; 380 alu.src = src; 381 for (int j = 0; j < 4; j++) 382 alu.swizzle[j] = j; 383 384 return nir_imov_alu(build, alu, num_components); 385 } 386 387 /** 388 * Similar to nir_ssa_for_src(), but for alu src's, respecting the 389 * nir_alu_src's swizzle. 390 */ 391 static inline nir_ssa_def * 392 nir_ssa_for_alu_src(nir_builder *build, nir_alu_instr *instr, unsigned srcn) 393 { 394 static uint8_t trivial_swizzle[4] = { 0, 1, 2, 3 }; 395 nir_alu_src *src = &instr->src[srcn]; 396 unsigned num_components = nir_ssa_alu_instr_src_components(instr, srcn); 397 398 if (src->src.is_ssa && (src->src.ssa->num_components == num_components) && 399 !src->abs && !src->negate && 400 (memcmp(src->swizzle, trivial_swizzle, num_components) == 0)) 401 return src->src.ssa; 402 403 return nir_imov_alu(build, *src, num_components); 404 } 405 406 static inline nir_ssa_def * 407 nir_load_var(nir_builder *build, nir_variable *var) 408 { 409 const unsigned num_components = glsl_get_vector_elements(var->type); 410 411 nir_intrinsic_instr *load = 412 nir_intrinsic_instr_create(build->shader, nir_intrinsic_load_var); 413 load->num_components = num_components; 414 load->variables[0] = nir_deref_var_create(load, var); 415 nir_ssa_dest_init(&load->instr, &load->dest, num_components, 416 glsl_get_bit_size(var->type), NULL); 417 nir_builder_instr_insert(build, &load->instr); 418 return &load->dest.ssa; 419 } 420 421 static inline nir_ssa_def * 422 nir_load_deref_var(nir_builder *build, nir_deref_var *deref) 423 { 424 const struct glsl_type *type = nir_deref_tail(&deref->deref)->type; 425 const unsigned num_components = glsl_get_vector_elements(type); 426 427 nir_intrinsic_instr *load = 428 nir_intrinsic_instr_create(build->shader, nir_intrinsic_load_var); 429 load->num_components = num_components; 430 load->variables[0] = nir_deref_var_clone(deref, load); 431 nir_ssa_dest_init(&load->instr, &load->dest, num_components, 432 glsl_get_bit_size(type), NULL); 433 nir_builder_instr_insert(build, &load->instr); 434 return &load->dest.ssa; 435 } 436 437 static inline void 438 nir_store_var(nir_builder *build, nir_variable *var, nir_ssa_def *value, 439 unsigned writemask) 440 { 441 const unsigned num_components = glsl_get_vector_elements(var->type); 442 443 nir_intrinsic_instr *store = 444 nir_intrinsic_instr_create(build->shader, nir_intrinsic_store_var); 445 store->num_components = num_components; 446 nir_intrinsic_set_write_mask(store, writemask); 447 store->variables[0] = nir_deref_var_create(store, var); 448 store->src[0] = nir_src_for_ssa(value); 449 nir_builder_instr_insert(build, &store->instr); 450 } 451 452 static inline void 453 nir_store_deref_var(nir_builder *build, nir_deref_var *deref, 454 nir_ssa_def *value, unsigned writemask) 455 { 456 const unsigned num_components = 457 glsl_get_vector_elements(nir_deref_tail(&deref->deref)->type); 458 459 nir_intrinsic_instr *store = 460 nir_intrinsic_instr_create(build->shader, nir_intrinsic_store_var); 461 store->num_components = num_components; 462 store->const_index[0] = writemask & ((1 << num_components) - 1); 463 store->variables[0] = nir_deref_var_clone(deref, store); 464 store->src[0] = nir_src_for_ssa(value); 465 nir_builder_instr_insert(build, &store->instr); 466 } 467 468 static inline void 469 nir_copy_deref_var(nir_builder *build, nir_deref_var *dest, nir_deref_var *src) 470 { 471 assert(nir_deref_tail(&dest->deref)->type == 472 nir_deref_tail(&src->deref)->type); 473 474 nir_intrinsic_instr *copy = 475 nir_intrinsic_instr_create(build->shader, nir_intrinsic_copy_var); 476 copy->variables[0] = nir_deref_var_clone(dest, copy); 477 copy->variables[1] = nir_deref_var_clone(src, copy); 478 nir_builder_instr_insert(build, ©->instr); 479 } 480 481 static inline void 482 nir_copy_var(nir_builder *build, nir_variable *dest, nir_variable *src) 483 { 484 nir_intrinsic_instr *copy = 485 nir_intrinsic_instr_create(build->shader, nir_intrinsic_copy_var); 486 copy->variables[0] = nir_deref_var_create(copy, dest); 487 copy->variables[1] = nir_deref_var_create(copy, src); 488 nir_builder_instr_insert(build, ©->instr); 489 } 490 491 /* Generic builder for system values. */ 492 static inline nir_ssa_def * 493 nir_load_system_value(nir_builder *build, nir_intrinsic_op op, int index) 494 { 495 nir_intrinsic_instr *load = nir_intrinsic_instr_create(build->shader, op); 496 load->num_components = nir_intrinsic_infos[op].dest_components; 497 load->const_index[0] = index; 498 nir_ssa_dest_init(&load->instr, &load->dest, 499 nir_intrinsic_infos[op].dest_components, 32, NULL); 500 nir_builder_instr_insert(build, &load->instr); 501 return &load->dest.ssa; 502 } 503 504 /* Generate custom builders for system values. */ 505 #define INTRINSIC(name, num_srcs, src_components, has_dest, dest_components, \ 506 num_variables, num_indices, idx0, idx1, idx2, flags) 507 #define LAST_INTRINSIC(name) 508 509 #define DEFINE_SYSTEM_VALUE(name) \ 510 static inline nir_ssa_def * \ 511 nir_load_##name(nir_builder *build) \ 512 { \ 513 return nir_load_system_value(build, nir_intrinsic_load_##name, 0); \ 514 } \ 515 516 #include "nir_intrinsics.h" 517 518 static inline nir_ssa_def * 519 nir_load_barycentric(nir_builder *build, nir_intrinsic_op op, 520 unsigned interp_mode) 521 { 522 nir_intrinsic_instr *bary = nir_intrinsic_instr_create(build->shader, op); 523 nir_ssa_dest_init(&bary->instr, &bary->dest, 2, 32, NULL); 524 nir_intrinsic_set_interp_mode(bary, interp_mode); 525 nir_builder_instr_insert(build, &bary->instr); 526 return &bary->dest.ssa; 527 } 528 529 static inline void 530 nir_jump(nir_builder *build, nir_jump_type jump_type) 531 { 532 nir_jump_instr *jump = nir_jump_instr_create(build->shader, jump_type); 533 nir_builder_instr_insert(build, &jump->instr); 534 } 535 536 #endif /* NIR_BUILDER_H */ 537