radeonsi/nir: call nir_serialize only once per shader
authorMarek Olšák <marek.olsak@amd.com>
Thu, 7 Nov 2019 23:43:07 +0000 (18:43 -0500)
committerMarek Olšák <marek.olsak@amd.com>
Fri, 8 Nov 2019 20:30:28 +0000 (15:30 -0500)
We were calling it twice.

First serialize it, then use it to compute the cache key.

Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
src/gallium/drivers/radeonsi/si_state_shaders.c

index ddd27fb8176f31985db4f98e0882fb97a3f3ddfc..5e72611734a04d00d69b55299d50111548cdf05d 100644 (file)
@@ -47,7 +47,6 @@
 void si_get_ir_cache_key(struct si_shader_selector *sel, bool ngg, bool es,
                         unsigned char ir_sha1_cache_key[20])
 {
-       struct blob blob;
        unsigned ir_size;
        void *ir_binary;
 
@@ -56,12 +55,9 @@ void si_get_ir_cache_key(struct si_shader_selector *sel, bool ngg, bool es,
                ir_size = tgsi_num_tokens(sel->tokens) *
                          sizeof(struct tgsi_token);
        } else {
-               assert(sel->nir);
-
-               blob_init(&blob);
-               nir_serialize(&blob, sel->nir, true);
-               ir_binary = blob.data;
-               ir_size = blob.size;
+               assert(sel->nir_binary);
+               ir_binary = sel->nir_binary;
+               ir_size = sel->nir_size;
        }
 
        /* These settings affect the compilation, but they are not derived
@@ -87,9 +83,6 @@ void si_get_ir_cache_key(struct si_shader_selector *sel, bool ngg, bool es,
            sel->type == PIPE_SHADER_GEOMETRY)
                _mesa_sha1_update(&ctx, &sel->so, sizeof(sel->so));
        _mesa_sha1_final(&ctx, ir_sha1_cache_key);
-
-       if (sel->nir)
-               blob_finish(&blob);
 }
 
 /** Copy "data" to "ptr" and return the next dword following copied data. */
@@ -2465,6 +2458,23 @@ static void si_init_shader_selector_async(void *job, int thread_index)
        if (!compiler->passes)
                si_init_compiler(sscreen, compiler);
 
+       /* Serialize NIR to save memory. Monolithic shader variants
+        * have to deserialize NIR before compilation.
+        */
+       if (sel->nir) {
+               struct blob blob;
+                size_t size;
+
+               blob_init(&blob);
+               /* true = remove optional debugging data to increase
+                * the likehood of getting more shader cache hits.
+                * It also drops variable names, so we'll save more memory.
+                */
+               nir_serialize(&blob, sel->nir, true);
+               blob_finish_get_buffer(&blob, &sel->nir_binary, &size);
+               sel->nir_size = size;
+       }
+
        /* Compile the main shader part for use with a prolog and/or epilog.
         * If this fails, the driver will try to compile a monolithic shader
         * on demand.
@@ -2582,18 +2592,8 @@ static void si_init_shader_selector_async(void *job, int thread_index)
                si_shader_vs(sscreen, sel->gs_copy_shader, sel);
        }
 
+       /* Free NIR. We only keep serialized NIR after this point. */
        if (sel->nir) {
-               /* Serialize NIR to save memory. Monolithic shader variants
-                * have to deserialize NIR before compilation.
-                */
-               struct blob blob;
-               blob_init(&blob);
-               nir_serialize(&blob, sel->nir, false);
-               sel->nir_binary = malloc(blob.size);
-               memcpy(sel->nir_binary, blob.data, blob.size);
-               sel->nir_size = blob.size;
-               blob_finish(&blob);
-
                ralloc_free(sel->nir);
                sel->nir = NULL;
        }