lp_bld_tgsi_soa.c revision bc2875aa483a0fef7f6e32c1886f6e2edaba7694
1/************************************************************************** 2 * 3 * Copyright 2009 VMware, Inc. 4 * Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation the rights to use, copy, modify, merge, publish, 11 * distribute, sub license, and/or sell copies of the Software, and to 12 * permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the 16 * next paragraph) shall be included in all copies or substantial portions 17 * of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * 27 **************************************************************************/ 28 29/** 30 * @file 31 * TGSI to LLVM IR translation -- SoA. 32 * 33 * @author Jose Fonseca <jfonseca@vmware.com> 34 * 35 * Based on tgsi_sse2.c code written by Michal Krol, Keith Whitwell, 36 * Brian Paul, and others. 37 */ 38 39#include "pipe/p_config.h" 40#include "pipe/p_shader_tokens.h" 41#include "util/u_debug.h" 42#include "util/u_math.h" 43#include "util/u_memory.h" 44#include "tgsi/tgsi_dump.h" 45#include "tgsi/tgsi_exec.h" 46#include "tgsi/tgsi_info.h" 47#include "tgsi/tgsi_parse.h" 48#include "tgsi/tgsi_util.h" 49#include "tgsi/tgsi_scan.h" 50#include "lp_bld_tgsi_action.h" 51#include "lp_bld_type.h" 52#include "lp_bld_const.h" 53#include "lp_bld_arit.h" 54#include "lp_bld_bitarit.h" 55#include "lp_bld_gather.h" 56#include "lp_bld_init.h" 57#include "lp_bld_logic.h" 58#include "lp_bld_swizzle.h" 59#include "lp_bld_flow.h" 60#include "lp_bld_quad.h" 61#include "lp_bld_tgsi.h" 62#include "lp_bld_limits.h" 63#include "lp_bld_debug.h" 64#include "lp_bld_printf.h" 65 66 67static void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context *bld) 68{ 69 mask->bld = bld; 70 mask->has_mask = FALSE; 71 mask->cond_stack_size = 0; 72 mask->loop_stack_size = 0; 73 mask->call_stack_size = 0; 74 75 mask->int_vec_type = lp_build_int_vec_type(bld->gallivm, mask->bld->type); 76 mask->exec_mask = mask->ret_mask = mask->break_mask = mask->cont_mask = mask->cond_mask = 77 LLVMConstAllOnes(mask->int_vec_type); 78} 79 80static void lp_exec_mask_update(struct lp_exec_mask *mask) 81{ 82 LLVMBuilderRef builder = mask->bld->gallivm->builder; 83 84 if (mask->loop_stack_size) { 85 /*for loops we need to update the entire mask at runtime */ 86 LLVMValueRef tmp; 87 assert(mask->break_mask); 88 tmp = LLVMBuildAnd(builder, 89 mask->cont_mask, 90 mask->break_mask, 91 "maskcb"); 92 mask->exec_mask = LLVMBuildAnd(builder, 93 mask->cond_mask, 94 tmp, 95 "maskfull"); 96 } else 97 mask->exec_mask = mask->cond_mask; 98 99 if (mask->call_stack_size) { 100 mask->exec_mask = LLVMBuildAnd(builder, 101 mask->exec_mask, 102 mask->ret_mask, 103 "callmask"); 104 } 105 106 mask->has_mask = (mask->cond_stack_size > 0 || 107 mask->loop_stack_size > 0 || 108 mask->call_stack_size > 0); 109} 110 111static void lp_exec_mask_cond_push(struct lp_exec_mask *mask, 112 LLVMValueRef val) 113{ 114 LLVMBuilderRef builder = mask->bld->gallivm->builder; 115 116 assert(mask->cond_stack_size < LP_MAX_TGSI_NESTING); 117 if (mask->cond_stack_size == 0) { 118 assert(mask->cond_mask == LLVMConstAllOnes(mask->int_vec_type)); 119 } 120 mask->cond_stack[mask->cond_stack_size++] = mask->cond_mask; 121 assert(LLVMTypeOf(val) == mask->int_vec_type); 122 mask->cond_mask = LLVMBuildAnd(builder, 123 mask->cond_mask, 124 val, 125 ""); 126 lp_exec_mask_update(mask); 127} 128 129static void lp_exec_mask_cond_invert(struct lp_exec_mask *mask) 130{ 131 LLVMBuilderRef builder = mask->bld->gallivm->builder; 132 LLVMValueRef prev_mask; 133 LLVMValueRef inv_mask; 134 135 assert(mask->cond_stack_size); 136 prev_mask = mask->cond_stack[mask->cond_stack_size - 1]; 137 if (mask->cond_stack_size == 1) { 138 assert(prev_mask == LLVMConstAllOnes(mask->int_vec_type)); 139 } 140 141 inv_mask = LLVMBuildNot(builder, mask->cond_mask, ""); 142 143 mask->cond_mask = LLVMBuildAnd(builder, 144 inv_mask, 145 prev_mask, ""); 146 lp_exec_mask_update(mask); 147} 148 149static void lp_exec_mask_cond_pop(struct lp_exec_mask *mask) 150{ 151 assert(mask->cond_stack_size); 152 mask->cond_mask = mask->cond_stack[--mask->cond_stack_size]; 153 lp_exec_mask_update(mask); 154} 155 156static void lp_exec_bgnloop(struct lp_exec_mask *mask) 157{ 158 LLVMBuilderRef builder = mask->bld->gallivm->builder; 159 160 if (mask->loop_stack_size == 0) { 161 assert(mask->loop_block == NULL); 162 assert(mask->cont_mask == LLVMConstAllOnes(mask->int_vec_type)); 163 assert(mask->break_mask == LLVMConstAllOnes(mask->int_vec_type)); 164 assert(mask->break_var == NULL); 165 } 166 167 assert(mask->loop_stack_size < LP_MAX_TGSI_NESTING); 168 169 mask->loop_stack[mask->loop_stack_size].loop_block = mask->loop_block; 170 mask->loop_stack[mask->loop_stack_size].cont_mask = mask->cont_mask; 171 mask->loop_stack[mask->loop_stack_size].break_mask = mask->break_mask; 172 mask->loop_stack[mask->loop_stack_size].break_var = mask->break_var; 173 ++mask->loop_stack_size; 174 175 mask->break_var = lp_build_alloca(mask->bld->gallivm, mask->int_vec_type, ""); 176 LLVMBuildStore(builder, mask->break_mask, mask->break_var); 177 178 mask->loop_block = lp_build_insert_new_block(mask->bld->gallivm, "bgnloop"); 179 LLVMBuildBr(builder, mask->loop_block); 180 LLVMPositionBuilderAtEnd(builder, mask->loop_block); 181 182 mask->break_mask = LLVMBuildLoad(builder, mask->break_var, ""); 183 184 lp_exec_mask_update(mask); 185} 186 187static void lp_exec_break(struct lp_exec_mask *mask) 188{ 189 LLVMBuilderRef builder = mask->bld->gallivm->builder; 190 LLVMValueRef exec_mask = LLVMBuildNot(builder, 191 mask->exec_mask, 192 "break"); 193 194 mask->break_mask = LLVMBuildAnd(builder, 195 mask->break_mask, 196 exec_mask, "break_full"); 197 198 lp_exec_mask_update(mask); 199} 200 201static void lp_exec_continue(struct lp_exec_mask *mask) 202{ 203 LLVMBuilderRef builder = mask->bld->gallivm->builder; 204 LLVMValueRef exec_mask = LLVMBuildNot(builder, 205 mask->exec_mask, 206 ""); 207 208 mask->cont_mask = LLVMBuildAnd(builder, 209 mask->cont_mask, 210 exec_mask, ""); 211 212 lp_exec_mask_update(mask); 213} 214 215 216static void lp_exec_endloop(struct gallivm_state *gallivm, 217 struct lp_exec_mask *mask) 218{ 219 LLVMBuilderRef builder = mask->bld->gallivm->builder; 220 LLVMBasicBlockRef endloop; 221 LLVMTypeRef reg_type = LLVMIntTypeInContext(gallivm->context, 222 mask->bld->type.width * 223 mask->bld->type.length); 224 LLVMValueRef i1cond; 225 226 assert(mask->break_mask); 227 228 /* 229 * Restore the cont_mask, but don't pop 230 */ 231 assert(mask->loop_stack_size); 232 mask->cont_mask = mask->loop_stack[mask->loop_stack_size - 1].cont_mask; 233 lp_exec_mask_update(mask); 234 235 /* 236 * Unlike the continue mask, the break_mask must be preserved across loop 237 * iterations 238 */ 239 LLVMBuildStore(builder, mask->break_mask, mask->break_var); 240 241 /* i1cond = (mask == 0) */ 242 i1cond = LLVMBuildICmp( 243 builder, 244 LLVMIntNE, 245 LLVMBuildBitCast(builder, mask->exec_mask, reg_type, ""), 246 LLVMConstNull(reg_type), ""); 247 248 endloop = lp_build_insert_new_block(mask->bld->gallivm, "endloop"); 249 250 LLVMBuildCondBr(builder, 251 i1cond, mask->loop_block, endloop); 252 253 LLVMPositionBuilderAtEnd(builder, endloop); 254 255 assert(mask->loop_stack_size); 256 --mask->loop_stack_size; 257 mask->loop_block = mask->loop_stack[mask->loop_stack_size].loop_block; 258 mask->cont_mask = mask->loop_stack[mask->loop_stack_size].cont_mask; 259 mask->break_mask = mask->loop_stack[mask->loop_stack_size].break_mask; 260 mask->break_var = mask->loop_stack[mask->loop_stack_size].break_var; 261 262 lp_exec_mask_update(mask); 263} 264 265/* stores val into an address pointed to by dst. 266 * mask->exec_mask is used to figure out which bits of val 267 * should be stored into the address 268 * (0 means don't store this bit, 1 means do store). 269 */ 270static void lp_exec_mask_store(struct lp_exec_mask *mask, 271 LLVMValueRef pred, 272 LLVMValueRef val, 273 LLVMValueRef dst) 274{ 275 LLVMBuilderRef builder = mask->bld->gallivm->builder; 276 277 /* Mix the predicate and execution mask */ 278 if (mask->has_mask) { 279 if (pred) { 280 pred = LLVMBuildAnd(builder, pred, mask->exec_mask, ""); 281 } else { 282 pred = mask->exec_mask; 283 } 284 } 285 286 if (pred) { 287 LLVMValueRef real_val, dst_val; 288 289 dst_val = LLVMBuildLoad(builder, dst, ""); 290 real_val = lp_build_select(mask->bld, 291 pred, 292 val, dst_val); 293 294 LLVMBuildStore(builder, real_val, dst); 295 } else 296 LLVMBuildStore(builder, val, dst); 297} 298 299static void lp_exec_mask_call(struct lp_exec_mask *mask, 300 int func, 301 int *pc) 302{ 303 assert(mask->call_stack_size < LP_MAX_TGSI_NESTING); 304 mask->call_stack[mask->call_stack_size].pc = *pc; 305 mask->call_stack[mask->call_stack_size].ret_mask = mask->ret_mask; 306 mask->call_stack_size++; 307 *pc = func; 308} 309 310static void lp_exec_mask_ret(struct lp_exec_mask *mask, int *pc) 311{ 312 LLVMBuilderRef builder = mask->bld->gallivm->builder; 313 LLVMValueRef exec_mask; 314 315 if (mask->call_stack_size == 0) { 316 /* returning from main() */ 317 *pc = -1; 318 return; 319 } 320 exec_mask = LLVMBuildNot(builder, 321 mask->exec_mask, 322 "ret"); 323 324 mask->ret_mask = LLVMBuildAnd(builder, 325 mask->ret_mask, 326 exec_mask, "ret_full"); 327 328 lp_exec_mask_update(mask); 329} 330 331static void lp_exec_mask_bgnsub(struct lp_exec_mask *mask) 332{ 333} 334 335static void lp_exec_mask_endsub(struct lp_exec_mask *mask, int *pc) 336{ 337 assert(mask->call_stack_size); 338 mask->call_stack_size--; 339 *pc = mask->call_stack[mask->call_stack_size].pc; 340 mask->ret_mask = mask->call_stack[mask->call_stack_size].ret_mask; 341 lp_exec_mask_update(mask); 342} 343 344 345/** 346 * Return pointer to a temporary register channel (src or dest). 347 * Note that indirect addressing cannot be handled here. 348 * \param index which temporary register 349 * \param chan which channel of the temp register. 350 */ 351LLVMValueRef 352lp_get_temp_ptr_soa(struct lp_build_tgsi_soa_context *bld, 353 unsigned index, 354 unsigned chan) 355{ 356 LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder; 357 assert(chan < 4); 358 if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) { 359 LLVMValueRef lindex = lp_build_const_int32(bld->bld_base.base.gallivm, index * 4 + chan); 360 return LLVMBuildGEP(builder, bld->temps_array, &lindex, 1, ""); 361 } 362 else { 363 return bld->temps[index][chan]; 364 } 365} 366 367/** 368 * Return pointer to a output register channel (src or dest). 369 * Note that indirect addressing cannot be handled here. 370 * \param index which output register 371 * \param chan which channel of the output register. 372 */ 373LLVMValueRef 374lp_get_output_ptr(struct lp_build_tgsi_soa_context *bld, 375 unsigned index, 376 unsigned chan) 377{ 378 LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder; 379 assert(chan < 4); 380 if (bld->indirect_files & (1 << TGSI_FILE_OUTPUT)) { 381 LLVMValueRef lindex = lp_build_const_int32(bld->bld_base.base.gallivm, 382 index * 4 + chan); 383 return LLVMBuildGEP(builder, bld->outputs_array, &lindex, 1, ""); 384 } 385 else { 386 return bld->outputs[index][chan]; 387 } 388} 389 390/** 391 * Gather vector. 392 * XXX the lp_build_gather() function should be capable of doing this 393 * with a little work. 394 */ 395static LLVMValueRef 396build_gather(struct lp_build_tgsi_soa_context *bld, 397 LLVMValueRef base_ptr, 398 LLVMValueRef indexes) 399{ 400 LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder; 401 LLVMValueRef res = bld->bld_base.base.undef; 402 unsigned i; 403 404 /* 405 * Loop over elements of index_vec, load scalar value, insert it into 'res'. 406 */ 407 for (i = 0; i < bld->bld_base.base.type.length; i++) { 408 LLVMValueRef ii = lp_build_const_int32(bld->bld_base.base.gallivm, i); 409 LLVMValueRef index = LLVMBuildExtractElement(builder, 410 indexes, ii, ""); 411 LLVMValueRef scalar_ptr = LLVMBuildGEP(builder, base_ptr, 412 &index, 1, "gather_ptr"); 413 LLVMValueRef scalar = LLVMBuildLoad(builder, scalar_ptr, ""); 414 415 res = LLVMBuildInsertElement(builder, res, scalar, ii, ""); 416 } 417 418 return res; 419} 420 421 422/** 423 * Scatter/store vector. 424 */ 425static void 426emit_mask_scatter(struct lp_build_tgsi_soa_context *bld, 427 LLVMValueRef base_ptr, 428 LLVMValueRef indexes, 429 LLVMValueRef values, 430 struct lp_exec_mask *mask, 431 LLVMValueRef pred) 432{ 433 struct gallivm_state *gallivm = bld->bld_base.base.gallivm; 434 LLVMBuilderRef builder = gallivm->builder; 435 unsigned i; 436 437 /* Mix the predicate and execution mask */ 438 if (mask->has_mask) { 439 if (pred) { 440 pred = LLVMBuildAnd(builder, pred, mask->exec_mask, ""); 441 } 442 else { 443 pred = mask->exec_mask; 444 } 445 } 446 447 /* 448 * Loop over elements of index_vec, store scalar value. 449 */ 450 for (i = 0; i < bld->bld_base.base.type.length; i++) { 451 LLVMValueRef ii = lp_build_const_int32(gallivm, i); 452 LLVMValueRef index = LLVMBuildExtractElement(builder, indexes, ii, ""); 453 LLVMValueRef scalar_ptr = LLVMBuildGEP(builder, base_ptr, &index, 1, "scatter_ptr"); 454 LLVMValueRef val = LLVMBuildExtractElement(builder, values, ii, "scatter_val"); 455 LLVMValueRef scalar_pred = pred ? 456 LLVMBuildExtractElement(builder, pred, ii, "scatter_pred") : NULL; 457 458 if (0) 459 lp_build_printf(gallivm, "scatter %d: val %f at %d %p\n", 460 ii, val, index, scalar_ptr); 461 462 if (scalar_pred) { 463 LLVMValueRef real_val, dst_val; 464 dst_val = LLVMBuildLoad(builder, scalar_ptr, ""); 465 real_val = lp_build_select(&bld->elem_bld, scalar_pred, val, dst_val); 466 LLVMBuildStore(builder, real_val, scalar_ptr); 467 } 468 else { 469 LLVMBuildStore(builder, val, scalar_ptr); 470 } 471 } 472} 473 474 475/** 476 * Read the current value of the ADDR register, convert the floats to 477 * ints, add the base index and return the vector of offsets. 478 * The offsets will be used to index into the constant buffer or 479 * temporary register file. 480 */ 481static LLVMValueRef 482get_indirect_index(struct lp_build_tgsi_soa_context *bld, 483 unsigned reg_file, unsigned reg_index, 484 const struct tgsi_src_register *indirect_reg) 485{ 486 LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder; 487 struct lp_build_context *uint_bld = &bld->uint_bld; 488 /* always use X component of address register */ 489 unsigned swizzle = indirect_reg->SwizzleX; 490 LLVMValueRef base; 491 LLVMValueRef rel; 492 LLVMValueRef max_index; 493 LLVMValueRef index; 494 495 assert(bld->indirect_files & (1 << reg_file)); 496 497 base = lp_build_const_int_vec(bld->bld_base.base.gallivm, uint_bld->type, reg_index); 498 499 assert(swizzle < 4); 500 rel = LLVMBuildLoad(builder, 501 bld->addr[indirect_reg->Index][swizzle], 502 "load addr reg"); 503 504 /* for indexing we want integers */ 505 rel = LLVMBuildFPToSI(builder, 506 rel, 507 uint_bld->vec_type, ""); 508 509 index = lp_build_add(uint_bld, base, rel); 510 511 max_index = lp_build_const_int_vec(bld->bld_base.base.gallivm, 512 uint_bld->type, 513 bld->bld_base.info->file_max[reg_file]); 514 515 assert(!uint_bld->type.sign); 516 index = lp_build_min(uint_bld, index, max_index); 517 518 return index; 519} 520 521static LLVMValueRef 522emit_fetch_constant( 523 struct lp_build_tgsi_context * bld_base, 524 const struct tgsi_full_src_register * reg, 525 const unsigned swizzle) 526{ 527 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 528 struct gallivm_state *gallivm = bld_base->base.gallivm; 529 LLVMBuilderRef builder = gallivm->builder; 530 struct lp_build_context *uint_bld = &bld->uint_bld; 531 LLVMValueRef indirect_index = NULL; 532 533 /* XXX: Handle fetching xyzw components as a vector */ 534 assert(swizzle != ~0); 535 536 if (reg->Register.Indirect) { 537 indirect_index = get_indirect_index(bld, 538 reg->Register.File, 539 reg->Register.Index, 540 ®->Indirect); 541 } 542 543 if (reg->Register.Indirect) { 544 LLVMValueRef swizzle_vec = 545 lp_build_const_int_vec(bld->bld_base.base.gallivm, uint_bld->type, swizzle); 546 LLVMValueRef index_vec; /* index into the const buffer */ 547 548 /* index_vec = indirect_index * 4 + swizzle */ 549 index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2); 550 index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec); 551 552 /* Gather values from the constant buffer */ 553 return build_gather(bld, bld->consts_ptr, index_vec); 554 } 555 else { 556 LLVMValueRef index; /* index into the const buffer */ 557 LLVMValueRef scalar, scalar_ptr; 558 559 index = lp_build_const_int32(gallivm, reg->Register.Index*4 + swizzle); 560 561 scalar_ptr = LLVMBuildGEP(builder, bld->consts_ptr, 562 &index, 1, ""); 563 scalar = LLVMBuildLoad(builder, scalar_ptr, ""); 564 565 return lp_build_broadcast_scalar(&bld->bld_base.base, scalar); 566 } 567} 568 569static LLVMValueRef 570emit_fetch_immediate( 571 struct lp_build_tgsi_context * bld_base, 572 const struct tgsi_full_src_register * reg, 573 const unsigned swizzle) 574{ 575 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 576 LLVMValueRef res = bld->immediates[reg->Register.Index][swizzle]; 577 assert(res); 578 return res; 579} 580 581static LLVMValueRef 582emit_fetch_input( 583 struct lp_build_tgsi_context * bld_base, 584 const struct tgsi_full_src_register * reg, 585 const unsigned swizzle) 586{ 587 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 588 struct gallivm_state *gallivm = bld->bld_base.base.gallivm; 589 LLVMBuilderRef builder = gallivm->builder; 590 struct lp_build_context *uint_bld = &bld->uint_bld; 591 LLVMValueRef indirect_index = NULL; 592 LLVMValueRef res; 593 594 if (reg->Register.Indirect) { 595 indirect_index = get_indirect_index(bld, 596 reg->Register.File, 597 reg->Register.Index, 598 ®->Indirect); 599 } 600 601 if (reg->Register.Indirect) { 602 LLVMValueRef swizzle_vec = 603 lp_build_const_int_vec(gallivm, uint_bld->type, swizzle); 604 LLVMValueRef length_vec = 605 lp_build_const_int_vec(gallivm, uint_bld->type, bld->bld_base.base.type.length); 606 LLVMValueRef index_vec; /* index into the const buffer */ 607 LLVMValueRef inputs_array; 608 LLVMTypeRef float4_ptr_type; 609 610 /* index_vec = (indirect_index * 4 + swizzle) * length */ 611 index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2); 612 index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec); 613 index_vec = lp_build_mul(uint_bld, index_vec, length_vec); 614 615 /* cast inputs_array pointer to float* */ 616 float4_ptr_type = LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0); 617 inputs_array = LLVMBuildBitCast(builder, bld->inputs_array, 618 float4_ptr_type, ""); 619 620 /* Gather values from the temporary register array */ 621 res = build_gather(bld, inputs_array, index_vec); 622 } else { 623 if (bld->indirect_files & (1 << TGSI_FILE_INPUT)) { 624 LLVMValueRef lindex = lp_build_const_int32(gallivm, 625 reg->Register.Index * 4 + swizzle); 626 LLVMValueRef input_ptr = LLVMBuildGEP(builder, 627 bld->inputs_array, &lindex, 1, ""); 628 res = LLVMBuildLoad(builder, input_ptr, ""); 629 } 630 else { 631 res = bld->inputs[reg->Register.Index][swizzle]; 632 } 633 } 634 assert(res); 635 return res; 636} 637 638static LLVMValueRef 639emit_fetch_temporary( 640 struct lp_build_tgsi_context * bld_base, 641 const struct tgsi_full_src_register * reg, 642 const unsigned swizzle) 643{ 644 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 645 struct gallivm_state *gallivm = bld->bld_base.base.gallivm; 646 LLVMBuilderRef builder = gallivm->builder; 647 struct lp_build_context *uint_bld = &bld->uint_bld; 648 LLVMValueRef indirect_index = NULL; 649 LLVMValueRef res; 650 651 if (reg->Register.Indirect) { 652 indirect_index = get_indirect_index(bld, 653 reg->Register.File, 654 reg->Register.Index, 655 ®->Indirect); 656 } 657 658 if (reg->Register.Indirect) { 659 LLVMValueRef swizzle_vec = 660 lp_build_const_int_vec(bld->bld_base.base.gallivm, uint_bld->type, swizzle); 661 LLVMValueRef length_vec = 662 lp_build_const_int_vec(bld->bld_base.base.gallivm, uint_bld->type, 663 bld->bld_base.base.type.length); 664 LLVMValueRef index_vec; /* index into the const buffer */ 665 LLVMValueRef temps_array; 666 LLVMTypeRef float4_ptr_type; 667 668 /* index_vec = (indirect_index * 4 + swizzle) * length */ 669 index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2); 670 index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec); 671 index_vec = lp_build_mul(uint_bld, index_vec, length_vec); 672 673 /* cast temps_array pointer to float* */ 674 float4_ptr_type = LLVMPointerType(LLVMFloatTypeInContext(bld->bld_base.base.gallivm->context), 0); 675 temps_array = LLVMBuildBitCast(builder, bld->temps_array, 676 float4_ptr_type, ""); 677 678 /* Gather values from the temporary register array */ 679 res = build_gather(bld, temps_array, index_vec); 680 } 681 else { 682 LLVMValueRef temp_ptr; 683 temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, swizzle); 684 res = LLVMBuildLoad(builder, temp_ptr, ""); 685 if (!res) 686 return bld->bld_base.base.undef; 687 } 688 689 return res; 690} 691 692static LLVMValueRef 693emit_fetch_system_value( 694 struct lp_build_tgsi_context * bld_base, 695 const struct tgsi_full_src_register * reg, 696 const unsigned swizzle) 697{ 698 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 699 struct gallivm_state *gallivm = bld->bld_base.base.gallivm; 700 LLVMBuilderRef builder = gallivm->builder; 701 LLVMValueRef index; /* index into the system value array */ 702 LLVMValueRef scalar, scalar_ptr; 703 704 assert(!reg->Register.Indirect); 705 706 index = lp_build_const_int32(gallivm, reg->Register.Index * 4 + swizzle); 707 708 scalar_ptr = LLVMBuildGEP(builder, bld->system_values_array, &index, 1, ""); 709 scalar = LLVMBuildLoad(builder, scalar_ptr, ""); 710 711 return lp_build_broadcast_scalar(&bld->bld_base.base, scalar); 712} 713 714/** 715 * Register fetch with derivatives. 716 */ 717static void 718emit_fetch_deriv( 719 struct lp_build_tgsi_soa_context *bld, 720 LLVMValueRef src, 721 LLVMValueRef *res, 722 LLVMValueRef *ddx, 723 LLVMValueRef *ddy) 724{ 725 if(res) 726 *res = src; 727 728 /* TODO: use interpolation coeffs for inputs */ 729 730 if(ddx) 731 *ddx = lp_build_ddx(&bld->bld_base.base, src); 732 733 if(ddy) 734 *ddy = lp_build_ddy(&bld->bld_base.base, src); 735} 736 737 738/** 739 * Predicate. 740 */ 741static void 742emit_fetch_predicate( 743 struct lp_build_tgsi_soa_context *bld, 744 const struct tgsi_full_instruction *inst, 745 LLVMValueRef *pred) 746{ 747 LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder; 748 unsigned index; 749 unsigned char swizzles[4]; 750 LLVMValueRef unswizzled[4] = {NULL, NULL, NULL, NULL}; 751 LLVMValueRef value; 752 unsigned chan; 753 754 if (!inst->Instruction.Predicate) { 755 TGSI_FOR_EACH_CHANNEL( chan ) { 756 pred[chan] = NULL; 757 } 758 return; 759 } 760 761 swizzles[0] = inst->Predicate.SwizzleX; 762 swizzles[1] = inst->Predicate.SwizzleY; 763 swizzles[2] = inst->Predicate.SwizzleZ; 764 swizzles[3] = inst->Predicate.SwizzleW; 765 766 index = inst->Predicate.Index; 767 assert(index < LP_MAX_TGSI_PREDS); 768 769 TGSI_FOR_EACH_CHANNEL( chan ) { 770 unsigned swizzle = swizzles[chan]; 771 772 /* 773 * Only fetch the predicate register channels that are actually listed 774 * in the swizzles 775 */ 776 if (!unswizzled[swizzle]) { 777 value = LLVMBuildLoad(builder, 778 bld->preds[index][swizzle], ""); 779 780 /* 781 * Convert the value to an integer mask. 782 * 783 * TODO: Short-circuit this comparison -- a D3D setp_xx instructions 784 * is needlessly causing two comparisons due to storing the intermediate 785 * result as float vector instead of an integer mask vector. 786 */ 787 value = lp_build_compare(bld->bld_base.base.gallivm, 788 bld->bld_base.base.type, 789 PIPE_FUNC_NOTEQUAL, 790 value, 791 bld->bld_base.base.zero); 792 if (inst->Predicate.Negate) { 793 value = LLVMBuildNot(builder, value, ""); 794 } 795 796 unswizzled[swizzle] = value; 797 } else { 798 value = unswizzled[swizzle]; 799 } 800 801 pred[chan] = value; 802 } 803} 804 805 806/** 807 * Register store. 808 */ 809static void 810emit_store_chan( 811 struct lp_build_tgsi_context *bld_base, 812 const struct tgsi_full_instruction *inst, 813 unsigned index, 814 unsigned chan_index, 815 LLVMValueRef pred, 816 LLVMValueRef value) 817{ 818 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 819 struct gallivm_state *gallivm = bld->bld_base.base.gallivm; 820 LLVMBuilderRef builder = gallivm->builder; 821 const struct tgsi_full_dst_register *reg = &inst->Dst[index]; 822 struct lp_build_context *uint_bld = &bld->uint_bld; 823 LLVMValueRef indirect_index = NULL; 824 825 switch( inst->Instruction.Saturate ) { 826 case TGSI_SAT_NONE: 827 break; 828 829 case TGSI_SAT_ZERO_ONE: 830 value = lp_build_max(&bld->bld_base.base, value, bld->bld_base.base.zero); 831 value = lp_build_min(&bld->bld_base.base, value, bld->bld_base.base.one); 832 break; 833 834 case TGSI_SAT_MINUS_PLUS_ONE: 835 value = lp_build_max(&bld->bld_base.base, value, lp_build_const_vec(bld->bld_base.base.gallivm, bld->bld_base.base.type, -1.0)); 836 value = lp_build_min(&bld->bld_base.base, value, bld->bld_base.base.one); 837 break; 838 839 default: 840 assert(0); 841 } 842 843 if (reg->Register.Indirect) { 844 indirect_index = get_indirect_index(bld, 845 reg->Register.File, 846 reg->Register.Index, 847 ®->Indirect); 848 } else { 849 assert(reg->Register.Index <= 850 bld->bld_base.info->file_max[reg->Register.File]); 851 } 852 853 switch( reg->Register.File ) { 854 case TGSI_FILE_OUTPUT: 855 if (reg->Register.Indirect) { 856 LLVMValueRef chan_vec = 857 lp_build_const_int_vec(gallivm, uint_bld->type, chan_index); 858 LLVMValueRef length_vec = 859 lp_build_const_int_vec(gallivm, uint_bld->type, bld->bld_base.base.type.length); 860 LLVMValueRef index_vec; /* indexes into the temp registers */ 861 LLVMValueRef outputs_array; 862 LLVMValueRef pixel_offsets; 863 LLVMTypeRef float_ptr_type; 864 int i; 865 866 /* build pixel offset vector: {0, 1, 2, 3, ...} */ 867 pixel_offsets = uint_bld->undef; 868 for (i = 0; i < bld->bld_base.base.type.length; i++) { 869 LLVMValueRef ii = lp_build_const_int32(gallivm, i); 870 pixel_offsets = LLVMBuildInsertElement(builder, pixel_offsets, 871 ii, ii, ""); 872 } 873 874 /* index_vec = (indirect_index * 4 + chan_index) * length + offsets */ 875 index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2); 876 index_vec = lp_build_add(uint_bld, index_vec, chan_vec); 877 index_vec = lp_build_mul(uint_bld, index_vec, length_vec); 878 index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets); 879 880 float_ptr_type = 881 LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0); 882 outputs_array = LLVMBuildBitCast(builder, bld->outputs_array, 883 float_ptr_type, ""); 884 885 /* Scatter store values into temp registers */ 886 emit_mask_scatter(bld, outputs_array, index_vec, value, 887 &bld->exec_mask, pred); 888 } 889 else { 890 LLVMValueRef out_ptr = lp_get_output_ptr(bld, reg->Register.Index, 891 chan_index); 892 lp_exec_mask_store(&bld->exec_mask, pred, value, out_ptr); 893 } 894 break; 895 896 case TGSI_FILE_TEMPORARY: 897 if (reg->Register.Indirect) { 898 LLVMValueRef chan_vec = 899 lp_build_const_int_vec(gallivm, uint_bld->type, chan_index); 900 LLVMValueRef length_vec = 901 lp_build_const_int_vec(gallivm, uint_bld->type, 902 bld->bld_base.base.type.length); 903 LLVMValueRef index_vec; /* indexes into the temp registers */ 904 LLVMValueRef temps_array; 905 LLVMValueRef pixel_offsets; 906 LLVMTypeRef float_ptr_type; 907 int i; 908 909 /* build pixel offset vector: {0, 1, 2, 3, ...} */ 910 pixel_offsets = uint_bld->undef; 911 for (i = 0; i < bld->bld_base.base.type.length; i++) { 912 LLVMValueRef ii = lp_build_const_int32(gallivm, i); 913 pixel_offsets = LLVMBuildInsertElement(builder, pixel_offsets, 914 ii, ii, ""); 915 } 916 917 /* index_vec = (indirect_index * 4 + chan_index) * length + offsets */ 918 index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2); 919 index_vec = lp_build_add(uint_bld, index_vec, chan_vec); 920 index_vec = lp_build_mul(uint_bld, index_vec, length_vec); 921 index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets); 922 923 float_ptr_type = 924 LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0); 925 temps_array = LLVMBuildBitCast(builder, bld->temps_array, 926 float_ptr_type, ""); 927 928 /* Scatter store values into temp registers */ 929 emit_mask_scatter(bld, temps_array, index_vec, value, 930 &bld->exec_mask, pred); 931 } 932 else { 933 LLVMValueRef temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, 934 chan_index); 935 lp_exec_mask_store(&bld->exec_mask, pred, value, temp_ptr); 936 } 937 break; 938 939 case TGSI_FILE_ADDRESS: 940 lp_exec_mask_store(&bld->exec_mask, pred, value, 941 bld->addr[reg->Register.Index][chan_index]); 942 break; 943 944 case TGSI_FILE_PREDICATE: 945 lp_exec_mask_store(&bld->exec_mask, pred, value, 946 bld->preds[reg->Register.Index][chan_index]); 947 break; 948 949 default: 950 assert( 0 ); 951 } 952} 953 954static void 955emit_store( 956 struct lp_build_tgsi_context * bld_base, 957 const struct tgsi_full_instruction * inst, 958 const struct tgsi_opcode_info * info, 959 LLVMValueRef dst[4]) 960 961{ 962 unsigned chan_index; 963 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 964 965 if(info->num_dst) { 966 LLVMValueRef pred[TGSI_NUM_CHANNELS]; 967 968 emit_fetch_predicate( bld, inst, pred ); 969 970 TGSI_FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) { 971 emit_store_chan(bld_base, inst, 0, chan_index, pred[chan_index], dst[chan_index]); 972 } 973 } 974} 975 976/** 977 * High-level instruction translators. 978 */ 979 980static void 981emit_tex( struct lp_build_tgsi_soa_context *bld, 982 const struct tgsi_full_instruction *inst, 983 enum lp_build_tex_modifier modifier, 984 LLVMValueRef *texel) 985{ 986 LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder; 987 unsigned unit; 988 LLVMValueRef lod_bias, explicit_lod; 989 LLVMValueRef oow = NULL; 990 LLVMValueRef coords[3]; 991 LLVMValueRef ddx[3]; 992 LLVMValueRef ddy[3]; 993 unsigned num_coords; 994 unsigned i; 995 996 if (!bld->sampler) { 997 _debug_printf("warning: found texture instruction but no sampler generator supplied\n"); 998 for (i = 0; i < 4; i++) { 999 texel[i] = bld->bld_base.base.undef; 1000 } 1001 return; 1002 } 1003 1004 switch (inst->Texture.Texture) { 1005 case TGSI_TEXTURE_1D: 1006 num_coords = 1; 1007 break; 1008 case TGSI_TEXTURE_1D_ARRAY: 1009 case TGSI_TEXTURE_2D: 1010 case TGSI_TEXTURE_RECT: 1011 num_coords = 2; 1012 break; 1013 case TGSI_TEXTURE_SHADOW1D: 1014 case TGSI_TEXTURE_SHADOW1D_ARRAY: 1015 case TGSI_TEXTURE_SHADOW2D: 1016 case TGSI_TEXTURE_SHADOWRECT: 1017 case TGSI_TEXTURE_2D_ARRAY: 1018 case TGSI_TEXTURE_3D: 1019 case TGSI_TEXTURE_CUBE: 1020 num_coords = 3; 1021 break; 1022 case TGSI_TEXTURE_SHADOW2D_ARRAY: 1023 num_coords = 4; 1024 break; 1025 default: 1026 assert(0); 1027 return; 1028 } 1029 1030 if (modifier == LP_BLD_TEX_MODIFIER_LOD_BIAS) { 1031 lod_bias = lp_build_emit_fetch( &bld->bld_base, inst, 0, 3 ); 1032 explicit_lod = NULL; 1033 } 1034 else if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_LOD) { 1035 lod_bias = NULL; 1036 explicit_lod = lp_build_emit_fetch( &bld->bld_base, inst, 0, 3 ); 1037 } 1038 else { 1039 lod_bias = NULL; 1040 explicit_lod = NULL; 1041 } 1042 1043 if (modifier == LP_BLD_TEX_MODIFIER_PROJECTED) { 1044 oow = lp_build_emit_fetch( &bld->bld_base, inst, 0, 3 ); 1045 oow = lp_build_rcp(&bld->bld_base.base, oow); 1046 } 1047 1048 for (i = 0; i < num_coords; i++) { 1049 coords[i] = lp_build_emit_fetch( &bld->bld_base, inst, 0, i ); 1050 if (modifier == LP_BLD_TEX_MODIFIER_PROJECTED) 1051 coords[i] = lp_build_mul(&bld->bld_base.base, coords[i], oow); 1052 } 1053 for (i = num_coords; i < 3; i++) { 1054 coords[i] = bld->bld_base.base.undef; 1055 } 1056 1057 if (modifier == LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV) { 1058 LLVMValueRef index0 = lp_build_const_int32(bld->bld_base.base.gallivm, 0); 1059 for (i = 0; i < num_coords; i++) { 1060 LLVMValueRef src1 = lp_build_emit_fetch( &bld->bld_base, inst, 1, i ); 1061 LLVMValueRef src2 = lp_build_emit_fetch( &bld->bld_base, inst, 2, i ); 1062 ddx[i] = LLVMBuildExtractElement(builder, src1, index0, ""); 1063 ddy[i] = LLVMBuildExtractElement(builder, src2, index0, ""); 1064 } 1065 unit = inst->Src[3].Register.Index; 1066 } else { 1067 for (i = 0; i < num_coords; i++) { 1068 ddx[i] = lp_build_scalar_ddx( &bld->bld_base.base, coords[i] ); 1069 ddy[i] = lp_build_scalar_ddy( &bld->bld_base.base, coords[i] ); 1070 } 1071 unit = inst->Src[1].Register.Index; 1072 } 1073 for (i = num_coords; i < 3; i++) { 1074 ddx[i] = LLVMGetUndef(bld->bld_base.base.elem_type); 1075 ddy[i] = LLVMGetUndef(bld->bld_base.base.elem_type); 1076 } 1077 1078 bld->sampler->emit_fetch_texel(bld->sampler, 1079 bld->bld_base.base.gallivm, 1080 bld->bld_base.base.type, 1081 unit, num_coords, coords, 1082 ddx, ddy, 1083 lod_bias, explicit_lod, 1084 texel); 1085} 1086 1087static boolean 1088near_end_of_shader(struct lp_build_tgsi_soa_context *bld, 1089 int pc) 1090{ 1091 int i; 1092 1093 for (i = 0; i < 5; i++) { 1094 unsigned opcode; 1095 1096 if (pc + i >= bld->bld_base.info->num_instructions) 1097 return TRUE; 1098 1099 opcode = bld->bld_base.instructions[pc + i].Instruction.Opcode; 1100 1101 if (opcode == TGSI_OPCODE_END) 1102 return TRUE; 1103 1104 if (opcode == TGSI_OPCODE_TEX || 1105 opcode == TGSI_OPCODE_TXP || 1106 opcode == TGSI_OPCODE_TXD || 1107 opcode == TGSI_OPCODE_TXB || 1108 opcode == TGSI_OPCODE_TXL || 1109 opcode == TGSI_OPCODE_TXF || 1110 opcode == TGSI_OPCODE_TXQ || 1111 opcode == TGSI_OPCODE_CAL || 1112 opcode == TGSI_OPCODE_CALLNZ || 1113 opcode == TGSI_OPCODE_IF || 1114 opcode == TGSI_OPCODE_IFC || 1115 opcode == TGSI_OPCODE_BGNLOOP || 1116 opcode == TGSI_OPCODE_SWITCH) 1117 return FALSE; 1118 } 1119 1120 return TRUE; 1121} 1122 1123 1124 1125/** 1126 * Kill fragment if any of the src register values are negative. 1127 */ 1128static void 1129emit_kil( 1130 struct lp_build_tgsi_soa_context *bld, 1131 const struct tgsi_full_instruction *inst, 1132 int pc) 1133{ 1134 LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder; 1135 const struct tgsi_full_src_register *reg = &inst->Src[0]; 1136 LLVMValueRef terms[TGSI_NUM_CHANNELS]; 1137 LLVMValueRef mask; 1138 unsigned chan_index; 1139 1140 memset(&terms, 0, sizeof terms); 1141 1142 TGSI_FOR_EACH_CHANNEL( chan_index ) { 1143 unsigned swizzle; 1144 1145 /* Unswizzle channel */ 1146 swizzle = tgsi_util_get_full_src_register_swizzle( reg, chan_index ); 1147 1148 /* Check if the component has not been already tested. */ 1149 assert(swizzle < TGSI_NUM_CHANNELS); 1150 if( !terms[swizzle] ) 1151 /* TODO: change the comparison operator instead of setting the sign */ 1152 terms[swizzle] = lp_build_emit_fetch(&bld->bld_base, inst, 0, chan_index ); 1153 } 1154 1155 mask = NULL; 1156 TGSI_FOR_EACH_CHANNEL( chan_index ) { 1157 if(terms[chan_index]) { 1158 LLVMValueRef chan_mask; 1159 1160 /* 1161 * If term < 0 then mask = 0 else mask = ~0. 1162 */ 1163 chan_mask = lp_build_cmp(&bld->bld_base.base, PIPE_FUNC_GEQUAL, terms[chan_index], bld->bld_base.base.zero); 1164 1165 if(mask) 1166 mask = LLVMBuildAnd(builder, mask, chan_mask, ""); 1167 else 1168 mask = chan_mask; 1169 } 1170 } 1171 1172 if(mask) { 1173 lp_build_mask_update(bld->mask, mask); 1174 1175 if (!near_end_of_shader(bld, pc)) 1176 lp_build_mask_check(bld->mask); 1177 } 1178} 1179 1180 1181/** 1182 * Predicated fragment kill. 1183 * XXX Actually, we do an unconditional kill (as in tgsi_exec.c). 1184 * The only predication is the execution mask which will apply if 1185 * we're inside a loop or conditional. 1186 */ 1187static void 1188emit_kilp(struct lp_build_tgsi_soa_context *bld, 1189 int pc) 1190{ 1191 LLVMBuilderRef builder = bld->bld_base.base.gallivm->builder; 1192 LLVMValueRef mask; 1193 1194 /* For those channels which are "alive", disable fragment shader 1195 * execution. 1196 */ 1197 if (bld->exec_mask.has_mask) { 1198 mask = LLVMBuildNot(builder, bld->exec_mask.exec_mask, "kilp"); 1199 } 1200 else { 1201 LLVMValueRef zero = LLVMConstNull(bld->bld_base.base.int_vec_type); 1202 mask = zero; 1203 } 1204 1205 lp_build_mask_update(bld->mask, mask); 1206 1207 if (!near_end_of_shader(bld, pc)) 1208 lp_build_mask_check(bld->mask); 1209} 1210 1211 1212/** 1213 * Emit code which will dump the value of all the temporary registers 1214 * to stdout. 1215 */ 1216static void 1217emit_dump_temps(struct lp_build_tgsi_soa_context *bld) 1218{ 1219 struct gallivm_state *gallivm = bld->bld_base.base.gallivm; 1220 LLVMBuilderRef builder = gallivm->builder; 1221 LLVMValueRef temp_ptr; 1222 LLVMValueRef i0 = lp_build_const_int32(gallivm, 0); 1223 LLVMValueRef i1 = lp_build_const_int32(gallivm, 1); 1224 LLVMValueRef i2 = lp_build_const_int32(gallivm, 2); 1225 LLVMValueRef i3 = lp_build_const_int32(gallivm, 3); 1226 int index; 1227 int n = bld->bld_base.info->file_max[TGSI_FILE_TEMPORARY]; 1228 1229 for (index = 0; index < n; index++) { 1230 LLVMValueRef idx = lp_build_const_int32(gallivm, index); 1231 LLVMValueRef v[4][4], res; 1232 int chan; 1233 1234 lp_build_printf(gallivm, "TEMP[%d]:\n", idx); 1235 1236 for (chan = 0; chan < 4; chan++) { 1237 temp_ptr = lp_get_temp_ptr_soa(bld, index, chan); 1238 res = LLVMBuildLoad(builder, temp_ptr, ""); 1239 v[chan][0] = LLVMBuildExtractElement(builder, res, i0, ""); 1240 v[chan][1] = LLVMBuildExtractElement(builder, res, i1, ""); 1241 v[chan][2] = LLVMBuildExtractElement(builder, res, i2, ""); 1242 v[chan][3] = LLVMBuildExtractElement(builder, res, i3, ""); 1243 } 1244 1245 lp_build_printf(gallivm, " X: %f %f %f %f\n", 1246 v[0][0], v[0][1], v[0][2], v[0][3]); 1247 lp_build_printf(gallivm, " Y: %f %f %f %f\n", 1248 v[1][0], v[1][1], v[1][2], v[1][3]); 1249 lp_build_printf(gallivm, " Z: %f %f %f %f\n", 1250 v[2][0], v[2][1], v[2][2], v[2][3]); 1251 lp_build_printf(gallivm, " W: %f %f %f %f\n", 1252 v[3][0], v[3][1], v[3][2], v[3][3]); 1253 } 1254} 1255 1256 1257 1258void 1259lp_emit_declaration_soa( 1260 struct lp_build_tgsi_context *bld_base, 1261 const struct tgsi_full_declaration *decl) 1262{ 1263 struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base); 1264 struct gallivm_state *gallivm = bld->bld_base.base.gallivm; 1265 LLVMTypeRef vec_type = bld->bld_base.base.vec_type; 1266 const unsigned first = decl->Range.First; 1267 const unsigned last = decl->Range.Last; 1268 unsigned idx, i; 1269 1270 for (idx = first; idx <= last; ++idx) { 1271 assert(last <= bld->bld_base.info->file_max[decl->Declaration.File]); 1272 switch (decl->Declaration.File) { 1273 case TGSI_FILE_TEMPORARY: 1274 assert(idx < LP_MAX_TGSI_TEMPS); 1275 if (!(bld->indirect_files & (1 << TGSI_FILE_TEMPORARY))) { 1276 for (i = 0; i < TGSI_NUM_CHANNELS; i++) 1277 bld->temps[idx][i] = lp_build_alloca(gallivm, vec_type, "temp"); 1278 } 1279 break; 1280 1281 case TGSI_FILE_OUTPUT: 1282 if (!(bld->indirect_files & (1 << TGSI_FILE_OUTPUT))) { 1283 for (i = 0; i < TGSI_NUM_CHANNELS; i++) 1284 bld->outputs[idx][i] = lp_build_alloca(gallivm, 1285 vec_type, "output"); 1286 } 1287 break; 1288 1289 case TGSI_FILE_ADDRESS: 1290 assert(idx < LP_MAX_TGSI_ADDRS); 1291 for (i = 0; i < TGSI_NUM_CHANNELS; i++) 1292 bld->addr[idx][i] = lp_build_alloca(gallivm, vec_type, "addr"); 1293 break; 1294 1295 case TGSI_FILE_PREDICATE: 1296 assert(idx < LP_MAX_TGSI_PREDS); 1297 for (i = 0; i < TGSI_NUM_CHANNELS; i++) 1298 bld->preds[idx][i] = lp_build_alloca(gallivm, vec_type, 1299 "predicate"); 1300 break; 1301 1302 default: 1303 /* don't need to declare other vars */ 1304 break; 1305 } 1306 } 1307} 1308 1309 1310void lp_emit_immediate_soa( 1311 struct lp_build_tgsi_context *bld_base, 1312 const struct tgsi_full_immediate *imm) 1313{ 1314 struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base); 1315 struct gallivm_state * gallivm = bld_base->base.gallivm; 1316 1317 /* simply copy the immediate values into the next immediates[] slot */ 1318 unsigned i; 1319 const uint size = imm->Immediate.NrTokens - 1; 1320 assert(size <= 4); 1321 assert(bld->num_immediates < LP_MAX_TGSI_IMMEDIATES); 1322 1323 for( i = 0; i < size; ++i ) 1324 bld->immediates[bld->num_immediates][i] = 1325 lp_build_const_vec(gallivm, bld_base->base.type, imm->u[i].Float); 1326 1327 for( i = size; i < 4; ++i ) 1328 bld->immediates[bld->num_immediates][i] = bld_base->base.undef; 1329 1330 bld->num_immediates++; 1331} 1332 1333static void 1334ddx_emit( 1335 const struct lp_build_tgsi_action * action, 1336 struct lp_build_tgsi_context * bld_base, 1337 struct lp_build_emit_data * emit_data) 1338{ 1339 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1340 1341 emit_fetch_deriv(bld, emit_data->args[0], NULL, 1342 &emit_data->output[emit_data->chan], NULL); 1343} 1344 1345static void 1346ddy_emit( 1347 const struct lp_build_tgsi_action * action, 1348 struct lp_build_tgsi_context * bld_base, 1349 struct lp_build_emit_data * emit_data) 1350{ 1351 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1352 1353 emit_fetch_deriv(bld, emit_data->args[0], NULL, NULL, 1354 &emit_data->output[emit_data->chan]); 1355} 1356 1357static void 1358kilp_emit( 1359 const struct lp_build_tgsi_action * action, 1360 struct lp_build_tgsi_context * bld_base, 1361 struct lp_build_emit_data * emit_data) 1362{ 1363 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1364 1365 emit_kilp(bld, bld_base->pc - 1); 1366} 1367 1368static void 1369kil_emit( 1370 const struct lp_build_tgsi_action * action, 1371 struct lp_build_tgsi_context * bld_base, 1372 struct lp_build_emit_data * emit_data) 1373{ 1374 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1375 1376 emit_kil(bld, emit_data->inst, bld_base->pc - 1); 1377} 1378 1379static void 1380tex_emit( 1381 const struct lp_build_tgsi_action * action, 1382 struct lp_build_tgsi_context * bld_base, 1383 struct lp_build_emit_data * emit_data) 1384{ 1385 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1386 1387 emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_NONE, emit_data->output); 1388} 1389 1390static void 1391txb_emit( 1392 const struct lp_build_tgsi_action * action, 1393 struct lp_build_tgsi_context * bld_base, 1394 struct lp_build_emit_data * emit_data) 1395{ 1396 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1397 1398 emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_LOD_BIAS, 1399 emit_data->output); 1400} 1401 1402static void 1403txd_emit( 1404 const struct lp_build_tgsi_action * action, 1405 struct lp_build_tgsi_context * bld_base, 1406 struct lp_build_emit_data * emit_data) 1407{ 1408 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1409 1410 emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_EXPLICIT_DERIV, 1411 emit_data->output); 1412} 1413 1414static void 1415txl_emit( 1416 const struct lp_build_tgsi_action * action, 1417 struct lp_build_tgsi_context * bld_base, 1418 struct lp_build_emit_data * emit_data) 1419{ 1420 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1421 1422 emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_EXPLICIT_LOD, 1423 emit_data->output); 1424} 1425 1426static void 1427txp_emit( 1428 const struct lp_build_tgsi_action * action, 1429 struct lp_build_tgsi_context * bld_base, 1430 struct lp_build_emit_data * emit_data) 1431{ 1432 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1433 1434 emit_tex(bld, emit_data->inst, LP_BLD_TEX_MODIFIER_PROJECTED, 1435 emit_data->output); 1436} 1437 1438static void 1439cal_emit( 1440 const struct lp_build_tgsi_action * action, 1441 struct lp_build_tgsi_context * bld_base, 1442 struct lp_build_emit_data * emit_data) 1443{ 1444 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1445 1446 lp_exec_mask_call(&bld->exec_mask, emit_data->inst->Label.Label, 1447 &bld_base->pc); 1448} 1449 1450static void 1451ret_emit( 1452 const struct lp_build_tgsi_action * action, 1453 struct lp_build_tgsi_context * bld_base, 1454 struct lp_build_emit_data * emit_data) 1455{ 1456 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1457 1458 lp_exec_mask_ret(&bld->exec_mask, &bld_base->pc); 1459} 1460 1461static void 1462brk_emit( 1463 const struct lp_build_tgsi_action * action, 1464 struct lp_build_tgsi_context * bld_base, 1465 struct lp_build_emit_data * emit_data) 1466{ 1467 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1468 1469 lp_exec_break(&bld->exec_mask); 1470} 1471 1472static void 1473if_emit( 1474 const struct lp_build_tgsi_action * action, 1475 struct lp_build_tgsi_context * bld_base, 1476 struct lp_build_emit_data * emit_data) 1477{ 1478 LLVMValueRef tmp; 1479 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1480 1481 tmp = lp_build_cmp(&bld_base->base, PIPE_FUNC_NOTEQUAL, 1482 emit_data->args[0], bld->bld_base.base.zero); 1483 lp_exec_mask_cond_push(&bld->exec_mask, tmp); 1484} 1485 1486static void 1487bgnloop_emit( 1488 const struct lp_build_tgsi_action * action, 1489 struct lp_build_tgsi_context * bld_base, 1490 struct lp_build_emit_data * emit_data) 1491{ 1492 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1493 1494 lp_exec_bgnloop(&bld->exec_mask); 1495} 1496 1497static void 1498bgnsub_emit( 1499 const struct lp_build_tgsi_action * action, 1500 struct lp_build_tgsi_context * bld_base, 1501 struct lp_build_emit_data * emit_data) 1502{ 1503 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1504 1505 lp_exec_mask_bgnsub(&bld->exec_mask); 1506} 1507 1508static void 1509else_emit( 1510 const struct lp_build_tgsi_action * action, 1511 struct lp_build_tgsi_context * bld_base, 1512 struct lp_build_emit_data * emit_data) 1513{ 1514 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1515 1516 lp_exec_mask_cond_invert(&bld->exec_mask); 1517} 1518 1519static void 1520endif_emit( 1521 const struct lp_build_tgsi_action * action, 1522 struct lp_build_tgsi_context * bld_base, 1523 struct lp_build_emit_data * emit_data) 1524{ 1525 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1526 1527 lp_exec_mask_cond_pop(&bld->exec_mask); 1528} 1529 1530static void 1531endloop_emit( 1532 const struct lp_build_tgsi_action * action, 1533 struct lp_build_tgsi_context * bld_base, 1534 struct lp_build_emit_data * emit_data) 1535{ 1536 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1537 1538 lp_exec_endloop(bld_base->base.gallivm, &bld->exec_mask); 1539} 1540 1541static void 1542endsub_emit( 1543 const struct lp_build_tgsi_action * action, 1544 struct lp_build_tgsi_context * bld_base, 1545 struct lp_build_emit_data * emit_data) 1546{ 1547 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1548 1549 lp_exec_mask_endsub(&bld->exec_mask, &bld_base->pc); 1550} 1551 1552static void 1553cont_emit( 1554 const struct lp_build_tgsi_action * action, 1555 struct lp_build_tgsi_context * bld_base, 1556 struct lp_build_emit_data * emit_data) 1557{ 1558 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1559 1560 lp_exec_continue(&bld->exec_mask); 1561} 1562 1563/* XXX: Refactor and move it to lp_bld_tgsi_action.c 1564 * 1565 * XXX: What do the comments about xmm registers mean? Maybe they are left over 1566 * from old code, but there is no garauntee that LLVM will use those registers 1567 * for this code. 1568 * 1569 * XXX: There should be no calls to lp_build_emit_fetch in this function. This 1570 * should be handled by the emit_data->fetch_args function. */ 1571static void 1572nrm_emit( 1573 const struct lp_build_tgsi_action * action, 1574 struct lp_build_tgsi_context * bld_base, 1575 struct lp_build_emit_data * emit_data) 1576{ 1577 LLVMValueRef tmp0, tmp1; 1578 LLVMValueRef tmp4 = NULL; 1579 LLVMValueRef tmp5 = NULL; 1580 LLVMValueRef tmp6 = NULL; 1581 LLVMValueRef tmp7 = NULL; 1582 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1583 1584 uint dims = (emit_data->inst->Instruction.Opcode == TGSI_OPCODE_NRM) ? 3 : 4; 1585 1586 if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_X) || 1587 TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_Y) || 1588 TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_Z) || 1589 (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_W) && dims == 4)) { 1590 1591 /* NOTE: Cannot use xmm regs 2/3 here (see emit_rsqrt() above). */ 1592 1593 /* xmm4 = src.x */ 1594 /* xmm0 = src.x * src.x */ 1595 tmp0 = lp_build_emit_fetch(&bld->bld_base, emit_data->inst, 0, TGSI_CHAN_X); 1596 if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_X)) { 1597 tmp4 = tmp0; 1598 } 1599 tmp0 = lp_build_mul( &bld->bld_base.base, tmp0, tmp0); 1600 1601 /* xmm5 = src.y */ 1602 /* xmm0 = xmm0 + src.y * src.y */ 1603 tmp1 = lp_build_emit_fetch(&bld->bld_base, emit_data->inst, 0, TGSI_CHAN_Y); 1604 if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_Y)) { 1605 tmp5 = tmp1; 1606 } 1607 tmp1 = lp_build_mul( &bld->bld_base.base, tmp1, tmp1); 1608 tmp0 = lp_build_add( &bld->bld_base.base, tmp0, tmp1); 1609 1610 /* xmm6 = src.z */ 1611 /* xmm0 = xmm0 + src.z * src.z */ 1612 tmp1 = lp_build_emit_fetch(&bld->bld_base, emit_data->inst, 0, TGSI_CHAN_Z); 1613 if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_Z)) { 1614 tmp6 = tmp1; 1615 } 1616 tmp1 = lp_build_mul( &bld->bld_base.base, tmp1, tmp1); 1617 tmp0 = lp_build_add( &bld->bld_base.base, tmp0, tmp1); 1618 1619 if (dims == 4) { 1620 /* xmm7 = src.w */ 1621 /* xmm0 = xmm0 + src.w * src.w */ 1622 tmp1 = lp_build_emit_fetch(&bld->bld_base, emit_data->inst, 0, TGSI_CHAN_W); 1623 if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_W)) { 1624 tmp7 = tmp1; 1625 } 1626 tmp1 = lp_build_mul( &bld->bld_base.base, tmp1, tmp1); 1627 tmp0 = lp_build_add( &bld->bld_base.base, tmp0, tmp1); 1628 } 1629 /* xmm1 = 1 / sqrt(xmm0) */ 1630 tmp1 = lp_build_rsqrt( &bld->bld_base.base, tmp0); 1631 /* dst.x = xmm1 * src.x */ 1632 if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_X)) { 1633 emit_data->output[TGSI_CHAN_X] = lp_build_mul( &bld->bld_base.base, tmp4, tmp1); 1634 } 1635 /* dst.y = xmm1 * src.y */ 1636 if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_Y)) { 1637 emit_data->output[TGSI_CHAN_Y] = lp_build_mul( &bld->bld_base.base, tmp5, tmp1); 1638 } 1639 1640 /* dst.z = xmm1 * src.z */ 1641 if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_Z)) { 1642 emit_data->output[TGSI_CHAN_Z] = lp_build_mul( &bld->bld_base.base, tmp6, tmp1); 1643 } 1644 /* dst.w = xmm1 * src.w */ 1645 if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_X) && dims == 4) { 1646 emit_data->output[TGSI_CHAN_W] = lp_build_mul( &bld->bld_base.base, tmp7, tmp1); 1647 } 1648 } 1649 1650 /* dst.w = 1.0 */ 1651 if (TGSI_IS_DST0_CHANNEL_ENABLED(emit_data->inst, TGSI_CHAN_W) && dims == 3) { 1652 emit_data->output[TGSI_CHAN_W] = bld->bld_base.base.one; 1653 } 1654} 1655 1656static void emit_prologue(struct lp_build_tgsi_context * bld_base) 1657{ 1658 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1659 struct gallivm_state * gallivm = bld_base->base.gallivm; 1660 1661 if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) { 1662 LLVMValueRef array_size = 1663 lp_build_const_int32(gallivm, 1664 bld_base->info->file_max[TGSI_FILE_TEMPORARY] * 4 + 4); 1665 bld->temps_array = lp_build_array_alloca(gallivm, 1666 bld_base->base.vec_type, array_size, 1667 "temp_array"); 1668 } 1669 1670 if (bld->indirect_files & (1 << TGSI_FILE_OUTPUT)) { 1671 LLVMValueRef array_size = 1672 lp_build_const_int32(gallivm, 1673 bld_base->info->file_max[TGSI_FILE_OUTPUT] * 4 + 4); 1674 bld->outputs_array = lp_build_array_alloca(gallivm, 1675 bld_base->base.vec_type, array_size, 1676 "output_array"); 1677 } 1678 1679 /* If we have indirect addressing in inputs we need to copy them into 1680 * our alloca array to be able to iterate over them */ 1681 if (bld->indirect_files & (1 << TGSI_FILE_INPUT)) { 1682 unsigned index, chan; 1683 LLVMTypeRef vec_type = bld_base->base.vec_type; 1684 LLVMValueRef array_size = lp_build_const_int32(gallivm, 1685 bld_base->info->file_max[TGSI_FILE_INPUT]*4 + 4); 1686 bld->inputs_array = lp_build_array_alloca(gallivm, 1687 vec_type, array_size, 1688 "input_array"); 1689 1690 assert(bld_base->info->num_inputs 1691 <= bld_base->info->file_max[TGSI_FILE_INPUT] + 1); 1692 1693 for (index = 0; index < bld_base->info->num_inputs; ++index) { 1694 for (chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) { 1695 LLVMValueRef lindex = 1696 lp_build_const_int32(gallivm, index * 4 + chan); 1697 LLVMValueRef input_ptr = 1698 LLVMBuildGEP(gallivm->builder, bld->inputs_array, 1699 &lindex, 1, ""); 1700 LLVMValueRef value = bld->inputs[index][chan]; 1701 if (value) 1702 LLVMBuildStore(gallivm->builder, value, input_ptr); 1703 } 1704 } 1705 } 1706} 1707 1708static void emit_epilogue(struct lp_build_tgsi_context * bld_base) 1709{ 1710 struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base); 1711 1712 if (0) { 1713 /* for debugging */ 1714 emit_dump_temps(bld); 1715 } 1716 1717 /* If we have indirect addressing in outputs we need to copy our alloca array 1718 * to the outputs slots specified by the called */ 1719 if (bld->indirect_files & (1 << TGSI_FILE_OUTPUT)) { 1720 unsigned index, chan; 1721 assert(bld_base->info->num_outputs <= 1722 bld_base->info->file_max[TGSI_FILE_OUTPUT] + 1); 1723 for (index = 0; index < bld_base->info->num_outputs; ++index) { 1724 for (chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) { 1725 bld->outputs[index][chan] = lp_get_output_ptr(bld, index, chan); 1726 } 1727 } 1728 } 1729} 1730 1731void 1732lp_build_tgsi_soa(struct gallivm_state *gallivm, 1733 const struct tgsi_token *tokens, 1734 struct lp_type type, 1735 struct lp_build_mask_context *mask, 1736 LLVMValueRef consts_ptr, 1737 LLVMValueRef system_values_array, 1738 const LLVMValueRef *pos, 1739 const LLVMValueRef (*inputs)[TGSI_NUM_CHANNELS], 1740 LLVMValueRef (*outputs)[TGSI_NUM_CHANNELS], 1741 struct lp_build_sampler_soa *sampler, 1742 const struct tgsi_shader_info *info) 1743{ 1744 struct lp_build_tgsi_soa_context bld; 1745 1746 struct lp_type res_type; 1747 1748 assert(type.length <= LP_MAX_VECTOR_LENGTH); 1749 memset(&res_type, 0, sizeof res_type); 1750 res_type.width = type.width; 1751 res_type.length = type.length; 1752 res_type.sign = 1; 1753 1754 /* Setup build context */ 1755 memset(&bld, 0, sizeof bld); 1756 lp_build_context_init(&bld.bld_base.base, gallivm, type); 1757 lp_build_context_init(&bld.uint_bld, gallivm, lp_uint_type(type)); 1758 lp_build_context_init(&bld.elem_bld, gallivm, lp_elem_type(type)); 1759 bld.mask = mask; 1760 bld.pos = pos; 1761 bld.inputs = inputs; 1762 bld.outputs = outputs; 1763 bld.consts_ptr = consts_ptr; 1764 bld.sampler = sampler; 1765 bld.bld_base.info = info; 1766 bld.indirect_files = info->indirect_files; 1767 1768 bld.bld_base.soa = TRUE; 1769 bld.bld_base.emit_fetch_funcs[TGSI_FILE_CONSTANT] = emit_fetch_constant; 1770 bld.bld_base.emit_fetch_funcs[TGSI_FILE_IMMEDIATE] = emit_fetch_immediate; 1771 bld.bld_base.emit_fetch_funcs[TGSI_FILE_INPUT] = emit_fetch_input; 1772 bld.bld_base.emit_fetch_funcs[TGSI_FILE_TEMPORARY] = emit_fetch_temporary; 1773 bld.bld_base.emit_fetch_funcs[TGSI_FILE_SYSTEM_VALUE] = emit_fetch_system_value; 1774 bld.bld_base.emit_store = emit_store; 1775 1776 bld.bld_base.emit_declaration = lp_emit_declaration_soa; 1777 bld.bld_base.emit_immediate = lp_emit_immediate_soa; 1778 1779 bld.bld_base.emit_prologue = emit_prologue; 1780 bld.bld_base.emit_epilogue = emit_epilogue; 1781 1782 /* Set opcode actions */ 1783 lp_set_default_actions_cpu(&bld.bld_base); 1784 1785 bld.bld_base.op_actions[TGSI_OPCODE_BGNLOOP].emit = bgnloop_emit; 1786 bld.bld_base.op_actions[TGSI_OPCODE_BGNSUB].emit = bgnsub_emit; 1787 bld.bld_base.op_actions[TGSI_OPCODE_BRK].emit = brk_emit; 1788 bld.bld_base.op_actions[TGSI_OPCODE_CAL].emit = cal_emit; 1789 bld.bld_base.op_actions[TGSI_OPCODE_CONT].emit = cont_emit; 1790 bld.bld_base.op_actions[TGSI_OPCODE_DDX].emit = ddx_emit; 1791 bld.bld_base.op_actions[TGSI_OPCODE_DDY].emit = ddy_emit; 1792 bld.bld_base.op_actions[TGSI_OPCODE_ELSE].emit = else_emit; 1793 bld.bld_base.op_actions[TGSI_OPCODE_ENDIF].emit = endif_emit; 1794 bld.bld_base.op_actions[TGSI_OPCODE_ENDLOOP].emit = endloop_emit; 1795 bld.bld_base.op_actions[TGSI_OPCODE_ENDSUB].emit = endsub_emit; 1796 bld.bld_base.op_actions[TGSI_OPCODE_IF].emit = if_emit; 1797 bld.bld_base.op_actions[TGSI_OPCODE_KIL].emit = kil_emit; 1798 bld.bld_base.op_actions[TGSI_OPCODE_KILP].emit = kilp_emit; 1799 bld.bld_base.op_actions[TGSI_OPCODE_NRM].emit = nrm_emit; 1800 bld.bld_base.op_actions[TGSI_OPCODE_NRM4].emit = nrm_emit; 1801 bld.bld_base.op_actions[TGSI_OPCODE_RET].emit = ret_emit; 1802 bld.bld_base.op_actions[TGSI_OPCODE_TEX].emit = tex_emit; 1803 bld.bld_base.op_actions[TGSI_OPCODE_TXB].emit = txb_emit; 1804 bld.bld_base.op_actions[TGSI_OPCODE_TXD].emit = txd_emit; 1805 bld.bld_base.op_actions[TGSI_OPCODE_TXL].emit = txl_emit; 1806 bld.bld_base.op_actions[TGSI_OPCODE_TXP].emit = txp_emit; 1807 1808 lp_exec_mask_init(&bld.exec_mask, &bld.bld_base.base); 1809 1810 1811 bld.system_values_array = system_values_array; 1812 1813 lp_build_tgsi_llvm(&bld.bld_base, tokens); 1814 1815 if (0) { 1816 LLVMBasicBlockRef block = LLVMGetInsertBlock(gallivm->builder); 1817 LLVMValueRef function = LLVMGetBasicBlockParent(block); 1818 debug_printf("11111111111111111111111111111 \n"); 1819 tgsi_dump(tokens, 0); 1820 lp_debug_dump_value(function); 1821 debug_printf("2222222222222222222222222222 \n"); 1822 } 1823 1824 if (0) { 1825 LLVMModuleRef module = LLVMGetGlobalParent( 1826 LLVMGetBasicBlockParent(LLVMGetInsertBlock(gallivm->builder))); 1827 LLVMDumpModule(module); 1828 1829 } 1830} 1831 1832 1833/** 1834 * Build up the system values array out of individual values such as 1835 * the instance ID, front-face, primitive ID, etc. The shader info is 1836 * used to determine which system values are needed and where to put 1837 * them in the system values array. 1838 * 1839 * XXX only instance ID is implemented at this time. 1840 * 1841 * The system values register file is similar to the constants buffer. 1842 * Example declaration: 1843 * DCL SV[0], INSTANCEID 1844 * Example instruction: 1845 * MOVE foo, SV[0].xxxx; 1846 * 1847 * \return LLVM float array (interpreted as float [][4]) 1848 */ 1849LLVMValueRef 1850lp_build_system_values_array(struct gallivm_state *gallivm, 1851 const struct tgsi_shader_info *info, 1852 LLVMValueRef instance_id, 1853 LLVMValueRef facing) 1854{ 1855 LLVMValueRef size = lp_build_const_int32(gallivm, 4 * info->num_system_values); 1856 LLVMTypeRef float_t = LLVMFloatTypeInContext(gallivm->context); 1857 LLVMValueRef array = lp_build_array_alloca(gallivm, float_t, 1858 size, "sysvals_array"); 1859 unsigned i; 1860 1861 for (i = 0; i < info->num_system_values; i++) { 1862 LLVMValueRef index = lp_build_const_int32(gallivm, i * 4); 1863 LLVMValueRef ptr, value = 0; 1864 1865 switch (info->system_value_semantic_name[i]) { 1866 case TGSI_SEMANTIC_INSTANCEID: 1867 /* convert instance ID from int to float */ 1868 value = LLVMBuildSIToFP(gallivm->builder, instance_id, float_t, 1869 "sysval_instanceid"); 1870 break; 1871 case TGSI_SEMANTIC_FACE: 1872 /* fall-through */ 1873 default: 1874 assert(0 && "unexpected semantic in build_system_values_array()"); 1875 } 1876 1877 ptr = LLVMBuildGEP(gallivm->builder, array, &index, 1, ""); 1878 LLVMBuildStore(gallivm->builder, value, ptr); 1879 } 1880 1881 return array; 1882} 1883