directx-11 - 创建交换链时如何解决此多重采样错误?

标签 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 渲染目标。

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

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

You also can't create it as an DXGI_FORMAT_*_SRGB gamma-correcting swapchain with the new DXGI_SWAP_EFFECT_FLIP_* models. You can create a Render Target View that is DXGI_FORMAT_*_SRGB for a swapchain that is not sRGB to get the same effect. There's a little bit of a gotcha doing both MSAA and sRGB together with the new flip models that is fixed in Windows 10 Fall Creators Update (16299) or later.

If you were using DirectX 12, you don't have the option of using the older swap effects, so you have to implement the MSAA render target directly. Again, see 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 是非常愚蠢的。

To get a sense of just how much of a modern game is doing multiple passes of rendering, see this blog post

查看 DirectX 工具包了解 DX 11DX12

更新:我在最近的 blog post 中详细介绍了这一点。

关于directx-11 - 创建交换链时如何解决此多重采样错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56286975/

相关文章:

c# - DirectX:世界观察矩阵——我的误解在哪里?

c++ - 延迟渲染 : Performance issues

directx - DX11 中的多纹理如何工作?

c++ - 如何向下遍历四叉树以获得最底层的节点(3D、C++、DX11)

c++ - DirectX 11 内存重新分配错误

c++ - 如何将鼠标移动转换为相机平移

C++ HLSL 缓冲区变量

c++ - 在 DirectX 11 中将着色器资源发送到 GPU

c++ - 了解 DirectX11 和 Directx11.1 示例 msdn 代码

c++ - 我正在尝试为正方形设置棋盘纹理