Swap chain creation failed

Recommended Posts

I create my swap chain in the following way:

// Create a DXGI_SWAP_CHAIN_DESC1.
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {};
swap_chain_desc.Width = static_cast< UINT >(GetWidth());
swap_chain_desc.Height = static_cast< UINT >(GetHeight());
swap_chain_desc.Format = m_display_configuration->GetDisplayFormat();
swap_chain_desc.SampleDesc = m_display_configuration->GetMSAASampleDesc();
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_UNORDERED_ACCESS;
swap_chain_desc.BufferCount = 1u;
swap_chain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

// Create a DXGI_SWAP_CHAIN_FULLSCREEN_DESC.
DXGI_SWAP_CHAIN_FULLSCREEN_DESC swap_chain_fullscreen_desc = {};
swap_chain_fullscreen_desc.RefreshRate = m_display_configuration->GetDisplayRefreshRate();
swap_chain_fullscreen_desc.Windowed = TRUE;

// Get the IDXGISwapChain1.
ComPtr< IDXGISwapChain1 > swap_chain1;
const HRESULT result_swap_chain1 = dxgi_factory3->CreateSwapChainForHwnd(m_device.Get(), m_hwindow, &swap_chain_desc, &swap_chain_fullscreen_desc, nullptr, swap_chain1.ReleaseAndGetAddressOf());

The only thing that changed is the addition of DXGI_USAGE_UNORDERED_ACCESS (without DXGI_USAGE_UNORDERED_ACCESS, everything works fine).

The error code is 0x80070057 (E_INVALIDARG).

Any ideas what's missing? If I remove DXGI_USAGE_SHADER_INPUT, the issue remains; so it has clearly something to do with DXGI_USAGE_UNORDERED_ACCES.

Edited by matt77hias

Share on other sites

Is this D3D12? UAV access is not allowed on Swap Chains any more.

Share on other sites
1 minute ago, ajmiles said:

Is this D3D12? UAV access is not allowed on Swap Chains any more.

D3D11.2 (Windows 8.1)

Edited by matt77hias

Share on other sites

Oh, is your "Format" _SRGB? You aren't allowed to create UAVs of SRGB formatted textures.

Share on other sites
2 minutes ago, ajmiles said:

Oh, is your "Format" _SRGB? You aren't allowed to create UAVs of SRGB formatted textures.

DXGI_FORMAT_B8G8R8A8_UNORM

Share on other sites

Did you create your D3D Device with the D3D11_CREATE_DEVICE_DEBUG flag, you should be getting an error printed out for what's up?

Share on other sites
6 minutes ago, ajmiles said:

Oh, is your "Format" _SRGB? You aren't allowed to create UAVs of SRGB formatted textures.

The swapchain is an exception, you cannot create it with a typeless format, so there is a few bypass on aliasing views with different formats. ( not sure if this one is tho ).

As UAV for backbuffers is kind of deprecated anyway, i would recommend to not use that, create a separate resource and just perform a final copy to the swap chain at the end.

Share on other sites
8 minutes ago, ajmiles said:

Did you create your D3D Device with the D3D11_CREATE_DEVICE_DEBUG flag, you should be getting an error printed out for what's up?

D3D11 ERROR: ID3D11Device::CreateTexture2D: The format (0x57, B8G8R8A8_UNORM) cannot be bound as an UnorderedAccessView, or cast to a format that could be bound as an UnorderedAccessView.  Therefore this format does not support D3D11_BIND_UNORDERED_ACCESS. [ STATE_CREATION ERROR #92: CREATETEXTURE2D_UNSUPPORTEDFORMAT]
Exception thrown at 0x00007FF9EFEE95FC in FPS.exe: Microsoft C++ exception: _com_error at memory location 0x0000009E0273BE00.
D3D11 ERROR: ID3D11Device::CreateTexture2D: Returning E_INVALIDARG, meaning invalid parameters were passed. [ STATE_CREATION ERROR #104: CREATETEXTURE2D_INVALIDARG_RETURN]

Share on other sites

Unless you intended to use Direct2D, which I think requires use of BGRA, you may as well just create your swap chain as R8G8B8A8_UNORM.

Share on other sites

Based on the comments, it's maybe idd. better to use a separate resource (although this feels like a waste).

6 minutes ago, ajmiles said:

Unless you intended to use Direct2D, which I think requires use of BGRA, you may as well just create your swap chain as R8G8B8A8_UNORM.

Completely, overlooked that one in DXGI_FORMAT enum.

That one works!

Edited by matt77hias

Share on other sites

Correct, BGRA isn't supported as a UAV. I'm pretty sure it's an oversight, but UAV access was only ever enabled for the RGBA channel ordering.

Share on other sites
On 6-9-2017 at 8:23 PM, galop1n said:

As UAV for backbuffers is kind of deprecated anyway, i would recommend to not use that, create a separate resource and just perform a final copy to the swap chain at the end.

It is easy to fix, but since using the back buffer as a UAV seems so natural for GPGPU stuff, I wonder why forcing the detour in newer versions?

Share on other sites
8 hours ago, matt77hias said:

It is easy to fix, but since using the back buffer as a UAV seems so natural for GPGPU stuff, I wonder why forcing the detour in newer versions?

This is the answer of a Microsoft guy on the topic

Quote
D3D12 doesn't support unordered access on swapchain buffers, because the bindless nature of UAV access conflicts with the ability to synchronize/validate writes to those buffers. D3D11 does not have this restriction.

Share on other sites
6 minutes ago, galop1n said:

the bindless nature of UAV access

What do you mean with "bindless nature"?

Share on other sites

In D3D12, you can create a descriptor table containing 1,000,000 UAVs, and use data passed to the shader in order to determine which ones are being used. That, combined with the fact that they're GPU-side descriptors (which don't need to be initialized until GPU timeline execution of the command list) means that we can't just inspect which resources are "bound" to the pipeline via UAVs like we can with render targets, which only use CPU-side descriptors and only have 8 slots. We require the ability to track back buffer references in order to synchronize with the display so that VSync presents work correctly.

So, as long as that VSync synchronization is implicit, it precludes UAV access to those resources.

Share on other sites
17 minutes ago, matt77hias said:

What do you mean with "bindless nature"?

With DX11, it is easy, you want to write to an UAV, you have to bind it at a fixed slot with a single API, and it is represented with a fat iUnknow object.

With DX12, all you need is to allocate a slot in a descriptor heap, set the offset as a descriptor table and voilà. The thing is that the descriptor validity is up to the user, they are volatile, you could even set them after the command list is closed if you feel like it, or set some fence and trigger some nifty callback to late set a descriptor based on whatever. To be short, who knows what may be done !

This is why they can't assume anything and for the back buffer that has stronger requirements for being used by the compositor, it was not ok.

Create an account

Register a new account

• Forum Statistics

• Total Topics
628645
• Total Posts
2984028

• 9
• 9
• 9
• 10
• 21