@@ -33,6 +33,10 @@ void* D3D12Hook::Streamline::link_swapchain_to_cmd_queue(void* rcx, void* rdx, v
3333 return hook->get_original <decltype (link_swapchain_to_cmd_queue)>()(rcx, rdx, r8, r9);
3434 }
3535
36+ while (g_framework == nullptr ) {
37+ std::this_thread::yield ();
38+ }
39+
3640 std::scoped_lock _{g_framework->get_hook_monitor_mutex ()};
3741
3842 spdlog::info (" [Streamline] linkSwapchainToCmdQueue: {:x}" , (uintptr_t )_ReturnAddress ());
@@ -57,6 +61,39 @@ void* D3D12Hook::Streamline::link_swapchain_to_cmd_queue(void* rcx, void* rdx, v
5761 return result;
5862}
5963
64+ HRESULT WINAPI D3D12Hook::create_swapchain (IDXGIFactory4* factory, IUnknown* device, HWND hwnd, const DXGI_SWAP_CHAIN_DESC * desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC * p_fullscreen_desc, IDXGIOutput* p_restrict_to_output, IDXGISwapChain** swap_chain) {
65+ auto create_swap_chain_fn = s_create_swapchain_hook->get_original <decltype (D3D12Hook::create_swapchain)*>();
66+
67+ if (g_inside_d3d12_hook) {
68+ spdlog::info (" create_swapchain (inside D3D12 hook)" );
69+ return create_swap_chain_fn (factory, device, hwnd, desc, p_fullscreen_desc, p_restrict_to_output, swap_chain);
70+ }
71+
72+ spdlog::info (" create_swapchain called" );
73+
74+ while (g_framework == nullptr ) {
75+ std::this_thread::yield ();
76+ }
77+
78+ std::scoped_lock _{g_framework->get_hook_monitor_mutex ()};
79+
80+ bool hook_was_nullptr = g_d3d12_hook == nullptr ;
81+
82+ if (g_d3d12_hook != nullptr && g_framework->get_d3d12_hook () != nullptr ) {
83+ g_framework->on_reset (); // Needed to prevent a crash due to resources hanging around
84+ g_d3d12_hook->unhook (); // Removes all vtable hooks
85+ }
86+
87+ const auto result = create_swap_chain_fn (factory, device, hwnd, desc, p_fullscreen_desc, p_restrict_to_output, swap_chain);
88+
89+ // rather than waiting on the hook monitor to notice the hook isn't working
90+ if (!hook_was_nullptr) {
91+ g_framework->hook_d3d12 ();
92+ }
93+
94+ return result;
95+ }
96+
6097void D3D12Hook::hook_streamline (HMODULE dlssg_module) try {
6198 if (D3D12Hook::s_streamline.setup ) {
6299 return ;
@@ -325,10 +362,13 @@ bool D3D12Hook::hook() {
325362 return false ;
326363 }
327364
328- const auto ti = utility::rtti::get_type_info (swap_chain1);
329-
330365 try {
331- const auto swapchain_classname = ti != nullptr ? std::string_view{ti->name ()} : " unknown" ;
366+ const auto ti = utility::rtti::get_type_info (swap_chain1);
367+ const auto swapchain_classname = ti != nullptr && ti->name () != nullptr ? std::string_view{ti->name ()} : " unknown" ;
368+ const auto raw_name = ti != nullptr && ti->raw_name () != nullptr ? std::string_view{ti->raw_name ()} : " unknown" ;
369+
370+ spdlog::info (" Swapchain type info: {}" , swapchain_classname);
371+ spdlog::info (" Swapchain raw type info: {}" , raw_name);
332372
333373 if (swapchain_classname.contains (" interposer::DXGISwapChain" )) { // DLSS3
334374 spdlog::info (" Found Streamline (DLSSFG) swapchain during dummy initialization: {:x}" , (uintptr_t )swap_chain1);
@@ -346,6 +386,8 @@ bool D3D12Hook::hook() {
346386
347387 spdlog::info (" Finding command queue offset" );
348388
389+ m_command_queue_offset = 0 ;
390+
349391 // Find the command queue offset in the swapchain
350392 for (auto i = 0 ; i < 512 * sizeof (void *); i += sizeof (void *)) {
351393 const auto base = (uintptr_t )swap_chain1 + i;
@@ -442,6 +484,12 @@ bool D3D12Hook::hook() {
442484
443485 auto & present_fn = (*(void ***)target_swapchain)[8 ]; // Present
444486 m_present_hook = std::make_unique<PointerHook>(&present_fn, &D3D12Hook::present);
487+
488+ if (s_create_swapchain_hook == nullptr ) {
489+ auto & create_swapchain_fn = (*(void ***)factory)[15 ]; // CreateSwapChainForHwnd
490+ s_create_swapchain_hook = std::make_unique<PointerHook>(&create_swapchain_fn, &D3D12Hook::create_swapchain);
491+ }
492+
445493 m_hooked = true ;
446494 } catch (const std::exception& e) {
447495 spdlog::error (" Failed to initialize hooks: {}" , e.what ());
@@ -468,6 +516,10 @@ bool D3D12Hook::hook() {
468516}
469517
470518bool D3D12Hook::unhook () {
519+ while (g_framework == nullptr ) {
520+ std::this_thread::yield ();
521+ }
522+
471523 std::scoped_lock _{g_framework->get_hook_monitor_mutex ()};
472524
473525 if (!m_hooked) {
@@ -488,6 +540,10 @@ bool D3D12Hook::unhook() {
488540thread_local int32_t g_present_depth = 0 ;
489541
490542HRESULT WINAPI D3D12Hook::present (IDXGISwapChain3* swap_chain, uint64_t sync_interval, uint64_t flags, void * r9) {
543+ while (g_framework == nullptr ) {
544+ std::this_thread::yield ();
545+ }
546+
491547 std::scoped_lock _{g_framework->get_hook_monitor_mutex ()};
492548
493549 auto d3d12 = g_d3d12_hook;
@@ -620,6 +676,10 @@ HRESULT WINAPI D3D12Hook::present(IDXGISwapChain3* swap_chain, uint64_t sync_int
620676thread_local int32_t g_resize_buffers_depth = 0 ;
621677
622678HRESULT WINAPI D3D12Hook::resize_buffers (IDXGISwapChain3* swap_chain, UINT buffer_count, UINT width, UINT height, DXGI_FORMAT new_format, UINT swap_chain_flags) {
679+ while (g_framework == nullptr ) {
680+ std::this_thread::yield ();
681+ }
682+
623683 std::scoped_lock _{g_framework->get_hook_monitor_mutex ()};
624684
625685 spdlog::info (" D3D12 resize buffers called" );
@@ -705,6 +765,10 @@ HRESULT WINAPI D3D12Hook::resize_buffers(IDXGISwapChain3* swap_chain, UINT buffe
705765thread_local int32_t g_resize_target_depth = 0 ;
706766
707767HRESULT WINAPI D3D12Hook::resize_target (IDXGISwapChain3* swap_chain, const DXGI_MODE_DESC * new_target_parameters) {
768+ while (g_framework == nullptr ) {
769+ std::this_thread::yield ();
770+ }
771+
708772 std::scoped_lock _{g_framework->get_hook_monitor_mutex ()};
709773
710774 spdlog::info (" D3D12 resize target called" );
@@ -786,21 +850,3 @@ HRESULT WINAPI D3D12Hook::resize_target(IDXGISwapChain3* swap_chain, const DXGI_
786850
787851 return result;
788852}
789-
790- /* HRESULT WINAPI D3D12Hook::create_swap_chain(IDXGIFactory4* factory, IUnknown* device, HWND hwnd, const DXGI_SWAP_CHAIN_DESC* desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* p_fullscreen_desc, IDXGIOutput* p_restrict_to_output, IDXGISwapChain** swap_chain)
791- {
792- spdlog::info("D3D12 create swapchain called");
793-
794- auto d3d12 = g_d3d12_hook;
795-
796- d3d12->m_command_queue = (ID3D12CommandQueue*)device;
797-
798- if (d3d12->m_on_create_swap_chain) {
799- d3d12->m_on_create_swap_chain(*d3d12);
800- }
801-
802- auto create_swap_chain_fn = d3d12->m_create_swap_chain_hook->get_original<decltype(D3D12Hook::create_swap_chain)>();
803-
804- return create_swap_chain_fn(factory, device, hwnd, desc, p_fullscreen_desc, p_restrict_to_output, swap_chain);
805- }*/
806-
0 commit comments