v3dv: add debug option to disable custom pipeline caches for meta operations

Included as a new option of the existing V3DV_ENABLE_PIPELINE_CACHE
environment variable.

Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29218>
This commit is contained in:
Alejandro Piñeiro 2024-05-15 12:16:47 +02:00
parent 795057d44e
commit 4f26303dbb
4 changed files with 100 additions and 69 deletions

View file

@ -560,33 +560,44 @@ v3dv_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
instance->vk.physical_devices.enumerate = enumerate_devices;
instance->vk.physical_devices.destroy = destroy_physical_device;
/* We start with the default values for the pipeline_cache envvars */
/* We start with the default values for the pipeline_cache envvars.
*
* FIXME: with so many options now, perhaps we could use parse_debug_string
*/
instance->pipeline_cache_enabled = true;
instance->default_pipeline_cache_enabled = true;
instance->meta_cache_enabled = true;
const char *pipeline_cache_str = getenv("V3DV_ENABLE_PIPELINE_CACHE");
if (pipeline_cache_str != NULL) {
if (strncmp(pipeline_cache_str, "full", 4) == 0) {
/* nothing to do, just to filter correct values */
} else if (strncmp(pipeline_cache_str, "no-default-cache", 16) == 0) {
instance->default_pipeline_cache_enabled = false;
} else if (strncmp(pipeline_cache_str, "no-meta-cache", 13) == 0) {
instance->meta_cache_enabled = false;
} else if (strncmp(pipeline_cache_str, "off", 3) == 0) {
instance->pipeline_cache_enabled = false;
instance->default_pipeline_cache_enabled = false;
instance->meta_cache_enabled = false;
} else {
fprintf(stderr, "Wrong value for envvar V3DV_ENABLE_PIPELINE_CACHE. "
"Allowed values are: full, no-default-cache, off\n");
"Allowed values are: full, no-default-cache, no-meta-cache, off\n");
}
}
if (instance->pipeline_cache_enabled == false) {
fprintf(stderr, "WARNING: v3dv pipeline cache is disabled. Performance "
"can be affected negatively\n");
} else {
if (instance->default_pipeline_cache_enabled == false) {
fprintf(stderr, "WARNING: default v3dv pipeline cache is disabled. "
"Performance can be affected negatively\n");
}
}
if (instance->default_pipeline_cache_enabled == false) {
fprintf(stderr, "WARNING: default v3dv pipeline cache is disabled. "
"Performance can be affected negatively\n");
}
if (instance->meta_cache_enabled == false) {
fprintf(stderr, "WARNING: custom pipeline cache for meta operations are disabled. "
"Performance can be affected negatively\n");
}
VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));

View file

