iris: Serialize the NIR to a blob we can use for shader cache purposes.
authorKenneth Graunke <kenneth@whitecape.org>
Tue, 21 May 2019 06:25:40 +0000 (23:25 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Tue, 21 May 2019 22:05:38 +0000 (15:05 -0700)
We will use a hash of the serialized NIR together with brw_prog_*_key
(for NOS) as the disk cache key, where the disk cache contains actual
assembly shaders.

Reviewed-by: Dylan Baker <dylan@pnwbakers.com>
src/gallium/drivers/iris/iris_context.h
src/gallium/drivers/iris/iris_program.c

index 294f325d19d69004de724d1ebb84dc2cf312c93f..a3e4da792e90ea09e4160cc97c11bf3d6768a20e 100644 (file)
@@ -260,6 +260,10 @@ struct iris_uncompiled_shader {
 
    struct pipe_stream_output_info stream_output;
 
+   /* The serialized NIR (for the disk cache) and size in bytes. */
+   void *ir_cache_binary;
+   uint32_t ir_cache_binary_size;
+
    unsigned program_id;
 
    /** Bitfield of (1 << IRIS_NOS_*) flags. */
index 834a366135506aff816e517afe391cdaaeada70f..5c1af3c8a4b20705b92b1e7da968ef134944b52a 100644 (file)
@@ -38,6 +38,7 @@
 #include "util/u_atomic.h"
 #include "compiler/nir/nir.h"
 #include "compiler/nir/nir_builder.h"
+#include "compiler/nir/nir_serialize.h"
 #include "intel/compiler/brw_compiler.h"
 #include "intel/compiler/brw_nir.h"
 #include "iris_context.h"
@@ -1458,6 +1459,26 @@ iris_create_uncompiled_shader(struct pipe_context *ctx,
       update_so_info(&ish->stream_output, nir->info.outputs_written);
    }
 
+   if (screen->disk_cache) {
+      /* Serialize the NIR to a binary blob that we can hash for the disk
+       * cache.  First, drop unnecessary information (like variable names)
+       * so the serialized NIR is smaller, and also to let us detect more
+       * isomorphic shaders when hashing, increasing cache hits.
+       *
+       * We skip this step when not using the disk cache, as variable names
+       * are useful for inspecting and debugging shaders.
+       */
+      nir_strip(nir);
+
+      struct blob blob;
+      blob_init(&blob);
+      nir_serialize(&blob, ish->nir);
+      ish->ir_cache_binary = malloc(blob.size);
+      ish->ir_cache_binary_size = blob.size;
+      memcpy(ish->ir_cache_binary, blob.data, blob.size);
+      blob_finish(&blob);
+   }
+
    return ish;
 }