radv: add cache items to in memory cache when reading from disk

Otherwise we will leak them, load duplicates from disk rather
than memory and never write items loaded from disk to the apps
pipeline cache.

Fixes: fd24be134f 'radv: make use of on-disk cache'
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
This commit is contained in:
Timothy Arceri 2017-10-26 09:35:48 +11:00
parent 446c5726ec
commit 1e84e53712

View file

@ -172,86 +172,6 @@ radv_pipeline_cache_search(struct radv_pipeline_cache *cache,
return entry; return entry;
} }
bool
radv_create_shader_variants_from_pipeline_cache(struct radv_device *device,
struct radv_pipeline_cache *cache,
const unsigned char *sha1,
struct radv_shader_variant **variants)
{
struct cache_entry *entry;
if (!cache)
cache = device->mem_cache;
pthread_mutex_lock(&cache->mutex);
entry = radv_pipeline_cache_search_unlocked(cache, sha1);
if (!entry) {
/* Again, don't cache when we want debug info, since this isn't
* present in the cache. */
if (!device->physical_device->disk_cache ||
(device->instance->debug_flags & RADV_DEBUG_NO_CACHE) ||
device->keep_shader_info) {
pthread_mutex_unlock(&cache->mutex);
return false;
}
uint8_t disk_sha1[20];
disk_cache_compute_key(device->physical_device->disk_cache,
sha1, 20, disk_sha1);
entry = (struct cache_entry *)
disk_cache_get(device->physical_device->disk_cache,
disk_sha1, NULL);
if (!entry) {
pthread_mutex_unlock(&cache->mutex);
return false;
}
}
char *p = entry->code;
for(int i = 0; i < MESA_SHADER_STAGES; ++i) {
if (!entry->variants[i] && entry->code_sizes[i]) {
struct radv_shader_variant *variant;
struct cache_entry_variant_info info;
variant = calloc(1, sizeof(struct radv_shader_variant));
if (!variant) {
pthread_mutex_unlock(&cache->mutex);
return false;
}
memcpy(&info, p, sizeof(struct cache_entry_variant_info));
p += sizeof(struct cache_entry_variant_info);
variant->config = info.config;
variant->info = info.variant_info;
variant->rsrc1 = info.rsrc1;
variant->rsrc2 = info.rsrc2;
variant->code_size = entry->code_sizes[i];
variant->ref_count = 1;
void *ptr = radv_alloc_shader_memory(device, variant);
memcpy(ptr, p, entry->code_sizes[i]);
p += entry->code_sizes[i];
entry->variants[i] = variant;
} else if (entry->code_sizes[i]) {
p += sizeof(struct cache_entry_variant_info) + entry->code_sizes[i];
}
}
for (int i = 0; i < MESA_SHADER_STAGES; ++i)
if (entry->variants[i])
p_atomic_inc(&entry->variants[i]->ref_count);
memcpy(variants, entry->variants, sizeof(entry->variants));
pthread_mutex_unlock(&cache->mutex);
return true;
}
static void static void
radv_pipeline_cache_set_entry(struct radv_pipeline_cache *cache, radv_pipeline_cache_set_entry(struct radv_pipeline_cache *cache,
struct cache_entry *entry) struct cache_entry *entry)
@ -321,6 +241,87 @@ radv_pipeline_cache_add_entry(struct radv_pipeline_cache *cache,
radv_pipeline_cache_set_entry(cache, entry); radv_pipeline_cache_set_entry(cache, entry);
} }
bool
radv_create_shader_variants_from_pipeline_cache(struct radv_device *device,
struct radv_pipeline_cache *cache,
const unsigned char *sha1,
struct radv_shader_variant **variants)
{
struct cache_entry *entry;
if (!cache)
cache = device->mem_cache;
pthread_mutex_lock(&cache->mutex);
entry = radv_pipeline_cache_search_unlocked(cache, sha1);
if (!entry) {
/* Again, don't cache when we want debug info, since this isn't
* present in the cache. */
if (!device->physical_device->disk_cache ||
(device->instance->debug_flags & RADV_DEBUG_NO_CACHE) ||
device->keep_shader_info) {
pthread_mutex_unlock(&cache->mutex);
return false;
}
uint8_t disk_sha1[20];
disk_cache_compute_key(device->physical_device->disk_cache,
sha1, 20, disk_sha1);
entry = (struct cache_entry *)
disk_cache_get(device->physical_device->disk_cache,
disk_sha1, NULL);
if (!entry) {
pthread_mutex_unlock(&cache->mutex);
return false;
} else {
radv_pipeline_cache_add_entry(cache, entry);
}
}
char *p = entry->code;
for(int i = 0; i < MESA_SHADER_STAGES; ++i) {
if (!entry->variants[i] && entry->code_sizes[i]) {
struct radv_shader_variant *variant;
struct cache_entry_variant_info info;
variant = calloc(1, sizeof(struct radv_shader_variant));
if (!variant) {
pthread_mutex_unlock(&cache->mutex);
return false;
}
memcpy(&info, p, sizeof(struct cache_entry_variant_info));
p += sizeof(struct cache_entry_variant_info);
variant->config = info.config;
variant->info = info.variant_info;
variant->rsrc1 = info.rsrc1;
variant->rsrc2 = info.rsrc2;
variant->code_size = entry->code_sizes[i];
variant->ref_count = 1;
void *ptr = radv_alloc_shader_memory(device, variant);
memcpy(ptr, p, entry->code_sizes[i]);
p += entry->code_sizes[i];
entry->variants[i] = variant;
} else if (entry->code_sizes[i]) {
p += sizeof(struct cache_entry_variant_info) + entry->code_sizes[i];
}
}
for (int i = 0; i < MESA_SHADER_STAGES; ++i)
if (entry->variants[i])
p_atomic_inc(&entry->variants[i]->ref_count);
memcpy(variants, entry->variants, sizeof(entry->variants));
pthread_mutex_unlock(&cache->mutex);
return true;
}
void void
radv_pipeline_cache_insert_shaders(struct radv_device *device, radv_pipeline_cache_insert_shaders(struct radv_device *device,
struct radv_pipeline_cache *cache, struct radv_pipeline_cache *cache,