首页 > 解决方案 > 创建交换链时如何解决此多重采样错误?

问题描述

我在创建交换链时收到关于多重采样的 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.

如何解决此错误?

标签: directx-11

解决方案


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

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

有关详细的代码示例,请参阅GitHub

您也无法使用新模型将其创建为DXGI_FORMAT_*_SRGB伽马校正交换链。您可以为非 sRGB 的交换链DXGI_SWAP_EFFECT_FLIP_*创建一个渲染目标视图以获得相同的效果。DXGI_FORMAT_*_SRGBMSAA 和 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 11DX12的 DirectX 工具包

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


推荐阅读