[Mesa-dev] [PATCH 6/6] anv: Add support for the on-disk shader cache

Timothy Arceri tarceri at itsqueeze.com
Sat Jun 30 05:15:57 UTC 2018


Series:

Reviewed-by: Timothy Arceri <tarceri at itsqueeze.com>

On 30/06/18 13:44, Jason Ekstrand wrote:
> ---
>   src/intel/vulkan/anv_device.c         | 36 ++++++++++
>   src/intel/vulkan/anv_pipeline_cache.c | 98 ++++++++++++++++++++++++---
>   src/intel/vulkan/anv_private.h        |  3 +
>   3 files changed, 126 insertions(+), 11 deletions(-)
> 
> diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
> index a864c702c3f..ca6e1c0cace 100644
> --- a/src/intel/vulkan/anv_device.c
> +++ b/src/intel/vulkan/anv_device.c
> @@ -35,6 +35,7 @@
>   #include "util/strtod.h"
>   #include "util/debug.h"
>   #include "util/build_id.h"
> +#include "util/disk_cache.h"
>   #include "util/mesa-sha1.h"
>   #include "vk_util.h"
>   #include "common/gen_defines.h"
> @@ -233,6 +234,8 @@ anv_physical_device_init_uuids(struct anv_physical_device *device)
>                          "build-id too short.  It needs to be a SHA");
>      }
>   
> +   memcpy(device->driver_build_sha1, build_id_data(note), 20);
> +
>      struct mesa_sha1 sha1_ctx;
>      uint8_t sha1[20];
>      STATIC_ASSERT(VK_UUID_SIZE <= sizeof(sha1));
> @@ -271,6 +274,35 @@ anv_physical_device_init_uuids(struct anv_physical_device *device)
>      return VK_SUCCESS;
>   }
>   
> +static void
> +anv_physical_device_init_disk_cache(struct anv_physical_device *device)
> +{
> +#ifdef ENABLE_SHADER_CACHE
> +   char renderer[9];
> +   MAYBE_UNUSED int len = snprintf(renderer, sizeof(renderer), "anv_%04x",
> +                                   device->chipset_id);
> +   assert(len == sizeof(renderer) - 1);
> +
> +   char timestamp[41];
> +   _mesa_sha1_format(timestamp, device->driver_build_sha1);
> +
> +   device->disk_cache = disk_cache_create(renderer, timestamp, 0);
> +#else
> +   device->disk_cache = NULL;
> +#endif
> +}
> +
> +static void
> +anv_physical_device_free_disk_cache(struct anv_physical_device *device)
> +{
> +#ifdef ENABLE_SHADER_CACHE
> +   if (device->disk_cache)
> +      disk_cache_destroy(device->disk_cache);
> +#else
> +   assert(device->disk_cache == NULL);
> +#endif
> +}
> +
>   static VkResult
>   anv_physical_device_init(struct anv_physical_device *device,
>                            struct anv_instance *instance,
> @@ -442,6 +474,8 @@ anv_physical_device_init(struct anv_physical_device *device,
>      if (result != VK_SUCCESS)
>         goto fail;
>   
> +   anv_physical_device_init_disk_cache(device);
> +
>      if (instance->enabled_extensions.KHR_display) {
>         master_fd = open(primary_path, O_RDWR | O_CLOEXEC);
>         if (master_fd >= 0) {
> @@ -459,6 +493,7 @@ anv_physical_device_init(struct anv_physical_device *device,
>      result = anv_init_wsi(device);
>      if (result != VK_SUCCESS) {
>         ralloc_free(device->compiler);
> +      anv_physical_device_free_disk_cache(device);
>         goto fail;
>      }
>   
> @@ -481,6 +516,7 @@ static void
>   anv_physical_device_finish(struct anv_physical_device *device)
>   {
>      anv_finish_wsi(device);
> +   anv_physical_device_free_disk_cache(device);
>      ralloc_free(device->compiler);
>      close(device->local_fd);
>      if (device->master_fd >= 0)
> diff --git a/src/intel/vulkan/anv_pipeline_cache.c b/src/intel/vulkan/anv_pipeline_cache.c
> index e57cd1c75c6..d4c7262dc05 100644
> --- a/src/intel/vulkan/anv_pipeline_cache.c
> +++ b/src/intel/vulkan/anv_pipeline_cache.c
> @@ -24,6 +24,8 @@
>   #include "compiler/blob.h"
>   #include "util/hash_table.h"
>   #include "util/debug.h"
> +#include "util/disk_cache.h"
> +#include "util/mesa-sha1.h"
>   #include "anv_private.h"
>   
>   struct anv_shader_bin *
> @@ -280,6 +282,25 @@ anv_pipeline_cache_search(struct anv_pipeline_cache *cache,
>      return shader;
>   }
>   
> +static void
> +anv_pipeline_cache_add_shader_bin(struct anv_pipeline_cache *cache,
> +                                  struct anv_shader_bin *bin)
> +{
> +   if (!cache->cache)
> +      return;
> +
> +   pthread_mutex_lock(&cache->mutex);
> +
> +   struct hash_entry *entry = _mesa_hash_table_search(cache->cache, bin->key);
> +   if (entry == NULL) {
> +      /* Take a reference for the cache */
> +      anv_shader_bin_ref(bin);
> +      _mesa_hash_table_insert(cache->cache, bin->key, bin);
> +   }
> +
> +   pthread_mutex_unlock(&cache->mutex);
> +}
> +
>   static struct anv_shader_bin *
>   anv_pipeline_cache_add_shader_locked(struct anv_pipeline_cache *cache,
>                                        const void *key_data, uint32_t key_size,
> @@ -540,7 +561,38 @@ anv_device_search_for_kernel(struct anv_device *device,
>                                struct anv_pipeline_cache *cache,
>                                const void *key_data, uint32_t key_size)
>   {
> -   return cache ? anv_pipeline_cache_search(cache, key_data, key_size) : NULL;
> +   struct anv_shader_bin *bin;
> +
> +   if (cache) {
> +      bin = anv_pipeline_cache_search(cache, key_data, key_size);
> +      if (bin)
> +         return bin;
> +   }
> +
> +#ifdef ENABLE_SHADER_CACHE
> +   struct disk_cache *disk_cache = device->instance->physicalDevice.disk_cache;
> +   if (disk_cache) {
> +      cache_key cache_key;
> +      disk_cache_compute_key(disk_cache, key_data, key_size, cache_key);
> +
> +      size_t buffer_size;
> +      uint8_t *buffer = disk_cache_get(disk_cache, cache_key, &buffer_size);
> +      if (buffer) {
> +         struct blob_reader blob;
> +         blob_reader_init(&blob, buffer, buffer_size);
> +         bin = anv_shader_bin_create_from_blob(device, &blob);
> +         free(buffer);
> +
> +         if (bin) {
> +            if (cache)
> +               anv_pipeline_cache_add_shader_bin(cache, bin);
> +            return bin;
> +         }
> +      }
> +   }
> +#endif
> +
> +   return NULL;
>   }
>   
>   struct anv_shader_bin *
> @@ -554,17 +606,41 @@ anv_device_upload_kernel(struct anv_device *device,
>                            uint32_t prog_data_size,
>                            const struct anv_pipeline_bind_map *bind_map)
>   {
> +   struct anv_shader_bin *bin;
>      if (cache) {
> -      return anv_pipeline_cache_upload_kernel(cache, key_data, key_size,
> -                                              kernel_data, kernel_size,
> -                                              constant_data, constant_data_size,
> -                                              prog_data, prog_data_size,
> -                                              bind_map);
> +      bin = anv_pipeline_cache_upload_kernel(cache, key_data, key_size,
> +                                             kernel_data, kernel_size,
> +                                             constant_data, constant_data_size,
> +                                             prog_data, prog_data_size,
> +                                             bind_map);
>      } else {
> -      return anv_shader_bin_create(device, key_data, key_size,
> -                                   kernel_data, kernel_size,
> -                                   constant_data, constant_data_size,
> -                                   prog_data, prog_data_size,
> -                                   prog_data->param, bind_map);
> +      bin = anv_shader_bin_create(device, key_data, key_size,
> +                                  kernel_data, kernel_size,
> +                                  constant_data, constant_data_size,
> +                                  prog_data, prog_data_size,
> +                                  prog_data->param, bind_map);
>      }
> +
> +   if (bin == NULL)
> +      return NULL;
> +
> +#ifdef ENABLE_SHADER_CACHE
> +   struct disk_cache *disk_cache = device->instance->physicalDevice.disk_cache;
> +   if (disk_cache) {
> +      struct blob binary;
> +      blob_init(&binary);
> +      anv_shader_bin_write_to_blob(bin, &binary);
> +
> +      if (!binary.out_of_memory) {
> +         cache_key cache_key;
> +         disk_cache_compute_key(disk_cache, key_data, key_size, cache_key);
> +
> +         disk_cache_put(disk_cache, cache_key, binary.data, binary.size, NULL);
> +      }
> +
> +      blob_finish(&binary);
> +   }
> +#endif
> +
> +   return bin;
>   }
> diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
> index 1f1f9795cf3..4a26b1d3096 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -870,10 +870,13 @@ struct anv_physical_device {
>         struct anv_memory_heap                    heaps[VK_MAX_MEMORY_HEAPS];
>       } memory;
>   
> +    uint8_t                                     driver_build_sha1[20];
>       uint8_t                                     pipeline_cache_uuid[VK_UUID_SIZE];
>       uint8_t                                     driver_uuid[VK_UUID_SIZE];
>       uint8_t                                     device_uuid[VK_UUID_SIZE];
>   
> +    struct disk_cache *                         disk_cache;
> +
>       struct wsi_device                       wsi_device;
>       int                                         local_fd;
>       int                                         master_fd;
> 


More information about the mesa-dev mailing list