IDXGIFactory4::CreateSwapChain returns DXGI_ERROR_INVALID_CALL - directx-12

I am creating my Swapchain like this
ComPtr<IDXGIFactory4> factory;
CreateDXGIFactory1(__uuidof(IDXGIFactory4), (void**)&factory);
DXGI_SWAP_CHAIN_DESC scd;
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));
scd.BufferCount = 2;
scd.BufferDesc.Width = mWidth;
scd.BufferDesc.Height = mHeight;
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
scd.OutputWindow = mHwnd;
scd.Windowed = true;
scd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
scd.SampleDesc.Count = 1;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
ComPtr<IDXGISwapChain> swapchain;
factory->CreateSwapChain(mQueue.Get(), &scd, &swapchain);
In Debug mode, this works fine, but in Release (either in x86 or x64), CreateSwapChain returns DXGI_ERROR_INVALID_CALL.
Can anyone explain to me why this is working in Debug mode, but not in Release mode?
Thanks!
Note: I'm using Direct3D 12

I found the solution! Yay :)
I forgot to link the DX12 libs....

Related

How to stop Direct3D 11 from stretching fullscreen to monitor size?

I am trying to make my Direct3D window fullscreen, with an 800x600 resolution. However, everything I try makes the screen stretch to cover the entire monitor, instead of just taking up an 800x600 area with black bars on the sides. The cursor is also stretched.
I create my swap chain with this DXGI_SWAP_CHAIN_DESC:
DXGI_SWAP_CHAIN_DESC sd{};
sd.BufferDesc.Width = 0;
sd.BufferDesc.Height = 0;
sd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 0;
sd.BufferDesc.RefreshRate.Denominator = 0;
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.BufferCount = 1;
sd.OutputWindow = hWnd;
sd.Windowed = TRUE;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
sd.Flags = 0;
Then I set the screen resolution using this code:
DEVMODEW devMode{};
devMode.dmSize = sizeof(devMode);
devMode.dmPelsWidth = width;
devMode.dmPelsHeight = height;
devMode.dmFields = DM_PELSHEIGHT | DM_PELSWIDTH;
LONG res = ChangeDisplaySettingsW(&devMode, CDS_FULLSCREEN);
Finally I set the swap chain to be fullscreen:
HRESULT hr = swap->SetFullscreenState(on, nullptr);
Also, in my window procedure I call this whenever WM_SIZE is received:
swapChain.reset(); // Destroy swap chain
context->ClearState();
if (FAILED(swap->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0))) throw Exception("Failed to resize buffers");
swapChain.emplace(swap.Get(), device.Get(), context.Get(), hWnd); // Recreate swap chain
I have tried using DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH in both the DXGI_SWAP_CHAIN_DESC and the ResizeBuffers, as well as calling IDXGISwapChain::ResizeTarget with my desired size, but I still get the same problem.

Direct3D11: Sharing a texture between devices: black texture

