From: Marek Olšák Date: Sat, 30 Nov 2019 02:25:07 +0000 (-0500) Subject: radeonsi: use the live shader cache X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0db74f479b9c5efe52c5d021fe04ba5ce1f4e1bd;p=mesa.git radeonsi: use the live shader cache Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- diff --git a/src/gallium/drivers/radeonsi/si_compute.c b/src/gallium/drivers/radeonsi/si_compute.c index 25e08c6f428..610c1333597 100644 --- a/src/gallium/drivers/radeonsi/si_compute.c +++ b/src/gallium/drivers/radeonsi/si_compute.c @@ -213,7 +213,7 @@ static void *si_create_compute_state( struct si_compute *program = CALLOC_STRUCT(si_compute); struct si_shader_selector *sel = &program->sel; - pipe_reference_init(&sel->reference, 1); + pipe_reference_init(&sel->base.reference, 1); sel->type = PIPE_SHADER_COMPUTE; sel->screen = sscreen; program->shader.selector = &program->sel; diff --git a/src/gallium/drivers/radeonsi/si_compute.h b/src/gallium/drivers/radeonsi/si_compute.h index 5e2883d9e83..14c3c8cb789 100644 --- a/src/gallium/drivers/radeonsi/si_compute.h +++ b/src/gallium/drivers/radeonsi/si_compute.h @@ -50,7 +50,7 @@ void si_destroy_compute(struct si_compute *program); static inline void si_compute_reference(struct si_compute **dst, struct si_compute *src) { - if (pipe_reference(&(*dst)->sel.reference, &src->sel.reference)) + if (pipe_reference(&(*dst)->sel.base.reference, &src->sel.base.reference)) si_destroy_compute(*dst); *dst = src; diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 13c13031b54..55bd2b0324f 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -815,6 +815,7 @@ static void si_destroy_screen(struct pipe_screen* pscreen) slab_destroy_parent(&sscreen->pool_transfers); disk_cache_destroy(sscreen->disk_shader_cache); + util_live_shader_cache_deinit(&sscreen->live_shader_cache); sscreen->ws->destroy(sscreen->ws); FREE(sscreen); } @@ -1002,6 +1003,7 @@ radeonsi_screen_create_impl(struct radeon_winsys *ws, si_init_screen_state_functions(sscreen); si_init_screen_texture_functions(sscreen); si_init_screen_query_functions(sscreen); + si_init_screen_live_shader_cache(sscreen); /* Set these flags in debug_flags early, so that the shader cache takes * them into account. diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index a7c885dda64..523385228cc 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -601,6 +601,9 @@ struct si_screen { simple_mtx_t shader_cache_mutex; struct hash_table *shader_cache; + /* Shader cache of live shaders. */ + struct util_live_shader_cache live_shader_cache; + /* Shader compiler queue for multithreaded compilation. */ struct util_queue shader_compiler_queue; /* Use at most 3 normal compiler threads on quadcore and better. @@ -1587,6 +1590,19 @@ si_texture_reference(struct si_texture **ptr, struct si_texture *res) pipe_resource_reference((struct pipe_resource **)ptr, &res->buffer.b.b); } +static inline void +si_shader_selector_reference(struct si_context *sctx, /* sctx can optionally be NULL */ + struct si_shader_selector **dst, + struct si_shader_selector *src) +{ + if (*dst == src) + return; + + struct si_screen *sscreen = src ? src->screen : (*dst)->screen; + util_shader_reference(&sctx->b, &sscreen->live_shader_cache, + (void**)dst, src); +} + static inline bool vi_dcc_enabled(struct si_texture *tex, unsigned level) { diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index f5fe060b790..0109f68a9ed 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -132,6 +132,7 @@ #define SI_SHADER_H #include "util/u_inlines.h" +#include "util/u_live_shader_cache.h" #include "util/u_queue.h" #include "util/simple_mtx.h" @@ -404,7 +405,7 @@ struct si_shader_info { * binaries for one NIR program. This can be shared by multiple contexts. */ struct si_shader_selector { - struct pipe_reference reference; + struct util_live_shader base; struct si_screen *screen; struct util_queue_fence ready; struct si_compiler_ctx_state compiler_ctx_state; @@ -918,18 +919,4 @@ si_shader_uses_bindless_images(struct si_shader_selector *selector) return selector ? selector->info.uses_bindless_images : false; } -void si_destroy_shader_selector(struct si_context *sctx, - struct si_shader_selector *sel); - -static inline void -si_shader_selector_reference(struct si_context *sctx, - struct si_shader_selector **dst, - struct si_shader_selector *src) -{ - if (pipe_reference(&(*dst)->reference, &src->reference)) - si_destroy_shader_selector(sctx, *dst); - - *dst = src; -} - #endif diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index 897c0adb922..824bf4fef41 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -599,6 +599,7 @@ void si_shader_cache_insert_shader(struct si_screen *sscreen, struct si_shader *shader, bool insert_into_disk_cache); bool si_update_shaders(struct si_context *sctx); +void si_init_screen_live_shader_cache(struct si_screen *sscreen); void si_init_shader_functions(struct si_context *sctx); bool si_init_shader_cache(struct si_screen *sscreen); void si_destroy_shader_cache(struct si_screen *sscreen); diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index 69827d0774b..ffa4289783e 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -2788,7 +2788,6 @@ static void *si_create_shader_selector(struct pipe_context *ctx, if (!sel) return NULL; - pipe_reference_init(&sel->reference, 1); sel->screen = sscreen; sel->compiler_ctx_state.debug = sctx->debug; sel->compiler_ctx_state.is_debug_context = sctx->is_debug; @@ -3055,6 +3054,14 @@ static void *si_create_shader_selector(struct pipe_context *ctx, return sel; } +static void *si_create_shader(struct pipe_context *ctx, + const struct pipe_shader_state *state) +{ + struct si_screen *sscreen = (struct si_screen *)ctx->screen; + + return util_live_shader_cache_get(ctx, &sscreen->live_shader_cache, state); +} + static void si_update_streamout_state(struct si_context *sctx) { struct si_shader_selector *shader_with_so = si_get_vs(sctx)->cso; @@ -3358,9 +3365,10 @@ static void si_delete_shader(struct si_context *sctx, struct si_shader *shader) free(shader); } -void si_destroy_shader_selector(struct si_context *sctx, - struct si_shader_selector *sel) +static void si_destroy_shader_selector(struct pipe_context *ctx, void *cso) { + struct si_context *sctx = (struct si_context*)ctx; + struct si_shader_selector *sel = (struct si_shader_selector *)cso; struct si_shader *p = sel->first_variant, *c; struct si_shader_ctx_state *current_shader[SI_NUM_SHADERS] = { [PIPE_SHADER_VERTEX] = &sctx->vs_shader, @@ -4242,16 +4250,23 @@ static void si_emit_scratch_state(struct si_context *sctx) } } +void si_init_screen_live_shader_cache(struct si_screen *sscreen) +{ + util_live_shader_cache_init(&sscreen->live_shader_cache, + si_create_shader_selector, + si_destroy_shader_selector); +} + void si_init_shader_functions(struct si_context *sctx) { sctx->atoms.s.spi_map.emit = si_emit_spi_map; sctx->atoms.s.scratch_state.emit = si_emit_scratch_state; - sctx->b.create_vs_state = si_create_shader_selector; - sctx->b.create_tcs_state = si_create_shader_selector; - sctx->b.create_tes_state = si_create_shader_selector; - sctx->b.create_gs_state = si_create_shader_selector; - sctx->b.create_fs_state = si_create_shader_selector; + sctx->b.create_vs_state = si_create_shader; + sctx->b.create_tcs_state = si_create_shader; + sctx->b.create_tes_state = si_create_shader; + sctx->b.create_gs_state = si_create_shader; + sctx->b.create_fs_state = si_create_shader; sctx->b.bind_vs_state = si_bind_vs_shader; sctx->b.bind_tcs_state = si_bind_tcs_shader;