5
\$\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\$
2
  • \$\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\$ Commented May 14, 2014 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\$ Commented May 15, 2014 at 17:06

2 Answers 2

3
\$\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\$
0
\$\begingroup\$

I am not sure why. But one more thing I've noticed is that if you want to switch to a fixed resolution after switching to full screen mode, you must first create the swapchain with width and height set to the desktop resolution OR create the swapchain with any width and height and then before calling SetFullScreenState, call ResizeTarget with the width and height set to the default desktop resolution (mostly for laptops, it's 1920x1080).

Now you can call ResizeTarget at any other point during your program to switch it to another resolution. I am not sure why it's like this, but it's something I observed and the only way I could perform this operation without starting out with a fullscreen swapchain.

If you start the swapchain with some other resolution, and when u set a particular resolution later on, it doesn't choose that resolution and chooses something else, or worse, just shows a blank screen.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .