llvmpipe: add initial shader create/bind/destroy variants framework.
authorDave Airlie <airlied@redhat.com>
Tue, 27 Aug 2019 04:42:34 +0000 (14:42 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 4 Sep 2019 05:22:20 +0000 (15:22 +1000)
This is mostly a port of the fragment shader framework

Reviewed-by: Roland Scheidegger <sroland@vmware.com>
src/gallium/drivers/llvmpipe/lp_context.c
src/gallium/drivers/llvmpipe/lp_state.h
src/gallium/drivers/llvmpipe/lp_state_cs.c
src/gallium/drivers/llvmpipe/lp_state_cs.h

index bfdf41570ffb5a3689ba292936c213beb8f2e7e7..c49e6691495f3f6685f3be91e3da733f50297bac 100644 (file)
@@ -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);
index ea6542735a50710de989c220919c3ddde9e0e68d..46885a7e701fe3bf333610bd33ad90fd58b6f4aa 100644 (file)
@@ -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);
 
index d6faa77598c1004ecb9a0fa24f10e56a4d5d736f..cc515c43075ffa7f3fffe0f236efe346f35fcfc3 100644 (file)
  *
  **************************************************************************/
 #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)
index a2c470460bc15b8ecf66e318f8ff73f8910db57c..adb2a36367973e3cb2f367d4649b983fcdb55c6d 100644 (file)
@@ -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 {