there is another question with the same title on the site, but that one didn't solve my problem
I'm writing a Direct3D 11 desktop application, and I'm trying to implement waitable swap chain introduced by this document to reduce latency (specifically, the latency between when user moved the mouse and when the monitor displayed the change)
Now the problem is, I called WaitForSingleObject
on the handle returned by GetFrameLatencyWaitableObject
, but it did not wait at all and returned immediately, (which result in my application getting about 200 to 1000 fps, when my monitor is 60Hz) so my questions are:
Did even I understand correctly what a waitable swap chain does? According to my understanding, this thing is very similar to VSync (which is done by passing 1 for the
SyncInterval
param when callingPresent
on the swap chain), except instead of waiting for a previous frame to finish presenting on the screen at the end of a render loop (which is when we're callingPresent
), we can wait at the start of a render loop (by callingWaitForSingleObject
on the waitable object)If I understood correctly, then what am I missing? or is this thing only works for UWP applications? (because that document and its sample project are in UWP?)
here's my code to create swap chain:
SwapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
SwapChainDesc.Stereo = false;
SwapChainDesc.SampleDesc.Count = 1;
SwapChainDesc.SampleDesc.Quality = 0;
SwapChainDesc.BufferUsage = D3D11_BIND_RENDER_TARGET;
SwapChainDesc.BufferCount = 2;
SwapChainDesc.Scaling = DXGI_SCALING_STRETCH;
SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
SwapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
SwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
result = Factory2->CreateSwapChainForHwnd(Device.Get(), hWnd, &SwapChainDesc, &FullscreenDesc, nullptr, &SwapChain1);
if (FAILED(result)) return result;
here's my code to get waitable object:
result = SwapChain2->SetMaximumFrameLatency(1); // also tried setting it to "2"
if (FAILED(result)) return result;
WaitableObject = SwapChain2->GetFrameLatencyWaitableObject(); // also, I never call ResizeBuffers
if (WaitableObject == NULL) return E_FAIL;
and here's my code for render loop:
while (Running) {
if (WaitForSingleObject(WaitableObject, 1000) == WAIT_OBJECT_0) {
Render();
HRESULT result = SwapChain->Present(0, 0);
if (FAILED(result)) return result;
}
}