From 5b205ef41307406983ffac829ae423d08f7527bc Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Tue, 29 Nov 2022 15:53:41 +0100 Subject: [PATCH] r600: Store nir shaders serialized to save memory Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7247 Signed-off-by: Gert Wollny Part-of: --- src/gallium/drivers/r600/r600_pipe.h | 6 +++- src/gallium/drivers/r600/r600_shader.c | 37 ++++++++++++++++---- src/gallium/drivers/r600/r600_state_common.c | 2 ++ 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 8e1cc69447f..93f1619063a 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -344,7 +344,11 @@ struct r600_pipe_shader_selector { struct r600_pipe_shader *current; struct tgsi_token *tokens; - struct nir_shader *nir; + struct nir_shader *nir; + + size_t nir_blob_size; + void *nir_blob; + struct pipe_stream_output_info so; struct tgsi_shader_info info; diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index db0b16f9bdd..2cc06a5c5d4 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -20,6 +20,8 @@ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include "nir_serialize.h" +#include "pipe/p_defines.h" #include "r600_sq.h" #include "r600_formats.h" #include "r600_opcodes.h" @@ -174,6 +176,18 @@ int r600_pipe_shader_create(struct pipe_context *ctx, int r; struct r600_screen *rscreen = (struct r600_screen *)ctx->screen; + const nir_shader_compiler_options *nir_options = + (const nir_shader_compiler_options *) + ctx->screen->get_compiler_options(ctx->screen, + PIPE_SHADER_IR_NIR, + shader->shader.processor_type); + if (!sel->nir && !(sel->ir_type == PIPE_SHADER_IR_TGSI)) { + assert(sel->nir_blob); + struct blob_reader blob_reader; + blob_reader_init(&blob_reader, sel->nir_blob, sel->nir_blob_size); + sel->nir = nir_deserialize(NULL, nir_options, &blob_reader); + } + int processor = sel->ir_type == PIPE_SHADER_IR_TGSI ? tgsi_get_processor_type(sel->tokens): pipe_shader_type_from_mesa(sel->nir->info.stage); @@ -196,17 +210,15 @@ int r600_pipe_shader_create(struct pipe_context *ctx, } } else { glsl_type_singleton_init_or_ref(); - if (sel->ir_type == PIPE_SHADER_IR_TGSI) { if (sel->nir) ralloc_free(sel->nir); + if (sel->nir_blob) { + free(sel->nir_blob); + sel->nir_blob = NULL; + } sel->nir = tgsi_to_nir(sel->tokens, ctx->screen, true); - const nir_shader_compiler_options *nir_options = - (const nir_shader_compiler_options *) - ctx->screen->get_compiler_options(ctx->screen, - PIPE_SHADER_IR_NIR, - shader->shader.processor_type); - /* Lower int64 ops because we have some r600 build-in shaders that use it */ + /* Lower int64 ops because we have some r600 build-in shaders that use it */ if (nir_options->lower_int64_options) { NIR_PASS_V(sel->nir, nir_lower_regs_to_ssa); NIR_PASS_V(sel->nir, nir_lower_alu_to_scalar, r600_lower_to_scalar_instr_filter, NULL); @@ -383,6 +395,17 @@ int r600_pipe_shader_create(struct pipe_context *ctx, shader->shader.bc.ncf, shader->shader.bc.nstack); + if (!sel->nir_blob && sel->nir) { + struct blob blob; + blob_init(&blob); + nir_serialize(&blob, sel->nir, false); + sel->nir_blob = malloc(blob.size); + memcpy(sel->nir_blob, blob.data, blob.size); + sel->nir_blob_size = blob.size; + } + ralloc_free(sel->nir); + sel->nir = NULL; + return 0; error: diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index be03117b8ae..a124a81e318 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -1191,6 +1191,8 @@ void r600_delete_shader_selector(struct pipe_context *ctx, } else if (sel->ir_type == PIPE_SHADER_IR_NIR) ralloc_free(sel->nir); + if (sel->nir_blob) + free(sel->nir_blob); free(sel); }