[D3D12] CreateDevice fails

Started by
10 comments, last by JorisS 8 years, 3 months ago

Hello,

I'm currently implementing DirectX 12 into an engine that we developing last few months.

I have now a basic renderer that is able to render models, textures and using shaders.

But now I'm running into a problem I can't figure out anymore. Since last week the D3D12CreateDevice() is failing.

The error happens when I loop through the adapters to find any adapter with DX12 support.

The code is very similar from the samples:


ComPtr<IDXGIAdapter1> adapter;
	*ppAdapter = nullptr;

	for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &adapter); ++adapterIndex)
	{
		DXGI_ADAPTER_DESC1 desc;
		adapter->GetDesc1(&desc);

		if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
		{
			// Don't select the Basic Render Driver adapter.
			continue;
		}

		// Check to see if the adapter supports Direct3D 12, but don't create the actual device yet.
		HRESULT r = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr);
		if (SUCCEEDED(r))
		{
			break;
		}
		else
		{
			// Log why it cant create:
			IS_FAILED(r);
		}
	}

	*ppAdapter = adapter.Detach();

Return value of r:
HRESULT r = E_POINTER Invalid pointer.

The return value is bit unusual for me that I don't know what to do with it.

My GPU is a GeForce GT 650M, which should be able to run DirectX 12 to some point. (It also runs the DirectX12 Sample and Mini Engine.)

If there is more information needed, please tell and I will provide.

Many Thanks,

Joris

Advertisement

Since you're never actually passing in a device pointer I assume this code purely tests whether an adapter would support D3D12? You're running a GT 650M, which tells me you're probably running this on a laptop. Is there any chance this code is finding your laptop's integrated card (if you have one that is) first and is then failing because this card does not support D3D12?

I gets all your texture budgets!

If Radikalizm is right about finding the integrated instead of the discrete graphics, IIRC there is a control panel app that lets you switch between the two (force) on a per application basis.

edit - actually I'm not sure if it is per app.

-potential energy is easily made kinetic-

If Radikalizm is right about finding the integrated instead of the discrete graphics, IIRC there is a control panel app that lets you switch between the two (force) on a per application basis.

Better yet, adjust your code so it properly looks for the most suitable adapter so your integrated card can never be picked to create the device on. No need to mess with control panel settings.

I gets all your texture budgets!

Edit: disregard earlier comment, I didn't see Radikalizm's first post, and he's right, you can send nullptr as the last parameter to test adapter support for DX12

https://msdn.microsoft.com/en-us/library/windows/desktop/dn770336(v=vs.85).aspx

If Radikalizm is right about finding the integrated instead of the discrete graphics, IIRC there is a control panel app that lets you switch between the two (force) on a per application basis.

Better yet, adjust your code so it properly looks for the most suitable adapter so your integrated card can never be picked to create the device on. No need to mess with control panel settings.

I've heard the system will sometimes automatically choose the adapter based on "how demanding the application is". (has to do with power management) As in even if you enumerate the discrete it will give you integrated.(or something like that) And the only solution is the control panel app. Am I mistaken on this? I've never confirmed as I don't have a laptop.

-potential energy is easily made kinetic-

Thanks for the replies.

Since you're never actually passing in a device pointer I assume this code purely tests whether an adapter would support D3D12? You're running a GT 650M, which tells me you're probably running this on a laptop. Is there any chance this code is finding your laptop's integrated card (if you have one that is) first and is then failing because this card does not support D3D12?

Yes, I have indeed a integrated card but it loops through all adapters, so it should find the 650m anyway. And my integrated card doesn't support D3D12 so it fails anyway.

Logging the description of the adapter give me this:


The log file was opened
Info: Getting graphics hardware adapter..

Info: NVIDIA GeForce GT 650M  
Error: (DX12)
		File: -
		Line: 69
		Error: Invalid pointer

Info: Intel(R) HD Graphics 4000
Error: (DX12)
		File: -
		Line: 69
		Error: The specified device interface or feature level is not supported on this system.

So it should take the first adapter with D3D12 support.

If Radikalizm is right about finding the integrated instead of the discrete graphics, IIRC there is a control panel app that lets you switch between the two (force) on a per application basis.

Better yet, adjust your code so it properly looks for the most suitable adapter so your integrated card can never be picked to create the device on. No need to mess with control panel settings.

I've heard the system will sometimes automatically choose the adapter based on "how demanding the application is". (has to do with power management) As in even if you enumerate the discrete it will give you integrated.(or something like that) And the only solution is the control panel app. Am I mistaken on this? I've never confirmed as I don't have a laptop.

I'm not sure, if there is then it is new for me. I know that default nvidia drivers settings needs to be changed to make sure that the 650M comes first. http://puu.sh/mcoLg/c7d032f645.png (see "Preferred graphics processor", it needs to be set to High-performance NVIDIA processor). I will look around my control panel/power options. But it strange because I can run the directX12 samples without any problem..


I'm not sure, if there is then it is new for me. I know that default nvidia drivers settings needs to be changed to make sure that the 650M comes first. "Preferred graphics processor", it needs to be set to High-performance NVIDIA processor).

Does that control panel app have a per application setting for GPU? If so did you check it for your app? Maybe the setting in the control panel app isn't working properly, you could try uninstalling cleaning and then reinstalling the drivers. There used to be a program that does that... DDU? (display driver uninstaller) Don't know if its up to date though.

edit - Actually I think you're doing something wrong here:

D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr);

shouldn't the _uuidof be IID_PPV_ARGS

according to this page https://msdn.microsoft.com/en-us/library/windows/desktop/dn770336(v=vs.85).aspx

-potential energy is easily made kinetic-

The other thing I noticed is the last parameter of the D3D12CreateDevice method is optional as in I don't think it's allowed to be null.

edit - BTW here is the same code from one of the MS samples.

ThrowIfFailed(D3D12CreateDevice(
nullptr,
D3D_FEATURE_LEVEL_11_0,
IID_PPV_ARGS(&m_device)
));
you're using a explict adapter so the first nullptr isn't your thing but notice the last argument isn't there.

-potential energy is easily made kinetic-

The other thing I noticed is the last parameter of the D3D12CreateDevice method is optional as in I don't think it's allowed to be null.

edit - BTW here is the same code from one of the MS samples.

ThrowIfFailed(D3D12CreateDevice(
nullptr,
D3D_FEATURE_LEVEL_11_0,
IID_PPV_ARGS(&m_device)
));
you're using a explict adapter so the first nullptr isn't your thing but notice the last argument isn't there.

I think it can be null, either way I changed it to:


HRESULT r = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&tempDevice));

which still doesn't work sad.png

I have also tried uninstalling and installing Nvidia, doesn't work

This topic is closed to new replies.

Advertisement