创建交换链时如何修复此多重采样错误?

Han*_*tor 4 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);
Run Code Online (Sandbox Code Playgroud)

调试输出:

DXGI ERROR: IDXGIFactory::CreateSwapChain: Flip model swapchains (DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL and DXGI_SWAP_EFFECT_FLIP_DISCARD) do not support multisampling.
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个错误?

Chu*_*urn 9

TL;DR将翻转模型更改为较旧的模型DXGI_SWAP_EFFECT_DISCARD,或者创建您明确解析的 MSAA 渲染目标。

  1. 将交换链创建为一个示例(即无 MSAA)。
  2. 创建使用一个或多个样本(即 MSAA)的渲染目标纹理。
  3. 为 MSAA 渲染目标创建渲染目标视图
  4. 每个帧渲染到 MSAA 渲染目标,然后ResolveSubresource渲染到交换链后缓冲区(或其他一些单样本缓冲区),然后Present.

详细代码示例请参见GitHub

您也无法将其创建为DXGI_FORMAT_*_SRGBDXGI_SWAP_EFFECT_FLIP_*模型的伽玛校正交换链。您可以为非 sRGB 的交换链创建一个渲染目标视图DXGI_FORMAT_*_SRGB以获得相同的效果。将 MSAA 和 sRGB 与新的翻转模型一起使用时存在一些问题,该问题已在 Windows 10 秋季创意者更新 (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
Run Code Online (Sandbox Code Playgroud)

正如您从该流程中看到的,除了玩具示例或示例代码之外,将交换链设为 MSAA 是非常愚蠢的。

要了解现代游戏中有多少是在进行多次渲染,请参阅此博客文章

请参阅适用于DX 11DX12的 DirectX 工具套件

更新:我在最近的一篇博客文章中详细介绍了这一点