*
**************************************************************************/
#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)
#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
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 {