Files
FEX-Emu--FEX/ThunkLibs/libGL/libGL_Guest.cpp
T
Tony Wasserka cd05cdaa57 Thunks: Make GL guest thunks implicitly load libX11.so
Steam's gameoverlayrenderer.so relies on libX11 symbols to be available
without actually loading that library directly. This works on an unthunked
system since libGL.so depends on libGLX.so, which in turn pulls in libX11.so
at load-time. Adding a fake libX11 dependency to the libGL-guest thunks
reproduces this behavior.
2022-08-04 11:46:26 +02:00

73 lines
2.0 KiB
C++

/*
$info$
tags: thunklibs|GL
desc: Handles glXGetProcAddress
$end_info$
*/
#define GL_GLEXT_PROTOTYPES 1
#define GLX_GLXEXT_PROTOTYPES 1
#include <GL/glx.h>
#include <GL/glxext.h>
#include <GL/gl.h>
#include <GL/glext.h>
#undef GL_ARB_viewport_array
#include "glcorearb.h"
#include <stdio.h>
#include <cstdlib>
#include <functional>
#include <string_view>
#include <unordered_map>
#include "common/Guest.h"
#include "thunks.inl"
#include "function_packs.inl"
#include "function_packs_public.inl"
#include "symbol_list.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<std::string_view, uintptr_t /* guest function address */> HostPtrInvokers =
std::invoke([]() {
#define PAIR(name, unused) Ret[#name] = reinterpret_cast<uintptr_t>(GetCallerForHostThunkFromRuntimePointer<fexthunks_libGL_hostcall_##name>(name));
std::unordered_map<std::string_view, uintptr_t> 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<const char*>(procname));
if (TargetFuncIt == HostPtrInvokers.end()) {
// Extension found in host but not in our interface definition => treat as fatal error
fprintf(stderr, "glXGetProcAddress: not found %s\n", procname);
__builtin_trap();
}
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)