From: Pierre-Eric Pelloux-Prayer Date: Wed, 19 May 2021 15:11:57 +0000 (+0200) Subject: radeonsi: add si_install_draw_wrapper X-Git-Tag: upstream/21.2.3~1941 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b2bd9c5ccd79dc0ba3c6ec614c8fa598bb0f134a;p=platform%2Fupstream%2Fmesa.git radeonsi: add si_install_draw_wrapper This allows to implement custom draw_vbo code-path without touching si_draw_vbo. As an example, skipped all draw calls with an odd new_draws could be done like this: void mywrapper(...) { if (new_draws % 2) return; return sctx->real_draw_vbo(...); } if (some_condition_is_met) si_install_draw_wrapper(sctx, mywrapper); Instead of having to add the "if ()" condition inside si_draw_vbo. Note that a single wrapper may be installed so care must be taken to not override an existing wrapper. Reviewed-by: Marek Olšák Part-of: --- diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index e741a76..1fc1d9e 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -1286,6 +1286,8 @@ struct si_context { struct hash_table *dirty_implicit_resources; pipe_draw_vbo_func draw_vbo[NUM_GFX_VERSIONS - GFX6][2][2][2][2]; + /* When b.draw_vbo is a wrapper, real_draw_vbo is the real draw_vbo function */ + pipe_draw_vbo_func real_draw_vbo; /* SQTT */ struct ac_thread_trace_data *thread_trace; @@ -1341,6 +1343,11 @@ void si_replace_buffer_storage(struct pipe_context *ctx, struct pipe_resource *d void si_init_screen_buffer_functions(struct si_screen *sscreen); void si_init_buffer_functions(struct si_context *sctx); +/* Replace the sctx->b.draw_vbo function with a wrapper. This can be use to implement + * optimizations without affecting the normal draw_vbo functions perf. + */ +void si_install_draw_wrapper(struct si_context *sctx, pipe_draw_vbo_func wrapper); + /* si_clear.c */ #define SI_CLEAR_TYPE_CMASK (1 << 0) #define SI_CLEAR_TYPE_DCC (1 << 1) @@ -2010,12 +2017,16 @@ static inline unsigned si_get_shader_wave_size(struct si_shader *shader) static inline void si_select_draw_vbo(struct si_context *sctx) { - sctx->b.draw_vbo = sctx->draw_vbo[sctx->chip_class - GFX6] - [!!sctx->shader.tes.cso] - [!!sctx->shader.gs.cso] - [sctx->ngg] - [si_compute_prim_discard_enabled(sctx)]; - assert(sctx->b.draw_vbo); + pipe_draw_vbo_func draw_vbo = sctx->draw_vbo[sctx->chip_class - GFX6] + [!!sctx->shader.tes.cso] + [!!sctx->shader.gs.cso] + [sctx->ngg] + [si_compute_prim_discard_enabled(sctx)]; + assert(draw_vbo); + if (unlikely(sctx->real_draw_vbo)) + sctx->real_draw_vbo = draw_vbo; + else + sctx->b.draw_vbo = draw_vbo; } /* Return the number of samples that the rasterizer uses. */ diff --git a/src/gallium/drivers/radeonsi/si_state_draw.cpp b/src/gallium/drivers/radeonsi/si_state_draw.cpp index f704967..67b6610 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.cpp +++ b/src/gallium/drivers/radeonsi/si_state_draw.cpp @@ -2416,3 +2416,18 @@ void si_init_draw_functions(struct si_context *sctx) si_init_ia_multi_vgt_param_table(sctx); } + +extern "C" +void si_install_draw_wrapper(struct si_context *sctx, pipe_draw_vbo_func wrapper) +{ + if (wrapper) { + if (wrapper != sctx->b.draw_vbo) { + assert (!sctx->real_draw_vbo); + sctx->real_draw_vbo = sctx->b.draw_vbo; + sctx->b.draw_vbo = wrapper; + } + } else if (sctx->real_draw_vbo) { + sctx->real_draw_vbo = NULL; + si_select_draw_vbo(sctx); + } +}