Sign in to follow this  
Texus

CreateSwapChain failed

Recommended Posts

I recently started working with Direct3D 11, but I am having some problems with initializing it.

The code below failes on the last line. It returns the following hr: -2005270527.
I have tried to use GetLastError and then use HRESULT_FROM_WIN32, and I get the following error: "The specified module could not be found."

I know I can use [size="2"]D3D11CreateDeviceAndSwapChain, but I need the IDXGIFactory to disable ALT-ENTER.

[/size]Can someone please tell me what is wrong with the following code.
It worked with Direct3D 10 and the only difference is [size="2"]D3D11CreateDevice instead of D3D10CreateDevice.[/size]

[code]
D3D11CreateDevice(0, D3D_DRIVER_TYPE_HARDWARE, 0, 0, 0, 0, D3D11_SDK_VERSION, &Device, 0, &DevCon);

CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)&Factory);

DXGI_SWAP_CHAIN_DESC SwapChainDesc;
ZeroMemory(&SwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
SwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
SwapChainDesc.BufferDesc.Width = 800;
SwapChainDesc.BufferDesc.Height = 600;
SwapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
SwapChainDesc.BufferDesc.RefreshRate.Denominator = 0;
SwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
SwapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
SwapChainDesc.SampleDesc.Count = 1;
SwapChainDesc.SampleDesc.Quality = 0;
SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
SwapChainDesc.BufferCount = 1;
SwapChainDesc.OutputWindow = Window->hWnd;
SwapChainDesc.Windowed = true;
SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
SwapChainDesc.Flags = 0;

Factory->CreateSwapChain(Device, &SwapChainDesc, &SwapChain);
[/code]

Share this post


Link to post
Share on other sites
I could be wrong but the RefreshRate variable looks wrong to me. Should probably be set like this instead (for 60hz)

SwapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
SwapChainDesc.BufferDesc.RefreshRate.Denominator = 1;

Share this post


Link to post
Share on other sites
[quote name='Texus' timestamp='1306077369' post='4814242']
I recently started working with Direct3D 11, but I am having some problems with initializing it.

The code below failes on the last line. It returns the following hr: -2005270527.
[/quote]
That return code should correspond to one of [url="http://msdn.microsoft.com/en-us/library/ff476174%28v=VS.85%29.aspx"]these DirectX return codes[/url], which should at least help to better define and narrow down the problem.

Share this post


Link to post
Share on other sites
[quote name='yckx' timestamp='1306168610' post='4814640']
That return code should correspond to one of [url="http://msdn.microsoft.com/en-us/library/ff476174%28v=VS.85%29.aspx"]these DirectX return codes[/url].
[/quote]
I did found some return codes here that I was not comparing my hr with, but none of the return codes equals to my hr.

I finally found out what the hr is by using DXTrace. The error is DXGI_ERROR_INVALID_CALL.
I went to the msdn site and there I found that I would get this error when [i]pDesc[/i] or [i]ppSwapChain[/i] is NULL.

My SwapChain is NULL when calling the function, but isn't this supposed to be?

Share this post


Link to post
Share on other sites
[quote]
How do you declare SwapChain?
[/quote]
[code]
IDXGISwapChain SwapChain;
SwapChain = NULL;
[/code]
I already tried to don't make it NULL, but it has the same result.

I did however find a way to make my code work by replacing CreateDXGIFactory with:
[code]
IDXGIDevice* pDXGIDevice;
Device->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice);

IDXGIAdapter* pDXGIAdapter;
pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&pDXGIAdapter);

pDXGIAdapter->GetParent(__uuidof(IDXGIFactory), (void **)&Factory);
[/code]
Do I really need to do it this way or is there a way to just use CreateDXGIFactory?

Share this post


Link to post
Share on other sites
This is my function for creating the device and swap chain:

[code]
void D3DSysClass::CreateDeviceAndSwapChain()
{
HRESULT hr = S_OK;

UINT createDeviceFlags = 0;

#ifdef D3DDEBUG
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
UINT numDriverTypes = ARRAYSIZE( driverTypes );

D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0
};
UINT numFeatureLevels = ARRAYSIZE( featureLevels );

DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory( &sd, sizeof( sd ) );
sd.BufferCount = 1;
sd.BufferDesc.Width = pWindow->GetWidth();
sd.BufferDesc.Height = pWindow->GetHeight();
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_UNORDERED_ACCESS;
sd.OutputWindow = pWindow->GetHWnd();
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;

for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
{
g_driverType = driverTypes[driverTypeIndex];
hr = D3D11CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels,
D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext );
if( SUCCEEDED( hr ) )
break;
}
if( FAILED( hr ) )
{
MessageBox(NULL, L"D3D11CreateDeviceAndSwapChain() failed in D3DSysClass()", L"Error", MB_OK);
exit(0);
}
}
[/code]

Hope that helps.

Share this post


Link to post
Share on other sites
[url="http://msdn.microsoft.com/en-us/library/bb174537%28v=vs.85%29.aspx"]http://msdn.microsoft.com/en-us/library/bb174537%28v=vs.85%29.aspx[/url]

IDXGIFactory::CreateSwapChain takes [b]**ppSwapChain[/b] as it's param, you're passing it [b]*ppSwapChain[/b].

Try this instead:[code]IDXGISwapChain *SwapChain = NULL;
.
.
.

Factory->CreateSwapChain(Device, &SwapChainDesc, &SwapChain);[/code]

See the difference?

Share this post


Link to post
Share on other sites
[quote name='mhagain' timestamp='1306329164' post='4815583']
IDXGIFactory::CreateSwapChain takes [b]**ppSwapChain[/b] as it's param, you're passing it [b]*ppSwapChain[/b].
[/quote]
I am sorry, it is my post that is wrong, it should have been: [color="#660066"]IDXGISwapChain*[/color] [color="#660066"]SwapChain[/color][color="#666600"];[/color]

forsandifs: In normal situations I do something like that too, but as far as I know I need a IDXGIFactory to disable ALT-ENTER.

I will just continue working like I discribed in my last post. It makes my code a bit longer, but at least it works.

I want to thank all of you for your help.

Share this post


Link to post
Share on other sites
I looked around, and with some google searching, I found two instances of open source code that follows your method, and none that use IDXGIFactory::CreateSwapChain.

I also found [url="http://www.gamedev.net/blog/411/entry-1998218-d3d11-programming-tip-3/"]this journal entry[/url] and [url="http://www.gamedev.net/topic/564818-d3d11-swapchain-confusion/"]this thread[/url], which seem to help explain what's going on with D3D11 and DXGI.

Share this post


Link to post
Share on other sites
[quote name='yckx' timestamp='1306532693' post='4816575']
I also found [url="http://www.gamedev.net/blog/411/entry-1998218-d3d11-programming-tip-3/"]this journal entry[/url] and [url="http://www.gamedev.net/topic/564818-d3d11-swapchain-confusion/"]this thread[/url], which seem to help explain what's going on with D3D11 and DXGI.
[/quote]
Thanks for the links.

Share this post


Link to post
Share on other sites
You can use CreateDeviceAndSwapChain and still use the DXGIFactory to disable alt+enter, or atleast you can in DX10. All you have to do is make sure the adapter that you pass to CreateDeviceAndSwapChain has been retrieved from the DXGIFactory.
Also I wouldn't recommend setting up the BufferDesc member of the swapchain decription with hardcoded values like that. I would recommend setting it up with values and then using FindClosestMatchingMode on DXGIOutput to setup the one you pass in. This will make sure the values in it are values that are valid on the system it is running on. Especially the refreshrate parameter is often wrong if you hardcode it since it usually shouldn't actually be 60.0 but more like 59.999. You can use GetDisplayModeList on DXGIOutput to get a list of all valid modes on the system.
I have only done this in DX10 though so maybe some stuff changed but I would imagine it's still basically the same.

Share this post


Link to post
Share on other sites
If he isn't having this problem anymore, I still am.

