wait on swapchain to reduce vsync latency

This commit is contained in:
jacob 2025-06-02 19:32:54 -05:00
parent c7b5a41523
commit e7bdb1c24f
2 changed files with 29 additions and 9 deletions

View File

@ -37,7 +37,7 @@
# define DX11_SHADER_DEBUG 0
#endif
#define DX11_SWAPCHAIN_FLAGS (DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING)
#define DX11_SWAPCHAIN_FLAGS (DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING | DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT)
#define DX11_SWAPCHAIN_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM)
#define DX11_SWAPCHAIN_RTV_FORMAT (DXGI_FORMAT_R8G8B8A8_UNORM_SRGB)
@ -196,9 +196,11 @@ GLOBAL struct {
#endif
ID3D11Device *dev;
ID3D11DeviceContext *devcon;
IDXGISwapChain1 *swapchain;
IDXGISwapChain2 *swapchain;
HANDLE swapchain_waitable;
struct dx11_texture backbuffer_texture;
ID3D11BlendState *blend_state;
@ -286,9 +288,9 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
init_shader_table();
HRESULT hr;
ID3D11Device *device;
ID3D11DeviceContext *context;
IDXGISwapChain1 *swapchain;
ID3D11Device *device = NULL;
ID3D11DeviceContext *context = NULL;
IDXGISwapChain2 *swapchain = NULL;
/* Create D3D11 device & context */
{
@ -357,16 +359,21 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
.Format = DX11_SWAPCHAIN_FORMAT,
.SampleDesc = { 1, 0 },
.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT,
.BufferCount = 2,
.BufferCount = 3,
.Scaling = DXGI_SCALING_NONE,
.Flags = DX11_SWAPCHAIN_FLAGS,
.AlphaMode = DXGI_ALPHA_MODE_IGNORE,
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD,
};
hr = IDXGIFactory2_CreateSwapChainForHwnd(factory, (IUnknown *)device, hwnd, &desc, NULL, NULL, &swapchain);
IDXGISwapChain1 *swapchain1 = NULL;
hr = IDXGIFactory2_CreateSwapChainForHwnd(factory, (IUnknown *)device, hwnd, &desc, NULL, NULL, &swapchain1);
ASSERT(SUCCEEDED(hr));
if (SUCCEEDED(hr)) {
IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain2, (void **)&swapchain);
}
/* Disable Alt+Enter changing monitor resolution to match window size */
IDXGIFactory_MakeWindowAssociation(factory, hwnd, DXGI_MWA_NO_ALT_ENTER);
@ -385,6 +392,13 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
G.swapchain = swapchain;
G.backbuffer_texture.is_backbuffer = true;
/* Create the swapchain waitable object */
if (G.swapchain != NULL) {
IDXGISwapChain2_SetMaximumFrameLatency(G.swapchain, 1);
G.swapchain_waitable = IDXGISwapChain2_GetFrameLatencyWaitableObject(G.swapchain);
ASSERT(G.swapchain_waitable != NULL);
}
struct string prof_ctx_name = LIT("D3d11 Context");
(UNUSED)prof_ctx_name;
__prof_dx11_ctx_alloc(G.profiling_ctx, G.dev, G.devcon, prof_ctx_name.text, prof_ctx_name.len);
@ -1962,13 +1976,18 @@ void gpu_swap_backbuffer(i32 vsync)
#endif
i32 flags = 0;
if (vsync == 0) {
if (vsync) {
if (G.swapchain_waitable != NULL) {
__profscope(Present wait);
WaitForSingleObjectEx(G.swapchain_waitable, 1000, TRUE);
}
} else {
flags = DXGI_PRESENT_ALLOW_TEARING;
}
gpu_capture_image_for_profiler();
{
__profscope(IDXGISwapchain_Present);
__profscope(Present);
IDXGISwapChain1_Present(G.swapchain, vsync, flags);
__prof_dx11_collect(G.profiling_ctx);
__profframe(0);

View File

@ -1211,6 +1211,7 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam,
result = DefWindowProcW(hwnd, msg, wparam, lparam);
} break;
case WM_ENTERSIZEMOVE:
case WM_MOVE:
case WM_MOVING:
case WM_SIZE: