Skip to content

Commit 660018e

Browse files
committed
Experimental swapchain delay
- Adds an on-demand delay (up to 3 seconds) to wait for the runner to initialize D3D11 device and swapchain in Stage 2 hooks.
1 parent ea9e6b0 commit 660018e

File tree

3 files changed

+134
-40
lines changed

3 files changed

+134
-40
lines changed

YYToolkit/source/YYTK/Module Interface/Interface.cpp

Lines changed: 128 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,96 @@ namespace YYTK
3636
}
3737
}
3838

39+
AurieStatus YYTKInterfaceImpl::YkFetchD3D11Info(
40+
OUT ID3D11Device** DeviceObject,
41+
OUT IDXGISwapChain** Swapchain
42+
)
43+
{
44+
AurieStatus last_status = AURIE_SUCCESS;
45+
46+
// Call os_get_info, which gets us the necessary info
47+
RValue os_info_ds_map;
48+
last_status = CallBuiltinEx(
49+
os_info_ds_map,
50+
"os_get_info",
51+
nullptr,
52+
nullptr,
53+
{}
54+
);
55+
56+
// This is not checking the return value of os_get_info,
57+
// instead checking if we even called the function successfully.
58+
if (!AurieSuccess(last_status))
59+
{
60+
this->PrintError(
61+
__FILE__,
62+
__LINE__,
63+
"Failed to call os_get_info function! (%s)",
64+
AurieStatusToString(last_status)
65+
);
66+
67+
return last_status;
68+
}
69+
70+
// Pull everything needed from the DS List
71+
// We need to pass the pointer to the interface into the RValue initializer
72+
// here, because Aurie didn't yet put our interface in its array (we're being called from stage II init),
73+
// therefore the hidden ObGetInterface calls within the RValue would fail.
74+
RValue dx_swapchain, dx_device;
75+
76+
last_status = CallBuiltinEx(
77+
dx_device,
78+
"ds_map_find_value",
79+
nullptr,
80+
nullptr,
81+
{ os_info_ds_map, RValue("video_d3d11_device", this) }
82+
);
83+
84+
// This is not checking the return value of ds_map_find_value,
85+
// instead checking if we even called the function successfully.
86+
if (!AurieSuccess(last_status))
87+
{
88+
this->PrintError(
89+
__FILE__,
90+
__LINE__,
91+
"Failed to get video_d3d11_device! (%s)",
92+
AurieStatusToString(last_status)
93+
);
94+
95+
return AURIE_OBJECT_NOT_FOUND;
96+
}
97+
98+
last_status = CallBuiltinEx(
99+
dx_swapchain,
100+
"ds_map_find_value",
101+
nullptr,
102+
nullptr,
103+
{ os_info_ds_map, RValue("video_d3d11_swapchain", this) }
104+
);
105+
106+
// This is not checking the return value of ds_map_find_value,
107+
// instead checking if we even called the function successfully.
108+
if (!AurieSuccess(last_status))
109+
{
110+
this->PrintError(
111+
__FILE__,
112+
__LINE__,
113+
"Failed to get video_d3d11_swapchain! (%s)",
114+
AurieStatusToString(last_status)
115+
);
116+
117+
return AURIE_OBJECT_NOT_FOUND;
118+
}
119+
120+
if (DeviceObject)
121+
*DeviceObject = static_cast<ID3D11Device*>(dx_device.m_Pointer);
122+
123+
if (Swapchain)
124+
*Swapchain = static_cast<IDXGISwapChain*>(dx_swapchain.m_Pointer);
125+
126+
return AURIE_SUCCESS;
127+
}
128+
39129
size_t YYTKInterfaceImpl::YkDetermineFunctionEntrySize()
40130
{
41131
if (!m_FunctionsArray)
@@ -384,7 +474,7 @@ namespace YYTK
384474
&m_RValueArrayOffset
385475
);
386476
}
387-
477+
388478
if (!AurieSuccess(last_status))
389479
{
390480
this->PrintWarning(
@@ -526,76 +616,75 @@ namespace YYTK
526616
return last_status;
527617
}
528618

529-
// Find D3D11 stuff
530-
RValue os_info_ds_map;
619+
// Find window handle
620+
RValue window_handle;
621+
531622
last_status = CallBuiltinEx(
532-
os_info_ds_map,
533-
"os_get_info",
623+
window_handle,
624+
"window_handle",
534625
nullptr,
535626
nullptr,
536-
{}
627+
{ }
537628
);
538629

539630
if (!AurieSuccess(last_status))
540631
{
541632
this->PrintError(
542633
__FILE__,
543634
__LINE__,
544-
"Failed to call os_get_info function! (%s)",
635+
"Failed to get window_handle! (%s)",
545636
AurieStatusToString(last_status)
546637
);
547638

548639
return last_status;
549640
}
550641

551-
// Pull everything needed from the DS List
552-
// We need to pass the pointer to the interface into the RValue initializer
553-
// here, because Aurie didn't yet put our interface in its array, therefore
554-
// the hidden ObGetInterface calls within the RValue would fail.
555-
RValue dx_swapchain, window_handle;
556-
557-
last_status = CallBuiltinEx(
558-
dx_swapchain,
559-
"ds_map_find_value",
560-
nullptr,
561-
nullptr,
562-
{ os_info_ds_map, RValue("video_d3d11_swapchain", this) }
563-
);
642+
m_WindowHandle = reinterpret_cast<HWND>(window_handle.m_Pointer);
564643

565-
if (!AurieSuccess(last_status))
644+
// Fetch D3D11 info:
645+
//
646+
// There will be always at least one iteration.
647+
// The maximum wait time is determined by the value of d3d11_try_limit
648+
// prior to the loop.
649+
//
650+
// The os_get_info function may be called up to d3d11_try_limit times,
651+
// with the wait time (in milliseconds) being equal to d3d11_try_limit * 10.
652+
int d3d11_try_limit = 300;
653+
654+
while (d3d11_try_limit > 0)
566655
{
567-
this->PrintWarning(
568-
__FILE__,
569-
__LINE__,
570-
"Failed to get video_d3d11_swapchain! (%s)",
571-
AurieStatusToString(last_status)
656+
last_status = YkFetchD3D11Info(
657+
nullptr, // unused
658+
&m_EngineSwapchain
572659
);
573-
}
574660

575-
// Find window handle
576-
last_status = CallBuiltinEx(
577-
window_handle,
578-
"window_handle",
579-
nullptr,
580-
nullptr,
581-
{ }
582-
);
583661

662+
// If we succeeded, **and got the swapchain** we can simply break out without sleeping
663+
// Otherwise, wait 10ms and try again.
664+
if (AurieSuccess(last_status) && m_EngineSwapchain)
665+
break;
666+
667+
Sleep(10);
668+
669+
// Decrement our try counter, as to not get stuck in an infinite
670+
// loop, if for some reason the pointers never actually get set.
671+
d3d11_try_limit--;
672+
}
673+
674+
// When we get here, either we ran out of our "try limit" or we broke out.
675+
// If we broke out, AurieSuccess(last_status) will pass.
584676
if (!AurieSuccess(last_status))
585677
{
586678
this->PrintError(
587679
__FILE__,
588680
__LINE__,
589-
"Failed to get window_handle! (%s)",
681+
"Failed to fetch D3D11 info! (%s)",
590682
AurieStatusToString(last_status)
591683
);
592684

593685
return last_status;
594686
}
595687

596-
m_EngineSwapchain = reinterpret_cast<IDXGISwapChain*>(dx_swapchain.m_Pointer);
597-
m_WindowHandle = reinterpret_cast<HWND>(window_handle.m_Pointer);
598-
599688
assert(m_EngineSwapchain != nullptr);
600689

601690
last_status = Hooks::HkInitialize(

YYToolkit/source/YYTK/Module Interface/Interface.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ namespace YYTK
118118
}
119119
}
120120

121+
Aurie::AurieStatus YkFetchD3D11Info(
122+
OUT ID3D11Device** DeviceObject,
123+
OUT IDXGISwapChain** Swapchain
124+
);
125+
121126
size_t YkDetermineFunctionEntrySize();
122127

123128
// === Interface Functions ===

YYToolkit/source/YYTK/Shared.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
#define YYTK_MAJOR 3
1111
#define YYTK_MINOR 3
12-
#define YYTK_PATCH 2
12+
#define YYTK_PATCH 3
1313

1414
#ifndef YYTK_CPP_VERSION
1515
#ifndef _MSVC_LANG

0 commit comments

Comments
 (0)