diff --git a/renderdoc/driver/gl/gl_hooks_win32.cpp b/renderdoc/driver/gl/gl_hooks_win32.cpp index c30390548..d4f7778fb 100644 --- a/renderdoc/driver/gl/gl_hooks_win32.cpp +++ b/renderdoc/driver/gl/gl_hooks_win32.cpp @@ -734,13 +734,15 @@ class OpenGLHook : LibraryHook { bool success = true; + void *moduleHandle = Process::LoadModule(DLL_NAME); + if(wglGetProcAddress_hook() == NULL) - wglGetProcAddress_hook.SetFuncPtr(Process::GetFunctionAddress(DLL_NAME, "wglGetProcAddress")); + wglGetProcAddress_hook.SetFuncPtr(Process::GetFunctionAddress(moduleHandle, "wglGetProcAddress")); wglGetProcAddress_hooked("wglCreateContextAttribsARB"); #undef HookInit -#define HookInit(function) if(GL.function == NULL) GL.function = (CONCAT(function, _hooktype)) Process::GetFunctionAddress(DLL_NAME, STRINGIZE(function)); +#define HookInit(function) if(GL.function == NULL) GL.function = (CONCAT(function, _hooktype)) Process::GetFunctionAddress(moduleHandle, STRINGIZE(function)); // cheeky #undef HookExtension diff --git a/renderdoc/driver/vulkan/vk_dispatchtables.cpp b/renderdoc/driver/vulkan/vk_dispatchtables.cpp index 2b453a941..c9825d595 100644 --- a/renderdoc/driver/vulkan/vk_dispatchtables.cpp +++ b/renderdoc/driver/vulkan/vk_dispatchtables.cpp @@ -30,32 +30,19 @@ #include -#if !defined(WIN32) -#include -#endif - static VkLayerDispatchTable replayDeviceTable = {0}; static VkLayerInstanceDispatchTable replayInstanceTable = {0}; static bool replay = false; -void InitReplayTables() +void InitReplayTables(void *vulkanModule) { replay = true; - // VKTODOLOW this won't work with multiple devices - will need a replay device table for each - // not all functions will succeed - some need to be fetched through the below InitDeviceReplayTable() - // VKTODOMED need to move this into os_specific #undef HookInit - -#ifdef WIN32 - #define HookInit(name) table.name = (CONCAT(PFN_vk, name))GetProcAddress(LoadLibraryA("vulkan-0.dll"), STRINGIZE(CONCAT(vk, name))) -#else - void *libhandle = dlopen("libvulkan.so", RTLD_NOW); - #define HookInit(name) table.name = (CONCAT(PFN_vk, name))dlsym(libhandle, STRINGIZE(CONCAT(vk, name))) -#endif + #define HookInit(name) table.name = (CONCAT(PFN_vk, name))Process::GetFunctionAddress(vulkanModule, STRINGIZE(CONCAT(vk, name))) { VkLayerDispatchTable &table = replayDeviceTable; @@ -75,6 +62,8 @@ void InitInstanceReplayTables(VkInstance instance) VkLayerInstanceDispatchTable *table = GetInstanceDispatchTable(NULL); RDCASSERT(table); + // we know we'll only have one instance, so this is safe + #define InstanceGPA(func) table->func = (CONCAT(PFN_vk, func))table->GetInstanceProcAddr(instance, STRINGIZE(CONCAT(vk, func))); InstanceGPA(GetPhysicalDeviceSurfaceSupportKHR) @@ -88,6 +77,8 @@ void InitDeviceReplayTables(VkDevice device) { VkLayerDispatchTable *table = GetDeviceDispatchTable(NULL); RDCASSERT(table); + + // VKTODOLOW this won't work with multiple devices - will need a replay device table for each #define DeviceGPA(func) table->func = (CONCAT(PFN_vk, func))table->GetDeviceProcAddr(device, STRINGIZE(CONCAT(vk, func))); diff --git a/renderdoc/driver/vulkan/vk_dispatchtables.h b/renderdoc/driver/vulkan/vk_dispatchtables.h index 2bc4c6e87..a11822390 100644 --- a/renderdoc/driver/vulkan/vk_dispatchtables.h +++ b/renderdoc/driver/vulkan/vk_dispatchtables.h @@ -34,7 +34,7 @@ #include -void InitReplayTables(); +void InitReplayTables(void *vulkanModule); void InitInstanceReplayTables(VkInstance instance); void InitDeviceReplayTables(VkDevice device); diff --git a/renderdoc/driver/vulkan/vk_linux.cpp b/renderdoc/driver/vulkan/vk_linux.cpp index d340916af..002f190c1 100644 --- a/renderdoc/driver/vulkan/vk_linux.cpp +++ b/renderdoc/driver/vulkan/vk_linux.cpp @@ -115,7 +115,7 @@ RENDERDOC_WindowHandle WrappedVulkan::GetHandleForSurface(const VkSurfaceDescrip return NULL; } -bool LoadVulkanLibrary() +void *LoadVulkanLibrary() { return Process::LoadModule("libvulkan.so"); } diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index 602fa1bb6..3223500f3 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -2153,13 +2153,15 @@ void VulkanReplay::SetProxyBufferData(ResourceId bufid, byte *data, size_t dataS } // in vk_replay_platform.cpp -bool LoadVulkanLibrary(); +void *LoadVulkanLibrary(); ReplayCreateStatus Vulkan_CreateReplayDevice(const char *logfile, IReplayDriver **driver) { RDCDEBUG("Creating a VulkanReplay replay device"); + + void *module = LoadVulkanLibrary(); - if(!LoadVulkanLibrary()) + if(module == NULL) { RDCERR("Failed to load vulkan library"); return eReplayCreate_APIInitFailed; @@ -2177,7 +2179,7 @@ ReplayCreateStatus Vulkan_CreateReplayDevice(const char *logfile, IReplayDriver return eReplayCreate_APIIncompatibleVersion; } - InitReplayTables(); + InitReplayTables(module); if(initParams.APIVersion != VK_API_VERSION) { diff --git a/renderdoc/driver/vulkan/vk_win32.cpp b/renderdoc/driver/vulkan/vk_win32.cpp index 15745432f..903e3c47f 100644 --- a/renderdoc/driver/vulkan/vk_win32.cpp +++ b/renderdoc/driver/vulkan/vk_win32.cpp @@ -72,7 +72,7 @@ RENDERDOC_WindowHandle WrappedVulkan::GetHandleForSurface(const VkSurfaceDescrip return winDesc->pPlatformWindow; } -bool LoadVulkanLibrary() +void *LoadVulkanLibrary() { return Process::LoadModule("vulkan-0.dll"); } diff --git a/renderdoc/hooks/hooks.h b/renderdoc/hooks/hooks.h index fba9770c0..c4a058b33 100644 --- a/renderdoc/hooks/hooks.h +++ b/renderdoc/hooks/hooks.h @@ -61,7 +61,7 @@ class Hook bool Initialize(const char *function, const char *module_name, void *destination_function_ptr) { - orig_funcptr = Process::GetFunctionAddress(module_name, function); + orig_funcptr = Process::GetFunctionAddress(Process::LoadModule(module_name), function); return Win32_IAT_Hook(&orig_funcptr, module_name, function, destination_function_ptr); } diff --git a/renderdoc/os/linux/linux_process.cpp b/renderdoc/os/linux/linux_process.cpp index c78ec1749..f43a173af 100644 --- a/renderdoc/os/linux/linux_process.cpp +++ b/renderdoc/os/linux/linux_process.cpp @@ -451,22 +451,16 @@ void Process::StartGlobalHook(const char *pathmatch, const char *logfile, const RDCUNIMPLEMENTED("Global hooking of all processes on linux"); } -bool Process::LoadModule(const char *module) +void *Process::LoadModule(const char *module) { - return dlopen(module, RTLD_NOW) != NULL; + return dlopen(module, RTLD_NOW); } -void *Process::GetFunctionAddress(const char *module, const char *function) +void *Process::GetFunctionAddress(void *module, const char *function) { - void *handle = dlopen(module, RTLD_NOW); + if(module == NULL) return NULL; - if(handle == NULL) return NULL; - - void *ret = dlsym(handle, function); - - dlclose(handle); - - return ret; + return dlsym(module, function); } uint32_t Process::GetCurrentPID() diff --git a/renderdoc/os/os_specific.h b/renderdoc/os/os_specific.h index 34b6ca739..96648042a 100644 --- a/renderdoc/os/os_specific.h +++ b/renderdoc/os/os_specific.h @@ -50,8 +50,8 @@ namespace Process uint32_t LaunchProcess(const char *app, const char *workingDir, const char *cmdLine); uint32_t LaunchAndInjectIntoProcess(const char *app, const char *workingDir, const char *cmdLine, const char *logfile, const CaptureOptions *opts, bool waitForExit); - bool LoadModule(const char *module); - void *GetFunctionAddress(const char *module, const char *function); + void *LoadModule(const char *module); + void *GetFunctionAddress(void *module, const char *function); uint32_t GetCurrentPID(); }; diff --git a/renderdoc/os/win32/win32_process.cpp b/renderdoc/os/win32/win32_process.cpp index 034a42a57..ac7a522cc 100644 --- a/renderdoc/os/win32/win32_process.cpp +++ b/renderdoc/os/win32/win32_process.cpp @@ -590,22 +590,20 @@ void Process::StartGlobalHook(const char *pathmatch, const char *logfile, const #endif } -bool Process::LoadModule(const char *module) +void *Process::LoadModule(const char *module) { HMODULE mod = GetModuleHandleA(module); if(mod != NULL) - return true; + return mod; - return LoadLibraryA(module) != NULL; + return LoadLibraryA(module); } -void *Process::GetFunctionAddress(const char *module, const char *function) +void *Process::GetFunctionAddress(void *module, const char *function) { - HMODULE mod = GetModuleHandleA(module); - if(mod == 0) - return NULL; + if(module == NULL) return NULL; - return (void *)GetProcAddress(mod, function); + return (void *)GetProcAddress((HMODULE)module, function); } uint32_t Process::GetCurrentPID()