summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJosé Fonseca <jfonseca@vmware.com>2011-09-28 20:23:13 +0100
committerJosé Fonseca <jfonseca@vmware.com>2011-09-29 17:43:38 +0100
commitb8d1242c0bb29ef6866cbfdd75cb18eec9ba8068 (patch)
tree60c51e359b885a9d9dff8051506b7ecf6b1a7bc7 /src
parent47ff3f7cc516a1087ac6d4fee024f69d62708542 (diff)
downloadexternal_mesa3d-b8d1242c0bb29ef6866cbfdd75cb18eec9ba8068.zip
external_mesa3d-b8d1242c0bb29ef6866cbfdd75cb18eec9ba8068.tar.gz
external_mesa3d-b8d1242c0bb29ef6866cbfdd75cb18eec9ba8068.tar.bz2
llvmpipe: Prevent segfault during fs variant cache shrinking.
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 6243a96..646c38d 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -1366,10 +1366,21 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
*/
llvmpipe_finish(pipe, __FUNCTION__);
- for (i = 0; i < LP_MAX_SHADER_VARIANTS / 4; i++) {
- struct lp_fs_variant_list_item *item;
- item = last_elem(&lp->fs_variants_list);
- llvmpipe_remove_shader_variant(lp, item->base);
+ /*
+ * We need to re-check lp->nr_fs_variants because an arbitrarliy large
+ * number of shader variants (potentially all of them) could be
+ * 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;
+ item = last_elem(&lp->fs_variants_list);
+ if (!item) {
+ break;
+ }
+ llvmpipe_remove_shader_variant(lp, item->base);
+ }
}
}