I can create the swap chain fine using CreateDeviceAndSwapChain, but when I try to create the device and swap chain separately using the same swap chain desc, I get the '[url="http://msdn.microsoft.com/en-us/library/bb509553(v=VS.85).aspx"]DXGI_ERROR_INVALID_CALL[/url]' error returned from the CreateSwapChain function. Anyone have any ideas what I'm doing wrong or how these paths differ?

This works:
[code]
hr = D3D11CreateDeviceAndSwapChain( NULL, driverType, NULL, D3D11_CREATE_DEVICE_DEBUG,
NULL, NULL, D3D11_SDK_VERSION, &scd, &mpSwapChain, &mpDevice, NULL, &mpContext );
[/code]

This doesn't work (CreateSwapChain returns DXGI_ERROR_INVALID_CALL and mpSwapChain remains NULL).
[code]
hr = D3D11CreateDevice( NULL, driverType, NULL, D3D11_CREATE_DEVICE_DEBUG,
NULL, NULL, D3D11_SDK_VERSION, &mpDevice, NULL, &mpContext);

IDXGIFactory* pFactory;
hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&pFactory));

hr = pFactory->CreateSwapChain(mpDevice, &scd, &mpSwapChain);
[/code]

As mentioned, the help ([url="http://msdn.microsoft.com/en-us/library/bb174537(VS.85).aspx"]http://msdn.microsof...537(VS.85).aspx[/url]) suggests that this error means the desc or swapchain pointer is null. Neither of them is NULL in my case (the swapchain is NULL but the pointer to it is not). Also, some people mentioned that it might matter if I am opening it in windowed or full screen mode. It is definitely windowed mode in my case.

In case it matters, here is my swap chain desc:
[code]

DXGI_SWAP_CHAIN_DESC scd;
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));

scd.BufferCount = 1;
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
scd.BufferDesc.Width = width;
scd.BufferDesc.Height = height;
scd.BufferDesc.RefreshRate.Numerator = 60;
scd.BufferDesc.RefreshRate.Denominator = 1;
scd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
scd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scd.SampleDesc.Count = 1;
scd.SampleDesc.Quality = 0;
scd.OutputWindow = hWnd;
scd.Windowed = TRUE;
scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
[/code]

Share this post


Link to post
Share on other sites
For what it's worth, my swapchain and device creation looks a little like this and it works fine

[code]bool GraphicsDevice::Initialize(HWND windowHandle)
{
UINT flags = 0;
#ifdef _DEBUG
flags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

RECT rect;
::GetClientRect(windowHandle, &rect);
UINT width = static_cast<UINT>(rect.right);
UINT height = static_cast<UINT>(rect.bottom);

DXGI_SWAP_CHAIN_DESC sc = { 0 };
sc.BufferCount = 1;
sc.BufferDesc.Width = width;
sc.BufferDesc.Height = height;
sc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sc.BufferDesc.RefreshRate.Numerator = 60;
sc.BufferDesc.RefreshRate.Denominator = 1;
sc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sc.OutputWindow = windowHandle;
sc.SampleDesc.Count = 1;
sc.SampleDesc.Quality = 0;
sc.Windowed = true;

HRESULT hr = D3D11CreateDeviceAndSwapChain(
NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
flags,
NULL, /* feature levels */
0,
D3D11_SDK_VERSION,
&sc,
&swapChain.GetInterfacePtr(),
&device.GetInterfacePtr(),
&featureLevel,
&deviceContext.GetInterfacePtr());

if(FAILED(hr)) D3D::LogError(hr);

return hr == S_OK && CreateBuffers();
}[/code]

Share this post


Link to post
Share on other sites
[quote name='Neilo' timestamp='1313062424' post='4847623']
For what it's worth, my swapchain and device creation looks a little like this and it works fine
[/quote]


Cool! It works for me that way too. Does it still work for you if you break out the device and swap chain creation separately using the individual function calls?

Share this post


Link to post
Share on other sites
Yeah, I posted about that before here [url="http://www.gamedev.net/topic/564818-d3d11-swapchain-confusion/"]http://www.gamedev.net/topic/564818-d3d11-swapchain-confusion/[/url]

Useful if you want to render to multiple windows for tools or something, but not so much otherwise.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this