From f32c7232a8a16887af710a11f025381bc73640f0 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Mon, 28 Nov 2011 16:54:09 +0000 Subject: llvmpipe,draw,gallivm: Ensure we don't walk beyond the end of the shader variant list. u_simple_list.h uses a sentinel element, and not a NULL element. So ensure list is not empty when reducing the list of shader variants. Something I noticed while trying to free variants more aggressively. Reviewed-by: Brian Paul --- src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c | 9 +++++++-- src/gallium/drivers/llvmpipe/lp_state_fs.c | 6 ++++-- src/gallium/drivers/llvmpipe/lp_state_setup.c | 8 +++++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c index 7698f5ff2a..de6ce7fad4 100644 --- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c +++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c @@ -160,8 +160,13 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle, * XXX: should we flush here ? */ for (i = 0; i < DRAW_MAX_SHADER_VARIANTS / 4; i++) { - struct draw_llvm_variant_list_item *item = - last_elem(&fpme->llvm->vs_variants_list); + struct draw_llvm_variant_list_item *item; + if (is_empty_list(&fpme->llvm->vs_variants_list)) { + break; + } + item = last_elem(&fpme->llvm->vs_variants_list); + assert(item); + assert(item->base); draw_llvm_destroy_variant(item->base); } } diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 90f9271223..26f8d7ff76 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -1373,10 +1373,12 @@ llvmpipe_update_fs(struct llvmpipe_context *lp) 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) { + 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); } } diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.c b/src/gallium/drivers/llvmpipe/lp_state_setup.c index 97c9238f98..3243abff6e 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_state_setup.c @@ -837,7 +837,13 @@ cull_setup_variants(struct llvmpipe_context *lp) llvmpipe_finish(pipe, __FUNCTION__); for (i = 0; i < LP_MAX_SETUP_VARIANTS / 4; i++) { - struct lp_setup_variant_list_item *item = last_elem(&lp->setup_variants_list); + struct lp_setup_variant_list_item *item; + if (is_empty_list(&lp->setup_variants_list)) { + break; + } + item = last_elem(&lp->setup_variants_list); + assert(item); + assert(item->base); remove_setup_variant(lp, item->base); } } -- cgit v1.2.3