summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/llvmpipe
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_limits.h6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c34
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.h3
4 files changed, 33 insertions, 11 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index 70fba213095..438fc887083 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -129,6 +129,7 @@ struct llvmpipe_context {
/** List of all fragment shader variants */
struct lp_fs_variant_list_item fs_variants_list;
unsigned nr_fs_variants;
+ unsigned nr_fs_instrs;
/** JIT code generation */
struct gallivm_state *gallivm;
diff --git a/src/gallium/drivers/llvmpipe/lp_limits.h b/src/gallium/drivers/llvmpipe/lp_limits.h
index 2538164ffaa..43b00c56a5f 100644
--- a/src/gallium/drivers/llvmpipe/lp_limits.h
+++ b/src/gallium/drivers/llvmpipe/lp_limits.h
@@ -73,6 +73,12 @@
#define LP_MAX_SHADER_VARIANTS 1024
/**
+ * Max number of instructions (for all fragment shaders combined per context)
+ * that will be kept around.
+ */
+#define LP_MAX_SHADER_INSTRUCTIONS (128*1024)
+
+/**
* Max number of setup variants that will be kept around.
*
* These are determined by the combination of the fragment shader
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 26f8d7ff765..5af74fe7925 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -804,6 +804,7 @@ generate_fragment(struct llvmpipe_context *lp,
LLVMWriteBitcodeToFile(gallivm->module, "llvmpipe.bc");
}
+ variant->nr_instrs += lp_build_count_instructions(function);
/*
* Translate the LLVM IR into machine code.
*/
@@ -1129,6 +1130,7 @@ llvmpipe_remove_shader_variant(struct llvmpipe_context *lp,
/* 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);
}
@@ -1350,11 +1352,22 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
/* variant not found, create it now */
int64_t t0, t1, dt;
unsigned i;
+ unsigned variants_to_cull;
+
+ if (0) {
+ debug_printf("%u variants,\t%u instrs,\t%u instrs/variant\n",
+ lp->nr_fs_variants,
+ lp->nr_fs_instrs,
+ lp->nr_fs_variants ? lp->nr_fs_instrs / lp->nr_fs_variants : 0);
+ }
/* First, check if we've exceeded the max number of shader variants.
* If so, free 25% of them (the least recently used ones).
*/
- if (lp->nr_fs_variants >= LP_MAX_SHADER_VARIANTS) {
+ variants_to_cull = lp->nr_fs_variants >= LP_MAX_SHADER_VARIANTS ? LP_MAX_SHADER_VARIANTS / 4 : 0;
+
+ if (variants_to_cull ||
+ lp->nr_fs_instrs >= LP_MAX_SHADER_INSTRUCTIONS) {
struct pipe_context *pipe = &lp->pipe;
/*
@@ -1370,17 +1383,15 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
* pending for destruction on flush.
*/
- if (lp->nr_fs_variants >= LP_MAX_SHADER_VARIANTS) {
- for (i = 0; i < LP_MAX_SHADER_VARIANTS / 4; i++) {
- struct lp_fs_variant_list_item *item;
- if (is_empty_list(&lp->fs_variants_list)) {
- break;
- }
- item = last_elem(&lp->fs_variants_list);
- assert(item);
- assert(item->base);
- llvmpipe_remove_shader_variant(lp, item->base);
+ for (i = 0; i < variants_to_cull || lp->nr_fs_instrs >= LP_MAX_SHADER_INSTRUCTIONS; i++) {
+ struct lp_fs_variant_list_item *item;
+ if (is_empty_list(&lp->fs_variants_list)) {
+ break;
}
+ item = last_elem(&lp->fs_variants_list);
+ assert(item);
+ assert(item->base);
+ llvmpipe_remove_shader_variant(lp, item->base);
}
}
@@ -1401,6 +1412,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
insert_at_head(&shader->variants, &variant->list_item_local);
insert_at_head(&lp->fs_variants_list, &variant->list_item_global);
lp->nr_fs_variants++;
+ lp->nr_fs_instrs += variant->nr_instrs;
shader->variants_cached++;
}
}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.h b/src/gallium/drivers/llvmpipe/lp_state_fs.h
index 98410c69359..273d241d8fc 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.h
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.h
@@ -88,6 +88,9 @@ struct lp_fragment_shader_variant
lp_jit_frag_func jit_function[2];
+ /* Total number of LLVM instructions generated */
+ unsigned nr_instrs;
+
struct lp_fs_variant_list_item list_item_global, list_item_local;
struct lp_fragment_shader *shader;