diff options
author | Zack Rusin <zackr@vmware.com> | 2010-06-25 19:31:09 -0400 |
---|---|---|
committer | Zack Rusin <zackr@vmware.com> | 2010-06-25 19:33:27 -0400 |
commit | 8ebfcf31eb905b7d47e520c04420620ae21bdf4e (patch) | |
tree | d1babc0a7da5addcfea47fbb0bd2dcbf3ad0687d /src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c | |
parent | 5cf1921e6d7ba36e6e882094d3280e3cd363df61 (diff) |
draw: limit the number of vertex shader variants kept around
we used to create and cache unltimited number of variant, this
change limits the number of variants kept around to a fixed number.
the change is based on a similar patch by Roland for llvmpipe fragment
shaders.
Diffstat (limited to 'src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c')
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c | 82 |
1 files changed, 39 insertions, 43 deletions
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 c7f76397e7..d33969ac70 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 @@ -52,9 +52,7 @@ struct llvm_middle_end { unsigned opt; struct draw_llvm *llvm; - struct draw_llvm_variant *variants; struct draw_llvm_variant *current_variant; - int nr_variants; }; @@ -66,9 +64,11 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle, { struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle; struct draw_context *draw = fpme->draw; - struct draw_vertex_shader *vs = draw->vs.vertex_shader; + struct llvm_vertex_shader *shader = + llvm_vertex_shader(draw->vs.vertex_shader); struct draw_llvm_variant_key key; struct draw_llvm_variant *variant = NULL; + struct draw_llvm_variant_list_item *li; unsigned i; unsigned instance_id_index = ~0; @@ -80,13 +80,13 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle, /* Add one to num_outputs because the pipeline occasionally tags on * an additional texcoord, eg for AA lines. */ - unsigned nr = MAX2( vs->info.num_inputs, - vs->info.num_outputs + 1 ); + unsigned nr = MAX2( shader->base.info.num_inputs, + shader->base.info.num_outputs + 1 ); /* Scan for instanceID system value. */ - for (i = 0; i < vs->info.num_inputs; i++) { - if (vs->info.input_semantic_name[i] == TGSI_SEMANTIC_INSTANCEID) { + for (i = 0; i < shader->base.info.num_inputs; i++) { + if (shader->base.info.input_semantic_name[i] == TGSI_SEMANTIC_INSTANCEID) { instance_id_index = i; break; } @@ -130,20 +130,41 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle, draw_llvm_make_variant_key(fpme->llvm, &key); - variant = fpme->variants; - while(variant) { - if(memcmp(&variant->key, &key, sizeof key) == 0) + li = first_elem(&shader->variants); + while(!at_end(&shader->variants, li)) { + if(memcmp(&li->base->key, &key, sizeof key) == 0) { + variant = li->base; break; + } + li = next_elem(li); + } - variant = variant->next; + if (variant) { + move_to_head(&fpme->llvm->vs_variants_list, &variant->list_item_global); } + else { + unsigned i; + if (fpme->llvm->nr_variants >= DRAW_MAX_SHADER_VARIANTS) { + /* + * XXX: should we flush here ? + */ + for (i = 0; i < DRAW_MAX_SHADER_VARIANTS / 4; i++) { + struct draw_llvm_variant_list_item *item = + last_elem(&fpme->llvm->vs_variants_list); + draw_llvm_destroy_variant(item->base); + } + } - if (!variant) { - variant = draw_llvm_prepare(fpme->llvm, nr); - variant->next = fpme->variants; - fpme->variants = variant; - ++fpme->nr_variants; + variant = draw_llvm_create_variant(fpme->llvm, nr); + + if (variant) { + insert_at_head(&shader->variants, &variant->list_item_local); + insert_at_head(&fpme->llvm->vs_variants_list, &variant->list_item_global); + fpme->llvm->nr_variants++; + shader->variants_cached++; + } } + fpme->current_variant = variant; /*XXX we only support one constant buffer */ @@ -358,31 +379,7 @@ static void llvm_middle_end_finish( struct draw_pt_middle_end *middle ) static void llvm_middle_end_destroy( struct draw_pt_middle_end *middle ) { struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle; - struct draw_context *draw = fpme->draw; - struct draw_llvm_variant *variant = NULL; - - variant = fpme->variants; - while(variant) { - struct draw_llvm_variant *next = variant->next; - - if (variant->function_elts) { - if (variant->function_elts) - LLVMFreeMachineCodeForFunction(draw->engine, - variant->function_elts); - LLVMDeleteFunction(variant->function_elts); - } - if (variant->function) { - if (variant->function) - LLVMFreeMachineCodeForFunction(draw->engine, - variant->function); - LLVMDeleteFunction(variant->function); - } - - FREE(variant); - - variant = next; - } if (fpme->fetch) draw_pt_fetch_destroy( fpme->fetch ); @@ -402,7 +399,8 @@ static void llvm_middle_end_destroy( struct draw_pt_middle_end *middle ) } -struct draw_pt_middle_end *draw_pt_fetch_pipeline_or_emit_llvm( struct draw_context *draw ) +struct draw_pt_middle_end * +draw_pt_fetch_pipeline_or_emit_llvm(struct draw_context *draw) { struct llvm_middle_end *fpme = 0; @@ -442,9 +440,7 @@ 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; - fpme->nr_variants = 0; return &fpme->base; |