v3dv/pipeline_cache: add default pipeline cache

That it would be used as fallback. Three advantages:

  * Having a cache for user operations even if the user doesn't
    provide it.

  * Having a cache for internal operations. v3dv_meta_copy creates
    pipelines for some copy path, so it is interesting to have them
    cached.

  * Testing: so now the pipeline cache is tested by more CTS tests.

As any other pipeline cache, it can be disabled with the
V3DV_ENABLE_PIPELINE_CACHE. It was suggested that would make sense to
have a specific envvar for the default pipeline cache, but for now
just one envvar is enough.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
Alejandro Piñeiro
2020-07-22 02:08:06 +02:00
committed by Marge Bot
parent 48a64f28c2
commit 35381a4696
4 changed files with 64 additions and 27 deletions
+7
View File
@@ -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);
+14 -2
View File
@@ -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)
+32 -24
View File
@@ -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);
}
+11 -1
View File
@@ -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,