compiler: Save a single copy of the softfp64 shader in the context.
authorKenneth Graunke <kenneth@whitecape.org>
Tue, 9 Jul 2019 07:32:42 +0000 (00:32 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 11 Jul 2019 05:14:36 +0000 (22:14 -0700)
We were recompiling the softfp64 library of functions from GLSL to NIR
every time we compiled a shader that used fp64.  Worse, we were ralloc
stealing it to the GL context.  This meant that we'd accumulate lots of
copies for the lifetime of the context, which was a big space leak.

Instead, we can simply stash a single copy in the GL context, and use
it for subsequent compiles.  Having a single copy should be fine from
a memory context point of view: nir_inline_function_impl already clones
the necessary nir_function_impl's as it inlines.

KHR-GL45.enhanced_layouts.ssb_member_align_non_power_of_2 was previously
OOM'ing a system with 16GB of RAM when using softfp64.  Now it finishes
much more quickly and uses only ~200MB of RAM.

Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
src/mesa/drivers/dri/i965/brw_program.c
src/mesa/main/context.c
src/mesa/main/mtypes.h
src/mesa/state_tracker/st_glsl_to_nir.cpp

index 57fcf32efd178c18b9b16f3518e23c9e7685d042..0e91612d845f49fdd8ae2fb9395c92dc44bb1bee 100644 (file)
@@ -110,14 +110,12 @@ brw_create_nir(struct brw_context *brw,
 
    nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
 
-   nir_shader *softfp64 = NULL;
-   if ((options->lower_doubles_options & nir_lower_fp64_full_software) &&
-       nir->info.uses_64bit) {
-      softfp64 = glsl_float64_funcs_to_nir(ctx, options);
-      ralloc_steal(ralloc_parent(nir), softfp64);
+   if (!ctx->SoftFP64 && nir->info.uses_64bit &&
+       (options->lower_doubles_options & nir_lower_fp64_full_software)) {
+      ctx->SoftFP64 = glsl_float64_funcs_to_nir(ctx, options);
    }
 
-   brw_preprocess_nir(brw->screen->compiler, nir, softfp64);
+   brw_preprocess_nir(brw->screen->compiler, nir, ctx->SoftFP64);
 
    if (stage == MESA_SHADER_TESS_CTRL) {
       /* Lower gl_PatchVerticesIn from a sys. value to a uniform on Gen8+. */
index 2734693b1178a6ca829cf2a8febcf7dbe11359ec..42fb404b50ecd2e039d6b927f2f35f1688cb4fe4 100644 (file)
@@ -1397,6 +1397,8 @@ _mesa_free_context_data(struct gl_context *ctx, bool destroy_compiler_types)
    if (destroy_compiler_types)
       _mesa_destroy_shader_compiler_types();
 
+   ralloc_free(ctx->SoftFP64);
+
    /* unbind the context if it's currently bound */
    if (ctx == _mesa_get_current_context()) {
       _mesa_make_current(NULL, NULL, NULL);
index 13e18e6e8ab968c1fe3ce5bac0bfbafae4b4e7a6..2b87c70111629deb14747c198574d97c6ccae963 100644 (file)
@@ -4970,6 +4970,11 @@ struct gl_context
     */
    struct gl_pipeline_object *_Shader;
 
+   /**
+    * NIR containing the functions that implement software fp64 support.
+    */
+   struct nir_shader *SoftFP64;
+
    struct gl_query_state Query;  /**< occlusion, timer queries */
 
    struct gl_transform_feedback_state TransformFeedback;
index 221c8a030b0c2d9354d9631eb24f6ba64c2425f4..be1fc3b24842af1cd6d7f98dfe00b05b240fb743 100644 (file)
@@ -328,11 +328,9 @@ st_glsl_to_nir(struct st_context *st, struct gl_program *prog,
    }
 
    nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
-   nir_shader *softfp64 = NULL;
-   if (nir->info.uses_64bit &&
+   if (!st->ctx->SoftFP64 && nir->info.uses_64bit &&
        (options->lower_doubles_options & nir_lower_fp64_full_software) != 0) {
-      softfp64 = glsl_float64_funcs_to_nir(st->ctx, options);
-      ralloc_steal(ralloc_parent(nir), softfp64);
+      st->ctx->SoftFP64 = glsl_float64_funcs_to_nir(st->ctx, options);
    }
 
    nir_variable_mode mask =
@@ -381,7 +379,7 @@ st_glsl_to_nir(struct st_context *st, struct gl_program *prog,
          }
          if (options->lower_doubles_options) {
             NIR_PASS(progress, nir, nir_lower_doubles,
-                     softfp64, options->lower_doubles_options);
+                     st->ctx->SoftFP64, options->lower_doubles_options);
          }
          NIR_PASS(progress, nir, nir_opt_algebraic);
          lowered_64bit_ops |= progress;