Skip to content

Commit bb36f7a

Browse files
committed
VSync is now fully disabled on inject
1 parent ca6bd8e commit bb36f7a

File tree

2 files changed

+88
-9
lines changed

2 files changed

+88
-9
lines changed

src/client/hook/impl/DXHooks.cpp

Lines changed: 85 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,52 @@
44
#include "client/render/Renderer.h"
55

66
namespace {
7+
typedef HRESULT(WINAPI* CreateSwapChainForCoreWindow_t)(
8+
IDXGIFactory2*,
9+
IUnknown*,
10+
IUnknown*,
11+
const DXGI_SWAP_CHAIN_DESC1*,
12+
IDXGIOutput*,
13+
IDXGISwapChain1**);
14+
15+
bool tearingSupported = false;
716
std::shared_ptr<Hook> PresentHook;
817
std::shared_ptr<Hook> ResizeBuffersHook;
918
std::shared_ptr<Hook> ExecuteCommandListsHook;
1019
}
1120

21+
void CheckTearingSupport() {
22+
ComPtr<IDXGIFactory5> factory5;
23+
if (SUCCEEDED(CreateDXGIFactory1(IID_PPV_ARGS(&factory5)))) {
24+
BOOL allowTearing = FALSE;
25+
if (SUCCEEDED(factory5->CheckFeatureSupport(
26+
DXGI_FEATURE_PRESENT_ALLOW_TEARING,
27+
&allowTearing,
28+
sizeof(allowTearing)))) {
29+
tearingSupported = allowTearing;
30+
}
31+
}
32+
}
33+
34+
CreateSwapChainForCoreWindow_t origCreateSwapChain = nullptr;
35+
36+
HRESULT WINAPI DXHooks::CreateSwapChainForCoreWindowHook(
37+
IDXGIFactory2* factory,
38+
IUnknown* device,
39+
IUnknown* window,
40+
const DXGI_SWAP_CHAIN_DESC1* desc,
41+
IDXGIOutput* output,
42+
IDXGISwapChain1** swapChain) {
43+
44+
DXGI_SWAP_CHAIN_DESC1 modifiedDesc = *desc;
45+
if (tearingSupported) {
46+
modifiedDesc.Flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
47+
}
48+
49+
return origCreateSwapChain(factory, device, window, &modifiedDesc,
50+
output, swapChain);
51+
}
52+
1253
HRESULT __stdcall DXHooks::SwapChain_Present(IDXGISwapChain* chain, UINT SyncInterval, UINT Flags) {
1354
if (Latite::getRenderer().hasInitialized()) {
1455
auto lock = Latite::getRenderer().lock();
@@ -28,18 +69,42 @@ HRESULT __stdcall DXHooks::SwapChain_Present(IDXGISwapChain* chain, UINT SyncInt
2869
// hasKilled = true;
2970
//}
3071

31-
return PresentHook->oFunc<decltype(&SwapChain_Present)>()(chain, SyncInterval, Flags);
72+
UINT presentFlags = Flags;
73+
UINT syncInterval;
74+
if (tearingSupported) {
75+
syncInterval = 0;
76+
presentFlags |= DXGI_PRESENT_ALLOW_TEARING;
77+
} else {
78+
syncInterval = SyncInterval;
79+
}
80+
81+
return PresentHook->oFunc<decltype(&SwapChain_Present)>()(chain, syncInterval, presentFlags);
3282
}
3383

34-
HRESULT __stdcall DXHooks::SwapChain_ResizeBuffers(IDXGISwapChain* chain, UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags) {
84+
HRESULT __stdcall DXHooks::SwapChain_ResizeBuffers(
85+
IDXGISwapChain* chain,
86+
UINT BufferCount,
87+
UINT Width,
88+
UINT Height,
89+
DXGI_FORMAT NewFormat,
90+
UINT SwapChainFlags) {
91+
3592
Latite::getRenderer().reinit();
36-
return ResizeBuffersHook->oFunc<decltype(&SwapChain_ResizeBuffers)>()(chain, BufferCount, Width, Height, NewFormat, SwapChainFlags);
93+
UINT newFlags = SwapChainFlags;
94+
if (tearingSupported) {
95+
newFlags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
96+
}
97+
98+
return ResizeBuffersHook->oFunc<decltype(&SwapChain_ResizeBuffers)>()(
99+
chain, BufferCount, Width, Height, NewFormat, newFlags);
37100
}
38101

39-
HRESULT __stdcall DXHooks::CommandQueue_ExecuteCommandLists(ID3D12CommandQueue* queue, UINT NumCommandLists, ID3D12CommandList* const* ppCommandLists) {
40-
auto lock = Latite::getRenderer().lock();
41-
Latite::getRenderer().setCommandQueue(queue);
42-
return ExecuteCommandListsHook->oFunc<decltype(&CommandQueue_ExecuteCommandLists)>()(queue, NumCommandLists, ppCommandLists);
102+
HRESULT __stdcall DXHooks::CommandQueue_ExecuteCommandLists(ID3D12CommandQueue* queue, UINT NumCommandLists,
103+
ID3D12CommandList* const* ppCommandLists) {
104+
auto lock = Latite::getRenderer().lock();
105+
Latite::getRenderer().setCommandQueue(queue);
106+
return ExecuteCommandListsHook->oFunc<decltype(&CommandQueue_ExecuteCommandLists)>()(
107+
queue, NumCommandLists, ppCommandLists);
43108
}
44109

45110
DXHooks::DXHooks() : HookGroup("DirectX") {
@@ -51,6 +116,8 @@ DXHooks::DXHooks() : HookGroup("DirectX") {
51116
ComPtr<ID3D11DeviceContext> dctx;
52117
ComPtr<ID3D12CommandQueue> cqueue;
53118

119+
CheckTearingSupport();
120+
54121
ThrowIfFailed(CreateDXGIFactory(IID_PPV_ARGS(&factory)));
55122
ThrowIfFailed(factory->EnumAdapters(0, adapter.GetAddressOf()));
56123

@@ -84,8 +151,9 @@ DXHooks::DXHooks() : HookGroup("DirectX") {
84151
D3D_FEATURE_LEVEL lvl[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1 };
85152

86153
D3D_FEATURE_LEVEL featureLevel;
87-
auto hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, lvl, 2, D3D11_SDK_VERSION,
88-
&swapChainDesc, swapChain.GetAddressOf(), device.GetAddressOf(), &featureLevel, dctx.GetAddressOf());
154+
auto hr = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, lvl, 2, D3D11_SDK_VERSION,
155+
&swapChainDesc, swapChain.GetAddressOf(), device.GetAddressOf(),
156+
&featureLevel, dctx.GetAddressOf());
89157

90158
uintptr_t* vftable = *reinterpret_cast<uintptr_t**>(swapChain.Get());
91159
uintptr_t* cqueueVftable = nullptr;
@@ -109,6 +177,14 @@ DXHooks::DXHooks() : HookGroup("DirectX") {
109177
DestroyWindow(hWnd);
110178
UnregisterClass(L"dummywnd", Latite::get().dllInst);
111179

180+
ComPtr<IDXGIFactory2> factory2;
181+
if (SUCCEEDED(factory.As(&factory2))) {
182+
void** vtable = *(void***)factory2.Get();
183+
MH_CreateHook(vtable[16], DXHooks::CreateSwapChainForCoreWindowHook,
184+
(void**)&origCreateSwapChain);
185+
MH_EnableHook(vtable[16]);
186+
}
187+
112188
PresentHook = addHook(vftable[8], SwapChain_Present, "IDXGISwapChain::Present");
113189
ResizeBuffersHook = addHook(vftable[13], SwapChain_ResizeBuffers, "IDXGISwapChain::ResizeBuffers");
114190

src/client/hook/impl/DXHooks.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44

55
class DXHooks : public HookGroup {
66
private:
7+
static HRESULT WINAPI CreateSwapChainForCoreWindowHook(IDXGIFactory2* pFactory, IUnknown* pDevice, IUnknown* pWindow, const DXGI_SWAP_CHAIN_DESC1* pDesc, IDXGIOutput* pRestrictToOutput, IDXGISwapChain1** ppSwapChain);
78
static HRESULT __stdcall SwapChain_Present(IDXGISwapChain* chain, UINT SyncInterval, UINT Flags);
89
static HRESULT __stdcall SwapChain_ResizeBuffers(IDXGISwapChain* chain, UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags);
910
static HRESULT __stdcall CommandQueue_ExecuteCommandLists(ID3D12CommandQueue* queue, UINT NumCommandLists, ID3D12CommandList* const* ppCommandLists);
11+
12+
void checkTearingSupport();
1013
public:
1114
DXHooks();
1215
};

0 commit comments

Comments
 (0)