I am currently writing a Directx 11 engine and have problems with the resolution when switching to exclusive fullscreen on my 1440p monitor. If i call SetFullscreenState(TRUE, NULL), the screen changes modes from 2560x1440 to 1920x1440 and my windows gets stretched. The WM_SIZE message also contains the size 1920x1440.
My initialization code (without error checking):
DXGI_SWAP_CHAIN_DESC swap_chain_desc = {0};
swap_chain_desc.BufferDesc.Width = window_data.width;
swap_chain_desc.BufferDesc.Height = window_data.height;
swap_chain_desc.BufferDesc.Format = DXGI_FORMAT.B8G8R8A8_UNORM;
swap_chain_desc.BufferDesc.Scaling = DXGI_MODE_SCALING.STRETCHED;
swap_chain_desc.SampleDesc.Count = 1;
swap_chain_desc.SampleDesc.Quality = 0;
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swap_chain_desc.BufferCount = 2;
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT.FLIP_DISCARD;
swap_chain_desc.OutputWindow = window_data.window_handle;
swap_chain_desc.Windowed = true;
//swap_chain_desc.Flags |= DXGI_SWAP_CHAIN_FLAG.ALLOW_MODE_SWITCH;
D3D_FEATURE_LEVEL feature_level;
UINT flags = D3D11_CREATE_DEVICE_FLAG.DEBUG;
HRESULT hr = D3D11CreateDeviceAndSwapChain(null, D3D_DRIVER_TYPE.HARDWARE, null, flags, null, 0, D3D11_SDK_VERSION,
&swap_chain_desc, &swap_chain, &device, &feature_level, &device_context);
d3d11_data.current_swap_chain_flags = swap_chain_desc.Flags;
When i get a WM_SIZE message, i resize the swap chain to the size passed as lParam. I also make sure not to change the swap chain flags when resizing:
UINT width = LOWORD(lParam);
UINT height = HIWORD(lParam);
d3d11_data.device_context.OMSetRenderTargets(0, null, null);
d3d11_data.render_target_view.Release();
HRESULT hr = d3d11_data.swap_chain.ResizeBuffers(0, width, height, DXGI_FORMAT.UNKNOWN, d3d11_data.current_swap_chain_flags);
ID3D11Texture2D framebuffer;
hr = d3d11_data.swap_chain.GetBuffer(0, &IID_ID3D11Texture2D, cast(void**)&framebuffer);
hr = d3d11_data.device.CreateRenderTargetView(framebuffer, null, &d3d11_data.render_target_view);
framebuffer.Release();
d3d11_data.device_context.OMSetRenderTargets(1, &d3d11_data.render_target_view, null);
D3D11_VIEWPORT viewport = {0};
viewport.Width = width;
viewport.Height = height;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
d3d11_data.device_context.RSSetViewports(1, &viewport);
I do not get any debug output nor do any of these functions return an error code. Things i have tried:
Messing with the compatibility setting of the application (DPI, "fullscreen optimization").
Ignoring the size passed with WM_SIZE and resizing the swap chain to 2560x1440.
Passing the DXGI_SWAP_CHAIN_FLAG.ALLOW_MODE_SWITCH flag and setting the render target to 2560x1440 using ResizeTarget and a DXGI_MODE_DESC optained via mode enumaration. This will change the refresh rate to e.g. 60Hz, but the resolution will still be 1920x1440.
Using a different windowed resolution before going fullscreen.
Enabling DXGI debug output via DXGIGetDebugInterface
None of them had any visible effect on the result. Windowed fullscreen via SetWindowPos works fine at the correct resolution. Any ideas on what might be happening?
assert(!FAILED(hr));
checks as a bare minimum when calling functions that return an HRESULT. \$\endgroup\$