anv/pipeline: Recompile all shaders if any are missing from the cache
authorJason Ekstrand <jason.ekstrand@intel.com>
Fri, 27 Oct 2017 22:05:02 +0000 (15:05 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Thu, 2 Aug 2018 17:29:20 +0000 (10:29 -0700)
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
src/intel/vulkan/anv_pipeline.c

index 71b60e922143d053f1af61b1acb87c4723f8ff06..cbde4b150c0754d7fcbfbfff762e5567ed833a58 100644 (file)
@@ -1066,6 +1066,7 @@ anv_pipeline_compile_graphics(struct anv_pipeline *pipeline,
    unsigned char sha1[20];
    anv_pipeline_hash_graphics(pipeline, layout, stages, sha1);
 
+   unsigned found = 0;
    for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) {
       if (!stages[s].entrypoint)
          continue;
@@ -1077,8 +1078,42 @@ anv_pipeline_compile_graphics(struct anv_pipeline *pipeline,
          anv_device_search_for_kernel(pipeline->device, cache,
                                       &stages[s].cache_key,
                                       sizeof(stages[s].cache_key));
-      if (bin)
+      if (bin) {
+         found++;
          pipeline->shaders[s] = bin;
+      }
+   }
+
+   if (found == __builtin_popcount(pipeline->active_stages)) {
+      /* We found all our shaders in the cache.  We're done. */
+      return VK_SUCCESS;
+   } else if (found > 0) {
+      /* We found some but not all of our shaders.  This shouldn't happen
+       * most of the time but it can if we have a partially populated
+       * pipeline cache.
+       */
+      assert(found < __builtin_popcount(pipeline->active_stages));
+
+      vk_debug_report(&pipeline->device->instance->debug_report_callbacks,
+                      VK_DEBUG_REPORT_WARNING_BIT_EXT |
+                      VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
+                      VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT,
+                      (uint64_t)(uintptr_t)cache,
+                      0, 0, "anv",
+                      "Found a partial pipeline in the cache.  This is "
+                      "most likely caused by an incomplete pipeline cache "
+                      "import or export");
+
+      /* We're going to have to recompile anyway, so just throw away our
+       * references to the shaders in the cache.  We'll get them out of the
+       * cache again as part of the compilation process.
+       */
+      for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) {
+         if (pipeline->shaders[s]) {
+            anv_shader_bin_unref(pipeline->device, pipeline->shaders[s]);
+            pipeline->shaders[s] = NULL;
+         }
+      }
    }
 
    for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) {
@@ -1086,9 +1121,7 @@ anv_pipeline_compile_graphics(struct anv_pipeline *pipeline,
          continue;
 
       assert(stages[s].stage == s);
-
-      if (pipeline->shaders[s])
-         continue;
+      assert(pipeline->shaders[s] == NULL);
 
       switch (s) {
       case MESA_SHADER_VERTEX: