D3D12 Enabling Multi-Sampling.

Started by
4 comments, last by Daganar 7 years, 1 month ago

Hi all, I was hoping somebody could point me in the right direction for enabling multi-sampling for a render target in D3D12.. Everywhere I've read states that I should enable it via the DXGI_SAMPLE_DESC in the swapchain and the pipeline state object. I am having two issues with this, first of changing the count/quality on the swapchain always fails with the error:

"IDXGIFactory::CreateSwapChain: Flip model swapchains (DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL and DXGI_SWAP_EFFECT_FLIP_DISCARD) do not support multisampling"

Okay.. So I swap to a non-flip mode and then I just get the next error:

"IDXGIFactory::CreateSwapChain: This D3D API version requires the swap effect to be one of DXGI_SWAP_EFFECT_FLIP_*. [ MISCELLANEOUS ERROR #273: ]"

I'm unable to find any documentation on this, but to me it sounds like I'm completely unable to enable multi-sampling?

Thanks.

Advertisement

The swap chain is the data that's sent to the monitor, and monitors can't display MSAA texture. In older versions of D3D, they allowed you to do this, and internally they pulled some magic to resolve the MSAA data to a non-MSAA texture before it was sent to the monitor. D3D12 gets rid of all that internal magic. So - create your swap chain as normal (non-MSAA), but create yourself another texture that is MSAA and render the scene to it. Then resolve your MSAA texture to your non-MSAA swap chain.

The swap chain is the data that's sent to the monitor, and monitors can't display MSAA texture. In older versions of D3D, they allowed you to do this, and internally they pulled some magic to resolve the MSAA data to a non-MSAA texture before it was sent to the monitor. D3D12 gets rid of all that internal magic. So - create your swap chain as normal (non-MSAA), but create yourself another texture that is MSAA and render the scene to it. Then resolve your MSAA texture to your non-MSAA swap chain.

Ah of course, thanks for the quick reply.

Usually back buffer is resolved.

You have (intermediate) texture(s), where you render to, and resolve them to No-MSAA back buffer (AKA swap chain)

I was reading a bit in Introduction to 3D Game Programming with DirectX 12 by Frank Luna and he talks briefly about enabling MSAA via the SwapChain, which is apparently completely incorrect...

For anyone wanting to know my solution (as there seems to be little info on this) I had to do the following;

  • Create as usual SwapChain with SampleDesc.Count = 1 and SampleDesc.Quality = 0.
  • Create SwapChain RTV's as usual.
  • Create another RenderTarget texture + view with the required sample count and quality.
  • Create PipelineStateObject with the SAME count and quality (this also applies to depth-stencil buffer)
  • Use the non-SwapChain render targets to render your scene to.
  • When you are ready to display contents on the screen, transition the non-SwapChain render target to "D3D12_RESOURCE_STATE_RESOLVE_SOURCE" state and the actual SwapChain render target to "D3D12_RESOURCE_STATE_RESOLVE_DEST"
  • Call ResolveSubresource on your command list with the correct source/destination.
  • Transition the SwapChain render target to D3D12_RESOURCE_STATE_PRESENT and you are done.

Also worth mentioning to retrieve the number of quality levels supported can be done like so:


D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msLevels;
msLevels.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Replace with your render target format.
msLevels.SampleCount = 4; // Replace with your sample count.
msLevels.Flags = D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE;

m_Device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &msLevels, sizeof(msLevels));

Doing this will store the quality level for the sample count in D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS::NumQualityLevels

This topic is closed to new replies.

Advertisement