/* $info$ tags: thunklibs|GL desc: Handles glXGetProcAddress $end_info$ */ #define GL_GLEXT_PROTOTYPES 1 #define GLX_GLXEXT_PROTOTYPES 1 #include #include #include #include #undef GL_ARB_viewport_array #include "glcorearb.h" #include #include #include #include #include #include "common/Guest.h" #include "thunkgen_guest_libGL.inl" typedef void voidFunc(); // Maps OpenGL API function names to the address of a guest function which is // linked to the corresponding host function pointer const std::unordered_map HostPtrInvokers = std::invoke([]() { #define PAIR(name, unused) Ret[#name] = reinterpret_cast(GetCallerForHostFunction(name)); std::unordered_map Ret; FOREACH_internal_SYMBOL(PAIR); return Ret; #undef PAIR }); extern "C" { voidFunc *glXGetProcAddress(const GLubyte *procname) { auto Ret = fexfn_pack_glXGetProcAddress(procname); if (!Ret) { return nullptr; } auto TargetFuncIt = HostPtrInvokers.find(reinterpret_cast(procname)); if (TargetFuncIt == HostPtrInvokers.end()) { std::string_view procname_s { reinterpret_cast(procname) }; // If glXGetProcAddress is querying itself, then we can just return itself. // Some games do this for unknown reasons. if (procname_s == "glXGetProcAddress" || procname_s == "glXGetProcAddressARB") { return reinterpret_cast(glXGetProcAddress); } // Extension found in host but not in our interface definition => Not fatal but warn about it // Some games query leaked GLES symbols but don't use them // glFrustrumf : ES 1.x function // - Papers, Please // - Dicey Dungeons fprintf(stderr, "glXGetProcAddress: not found %s\n", procname); return nullptr; } LinkAddressToFunction((uintptr_t)Ret, TargetFuncIt->second); return Ret; } voidFunc *glXGetProcAddressARB(const GLubyte *procname) { return glXGetProcAddress(procname); } } // libGL.so must pull in libX11.so as a dependency. Referencing some libX11 // symbol here prevents the linker from optimizing away the unused dependency auto implicit_libx11_dependency = XSetErrorHandler; LOAD_LIB(libGL)