Prcuvu
Prcuvu

Reputation: 1

Why would D3D11CreateDeviceAndSwapChain fail when back buffer pixel format set to DXGI_FORMAT_B8G8R8X8_UNORM?

I am trying to port a piece of Direct3D 9 code to Direct3D 11. The original code uses an adapter format of D3DFMT_X8R8G8B8. I searched MSDN and found the equivalent in Direct3D 11 is DXGI_FORMAT_B8G8R8X8_UNORM. Here is my modified code for Direct3D 11 after creating the window:

DXGI_SWAP_CHAIN_DESC swap_chain_description;
ZeroMemory(&swap_chain_description, sizeof swap_chain_description);
swap_chain_description.BufferDesc.Width = window_width;
swap_chain_description.BufferDesc.Height = window_height;
swap_chain_description.BufferDesc.RefreshRate.Denominator = 1;
swap_chain_description.BufferDesc.Format = DXGI_FORMAT_B8G8R8X8_UNORM;
swap_chain_description.SampleDesc.Count = 1;
swap_chain_description.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swap_chain_description.BufferCount = 1;
swap_chain_description.OutputWindow = hWnd;
swap_chain_description.Windowed = TRUE;
swap_chain_description.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swap_chain_description.Flags = 0;

HRESULT hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &swap_chain_description, &dxgi_swap_chain, &d3d11_device, supported_feature_level, &d3d11_device_context);
if (FAILED(hr)) {
    return EXIT_FAILURE;
}

My code failed miserably when D3D11CreateDeviceAndSwapChain returned E_INVALIDARG. I changed the BufferDesc.Format to DXGI_FORMAT_R8G8B8A8_UNORM and the function returned S_OK as intended. Why would this happen? Is it DXGI_FORMAT_B8G8R8X8_UNORM being deprecated or something else beyond my knowledge?

Upvotes: 0

Views: 2137

Answers (2)

Chuck Walbourn
Chuck Walbourn

Reputation: 41057

For Direct3D 11, you should familiarize yourself with Direct3D hardware feature levels--see this blog post for some background. Modern Direct3D only supports a specific set of formats for 'display out' (i.e. a backbuffer) indicated by D3D11_FORMAT_SUPPORT_DISPLAY. These are supported by all Direct3D 11 compatible hardware (Feature levels 9.1 - 12.1):

DXGI_FORMAT_R8G8B8A8_UNORM
DXGI_FORMAT_B8G8R8A8_UNORM

DXGI_FORMAT_R8G8B8A8_UNORM_SRGB and B8G8R8A8_UNORM_SRGB are also supported as backbuffer formats when using 'older' presentation styles, but aren't directly supported for new flip style models DXGI_SWAP_EFFECT_FLIP_*. In those cases, you provide the *_SRGB format only for the render target view, not the backbuffer itself.

Direct3D Hardware Feature Level 10.0 or better also supports:

DXGI_FORMAT_R16G16B16A16_FLOAT
DXGI_FORMAT_R10G10B10A2_UNORM

See Anatomy of Direct3D 11 Create Device

If you are running Windows 8.1 or Windows 10 for your development machine, you should also look at how to enable the DXGI Debug Layer as this would have provided more information for this failure.

DXGI WARNING: IDXGIFactory::CreateSwapChain: Blt-model swap effects (DXGI_SWAP_EFFECT_DISCARD and DXGI_SWAP_EFFECT_SEQUENTIAL)
are legacy swap effects that are predominantly superceded by their
flip-model counterparts (DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL and DXGI_SWAP_EFFECT_FLIP_DISCARD).
Please consider updating your application to leverage flip-model swap effects
to benefit from modern presentation enhancements. More information
is available at http://aka.ms/dxgiflipmodel. [ MISCELLANEOUS WARNING #294: ]

DXGI ERROR: IDXGIFactory::CreateSwapChain: Flip model swapchains (DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL
and DXGI_SWAP_EFFECT_FLIP_DISCARD) only support the following Formats:
(DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_B8G8R8A8_UNORM,
DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R10G10B10A2_UNORM), assuming
the underlying Device does as well.
DXGI_SWAP_CHAIN_DESC{ SwapChainType = ..._HWND, BufferDesc = DXGI_MODE_DESC1{Width = 800, Height = 600, RefreshRate = DXGI_RATIONAL{ Numerator = 0, Denominator = 0 }, Format = B8G8R8X8_UNORM, ScanlineOrdering = ..._UNSPECIFIED, Scaling = ..._UNSPECIFIED, Stereo = FALSE }, SampleDesc = DXGI_SAMPLE_DESC{ Count = 1, Quality = 0 }, BufferUsage = 0x20, BufferCount = 2, OutputWindow = 0x0023094C, Scaling = ..._STRETCH, Windowed = TRUE, SwapEffect = ..._FLIP_DISCARD, AlphaMode = ..._IGNORE, Flags = 0x0 }[ MISCELLANEOUS ERROR #101: ]

Upvotes: 1

Fëamarto
Fëamarto

Reputation: 314

Now I never coded in Direct3D but the way I see this is generic.

D3DFMT_X8R8G8B8 is according to MSDN a 32-bit RGB pixel format, where 8 bits are reserved for each color. This means there is no alpha, the first byte is not used.

Your selected counterpart is similar in that respect - no alpha. MSDN: A four-component, 32-bit unsigned-normalized-integer format that supports 8 bits for each color channel and 8 bits unused.

The latter format is not actually a counterpart as it places colours in different bytes but this should not matter as long as you properly render all textures.

I think the problem is with your hardware not supporting a non-alpha format. Did you try running the old code on the same hardware? And are you sure the old DX3D does not add the alpha channel silently? Typically API will ask the driver for supported formats and will try to match with yours. On failure it will produce an error like that. Also some drivers will not accept a non-alpha format for hardware buffers. This is why the R8G8B8A8 format works because it supports alpha channel.

Upvotes: 0

Related Questions