Feat[lwjgl]: standard Vulkan loader between OSMesa and LWJGL

This commit is contained in:
artdeell 2023-09-17 17:58:36 +03:00
parent 864b2bfb39
commit 96ccf71509
6 changed files with 34 additions and 10 deletions

View File

@ -1 +1 @@
1687078018167
1694961457757

View File

@ -3,13 +3,14 @@
//
#include <android/dlext.h>
#include <string.h>
#include <stdio.h>
// Silence the warnings about using reserved identifiers (we need to link to these to not pollute the global symtab)
//NOLINTBEGIN
__attribute__((weak)) void* __loader_android_dlopen_ext(const char* filename,
static void* (*android_dlopen_ext_p)(const char* filename,
int flags,
const android_dlextinfo* extinfo,
const void* caller_addr);
__attribute__((weak)) struct android_namespace_t* __loader_android_get_exported_namespace(const char* name);
static struct android_namespace_t* (*android_get_exported_namespace_p)(const char* name);
//NOLINTEND
static void* ready_handle;
@ -18,13 +19,16 @@ static const char *sphal_namespaces[3] = {
};
__attribute__((visibility("default"), used)) void app__pojav_linkerhook_pass_handle(void* data) {
__attribute__((visibility("default"), used)) void app__pojav_linkerhook_pass_handles(void* data, void* android_dlopen_ext,
void* android_get_exported_namespace) {
ready_handle = data;
android_dlopen_ext_p = android_dlopen_ext;
android_get_exported_namespace_p = android_get_exported_namespace;
}
__attribute__((visibility("default"), used)) void *android_dlopen_ext(const char *filename, int flags, const android_dlextinfo *extinfo) {
if(!strstr(filename, "vulkan."))
return __loader_android_dlopen_ext(filename, flags, extinfo, &android_dlopen_ext);
return android_dlopen_ext_p(filename, flags, extinfo, &android_dlopen_ext);
return ready_handle;
}
@ -32,15 +36,17 @@ __attribute__((visibility("default"), used)) void *android_load_sphal_library(co
if(strstr(filename, "vulkan.")) {
return ready_handle;
}
//printf("__loader_android_get_exported_namespace = %p\n__loader_android_dlopen_ext = %p\n", __loader_android_get_exported_namespace,
// __loader_android_dlopen_ext);
struct android_namespace_t* androidNamespace;
for(int i = 0; i < 3; i++) {
androidNamespace = __loader_android_get_exported_namespace(sphal_namespaces[i]);
androidNamespace = android_get_exported_namespace_p(sphal_namespaces[i]);
if(androidNamespace != NULL) break;
}
android_dlextinfo info;
info.flags = ANDROID_DLEXT_USE_NAMESPACE;
info.library_namespace = androidNamespace;
return __loader_android_dlopen_ext(filename, flags, &info, &android_dlopen_ext);
return android_dlopen_ext_p(filename, flags, &info, &android_dlopen_ext);
}
// This is done for older android versions which don't

View File

@ -164,13 +164,21 @@ void* load_turnip_vulkan() {
dlclose(linkerhook);
return NULL;
}
void (*linkerhook_set_data)(void*) = dlsym(linkerhook, "app__pojav_linkerhook_pass_handle");
if(linkerhook_set_data == NULL) {
void* dl_android = linker_ns_dlopen("libdl_android.so", RTLD_LOCAL | RTLD_LAZY);
if(dl_android == NULL) {
dlclose(linkerhook);
dlclose(turnip_driver_handle);
return NULL;
}
linkerhook_set_data(turnip_driver_handle);
void* android_get_exported_namespace = dlsym(dl_android, "android_get_exported_namespace");
void (*linkerhook_pass_handles)(void*, void*, void*) = dlsym(linkerhook, "app__pojav_linkerhook_pass_handles");
if(linkerhook_pass_handles == NULL || android_get_exported_namespace == NULL) {
dlclose(dl_android);
dlclose(linkerhook);
dlclose(turnip_driver_handle);
return NULL;
}
linkerhook_pass_handles(turnip_driver_handle, android_dlopen_ext, android_get_exported_namespace);
void* libvulkan = linker_ns_dlopen_unique(cache_dir, "libvulkan.so", RTLD_LOCAL | RTLD_NOW);
return libvulkan;
}
@ -329,6 +337,16 @@ EXTERNAL_API void* pojavCreateContext(void* contextSrc) {
abort();
}
EXTERNAL_API JNIEXPORT jlong JNICALL
Java_org_lwjgl_vulkan_VK_getVulkanDriverHandle(ABI_COMPAT JNIEnv *env, ABI_COMPAT jclass thiz) {
printf("EGLBridge: LWJGL-side Vulkan loader requested the Vulkan handle\n");
// The code below still uses the env var because
// 1. it's easier to do that
// 2. it won't break if something will try to load vulkan and osmesa simultaneously
if(getenv("VULKAN_PTR") == NULL) load_vulkan();
return strtoul(getenv("VULKAN_PTR"), NULL, 0x10);
}
EXTERNAL_API JNIEXPORT jlong JNICALL
Java_org_lwjgl_opengl_GL_getGraphicsBufferAddr(ABI_COMPAT JNIEnv *env, ABI_COMPAT jobject thiz) {
return (jlong) buf.bits;

Binary file not shown.