@ -278,15 +278,16 @@ create_depth_clear_pipeline_layout(struct v3dv_device *device,
void
v3dv_meta_clear_init(struct v3dv_device *device)
{
device->meta.color_clear.cache =
_mesa_hash_table_create(NULL, u64_hash, u64_compare);
if (device->instance->meta_cache_enabled) {
device->meta.color_clear.cache =
_mesa_hash_table_create(NULL, u64_hash, u64_compare);
device->meta.depth_clear.cache =
_mesa_hash_table_create(NULL, u64_hash, u64_compare);
}
create_color_clear_pipeline_layout(device,
&device->meta.color_clear.p_layout);
device->meta.depth_clear.cache =
_mesa_hash_table_create(NULL, u64_hash, u64_compare);
create_depth_clear_pipeline_layout(device,
&device->meta.depth_clear.p_layout);
}
@ -296,23 +297,25 @@ v3dv_meta_clear_finish(struct v3dv_device *device)
{
VkDevice _device = v3dv_device_to_handle(device);
hash_table_foreach(device->meta.color_clear.cache, entry) {
struct v3dv_meta_color_clear_pipeline *item = entry->data;
destroy_color_clear_pipeline(_device, (uintptr_t)item, &device->vk.alloc);
if (device->instance->meta_cache_enabled) {
hash_table_foreach(device->meta.color_clear.cache, entry) {
struct v3dv_meta_color_clear_pipeline *item = entry->data;
destroy_color_clear_pipeline(_device, (uintptr_t)item, &device->vk.alloc);
}
_mesa_hash_table_destroy(device->meta.color_clear.cache, NULL);
hash_table_foreach(device->meta.depth_clear.cache, entry) {
struct v3dv_meta_depth_clear_pipeline *item = entry->data;
destroy_depth_clear_pipeline(_device, item, &device->vk.alloc);
}
_mesa_hash_table_destroy(device->meta.depth_clear.cache, NULL);
}
_mesa_hash_table_destroy(device->meta.color_clear.cache, NULL);
if (device->meta.color_clear.p_layout) {
v3dv_DestroyPipelineLayout(_device, device->meta.color_clear.p_layout,
&device->vk.alloc);
}
hash_table_foreach(device->meta.depth_clear.cache, entry) {
struct v3dv_meta_depth_clear_pipeline *item = entry->data;
destroy_depth_clear_pipeline(_device, item, &device->vk.alloc);
}
_mesa_hash_table_destroy(device->meta.depth_clear.cache, NULL);
if (device->meta.depth_clear.p_layout) {
v3dv_DestroyPipelineLayout(_device, device->meta.depth_clear.p_layout,
&device->vk.alloc);
@ -826,7 +829,8 @@ get_color_clear_pipeline(struct v3dv_device *device,
* vkQuake3, the fact that we are not caching here doesn't seem to have
* any significant impact in performance, so it might not be worth it.
*/
const bool can_cache_pipeline = (pass == NULL);
const bool can_cache_pipeline =
(pass == NULL) && (device->instance->meta_cache_enabled);
uint64_t key;
if (can_cache_pipeline) {
@ -924,15 +928,18 @@ get_depth_clear_pipeline(struct v3dv_device *device,
const VkFormat format = pass->attachments[attachment_idx].desc.format;
assert(vk_format_is_depth_or_stencil(format));
const uint64_t key =
get_depth_clear_pipeline_cache_key(aspects, format, samples, is_layered);
mtx_lock(&device->meta.mtx);
struct hash_entry *entry =
_mesa_hash_table_search(device->meta.depth_clear.cache, &key);
if (entry) {
mtx_unlock(&device->meta.mtx);
*pipeline = entry->data;
return VK_SUCCESS;
uint64_t key;
if (device->instance->meta_cache_enabled) {
key = get_depth_clear_pipeline_cache_key(aspects, format, samples,
is_layered);
mtx_lock(&device->meta.mtx);
struct hash_entry *entry =
_mesa_hash_table_search(device->meta.depth_clear.cache, &key);
if (entry) {
mtx_unlock(&device->meta.mtx);
*pipeline = entry->data;
return VK_SUCCESS;
}
}
*pipeline = vk_zalloc2(&device->vk.alloc, NULL, sizeof(**pipeline), 8,
@ -954,15 +961,18 @@ get_depth_clear_pipeline(struct v3dv_device *device,
if (result != VK_SUCCESS)
goto fail;
(*pipeline)->key = key;
_mesa_hash_table_insert(device->meta.depth_clear.cache,
&(*pipeline)->key, *pipeline);
if (device->instance->meta_cache_enabled) {
(*pipeline)->key = key;
_mesa_hash_table_insert(device->meta.depth_clear.cache,
&(*pipeline)->key, *pipeline);
mtx_unlock(&device->meta.mtx);
}
mtx_unlock(&device->meta.mtx);
return VK_SUCCESS;
fail:
mtx_unlock(&device->meta.mtx);
if (device->instance->meta_cache_enabled)
mtx_unlock(&device->meta.mtx);
VkDevice _device = v3dv_device_to_handle(device);
if (*pipeline) {

View file

@ -2433,17 +2433,19 @@ get_copy_texel_buffer_pipeline(
bool ok = true;
uint8_t key[V3DV_META_TEXEL_BUFFER_COPY_CACHE_KEY_SIZE];
get_texel_buffer_copy_pipeline_cache_key(format, cmask, cswizzle, is_layered,
key);
if (device->instance->meta_cache_enabled) {
get_texel_buffer_copy_pipeline_cache_key(format, cmask, cswizzle, is_layered,
key);
mtx_lock(&device->meta.mtx);
struct hash_entry *entry =
_mesa_hash_table_search(device->meta.texel_buffer_copy.cache[image_type],
key);
if (entry) {
mtx_unlock(&device->meta.mtx);
*pipeline = entry->data;
return true;
mtx_lock(&device->meta.mtx);
struct hash_entry *entry =
_mesa_hash_table_search(device->meta.texel_buffer_copy.cache[image_type],
key);
if (entry) {
mtx_unlock(&device->meta.mtx);
*pipeline = entry->data;
return true;
}
}
*pipeline = vk_zalloc2(&device->vk.alloc, NULL, sizeof(**pipeline), 8,
@ -2468,16 +2470,19 @@ get_copy_texel_buffer_pipeline(
if (!ok)
goto fail;
uint8_t *dupkey = malloc(V3DV_META_TEXEL_BUFFER_COPY_CACHE_KEY_SIZE);
memcpy(dupkey, key, V3DV_META_TEXEL_BUFFER_COPY_CACHE_KEY_SIZE);
_mesa_hash_table_insert(device->meta.texel_buffer_copy.cache[image_type],
dupkey, *pipeline);
if (device->instance->meta_cache_enabled) {
uint8_t *dupkey = malloc(V3DV_META_TEXEL_BUFFER_COPY_CACHE_KEY_SIZE);
memcpy(dupkey, key, V3DV_META_TEXEL_BUFFER_COPY_CACHE_KEY_SIZE);
_mesa_hash_table_insert(device->meta.texel_buffer_copy.cache[image_type],
dupkey, *pipeline);
mtx_unlock(&device->meta.mtx);
}
mtx_unlock(&device->meta.mtx);
return true;
fail:
mtx_unlock(&device->meta.mtx);
if (device->instance->meta_cache_enabled)
mtx_unlock(&device->meta.mtx);
VkDevice _device = v3dv_device_to_handle(device);
if (*pipeline) {
@ -4086,15 +4091,17 @@ get_blit_pipeline(struct v3dv_device *device,
bool ok = true;
uint8_t key[V3DV_META_BLIT_CACHE_KEY_SIZE];
get_blit_pipeline_cache_key(dst_format, src_format, cmask,
dst_samples, src_samples, key);
mtx_lock(&device->meta.mtx);
struct hash_entry *entry =
_mesa_hash_table_search(device->meta.blit.cache[src_type], &key);
if (entry) {
mtx_unlock(&device->meta.mtx);
*pipeline = entry->data;
return true;
if (device->instance->meta_cache_enabled) {
get_blit_pipeline_cache_key(dst_format, src_format, cmask,
dst_samples, src_samples, key);
mtx_lock(&device->meta.mtx);
struct hash_entry *entry =
_mesa_hash_table_search(device->meta.blit.cache[src_type], &key);
if (entry) {
mtx_unlock(&device->meta.mtx);
*pipeline = entry->data;
return true;
}
}
*pipeline = vk_zalloc2(&device->vk.alloc, NULL, sizeof(**pipeline), 8,
@ -4125,15 +4132,17 @@ get_blit_pipeline(struct v3dv_device *device,
if (!ok)
goto fail;
memcpy((*pipeline)->key, key, sizeof((*pipeline)->key));
_mesa_hash_table_insert(device->meta.blit.cache[src_type],
&(*pipeline)->key, *pipeline);
mtx_unlock(&device->meta.mtx);
if (device->instance->meta_cache_enabled) {
memcpy((*pipeline)->key, key, sizeof((*pipeline)->key));
_mesa_hash_table_insert(device->meta.blit.cache[src_type],
&(*pipeline)->key, *pipeline);
mtx_unlock(&device->meta.mtx);
}
return true;
fail:
mtx_unlock(&device->meta.mtx);
if (device->instance->meta_cache_enabled)
mtx_unlock(&device->meta.mtx);
VkDevice _device = v3dv_device_to_handle(device);
if (*pipeline) {

View file

@ -235,6 +235,7 @@ struct v3dv_instance {
bool pipeline_cache_enabled;
bool default_pipeline_cache_enabled;
bool meta_cache_enabled;
};
/* FIXME: In addition to tracking the last job submitted by GPU queue (cl, csd,