i965: Regenerate blob without gen program for shader cache
authorJordan Justen <jordan.l.justen@intel.com>
Mon, 9 Apr 2018 08:39:18 +0000 (01:39 -0700)
committerJordan Justen <jordan.l.justen@intel.com>
Tue, 10 Jul 2018 06:02:33 +0000 (23:02 -0700)
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
src/mesa/drivers/dri/i965/brw_program_binary.c

index 3528847..20d3a3c 100644 (file)
@@ -68,12 +68,74 @@ enum driver_cache_blob_part {
    NIR_PART,
 };
 
+static bool
+blob_parts_valid(void *blob, uint32_t size)
+{
+   struct blob_reader reader;
+   blob_reader_init(&reader, blob, size);
+
+   do {
+      uint32_t part_type = blob_read_uint32(&reader);
+      if (reader.overrun)
+         return false;
+      if (part_type == END_PART)
+         return reader.current == reader.end;
+      switch ((enum driver_cache_blob_part)part_type) {
+      case GEN_PART:
+      case NIR_PART:
+         /* Read the uint32_t part-size and skip over it */
+         blob_skip_bytes(&reader, blob_read_uint32(&reader));
+         if (reader.overrun)
+            return false;
+         break;
+      default:
+         return false;
+      }
+   } while (true);
+}
+
+static bool
+blob_has_part(void *blob, uint32_t size, enum driver_cache_blob_part part)
+{
+   struct blob_reader reader;
+   blob_reader_init(&reader, blob, size);
+
+   assert(blob_parts_valid(blob, size));
+   do {
+      uint32_t part_type = blob_read_uint32(&reader);
+      if (part_type == END_PART)
+         return false;
+      if (part_type == part)
+         return true;
+      blob_skip_bytes(&reader, blob_read_uint32(&reader));
+   } while (true);
+}
+
+static bool
+driver_blob_is_ready(void *blob, uint32_t size, bool with_gen_program)
+{
+   if (!blob) {
+      return false;
+   } else if (!blob_parts_valid(blob, size)) {
+      unreachable("Driver blob format is bad!");
+      return false;
+   } else if (blob_has_part(blob, size, GEN_PART) == with_gen_program) {
+      return true;
+   } else {
+      return false;
+   }
+}
+
 void
 brw_program_serialize_nir(struct gl_context *ctx, struct gl_program *prog)
 {
-   if (prog->driver_cache_blob)
+   if (driver_blob_is_ready(prog->driver_cache_blob,
+                            prog->driver_cache_blob_size, false))
       return;
 
+   if (prog->driver_cache_blob)
+      ralloc_free(prog->driver_cache_blob);
+
    struct blob writer;
    blob_init(&writer);
    blob_write_uint32(&writer, NIR_PART);