better performance

This commit is contained in:
izzy2lost
2026-02-25 06:18:06 -05:00
parent 75cbe170f9
commit 7362cacd59
5 changed files with 94 additions and 11 deletions
+5 -1
View File
@@ -43,7 +43,11 @@ android {
"-DXEMU_ANDROID_BUILD_ID=3",
"-DXEMU_ENABLE_XISO_CONVERTER=ON",
"-DCMAKE_C_FLAGS_DEBUG=-O2 -g0",
"-DCMAKE_CXX_FLAGS_DEBUG=-O2 -g0"
"-DCMAKE_CXX_FLAGS_DEBUG=-O2 -g0",
"-DCMAKE_C_FLAGS_RELEASE=-O3 -g0 -march=armv8.2-a -ffunction-sections -fdata-sections",
"-DCMAKE_CXX_FLAGS_RELEASE=-O3 -g0 -march=armv8.2-a -ffunction-sections -fdata-sections",
"-DCMAKE_EXE_LINKER_FLAGS_RELEASE=-Wl,--gc-sections",
"-DCMAKE_SHARED_LINKER_FLAGS_RELEASE=-Wl,--gc-sections"
)
cppFlags += listOf("-std=c++17", "-fexceptions", "-frtti")
}
+2
View File
@@ -844,6 +844,7 @@ target_compile_definitions(xemu_core PRIVATE
target_compile_options(xemu_core PRIVATE -g0
$<$<OR:$<CONFIG:Release>,$<CONFIG:RelWithDebInfo>,$<CONFIG:MinSizeRel>>:-UNDEBUG>
$<$<CONFIG:Release>:-O3 -march=armv8.2-a -ffunction-sections -fdata-sections>
)
target_include_directories(xemu_core PRIVATE
@@ -913,6 +914,7 @@ endif()
target_compile_options(xemu PRIVATE -fexceptions -frtti -g0
$<$<OR:$<CONFIG:Release>,$<CONFIG:RelWithDebInfo>,$<CONFIG:MinSizeRel>>:-UNDEBUG>
$<$<CONFIG:Release>:-O3 -march=armv8.2-a -ffunction-sections -fdata-sections>
)
target_include_directories(xemu PRIVATE
+72
View File
@@ -22,6 +22,10 @@
#include "renderer.h"
#include "hw/xbox/nv2a/pgraph/prim_rewrite.h"
#include <math.h>
#ifdef __ANDROID__
#include <SDL.h>
#include <android/log.h>
#endif
void pgraph_vk_draw_begin(NV2AState *d)
{
@@ -99,6 +103,22 @@ static bool pipeline_cache_entry_compare(Lru *lru, LruNode *node,
return memcmp(&snode->key, key, sizeof(PipelineKey));
}
#ifdef __ANDROID__
static char *get_pipeline_cache_path(PGRAPHVkState *r)
{
char *pref_path = SDL_GetPrefPath("xemu", "xemu");
if (!pref_path) {
return NULL;
}
char *path = g_strdup_printf("%svk_pipeline_cache_%08x_%08x.bin",
pref_path,
r->device_props.deviceID,
r->device_props.driverVersion);
SDL_free(pref_path);
return path;
}
#endif
static void init_pipeline_cache(PGRAPHState *pg)
{
PGRAPHVkState *r = pg->vk_renderer_state;
@@ -110,9 +130,33 @@ static void init_pipeline_cache(PGRAPHState *pg)
.pInitialData = NULL,
.pNext = NULL,
};
#ifdef __ANDROID__
g_autofree char *cache_path = get_pipeline_cache_path(r);
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);
}
}
}
#endif
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 =
@@ -135,6 +179,34 @@ static void finalize_pipeline_cache(PGRAPHState *pg)
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);
}
+6 -7
View File
@@ -498,15 +498,14 @@ void pgraph_vk_wait_for_surface_download(SurfaceBinding *surface)
NV2AState *d = g_nv2a;
bool require_download = qatomic_read(&surface->draw_dirty);
#ifdef __ANDROID__
/*
* Android Vulkan currently presents through the CPU/VGA fallback path.
* Force framebuffer surface download so fallback upload sees fresh pixels.
* Android presents through the CPU/VGA fallback path (no external memory
* interop). We rely on draw_dirty to gate downloads: it is set atomically
* whenever the Vulkan renderer draws to this surface and cleared after each
* successful download. Skipping the download when draw_dirty is false
* avoids a GPU stall on frames where the Xbox GPU has not redrawn the
* framebuffer (static screens, menus, load screens, etc.).
*/
if (!d->pgraph.vk_renderer_state->display.use_external_memory) {
require_download = true;
}
#endif
if (require_download) {
qemu_mutex_lock(&d->pfifo.lock);
+9 -3
View File
@@ -1381,7 +1381,7 @@ void xemu_android_display_loop(void)
sdl2_poll_events(&sdl2_console[0]);
bql_unlock();
qemu_mutex_unlock_main_loop();
SDL_Delay(16);
SDL_Delay(100);
continue;
}
sdl2_gl_refresh(&sdl2_console[0].dcl);
@@ -1570,7 +1570,7 @@ void sdl2_gl_refresh(DisplayChangeListener *dcl)
sdl2_poll_events(scon);
bql_unlock();
qemu_mutex_unlock_main_loop();
SDL_Delay(16);
SDL_Delay(100);
return;
}
#endif
@@ -1776,7 +1776,11 @@ void sdl2_gl_refresh(DisplayChangeListener *dcl)
bql_unlock();
qemu_mutex_unlock_main_loop();
#ifdef __ANDROID__
glFlush();
#else
glFinish();
#endif
nv2a_release_framebuffer_surface();
#ifdef __ANDROID__
android_log_gl_error("refresh-finish");
@@ -1807,7 +1811,9 @@ void sdl2_gl_refresh(DisplayChangeListener *dcl)
int64_t spin_acc = 0;
#endif
#ifndef _WIN32
#ifdef __ANDROID__
const int64_t sleep_threshold = 500000; // 0.5ms — Android CFS scheduler jitter is ~0.2ms
#elif !defined(_WIN32)
const int64_t sleep_threshold = 2000000;
#else
const int64_t sleep_threshold = 250000;