I have two D3D11 devices, each with its own context but on the same adapter.
I am trying to share a texture beween the two, but the texture I recieve on the other side is always black.
HRESULT hr;
// Make a shared texture on device_A / context_A
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Width = 1024;
desc.Height = 1024;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.CPUAccessFlags = 0;
desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
ID3D11Texture2D* copy_tex;
hr = device_A->CreateTexture2D(&desc, NULL, &copy_tex);
// Test the texture by filling it with some color
D3D11_RENDER_TARGET_VIEW_DESC rtvd = {};
rtvd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
rtvd.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
rtvd.Texture2D.MipSlice = 0;
ID3D11RenderTargetView* copy_tex_view = 0;
hr = device_A->CreateRenderTargetView(copy_tex, &rtvd, &copy_tex_view);
FLOAT clear_color[4] = {1, 0, 0, 1};
context_A->ClearRenderTargetView(copy_tex_view, clear_color);
// Now try to share it to device_B:
IDXGIResource* copy_tex_resource = 0;
hr = copy_tex->QueryInterface( __uuidof(IDXGIResource), (void**)&copy_tex_resource );
HANDLE copy_tex_shared_handle = 0;
hr = copy_tex_resource->GetSharedHandle(&copy_tex_shared_handle);
IDXGIResource* copy_tex_resource_mirror = 0;
hr = device_B->OpenSharedResource(copy_tex_shared_handle, __uuidof(ID3D11Texture2D), (void**)&copy_tex_resource_mirror);
ID3D11Texture2D* copy_tex_mirror = 0;
hr = copy_tex_resource_mirror->QueryInterface(__uuidof(ID3D11Texture2D), (void**)(&copy_tex_mirror));
However: the copy_tex_mirror texture is always black.
I don't get any HRESULT error codes, and can even use copy_tex_mirror on device_B / context_B normally, but I can't get the pixel data that I put into it on device_A.
Am I missing something?
Thanks in advance!
How do you know that the texture is always black? :-)
GPU operations are queued up by Direct3D, so when you open the shared resource on device_B, the ClearRenderTargetView() on device_A might not have been carried out yet. According to the MSDN library documentation on ID3D11Device::OpenSharedResource Method:
If a shared texture is updated on one device ID3D11DeviceContext::Flush must be called on that device.
We had a lot of issues such as this when we implemented shared textures between devices at work. If you add D3D9 or OpenGL to the mix, the pitfalls multiply..

' Error Code: E_FAIL ' when creating DirectX 10 Device and Swap Chain

