3 #include "draw_context.h"
6 #include "gallivm/lp_bld_arit.h"
7 #include "gallivm/lp_bld_struct.h"
8 #include "gallivm/lp_bld_type.h"
9 #include "gallivm/lp_bld_flow.h"
10 #include "gallivm/lp_bld_debug.h"
11 #include "gallivm/lp_bld_tgsi.h"
12 #include "gallivm/lp_bld_printf.h"
14 #include "tgsi/tgsi_exec.h"
16 #include "util/u_cpu_detect.h"
17 #include "util/u_string.h"
19 #include <llvm-c/Transforms/Scalar.h>
24 /* generates the draw jit function */
26 draw_llvm_generate(struct draw_llvm
*llvm
, struct draw_llvm_variant
*var
);
28 draw_llvm_generate_elts(struct draw_llvm
*llvm
, struct draw_llvm_variant
*var
);
31 init_globals(struct draw_llvm
*llvm
)
33 LLVMTypeRef texture_type
;
35 /* struct draw_jit_texture */
37 LLVMTypeRef elem_types
[4];
39 elem_types
[DRAW_JIT_TEXTURE_WIDTH
] = LLVMInt32Type();
40 elem_types
[DRAW_JIT_TEXTURE_HEIGHT
] = LLVMInt32Type();
41 elem_types
[DRAW_JIT_TEXTURE_STRIDE
] = LLVMInt32Type();
42 elem_types
[DRAW_JIT_TEXTURE_DATA
] = LLVMPointerType(LLVMInt8Type(), 0);
44 texture_type
= LLVMStructType(elem_types
, Elements(elem_types
), 0);
46 LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture
, width
,
47 llvm
->target
, texture_type
,
48 DRAW_JIT_TEXTURE_WIDTH
);
49 LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture
, height
,
50 llvm
->target
, texture_type
,
51 DRAW_JIT_TEXTURE_HEIGHT
);
52 LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture
, stride
,
53 llvm
->target
, texture_type
,
54 DRAW_JIT_TEXTURE_STRIDE
);
55 LP_CHECK_MEMBER_OFFSET(struct draw_jit_texture
, data
,
56 llvm
->target
, texture_type
,
57 DRAW_JIT_TEXTURE_DATA
);
58 LP_CHECK_STRUCT_SIZE(struct draw_jit_texture
,
59 llvm
->target
, texture_type
);
61 LLVMAddTypeName(llvm
->module
, "texture", texture_type
);
65 /* struct draw_jit_context */
67 LLVMTypeRef elem_types
[3];
68 LLVMTypeRef context_type
;
70 elem_types
[0] = LLVMPointerType(LLVMFloatType(), 0); /* vs_constants */
71 elem_types
[1] = LLVMPointerType(LLVMFloatType(), 0); /* vs_constants */
72 elem_types
[2] = LLVMArrayType(texture_type
, PIPE_MAX_SAMPLERS
); /* textures */
74 context_type
= LLVMStructType(elem_types
, Elements(elem_types
), 0);
76 LP_CHECK_MEMBER_OFFSET(struct draw_jit_context
, vs_constants
,
77 llvm
->target
, context_type
, 0);
78 LP_CHECK_MEMBER_OFFSET(struct draw_jit_context
, gs_constants
,
79 llvm
->target
, context_type
, 1);
80 LP_CHECK_MEMBER_OFFSET(struct draw_jit_context
, textures
,
81 llvm
->target
, context_type
,
82 DRAW_JIT_CONTEXT_TEXTURES_INDEX
);
83 LP_CHECK_STRUCT_SIZE(struct draw_jit_context
,
84 llvm
->target
, context_type
);
86 LLVMAddTypeName(llvm
->module
, "draw_jit_context", context_type
);
88 llvm
->context_ptr_type
= LLVMPointerType(context_type
, 0);
91 LLVMTypeRef buffer_ptr
= LLVMPointerType(LLVMIntType(8), 0);
92 llvm
->buffer_ptr_type
= LLVMPointerType(buffer_ptr
, 0);
94 /* struct pipe_vertex_buffer */
96 LLVMTypeRef elem_types
[4];
99 elem_types
[0] = LLVMInt32Type();
100 elem_types
[1] = LLVMInt32Type();
101 elem_types
[2] = LLVMInt32Type();
102 elem_types
[3] = LLVMPointerType(LLVMOpaqueType(), 0); /* vs_constants */
104 vb_type
= LLVMStructType(elem_types
, Elements(elem_types
), 0);
106 LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer
, stride
,
107 llvm
->target
, vb_type
, 0);
108 LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer
, buffer_offset
,
109 llvm
->target
, vb_type
, 2);
110 LP_CHECK_STRUCT_SIZE(struct pipe_vertex_buffer
,
111 llvm
->target
, vb_type
);
113 LLVMAddTypeName(llvm
->module
, "pipe_vertex_buffer", vb_type
);
115 llvm
->vb_ptr_type
= LLVMPointerType(vb_type
, 0);
120 create_vertex_header(struct draw_llvm
*llvm
, int data_elems
)
122 /* struct vertex_header */
123 LLVMTypeRef elem_types
[3];
124 LLVMTypeRef vertex_header
;
125 char struct_name
[24];
127 util_snprintf(struct_name
, 23, "vertex_header%d", data_elems
);
129 elem_types
[0] = LLVMIntType(32);
130 elem_types
[1] = LLVMArrayType(LLVMFloatType(), 4);
131 elem_types
[2] = LLVMArrayType(elem_types
[1], data_elems
);
133 vertex_header
= LLVMStructType(elem_types
, Elements(elem_types
), 0);
135 /* these are bit-fields and we can't take address of them
136 LP_CHECK_MEMBER_OFFSET(struct vertex_header, clipmask,
137 llvm->target, vertex_header,
138 DRAW_JIT_VERTEX_CLIPMASK);
139 LP_CHECK_MEMBER_OFFSET(struct vertex_header, edgeflag,
140 llvm->target, vertex_header,
141 DRAW_JIT_VERTEX_EDGEFLAG);
142 LP_CHECK_MEMBER_OFFSET(struct vertex_header, pad,
143 llvm->target, vertex_header,
144 DRAW_JIT_VERTEX_PAD);
145 LP_CHECK_MEMBER_OFFSET(struct vertex_header, vertex_id,
146 llvm->target, vertex_header,
147 DRAW_JIT_VERTEX_VERTEX_ID);
149 LP_CHECK_MEMBER_OFFSET(struct vertex_header
, clip
,
150 llvm
->target
, vertex_header
,
151 DRAW_JIT_VERTEX_CLIP
);
152 LP_CHECK_MEMBER_OFFSET(struct vertex_header
, data
,
153 llvm
->target
, vertex_header
,
154 DRAW_JIT_VERTEX_DATA
);
156 LLVMAddTypeName(llvm
->module
, struct_name
, vertex_header
);
158 return LLVMPointerType(vertex_header
, 0);
162 draw_llvm_create(struct draw_context
*draw
)
164 struct draw_llvm
*llvm
= CALLOC_STRUCT( draw_llvm
);
169 llvm
->engine
= draw
->engine
;
171 debug_assert(llvm
->engine
);
173 llvm
->module
= LLVMModuleCreateWithName("draw_llvm");
174 llvm
->provider
= LLVMCreateModuleProviderForExistingModule(llvm
->module
);
176 LLVMAddModuleProvider(llvm
->engine
, llvm
->provider
);
178 llvm
->target
= LLVMGetExecutionEngineTargetData(llvm
->engine
);
180 llvm
->pass
= LLVMCreateFunctionPassManager(llvm
->provider
);
181 LLVMAddTargetData(llvm
->target
, llvm
->pass
);
182 /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
183 * but there are more on SVN. */
184 /* TODO: Add more passes */
185 LLVMAddConstantPropagationPass(llvm
->pass
);
186 if(util_cpu_caps
.has_sse4_1
) {
187 /* FIXME: There is a bug in this pass, whereby the combination of fptosi
188 * and sitofp (necessary for trunc/floor/ceil/round implementation)
189 * somehow becomes invalid code.
191 LLVMAddInstructionCombiningPass(llvm
->pass
);
193 LLVMAddPromoteMemoryToRegisterPass(llvm
->pass
);
194 LLVMAddGVNPass(llvm
->pass
);
195 LLVMAddCFGSimplificationPass(llvm
->pass
);
201 LLVMDumpModule(llvm
->module
);
208 draw_llvm_destroy(struct draw_llvm
*llvm
)
213 struct draw_llvm_variant
*
214 draw_llvm_prepare(struct draw_llvm
*llvm
, int num_inputs
)
216 struct draw_llvm_variant
*variant
= MALLOC(sizeof(struct draw_llvm_variant
));
218 draw_llvm_make_variant_key(llvm
, &variant
->key
);
220 llvm
->vertex_header_ptr_type
= create_vertex_header(llvm
, num_inputs
);
222 draw_llvm_generate(llvm
, variant
);
223 draw_llvm_generate_elts(llvm
, variant
);
229 generate_vs(struct draw_llvm
*llvm
,
230 LLVMBuilderRef builder
,
231 LLVMValueRef (*outputs
)[NUM_CHANNELS
],
232 const LLVMValueRef (*inputs
)[NUM_CHANNELS
],
233 LLVMValueRef context_ptr
)
235 const struct tgsi_token
*tokens
= llvm
->draw
->vs
.vertex_shader
->state
.tokens
;
236 struct lp_type vs_type
;
237 LLVMValueRef consts_ptr
= draw_jit_context_vs_constants(builder
, context_ptr
);
239 memset(&vs_type
, 0, sizeof vs_type
);
240 vs_type
.floating
= TRUE
; /* floating point values */
241 vs_type
.sign
= TRUE
; /* values are signed */
242 vs_type
.norm
= FALSE
; /* values are not limited to [0,1] or [-1,1] */
243 vs_type
.width
= 32; /* 32-bit float */
244 vs_type
.length
= 4; /* 4 elements per vector */
246 num_vs
= 4; /* number of vertices per block */
249 /*tgsi_dump(tokens, 0);*/
250 lp_build_tgsi_soa(builder
,
253 NULL
/*struct lp_build_mask_context *mask*/,
259 &llvm
->draw
->vs
.vertex_shader
->info
);
263 static void print_vectorf(LLVMBuilderRef builder
,
267 val
[0] = LLVMBuildExtractElement(builder
, vec
,
268 LLVMConstInt(LLVMInt32Type(), 0, 0), "");
269 val
[1] = LLVMBuildExtractElement(builder
, vec
,
270 LLVMConstInt(LLVMInt32Type(), 1, 0), "");
271 val
[2] = LLVMBuildExtractElement(builder
, vec
,
272 LLVMConstInt(LLVMInt32Type(), 2, 0), "");
273 val
[3] = LLVMBuildExtractElement(builder
, vec
,
274 LLVMConstInt(LLVMInt32Type(), 3, 0), "");
275 lp_build_printf(builder
, "vector = [%f, %f, %f, %f]\n",
276 val
[0], val
[1], val
[2], val
[3]);
281 generate_fetch(LLVMBuilderRef builder
,
282 LLVMValueRef vbuffers_ptr
,
284 struct pipe_vertex_element
*velem
,
288 LLVMValueRef indices
= LLVMConstInt(LLVMInt64Type(), velem
->vertex_buffer_index
, 0);
289 LLVMValueRef vbuffer_ptr
= LLVMBuildGEP(builder
, vbuffers_ptr
,
291 LLVMValueRef vb_stride
= draw_jit_vbuffer_stride(builder
, vbuf
);
292 LLVMValueRef vb_max_index
= draw_jit_vbuffer_max_index(builder
, vbuf
);
293 LLVMValueRef vb_buffer_offset
= draw_jit_vbuffer_offset(builder
, vbuf
);
297 cond
= LLVMBuildICmp(builder
, LLVMIntULE
, index
, vb_max_index
, "");
299 index
= LLVMBuildSelect(builder
, cond
, index
, vb_max_index
, "");
301 stride
= LLVMBuildMul(builder
, vb_stride
, index
, "");
303 vbuffer_ptr
= LLVMBuildLoad(builder
, vbuffer_ptr
, "vbuffer");
305 stride
= LLVMBuildAdd(builder
, stride
,
308 stride
= LLVMBuildAdd(builder
, stride
,
309 LLVMConstInt(LLVMInt32Type(), velem
->src_offset
, 0),
312 /*lp_build_printf(builder, "vbuf index = %d, stride is %d\n", indices, stride);*/
313 vbuffer_ptr
= LLVMBuildGEP(builder
, vbuffer_ptr
, &stride
, 1, "");
315 *res
= draw_llvm_translate_from(builder
, vbuffer_ptr
, velem
->src_format
);
319 aos_to_soa(LLVMBuilderRef builder
,
324 LLVMValueRef channel
)
326 LLVMValueRef ex
, res
;
328 ex
= LLVMBuildExtractElement(builder
, val0
,
330 res
= LLVMBuildInsertElement(builder
,
331 LLVMConstNull(LLVMTypeOf(val0
)),
333 LLVMConstInt(LLVMInt32Type(), 0, 0),
336 ex
= LLVMBuildExtractElement(builder
, val1
,
338 res
= LLVMBuildInsertElement(builder
,
340 LLVMConstInt(LLVMInt32Type(), 1, 0),
343 ex
= LLVMBuildExtractElement(builder
, val2
,
345 res
= LLVMBuildInsertElement(builder
,
347 LLVMConstInt(LLVMInt32Type(), 2, 0),
350 ex
= LLVMBuildExtractElement(builder
, val3
,
352 res
= LLVMBuildInsertElement(builder
,
354 LLVMConstInt(LLVMInt32Type(), 3, 0),
361 soa_to_aos(LLVMBuilderRef builder
,
362 LLVMValueRef soa
[NUM_CHANNELS
],
363 LLVMValueRef aos
[NUM_CHANNELS
])
368 debug_assert(NUM_CHANNELS
== 4);
370 aos
[0] = LLVMConstNull(LLVMTypeOf(soa
[0]));
371 aos
[1] = aos
[2] = aos
[3] = aos
[0];
373 for (i
= 0; i
< NUM_CHANNELS
; ++i
) {
374 LLVMValueRef channel
= LLVMConstInt(LLVMInt32Type(), i
, 0);
376 comp
= LLVMBuildExtractElement(builder
, soa
[i
],
377 LLVMConstInt(LLVMInt32Type(), 0, 0), "");
378 aos
[0] = LLVMBuildInsertElement(builder
, aos
[0], comp
, channel
, "");
380 comp
= LLVMBuildExtractElement(builder
, soa
[i
],
381 LLVMConstInt(LLVMInt32Type(), 1, 0), "");
382 aos
[1] = LLVMBuildInsertElement(builder
, aos
[1], comp
, channel
, "");
384 comp
= LLVMBuildExtractElement(builder
, soa
[i
],
385 LLVMConstInt(LLVMInt32Type(), 2, 0), "");
386 aos
[2] = LLVMBuildInsertElement(builder
, aos
[2], comp
, channel
, "");
388 comp
= LLVMBuildExtractElement(builder
, soa
[i
],
389 LLVMConstInt(LLVMInt32Type(), 3, 0), "");
390 aos
[3] = LLVMBuildInsertElement(builder
, aos
[3], comp
, channel
, "");
396 convert_to_soa(LLVMBuilderRef builder
,
397 LLVMValueRef (*aos
)[NUM_CHANNELS
],
398 LLVMValueRef (*soa
)[NUM_CHANNELS
],
403 debug_assert(NUM_CHANNELS
== 4);
405 for (i
= 0; i
< num_attribs
; ++i
) {
406 LLVMValueRef val0
= aos
[i
][0];
407 LLVMValueRef val1
= aos
[i
][1];
408 LLVMValueRef val2
= aos
[i
][2];
409 LLVMValueRef val3
= aos
[i
][3];
411 soa
[i
][0] = aos_to_soa(builder
, val0
, val1
, val2
, val3
,
412 LLVMConstInt(LLVMInt32Type(), 0, 0));
413 soa
[i
][1] = aos_to_soa(builder
, val0
, val1
, val2
, val3
,
414 LLVMConstInt(LLVMInt32Type(), 1, 0));
415 soa
[i
][2] = aos_to_soa(builder
, val0
, val1
, val2
, val3
,
416 LLVMConstInt(LLVMInt32Type(), 2, 0));
417 soa
[i
][3] = aos_to_soa(builder
, val0
, val1
, val2
, val3
,
418 LLVMConstInt(LLVMInt32Type(), 3, 0));
423 store_aos(LLVMBuilderRef builder
,
428 LLVMValueRef id_ptr
= draw_jit_header_id(builder
, io_ptr
);
429 LLVMValueRef data_ptr
= draw_jit_header_data(builder
, io_ptr
);
430 LLVMValueRef indices
[3];
432 indices
[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
434 indices
[2] = LLVMConstInt(LLVMInt32Type(), 0, 0);
436 /* undefined vertex */
437 LLVMBuildStore(builder
, LLVMConstInt(LLVMInt32Type(),
441 lp_build_printf(builder
, " ---- %p storing attribute %d (io = %p)\n", data_ptr
, index
, io_ptr
);
444 /*lp_build_printf(builder, " ---- %p storing at %d (%p) ", io_ptr, index, data_ptr);
445 print_vectorf(builder, value);*/
446 data_ptr
= LLVMBuildBitCast(builder
, data_ptr
,
447 LLVMPointerType(LLVMArrayType(LLVMVectorType(LLVMFloatType(), 4), 0), 0),
449 data_ptr
= LLVMBuildGEP(builder
, data_ptr
, indices
, 2, "");
451 LLVMBuildStore(builder
, value
, data_ptr
);
454 LLVMValueRef x
, y
, z
, w
;
455 LLVMValueRef idx0
, idx1
, idx2
, idx3
;
456 LLVMValueRef gep0
, gep1
, gep2
, gep3
;
457 data_ptr
= LLVMBuildGEP(builder
, data_ptr
, indices
, 3, "");
459 idx0
= LLVMConstInt(LLVMInt32Type(), 0, 0);
460 idx1
= LLVMConstInt(LLVMInt32Type(), 1, 0);
461 idx2
= LLVMConstInt(LLVMInt32Type(), 2, 0);
462 idx3
= LLVMConstInt(LLVMInt32Type(), 3, 0);
464 x
= LLVMBuildExtractElement(builder
, value
,
466 y
= LLVMBuildExtractElement(builder
, value
,
468 z
= LLVMBuildExtractElement(builder
, value
,
470 w
= LLVMBuildExtractElement(builder
, value
,
473 gep0
= LLVMBuildGEP(builder
, data_ptr
, &idx0
, 1, "");
474 gep1
= LLVMBuildGEP(builder
, data_ptr
, &idx1
, 1, "");
475 gep2
= LLVMBuildGEP(builder
, data_ptr
, &idx2
, 1, "");
476 gep3
= LLVMBuildGEP(builder
, data_ptr
, &idx3
, 1, "");
478 /*lp_build_printf(builder, "##### x = %f (%p), y = %f (%p), z = %f (%p), w = %f (%p)\n",
479 x, gep0, y, gep1, z, gep2, w, gep3);*/
480 LLVMBuildStore(builder
, x
, gep0
);
481 LLVMBuildStore(builder
, y
, gep1
);
482 LLVMBuildStore(builder
, z
, gep2
);
483 LLVMBuildStore(builder
, w
, gep3
);
489 store_aos_array(LLVMBuilderRef builder
,
491 LLVMValueRef aos
[NUM_CHANNELS
],
495 LLVMValueRef attr_index
= LLVMConstInt(LLVMInt32Type(), attrib
, 0);
496 LLVMValueRef ind0
= LLVMConstInt(LLVMInt32Type(), 0, 0);
497 LLVMValueRef ind1
= LLVMConstInt(LLVMInt32Type(), 1, 0);
498 LLVMValueRef ind2
= LLVMConstInt(LLVMInt32Type(), 2, 0);
499 LLVMValueRef ind3
= LLVMConstInt(LLVMInt32Type(), 3, 0);
500 LLVMValueRef io0_ptr
, io1_ptr
, io2_ptr
, io3_ptr
;
502 debug_assert(NUM_CHANNELS
== 4);
504 io0_ptr
= LLVMBuildGEP(builder
, io_ptr
,
506 io1_ptr
= LLVMBuildGEP(builder
, io_ptr
,
508 io2_ptr
= LLVMBuildGEP(builder
, io_ptr
,
510 io3_ptr
= LLVMBuildGEP(builder
, io_ptr
,
514 lp_build_printf(builder
, " io = %p, indexes[%d, %d, %d, %d]\n",
515 io_ptr
, ind0
, ind1
, ind2
, ind3
);
518 store_aos(builder
, io0_ptr
, attr_index
, aos
[0]);
519 store_aos(builder
, io1_ptr
, attr_index
, aos
[1]);
520 store_aos(builder
, io2_ptr
, attr_index
, aos
[2]);
521 store_aos(builder
, io3_ptr
, attr_index
, aos
[3]);
525 convert_to_aos(LLVMBuilderRef builder
,
527 LLVMValueRef (*outputs
)[NUM_CHANNELS
],
531 unsigned chan
, attrib
;
534 lp_build_printf(builder
, " # storing begin\n");
536 for (attrib
= 0; attrib
< num_outputs
; ++attrib
) {
539 for(chan
= 0; chan
< NUM_CHANNELS
; ++chan
) {
540 if(outputs
[attrib
][chan
]) {
541 LLVMValueRef out
= LLVMBuildLoad(builder
, outputs
[attrib
][chan
], "");
542 lp_build_name(out
, "output%u.%c", attrib
, "xyzw"[chan
]);
543 /*lp_build_printf(builder, "output %d : %d ",
544 LLVMConstInt(LLVMInt32Type(), attrib, 0),
545 LLVMConstInt(LLVMInt32Type(), chan, 0));
546 print_vectorf(builder, out);*/
551 soa_to_aos(builder
, soa
, aos
);
552 store_aos_array(builder
,
559 lp_build_printf(builder
, " # storing end\n");
564 draw_llvm_generate(struct draw_llvm
*llvm
, struct draw_llvm_variant
*variant
)
566 LLVMTypeRef arg_types
[7];
567 LLVMTypeRef func_type
;
568 LLVMValueRef context_ptr
;
569 LLVMBasicBlockRef block
;
570 LLVMBuilderRef builder
;
571 LLVMValueRef start
, end
, count
, stride
, step
, io_itr
;
572 LLVMValueRef io_ptr
, vbuffers_ptr
, vb_ptr
;
573 struct draw_context
*draw
= llvm
->draw
;
575 struct lp_build_context bld
;
576 struct lp_build_loop_state lp_loop
;
577 struct lp_type vs_type
= lp_type_float_vec(32);
578 const int max_vertices
= 4;
579 LLVMValueRef outputs
[PIPE_MAX_SHADER_OUTPUTS
][NUM_CHANNELS
];
581 arg_types
[0] = llvm
->context_ptr_type
; /* context */
582 arg_types
[1] = llvm
->vertex_header_ptr_type
; /* vertex_header */
583 arg_types
[2] = llvm
->buffer_ptr_type
; /* vbuffers */
584 arg_types
[3] = LLVMInt32Type(); /* start */
585 arg_types
[4] = LLVMInt32Type(); /* count */
586 arg_types
[5] = LLVMInt32Type(); /* stride */
587 arg_types
[6] = llvm
->vb_ptr_type
; /* pipe_vertex_buffer's */
589 func_type
= LLVMFunctionType(LLVMVoidType(), arg_types
, Elements(arg_types
), 0);
591 variant
->function
= LLVMAddFunction(llvm
->module
, "draw_llvm_shader", func_type
);
592 LLVMSetFunctionCallConv(variant
->function
, LLVMCCallConv
);
593 for(i
= 0; i
< Elements(arg_types
); ++i
)
594 if(LLVMGetTypeKind(arg_types
[i
]) == LLVMPointerTypeKind
)
595 LLVMAddAttribute(LLVMGetParam(variant
->function
, i
), LLVMNoAliasAttribute
);
597 context_ptr
= LLVMGetParam(variant
->function
, 0);
598 io_ptr
= LLVMGetParam(variant
->function
, 1);
599 vbuffers_ptr
= LLVMGetParam(variant
->function
, 2);
600 start
= LLVMGetParam(variant
->function
, 3);
601 count
= LLVMGetParam(variant
->function
, 4);
602 stride
= LLVMGetParam(variant
->function
, 5);
603 vb_ptr
= LLVMGetParam(variant
->function
, 6);
605 lp_build_name(context_ptr
, "context");
606 lp_build_name(io_ptr
, "io");
607 lp_build_name(vbuffers_ptr
, "vbuffers");
608 lp_build_name(start
, "start");
609 lp_build_name(count
, "count");
610 lp_build_name(stride
, "stride");
611 lp_build_name(vb_ptr
, "vb");
617 block
= LLVMAppendBasicBlock(variant
->function
, "entry");
618 builder
= LLVMCreateBuilder();
619 LLVMPositionBuilderAtEnd(builder
, block
);
621 lp_build_context_init(&bld
, builder
, vs_type
);
623 end
= lp_build_add(&bld
, start
, count
);
625 step
= LLVMConstInt(LLVMInt32Type(), max_vertices
, 0);
628 lp_build_printf(builder
, "start = %d, end = %d, step = %d\n",
631 lp_build_loop_begin(builder
, start
, &lp_loop
);
633 LLVMValueRef inputs
[PIPE_MAX_SHADER_INPUTS
][NUM_CHANNELS
];
634 LLVMValueRef aos_attribs
[PIPE_MAX_SHADER_INPUTS
][NUM_CHANNELS
] = { { 0 } };
636 const LLVMValueRef (*ptr_aos
)[NUM_CHANNELS
];
638 io_itr
= LLVMBuildSub(builder
, lp_loop
.counter
, start
, "");
639 io
= LLVMBuildGEP(builder
, io_ptr
, &io_itr
, 1, "");
641 lp_build_printf(builder
, " --- io %d = %p, loop counter %d\n",
642 io_itr
, io
, lp_loop
.counter
);
644 for (i
= 0; i
< NUM_CHANNELS
; ++i
) {
645 LLVMValueRef true_index
= LLVMBuildAdd(
648 LLVMConstInt(LLVMInt32Type(), i
, 0), "");
649 for (j
= 0; j
< draw
->pt
.nr_vertex_elements
; ++j
) {
650 struct pipe_vertex_element
*velem
= &draw
->pt
.vertex_element
[j
];
651 LLVMValueRef vb_index
= LLVMConstInt(LLVMInt32Type(),
652 velem
->vertex_buffer_index
,
654 LLVMValueRef vb
= LLVMBuildGEP(builder
, vb_ptr
,
656 generate_fetch(builder
, vbuffers_ptr
,
657 &aos_attribs
[j
][i
], velem
, vb
, true_index
);
660 convert_to_soa(builder
, aos_attribs
, inputs
,
661 draw
->pt
.nr_vertex_elements
);
663 ptr_aos
= (const LLVMValueRef (*)[NUM_CHANNELS
]) inputs
;
670 convert_to_aos(builder
, io
, outputs
,
671 draw
->vs
.vertex_shader
->info
.num_outputs
,
674 lp_build_loop_end_cond(builder
, end
, step
, LLVMIntUGE
, &lp_loop
);
676 LLVMBuildRetVoid(builder
);
678 LLVMDisposeBuilder(builder
);
681 * Translate the LLVM IR into machine code.
684 if(LLVMVerifyFunction(variant
->function
, LLVMPrintMessageAction
)) {
685 LLVMDumpValue(variant
->function
);
690 LLVMRunFunctionPassManager(llvm
->pass
, variant
->function
);
693 LLVMDumpValue(variant
->function
);
696 variant
->jit_func
= (draw_jit_vert_func
)LLVMGetPointerToGlobal(llvm
->draw
->engine
, variant
->function
);
699 lp_disassemble(variant
->jit_func
);
704 draw_llvm_generate_elts(struct draw_llvm
*llvm
, struct draw_llvm_variant
*variant
)
706 LLVMTypeRef arg_types
[7];
707 LLVMTypeRef func_type
;
708 LLVMValueRef context_ptr
;
709 LLVMBasicBlockRef block
;
710 LLVMBuilderRef builder
;
711 LLVMValueRef fetch_elts
, fetch_count
, stride
, step
, io_itr
;
712 LLVMValueRef io_ptr
, vbuffers_ptr
, vb_ptr
;
713 struct draw_context
*draw
= llvm
->draw
;
715 struct lp_build_context bld
;
716 struct lp_build_loop_state lp_loop
;
717 struct lp_type vs_type
= lp_type_float_vec(32);
718 const int max_vertices
= 4;
719 LLVMValueRef outputs
[PIPE_MAX_SHADER_OUTPUTS
][NUM_CHANNELS
];
721 arg_types
[0] = llvm
->context_ptr_type
; /* context */
722 arg_types
[1] = llvm
->vertex_header_ptr_type
; /* vertex_header */
723 arg_types
[2] = llvm
->buffer_ptr_type
; /* vbuffers */
724 arg_types
[3] = LLVMPointerType(LLVMInt32Type(), 0); /* fetch_elts * */
725 arg_types
[4] = LLVMInt32Type(); /* fetch_count */
726 arg_types
[5] = LLVMInt32Type(); /* stride */
727 arg_types
[6] = llvm
->vb_ptr_type
; /* pipe_vertex_buffer's */
729 func_type
= LLVMFunctionType(LLVMVoidType(), arg_types
, Elements(arg_types
), 0);
731 variant
->function_elts
= LLVMAddFunction(llvm
->module
, "draw_llvm_shader_elts", func_type
);
732 LLVMSetFunctionCallConv(variant
->function_elts
, LLVMCCallConv
);
733 for(i
= 0; i
< Elements(arg_types
); ++i
)
734 if(LLVMGetTypeKind(arg_types
[i
]) == LLVMPointerTypeKind
)
735 LLVMAddAttribute(LLVMGetParam(variant
->function_elts
, i
), LLVMNoAliasAttribute
);
737 context_ptr
= LLVMGetParam(variant
->function_elts
, 0);
738 io_ptr
= LLVMGetParam(variant
->function_elts
, 1);
739 vbuffers_ptr
= LLVMGetParam(variant
->function_elts
, 2);
740 fetch_elts
= LLVMGetParam(variant
->function_elts
, 3);
741 fetch_count
= LLVMGetParam(variant
->function_elts
, 4);
742 stride
= LLVMGetParam(variant
->function_elts
, 5);
743 vb_ptr
= LLVMGetParam(variant
->function_elts
, 6);
745 lp_build_name(context_ptr
, "context");
746 lp_build_name(io_ptr
, "io");
747 lp_build_name(vbuffers_ptr
, "vbuffers");
748 lp_build_name(fetch_elts
, "fetch_elts");
749 lp_build_name(fetch_count
, "fetch_count");
750 lp_build_name(stride
, "stride");
751 lp_build_name(vb_ptr
, "vb");
757 block
= LLVMAppendBasicBlock(variant
->function_elts
, "entry");
758 builder
= LLVMCreateBuilder();
759 LLVMPositionBuilderAtEnd(builder
, block
);
761 lp_build_context_init(&bld
, builder
, vs_type
);
763 step
= LLVMConstInt(LLVMInt32Type(), max_vertices
, 0);
765 lp_build_loop_begin(builder
, LLVMConstInt(LLVMInt32Type(), 0, 0), &lp_loop
);
767 LLVMValueRef inputs
[PIPE_MAX_SHADER_INPUTS
][NUM_CHANNELS
];
768 LLVMValueRef aos_attribs
[PIPE_MAX_SHADER_INPUTS
][NUM_CHANNELS
] = { { 0 } };
770 const LLVMValueRef (*ptr_aos
)[NUM_CHANNELS
];
772 io_itr
= lp_loop
.counter
;
773 io
= LLVMBuildGEP(builder
, io_ptr
, &io_itr
, 1, "");
775 lp_build_printf(builder
, " --- io %d = %p, loop counter %d\n",
776 io_itr
, io
, lp_loop
.counter
);
778 for (i
= 0; i
< NUM_CHANNELS
; ++i
) {
779 LLVMValueRef true_index
= LLVMBuildAdd(
782 LLVMConstInt(LLVMInt32Type(), i
, 0), "");
783 LLVMValueRef fetch_ptr
= LLVMBuildGEP(builder
, fetch_elts
,
785 true_index
= LLVMBuildLoad(builder
, fetch_ptr
, "fetch_elt");
786 for (j
= 0; j
< draw
->pt
.nr_vertex_elements
; ++j
) {
787 struct pipe_vertex_element
*velem
= &draw
->pt
.vertex_element
[j
];
788 LLVMValueRef vb_index
= LLVMConstInt(LLVMInt32Type(),
789 velem
->vertex_buffer_index
,
791 LLVMValueRef vb
= LLVMBuildGEP(builder
, vb_ptr
,
793 generate_fetch(builder
, vbuffers_ptr
,
794 &aos_attribs
[j
][i
], velem
, vb
, true_index
);
797 convert_to_soa(builder
, aos_attribs
, inputs
,
798 draw
->pt
.nr_vertex_elements
);
800 ptr_aos
= (const LLVMValueRef (*)[NUM_CHANNELS
]) inputs
;
807 convert_to_aos(builder
, io
, outputs
,
808 draw
->vs
.vertex_shader
->info
.num_outputs
,
811 lp_build_loop_end_cond(builder
, fetch_count
, step
, LLVMIntUGE
, &lp_loop
);
813 LLVMBuildRetVoid(builder
);
815 LLVMDisposeBuilder(builder
);
818 * Translate the LLVM IR into machine code.
821 if(LLVMVerifyFunction(variant
->function_elts
, LLVMPrintMessageAction
)) {
822 LLVMDumpValue(variant
->function_elts
);
827 LLVMRunFunctionPassManager(llvm
->pass
, variant
->function_elts
);
830 LLVMDumpValue(variant
->function_elts
);
833 variant
->jit_func_elts
= (draw_jit_vert_func_elts
)LLVMGetPointerToGlobal(
834 llvm
->draw
->engine
, variant
->function_elts
);
837 lp_disassemble(variant
->jit_func_elts
);
841 draw_llvm_make_variant_key(struct draw_llvm
*llvm
,
842 struct draw_llvm_variant_key
*key
)
844 memset(key
, 0, sizeof(struct draw_llvm_variant_key
));
846 key
->nr_vertex_elements
= llvm
->draw
->pt
.nr_vertex_elements
;
848 memcpy(key
->vertex_element
,
849 llvm
->draw
->pt
.vertex_element
,
850 sizeof(struct pipe_vertex_element
) * key
->nr_vertex_elements
);
853 &llvm
->draw
->vs
.vertex_shader
->state
,
854 sizeof(struct pipe_shader_state
));