4
\$\begingroup\$

In my application I can switch back and forth between windowed and fullscreen mode using IDXGISwapChain::SetFullscreenState. When the WM_SIZE is handled, IDXGISwapChain::ResizeBuffers is called in response. This works fine and when entering fullscreen mode DXGI chooses the desktop resolution.

The problem comes when I'm trying to change resolution while remaining in fullscreen. I try to change resolution by using IDXGISwapChain::ResizeTarget. The mode description I'm trying to switch to is aquired by using IDXGIOutput::GetDisplayModeList, so it should be valid. When doing the resize I get the usual blinking that happens when I enter fullscreen, but nothing has changed; the resolution is still the same and there's no WM_SIZE message being generated like in Choosing the DXGI Output and Size.

DXGI best practices also contains alot of information but it didn't help me.

I am using the DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH flag when creating the swap chain and I have also tried using IDXGIFactory::MakeWindowAssociation with the DXGI_MWA_NO_WINDOW_CHANGES and DXGI_MWA_NO_ALT_ENTER flags to no avail.

If I hardcode the swap chain to be created in fullscreen mode using a low resolution I can see the mouse cursor being jagged and larger, and this visual difference is not present when changing resolution.

Am I possibly getting the concepts wrong here? Am I supposed to get a WM_SIZE message after calling ResizeTarget? How are the display mode and back buffer related? I know that when the front buffer size is changed the back buffer should be resized to match in order to do flips instead of blits according to the links, which is why it's recommended to do the resize when the application gets the WM_SIZE message.

In a few of the similar questions I've found there are discussions about it maybe being a bug, but they all just died out with no final answer.

EDIT: I just tried to manually call OnResize (my method actually calling ResizeBuffers and so forth) after I attempt to change resolution and the following warning shows up in the debugger (not visible before):

DXGI WARNING: IDXGISwapChain::Present: Fullscreen presentation inefficiencies incurred due to application not using IDXGISwapChain::ResizeBuffers appropriately, specifying a DXGI_MODE_DESC not available in IDXGIOutput::GetDisplayModeList, or not using DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH.DXGI_SWAP_CHAIN_DESC::BufferDesc = { 800, 600, { 60, 1 }, R8G8B8A8_UNORM_SRGB, 0, 0 }; DXGI_SWAP_CHAIN_DESC::SampleDesc = { 1, 0 }; DXGI_SWAP_CHAIN_DESC::Flags = 0; [ MISCELLANEOUS WARNING #98: ]

The new resolution (800x600) seems to be set, but note that the Flags member is 0. Shouldn't it be 0x2? Could that be the reason the resolution doesn't have any effect? The flag is set in the swap chain description right before the swap chain is created so I don't understand how it's changed to 0.

EDIT 2: In a tiny remark at the bottom of the DXGI_SWAP_CHAIN_FLAG documentation it says that ResizeBuffers can reset or change the flags. I took a look at my code and there it was: flag was set to zero (reading my book I must have accepted it as reusing the old flag or something). I changed it to allow mode switch and voilá, resolution changed and I got my WM_SIZE. I did however get a couple of warnings about presentation inefficiencies but that was expected, and I have plans on how to fix those.

\$\endgroup\$
  • \$\begingroup\$ Re: your edit 2: it looks like you've solved your problem; if so you should post it as an answer and accept it (yes, SE allows this). \$\endgroup\$ – Maximus Minimus May 14 '14 at 19:50
  • \$\begingroup\$ Indeed, last time I had to wait a while so I figured I had to do the same now. Answer incoming. \$\endgroup\$ – Andreas Flöjt May 15 '14 at 17:06
2
\$\begingroup\$

If anyone else stumbles across this problem:

For me, the underlying problem was that the swap chain flag was reset even though I explicitly set the DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH when creating the swap chain. It turns out that IDXGISwapChain::ResizeBuffers is able to reset or change the swap chain flags. I used a value of zero (probably thinking that it would not alter anything) which disabled mode change. Changing it to allow mode switches resulted in IDXGISwapChain::ResizeTarget properly switching display mode and generating a WM_SIZE message.

Am I possibly getting the concepts wrong here? Am I supposed to get a WM_SIZE message after calling ResizeTarget?

Yes, ResizeTarget does generate a WM_SIZE message (even if you're remaining in fullscreen).

(If you have any problem regarding DXGI you really should follow the links of the original post; they're stuffed with good information)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.