From a6f6ca37c82bb6810971cab0dccc308e4d28a05a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 27 Aug 2019 14:42:34 +1000 Subject: [PATCH] llvmpipe: add initial shader create/bind/destroy variants framework. This is mostly a port of the fragment shader framework Reviewed-by: Roland Scheidegger --- src/gallium/drivers/llvmpipe/lp_context.c | 1 + src/gallium/drivers/llvmpipe/lp_state.h | 3 + src/gallium/drivers/llvmpipe/lp_state_cs.c | 95 ++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_state_cs.h | 19 +++++ 4 files changed, 118 insertions(+) diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index bfdf41570ff..c49e6691495 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -168,6 +168,7 @@ llvmpipe_create_context(struct pipe_screen *screen, void *priv, llvmpipe_init_blend_funcs(llvmpipe); llvmpipe_init_clip_funcs(llvmpipe); llvmpipe_init_draw_funcs(llvmpipe); + llvmpipe_init_compute_funcs(llvmpipe); llvmpipe_init_sampler_funcs(llvmpipe); llvmpipe_init_query_funcs( llvmpipe ); llvmpipe_init_vertex_funcs(llvmpipe); diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index ea6542735a5..46885a7e701 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -109,6 +109,9 @@ llvmpipe_init_vertex_funcs(struct llvmpipe_context *llvmpipe); void llvmpipe_init_draw_funcs(struct llvmpipe_context *llvmpipe); +void +llvmpipe_init_compute_funcs(struct llvmpipe_context *llvmpipe); + void llvmpipe_init_clip_funcs(struct llvmpipe_context *llvmpipe); diff --git a/src/gallium/drivers/llvmpipe/lp_state_cs.c b/src/gallium/drivers/llvmpipe/lp_state_cs.c index d6faa77598c..cc515c43075 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_cs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_cs.c @@ -23,8 +23,103 @@ * **************************************************************************/ #include "util/u_memory.h" +#include "util/simple_list.h" +#include "tgsi/tgsi_parse.h" +#include "gallivm/lp_bld_debug.h" #include "lp_state_cs.h" +#include "lp_context.h" +#include "lp_debug.h" +#include "lp_state.h" + +static void * +llvmpipe_create_compute_state(struct pipe_context *pipe, + const struct pipe_compute_state *templ) +{ + struct lp_compute_shader *shader; + + shader = CALLOC_STRUCT(lp_compute_shader); + if (!shader) + return NULL; + + assert(templ->ir_type == PIPE_SHADER_IR_TGSI); + shader->base.tokens = tgsi_dup_tokens(templ->prog); + + lp_build_tgsi_info(shader->base.tokens, &shader->info); + make_empty_list(&shader->variants); + + return shader; +} + +static void +llvmpipe_bind_compute_state(struct pipe_context *pipe, + void *cs) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + if (llvmpipe->cs == cs) + return; + + llvmpipe->cs = (struct lp_compute_shader *)cs; +} + +/** + * Remove shader variant from two lists: the shader's variant list + * and the context's variant list. + */ +static void +llvmpipe_remove_cs_shader_variant(struct llvmpipe_context *lp, + struct lp_compute_shader_variant *variant) +{ + if ((LP_DEBUG & DEBUG_CS) || (gallivm_debug & GALLIVM_DEBUG_IR)) { + debug_printf("llvmpipe: del cs #%u var %u v created %u v cached %u " + "v total cached %u inst %u total inst %u\n", + variant->shader->no, variant->no, + variant->shader->variants_created, + variant->shader->variants_cached, + lp->nr_cs_variants, variant->nr_instrs, lp->nr_cs_instrs); + } + + gallivm_destroy(variant->gallivm); + + /* remove from shader's list */ + remove_from_list(&variant->list_item_local); + variant->shader->variants_cached--; + + /* remove from context's list */ + remove_from_list(&variant->list_item_global); + lp->nr_fs_variants--; + lp->nr_fs_instrs -= variant->nr_instrs; + + FREE(variant); +} + +static void +llvmpipe_delete_compute_state(struct pipe_context *pipe, + void *cs) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + struct lp_compute_shader *shader = cs; + struct lp_cs_variant_list_item *li; + + /* Delete all the variants */ + li = first_elem(&shader->variants); + while(!at_end(&shader->variants, li)) { + struct lp_cs_variant_list_item *next = next_elem(li); + llvmpipe_remove_cs_shader_variant(llvmpipe, li->base); + li = next; + } + tgsi_free_tokens(shader->base.tokens); + FREE(shader); +} + +void +llvmpipe_init_compute_funcs(struct llvmpipe_context *llvmpipe) +{ + llvmpipe->pipe.create_compute_state = llvmpipe_create_compute_state; + llvmpipe->pipe.bind_compute_state = llvmpipe_bind_compute_state; + llvmpipe->pipe.delete_compute_state = llvmpipe_delete_compute_state; +} void lp_csctx_destroy(struct lp_cs_context *csctx) diff --git a/src/gallium/drivers/llvmpipe/lp_state_cs.h b/src/gallium/drivers/llvmpipe/lp_state_cs.h index a2c470460bc..adb2a363679 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_cs.h +++ b/src/gallium/drivers/llvmpipe/lp_state_cs.h @@ -31,7 +31,9 @@ #include "pipe/p_state.h" #include "gallivm/lp_bld.h" +#include "gallivm/lp_bld_tgsi.h" /* for lp_tgsi_info */ #include "lp_jit.h" + struct lp_compute_shader_variant; struct lp_compute_shader_variant_key @@ -52,12 +54,29 @@ struct lp_compute_shader_variant LLVMTypeRef jit_cs_context_ptr_type; LLVMTypeRef jit_cs_thread_data_ptr_type; + + /* Total number of LLVM instructions generated */ + unsigned nr_instrs; + + struct lp_cs_variant_list_item list_item_global, list_item_local; + + struct lp_compute_shader *shader; + + /* For debugging/profiling purposes */ + unsigned no; }; struct lp_compute_shader { struct pipe_shader_state base; struct lp_cs_variant_list_item variants; + + struct lp_tgsi_info info; + /* For debugging/profiling purposes */ + unsigned variant_key_size; + unsigned no; + unsigned variants_created; + unsigned variants_cached; }; struct lp_cs_exec { -- 2.30.2