From e84cf80fe158bb1ec0bd4ce72fee72c566388ee1 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 29 Mar 2023 07:47:43 -0400 Subject: [PATCH] zink: always store nir serialized this saves a ton of memory and has minimal, if any cpu impact Part-of: --- src/gallium/drivers/zink/zink_program.c | 30 +++++++++++++++++++++--------- src/gallium/drivers/zink/zink_types.h | 4 ++-- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index 315a72d..f1b22f8 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -152,7 +152,7 @@ create_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *scr assert(ctx); //TODO async mod = zink_shader_tcs_compile(screen, zs, patch_vertices); } else { - mod = zink_shader_compile(screen, zs, nir_shader_clone(NULL, prog->nir[stage]), key, &ctx->di.zs_swizzle[stage]); + mod = zink_shader_compile(screen, zs, zink_shader_blob_deserialize(screen, &prog->blobs[stage]), key, &ctx->di.zs_swizzle[stage]); } if (!mod) { FREE(zm); @@ -267,7 +267,7 @@ create_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_scr struct zink_tcs_key *tcs = (struct zink_tcs_key*)key; mod = zink_shader_tcs_compile(screen, zs, tcs->patch_vertices); } else { - mod = zink_shader_compile(screen, zs, nir_shader_clone(NULL, prog->nir[stage]), (struct zink_shader_key*)key, shadow_needs_shader_swizzle ? &ctx->di.zs_swizzle[stage] : NULL); + mod = zink_shader_compile(screen, zs, zink_shader_blob_deserialize(screen, &prog->blobs[stage]), (struct zink_shader_key*)key, shadow_needs_shader_swizzle ? &ctx->di.zs_swizzle[stage] : NULL); } if (!mod) { FREE(zm); @@ -843,7 +843,7 @@ update_cs_shader_module(struct zink_context *ctx, struct zink_compute_program *c if (!zm) { return; } - mod = zink_shader_compile(screen, zs, nir_shader_clone(NULL, comp->nir), key, zs_swizzle_size ? &ctx->di.zs_swizzle[MESA_SHADER_COMPUTE] : NULL); + mod = zink_shader_compile(screen, zs, zink_shader_blob_deserialize(screen, &comp->shader->blob), key, zs_swizzle_size ? &ctx->di.zs_swizzle[MESA_SHADER_COMPUTE] : NULL); if (!mod) { FREE(zm); return; @@ -1027,6 +1027,8 @@ zink_create_gfx_program(struct zink_context *ctx, prog->base.removed = true; prog->optimal_keys = screen->optimal_keys; + nir_shader *nir[ZINK_GFX_SHADER_COUNT]; + prog->has_edgeflags = prog->shaders[MESA_SHADER_VERTEX] && prog->shaders[MESA_SHADER_VERTEX]->has_edgeflags; for (int i = 0; i < ZINK_GFX_SHADER_COUNT; ++i) { @@ -1039,18 +1041,26 @@ zink_create_gfx_program(struct zink_context *ctx, prog->stages_present |= BITFIELD_BIT(i); prog->optimal_keys &= !prog->shaders[i]->non_fs.is_generated; prog->needs_inlining |= prog->shaders[i]->needs_inlining; - prog->nir[i] = zink_shader_deserialize(screen, stages[i]); + nir[i] = zink_shader_deserialize(screen, stages[i]); + } else { + nir[i] = NULL; } } if (stages[MESA_SHADER_TESS_EVAL] && !stages[MESA_SHADER_TESS_CTRL]) { prog->shaders[MESA_SHADER_TESS_EVAL]->non_fs.generated_tcs = prog->shaders[MESA_SHADER_TESS_CTRL] = - zink_shader_tcs_create(screen, prog->nir[MESA_SHADER_VERTEX], vertices_per_patch, &prog->nir[MESA_SHADER_TESS_CTRL]); + zink_shader_tcs_create(screen, nir[MESA_SHADER_VERTEX], vertices_per_patch, &nir[MESA_SHADER_TESS_CTRL]); prog->stages_present |= BITFIELD_BIT(MESA_SHADER_TESS_CTRL); } prog->stages_remaining = prog->stages_present; - assign_io(screen, prog->nir); + assign_io(screen, nir); + for (unsigned i = 0; i < ZINK_GFX_SHADER_COUNT; i++) { + if (nir[i]) + zink_shader_serialize_blob(nir[i], &prog->blobs[i]); + ralloc_free(nir[i]); + } + if (stages[MESA_SHADER_GEOMETRY]) prog->last_vertex_stage = stages[MESA_SHADER_GEOMETRY]; @@ -1255,7 +1265,9 @@ precompile_compute_job(void *data, void *gdata, int thread_index) comp->shader = zink_shader_create(screen, comp->nir, NULL); comp->curr = comp->module = CALLOC_STRUCT(zink_shader_module); assert(comp->module); - comp->module->shader = zink_shader_compile(screen, comp->shader, nir_shader_clone(NULL, comp->nir), NULL, NULL); + comp->module->shader = zink_shader_compile(screen, comp->shader, comp->nir, NULL, NULL); + /* comp->nir will be freed by zink_shader_compile */ + comp->nir = NULL; assert(comp->module->shader); util_dynarray_init(&comp->shader_cache[0], comp); util_dynarray_init(&comp->shader_cache[1], comp); @@ -1456,7 +1468,7 @@ zink_destroy_gfx_program(struct zink_screen *screen, destroy_shader_cache(screen, &prog->shader_cache[i][0][1]); destroy_shader_cache(screen, &prog->shader_cache[i][1][0]); destroy_shader_cache(screen, &prog->shader_cache[i][1][1]); - ralloc_free(prog->nir[i]); + blob_finish(&prog->blobs[i]); } } if (prog->is_separable) @@ -1475,7 +1487,7 @@ zink_destroy_compute_program(struct zink_screen *screen, assert(!comp->shader->spirv); _mesa_set_destroy(comp->shader->programs, NULL); - ralloc_free(comp->nir); + blob_finish(&comp->shader->blob); ralloc_free(comp->shader); destroy_shader_cache(screen, &comp->shader_cache[0]); diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index 9bd2970..e7b409c 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -1038,7 +1038,7 @@ struct zink_gfx_program { /* full */ VkShaderModule modules[ZINK_GFX_SHADER_COUNT]; // compute stage doesn't belong here uint32_t module_hash[ZINK_GFX_SHADER_COUNT]; - struct nir_shader *nir[ZINK_GFX_SHADER_COUNT]; + struct blob blobs[ZINK_GFX_SHADER_COUNT]; struct util_dynarray shader_cache[ZINK_GFX_SHADER_COUNT][2][2]; //normal, nonseamless cubes, inline uniforms unsigned inlined_variant_count[ZINK_GFX_SHADER_COUNT]; uint32_t default_variant_hash; @@ -1065,7 +1065,7 @@ struct zink_compute_program { bool use_local_size; unsigned num_inlinable_uniforms; - nir_shader *nir; + nir_shader *nir; //only until precompile finishes struct zink_shader_module *curr; -- 2.7.4