diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c index ac715908aee..7e819c5ca27 100644 --- a/src/broadcom/vulkan/v3dv_device.c +++ b/src/broadcom/vulkan/v3dv_device.c @@ -1393,6 +1393,8 @@ v3dv_CreateDevice(VkPhysicalDevice physicalDevice, init_device_dispatch(device); init_device_meta(device); v3dv_bo_cache_init(device); + v3dv_pipeline_cache_init(&device->default_pipeline_cache, device, + device->instance->pipeline_cache_enabled); *pDevice = v3dv_device_to_handle(device); @@ -1415,6 +1417,11 @@ v3dv_DestroyDevice(VkDevice _device, pthread_mutex_destroy(&device->mutex); drmSyncobjDestroy(device->render_fd, device->last_job_sync); destroy_device_meta(device); + v3dv_pipeline_cache_finish(&device->default_pipeline_cache); + + /* Bo cache should be removed the last, as any other object could be + * freeing their private bos + */ v3dv_bo_cache_destroy(device); vk_free2(&default_alloc, pAllocator, device); diff --git a/src/broadcom/vulkan/v3dv_pipeline.c b/src/broadcom/vulkan/v3dv_pipeline.c index d5cba455db4..b0afc29f835 100644 --- a/src/broadcom/vulkan/v3dv_pipeline.c +++ b/src/broadcom/vulkan/v3dv_pipeline.c @@ -1522,8 +1522,13 @@ v3dv_get_shader_variant(struct v3dv_pipeline_stage *p_stage, return entry->data; } - /* Now we search on the pipeline cache if available */ + /* Now we search on the pipeline cache if provided by the user, or the + * default one*/ struct v3dv_pipeline *pipeline = p_stage->pipeline; + struct v3dv_device *device = pipeline->device; + if (cache == NULL && device->instance->pipeline_cache_enabled) + cache = &device->default_pipeline_cache; + unsigned char variant_sha1[20]; pipeline_hash_variant(p_stage, key, key_size, variant_sha1); @@ -1541,7 +1546,6 @@ v3dv_get_shader_variant(struct v3dv_pipeline_stage *p_stage, /* If we don't find the variant in any cache, we compile one and add the * variant to the cache */ - struct v3dv_device *device = pipeline->device; struct v3dv_physical_device *physical_device = &pipeline->device->instance->physicalDevice; const struct v3d_compiler *compiler = physical_device->compiler; @@ -2849,6 +2853,10 @@ graphics_pipeline_create(VkDevice _device, struct v3dv_pipeline *pipeline; VkResult result; + /* Use the default pipeline cache if none is specified */ + if (cache == NULL && device->instance->pipeline_cache_enabled) + cache = &device->default_pipeline_cache; + pipeline = vk_zalloc2(&device->alloc, pAllocator, sizeof(*pipeline), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); if (pipeline == NULL) @@ -3000,6 +3008,10 @@ compute_pipeline_create(VkDevice _device, struct v3dv_pipeline *pipeline; VkResult result; + /* Use the default pipeline cache if none is specified */ + if (cache == NULL && device->instance->pipeline_cache_enabled) + cache = &device->default_pipeline_cache; + pipeline = vk_zalloc2(&device->alloc, pAllocator, sizeof(*pipeline), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); if (pipeline == NULL) diff --git a/src/broadcom/vulkan/v3dv_pipeline_cache.c b/src/broadcom/vulkan/v3dv_pipeline_cache.c index 0da690dfd34..d3a58c230a3 100644 --- a/src/broadcom/vulkan/v3dv_pipeline_cache.c +++ b/src/broadcom/vulkan/v3dv_pipeline_cache.c @@ -174,10 +174,10 @@ v3dv_pipeline_cache_search_for_nir(struct v3dv_pipeline *pipeline, return NULL; } -static void -pipeline_cache_init(struct v3dv_pipeline_cache *cache, - struct v3dv_device *device, - bool cache_enabled) +void +v3dv_pipeline_cache_init(struct v3dv_pipeline_cache *cache, + struct v3dv_device *device, + bool cache_enabled) { cache->_loader_data.loaderMagic = ICD_LOADER_MAGIC; @@ -208,7 +208,7 @@ v3dv_pipeline_cache_search_for_variant(struct v3dv_pipeline *pipeline, struct v3dv_pipeline_cache *cache, unsigned char sha1_key[20]) { - if (!cache || !cache->nir_cache) + if (!cache || !cache->variant_cache) return NULL; if (unlikely(dump_stats)) { @@ -443,8 +443,8 @@ v3dv_CreatePipelineCache(VkDevice _device, if (cache == NULL) return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); - pipeline_cache_init(cache, device, - device->instance->pipeline_cache_enabled); + v3dv_pipeline_cache_init(cache, device, + device->instance->pipeline_cache_enabled); if (pCreateInfo->initialDataSize > 0) { pipeline_cache_load(cache, @@ -457,6 +457,30 @@ v3dv_CreatePipelineCache(VkDevice _device, return VK_SUCCESS; } +void +v3dv_pipeline_cache_finish(struct v3dv_pipeline_cache *cache) +{ + pthread_mutex_destroy(&cache->mutex); + + if (cache->nir_cache) { + hash_table_foreach(cache->nir_cache, entry) + ralloc_free(entry->data); + + _mesa_hash_table_destroy(cache->nir_cache, NULL); + } + + if (cache->variant_cache) { + hash_table_foreach(cache->variant_cache, entry) { + struct v3dv_shader_variant *variant = entry->data; + if (variant) + v3dv_shader_variant_unref(cache->device, variant); + } + + _mesa_hash_table_destroy(cache->variant_cache, NULL); + + } +} + void v3dv_DestroyPipelineCache(VkDevice _device, VkPipelineCache _cache, @@ -468,23 +492,7 @@ v3dv_DestroyPipelineCache(VkDevice _device, if (!cache) return; - pthread_mutex_destroy(&cache->mutex); - - if (cache->nir_cache) { - hash_table_foreach(cache->nir_cache, entry) - ralloc_free(entry->data); - - _mesa_hash_table_destroy(cache->nir_cache, NULL); - - hash_table_foreach(cache->variant_cache, entry) { - struct v3dv_shader_variant *variant = entry->data; - if (variant) - v3dv_shader_variant_unref(device, variant); - } - - _mesa_hash_table_destroy(cache->variant_cache, NULL); - - } + v3dv_pipeline_cache_finish(cache); vk_free2(&device->alloc, pAllocator, cache); } diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h index 341aa6b8df9..4f0476f04d1 100644 --- a/src/broadcom/vulkan/v3dv_private.h +++ b/src/broadcom/vulkan/v3dv_private.h @@ -338,6 +338,8 @@ struct v3dv_device { uint32_t bo_size; uint32_t bo_count; + + struct v3dv_pipeline_cache default_pipeline_cache; }; struct v3dv_device_memory { @@ -1296,7 +1298,9 @@ struct v3dv_pipeline_stage { /* Cache with all the shader variants built for this pipeline. This one is * required over the pipeline cache because we still allow to create shader - * variants after Pipeline creation. + * variants after Pipeline creation. Note that it would be possible to + * remove it and rely completely on the default pipeline cache, but then, + * we would need to stop to support the envvar V3DV_ENABLE_PIPELINE_CACHE */ struct hash_table *cache; @@ -1806,6 +1810,12 @@ v3dv_immutable_samplers(const struct v3dv_descriptor_set_layout *set, return (const struct v3dv_sampler *) ((const char *) set + binding->immutable_samplers_offset); } +void v3dv_pipeline_cache_init(struct v3dv_pipeline_cache *cache, + struct v3dv_device *device, + bool cache_enabled); + +void v3dv_pipeline_cache_finish(struct v3dv_pipeline_cache *cache); + void v3dv_pipeline_cache_upload_nir(struct v3dv_pipeline *pipeline, struct v3dv_pipeline_cache *cache, nir_shader *nir,