draw_llvm.c revision 1570760a9756234978ff56a9db4c781a630fe6ce
1#include "draw_llvm.h" 2 3#include "draw_context.h" 4#include "draw_vs.h" 5 6#include "gallivm/lp_bld_arit.h" 7#include "gallivm/lp_bld_interp.h" 8#include "gallivm/lp_bld_struct.h" 9#include "gallivm/lp_bld_type.h" 10#include "gallivm/lp_bld_flow.h" 11#include "gallivm/lp_bld_debug.h" 12#include "gallivm/lp_bld_tgsi.h" 13#include "gallivm/lp_bld_printf.h" 14 15#include "util/u_cpu_detect.h" 16#include "tgsi/tgsi_dump.h" 17 18#include <llvm-c/Transforms/Scalar.h> 19 20#define DEBUG_STORE 0 21 22 23/* generates the draw jit function */ 24static void 25draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *var); 26 27static void 28init_globals(struct draw_llvm *llvm) 29{ 30 LLVMTypeRef texture_type; 31 32 /* struct draw_jit_texture */ 33 { 34 LLVMTypeRef elem_types[4]; 35 36 elem_types[DRAW_JIT_TEXTURE_WIDTH] = LLVMInt32Type(); 37 elem_types[DRAW_JIT_TEXTURE_HEIGHT] = LLVMInt32Type(); 38 elem_types[DRAW_JIT_TEXTURE_STRIDE] = LLVMInt32Type(); 39 elem_types[DRAW_JIT_TEXTURE_DATA] = LLVMPointerType(LLVMInt8Type(), 0); 40 41 texture_type = LLVMStructType(elem_types, Elements(elem_types), 0); 42 43 LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, width, 44 llvm->target, texture_type, 45 DRAW_JIT_TEXTURE_WIDTH); 46 LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, height, 47 llvm->target, texture_type, 48 DRAW_JIT_TEXTURE_HEIGHT); 49 LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, stride, 50 llvm->target, texture_type, 51 DRAW_JIT_TEXTURE_STRIDE); 52 LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture, data, 53 llvm->target, texture_type, 54 DRAW_JIT_TEXTURE_DATA); 55 LP_CHECK_STRUCT_SIZE(struct draw_jit_texture, 56 llvm->target, texture_type); 57 58 LLVMAddTypeName(llvm->module, "texture", texture_type); 59 } 60 61 62 /* struct draw_jit_context */ 63 { 64 LLVMTypeRef elem_types[3]; 65 LLVMTypeRef context_type; 66 67 elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* vs_constants */ 68 elem_types[1] = LLVMPointerType(LLVMFloatType(), 0); /* vs_constants */ 69 elem_types[2] = LLVMArrayType(texture_type, PIPE_MAX_SAMPLERS); /* textures */ 70 71 context_type = LLVMStructType(elem_types, Elements(elem_types), 0); 72 73 LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, vs_constants, 74 llvm->target, context_type, 0); 75 LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, gs_constants, 76 llvm->target, context_type, 1); 77 LP_CHECK_MEMBER_OFFSET(struct draw_jit_context, textures, 78 llvm->target, context_type, 79 DRAW_JIT_CONTEXT_TEXTURES_INDEX); 80 LP_CHECK_STRUCT_SIZE(struct draw_jit_context, 81 llvm->target, context_type); 82 83 LLVMAddTypeName(llvm->module, "draw_jit_context", context_type); 84 85 llvm->context_ptr_type = LLVMPointerType(context_type, 0); 86 } 87 { 88 LLVMTypeRef buffer_ptr = LLVMPointerType(LLVMIntType(8), 0); 89 llvm->buffer_ptr_type = LLVMPointerType(buffer_ptr, 0); 90 } 91} 92 93static LLVMTypeRef 94create_vertex_header(struct draw_llvm *llvm, int data_elems) 95{ 96 /* struct vertex_header */ 97 LLVMTypeRef elem_types[3]; 98 LLVMTypeRef vertex_header; 99 char struct_name[24]; 100 101 snprintf(struct_name, 23, "vertex_header%d", data_elems); 102 103 elem_types[0] = LLVMIntType(32); 104 elem_types[1] = LLVMArrayType(LLVMFloatType(), 4); 105 elem_types[2] = LLVMArrayType(elem_types[1], data_elems); 106 107 vertex_header = LLVMStructType(elem_types, Elements(elem_types), 0); 108 109 /* these are bit-fields and we can't take address of them 110 LP_CHECK_MEMBER_OFFSET(struct vertex_header, clipmask, 111 llvm->target, vertex_header, 112 DRAW_JIT_VERTEX_CLIPMASK); 113 LP_CHECK_MEMBER_OFFSET(struct vertex_header, edgeflag, 114 llvm->target, vertex_header, 115 DRAW_JIT_VERTEX_EDGEFLAG); 116 LP_CHECK_MEMBER_OFFSET(struct vertex_header, pad, 117 llvm->target, vertex_header, 118 DRAW_JIT_VERTEX_PAD); 119 LP_CHECK_MEMBER_OFFSET(struct vertex_header, vertex_id, 120 llvm->target, vertex_header, 121 DRAW_JIT_VERTEX_VERTEX_ID); 122 */ 123 LP_CHECK_MEMBER_OFFSET(struct vertex_header, clip, 124 llvm->target, vertex_header, 125 DRAW_JIT_VERTEX_CLIP); 126 LP_CHECK_MEMBER_OFFSET(struct vertex_header, data, 127 llvm->target, vertex_header, 128 DRAW_JIT_VERTEX_DATA); 129 130 LLVMAddTypeName(llvm->module, struct_name, vertex_header); 131 132 return LLVMPointerType(vertex_header, 0); 133} 134 135struct draw_llvm * 136draw_llvm_create(struct draw_context *draw) 137{ 138 struct draw_llvm *llvm = CALLOC_STRUCT( draw_llvm ); 139 140 util_cpu_detect(); 141 142 llvm->draw = draw; 143 llvm->engine = draw->engine; 144 145 debug_assert(llvm->engine); 146 147 llvm->module = LLVMModuleCreateWithName("draw_llvm"); 148 llvm->provider = LLVMCreateModuleProviderForExistingModule(llvm->module); 149 150 LLVMAddModuleProvider(llvm->engine, llvm->provider); 151 152 llvm->target = LLVMGetExecutionEngineTargetData(llvm->engine); 153 154 llvm->pass = LLVMCreateFunctionPassManager(llvm->provider); 155 LLVMAddTargetData(llvm->target, llvm->pass); 156 /* These are the passes currently listed in llvm-c/Transforms/Scalar.h, 157 * but there are more on SVN. */ 158 /* TODO: Add more passes */ 159 LLVMAddConstantPropagationPass(llvm->pass); 160 if(util_cpu_caps.has_sse4_1) { 161 /* FIXME: There is a bug in this pass, whereby the combination of fptosi 162 * and sitofp (necessary for trunc/floor/ceil/round implementation) 163 * somehow becomes invalid code. 164 */ 165 LLVMAddInstructionCombiningPass(llvm->pass); 166 } 167 LLVMAddPromoteMemoryToRegisterPass(llvm->pass); 168 LLVMAddGVNPass(llvm->pass); 169 LLVMAddCFGSimplificationPass(llvm->pass); 170 171 init_globals(llvm); 172 173 174#if 1 175 LLVMDumpModule(llvm->module); 176#endif 177 178 return llvm; 179} 180 181void 182draw_llvm_destroy(struct draw_llvm *llvm) 183{ 184 free(llvm); 185} 186 187struct draw_llvm_variant * 188draw_llvm_prepare(struct draw_llvm *llvm, int num_inputs) 189{ 190 struct draw_llvm_variant *variant = MALLOC(sizeof(struct draw_llvm_variant)); 191 192 draw_llvm_make_variant_key(llvm, &variant->key); 193 194 llvm->vertex_header_ptr_type = create_vertex_header(llvm, num_inputs); 195 196 draw_llvm_generate(llvm, variant); 197 198 return variant; 199} 200 201 202struct draw_context *draw_create_with_llvm(LLVMExecutionEngineRef engine) 203{ 204 struct draw_context *draw = CALLOC_STRUCT( draw_context ); 205 if (draw == NULL) 206 goto fail; 207 draw->engine = engine; 208 209 if (!draw_init(draw)) 210 goto fail; 211 212 return draw; 213 214fail: 215 draw_destroy( draw ); 216 return NULL; 217} 218 219static void 220generate_vs(struct draw_llvm *llvm, 221 LLVMBuilderRef builder, 222 LLVMValueRef (*outputs)[NUM_CHANNELS], 223 const LLVMValueRef (*inputs)[NUM_CHANNELS], 224 LLVMValueRef context_ptr) 225{ 226 const struct tgsi_token *tokens = llvm->draw->vs.vertex_shader->state.tokens; 227 struct lp_type vs_type; 228 LLVMValueRef consts_ptr = draw_jit_context_vs_constants(builder, context_ptr); 229 230 memset(&vs_type, 0, sizeof vs_type); 231 vs_type.floating = TRUE; /* floating point values */ 232 vs_type.sign = TRUE; /* values are signed */ 233 vs_type.norm = FALSE; /* values are not limited to [0,1] or [-1,1] */ 234 vs_type.width = 32; /* 32-bit float */ 235 vs_type.length = 4; /* 4 elements per vector */ 236#if 0 237 num_vs = 4; /* number of vertices per block */ 238#endif 239 240 tgsi_dump(tokens, 0); 241 lp_build_tgsi_soa(builder, 242 tokens, 243 vs_type, 244 NULL /*struct lp_build_mask_context *mask*/, 245 consts_ptr, 246 NULL /*pos*/, 247 inputs, 248 outputs, 249 NULL/*sampler*/); 250} 251 252#if DEBUG_STORE 253static void print_vectorf(LLVMBuilderRef builder, 254 LLVMValueRef vec) 255{ 256 LLVMValueRef val[4]; 257 val[0] = LLVMBuildExtractElement(builder, vec, 258 LLVMConstInt(LLVMInt32Type(), 0, 0), ""); 259 val[1] = LLVMBuildExtractElement(builder, vec, 260 LLVMConstInt(LLVMInt32Type(), 1, 0), ""); 261 val[2] = LLVMBuildExtractElement(builder, vec, 262 LLVMConstInt(LLVMInt32Type(), 2, 0), ""); 263 val[3] = LLVMBuildExtractElement(builder, vec, 264 LLVMConstInt(LLVMInt32Type(), 3, 0), ""); 265 lp_build_printf(builder, "vector = [%f, %f, %f, %f]\n", 266 val[0], val[1], val[2], val[3]); 267} 268#endif 269 270static void 271generate_fetch(LLVMBuilderRef builder, 272 LLVMValueRef vbuffers_ptr, 273 LLVMValueRef *res, 274 struct pipe_vertex_element *velem, 275 struct pipe_vertex_buffer *vbuf, 276 LLVMValueRef index) 277{ 278 LLVMValueRef indices = LLVMConstInt(LLVMInt64Type(), velem->vertex_buffer_index, 0); 279 LLVMValueRef vbuffer_ptr = LLVMBuildGEP(builder, vbuffers_ptr, 280 &indices, 1, ""); 281 LLVMValueRef stride = LLVMBuildMul(builder, 282 LLVMConstInt(LLVMInt32Type(), vbuf->stride, 0), 283 index, ""); 284 285 vbuffer_ptr = LLVMBuildLoad(builder, vbuffer_ptr, "vbuffer"); 286 287 stride = LLVMBuildAdd(builder, stride, 288 LLVMConstInt(LLVMInt32Type(), vbuf->buffer_offset, 0), 289 ""); 290 stride = LLVMBuildAdd(builder, stride, 291 LLVMConstInt(LLVMInt32Type(), velem->src_offset, 0), 292 ""); 293 294 /*lp_build_printf(builder, "vbuf index = %d, stride is %d\n", indices, stride);*/ 295 vbuffer_ptr = LLVMBuildGEP(builder, vbuffer_ptr, &stride, 1, ""); 296 297 *res = draw_llvm_translate_from(builder, vbuffer_ptr, velem->src_format); 298} 299 300static LLVMValueRef 301aos_to_soa(LLVMBuilderRef builder, 302 LLVMValueRef val0, 303 LLVMValueRef val1, 304 LLVMValueRef val2, 305 LLVMValueRef val3, 306 LLVMValueRef channel) 307{ 308 LLVMValueRef ex, res; 309 310 ex = LLVMBuildExtractElement(builder, val0, 311 channel, ""); 312 res = LLVMBuildInsertElement(builder, 313 LLVMConstNull(LLVMTypeOf(val0)), 314 ex, 315 LLVMConstInt(LLVMInt32Type(), 0, 0), 316 ""); 317 318 ex = LLVMBuildExtractElement(builder, val1, 319 channel, ""); 320 res = LLVMBuildInsertElement(builder, 321 res, ex, 322 LLVMConstInt(LLVMInt32Type(), 1, 0), 323 ""); 324 325 ex = LLVMBuildExtractElement(builder, val2, 326 channel, ""); 327 res = LLVMBuildInsertElement(builder, 328 res, ex, 329 LLVMConstInt(LLVMInt32Type(), 2, 0), 330 ""); 331 332 ex = LLVMBuildExtractElement(builder, val3, 333 channel, ""); 334 res = LLVMBuildInsertElement(builder, 335 res, ex, 336 LLVMConstInt(LLVMInt32Type(), 3, 0), 337 ""); 338 339 return res; 340} 341 342static void 343soa_to_aos(LLVMBuilderRef builder, 344 LLVMValueRef soa[NUM_CHANNELS], 345 LLVMValueRef aos[NUM_CHANNELS]) 346{ 347 LLVMValueRef comp; 348 int i = 0; 349 350 debug_assert(NUM_CHANNELS == 4); 351 352 aos[0] = LLVMConstNull(LLVMTypeOf(soa[0])); 353 aos[1] = aos[2] = aos[3] = aos[0]; 354 355 for (i = 0; i < NUM_CHANNELS; ++i) { 356 LLVMValueRef channel = LLVMConstInt(LLVMInt32Type(), i, 0); 357 358 comp = LLVMBuildExtractElement(builder, soa[i], 359 LLVMConstInt(LLVMInt32Type(), 0, 0), ""); 360 aos[0] = LLVMBuildInsertElement(builder, aos[0], comp, channel, ""); 361 362 comp = LLVMBuildExtractElement(builder, soa[i], 363 LLVMConstInt(LLVMInt32Type(), 1, 0), ""); 364 aos[1] = LLVMBuildInsertElement(builder, aos[1], comp, channel, ""); 365 366 comp = LLVMBuildExtractElement(builder, soa[i], 367 LLVMConstInt(LLVMInt32Type(), 2, 0), ""); 368 aos[2] = LLVMBuildInsertElement(builder, aos[2], comp, channel, ""); 369 370 comp = LLVMBuildExtractElement(builder, soa[i], 371 LLVMConstInt(LLVMInt32Type(), 3, 0), ""); 372 aos[3] = LLVMBuildInsertElement(builder, aos[3], comp, channel, ""); 373 374 } 375} 376 377static void 378convert_to_soa(LLVMBuilderRef builder, 379 LLVMValueRef (*aos)[NUM_CHANNELS], 380 LLVMValueRef (*soa)[NUM_CHANNELS], 381 int num_attribs) 382{ 383 int i; 384 385 debug_assert(NUM_CHANNELS == 4); 386 387 for (i = 0; i < num_attribs; ++i) { 388 LLVMValueRef val0 = aos[i][0]; 389 LLVMValueRef val1 = aos[i][1]; 390 LLVMValueRef val2 = aos[i][2]; 391 LLVMValueRef val3 = aos[i][3]; 392 393 soa[i][0] = aos_to_soa(builder, val0, val1, val2, val3, 394 LLVMConstInt(LLVMInt32Type(), 0, 0)); 395 soa[i][1] = aos_to_soa(builder, val0, val1, val2, val3, 396 LLVMConstInt(LLVMInt32Type(), 1, 0)); 397 soa[i][2] = aos_to_soa(builder, val0, val1, val2, val3, 398 LLVMConstInt(LLVMInt32Type(), 2, 0)); 399 soa[i][3] = aos_to_soa(builder, val0, val1, val2, val3, 400 LLVMConstInt(LLVMInt32Type(), 3, 0)); 401 } 402} 403 404static void 405store_aos(LLVMBuilderRef builder, 406 LLVMValueRef io_ptr, 407 LLVMValueRef index, 408 LLVMValueRef value) 409{ 410 LLVMValueRef id_ptr = draw_jit_header_id(builder, io_ptr); 411 LLVMValueRef data_ptr = draw_jit_header_data(builder, io_ptr); 412 LLVMValueRef indices[3]; 413 414 indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0); 415 indices[1] = index; 416 indices[2] = LLVMConstInt(LLVMInt32Type(), 0, 0); 417 418 /* undefined vertex */ 419 LLVMBuildStore(builder, LLVMConstInt(LLVMInt32Type(), 420 0xffff, 0), id_ptr); 421 422#if DEBUG_STORE 423 lp_build_printf(builder, " ---- %p storing attribute %d (io = %p)\n", data_ptr, index, io_ptr); 424#endif 425#if 0 426 /*lp_build_printf(builder, " ---- %p storing at %d (%p) ", io_ptr, index, data_ptr); 427 print_vectorf(builder, value);*/ 428 data_ptr = LLVMBuildBitCast(builder, data_ptr, 429 LLVMPointerType(LLVMArrayType(LLVMVectorType(LLVMFloatType(), 4), 0), 0), 430 "datavec"); 431 data_ptr = LLVMBuildGEP(builder, data_ptr, indices, 2, ""); 432 433 LLVMBuildStore(builder, value, data_ptr); 434#else 435 { 436 LLVMValueRef x, y, z, w; 437 LLVMValueRef idx0, idx1, idx2, idx3; 438 LLVMValueRef gep0, gep1, gep2, gep3; 439 data_ptr = LLVMBuildGEP(builder, data_ptr, indices, 3, ""); 440 441 idx0 = LLVMConstInt(LLVMInt32Type(), 0, 0); 442 idx1 = LLVMConstInt(LLVMInt32Type(), 1, 0); 443 idx2 = LLVMConstInt(LLVMInt32Type(), 2, 0); 444 idx3 = LLVMConstInt(LLVMInt32Type(), 3, 0); 445 446 x = LLVMBuildExtractElement(builder, value, 447 idx0, ""); 448 y = LLVMBuildExtractElement(builder, value, 449 idx1, ""); 450 z = LLVMBuildExtractElement(builder, value, 451 idx2, ""); 452 w = LLVMBuildExtractElement(builder, value, 453 idx3, ""); 454 455 gep0 = LLVMBuildGEP(builder, data_ptr, &idx0, 1, ""); 456 gep1 = LLVMBuildGEP(builder, data_ptr, &idx1, 1, ""); 457 gep2 = LLVMBuildGEP(builder, data_ptr, &idx2, 1, ""); 458 gep3 = LLVMBuildGEP(builder, data_ptr, &idx3, 1, ""); 459 460 /*lp_build_printf(builder, "##### x = %f (%p), y = %f (%p), z = %f (%p), w = %f (%p)\n", 461 x, gep0, y, gep1, z, gep2, w, gep3);*/ 462 LLVMBuildStore(builder, x, gep0); 463 LLVMBuildStore(builder, y, gep1); 464 LLVMBuildStore(builder, z, gep2); 465 LLVMBuildStore(builder, w, gep3); 466 } 467#endif 468} 469 470static void 471store_aos_array(LLVMBuilderRef builder, 472 LLVMValueRef io_ptr, 473 LLVMValueRef aos[NUM_CHANNELS], 474 int attrib, 475 int num_outputs) 476{ 477 LLVMValueRef attr_index = LLVMConstInt(LLVMInt32Type(), attrib, 0); 478 LLVMValueRef ind0 = LLVMConstInt(LLVMInt32Type(), 0, 0); 479 LLVMValueRef ind1 = LLVMConstInt(LLVMInt32Type(), 1, 0); 480 LLVMValueRef ind2 = LLVMConstInt(LLVMInt32Type(), 2, 0); 481 LLVMValueRef ind3 = LLVMConstInt(LLVMInt32Type(), 3, 0); 482 LLVMValueRef io0_ptr, io1_ptr, io2_ptr, io3_ptr; 483 484 debug_assert(NUM_CHANNELS == 4); 485 486 io0_ptr = LLVMBuildGEP(builder, io_ptr, 487 &ind0, 1, ""); 488 io1_ptr = LLVMBuildGEP(builder, io_ptr, 489 &ind1, 1, ""); 490 io2_ptr = LLVMBuildGEP(builder, io_ptr, 491 &ind2, 1, ""); 492 io3_ptr = LLVMBuildGEP(builder, io_ptr, 493 &ind3, 1, ""); 494 495#if DEBUG_STORE 496 lp_build_printf(builder, " io = %p, indexes[%d, %d, %d, %d]\n", 497 io_ptr, ind0, ind1, ind2, ind3); 498#endif 499 500 store_aos(builder, io0_ptr, attr_index, aos[0]); 501 store_aos(builder, io1_ptr, attr_index, aos[1]); 502 store_aos(builder, io2_ptr, attr_index, aos[2]); 503 store_aos(builder, io3_ptr, attr_index, aos[3]); 504} 505 506static void 507convert_to_aos(LLVMBuilderRef builder, 508 LLVMValueRef io, 509 LLVMValueRef (*outputs)[NUM_CHANNELS], 510 int num_outputs, 511 int max_vertices) 512{ 513 unsigned chan, attrib; 514 515#if DEBUG_STORE 516 lp_build_printf(builder, " # storing begin\n"); 517#endif 518 for (attrib = 0; attrib < num_outputs; ++attrib) { 519 LLVMValueRef soa[4]; 520 LLVMValueRef aos[4]; 521 for(chan = 0; chan < NUM_CHANNELS; ++chan) { 522 if(outputs[attrib][chan]) { 523 LLVMValueRef out = LLVMBuildLoad(builder, outputs[attrib][chan], ""); 524 lp_build_name(out, "output%u.%c", attrib, "xyzw"[chan]); 525 /*lp_build_printf(builder, "output %d : %d ", 526 LLVMConstInt(LLVMInt32Type(), attrib, 0), 527 LLVMConstInt(LLVMInt32Type(), chan, 0)); 528 print_vectorf(builder, out);*/ 529 soa[chan] = out; 530 } else 531 soa[chan] = 0; 532 } 533 soa_to_aos(builder, soa, aos); 534 store_aos_array(builder, 535 io, 536 aos, 537 attrib, 538 num_outputs); 539 } 540#if DEBUG_STORE 541 lp_build_printf(builder, " # storing end\n"); 542#endif 543} 544 545static void 546draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) 547{ 548 LLVMTypeRef arg_types[6]; 549 LLVMTypeRef func_type; 550 LLVMValueRef context_ptr; 551 LLVMBasicBlockRef block; 552 LLVMBuilderRef builder; 553 LLVMValueRef start, end, count, stride, step, io_itr; 554 LLVMValueRef io_ptr, vbuffers_ptr; 555 struct draw_context *draw = llvm->draw; 556 unsigned i, j; 557 struct lp_build_context bld; 558 struct lp_build_loop_state lp_loop; 559 struct lp_type vs_type = lp_type_float_vec(32); 560 const int max_vertices = 4; 561 LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS]; 562 563 arg_types[0] = llvm->context_ptr_type; /* context */ 564 arg_types[1] = llvm->vertex_header_ptr_type; /* vertex_header */ 565 arg_types[2] = llvm->buffer_ptr_type; /* vbuffers */ 566 arg_types[3] = LLVMInt32Type(); /* start */ 567 arg_types[4] = LLVMInt32Type(); /* count */ 568 arg_types[5] = LLVMInt32Type(); /* stride */ 569 570 func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0); 571 572 variant->function = LLVMAddFunction(llvm->module, "draw_llvm_shader", func_type); 573 LLVMSetFunctionCallConv(variant->function, LLVMCCallConv); 574 for(i = 0; i < Elements(arg_types); ++i) 575 if(LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind) 576 LLVMAddAttribute(LLVMGetParam(variant->function, i), LLVMNoAliasAttribute); 577 578 context_ptr = LLVMGetParam(variant->function, 0); 579 io_ptr = LLVMGetParam(variant->function, 1); 580 vbuffers_ptr = LLVMGetParam(variant->function, 2); 581 start = LLVMGetParam(variant->function, 3); 582 count = LLVMGetParam(variant->function, 4); 583 stride = LLVMGetParam(variant->function, 5); 584 585 lp_build_name(context_ptr, "context"); 586 lp_build_name(io_ptr, "io"); 587 lp_build_name(vbuffers_ptr, "vbuffers"); 588 lp_build_name(start, "start"); 589 lp_build_name(count, "count"); 590 lp_build_name(stride, "stride"); 591 592 /* 593 * Function body 594 */ 595 596 block = LLVMAppendBasicBlock(variant->function, "entry"); 597 builder = LLVMCreateBuilder(); 598 LLVMPositionBuilderAtEnd(builder, block); 599 600 lp_build_context_init(&bld, builder, vs_type); 601 602 end = lp_build_add(&bld, start, count); 603 604 step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0); 605 606#if DEBUG_STORE 607 lp_build_printf(builder, "start = %d, end = %d, step = %d\n", 608 start, end, step); 609#endif 610 lp_build_loop_begin(builder, start, &lp_loop); 611 { 612 LLVMValueRef inputs[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS]; 613 LLVMValueRef aos_attribs[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS]; 614 LLVMValueRef io; 615 const LLVMValueRef (*ptr_aos)[NUM_CHANNELS]; 616 617 io_itr = LLVMBuildSub(builder, lp_loop.counter, start, ""); 618 io = LLVMBuildGEP(builder, io_ptr, &io_itr, 1, ""); 619#if DEBUG_STORE 620 lp_build_printf(builder, " --- io %d = %p, loop counter %d\n", 621 io_itr, io, lp_loop.counter); 622#endif 623 for (i = 0; i < NUM_CHANNELS; ++i) { 624 LLVMValueRef true_index = LLVMBuildAdd( 625 builder, 626 lp_loop.counter, 627 LLVMConstInt(LLVMInt32Type(), i, 0), ""); 628 for (j = 0; j < draw->pt.nr_vertex_elements; ++j) { 629 struct pipe_vertex_element *velem = &draw->pt.vertex_element[j]; 630 struct pipe_vertex_buffer *vbuf = &draw->pt.vertex_buffer[ 631 velem->vertex_buffer_index]; 632 generate_fetch(builder, vbuffers_ptr, 633 &aos_attribs[j][i], velem, vbuf, true_index); 634 } 635 } 636 convert_to_soa(builder, aos_attribs, inputs, 637 draw->pt.nr_vertex_elements); 638 639 ptr_aos = (const LLVMValueRef (*)[NUM_CHANNELS]) inputs; 640 generate_vs(llvm, 641 builder, 642 outputs, 643 ptr_aos, 644 context_ptr); 645 646 convert_to_aos(builder, io, outputs, 647 draw->vs.vertex_shader->info.num_outputs, 648 max_vertices); 649 } 650 lp_build_loop_end_cond(builder, end, step, LLVMIntUGE, &lp_loop); 651 652 LLVMBuildRetVoid(builder); 653 654 LLVMDisposeBuilder(builder); 655 656 /* 657 * Translate the LLVM IR into machine code. 658 */ 659 660#ifdef DEBUG 661 if(LLVMVerifyFunction(variant->function, LLVMPrintMessageAction)) { 662 LLVMDumpValue(variant->function); 663 assert(0); 664 } 665#endif 666 667 LLVMRunFunctionPassManager(llvm->pass, variant->function); 668 669 if (0) { 670 LLVMDumpValue(variant->function); 671 debug_printf("\n"); 672 } 673 variant->jit_func = (draw_jit_vert_func)LLVMGetPointerToGlobal(llvm->draw->engine, variant->function); 674 675 if (0) 676 lp_disassemble(variant->jit_func); 677} 678 679void 680draw_llvm_make_variant_key(struct draw_llvm *llvm, 681 struct draw_llvm_variant_key *key) 682{ 683 key->nr_vertex_buffers = llvm->draw->pt.nr_vertex_buffers; 684 key->nr_vertex_elements = llvm->draw->pt.nr_vertex_elements; 685 686 memcpy(key->vertex_buffer, 687 llvm->draw->pt.vertex_buffer, 688 sizeof(struct pipe_vertex_buffer) * PIPE_MAX_ATTRIBS); 689 690 memcpy(key->vertex_element, 691 llvm->draw->pt.vertex_element, 692 sizeof(struct pipe_vertex_element) * PIPE_MAX_ATTRIBS); 693 694 memcpy(&key->vs, 695 &llvm->draw->vs.vertex_shader->state, 696 sizeof(struct pipe_shader_state)); 697} 698