Skip to main content
GameDev.net gamedev.net
🔒 Locked

Unable to toggle fullscreen mode

Started by Rasmus Jan 12, 2015 at 2:33 AM 6 replies 6.5k views
Original Post
Rasmus
Rasmus

Hi all, this is probably the second time in the last 4 years I posted here. I usually manage to solve the issue myself, but this issue has given me a real headace sad.png Hopefully there are someone out there that could help me, googling the issue has lead me nowhere...

The problem is this:

I have a laptop which has two GPU:s, one "Intel HD 4400 Graphics 4600" and one "NVIDIA GeForce GTX 860M". Right now I am developing a game which gives the player the option from start to choose which graphic adapter, which output device and what resolution the game should have. This is done by calling IDXGIFactory1, IDXGIAdapter1 and IDXGIOutput. The problem is that both graphic adaptors is found when enumerating them, but only the "Intel HD 4400 Graphics 4600" card has any IDXGIOutput options. This is not a problem when running the game in windowed mode on the NVIDIA card, but once I try to go fullscreen with "m_pSwapChain->SetFullscreenState" it gives me the error:

DXGI ERROR: IDXGISwapChain::GetContainingOutput: The swapchain's adapter does not control the output on which the swapchain's window resides. [ MISCELLANEOUS ERROR #80: ]

After a long and tedious search I decided to check out one of the Direct3D11 SDK tutorials called "BasicHLSL11", when running this tutorial the "NVIDIA GeForce GTX 860M" had IDXGIOutput options and works nicely in fullscreen. The weird thing is that it didn't have any output options for the Intel card.

When looking through the code to see what the differences were between my code and the code in the tutorial I found no differerance at all.
I ran this code directly under the winmain() in my game and in the tutorial and the result was different, and I can't for the world of it figure out what it is that is causing the different result.


        IDXGIFactory1* pDXGIFactory;
        CreateDXGIFactory1(__uuidof(IDXGIFactory), (void**)(&pDXGIFactory));
        IDXGIAdapter1* pAdapter = NULL;
        pDXGIFactory->EnumAdapters1( 0, &pAdapter ); // <--- Gives a different order of adaptors
        DXGI_ADAPTER_DESC adapterDesc;
        pAdapter->GetDesc(&adapterDesc);
        IDXGIOutput* pOutput;
        if( FAILED( pAdapter->EnumOutputs( 0, &pOutput ) ) )
        {
            __debugbreak(); // <--- Here it breaks when running it from my game and on the NVIDIA card, it doesn't break when running the BasicHLSL tutorial.
        }

Don't mind the lack of error checking in the code, I have shrunken it down deliberatly for this purpose and there are no errors or warnings.

- In the BasicHLSL tutorial the result was that EnumAdapters1 with index 0 gave me the NVIDIA card with output options, and Index 1 the Intel card with no output options.

- In my game the EnumAdapters1 with index 0 gave me the Intel card with output options, and Index 1 the NVIDIA card with no output options.

So as I see it, it seems that the primary adaptors is switched somehow, but I have no idea what is the reason for this switching. I was hoping that some of you could have some knowledge about this?

Looking forward too your reply :)

------------------------------Check out me work at www.dmtribute.webs.com
PKLoki
PKLoki

This might actually have nothing to do with your code and everything to do with the NVidia/Intel "Optimus" graphics card management. I have a similar laptop (though mine's an older NVidia GPU) and I've had similar problems. Try going into the NVidia control panel and adding your exe to the list of programs, then selecting the 860M explicitly as the GPU to use for output. The NVidia control panel might know which GPU to select for the DirectX samples, but it won't know for your own application.

Rasmus
Rasmus

Thank you for the reply, you were right! That was the issue, I entered the NVIDIA control panel and managed the 3D settings for the game and voila, the option became avalible :)

What annoys me a bit is that it can't be managed from inside the game, I figure some other people playing the game would experience the same issue and blame the programmer :(

------------------------------Check out me work at www.dmtribute.webs.com
PKLoki
PKLoki

Agreed, the same thing had occurred to me, though I never researched it much after I found the workaround. I guess Intel and NVidia between them must have some way to manage the defaults, maybe setting a registry key in the installer or something. Anyone have any more info?

MattSutherlin
MattSutherlin

This document might help you out. It explains how NVidia expects your app to work with Optimus, although it doesn't give you a lot of good details regarding allowing your app to select between cards on the fly.

It might not be very end user friendly, but the simplest way is to just force your app to always use the NVidia card when an Optimus setup exists with this code:


extern "C" {
 _declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
}
JohnnyCode
JohnnyCode

There are two GPU devices on the system (as usualy later on- intel cpu serve this purpose along with dedicated gpu device).

Consider your device creation technique to analyze what gpu device your porcess picks on (it should not switch for the process, at least not for its routine requested on the device explicitly acquired by d3d). See this strucute especially, at the beginning of your porgram, at the point of requesting the device upon the window handle

DXGI_ADAPTER_DESC adapterDesc;

PKLoki
PKLoki

Thanks MattSutherlin, that's a very useful document.

Something else that just occurred to me is that I developed my last game in VS2012 Express Edition and had to sort this out manually. I'm now working in VS2013 Community Edition for new projects and I don't remember having to worry about it since I switched. Not sure why that might be (and not displeased either).

Adam_42
Adam_42

If you look at the documentation for EnumAdapters1 - http://msdn.microsoft.com/en-us/library/windows/desktop/ff471336%28v=vs.85%29.aspx the order in which it finds adapters is well defined:

EnumAdapters1 first returns the adapter with the output on which the desktop primary is displayed. This adapter corresponds with an index of zero. EnumAdapters1 next returns other adapters with outputs. EnumAdapters1 finally returns adapters without outputs.

Optimus is the thing that's making it work differently for different programs.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.