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