mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Port hakuX Vulkan pipeline cache save throttling
This commit is contained in:
@@ -19,7 +19,9 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/fast-hash.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "renderer.h"
|
||||
#include "ui/xemu-settings.h"
|
||||
#include "hw/xbox/nv2a/pgraph/prim_rewrite.h"
|
||||
#include <math.h>
|
||||
#ifdef __aarch64__
|
||||
@@ -107,6 +109,8 @@ static bool pipeline_cache_entry_compare(Lru *lru, LruNode *node,
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#define PIPELINE_CACHE_SAVE_INTERVAL_US (30 * 1000000LL)
|
||||
|
||||
static char *get_pipeline_cache_path(PGRAPHVkState *r)
|
||||
{
|
||||
char *pref_path = SDL_GetPrefPath("xemu", "xemu");
|
||||
@@ -120,6 +124,62 @@ static char *get_pipeline_cache_path(PGRAPHVkState *r)
|
||||
SDL_free(pref_path);
|
||||
return path;
|
||||
}
|
||||
|
||||
static void save_pipeline_cache_to_disk(PGRAPHVkState *r)
|
||||
{
|
||||
g_autofree char *cache_path = get_pipeline_cache_path(r);
|
||||
size_t data_size = 0;
|
||||
VkResult res;
|
||||
|
||||
if (!cache_path) {
|
||||
return;
|
||||
}
|
||||
|
||||
res = vkGetPipelineCacheData(r->device, r->vk_pipeline_cache,
|
||||
&data_size, NULL);
|
||||
if (res != VK_SUCCESS || data_size == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_autofree void *data = g_malloc(data_size);
|
||||
res = vkGetPipelineCacheData(r->device, r->vk_pipeline_cache,
|
||||
&data_size, data);
|
||||
if (res != VK_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
GError *err = NULL;
|
||||
if (g_file_set_contents(cache_path, (const gchar *)data,
|
||||
(gssize)data_size, &err)) {
|
||||
__android_log_print(ANDROID_LOG_INFO, "xemu-vk",
|
||||
"Saved pipeline cache: %zu bytes", data_size);
|
||||
} else {
|
||||
__android_log_print(ANDROID_LOG_WARN, "xemu-vk",
|
||||
"Failed to save pipeline cache");
|
||||
if (err) {
|
||||
g_error_free(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void maybe_save_pipeline_cache(PGRAPHVkState *r)
|
||||
{
|
||||
int64_t now;
|
||||
|
||||
if (!g_config.perf.cache_shaders) {
|
||||
return;
|
||||
}
|
||||
|
||||
now = qemu_clock_get_us(QEMU_CLOCK_REALTIME);
|
||||
if (r->pipeline_cache_last_save_us != 0 &&
|
||||
(now - r->pipeline_cache_last_save_us) <
|
||||
PIPELINE_CACHE_SAVE_INTERVAL_US) {
|
||||
return;
|
||||
}
|
||||
|
||||
r->pipeline_cache_last_save_us = now;
|
||||
save_pipeline_cache_to_disk(r);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void init_pipeline_cache(PGRAPHState *pg)
|
||||
@@ -135,19 +195,23 @@ static void init_pipeline_cache(PGRAPHState *pg)
|
||||
};
|
||||
|
||||
#ifdef __ANDROID__
|
||||
g_autofree char *cache_path = get_pipeline_cache_path(r);
|
||||
gchar *cache_data = NULL;
|
||||
g_autofree gchar *cache_data = NULL;
|
||||
gsize cache_data_size = 0;
|
||||
if (cache_path) {
|
||||
GError *err = NULL;
|
||||
if (g_file_get_contents(cache_path, &cache_data, &cache_data_size, &err)) {
|
||||
cache_info.initialDataSize = (size_t)cache_data_size;
|
||||
cache_info.pInitialData = (const void *)cache_data;
|
||||
__android_log_print(ANDROID_LOG_INFO, "xemu-vk",
|
||||
"Loaded pipeline cache: %zu bytes", cache_data_size);
|
||||
} else {
|
||||
if (err) {
|
||||
g_error_free(err);
|
||||
if (g_config.perf.cache_shaders) {
|
||||
g_autofree char *cache_path = get_pipeline_cache_path(r);
|
||||
if (cache_path) {
|
||||
GError *err = NULL;
|
||||
if (g_file_get_contents(cache_path, &cache_data, &cache_data_size,
|
||||
&err)) {
|
||||
cache_info.initialDataSize = (size_t)cache_data_size;
|
||||
cache_info.pInitialData = (const void *)cache_data;
|
||||
__android_log_print(ANDROID_LOG_INFO, "xemu-vk",
|
||||
"Loaded pipeline cache: %zu bytes",
|
||||
cache_data_size);
|
||||
} else {
|
||||
if (err) {
|
||||
g_error_free(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,10 +220,6 @@ static void init_pipeline_cache(PGRAPHState *pg)
|
||||
VK_CHECK(vkCreatePipelineCache(r->device, &cache_info, NULL,
|
||||
&r->vk_pipeline_cache));
|
||||
|
||||
#ifdef __ANDROID__
|
||||
g_free(cache_data);
|
||||
#endif
|
||||
|
||||
const size_t pipeline_cache_size = 2048;
|
||||
lru_init(&r->pipeline_cache);
|
||||
r->pipeline_cache_entries =
|
||||
@@ -178,38 +238,16 @@ static void finalize_pipeline_cache(PGRAPHState *pg)
|
||||
{
|
||||
PGRAPHVkState *r = pg->vk_renderer_state;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
if (g_config.perf.cache_shaders) {
|
||||
save_pipeline_cache_to_disk(r);
|
||||
}
|
||||
#endif
|
||||
|
||||
lru_flush(&r->pipeline_cache);
|
||||
g_free(r->pipeline_cache_entries);
|
||||
r->pipeline_cache_entries = NULL;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
g_autofree char *cache_path = get_pipeline_cache_path(r);
|
||||
if (cache_path) {
|
||||
size_t data_size = 0;
|
||||
VkResult res = vkGetPipelineCacheData(r->device, r->vk_pipeline_cache,
|
||||
&data_size, NULL);
|
||||
if (res == VK_SUCCESS && data_size > 0) {
|
||||
g_autofree void *data = g_malloc(data_size);
|
||||
res = vkGetPipelineCacheData(r->device, r->vk_pipeline_cache,
|
||||
&data_size, data);
|
||||
if (res == VK_SUCCESS) {
|
||||
GError *err = NULL;
|
||||
if (g_file_set_contents(cache_path, (const gchar *)data,
|
||||
(gssize)data_size, &err)) {
|
||||
__android_log_print(ANDROID_LOG_INFO, "xemu-vk",
|
||||
"Saved pipeline cache: %zu bytes", data_size);
|
||||
} else {
|
||||
__android_log_print(ANDROID_LOG_WARN, "xemu-vk",
|
||||
"Failed to save pipeline cache");
|
||||
if (err) {
|
||||
g_error_free(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
vkDestroyPipelineCache(r->device, r->vk_pipeline_cache, NULL);
|
||||
}
|
||||
|
||||
@@ -661,6 +699,9 @@ static void create_clear_pipeline(PGRAPHState *pg)
|
||||
r->pipeline_binding = snode;
|
||||
r->pipeline_binding_changed = true;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
maybe_save_pipeline_cache(r);
|
||||
#endif
|
||||
NV2A_VK_DGROUP_END();
|
||||
}
|
||||
|
||||
@@ -1077,6 +1118,9 @@ static void create_pipeline(PGRAPHState *pg)
|
||||
r->pipeline_binding = snode;
|
||||
r->pipeline_binding_changed = true;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
maybe_save_pipeline_cache(r);
|
||||
#endif
|
||||
NV2A_VK_DGROUP_END();
|
||||
}
|
||||
|
||||
|
||||
@@ -364,6 +364,7 @@ typedef struct PGRAPHVkState {
|
||||
PipelineBinding *pipeline_cache_entries;
|
||||
PipelineBinding *pipeline_binding;
|
||||
bool pipeline_binding_changed;
|
||||
int64_t pipeline_cache_last_save_us;
|
||||
|
||||
VkDescriptorPool descriptor_pool;
|
||||
VkDescriptorSetLayout descriptor_set_layout;
|
||||
|
||||
Reference in New Issue
Block a user