directx-11 - 创建交换链时如何解决此多重采样错误?
问题描述
我在创建交换链时收到关于多重采样的 DXGI 错误,在尝试解决此错误数小时后需要一些帮助。
我正在为学习 Direct3D 11 设置一个简单的窗口。我尝试更改 DXGI_SWAP_CHAIN_DESC1 结构中的 SampleDesc.Count 和 SampleDesc.Quality,但仍然出现错误。
// dxgiFactory is using interface IDXGIFactory7
// d3dDevice5 is using interface ID3D11Device5
ComPtr<IDXGISwapChain1> dxgiSwapChain1;
DXGI_SWAP_CHAIN_DESC1 desc;
desc.Width = 800;
desc.Height = 400;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.Stereo = FALSE;
desc.SampleDesc.Count = 0;
desc.SampleDesc.Quality = 0;
desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
desc.BufferCount = 3;
desc.Scaling = DXGI_SCALING_STRETCH;
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
desc.AlphaMode = DXGI_ALPHA_MODE_STRAIGHT;
desc.Flags = 0;
hr = dxgiFactory->CreateSwapChainForHwnd(d3dDevice5.Get(), hWnd, &desc, nullptr, nullptr, &dxgiSwapChain1);
调试输出:
DXGI ERROR: IDXGIFactory::CreateSwapChain: Flip model swapchains (DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL and DXGI_SWAP_EFFECT_FLIP_DISCARD) do not support multisampling.
如何解决此错误?
解决方案
TL;DR要么将翻转模型更改为旧模型,DXGI_SWAP_EFFECT_DISCARD
要么创建一个您明确解析的 MSAA 渲染目标。
- 将您的交换链创建为一个样本(即没有 MSAA)。
- 创建使用一个或多个样本(即 MSAA)的渲染目标纹理。
- 为您的 MSAA 渲染目标创建渲染目标视图
- 每一帧,渲染到您的 MSAA 渲染目标,然后
ResolveSubresource
到交换链后台缓冲区——或其他一些单样本缓冲区——,然后是Present
.
有关详细的代码示例,请参阅GitHub。
您也无法使用新模型将其创建为
DXGI_FORMAT_*_SRGB
伽马校正交换链。您可以为非 sRGB 的交换链DXGI_SWAP_EFFECT_FLIP_*
创建一个渲染目标视图以获得相同的效果。DXGI_FORMAT_*_SRGB
MSAA 和 sRGB 以及在 Windows 10 Fall Creators Update (16299) 或更高版本中修复的新翻盖模型存在一些问题。如果您使用的是 DirectX 12,则无法选择使用较旧的交换效果,因此您必须直接实现 MSAA 渲染目标。再次,请参阅GitHub。
在“Directx 12 / Vulkan 之前”的日子里,DirectX 通过在幕后为您做很多事情,使启用 MSAA 变得很容易。它将为显示创建一个非 MSAA 渲染目标,为您返回一个用于渲染的 MSAA 渲染目标,并作为Present
. 这很容易,但也有点浪费。
使用 DirectX 12 的新“无魔法”方法,您必须在应用程序中明确执行此操作。在实际游戏中,您无论如何都希望这样做,因为您通常会进行大量后期处理,并希望在解析之前做好解析,Present
甚至进行其他类型的解析(FXAA、MLAA、SMAA)。例如:
Render 3D scene to a floating-point MSAA render target
->
Resolve to a single-sample floating-point render target
->
Perform tone-mapping/color-grading/blur/bloom/etc.
->
Render UI/HUD
->
Perform HDR10 signal generation/gamma-correction/color-space warp
->
Present
正如您从该流程中看到的那样,除了玩具示例或示例代码之外,让交换链成为 MSAA 是非常愚蠢的。
要了解现代游戏有多少是在进行多次渲染,请参阅此博客文章
请参阅适用于DX 11和DX12的 DirectX 工具包
更新:我在最近的一篇博文中详细介绍了这一点
推荐阅读
- javascript - Firefox:第一个 CORS 请求被阻止,第二个有效
- processing - 如何为处理中的饼图创建单独的类选项卡?
- iis - IIS 页面缓冲慢下来
- r - 有没有办法在 dplyr 中对矩阵进行矢量化?
- reactjs - 单个 url 下的不同静态页面,取决于 cookie
- pdf - 这个PDF有问题吗?
- javascript - 1700 小时后的暗模式
- php - 如何处理两个相邻的 JSON 对象?
- python - 将 ripgrep 的输出通过管道传输到 Python 进行过滤(将文件名与匹配项分开)
- jsf - 在 JSF 中使用 HTML5 的输入表单属性