mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 15:20:10 +01:00
radv: fix caching on-demand meta shaders
This switches to disk_cache instead of our own mechanism which only stored meta shaders when the logical was destroyed. Meta shaders are still stored separately from the application shaders because they are common to all applications on a given GPU/Mesa version. The default cache is 32MiB which should be large enough. This fixes massive stuttering in FF7 Rebirth but all apps are technically affected. Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33370>
This commit is contained in:
parent
9d03c1afe0
commit
4fc856af98
3 changed files with 12 additions and 126 deletions
|
|
@ -13,13 +13,6 @@
|
|||
#include "vk_pipeline_cache.h"
|
||||
#include "vk_util.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#ifndef _WIN32
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
|
||||
static void
|
||||
radv_suspend_queries(struct radv_meta_saved_state *state, struct radv_cmd_buffer *cmd_buffer)
|
||||
{
|
||||
|
|
@ -292,54 +285,11 @@ meta_free(void *_device, void *data)
|
|||
device->vk.alloc.pfnFree(device->vk.alloc.pUserData, data);
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
static bool
|
||||
radv_builtin_cache_path(char *path)
|
||||
{
|
||||
char *xdg_cache_home = secure_getenv("XDG_CACHE_HOME");
|
||||
const char *suffix = "/radv_builtin_shaders";
|
||||
const char *suffix2 = "/.cache/radv_builtin_shaders";
|
||||
struct passwd pwd, *result;
|
||||
char path2[PATH_MAX + 1]; /* PATH_MAX is not a real max,but suffices here. */
|
||||
int ret;
|
||||
|
||||
if (xdg_cache_home) {
|
||||
ret = snprintf(path, PATH_MAX + 1, "%s%s%zd", xdg_cache_home, suffix, sizeof(void *) * 8);
|
||||
return ret > 0 && ret < PATH_MAX + 1;
|
||||
}
|
||||
|
||||
getpwuid_r(getuid(), &pwd, path2, PATH_MAX - strlen(suffix2), &result);
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
strcpy(path, pwd.pw_dir);
|
||||
strcat(path, "/.cache");
|
||||
if (mkdir(path, 0755) && errno != EEXIST)
|
||||
return false;
|
||||
|
||||
ret = snprintf(path, PATH_MAX + 1, "%s%s%zd", pwd.pw_dir, suffix2, sizeof(void *) * 8);
|
||||
return ret > 0 && ret < PATH_MAX + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint32_t
|
||||
num_cache_entries(VkPipelineCache cache)
|
||||
{
|
||||
struct set *s = vk_pipeline_cache_from_handle(cache)->object_cache;
|
||||
if (!s)
|
||||
return 0;
|
||||
return s->entries;
|
||||
}
|
||||
|
||||
static void
|
||||
radv_load_meta_pipeline(struct radv_device *device)
|
||||
radv_init_meta_cache(struct radv_device *device)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
char path[PATH_MAX + 1];
|
||||
struct stat st;
|
||||
void *data = NULL;
|
||||
int fd = -1;
|
||||
struct vk_pipeline_cache *cache = NULL;
|
||||
const struct radv_physical_device *pdev = radv_device_physical(device);
|
||||
struct vk_pipeline_cache *cache;
|
||||
|
||||
VkPipelineCacheCreateInfo create_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
|
||||
|
|
@ -347,81 +297,12 @@ radv_load_meta_pipeline(struct radv_device *device)
|
|||
|
||||
struct vk_pipeline_cache_create_info info = {
|
||||
.pCreateInfo = &create_info,
|
||||
.skip_disk_cache = true,
|
||||
.disk_cache = pdev->disk_cache_meta,
|
||||
};
|
||||
|
||||
if (!radv_builtin_cache_path(path))
|
||||
goto fail;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
goto fail;
|
||||
if (fstat(fd, &st))
|
||||
goto fail;
|
||||
data = malloc(st.st_size);
|
||||
if (!data)
|
||||
goto fail;
|
||||
if (read(fd, data, st.st_size) == -1)
|
||||
goto fail;
|
||||
|
||||
create_info.initialDataSize = st.st_size;
|
||||
create_info.pInitialData = data;
|
||||
|
||||
fail:
|
||||
cache = vk_pipeline_cache_create(&device->vk, &info, NULL);
|
||||
|
||||
if (cache) {
|
||||
if (cache)
|
||||
device->meta_state.cache = vk_pipeline_cache_to_handle(cache);
|
||||
device->meta_state.initial_cache_entries = num_cache_entries(device->meta_state.cache);
|
||||
}
|
||||
|
||||
free(data);
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
radv_store_meta_pipeline(struct radv_device *device)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
char path[PATH_MAX + 1], path2[PATH_MAX + 7];
|
||||
size_t size;
|
||||
void *data = NULL;
|
||||
|
||||
if (device->meta_state.cache == VK_NULL_HANDLE)
|
||||
return;
|
||||
|
||||
/* Skip serialization if no entries were added. */
|
||||
if (num_cache_entries(device->meta_state.cache) <= device->meta_state.initial_cache_entries)
|
||||
return;
|
||||
|
||||
if (vk_common_GetPipelineCacheData(radv_device_to_handle(device), device->meta_state.cache, &size, NULL))
|
||||
return;
|
||||
|
||||
if (!radv_builtin_cache_path(path))
|
||||
return;
|
||||
|
||||
strcpy(path2, path);
|
||||
strcat(path2, "XXXXXX");
|
||||
int fd = mkstemp(path2); // open(path, O_WRONLY | O_CREAT, 0600);
|
||||
if (fd < 0)
|
||||
return;
|
||||
data = malloc(size);
|
||||
if (!data)
|
||||
goto fail;
|
||||
|
||||
if (vk_common_GetPipelineCacheData(radv_device_to_handle(device), device->meta_state.cache, &size, data))
|
||||
goto fail;
|
||||
if (write(fd, data, size) == -1)
|
||||
goto fail;
|
||||
|
||||
rename(path2, path);
|
||||
fail:
|
||||
free(data);
|
||||
close(fd);
|
||||
unlink(path2);
|
||||
#endif
|
||||
}
|
||||
|
||||
VkResult
|
||||
|
|
@ -439,7 +320,7 @@ radv_device_init_meta(struct radv_device *device)
|
|||
.pfnFree = meta_free,
|
||||
};
|
||||
|
||||
radv_load_meta_pipeline(device);
|
||||
radv_init_meta_cache(device);
|
||||
|
||||
result = vk_meta_device_init(&device->vk, &device->meta_state.device);
|
||||
if (result != VK_SUCCESS)
|
||||
|
|
@ -488,7 +369,6 @@ radv_device_finish_meta(struct radv_device *device)
|
|||
|
||||
radv_device_finish_accel_struct_build_state(device);
|
||||
|
||||
radv_store_meta_pipeline(device);
|
||||
vk_common_DestroyPipelineCache(radv_device_to_handle(device), device->meta_state.cache, NULL);
|
||||
mtx_destroy(&device->meta_state.mtx);
|
||||
|
||||
|
|
|
|||
|
|
@ -2253,6 +2253,8 @@ radv_physical_device_try_create(struct radv_instance *instance, drmDevicePtr drm
|
|||
mesa_bytes_to_hex(buf, pdev->cache_uuid, VK_UUID_SIZE);
|
||||
pdev->vk.disk_cache = disk_cache_create(pdev->name, buf, 0);
|
||||
|
||||
pdev->disk_cache_meta = disk_cache_create_custom(pdev->name, buf, 0, "radv_builtin_shaders", 1024 * 32 /* 32MiB */);
|
||||
|
||||
radv_get_physical_device_properties(pdev);
|
||||
|
||||
if ((instance->debug_flags & RADV_DEBUG_INFO))
|
||||
|
|
@ -2298,6 +2300,7 @@ radv_physical_device_try_create(struct radv_instance *instance, drmDevicePtr drm
|
|||
fail_perfcounters:
|
||||
ac_destroy_perfcounters(&pdev->ac_perfcounters);
|
||||
disk_cache_destroy(pdev->vk.disk_cache);
|
||||
disk_cache_destroy(pdev->disk_cache_meta);
|
||||
fail_wsi:
|
||||
if (pdev->addrlib)
|
||||
ac_addrlib_destroy(pdev->addrlib);
|
||||
|
|
@ -2365,6 +2368,7 @@ radv_physical_device_destroy(struct vk_physical_device *vk_device)
|
|||
ac_addrlib_destroy(pdev->addrlib);
|
||||
pdev->ws->destroy(pdev->ws);
|
||||
disk_cache_destroy(pdev->vk.disk_cache);
|
||||
disk_cache_destroy(pdev->disk_cache_meta);
|
||||
if (pdev->local_fd != -1)
|
||||
close(pdev->local_fd);
|
||||
if (pdev->master_fd != -1)
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ struct radv_physical_device {
|
|||
uint8_t device_uuid[VK_UUID_SIZE];
|
||||
uint8_t cache_uuid[VK_UUID_SIZE];
|
||||
|
||||
struct disk_cache *disk_cache_meta;
|
||||
|
||||
struct ac_addrlib *addrlib;
|
||||
|
||||
int local_fd;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue