wait on swapchain to reduce vsync latency
This commit is contained in:
parent
c7b5a41523
commit
e7bdb1c24f
@ -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);
|
||||
|
||||
@ -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:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user