From d99b4a80c84b3af4a247b31260ec638d17fa6b08 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Tue, 11 Jun 2024 17:10:38 +0200 Subject: [PATCH] Library Forwarding/GL: Add glX support for 32-bit --- ThunkLibs/include/common/X11Manager.h | 13 ++++++++-- ThunkLibs/libGL/libGL_Guest.cpp | 5 ++-- ThunkLibs/libGL/libGL_Host.cpp | 37 ++++++++++++++++++++++++--- ThunkLibs/libGL/libGL_interface.cpp | 26 ++++++++++++++++--- 4 files changed, 70 insertions(+), 11 deletions(-) diff --git a/ThunkLibs/include/common/X11Manager.h b/ThunkLibs/include/common/X11Manager.h index 01ad7093a..a0b1f9e8e 100644 --- a/ThunkLibs/include/common/X11Manager.h +++ b/ThunkLibs/include/common/X11Manager.h @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -9,6 +10,14 @@ #include #include +#ifdef IS_32BIT_THUNK +using guest_long = int32_t; +using guest_size_t = int32_t; +#else +using guest_long = long; +using guest_size_t = size_t; +#endif + /** * Guest X11 displays and xcb connections can't be used by the host, so * instead an intermediary object is created and mapped to the original @@ -47,7 +56,7 @@ struct X11Manager { std::unique_lock lock(mutex); auto [it, inserted] = displays.emplace(GuestDisplay, nullptr); if (inserted) { - auto host_display = HostXOpenDisplay(DisplayString(GuestDisplay)); + auto host_display = HostXOpenDisplay(GuestXDisplayString(GuestDisplay)); fprintf(stderr, "Opening host-side X11 display: %p -> %p\n", GuestDisplay, host_display); if (!host_display) { fprintf(stderr, "ERROR: Could not open X display\n"); @@ -104,7 +113,7 @@ struct X11Manager { // NOTE: Struct pointers are replaced by void* to avoid involving data layout conversion here. int (*GuestXSync)(void*, int) = nullptr; - void* (*GuestXGetVisualInfo)(void*, long, void*, int*) = nullptr; + void* (*GuestXGetVisualInfo)(void*, guest_long, void*, int*) = nullptr; // XDisplayString internally just reads data from _XDisplay's internal struct definition. // This breaks when data layout is different, so allow reading from a guest context instead. diff --git a/ThunkLibs/libGL/libGL_Guest.cpp b/ThunkLibs/libGL/libGL_Guest.cpp index 1e264a6fa..120e28607 100644 --- a/ThunkLibs/libGL/libGL_Guest.cpp +++ b/ThunkLibs/libGL/libGL_Guest.cpp @@ -16,9 +16,10 @@ $end_info$ #undef GL_ARB_viewport_array #include "glcorearb.h" -#include -#include #include +#include +#include +#include #include #include #include diff --git a/ThunkLibs/libGL/libGL_Host.cpp b/ThunkLibs/libGL/libGL_Host.cpp index cfab36e95..3c76205e5 100644 --- a/ThunkLibs/libGL/libGL_Host.cpp +++ b/ThunkLibs/libGL/libGL_Host.cpp @@ -35,7 +35,7 @@ struct host_layout<_XDisplay*> { static X11Manager x11_manager; -static void* (*GuestMalloc)(size_t) = nullptr; +static void* (*GuestMalloc)(guest_size_t) = nullptr; host_layout<_XDisplay*>::host_layout(guest_layout<_XDisplay*>& guest) : guest_display(guest.force_get_host_pointer()) { @@ -136,10 +136,19 @@ auto fexfn_impl_libGL_glXGetProcAddress(const GLubyte* name) -> void (*)() { return (VoidFn)fexfn_impl_libGL_glXGetConfig; } else if (name_sv == "glXGetVisualFromFBConfig") { return (VoidFn)fexfn_impl_libGL_glXGetVisualFromFBConfig; +#ifdef IS_32BIT_THUNK + } else if (name_sv == "glXGetSelectedEvent") { + return (VoidFn)fexfn_impl_libGL_glXGetSelectedEvent; + } else if (name_sv == "glXGetSelectedEventSGIX") { + return (VoidFn)fexfn_impl_libGL_glXGetSelectedEventSGIX; +#endif } return (VoidFn)glXGetProcAddress((const GLubyte*)name); } +// TODO: unsigned int *glXEnumerateVideoDevicesNV (Display *dpy, int screen, int *nelements); + + void fexfn_impl_libGL_glCompileShaderIncludeARB(GLuint a_0, GLsizei Count, guest_layout a_2, const GLint* a_3) { // TODO: Only on 32-bit auto sources = (const char**)alloca(Count * sizeof(const char*)); @@ -282,7 +291,8 @@ static XVisualInfo* LookupHostVisualInfo(Display* HostDisplay, guest_layout {*GuestInfo.get_pointer()}.data; + auto ret = x11_manager.HostXGetVisualInfo(HostDisplay, uint64_t {VisualScreenMask | VisualIDMask}, &HostInfo, &num_matches); if (num_matches != 1) { fprintf(stderr, "ERROR: Did not find unique host XVisualInfo\n"); std::abort(); @@ -296,9 +306,17 @@ static guest_layout MapToGuestVisualInfo(Display* HostDisplay, XVi return guest_layout {.data = 0}; } - int num_matches; auto guest_display = x11_manager.HostToGuestDisplay(HostDisplay); - auto ret = x11_manager.GuestXGetVisualInfo(guest_display.get_pointer(), VisualScreenMask | VisualIDMask, HostInfo, &num_matches); +#ifndef IS_32BIT_THUNK + int num_matches; + auto GuestInfo = to_guest(to_host_layout(*HostInfo)); +#else + GuestStackBumpAllocator GuestStack; + auto& num_matches = *GuestStack.New(); + auto& GuestInfo = *GuestStack.New>(to_guest(to_host_layout(*HostInfo))); +#endif + auto ret = x11_manager.GuestXGetVisualInfo(guest_display.get_pointer(), VisualScreenMask | VisualIDMask, &GuestInfo, &num_matches); + if (num_matches != 1) { fprintf(stderr, "ERROR: Did not find unique guest XVisualInfo\n"); std::abort(); @@ -409,6 +427,17 @@ void fexfn_impl_libGL_glVertexArrayVertexBuffers(GLuint a_0, GLuint a_1, GLsizei } fexldr_ptr_libGL_glVertexArrayVertexBuffers(a_0, a_1, count, a_3, HostOffsets, a_5); } + +void fexfn_impl_libGL_glXGetSelectedEvent(Display* Display, GLXDrawable Drawable, guest_layout Mask) { + unsigned long HostMask; + fexldr_ptr_libGL_glXGetSelectedEvent(Display, Drawable, &HostMask); + *Mask.get_pointer() = HostMask; +} +void fexfn_impl_libGL_glXGetSelectedEventSGIX(Display* Display, GLXDrawable Drawable, guest_layout Mask) { + unsigned long HostMask; + fexldr_ptr_libGL_glXGetSelectedEventSGIX(Display, Drawable, &HostMask); + *Mask.get_pointer() = HostMask; +} #endif EXPORTS(libGL) diff --git a/ThunkLibs/libGL/libGL_interface.cpp b/ThunkLibs/libGL/libGL_interface.cpp index 17dc3604a..8765c93d2 100644 --- a/ThunkLibs/libGL/libGL_interface.cpp +++ b/ThunkLibs/libGL/libGL_interface.cpp @@ -74,7 +74,6 @@ struct fex_gen_config : fexgen::generate_guest_symtable, fexgen::indirect_guest_ template struct fex_gen_param {}; -#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; template<> @@ -135,8 +134,16 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; +#else +template<> +struct fex_gen_config : fexgen::custom_host_impl {}; +template<> +struct fex_gen_param : fexgen::ptr_passthrough {}; +#endif + template<> struct fex_gen_config {}; template<> @@ -215,8 +222,15 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK template<> struct fex_gen_config {}; +#else +template<> +struct fex_gen_config : fexgen::custom_host_impl {}; +template<> +struct fex_gen_param : fexgen::ptr_passthrough {}; +#endif template<> struct fex_gen_config {}; template<> @@ -241,7 +255,6 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; -#endif template<> struct fex_gen_config {}; @@ -6352,7 +6365,6 @@ struct fex_gen_config {}; template<> struct fex_gen_config {}; -#ifndef IS_32BIT_THUNK // glx.h template<> struct fex_gen_config {}; @@ -6428,8 +6440,11 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK +// TODO: 32-bit support template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; template<> @@ -6444,10 +6459,13 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK +// TODO: 32-bit support template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#endif template<> struct fex_gen_config {}; template<> @@ -6482,6 +6500,8 @@ template<> struct fex_gen_config {}; template<> struct fex_gen_config {}; +#ifndef IS_32BIT_THUNK +// TODO: 32-bit support template<> struct fex_gen_config {}; #endif