mirror of
https://github.com/FEX-Emu/FEX.git
synced 2024-11-24 15:10:01 +00:00
Vulkan: Handle queries for unknown functions more gracefully
This commit is contained in:
parent
6a43db8c8f
commit
83c2e52ba5
@ -36,18 +36,40 @@ const std::unordered_map<std::string_view, uintptr_t /* guest function address *
|
||||
#undef PAIR
|
||||
});
|
||||
|
||||
// This variable controls the behavior of vkGetDevice/InstanceProcAddr for functions we don't know the signature of:
|
||||
// - if false (default), we return a nullptr (since the application might have a fallback code path)
|
||||
// - if true, we return a stub function that fatally errors upon being called
|
||||
constexpr bool stub_unknown_functions = false;
|
||||
|
||||
// Fatally erroring function with a thunk-like interface. This is used as a placeholder for unknown Vulkan functions
|
||||
[[noreturn]] static void FatalError(void* raw_args) {
|
||||
auto called_function = reinterpret_cast<PackedArguments<void, uintptr_t>*>(raw_args)->a0;
|
||||
fprintf(stderr, "FATAL: Called unknown Vulkan function at address %p\n", reinterpret_cast<void*>(called_function));
|
||||
__builtin_trap();
|
||||
}
|
||||
|
||||
static PFN_vkVoidFunction MakeGuestCallable(const char* origin, PFN_vkVoidFunction func, const char* name) {
|
||||
auto It = HostPtrInvokers.find(name);
|
||||
if (It == HostPtrInvokers.end()) {
|
||||
fprintf(stderr, "%s: Unknown Vulkan function at address %p: %s\n", origin, func, name);
|
||||
if (stub_unknown_functions) {
|
||||
const auto StubHostPtrInvoker = CallHostThunkFromRuntimePointer<FatalError, void>;
|
||||
LinkAddressToFunction((uintptr_t)func, reinterpret_cast<uintptr_t>(StubHostPtrInvoker));
|
||||
return func;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
fprintf(stderr, "Linking address %p to host invoker %#lx\n", func, It->second);
|
||||
LinkAddressToFunction((uintptr_t)func, It->second);
|
||||
return func;
|
||||
}
|
||||
|
||||
PFN_vkVoidFunction vkGetDeviceProcAddr(VkDevice a_0,const char* a_1){
|
||||
auto Ret = fexfn_pack_vkGetDeviceProcAddr(a_0, a_1);
|
||||
if (!Ret) {
|
||||
return nullptr;
|
||||
}
|
||||
auto It = HostPtrInvokers.find(a_1);
|
||||
if (It == HostPtrInvokers.end() || !It->second) {
|
||||
fprintf(stderr, "\tvkGetDeviceProcAddr: Couldn't find Guest symbol: '%s'\n", a_1);
|
||||
__builtin_trap();
|
||||
}
|
||||
LinkAddressToFunction((uintptr_t)Ret, It->second);
|
||||
return Ret;
|
||||
return MakeGuestCallable(__FUNCTION__, Ret, a_1);
|
||||
}
|
||||
|
||||
PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance a_0,const char* a_1){
|
||||
@ -58,13 +80,7 @@ PFN_vkVoidFunction vkGetInstanceProcAddr(VkInstance a_0,const char* a_1){
|
||||
if (!Ret) {
|
||||
return nullptr;
|
||||
}
|
||||
auto It = HostPtrInvokers.find(a_1);
|
||||
if (It == HostPtrInvokers.end() || !It->second) {
|
||||
fprintf(stderr, "\tvkGetInstanceProcAddr: Couldn't find Guest symbol: '%s'\n", a_1);
|
||||
__builtin_trap();
|
||||
}
|
||||
LinkAddressToFunction((uintptr_t)Ret, It->second);
|
||||
return Ret;
|
||||
return MakeGuestCallable(__FUNCTION__, Ret, a_1);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user