i965: add cache fallback support using serialized nir
authorJordan Justen <jordan.l.justen@intel.com>
Thu, 19 Oct 2017 02:25:48 +0000 (19:25 -0700)
committerJordan Justen <jordan.l.justen@intel.com>
Wed, 1 Nov 2017 06:36:54 +0000 (23:36 -0700)
If the i965 gen program cannot be loaded from the cache, then we
fallback to using a serialized nir program.

This is based on "i965: add cache fallback support" by Timothy Arceri
<timothy.arceri@collabora.com>. Tim's version was written to fallback
to compiling from source, and therefore had to be much more complex.
After Connor and Jason implemented nir serialization, I was able to
rewrite and greatly simplify this patch.

Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Acked-by: Timothy Arceri <tarceri@itsqueeze.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_disk_cache.c

index f05ef853bfcf62b453e0bbed2549d0bdc669308b..73202d571f951d800591867ac01327e97f2e24e1 100644 (file)
@@ -24,6 +24,7 @@
 #include "compiler/blob.h"
 #include "compiler/glsl/ir_uniform.h"
 #include "compiler/glsl/shader_cache.h"
+#include "compiler/nir/nir_serialize.h"
 #include "main/mtypes.h"
 #include "util/disk_cache.h"
 #include "util/macros.h"
@@ -58,6 +59,27 @@ gen_shader_sha1(struct brw_context *brw, struct gl_program *prog,
    _mesa_sha1_compute(manifest, strlen(manifest), out_sha1);
 }
 
+static void
+restore_serialized_nir_shader(struct brw_context *brw, struct gl_program *prog,
+                              gl_shader_stage stage)
+{
+   prog->program_written_to_cache = false;
+   if (brw->ctx._Shader->Flags & GLSL_CACHE_INFO) {
+      fprintf(stderr, "falling back to nir %s.\n",
+              _mesa_shader_stage_to_abbrev(prog->info.stage));
+   }
+
+   if (!prog->nir) {
+      assert(prog->driver_cache_blob && prog->driver_cache_blob_size > 0);
+      const struct nir_shader_compiler_options *options =
+         brw->ctx.Const.ShaderCompilerOptions[stage].NirOptions;
+      struct blob_reader reader;
+      blob_reader_init(&reader, prog->driver_cache_blob,
+                       prog->driver_cache_blob_size);
+      prog->nir = nir_deserialize(NULL, options, &reader);
+   }
+}
+
 static void
 write_blob_program_data(struct blob *binary, gl_shader_stage stage,
                         const void *program,
@@ -258,6 +280,9 @@ brw_disk_cache_upload_program(struct brw_context *brw, gl_shader_stage stage)
        prog->sh.LinkedTransformFeedback->api_enabled)
       return false;
 
+   if (brw->ctx._Shader->Flags & GLSL_CACHE_FALLBACK)
+      goto fail;
+
    if (prog->sh.data->LinkStatus != linking_skipped)
       goto fail;
 
@@ -271,7 +296,7 @@ brw_disk_cache_upload_program(struct brw_context *brw, gl_shader_stage stage)
    return true;
 
 fail:
-   /*FIXME: Fall back and compile from source here. */
+   restore_serialized_nir_shader(brw, prog, stage);
    return false;
 }