summaryrefslogtreecommitdiffstats
path: root/src/intel/vulkan
diff options
context:
space:
mode:
Diffstat (limited to 'src/intel/vulkan')
-rw-r--r--src/intel/vulkan/anv_pipeline_cache.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/src/intel/vulkan/anv_pipeline_cache.c b/src/intel/vulkan/anv_pipeline_cache.c
index 3d2429a4e2a..f7a1e1c679a 100644
--- a/src/intel/vulkan/anv_pipeline_cache.c
+++ b/src/intel/vulkan/anv_pipeline_cache.c
@@ -116,11 +116,11 @@ anv_hash_shader(unsigned char *hash, const void *key, size_t key_size,
_mesa_sha1_final(ctx, hash);
}
-uint32_t
-anv_pipeline_cache_search(struct anv_pipeline_cache *cache,
- const unsigned char *sha1,
- const struct brw_stage_prog_data **prog_data,
- struct anv_pipeline_bind_map *map)
+static uint32_t
+anv_pipeline_cache_search_unlocked(struct anv_pipeline_cache *cache,
+ const unsigned char *sha1,
+ const struct brw_stage_prog_data **prog_data,
+ struct anv_pipeline_bind_map *map)
{
const uint32_t mask = cache->table_size - 1;
const uint32_t start = (*(uint32_t *) sha1);
@@ -152,7 +152,24 @@ anv_pipeline_cache_search(struct anv_pipeline_cache *cache,
}
}
- return NO_KERNEL;
+ unreachable("hash table should never be full");
+}
+
+uint32_t
+anv_pipeline_cache_search(struct anv_pipeline_cache *cache,
+ const unsigned char *sha1,
+ const struct brw_stage_prog_data **prog_data,
+ struct anv_pipeline_bind_map *map)
+{
+ uint32_t kernel;
+
+ pthread_mutex_lock(&cache->mutex);
+
+ kernel = anv_pipeline_cache_search_unlocked(cache, sha1, prog_data, map);
+
+ pthread_mutex_unlock(&cache->mutex);
+
+ return kernel;
}
static void
@@ -234,6 +251,19 @@ anv_pipeline_cache_upload_kernel(struct anv_pipeline_cache *cache,
struct anv_pipeline_bind_map *map)
{
pthread_mutex_lock(&cache->mutex);
+
+ /* Before uploading, check again that another thread didn't upload this
+ * shader while we were compiling it.
+ */
+ if (sha1) {
+ uint32_t cached_kernel =
+ anv_pipeline_cache_search_unlocked(cache, sha1, prog_data, map);
+ if (cached_kernel != NO_KERNEL) {
+ pthread_mutex_unlock(&cache->mutex);
+ return cached_kernel;
+ }
+ }
+
struct cache_entry *entry;
const uint32_t map_size =
@@ -270,7 +300,8 @@ anv_pipeline_cache_upload_kernel(struct anv_pipeline_cache *cache,
map->sampler_to_descriptor = p;
if (sha1 && env_var_as_boolean("ANV_ENABLE_PIPELINE_CACHE", false)) {
- assert(anv_pipeline_cache_search(cache, sha1, NULL, NULL) == NO_KERNEL);
+ assert(anv_pipeline_cache_search_unlocked(cache, sha1,
+ NULL, NULL) == NO_KERNEL);
memcpy(entry->sha1, sha1, sizeof(entry->sha1));
anv_pipeline_cache_add_entry(cache, entry, state.offset);