c - 当后台缓冲区像素格式设置为 DXGI_FORMAT_B8G8R8X8_UNORM 时,为什么 D3D11CreateDeviceAndSwapChain 会失败?

标签 c direct3d direct3d11

我正在尝试将一段 Direct3D 9 代码移植到 Direct3D 11。原始代码使用适配器格式 D3DFMT_X8R8G8B8 。我搜索了 MSDN,发现 Direct3D 11 中的等效项是 DXGI_FORMAT_B8G8R8X8_UNORM 。这是创建窗口后我对 Direct3D 11 的修改代码:

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;
}

D3D11CreateDeviceAndSwapChain 时,我的代码惨遭失败。返回E_INVALIDARG 。我改变了BufferDesc.FormatDXGI_FORMAT_R8G8B8A8_UNORM该函数返回 S_OK如预期。为什么会出现这种情况呢?是DXGI_FORMAT_B8G8R8X8_UNORM被弃用还是我不知道的其他事情?

最佳答案

对于 Direct3D 11,您应该熟悉 Direct3D hardware feature levels --参见this blog post一些背景。现代 Direct3D 仅支持由 D3D11_FORMAT_SUPPORT_DISPLAY 指示的一组特定的“显示输出”格式(即后备缓冲区)。所有 Direct3D 11 兼容硬件都支持这些(功能级别 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 硬件功能级别 10.0 或更高版本还支持:

DXGI_FORMAT_R16G16B16A16_FLOAT
DXGI_FORMAT_R10G10B10A2_UNORM

参见Anatomy of Direct3D 11 Create Device

如果您的开发计算机运行的是 Windows 8.1 或 Windows 10,您还应该了解如何启用 DXGI Debug Layer因为这将为这次失败提供更多信息。

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: ]

关于c - 当后台缓冲区像素格式设置为 DXGI_FORMAT_B8G8R8X8_UNORM 时,为什么 D3D11CreateDeviceAndSwapChain 会失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58129485/

相关文章:

Direct3D 场景之上的 QtQuick 2.0 场景

c++ - 在支持 11 的机器上最高 D3D_FEATURE_LEVEL 是 9.3

d - D语言释放资源

c - C中的Read()整数

c++ - IDXGIKeyedMutex::ReleaseSync 什么时候呈现 "done"?

c++ - DirectX:用完 Visual Studio 时图形失真

c++ - 我什么时候应该调整 Direct3D 11 后缓冲区的大小以防止其在调整大小期间被拉伸(stretch)?

c - stddef.h |212|错误 : expected ‘=’ , ‘,’ 、 ‘;’ 、 ‘asm’ 或 ‘__attribute__’ 在 ‘typedef’ 之前

c - 使用c从单板计算机写入mysql数据库

c++ - 如何仅在 C 中将 SIGINT 发送到后台进程