i965: Add brw_program_deserialize_driver_blob
authorJordan Justen <jordan.l.justen@intel.com>
Wed, 28 Feb 2018 22:41:02 +0000 (14:41 -0800)
committerJordan Justen <jordan.l.justen@intel.com>
Tue, 10 Jul 2018 06:02:32 +0000 (23:02 -0700)
brw_program_deserialize_driver_blob will be a more generic form of
brw_program_deserialize_nir. In addition to nir, it will also be able
to extract gen binaries and upload them to the program cache.

In this commit, it continues to only support nir.

Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_disk_cache.c
src/mesa/drivers/dri/i965/brw_program_binary.c

index c9705cbd9cc91a8047d5536d5344048e630fb90e..c9c01b7d56a44c0644447fdc0574c99b1a10d0cd 100644 (file)
@@ -1644,8 +1644,9 @@ brw_deserialize_program_binary(struct gl_context *ctx,
 void
 brw_program_serialize_nir(struct gl_context *ctx, struct gl_program *prog);
 void
-brw_program_deserialize_nir(struct gl_context *ctx, struct gl_program *prog,
-                            gl_shader_stage stage);
+brw_program_deserialize_driver_blob(struct gl_context *ctx,
+                                    struct gl_program *prog,
+                                    gl_shader_stage stage);
 
 /*======================================================================
  * Inline conversion functions.  These are better-typed than the
index ee6067ca51a0fdd4620432ecbeb296640651a269..4aa304eb4a6a4b967552f9795bfa3dece8c6022d 100644 (file)
@@ -246,7 +246,7 @@ read_and_upload(struct brw_context *brw, struct disk_cache *cache,
    if (unlikely(debug_enabled_for_stage(stage))) {
       fprintf(stderr, "NIR for %s program %d loaded from disk shader cache:\n",
               _mesa_shader_stage_to_abbrev(stage), brw_program(prog)->id);
-      brw_program_deserialize_nir(&brw->ctx, prog, stage);
+      brw_program_deserialize_driver_blob(&brw->ctx, prog, stage);
       nir_shader *nir = prog->nir;
       nir_print_shader(nir, stderr);
       fprintf(stderr, "Native code for %s %s shader %s from disk cache:\n",
@@ -299,7 +299,7 @@ fail:
               _mesa_shader_stage_to_abbrev(prog->info.stage));
    }
 
-   brw_program_deserialize_nir(&brw->ctx, prog, stage);
+   brw_program_deserialize_driver_blob(&brw->ctx, prog, stage);
 
    return false;
 }
index 099279ef37e0cb5adba9133afd53cc7d4a494083..cb1cfdb560a0e71b5cf2bb68faef2afd4fea89e8 100644 (file)
@@ -61,6 +61,11 @@ brw_get_program_binary_driver_sha1(struct gl_context *ctx, uint8_t *sha1)
    memcpy(sha1, driver_sha1, sizeof(uint8_t) * 20);
 }
 
+enum driver_cache_blob_part {
+   END_PART,
+   NIR_PART,
+};
+
 void
 brw_program_serialize_nir(struct gl_context *ctx, struct gl_program *prog)
 {
@@ -69,7 +74,12 @@ brw_program_serialize_nir(struct gl_context *ctx, struct gl_program *prog)
 
    struct blob writer;
    blob_init(&writer);
+   blob_write_uint32(&writer, NIR_PART);
+   intptr_t size_offset = blob_reserve_uint32(&writer);
+   size_t nir_start = writer.size;
    nir_serialize(&writer, prog->nir);
+   blob_overwrite_uint32(&writer, size_offset, writer.size - nir_start);
+   blob_write_uint32(&writer, END_PART);
    prog->driver_cache_blob = ralloc_size(NULL, writer.size);
    memcpy(prog->driver_cache_blob, writer.data, writer.size);
    prog->driver_cache_blob_size = writer.size;
@@ -77,24 +87,40 @@ brw_program_serialize_nir(struct gl_context *ctx, struct gl_program *prog)
 }
 
 void
-brw_program_deserialize_nir(struct gl_context *ctx, struct gl_program *prog,
-                            gl_shader_stage stage)
+brw_program_deserialize_driver_blob(struct gl_context *ctx,
+                                    struct gl_program *prog,
+                                    gl_shader_stage stage)
 {
-   if (!prog->nir) {
-      assert(prog->driver_cache_blob && prog->driver_cache_blob_size > 0);
-      const struct nir_shader_compiler_options *options =
-         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);
-   }
+   if (!prog->driver_cache_blob)
+      return;
+
+   struct blob_reader reader;
+   blob_reader_init(&reader, prog->driver_cache_blob,
+                    prog->driver_cache_blob_size);
+
+   do {
+      uint32_t part_type = blob_read_uint32(&reader);
+      if ((enum driver_cache_blob_part)part_type == END_PART)
+         break;
+      switch ((enum driver_cache_blob_part)part_type) {
+      case NIR_PART: {
+         uint32_t nir_size = blob_read_uint32(&reader);
+         assert(!reader.overrun &&
+                (uintptr_t)(reader.end - reader.current) > nir_size);
+         const struct nir_shader_compiler_options *options =
+            ctx->Const.ShaderCompilerOptions[stage].NirOptions;
+         prog->nir = nir_deserialize(NULL, options, &reader);
+         break;
+      }
+      default:
+         unreachable("Unsupported blob part type!");
+         break;
+      }
+   } while (true);
 
-   if (prog->driver_cache_blob) {
-      ralloc_free(prog->driver_cache_blob);
-      prog->driver_cache_blob = NULL;
-      prog->driver_cache_blob_size = 0;
-   }
+   ralloc_free(prog->driver_cache_blob);
+   prog->driver_cache_blob = NULL;
+   prog->driver_cache_blob_size = 0;
 }
 
 /* This is just a wrapper around brw_program_deserialize_nir() as i965
@@ -105,5 +131,5 @@ brw_deserialize_program_binary(struct gl_context *ctx,
                                struct gl_shader_program *shProg,
                                struct gl_program *prog)
 {
-   brw_program_deserialize_nir(ctx, prog, prog->info.stage);
+   brw_program_deserialize_driver_blob(ctx, prog, prog->info.stage);
 }