I am working though some simple DX tutorials of the book 'Introduction to 3D Game Programming with Direct3D 10.0'. I encountered some problems when I use the function of D3D10CreateDeviceAndSwapChain. The following is the codeļ¼š
// Fill out a DXGI_SWAP_CHAIN_DESC to describe our swap chain.
DXGI_SWAP_CHAIN_DESC sd;
sd.BufferDesc.Width = mClientWidth;
sd.BufferDesc.Height = mClientHeight;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
// No multisampling.
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.BufferCount = 1;
sd.OutputWindow = mhMainWnd;
sd.Windowed = true;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
sd.Flags = 0;
// Create the device.
UINT createDeviceFlags = 0;
#if defined(DEBUG) || defined(_DEBUG)
createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;
#endif
HR( D3D10CreateDeviceAndSwapChain(
0, //default adapter
md3dDriverType,
//D3D10_DRIVER_TYPE_HARDWARE,
0, // no software device
createDeviceFlags,
D3D10_SDK_VERSION,
&sd,
&mSwapChain,
&md3dDevice) );
And the error information is that:
Error Code: E_FAIL (0x80004005) Calling:D3D10CreateDeviceAndSwapChain(.....
when I change the parameter 'createDeviceFlags' of D3D10CreateDeviceAndSwapChain to 0 , then It works. But why?? I want to know the reason, who can tell me ???
MSDN Says
To create a device that supports the debug layer, you must install the DirectX SDK (to get D3D10SDKLayers.DLL), and then specify the D3D10_CREATE_DEVICE_DEBUG flag when calling D3D10CreateDevice.
So, did you install the SDK and do you have D3D10SDKLayers.DLL?
I'm having this exact problem. I got it to work when I switched out the D3D10_CREATE_DEVICE_DEBUG flag for 0. I think my computer is having trouble creating the debug layer for some reason. Not sure why, but at least I was able to create a window that way.
I have exactly the same issue with VS2010 on Windows 8 with DirectX SDK June 2010.
If I disable the debug layer everything works fine. This is of course rather annoying because the debug layer of DirectX is rather handy.
I also tried this workaround for a succesful installation of the DirectX SDK, but it didn't help me:
http://blogs.msdn.com/b/chuckw/archive/2011/12/09/known-issue-directx-sdk-june-2010-setup-and-the-s1023-error.aspx
Is there already a solution for this?

`E_FAIL` when creating DirectX 10 Device and Swap Chain - _com_error

I am working though some simple DX tutorials, and have hit an early snag. I am working on both an old laptop and a new PC, so I'm using d3d10_1.lib which lets me use a 9 feature set. The PC, however, does support all the way to DX11, so nothing should be a problem on there.
So here's the function where it fails:
bool DirectX9Renderer::Initialise(HWND* handle)
{
//window handle
hWnd = handle;
//get window dimensions
RECT rc;
GetClientRect( *hWnd, &rc );
UINT width = rc.right - rc.left;
UINT height = rc.bottom - rc.top;
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
//set buffer dimensions and format
swapChainDesc.BufferCount = 2;
swapChainDesc.BufferDesc.Width = width;
swapChainDesc.BufferDesc.Height = height;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;;
//set refresh rate
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
//sampling settings
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.SampleDesc.Count = 1;
//output window handle
swapChainDesc.OutputWindow = *hWnd;
swapChainDesc.Windowed = true;
HRESULT result = D3D10CreateDeviceAndSwapChain1( // this is line 57
NULL,
D3D10_DRIVER_TYPE_HARDWARE,
NULL,
D3D10_CREATE_DEVICE_SINGLETHREADED | D3D10_CREATE_DEVICE_DEBUG,
D3D10_FEATURE_LEVEL_9_1,
D3D10_1_SDK_VERSION,
&swapChainDesc,
&pSwapChain,
&pD3DDevice
);
if(FAILED(result))
{
return FatalError("D3D device creation failed");
}
// there's more stuff after this, but I don't get that far
}
So the call to D3D10CreateDeviceAndSwapChain1 fails with the less-helpful error code E_FAIL.
There is a line in the Debug output too:
First-chance exception at 0x770f56c4 in TileTest.exe: Microsoft C++ exception: _com_error at memory location 0x00b6e8d4..
I have tried using D3D10_DRIVER_TYPE_REFERENCE and different D3D10_FEATURE_LEVEL_xx values, but it doesn't seem to work.
I think the problem may have been to do with the D3D10_CREATE_DEVICE_FLAG I sent in. I changed the D3D10_CREATE_DEVICE_SINGLETHREADED | D3D10_CREATE_DEVICE_DEBUG to 0 and it now works.
I tried to create the device inside a VMware virtual machine. It failed (device stayed NULL) until I changed the requested FEATURE_LEVEL from D3D10_FEATURE_LEVEL_10_1 to D3D10_FEATURE_LEVEL_9_3. I've heard this also helps other PCs with real hardware.

error C2228: left of '.DXGI_MODE' must have class/struct/union Direct X

I am trying to setup my swap chain Buffer but I get the following error
error C2228: left of '.DXGI_MODE' must have class/struct/union
1> type is 'DXGI_MODE_SCANLINE_ORDER'
Note sure what I am doing wrong. here is the code
DXGI_SWAP_CHAIN_DESC swapChainDesc;
// Set the width and height of the buffers in the swap chain
swapChainDesc.BufferDesc.Width = 640;
swapChainDesc.BufferDesc.Height = 480;
// Set the refresh rate. This is how often the buffers get swapped out
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
// Set the surface format of the buffers
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferDesc.ScanlineOrdering.DXGI_MODE;
//_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
// Set how the buffers are used. Since you are drawing to the buffers, they are
//considered a render target
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
// Set the number of back buffers, 1 is the minimum and normally sufficient
swapChainDesc.BufferCount = 1;
// A handle to the main application window
swapChainDesc.OutputWindow = hWnd;
// Set whether you are running in a window or fullscreen mode
swapChainDesc.Windowed = TRUE;
// How the buffers are swapped. Discard allows the buffers to be overwritten
//completely when swapped.
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_NONPREROTATED;
Shouldn't this bit
swapChainDesc.BufferDesc.ScanlineOrdering.DXGI_MODE;
//_SCANLINE_ORDER_UNSPECIFIED;
in fact be
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
?
Did'n you mean
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE;
instead of
swapChainDesc.BufferDesc.ScanlineOrdering.DXGI_MODE;
swapChainDesc.BufferDesc.ScanlineOrdering is an enum DXGI_MODE_SCANLINE_ORDER, not a class type.
Use something like the following instead:
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;