summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Rusin <zackr@vmware.com>2010-04-06 16:28:48 -0400
committerZack Rusin <zackr@vmware.com>2010-04-06 16:28:48 -0400
commit323fdd8ae5baf16df6c57754e58adc8e22d28e10 (patch)
treebd3630fbf00ec0d086712e4e76091894b66a6d83
parent1e0bf24139f6047f505b138392fc0f1d6584d6bc (diff)
draw llvm: implement simple pipeline caching using variants
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.c75
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.h27
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c36
3 files changed, 103 insertions, 35 deletions
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index a09e2a9f0c..26f756c6f8 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -17,7 +17,12 @@
#include <llvm-c/Transforms/Scalar.h>
-#define DEBUG_STORE 1
+#define DEBUG_STORE 0
+
+
+/* generates the draw jit function */
+static void
+draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *var);
static void
init_globals(struct draw_llvm *llvm)
@@ -179,11 +184,18 @@ draw_llvm_destroy(struct draw_llvm *llvm)
free(llvm);
}
-void
+struct draw_llvm_variant *
draw_llvm_prepare(struct draw_llvm *llvm, int num_inputs)
{
+ struct draw_llvm_variant *variant = MALLOC(sizeof(struct draw_llvm_variant));
+
+ draw_llvm_make_variant_key(llvm, &variant->key);
+
llvm->vertex_header_ptr_type = create_vertex_header(llvm, num_inputs);
- draw_llvm_generate(llvm);
+
+ draw_llvm_generate(llvm, variant);
+
+ return variant;
}
@@ -530,15 +542,14 @@ convert_to_aos(LLVMBuilderRef builder,
#endif
}
-void
-draw_llvm_generate(struct draw_llvm *llvm)
+static void
+draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
{
LLVMTypeRef arg_types[6];
LLVMTypeRef func_type;
LLVMValueRef context_ptr;
LLVMBasicBlockRef block;
LLVMBuilderRef builder;
- LLVMValueRef function;
LLVMValueRef start, end, count, stride, step, io_itr;
LLVMValueRef io_ptr, vbuffers_ptr;
struct draw_context *draw = llvm->draw;
@@ -558,18 +569,18 @@ draw_llvm_generate(struct draw_llvm *llvm)
func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0);
- function = LLVMAddFunction(llvm->module, "draw_llvm_shader", func_type);
- LLVMSetFunctionCallConv(function, LLVMCCallConv);
+ variant->function = LLVMAddFunction(llvm->module, "draw_llvm_shader", func_type);
+ LLVMSetFunctionCallConv(variant->function, LLVMCCallConv);
for(i = 0; i < Elements(arg_types); ++i)
if(LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind)
- LLVMAddAttribute(LLVMGetParam(function, i), LLVMNoAliasAttribute);
+ LLVMAddAttribute(LLVMGetParam(variant->function, i), LLVMNoAliasAttribute);
- context_ptr = LLVMGetParam(function, 0);
- io_ptr = LLVMGetParam(function, 1);
- vbuffers_ptr = LLVMGetParam(function, 2);
- start = LLVMGetParam(function, 3);
- count = LLVMGetParam(function, 4);
- stride = LLVMGetParam(function, 5);
+ context_ptr = LLVMGetParam(variant->function, 0);
+ io_ptr = LLVMGetParam(variant->function, 1);
+ vbuffers_ptr = LLVMGetParam(variant->function, 2);
+ start = LLVMGetParam(variant->function, 3);
+ count = LLVMGetParam(variant->function, 4);
+ stride = LLVMGetParam(variant->function, 5);
lp_build_name(context_ptr, "context");
lp_build_name(io_ptr, "io");
@@ -582,7 +593,7 @@ draw_llvm_generate(struct draw_llvm *llvm)
* Function body
*/
- block = LLVMAppendBasicBlock(function, "entry");
+ block = LLVMAppendBasicBlock(variant->function, "entry");
builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(builder, block);
@@ -647,20 +658,40 @@ draw_llvm_generate(struct draw_llvm *llvm)
*/
#ifdef DEBUG
- if(LLVMVerifyFunction(function, LLVMPrintMessageAction)) {
- LLVMDumpValue(function);
+ if(LLVMVerifyFunction(variant->function, LLVMPrintMessageAction)) {
+ LLVMDumpValue(variant->function);
assert(0);
}
#endif
- LLVMRunFunctionPassManager(llvm->pass, function);
+ LLVMRunFunctionPassManager(llvm->pass, variant->function);
if (1) {
- LLVMDumpValue(function);
+ LLVMDumpValue(variant->function);
debug_printf("\n");
}
- llvm->jit_func = (draw_jit_vert_func)LLVMGetPointerToGlobal(llvm->draw->engine, function);
+ variant->jit_func = (draw_jit_vert_func)LLVMGetPointerToGlobal(llvm->draw->engine, variant->function);
if (1)
- lp_disassemble(llvm->jit_func);
+ lp_disassemble(variant->jit_func);
+}
+
+void
+draw_llvm_make_variant_key(struct draw_llvm *llvm,
+ struct draw_llvm_variant_key *key)
+{
+ key->nr_vertex_buffers = llvm->draw->pt.nr_vertex_buffers;
+ key->nr_vertex_elements = llvm->draw->pt.nr_vertex_elements;
+
+ memcpy(key->vertex_buffer,
+ llvm->draw->pt.vertex_buffer,
+ sizeof(struct pipe_vertex_buffer) * PIPE_MAX_ATTRIBS);
+
+ memcpy(key->vertex_element,
+ llvm->draw->pt.vertex_element,
+ sizeof(struct pipe_vertex_element) * PIPE_MAX_ATTRIBS);
+
+ memcpy(&key->vs,
+ &llvm->draw->vs.vertex_shader->state,
+ sizeof(struct pipe_shader_state));
}
diff --git a/src/gallium/auxiliary/draw/draw_llvm.h b/src/gallium/auxiliary/draw/draw_llvm.h
index afafa15e68..774eb16d90 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.h
+++ b/src/gallium/auxiliary/draw/draw_llvm.h
@@ -136,8 +136,6 @@ struct draw_llvm {
struct draw_jit_context jit_context;
- draw_jit_vert_func jit_func;
-
LLVMModuleRef module;
LLVMExecutionEngineRef engine;
LLVMModuleProviderRef provider;
@@ -150,22 +148,39 @@ struct draw_llvm {
};
+struct draw_llvm_variant_key
+{
+ struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+ unsigned nr_vertex_buffers;
+ struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
+ unsigned nr_vertex_elements;
+ struct pipe_shader_state vs;
+};
+
+struct draw_llvm_variant
+{
+ struct draw_llvm_variant_key key;
+ LLVMValueRef function;
+ draw_jit_vert_func jit_func;
+
+ struct draw_llvm_variant *next;
+};
+
struct draw_llvm *
draw_llvm_create(struct draw_context *draw);
void
draw_llvm_destroy(struct draw_llvm *llvm);
-void
+struct draw_llvm_variant *
draw_llvm_prepare(struct draw_llvm *llvm, int num_inputs);
-/* generates the draw jit function */
void
-draw_llvm_generate(struct draw_llvm *llvm);
+draw_llvm_make_variant_key(struct draw_llvm *llvm,
+ struct draw_llvm_variant_key *key);
LLVMValueRef
draw_llvm_translate_from(LLVMBuilderRef builder,
LLVMValueRef vbuffer,
enum pipe_format from_format);
-
#endif
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
index 307e6cc3a4..0ed043d950 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
@@ -53,6 +53,8 @@ struct llvm_middle_end {
unsigned opt;
struct draw_llvm *llvm;
+ struct draw_llvm_variant *variants;
+ struct draw_llvm_variant *current_variant;
};
@@ -66,6 +68,8 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
struct draw_context *draw = fpme->draw;
struct draw_vertex_shader *vs = draw->vs.vertex_shader;
struct draw_geometry_shader *gs = draw->gs.geometry_shader;
+ struct draw_llvm_variant_key key;
+ struct draw_llvm_variant *variant = NULL;
unsigned i;
unsigned instance_id_index = ~0;
@@ -129,7 +133,22 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
/* return even number */
*max_vertices = *max_vertices & ~1;
- draw_llvm_prepare(fpme->llvm, nr);
+ draw_llvm_make_variant_key(fpme->llvm, &key);
+
+ variant = fpme->variants;
+ while(variant) {
+ if(memcmp(&variant->key, &key, sizeof key) == 0)
+ break;
+
+ variant = variant->next;
+ }
+
+ if (!variant) {
+ variant = draw_llvm_prepare(fpme->llvm, nr);
+ variant->next = fpme->variants;
+ fpme->variants = variant;
+ }
+ fpme->current_variant = variant;
/*XXX we only support one constant buffer */
fpme->llvm->jit_context.vs_constants =
@@ -247,12 +266,12 @@ static void llvm_middle_end_linear_run( struct draw_pt_middle_end *middle,
debug_printf("#### Pipeline = %p (data = %p)\n",
pipeline_verts, pipeline_verts->data);
- fpme->llvm->jit_func( &fpme->llvm->jit_context,
- pipeline_verts,
- (const char **)draw->pt.user.vbuffer,
- start,
- count,
- fpme->vertex_size );
+ fpme->current_variant->jit_func( &fpme->llvm->jit_context,
+ pipeline_verts,
+ (const char **)draw->pt.user.vbuffer,
+ start,
+ count,
+ fpme->vertex_size );
if (draw_pt_post_vs_run( fpme->post_vs,
pipeline_verts,
@@ -430,6 +449,9 @@ struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit_llvm( struct draw_cont
if (!fpme->llvm)
goto fail;
+ fpme->variants = NULL;
+ fpme->current_variant = NULL;
+
return &fpme->base;
fail: