diff --git a/app_pojavlauncher/src/main/jni/Android.mk b/app_pojavlauncher/src/main/jni/Android.mk index 781da2e369..a712bf7cc6 100644 --- a/app_pojavlauncher/src/main/jni/Android.mk +++ b/app_pojavlauncher/src/main/jni/Android.mk @@ -50,9 +50,24 @@ LOCAL_SRC_FILES := \ environ/environ.c \ input_bridge_v3.c \ jre_launcher.c \ - utils.c + utils.c \ + driver_helper/nsbypass.c +ifeq ($(TARGET_ARCH_ABI),arm64-v8a) +LOCAL_CFLAGS += -DADRENO_POSSIBLE +LOCAL_LDLIBS += -lEGL -lGLESv2 +endif include $(BUILD_SHARED_LIBRARY) +#ifeq ($(TARGET_ARCH_ABI),arm64-v8a) +include $(CLEAR_VARS) +LOCAL_MODULE := linkerhook +LOCAL_SRC_FILES := driver_helper/hook.c +LOCAL_LDLIBS := -llog +LOCAL_LDFLAGS := -z global +include $(BUILD_SHARED_LIBRARY) +#endif + + include $(CLEAR_VARS) LOCAL_MODULE := istdio LOCAL_SHARED_LIBRARIES := xhook diff --git a/app_pojavlauncher/src/main/jni/Application.mk b/app_pojavlauncher/src/main/jni/Application.mk index ce2ec9f16c..9abb89c01a 100644 --- a/app_pojavlauncher/src/main/jni/Application.mk +++ b/app_pojavlauncher/src/main/jni/Application.mk @@ -1,4 +1,4 @@ # NDK_TOOLCHAIN_VERSION := 4.9 APP_PLATFORM := android-21 -APP_STL := system +APP_STL := c++_static # APP_ABI := armeabi-v7a arm64-v8a x86 x86_64 diff --git a/app_pojavlauncher/src/main/jni/ctxbridges/osmesa_loader.c b/app_pojavlauncher/src/main/jni/ctxbridges/osmesa_loader.c index c81c1977f7..906f761cff 100644 --- a/app_pojavlauncher/src/main/jni/ctxbridges/osmesa_loader.c +++ b/app_pojavlauncher/src/main/jni/ctxbridges/osmesa_loader.c @@ -5,18 +5,20 @@ #include #include #include "osmesa_loader.h" - +#include GLboolean (*OSMesaMakeCurrent_p) (OSMesaContext ctx, void *buffer, GLenum type, GLsizei width, GLsizei height); OSMesaContext (*OSMesaGetCurrentContext_p) (void); OSMesaContext (*OSMesaCreateContext_p) (GLenum format, OSMesaContext sharelist); void (*OSMesaDestroyContext_p) (OSMesaContext ctx); +void (*OSMesaFlushFrontbuffer_p) (); void (*OSMesaPixelStore_p) ( GLint pname, GLint value ); GLubyte* (*glGetString_p) (GLenum name); void (*glFinish_p) (void); void (*glClearColor_p) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); void (*glClear_p) (GLbitfield mask); void (*glReadPixels_p) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * data); +void (*glReadBuffer_p) (GLenum mode); void dlsym_OSMesa() { char* main_path = NULL; @@ -28,15 +30,20 @@ void dlsym_OSMesa() { void* dl_handle = NULL; dl_handle = dlopen(alt_path, RTLD_GLOBAL); if(dl_handle == NULL) dl_handle = dlopen(main_path, RTLD_GLOBAL); - if(dl_handle == NULL) abort(); + if(dl_handle == NULL) { + __android_log_print(ANDROID_LOG_INFO, "osmesa_loader", "failed to load OSMesa %s", dlerror()); + abort(); + } OSMesaMakeCurrent_p = dlsym(dl_handle, "OSMesaMakeCurrent"); OSMesaGetCurrentContext_p = dlsym(dl_handle,"OSMesaGetCurrentContext"); OSMesaCreateContext_p = dlsym(dl_handle, "OSMesaCreateContext"); OSMesaDestroyContext_p = dlsym(dl_handle, "OSMesaDestroyContext"); + OSMesaFlushFrontbuffer_p = dlsym(dl_handle, "OSMesaFlushFrontbuffer"); OSMesaPixelStore_p = dlsym(dl_handle,"OSMesaPixelStore"); glGetString_p = dlsym(dl_handle,"glGetString"); glClearColor_p = dlsym(dl_handle, "glClearColor"); glClear_p = dlsym(dl_handle,"glClear"); glFinish_p = dlsym(dl_handle,"glFinish"); glReadPixels_p = dlsym(dl_handle,"glReadPixels"); + glReadBuffer_p = dlsym(dl_handle, "glReadBuffer"); } \ No newline at end of file diff --git a/app_pojavlauncher/src/main/jni/ctxbridges/osmesa_loader.h b/app_pojavlauncher/src/main/jni/ctxbridges/osmesa_loader.h index 6cb76d25cc..6d5c0e3adc 100644 --- a/app_pojavlauncher/src/main/jni/ctxbridges/osmesa_loader.h +++ b/app_pojavlauncher/src/main/jni/ctxbridges/osmesa_loader.h @@ -12,11 +12,13 @@ extern GLboolean (*OSMesaMakeCurrent_p) (OSMesaContext ctx, void *buffer, GLenum extern OSMesaContext (*OSMesaGetCurrentContext_p) (void); extern OSMesaContext (*OSMesaCreateContext_p) (GLenum format, OSMesaContext sharelist); extern void (*OSMesaDestroyContext_p) (OSMesaContext ctx); +extern void (*OSMesaFlushFrontbuffer_p) (); extern void (*OSMesaPixelStore_p) ( GLint pname, GLint value ); extern GLubyte* (*glGetString_p) (GLenum name); extern void (*glFinish_p) (void); extern void (*glClearColor_p) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); extern void (*glClear_p) (GLbitfield mask); extern void (*glReadPixels_p) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * data); +extern void (*glReadBuffer_p) (GLenum mode); void dlsym_OSMesa(); #endif //POJAVLAUNCHER_OSMESA_LOADER_H diff --git a/app_pojavlauncher/src/main/jni/driver_helper/hook.c b/app_pojavlauncher/src/main/jni/driver_helper/hook.c new file mode 100644 index 0000000000..1a544d48cc --- /dev/null +++ b/app_pojavlauncher/src/main/jni/driver_helper/hook.c @@ -0,0 +1,43 @@ +// +// Created by maks on 05.06.2023. +// +#include +#include +#include + +typedef void* (*android_dlopen_ext_t)(const char *filename, int flags, const android_dlextinfo *extinfo); +typedef struct android_namespace_t* (*android_get_exported_namespace_t)(const char* name); + +static void* ready_handle; +static android_dlopen_ext_t original_func; +static android_get_exported_namespace_t android_get_exported_namespace; + +static const char *sphal_namespaces[3] = { + "sphal", "vendor", "default" +}; + + +__attribute__((visibility("default"))) void app__pojav_linkerhook_set_data(void* data, void* data1, void* data2) { + ready_handle = data; + original_func = data1; + android_get_exported_namespace = data2; +} + +__attribute__((visibility("default"))) void *android_dlopen_ext(const char *filename, int flags, const android_dlextinfo *extinfo) { + if(!strstr(filename, "vulkan.")) + return original_func(filename, flags, extinfo); + return ready_handle; +} + +__attribute__((visibility("default"))) void *android_load_sphal_library(const char *filename, int flags) { + if(strstr(filename, "vulkan.")) return ready_handle; + struct android_namespace_t* androidNamespace; + for(int i = 0; i < 3; i++) { + androidNamespace = android_get_exported_namespace(sphal_namespaces[i]); + if(androidNamespace != NULL) break; + } + android_dlextinfo info; + info.flags = ANDROID_DLEXT_USE_NAMESPACE; + info.library_namespace = androidNamespace; + return original_func(filename, flags, &info); +} \ No newline at end of file diff --git a/app_pojavlauncher/src/main/jni/driver_helper/nsbypass.c b/app_pojavlauncher/src/main/jni/driver_helper/nsbypass.c new file mode 100644 index 0000000000..e64a9e1ff1 --- /dev/null +++ b/app_pojavlauncher/src/main/jni/driver_helper/nsbypass.c @@ -0,0 +1,164 @@ +// +// Created by maks on 05.06.2023. +// +#include "nsbypass.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* upper 6 bits of an ARM64 instruction are the instruction name */ +#define OP_MS 0b11111100000000000000000000000000 +/* Branch Label instruction opcode and immediate mask */ +#define BL_OP 0b10010100000000000000000000000000 +#define BL_IM 0b00000011111111111111111111111111 +/* Library search path */ +#define SEARCH_PATH "/system/lib64" +#define ELF_EHDR Elf64_Ehdr +#define ELF_SHDR Elf64_Shdr +#define ELF_HALF Elf64_Half +#define ELF_XWORD Elf64_Xword +#define ELF_DYN Elf64_Dyn + +//#define ADRENO_POSSIBLE + +typedef void* (*loader_dlopen_t)(const char* filename, int flags, const void* caller_addr); + +typedef struct android_namespace_t* (*ld_android_create_namespace_t)( + const char* name, const char* ld_library_path, const char* default_library_path, uint64_t type, + const char* permitted_when_isolated_path, struct android_namespace_t* parent, const void* caller_addr); + +typedef struct android_namespace_t* (*ld_android_get_exported_namespace_t)(const char* name, const void* caller_addr); + +static ld_android_create_namespace_t android_create_namespace; +static ld_android_get_exported_namespace_t android_get_exported_namespace; +static struct android_namespace_t* namespace; + +struct android_namespace_t* local_android_create_namespace( + const char* name, const char* ld_library_path, const char* default_library_path, uint64_t type, + const char* permitted_when_isolated_path, struct android_namespace_t* parent) { + void* caller = __builtin_return_address(0); + return android_create_namespace(name, ld_library_path, default_library_path, type, permitted_when_isolated_path, parent, caller); +} + +struct android_namespace_t* ns_android_get_exported_namespace( + const char* name) { + void* caller = __builtin_return_address(0); + return android_get_exported_namespace(name, caller); +} + + +bool linker_ns_load(const char* lib_search_path) { +#ifndef ADRENO_POSSIBLE + return false; +#endif + uint32_t *dlext_bl_addr = (uint32_t*)&dlopen; + while((*dlext_bl_addr & OP_MS) != + BL_OP) dlext_bl_addr++; //walk through the function until we find the label that we need to go to + __android_log_print(ANDROID_LOG_INFO, "nsbypass", "found branch label: %u", *dlext_bl_addr); + loader_dlopen_t loader_dlopen; + loader_dlopen = (loader_dlopen_t)(((char *) dlext_bl_addr) + (*dlext_bl_addr & BL_IM)*4); + mprotect(loader_dlopen, PAGE_SIZE, PROT_WRITE | PROT_READ | PROT_EXEC); // reprotecting the function removes protection from indirect jumps + void* ld_android_handle = loader_dlopen("ld-android.so", RTLD_LAZY, &dlopen); + __android_log_print(ANDROID_LOG_INFO, "nsbypass", "ld-android.so handle: %p", ld_android_handle); + if(ld_android_handle == NULL) return false; + android_create_namespace = dlsym(ld_android_handle, "__loader_android_create_namespace"); + android_get_exported_namespace = dlsym(ld_android_handle, "__loader_android_get_exported_namespace"); + if(android_create_namespace == NULL || android_get_exported_namespace == NULL) { + dlclose(ld_android_handle); + return false; + } + char full_path[strlen(SEARCH_PATH) + strlen(lib_search_path) + 2 + 1]; + sprintf(full_path, "%s:%s", SEARCH_PATH, lib_search_path); + namespace = local_android_create_namespace("pojav-driver", + full_path, + full_path, + 3 /* TYPE_SHAFED | TYPE_ISOLATED */, + "/system/:/data/:/vendor/:/apex/", NULL); + return true; +} + +void* linker_ns_dlopen(const char* name, int flag) { +#ifndef ADRENO_POSSIBLE + return NULL; +#endif + android_dlextinfo dlextinfo; + dlextinfo.flags = ANDROID_DLEXT_USE_NAMESPACE; + dlextinfo.library_namespace = namespace; + return android_dlopen_ext(name, flag, &dlextinfo); +} + +bool patch_elf_soname(int patchfd, int realfd, uint16_t patchid) { + struct stat realstat; + if(fstat(realfd, &realstat)) return false; + if(ftruncate(patchfd, realstat.st_size) == -1) return false; + char* target = mmap(NULL, realstat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, patchfd, 0); + if(!target) return false; + if(read(realfd, target, realstat.st_size) != realstat.st_size) { + munmap(target, realstat.st_size); + return false; + } + close(realfd); + + + ELF_EHDR *ehdr = (ELF_EHDR*)target; + ELF_SHDR *shdr = (ELF_SHDR*)(target + ehdr->e_shoff); + for(ELF_HALF i = 0; i < ehdr->e_shnum; i++) { + ELF_SHDR *hdr = &shdr[i]; + if(hdr->sh_type == SHT_DYNAMIC) { + char* strtab = target + shdr[hdr->sh_link].sh_offset; + ELF_DYN *dynEntries = (ELF_DYN*)(target + hdr->sh_offset); + for(ELF_XWORD k = 0; k < (hdr->sh_size / hdr->sh_entsize);k++) { + ELF_DYN* dynEntry = &dynEntries[k]; + if(dynEntry->d_tag == DT_SONAME) { + char* soname = strtab + dynEntry->d_un.d_val; + char sprb[4]; + snprintf(sprb, 4, "%03x", patchid); + memcpy(soname, sprb, 3); + munmap(target, realstat.st_size); + return true; + } + } + } + } + return false; +} + +void* linker_ns_dlopen_unique(const char* tmpdir, const char* name, int flags) { +#ifndef ADRENO_POSSIBLE + return NULL; +#endif + char pathbuf[PATH_MAX]; + static uint16_t patch_id; + int patch_fd, real_fd; + snprintf(pathbuf,PATH_MAX,"%s/%d_p.so", tmpdir, patch_id); + patch_fd = open(pathbuf, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); + if(patch_fd == -1) return NULL; + snprintf(pathbuf,PATH_MAX,"%s/%s", SEARCH_PATH, name); + real_fd = open(pathbuf, O_RDONLY); + if(real_fd == -1) { + close(patch_fd); + return NULL; + } + if(!patch_elf_soname(patch_fd, real_fd, patch_id)) { + close(patch_fd); + close(real_fd); + return NULL; + } + android_dlextinfo extinfo; + extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE | ANDROID_DLEXT_USE_LIBRARY_FD; + extinfo.library_fd = patch_fd; + extinfo.library_namespace = namespace; + snprintf(pathbuf, PATH_MAX, "/proc/self/fd/%d", patch_fd); + return android_dlopen_ext(pathbuf, flags, &extinfo); +} \ No newline at end of file diff --git a/app_pojavlauncher/src/main/jni/driver_helper/nsbypass.h b/app_pojavlauncher/src/main/jni/driver_helper/nsbypass.h new file mode 100644 index 0000000000..1b59c8042f --- /dev/null +++ b/app_pojavlauncher/src/main/jni/driver_helper/nsbypass.h @@ -0,0 +1,15 @@ +// +// Created by maks on 05.06.2023. +// + +#ifndef POJAVLAUNCHER_NSBYPASS_H +#define POJAVLAUNCHER_NSBYPASS_H + +#include + +bool linker_ns_load(const char* lib_search_path); +void* linker_ns_dlopen(const char* name, int flag); +void* linker_ns_dlopen_unique(const char* tmpdir, const char* name, int flag); +struct android_namespace_t* ns_android_get_exported_namespace(const char*); + +#endif //POJAVLAUNCHER_NSBYPASS_H diff --git a/app_pojavlauncher/src/main/jni/egl_bridge.c b/app_pojavlauncher/src/main/jni/egl_bridge.c index e8eeb57733..7b37dedc61 100644 --- a/app_pojavlauncher/src/main/jni/egl_bridge.c +++ b/app_pojavlauncher/src/main/jni/egl_bridge.c @@ -11,6 +11,8 @@ #include #include +#include "ctxbridges/osmesa_loader.h" +#include "driver_helper/nsbypass.h" #ifdef GLES_TEST #include @@ -21,565 +23,9 @@ #include #include #include +#include #include "utils.h" #include "ctxbridges/gl_bridge.h" -// region OSMESA internals - -struct pipe_screen; - -//only get what we need to access/modify -struct st_manager -{ - struct pipe_screen *screen; -}; -struct st_context_iface -{ - void *st_context_private; -}; -struct zink_device_info -{ - bool have_EXT_conditional_rendering; - bool have_EXT_transform_feedback; -}; -struct zink_screen -{ - struct zink_device_info info; -}; - -enum st_attachment_type { - ST_ATTACHMENT_FRONT_LEFT, - ST_ATTACHMENT_BACK_LEFT, - ST_ATTACHMENT_FRONT_RIGHT, - ST_ATTACHMENT_BACK_RIGHT, - ST_ATTACHMENT_DEPTH_STENCIL, - ST_ATTACHMENT_ACCUM, - ST_ATTACHMENT_SAMPLE, - - ST_ATTACHMENT_COUNT, - ST_ATTACHMENT_INVALID = -1 -}; -enum pipe_format { - PIPE_FORMAT_NONE, - PIPE_FORMAT_B8G8R8A8_UNORM, - PIPE_FORMAT_B8G8R8X8_UNORM, - PIPE_FORMAT_A8R8G8B8_UNORM, - PIPE_FORMAT_X8R8G8B8_UNORM, - PIPE_FORMAT_B5G5R5A1_UNORM, - PIPE_FORMAT_R4G4B4A4_UNORM, - PIPE_FORMAT_B4G4R4A4_UNORM, - PIPE_FORMAT_R5G6B5_UNORM, - PIPE_FORMAT_B5G6R5_UNORM, - PIPE_FORMAT_R10G10B10A2_UNORM, - PIPE_FORMAT_L8_UNORM, /**< ubyte luminance */ - PIPE_FORMAT_A8_UNORM, /**< ubyte alpha */ - PIPE_FORMAT_I8_UNORM, /**< ubyte intensity */ - PIPE_FORMAT_L8A8_UNORM, /**< ubyte alpha, luminance */ - PIPE_FORMAT_L16_UNORM, /**< ushort luminance */ - PIPE_FORMAT_UYVY, - PIPE_FORMAT_YUYV, - PIPE_FORMAT_Z16_UNORM, - PIPE_FORMAT_Z16_UNORM_S8_UINT, - PIPE_FORMAT_Z32_UNORM, - PIPE_FORMAT_Z32_FLOAT, - PIPE_FORMAT_Z24_UNORM_S8_UINT, - PIPE_FORMAT_S8_UINT_Z24_UNORM, - PIPE_FORMAT_Z24X8_UNORM, - PIPE_FORMAT_X8Z24_UNORM, - PIPE_FORMAT_S8_UINT, /**< ubyte stencil */ - PIPE_FORMAT_R64_FLOAT, - PIPE_FORMAT_R64G64_FLOAT, - PIPE_FORMAT_R64G64B64_FLOAT, - PIPE_FORMAT_R64G64B64A64_FLOAT, - PIPE_FORMAT_R32_FLOAT, - PIPE_FORMAT_R32G32_FLOAT, - PIPE_FORMAT_R32G32B32_FLOAT, - PIPE_FORMAT_R32G32B32A32_FLOAT, - PIPE_FORMAT_R32_UNORM, - PIPE_FORMAT_R32G32_UNORM, - PIPE_FORMAT_R32G32B32_UNORM, - PIPE_FORMAT_R32G32B32A32_UNORM, - PIPE_FORMAT_R32_USCALED, - PIPE_FORMAT_R32G32_USCALED, - PIPE_FORMAT_R32G32B32_USCALED, - PIPE_FORMAT_R32G32B32A32_USCALED, - PIPE_FORMAT_R32_SNORM, - PIPE_FORMAT_R32G32_SNORM, - PIPE_FORMAT_R32G32B32_SNORM, - PIPE_FORMAT_R32G32B32A32_SNORM, - PIPE_FORMAT_R32_SSCALED, - PIPE_FORMAT_R32G32_SSCALED, - PIPE_FORMAT_R32G32B32_SSCALED, - PIPE_FORMAT_R32G32B32A32_SSCALED, - PIPE_FORMAT_R16_UNORM, - PIPE_FORMAT_R16G16_UNORM, - PIPE_FORMAT_R16G16B16_UNORM, - PIPE_FORMAT_R16G16B16A16_UNORM, - PIPE_FORMAT_R16_USCALED, - PIPE_FORMAT_R16G16_USCALED, - PIPE_FORMAT_R16G16B16_USCALED, - PIPE_FORMAT_R16G16B16A16_USCALED, - PIPE_FORMAT_R16_SNORM, - PIPE_FORMAT_R16G16_SNORM, - PIPE_FORMAT_R16G16B16_SNORM, - PIPE_FORMAT_R16G16B16A16_SNORM, - PIPE_FORMAT_R16_SSCALED, - PIPE_FORMAT_R16G16_SSCALED, - PIPE_FORMAT_R16G16B16_SSCALED, - PIPE_FORMAT_R16G16B16A16_SSCALED, - PIPE_FORMAT_R8_UNORM, - PIPE_FORMAT_R8G8_UNORM, - PIPE_FORMAT_R8G8B8_UNORM, - PIPE_FORMAT_B8G8R8_UNORM, - PIPE_FORMAT_R8G8B8A8_UNORM, - PIPE_FORMAT_X8B8G8R8_UNORM, - PIPE_FORMAT_R8_USCALED, - PIPE_FORMAT_R8G8_USCALED, - PIPE_FORMAT_R8G8B8_USCALED, - PIPE_FORMAT_B8G8R8_USCALED, - PIPE_FORMAT_R8G8B8A8_USCALED, - PIPE_FORMAT_B8G8R8A8_USCALED, - PIPE_FORMAT_A8B8G8R8_USCALED, - PIPE_FORMAT_R8_SNORM, - PIPE_FORMAT_R8G8_SNORM, - PIPE_FORMAT_R8G8B8_SNORM, - PIPE_FORMAT_B8G8R8_SNORM, - PIPE_FORMAT_R8G8B8A8_SNORM, - PIPE_FORMAT_B8G8R8A8_SNORM, - PIPE_FORMAT_R8_SSCALED, - PIPE_FORMAT_R8G8_SSCALED, - PIPE_FORMAT_R8G8B8_SSCALED, - PIPE_FORMAT_B8G8R8_SSCALED, - PIPE_FORMAT_R8G8B8A8_SSCALED, - PIPE_FORMAT_B8G8R8A8_SSCALED, - PIPE_FORMAT_A8B8G8R8_SSCALED, - PIPE_FORMAT_R32_FIXED, - PIPE_FORMAT_R32G32_FIXED, - PIPE_FORMAT_R32G32B32_FIXED, - PIPE_FORMAT_R32G32B32A32_FIXED, - PIPE_FORMAT_R16_FLOAT, - PIPE_FORMAT_R16G16_FLOAT, - PIPE_FORMAT_R16G16B16_FLOAT, - PIPE_FORMAT_R16G16B16A16_FLOAT, - - /* sRGB formats */ - PIPE_FORMAT_L8_SRGB, - PIPE_FORMAT_R8_SRGB, - PIPE_FORMAT_L8A8_SRGB, - PIPE_FORMAT_R8G8_SRGB, - PIPE_FORMAT_R8G8B8_SRGB, - PIPE_FORMAT_B8G8R8_SRGB, - PIPE_FORMAT_A8B8G8R8_SRGB, - PIPE_FORMAT_X8B8G8R8_SRGB, - PIPE_FORMAT_B8G8R8A8_SRGB, - PIPE_FORMAT_B8G8R8X8_SRGB, - PIPE_FORMAT_A8R8G8B8_SRGB, - PIPE_FORMAT_X8R8G8B8_SRGB, - PIPE_FORMAT_R8G8B8A8_SRGB, - - /* compressed formats */ - PIPE_FORMAT_DXT1_RGB, - PIPE_FORMAT_DXT1_RGBA, - PIPE_FORMAT_DXT3_RGBA, - PIPE_FORMAT_DXT5_RGBA, - - /* sRGB, compressed */ - PIPE_FORMAT_DXT1_SRGB, - PIPE_FORMAT_DXT1_SRGBA, - PIPE_FORMAT_DXT3_SRGBA, - PIPE_FORMAT_DXT5_SRGBA, - - /* rgtc compressed */ - PIPE_FORMAT_RGTC1_UNORM, - PIPE_FORMAT_RGTC1_SNORM, - PIPE_FORMAT_RGTC2_UNORM, - PIPE_FORMAT_RGTC2_SNORM, - - PIPE_FORMAT_R8G8_B8G8_UNORM, - PIPE_FORMAT_G8R8_G8B8_UNORM, - - /* mixed formats */ - PIPE_FORMAT_R8SG8SB8UX8U_NORM, - PIPE_FORMAT_R5SG5SB6U_NORM, - - /* TODO: re-order these */ - PIPE_FORMAT_A8B8G8R8_UNORM, - PIPE_FORMAT_B5G5R5X1_UNORM, - PIPE_FORMAT_R10G10B10A2_USCALED, - PIPE_FORMAT_R11G11B10_FLOAT, - PIPE_FORMAT_R9G9B9E5_FLOAT, - PIPE_FORMAT_Z32_FLOAT_S8X24_UINT, - PIPE_FORMAT_R1_UNORM, - PIPE_FORMAT_R10G10B10X2_USCALED, - PIPE_FORMAT_R10G10B10X2_SNORM, - PIPE_FORMAT_L4A4_UNORM, - PIPE_FORMAT_A2R10G10B10_UNORM, - PIPE_FORMAT_A2B10G10R10_UNORM, - PIPE_FORMAT_B10G10R10A2_UNORM, - PIPE_FORMAT_R10SG10SB10SA2U_NORM, - PIPE_FORMAT_R8G8Bx_SNORM, - PIPE_FORMAT_R8G8B8X8_UNORM, - PIPE_FORMAT_B4G4R4X4_UNORM, - - /* some stencil samplers formats */ - PIPE_FORMAT_X24S8_UINT, - PIPE_FORMAT_S8X24_UINT, - PIPE_FORMAT_X32_S8X24_UINT, - - PIPE_FORMAT_R3G3B2_UNORM, - PIPE_FORMAT_B2G3R3_UNORM, - PIPE_FORMAT_L16A16_UNORM, - PIPE_FORMAT_A16_UNORM, - PIPE_FORMAT_I16_UNORM, - - PIPE_FORMAT_LATC1_UNORM, - PIPE_FORMAT_LATC1_SNORM, - PIPE_FORMAT_LATC2_UNORM, - PIPE_FORMAT_LATC2_SNORM, - - PIPE_FORMAT_A8_SNORM, - PIPE_FORMAT_L8_SNORM, - PIPE_FORMAT_L8A8_SNORM, - PIPE_FORMAT_I8_SNORM, - PIPE_FORMAT_A16_SNORM, - PIPE_FORMAT_L16_SNORM, - PIPE_FORMAT_L16A16_SNORM, - PIPE_FORMAT_I16_SNORM, - - PIPE_FORMAT_A16_FLOAT, - PIPE_FORMAT_L16_FLOAT, - PIPE_FORMAT_L16A16_FLOAT, - PIPE_FORMAT_I16_FLOAT, - PIPE_FORMAT_A32_FLOAT, - PIPE_FORMAT_L32_FLOAT, - PIPE_FORMAT_L32A32_FLOAT, - PIPE_FORMAT_I32_FLOAT, - - PIPE_FORMAT_YV12, - PIPE_FORMAT_YV16, - PIPE_FORMAT_IYUV, /**< aka I420 */ - PIPE_FORMAT_NV12, - PIPE_FORMAT_NV21, - - /* PIPE_FORMAT_Y8_U8_V8_420_UNORM = IYUV */ - /* PIPE_FORMAT_Y8_U8V8_420_UNORM = NV12 */ - PIPE_FORMAT_Y8_U8_V8_422_UNORM, - PIPE_FORMAT_Y8_U8V8_422_UNORM, - PIPE_FORMAT_Y8_U8_V8_444_UNORM, - - PIPE_FORMAT_Y16_U16_V16_420_UNORM, - /* PIPE_FORMAT_Y16_U16V16_420_UNORM */ - PIPE_FORMAT_Y16_U16_V16_422_UNORM, - PIPE_FORMAT_Y16_U16V16_422_UNORM, - PIPE_FORMAT_Y16_U16_V16_444_UNORM, - - PIPE_FORMAT_A4R4_UNORM, - PIPE_FORMAT_R4A4_UNORM, - PIPE_FORMAT_R8A8_UNORM, - PIPE_FORMAT_A8R8_UNORM, - - PIPE_FORMAT_R10G10B10A2_SSCALED, - PIPE_FORMAT_R10G10B10A2_SNORM, - - PIPE_FORMAT_B10G10R10A2_USCALED, - PIPE_FORMAT_B10G10R10A2_SSCALED, - PIPE_FORMAT_B10G10R10A2_SNORM, - - PIPE_FORMAT_R8_UINT, - PIPE_FORMAT_R8G8_UINT, - PIPE_FORMAT_R8G8B8_UINT, - PIPE_FORMAT_R8G8B8A8_UINT, - - PIPE_FORMAT_R8_SINT, - PIPE_FORMAT_R8G8_SINT, - PIPE_FORMAT_R8G8B8_SINT, - PIPE_FORMAT_R8G8B8A8_SINT, - - PIPE_FORMAT_R16_UINT, - PIPE_FORMAT_R16G16_UINT, - PIPE_FORMAT_R16G16B16_UINT, - PIPE_FORMAT_R16G16B16A16_UINT, - - PIPE_FORMAT_R16_SINT, - PIPE_FORMAT_R16G16_SINT, - PIPE_FORMAT_R16G16B16_SINT, - PIPE_FORMAT_R16G16B16A16_SINT, - - PIPE_FORMAT_R32_UINT, - PIPE_FORMAT_R32G32_UINT, - PIPE_FORMAT_R32G32B32_UINT, - PIPE_FORMAT_R32G32B32A32_UINT, - - PIPE_FORMAT_R32_SINT, - PIPE_FORMAT_R32G32_SINT, - PIPE_FORMAT_R32G32B32_SINT, - PIPE_FORMAT_R32G32B32A32_SINT, - - PIPE_FORMAT_R64_UINT, - PIPE_FORMAT_R64_SINT, - - PIPE_FORMAT_A8_UINT, - PIPE_FORMAT_I8_UINT, - PIPE_FORMAT_L8_UINT, - PIPE_FORMAT_L8A8_UINT, - - PIPE_FORMAT_A8_SINT, - PIPE_FORMAT_I8_SINT, - PIPE_FORMAT_L8_SINT, - PIPE_FORMAT_L8A8_SINT, - - PIPE_FORMAT_A16_UINT, - PIPE_FORMAT_I16_UINT, - PIPE_FORMAT_L16_UINT, - PIPE_FORMAT_L16A16_UINT, - - PIPE_FORMAT_A16_SINT, - PIPE_FORMAT_I16_SINT, - PIPE_FORMAT_L16_SINT, - PIPE_FORMAT_L16A16_SINT, - - PIPE_FORMAT_A32_UINT, - PIPE_FORMAT_I32_UINT, - PIPE_FORMAT_L32_UINT, - PIPE_FORMAT_L32A32_UINT, - - PIPE_FORMAT_A32_SINT, - PIPE_FORMAT_I32_SINT, - PIPE_FORMAT_L32_SINT, - PIPE_FORMAT_L32A32_SINT, - - PIPE_FORMAT_B8G8R8_UINT, - PIPE_FORMAT_B8G8R8A8_UINT, - - PIPE_FORMAT_B8G8R8_SINT, - PIPE_FORMAT_B8G8R8A8_SINT, - - PIPE_FORMAT_A8R8G8B8_UINT, - PIPE_FORMAT_A8B8G8R8_UINT, - PIPE_FORMAT_A2R10G10B10_UINT, - PIPE_FORMAT_A2B10G10R10_UINT, - PIPE_FORMAT_B10G10R10A2_UINT, - PIPE_FORMAT_B10G10R10A2_SINT, - PIPE_FORMAT_R5G6B5_UINT, - PIPE_FORMAT_B5G6R5_UINT, - PIPE_FORMAT_R5G5B5A1_UINT, - PIPE_FORMAT_B5G5R5A1_UINT, - PIPE_FORMAT_A1R5G5B5_UINT, - PIPE_FORMAT_A1B5G5R5_UINT, - PIPE_FORMAT_R4G4B4A4_UINT, - PIPE_FORMAT_B4G4R4A4_UINT, - PIPE_FORMAT_A4R4G4B4_UINT, - PIPE_FORMAT_A4B4G4R4_UINT, - PIPE_FORMAT_R3G3B2_UINT, - PIPE_FORMAT_B2G3R3_UINT, - - PIPE_FORMAT_ETC1_RGB8, - - PIPE_FORMAT_R8G8_R8B8_UNORM, - PIPE_FORMAT_G8R8_B8R8_UNORM, - - PIPE_FORMAT_R8G8B8X8_SNORM, - PIPE_FORMAT_R8G8B8X8_SRGB, - PIPE_FORMAT_R8G8B8X8_UINT, - PIPE_FORMAT_R8G8B8X8_SINT, - PIPE_FORMAT_B10G10R10X2_UNORM, - PIPE_FORMAT_R16G16B16X16_UNORM, - PIPE_FORMAT_R16G16B16X16_SNORM, - PIPE_FORMAT_R16G16B16X16_FLOAT, - PIPE_FORMAT_R16G16B16X16_UINT, - PIPE_FORMAT_R16G16B16X16_SINT, - PIPE_FORMAT_R32G32B32X32_FLOAT, - PIPE_FORMAT_R32G32B32X32_UINT, - PIPE_FORMAT_R32G32B32X32_SINT, - - PIPE_FORMAT_R8A8_SNORM, - PIPE_FORMAT_R16A16_UNORM, - PIPE_FORMAT_R16A16_SNORM, - PIPE_FORMAT_R16A16_FLOAT, - PIPE_FORMAT_R32A32_FLOAT, - PIPE_FORMAT_R8A8_UINT, - PIPE_FORMAT_R8A8_SINT, - PIPE_FORMAT_R16A16_UINT, - PIPE_FORMAT_R16A16_SINT, - PIPE_FORMAT_R32A32_UINT, - PIPE_FORMAT_R32A32_SINT, - PIPE_FORMAT_R10G10B10A2_UINT, - PIPE_FORMAT_R10G10B10A2_SINT, - - PIPE_FORMAT_B5G6R5_SRGB, - - PIPE_FORMAT_BPTC_RGBA_UNORM, - PIPE_FORMAT_BPTC_SRGBA, - PIPE_FORMAT_BPTC_RGB_FLOAT, - PIPE_FORMAT_BPTC_RGB_UFLOAT, - - PIPE_FORMAT_G8R8_UNORM, - PIPE_FORMAT_G8R8_SNORM, - PIPE_FORMAT_G16R16_UNORM, - PIPE_FORMAT_G16R16_SNORM, - - PIPE_FORMAT_A8B8G8R8_SNORM, - PIPE_FORMAT_X8B8G8R8_SNORM, - - PIPE_FORMAT_ETC2_RGB8, - PIPE_FORMAT_ETC2_SRGB8, - PIPE_FORMAT_ETC2_RGB8A1, - PIPE_FORMAT_ETC2_SRGB8A1, - PIPE_FORMAT_ETC2_RGBA8, - PIPE_FORMAT_ETC2_SRGBA8, - PIPE_FORMAT_ETC2_R11_UNORM, - PIPE_FORMAT_ETC2_R11_SNORM, - PIPE_FORMAT_ETC2_RG11_UNORM, - PIPE_FORMAT_ETC2_RG11_SNORM, - - PIPE_FORMAT_ASTC_4x4, - PIPE_FORMAT_ASTC_5x4, - PIPE_FORMAT_ASTC_5x5, - PIPE_FORMAT_ASTC_6x5, - PIPE_FORMAT_ASTC_6x6, - PIPE_FORMAT_ASTC_8x5, - PIPE_FORMAT_ASTC_8x6, - PIPE_FORMAT_ASTC_8x8, - PIPE_FORMAT_ASTC_10x5, - PIPE_FORMAT_ASTC_10x6, - PIPE_FORMAT_ASTC_10x8, - PIPE_FORMAT_ASTC_10x10, - PIPE_FORMAT_ASTC_12x10, - PIPE_FORMAT_ASTC_12x12, - - PIPE_FORMAT_ASTC_4x4_SRGB, - PIPE_FORMAT_ASTC_5x4_SRGB, - PIPE_FORMAT_ASTC_5x5_SRGB, - PIPE_FORMAT_ASTC_6x5_SRGB, - PIPE_FORMAT_ASTC_6x6_SRGB, - PIPE_FORMAT_ASTC_8x5_SRGB, - PIPE_FORMAT_ASTC_8x6_SRGB, - PIPE_FORMAT_ASTC_8x8_SRGB, - PIPE_FORMAT_ASTC_10x5_SRGB, - PIPE_FORMAT_ASTC_10x6_SRGB, - PIPE_FORMAT_ASTC_10x8_SRGB, - PIPE_FORMAT_ASTC_10x10_SRGB, - PIPE_FORMAT_ASTC_12x10_SRGB, - PIPE_FORMAT_ASTC_12x12_SRGB, - - PIPE_FORMAT_ASTC_3x3x3, - PIPE_FORMAT_ASTC_4x3x3, - PIPE_FORMAT_ASTC_4x4x3, - PIPE_FORMAT_ASTC_4x4x4, - PIPE_FORMAT_ASTC_5x4x4, - PIPE_FORMAT_ASTC_5x5x4, - PIPE_FORMAT_ASTC_5x5x5, - PIPE_FORMAT_ASTC_6x5x5, - PIPE_FORMAT_ASTC_6x6x5, - PIPE_FORMAT_ASTC_6x6x6, - - PIPE_FORMAT_ASTC_3x3x3_SRGB, - PIPE_FORMAT_ASTC_4x3x3_SRGB, - PIPE_FORMAT_ASTC_4x4x3_SRGB, - PIPE_FORMAT_ASTC_4x4x4_SRGB, - PIPE_FORMAT_ASTC_5x4x4_SRGB, - PIPE_FORMAT_ASTC_5x5x4_SRGB, - PIPE_FORMAT_ASTC_5x5x5_SRGB, - PIPE_FORMAT_ASTC_6x5x5_SRGB, - PIPE_FORMAT_ASTC_6x6x5_SRGB, - PIPE_FORMAT_ASTC_6x6x6_SRGB, - - PIPE_FORMAT_FXT1_RGB, - PIPE_FORMAT_FXT1_RGBA, - - PIPE_FORMAT_P010, - PIPE_FORMAT_P012, - PIPE_FORMAT_P016, - - PIPE_FORMAT_R10G10B10X2_UNORM, - PIPE_FORMAT_A1R5G5B5_UNORM, - PIPE_FORMAT_A1B5G5R5_UNORM, - PIPE_FORMAT_X1B5G5R5_UNORM, - PIPE_FORMAT_R5G5B5A1_UNORM, - PIPE_FORMAT_A4R4G4B4_UNORM, - PIPE_FORMAT_A4B4G4R4_UNORM, - - PIPE_FORMAT_G8R8_SINT, - PIPE_FORMAT_A8B8G8R8_SINT, - PIPE_FORMAT_X8B8G8R8_SINT, - - PIPE_FORMAT_ATC_RGB, - PIPE_FORMAT_ATC_RGBA_EXPLICIT, - PIPE_FORMAT_ATC_RGBA_INTERPOLATED, - - PIPE_FORMAT_Z24_UNORM_S8_UINT_AS_R8G8B8A8, - - PIPE_FORMAT_AYUV, - PIPE_FORMAT_XYUV, - - PIPE_FORMAT_R8_G8B8_420_UNORM, - - PIPE_FORMAT_COUNT -}; - -struct st_visual -{ - bool no_config; - - /** - * Available buffers. Bitfield of ST_ATTACHMENT_*_MASK bits. - */ - unsigned buffer_mask; - - /** - * Buffer formats. The formats are always set even when the buffer is - * not available. - */ - enum pipe_format color_format; - enum pipe_format depth_stencil_format; - enum pipe_format accum_format; - unsigned samples; - - /** - * Desired render buffer. - */ - enum st_attachment_type render_buffer; -}; -typedef struct osmesa_buffer -{ - struct st_framebuffer_iface *stfb; - struct st_visual visual; - unsigned width, height; - - struct pipe_resource *textures[ST_ATTACHMENT_COUNT]; - - void *map; - - struct osmesa_buffer *next; /**< next in linked list */ -}; - - -typedef struct osmesa_context -{ - struct st_context_iface *stctx; - - bool ever_used; /*< Has this context ever been current? */ - - struct osmesa_buffer *current_buffer; - - /* Storage for depth/stencil, if the user has requested access. The backing - * driver always has its own storage for the actual depth/stencil, which we - * have to transfer in and out. - */ - void *zs; - unsigned zs_stride; - - enum pipe_format depth_stencil_format, accum_format; - - GLenum format; /*< User-specified context format */ - GLenum type; /*< Buffer's data type */ - GLint user_row_length; /*< user-specified number of pixels per row */ - GLboolean y_up; /*< TRUE -> Y increases upward */ - /*< FALSE -> Y increases downward */ - - /** Which postprocessing filters are enabled. */ - //safe to remove -}; -// endregion OSMESA internals struct PotatoBridge { /* EGLContext */ void* eglContextOld; @@ -596,16 +42,9 @@ struct PotatoBridge potatoBridge; #include "ctxbridges/egl_loader.h" #include "ctxbridges/osmesa_loader.h" -int (*vtest_main_p) (int argc, char** argv); -void (*vtest_swap_buffers_p) (void); #define RENDERER_GL4ES 1 #define RENDERER_VK_ZINK 2 -#define RENDERER_VIRGL 3 - -void* gbuffer; - -void* egl_make_current(void* window); void pojav_openGLOnLoad() { } @@ -653,7 +92,6 @@ void* pojavGetCurrentContext() { switch (pojav_environ->config_renderer) { case RENDERER_GL4ES: return (void *)eglGetCurrentContext_p(); - case RENDERER_VIRGL: case RENDERER_VK_ZINK: return (void *)OSMesaGetCurrentContext_p(); @@ -697,8 +135,6 @@ void dlsym_OSMesa(void* dl_handle) { bool loadSymbols() { switch (pojav_environ->config_renderer) { - case RENDERER_VIRGL: - dlsym_EGL(); case RENDERER_VK_ZINK: dlsym_OSMesa(); break; @@ -707,23 +143,64 @@ bool loadSymbols() { break; } } - -bool loadSymbolsVirGL() { - pojav_environ->config_renderer = RENDERER_VIRGL; - loadSymbols(); - - char* fileName = calloc(1, 1024); - - sprintf(fileName, "%s/libvirgl_test_server.so", getenv("POJAV_NATIVEDIR")); - void *handle = dlopen(fileName, RTLD_LAZY); - printf("VirGL: libvirgl_test_server = %p\n", handle); - if (!handle) { - printf("VirGL: %s\n", dlerror()); +//#define ADRENO_POSSIBLE +#ifdef ADRENO_POSSIBLE +//Checks if your graphics are Adreno. Returns true if your graphics are Adreno, false otherwise or if there was an error +bool checkAdrenoGraphics() { + EGLDisplay eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if(eglDisplay == EGL_NO_DISPLAY || eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE) return false; + EGLint egl_attributes[] = { EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 24, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; + EGLint num_configs = 0; + if(eglChooseConfig(eglDisplay, egl_attributes, NULL, 0, &num_configs) != EGL_TRUE || num_configs == 0) { + eglTerminate(eglDisplay); + return false; } - vtest_main_p = dlsym(handle, "vtest_main"); - vtest_swap_buffers_p = dlsym(handle, "vtest_swap_buffers"); - - free(fileName); + EGLConfig eglConfig; + eglChooseConfig(eglDisplay, egl_attributes, &eglConfig, 1, &num_configs); + const EGLint egl_context_attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE }; + EGLContext context = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, egl_context_attributes); + if(context == EGL_NO_CONTEXT) { + eglTerminate(eglDisplay); + return false; + } + if(eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, context) != EGL_TRUE) { + eglDestroyContext(eglDisplay, context); + eglTerminate(eglDisplay); + } + const char* vendor = glGetString(GL_VENDOR); + const char* renderer = glGetString(GL_RENDERER); + bool is_adreno = false; + if(strcmp(vendor, "Qualcomm") == 0 && strstr(renderer, "Adreno") != NULL) { + is_adreno = true; // TODO: check for Turnip support + } + eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglDestroyContext(eglDisplay, context); + eglTerminate(eglDisplay); + return is_adreno; +} +void* load_turnip_vulkan() { + if(!checkAdrenoGraphics()) return NULL; + const char* native_dir = getenv("POJAV_NATIVEDIR"); + const char* cache_dir = getenv("TMPDIR"); + linker_ns_load(native_dir); + void* linkerhook = linker_ns_dlopen("liblinkerhook.so", RTLD_LOCAL | RTLD_NOW); + void* turnip_driver_handle = linker_ns_dlopen("libvulkan.adr.so", RTLD_LOCAL | RTLD_NOW); + void (*linkerhook_set_data)(void*, void*, void*) = dlsym(linkerhook, "app__pojav_linkerhook_set_data"); + linkerhook_set_data(turnip_driver_handle, &android_dlopen_ext, &ns_android_get_exported_namespace); + void* libvulkan = linker_ns_dlopen_unique(cache_dir, "libvulkan.so", RTLD_LOCAL | RTLD_NOW); + return libvulkan; +} +#endif +void load_vulkan() { +#ifdef ADRENO_POSSIBLE + void* result = load_turnip_vulkan(); + if(result != NULL) { + printf("AdrenoSupp: Loaded Turnip, loader address: %p\n", result); + char envval[64]; + sprintf(envval, "%"PRIxPTR, (uintptr_t)result); + setenv("VULKAN_PTR", envval, 1); + } +#endif } int pojavInit() { @@ -739,19 +216,12 @@ int pojavInit() { // NOTE: Override for now. const char *renderer = getenv("POJAV_RENDERER"); - if (strncmp("opengles3_virgl", renderer, 15) == 0) { - pojav_environ->config_renderer = RENDERER_VIRGL; - setenv("GALLIUM_DRIVER","virpipe",1); - setenv("OSMESA_NO_FLUSH_FRONTBUFFER","1",false); - if(strcmp(getenv("OSMESA_NO_FLUSH_FRONTBUFFER"),"1") == 0) { - printf("VirGL: OSMesa buffer flush is DISABLED!\n"); - } - loadSymbolsVirGL(); - } else if (strncmp("opengles", renderer, 8) == 0) { + if (strncmp("opengles", renderer, 8) == 0) { pojav_environ->config_renderer = RENDERER_GL4ES; //loadSymbols(); } else if (strcmp(renderer, "vulkan_zink") == 0) { pojav_environ->config_renderer = RENDERER_VK_ZINK; + load_vulkan(); setenv("GALLIUM_DRIVER","zink",1); loadSymbols(); } @@ -762,111 +232,9 @@ int pojavInit() { } return 0; } - if (pojav_environ->config_renderer == RENDERER_VIRGL) { - if (potatoBridge.eglDisplay == NULL || potatoBridge.eglDisplay == EGL_NO_DISPLAY) { - potatoBridge.eglDisplay = eglGetDisplay_p(EGL_DEFAULT_DISPLAY); - if (potatoBridge.eglDisplay == EGL_NO_DISPLAY) { - printf("EGLBridge: Error eglGetDefaultDisplay() failed: %p\n", eglGetError_p()); - return 0; - } - } - printf("EGLBridge: Initializing\n"); - // printf("EGLBridge: ANativeWindow pointer = %p\n", pojav_environ->pojavWindow); - //(*env)->ThrowNew(env,(*env)->FindClass(env,"java/lang/Exception"),"Trace exception"); - if (!eglInitialize_p(potatoBridge.eglDisplay, NULL, NULL)) { - printf("EGLBridge: Error eglInitialize() failed: %s\n", eglGetError_p()); - return 0; - } - - static const EGLint attribs[] = { - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_ALPHA_SIZE, 8, - // Minecraft required on initial 24 - EGL_DEPTH_SIZE, 24, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_NONE - }; - - EGLint num_configs; - EGLint vid; - - if (!eglChooseConfig_p(potatoBridge.eglDisplay, attribs, &config, 1, &num_configs)) { - printf("EGLBridge: Error couldn't get an EGL visual config: %s\n", eglGetError_p()); - return 0; - } - - assert(config); - assert(num_configs > 0); - - if (!eglGetConfigAttrib_p(potatoBridge.eglDisplay, config, EGL_NATIVE_VISUAL_ID, &vid)) { - printf("EGLBridge: Error eglGetConfigAttrib() failed: %s\n", eglGetError_p()); - return 0; - } - - ANativeWindow_setBuffersGeometry(pojav_environ->pojavWindow, 0, 0, vid); - - eglBindAPI_p(EGL_OPENGL_ES_API); - - potatoBridge.eglSurface = eglCreateWindowSurface_p(potatoBridge.eglDisplay, config, pojav_environ->pojavWindow, NULL); - - if (!potatoBridge.eglSurface) { - printf("EGLBridge: Error eglCreateWindowSurface failed: %p\n", eglGetError_p()); - //(*env)->ThrowNew(env,(*env)->FindClass(env,"java/lang/Exception"),"Trace exception"); - return 0; - } - - // sanity checks - { - EGLint val; - assert(eglGetConfigAttrib_p(potatoBridge.eglDisplay, config, EGL_SURFACE_TYPE, &val)); - assert(val & EGL_WINDOW_BIT); - } - - printf("EGLBridge: Initialized!\n"); - printf("EGLBridge: ThreadID=%d\n", gettid()); - printf("EGLBridge: EGLDisplay=%p, EGLSurface=%p\n", -/* window==0 ? EGL_NO_CONTEXT : */ - potatoBridge.eglDisplay, - potatoBridge.eglSurface - ); - if (pojav_environ->config_renderer != RENDERER_VIRGL) { - return 1; - } - } - - if (pojav_environ->config_renderer == RENDERER_VIRGL) { - // Init EGL context and vtest server - const EGLint ctx_attribs[] = { - EGL_CONTEXT_CLIENT_VERSION, 3, - EGL_NONE - }; - EGLContext* ctx = eglCreateContext_p(potatoBridge.eglDisplay, config, NULL, ctx_attribs); - printf("VirGL: created EGL context %p\n", ctx); - - pthread_t t; - pthread_create(&t, NULL, egl_make_current, (void *)ctx); - usleep(100*1000); // need enough time for the server to init - } - - if (pojav_environ->config_renderer == RENDERER_VK_ZINK || pojav_environ->config_renderer == RENDERER_VIRGL) { - if(OSMesaCreateContext_p == NULL) { - printf("OSMDroid: %s\n",dlerror()); - return 0; - } - - printf("OSMDroid: width=%i;height=%i, reserving %i bytes for frame buffer\n", pojav_environ->savedWidth, pojav_environ->savedHeight, - pojav_environ->savedWidth * 4 * pojav_environ->savedHeight); - gbuffer = malloc(pojav_environ->savedWidth * 4 * pojav_environ->savedHeight+1); - if (gbuffer) { - printf("OSMDroid: created frame buffer\n"); - return 1; - } else { - printf("OSMDroid: can't generate frame buffer\n"); - return 0; - } + if (pojav_environ->config_renderer == RENDERER_VK_ZINK && OSMesaCreateContext_p != NULL) { + return 1; } return 0; @@ -883,77 +251,23 @@ void pojavSwapBuffers() { gl_swap_buffers(); } break; - case RENDERER_VIRGL: { - glFinish_p(); - vtest_swap_buffers_p(); - } break; - case RENDERER_VK_ZINK: { - OSMesaContext ctx = OSMesaGetCurrentContext_p(); - if(ctx == NULL) { - printf("Zink: attempted to swap buffers without context!"); - break; - } - OSMesaMakeCurrent_p(ctx,buf.bits,GL_UNSIGNED_BYTE,pojav_environ->savedWidth,pojav_environ->savedHeight); - glFinish_p(); - ANativeWindow_unlockAndPost(pojav_environ->pojavWindow); - //OSMesaMakeCurrent_p(ctx,gbuffer,GL_UNSIGNED_BYTE,savedWidth,savedHeight); - ANativeWindow_lock(pojav_environ->pojavWindow,&buf,NULL); + OSMesaFlushFrontbuffer_p(); } break; } } -void* egl_make_current(void* window) { - EGLBoolean success = eglMakeCurrent_p( - potatoBridge.eglDisplay, - window==0 ? (EGLSurface *) 0 : potatoBridge.eglSurface, - window==0 ? (EGLSurface *) 0 : potatoBridge.eglSurface, - /* window==0 ? EGL_NO_CONTEXT : */ (EGLContext *) window - ); - - if (success == EGL_FALSE) { - printf("EGLBridge: Error: eglMakeCurrent() failed: %p\n", eglGetError_p()); - } else { - printf("EGLBridge: eglMakeCurrent() succeed!\n"); - } - - if (pojav_environ->config_renderer == RENDERER_VIRGL) { - printf("VirGL: vtest_main = %p\n", vtest_main_p); - printf("VirGL: Calling VTest server's main function\n"); - vtest_main_p(3, (const char*[]){"vtest", "--no-loop-or-fork", "--use-gles", NULL, NULL}); - } -} - -bool locked = false; void pojavMakeCurrent(void* window) { - //if(OSMesaGetCurrentContext_p() != NULL) { - // printf("OSMDroid: skipped context reset\n"); - // return JNI_TRUE; - //} if(pojav_environ->config_renderer == RENDERER_GL4ES) { gl_make_current((render_window_t*)window); } - if (pojav_environ->config_renderer == RENDERER_VK_ZINK || pojav_environ->config_renderer == RENDERER_VIRGL) { + if (pojav_environ->config_renderer == RENDERER_VK_ZINK) { printf("OSMDroid: making current\n"); - OSMesaMakeCurrent_p((OSMesaContext)window,gbuffer,GL_UNSIGNED_BYTE,pojav_environ->savedWidth,pojav_environ->savedHeight); - if (pojav_environ->config_renderer == RENDERER_VK_ZINK) { - ANativeWindow_lock(pojav_environ->pojavWindow,&buf,NULL); - OSMesaPixelStore_p(OSMESA_ROW_LENGTH,buf.stride); - stride = buf.stride; - //ANativeWindow_unlockAndPost(pojav_environ->pojavWindow); - OSMesaPixelStore_p(OSMESA_Y_UP,0); - } - + OSMesaMakeCurrent_p((OSMesaContext)window,pojav_environ->pojavWindow,GL_UNSIGNED_BYTE,pojav_environ->savedWidth,pojav_environ->savedHeight); printf("OSMDroid: vendor: %s\n",glGetString_p(GL_VENDOR)); printf("OSMDroid: renderer: %s\n",glGetString_p(GL_RENDERER)); - glClear_p(GL_COLOR_BUFFER_BIT); - glClearColor_p(0.4f, 0.4f, 0.4f, 1.0f); - - // Trigger a texture creation, which then set VIRGL_TEXTURE_ID - int pixelsArr[4]; - glReadPixels_p(0, 0, 1, 1, GL_RGB, GL_INT, &pixelsArr); - - pojavSwapBuffers(); + glReadBuffer_p(GL_BACK); + glReadBuffer_p(GL_FRONT); return; } } @@ -978,19 +292,10 @@ Java_org_lwjgl_glfw_GLFW_nativeEglDetachOnCurrentThread(JNIEnv *env, jclass claz void* pojavCreateContext(void* contextSrc) { if (pojav_environ->config_renderer == RENDERER_GL4ES) { - /*const EGLint ctx_attribs[] = { - EGL_CONTEXT_CLIENT_VERSION, atoi(getenv("LIBGL_ES")), - EGL_NONE - }; - EGLContext* ctx = eglCreateContext_p(potatoBridge.eglDisplay, config, (void*)contextSrc, ctx_attribs); - potatoBridge.eglContext = ctx; - printf("EGLBridge: Created CTX pointer = %p\n",ctx); - //(*env)->ThrowNew(env,(*env)->FindClass(env,"java/lang/Exception"),"Trace exception"); - return (long)ctx;*/ return gl_init_context(contextSrc); } - if (pojav_environ->config_renderer == RENDERER_VK_ZINK || pojav_environ->config_renderer == RENDERER_VIRGL) { + if (pojav_environ->config_renderer == RENDERER_VK_ZINK) { printf("OSMDroid: generating context\n"); void* ctx = OSMesaCreateContext_p(OSMESA_RGBA,contextSrc); printf("OSMDroid: context=%p\n",ctx); @@ -1009,7 +314,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_GL_nativeRegalMakeCurrent(JNIEnv *e } JNIEXPORT jlong JNICALL Java_org_lwjgl_opengl_GL_getGraphicsBufferAddr(JNIEnv *env, jobject thiz) { - return &gbuffer; + return (jlong) pojav_environ->pojavWindow; } JNIEXPORT jintArray JNICALL Java_org_lwjgl_opengl_GL_getNativeWidthHeight(JNIEnv *env, jobject thiz) { @@ -1023,9 +328,6 @@ void pojavSwapInterval(int interval) { case RENDERER_GL4ES: { gl_swap_interval(interval); } break; - case RENDERER_VIRGL: { - eglSwapInterval_p(potatoBridge.eglDisplay, interval); - } break; case RENDERER_VK_ZINK: { printf("eglSwapInterval: NOT IMPLEMENTED YET!\n"); diff --git a/app_pojavlauncher/src/main/jniLibs/arm64-v8a/libOSMesa_8.so b/app_pojavlauncher/src/main/jniLibs/arm64-v8a/libOSMesa_8.so index 5a790eeebd..ba22ed0a4d 100644 Binary files a/app_pojavlauncher/src/main/jniLibs/arm64-v8a/libOSMesa_8.so and b/app_pojavlauncher/src/main/jniLibs/arm64-v8a/libOSMesa_8.so differ diff --git a/app_pojavlauncher/src/main/jniLibs/arm64-v8a/libvirgl_test_server.so b/app_pojavlauncher/src/main/jniLibs/arm64-v8a/libvirgl_test_server.so deleted file mode 100644 index 7fa43b7d9d..0000000000 Binary files a/app_pojavlauncher/src/main/jniLibs/arm64-v8a/libvirgl_test_server.so and /dev/null differ diff --git a/app_pojavlauncher/src/main/jniLibs/arm64-v8a/libvulkan.adr.so b/app_pojavlauncher/src/main/jniLibs/arm64-v8a/libvulkan.adr.so new file mode 100755 index 0000000000..02fd8533c8 Binary files /dev/null and b/app_pojavlauncher/src/main/jniLibs/arm64-v8a/libvulkan.adr.so differ diff --git a/app_pojavlauncher/src/main/res/values/headings_array.xml b/app_pojavlauncher/src/main/res/values/headings_array.xml index fb5d4c6953..b472191ce8 100644 --- a/app_pojavlauncher/src/main/res/values/headings_array.xml +++ b/app_pojavlauncher/src/main/res/values/headings_array.xml @@ -3,7 +3,7 @@ @string/mcl_setting_renderer_gles2_4 - @string/mcl_setting_renderer_virgl + zink @string/mcl_setting_renderer_angle @@ -37,7 +37,7 @@ opengles2 - opengles3_virgl + vulkan_zink opengles3_desktopgl_angle_vulkan