diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index 9fa1b535a2a..6d16e75f017 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -57,8 +57,12 @@ static void llvmpipe_destroy( struct pipe_context *pipe ) { struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); + struct llvmpipe_screen *lp_screen = llvmpipe_screen(pipe->screen); uint i; + mtx_lock(&lp_screen->ctx_mutex); + list_del(&llvmpipe->list); + mtx_unlock(&lp_screen->ctx_mutex); lp_print_counters(); if (llvmpipe->csctx) { @@ -189,8 +193,9 @@ llvmpipe_create_context(struct pipe_screen *screen, void *priv, unsigned flags) { struct llvmpipe_context *llvmpipe; + struct llvmpipe_screen *lp_screen = llvmpipe_screen(screen); - if (!llvmpipe_screen_late_init(llvmpipe_screen(screen))) + if (!llvmpipe_screen_late_init(lp_screen)) return NULL; llvmpipe = align_malloc(sizeof(struct llvmpipe_context), 16); @@ -258,7 +263,7 @@ llvmpipe_create_context(struct pipe_screen *screen, void *priv, goto fail; draw_set_disk_cache_callbacks(llvmpipe->draw, - llvmpipe_screen(screen), + lp_screen, lp_draw_disk_cache_find_shader, lp_draw_disk_cache_insert_shader); @@ -311,6 +316,9 @@ llvmpipe_create_context(struct pipe_screen *screen, void *priv, */ llvmpipe->dirty |= LP_NEW_SCISSOR; + mtx_lock(&lp_screen->ctx_mutex); + list_addtail(&llvmpipe->list, &lp_screen->ctx_list); + mtx_unlock(&lp_screen->ctx_mutex); return &llvmpipe->pipe; fail: diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 1cabf98177f..a61c8e0a569 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -58,6 +58,7 @@ struct lp_velems_state; struct llvmpipe_context { struct pipe_context pipe; /**< base class */ + struct list_head list; /** Constant state objects */ const struct pipe_blend_state *blend; struct pipe_sampler_state *samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS]; diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c index c72944232e7..c49836432a9 100644 --- a/src/gallium/drivers/llvmpipe/lp_flush.c +++ b/src/gallium/drivers/llvmpipe/lp_flush.c @@ -111,10 +111,12 @@ llvmpipe_flush_resource(struct pipe_context *pipe, boolean do_not_block, const char *reason) { - unsigned referenced; - - referenced = llvmpipe_is_resource_referenced(pipe, resource, level); - + unsigned referenced = 0; + struct llvmpipe_screen *lp_screen = llvmpipe_screen(pipe->screen); + mtx_lock(&lp_screen->ctx_mutex); + list_for_each_entry(struct llvmpipe_context, ctx, &lp_screen->ctx_list, list) + referenced |= llvmpipe_is_resource_referenced((struct pipe_context *)ctx, resource, level); + mtx_unlock(&lp_screen->ctx_mutex); if ((referenced & LP_REFERENCED_FOR_WRITE) || ((referenced & LP_REFERENCED_FOR_READ) && !read_only)) { diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index b8ab1a0ffde..1a0295ccc74 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -1079,6 +1079,8 @@ llvmpipe_create_screen(struct sw_winsys *winsys) snprintf(screen->renderer_string, sizeof(screen->renderer_string), "llvmpipe (LLVM " MESA_LLVM_VERSION_STRING ", %u bits)", lp_native_vector_width ); + list_inithead(&screen->ctx_list); + (void) mtx_init(&screen->ctx_mutex, mtx_plain); (void) mtx_init(&screen->cs_mutex, mtx_plain); (void) mtx_init(&screen->rast_mutex, mtx_plain); diff --git a/src/gallium/drivers/llvmpipe/lp_screen.h b/src/gallium/drivers/llvmpipe/lp_screen.h index c72bf838acb..18635c687bc 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.h +++ b/src/gallium/drivers/llvmpipe/lp_screen.h @@ -37,6 +37,7 @@ #include "pipe/p_screen.h" #include "pipe/p_defines.h" #include "os/os_thread.h" +#include "util/list.h" #include "gallivm/lp_bld.h" #include "gallivm/lp_bld_misc.h" @@ -67,6 +68,9 @@ struct llvmpipe_screen mtx_t late_mutex; bool late_init_done; + mtx_t ctx_mutex; + struct list_head ctx_list; + char renderer_string[100]; struct disk_cache *disk_shader_cache;