[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