MSAA and CheckFeatureSupport

Started by
8 comments, last by loreStefani 8 years, 4 months ago

Hello everyone, I've been playing around with D3D12 for the last two days but haven't been able to use MSAA. In D3D11 I used to determine the supported samples count and quality level with the method CheckMultisampleQualityLevels and now I'm trying to do the same with CheckFeatureSupport with the following piece of code:


D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msaaQualityDesc{};
msaaQualityDesc.SampleCount = 8;
msaaQualityDesc.Format = m_rtvFormat;
msaaQualityDesc.Flags = D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE;

while (msaaQualityDesc.SampleCount > 1) {
 HRESULT hr = m_device->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS,
                                            &msaaQualityDesc, 1);
 if (SUCCEEDED(hr)) {				
    break;
 }
 msaaQualityDesc.SampleCount--;
}

where m_rtvFormat has been DXGI_FORMAT_R8G8B8A8_UNORM and DXGI_FORMAT_B8G8R8A8_UNORM. The resulting samples count is always 1 with a GTX 970. Besides, the same combinations of format and samples count succeed in D3D11 on the same card. What am I doing wrong?

Advertisement

Your call to CheckFeatureSupport is wrong: the third parameter is "FeatureSupportDataSize Type: UINT The size of the structure passed to the pFeatureSupportData parameter." and 1 is certainly not a valid value.

Your call to CheckFeatureSupport is wrong: the third parameter is "FeatureSupportDataSize Type: UINT The size of the structure passed to the pFeatureSupportData parameter." and 1 is certainly not a valid value.

I cannot believe I missed that! it is even very clear in the docs...I should get some sleep.

Thank you very much!

Ok, I still can't get it to work. The CreateSwapChain call stopped working once the DXGI_SWAP_CHAIN_DESC has been filled with the MSAA parameters determined with CheckFeatureSupport. The error is DXGI_ERROR_INVALID_CALL which should indicate an invalid parameter, I'm lost.

The significant code is the following, I hope it is another silly mistake and I thank in advance whoever will try to help me.


//create device
D3D12CreateDevice(nullptr, //default adapter
		  m_featureLevel, //12.1
		  IID_PPV_ARGS(&m_device));

//create graphics command queue
D3D12_COMMAND_QUEUE_DESC commandQueueDesc{};
commandQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
commandQueueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
commandQueueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
commandQueueDesc.NodeMask = 0;

m_device->CreateCommandQueue(&commandQueueDesc, IID_PPV_ARGS(&m_commandQueue));

//create swap chain
DXGI_SWAP_CHAIN_DESC swapChainDesc{};
ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
swapChainDesc.BufferDesc.Width = width;
swapChainDesc.BufferDesc.Height = height;
swapChainDesc.BufferDesc.Format = m_rtvFormat;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = FRAMES_COUNT;
swapChainDesc.OutputWindow = getWindowHandle();
swapChainDesc.Windowed = TRUE;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swapChainDesc.Flags = 0;

D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msaaQualityDesc{};

//msaaQualityDesc is filled with the method discussed before...

swapChainDesc.SampleDesc.Count = msaaQualityDesc.SampleCount;
swapChainDesc.SampleDesc.Quality = msaaQualityDesc.NumQualityLevels-1;

ComPtr<IDXGIFactory4> factory{ nullptr };
CreateDXGIFactory1(IID_PPV_ARGS(&factory));

ComPtr<IDXGISwapChain> swapChain{ nullptr };
factory->CreateSwapChain(m_commandQueue.Get(),
                         &swapChainDesc, &swapChain); //this fails

What is the value of msaaQualityDesc.NumQualityLevels? In your original snippet you just check for SUCCEEDED(hr), but that just indicates if the checking function succeeded or not. Hardware support for a sample count/quality pair is indicated by NumQualityLevels being greater than zero.

Perhaps back buffers don't support MSAA with D3D12? I wouldn't be surprised if this were the case, since D3D12 it's much more explicit in dealing with swap chains. MSAA swap chains have to have a "hidden resolve" performed on them, where the driver resolves the subsamples of your MSAA back buffer to create a non-MSAA back buffer than can be displayed on the screen. If I were you, I would just do this yourself by creating a MSAA render target and then resolving that to your non-MSAA back buffer using ResolveSubresource.

What is the value of msaaQualityDesc.NumQualityLevels? In your original snippet you just check for SUCCEEDED(hr), but that just indicates if the checking function succeeded or not. Hardware support for a sample count/quality pair is indicated by NumQualityLevels being greater than zero.

You are right and I changed the loop to break when NumQualityLevels is greater then zero, I'll post that as soon as possibile. Thank you for the suggestion but the method still fails and with the values (Count, NumQualityLevels) = {(8, 1), (4, 1)}.

Perhaps back buffers don't support MSAA with D3D12? I wouldn't be surprised if this were the case, since D3D12 it's much more explicit in dealing with swap chains. MSAA swap chains have to have a "hidden resolve" performed on them, where the driver resolves the subsamples of your MSAA back buffer to create a non-MSAA back buffer than can be displayed on the screen. If I were you, I would just do this yourself by creating a MSAA render target and then resolving that to your non-MSAA back buffer using ResolveSubresource.


Thank you! I'll try that as soon as possibile, it looks definitely it.

In the documentation for DXGI_SWAP_CHAIN_DESC1 it says:

SampleDesc A DXGI_SAMPLE_DESC structure that describes multi-sampling parameters. This member is valid only with bit-block transfer (bitblt) model swap chains

The bitblt swap model is not supported by D3D12, so MJP was right about that.

Finally! I confirm that it works doing as suggested by MJP, by creating a separate MSAA render target and then ResolveSubresource it to the swap chain's back buffer. Thank you very much!

In the documentation for DXGI_SWAP_CHAIN_DESC1 it says:

SampleDesc A DXGI_SAMPLE_DESC structure that describes multi-sampling parameters. This member is valid only with bit-block transfer (bitblt) model swap chains

The bitblt swap model is not supported by D3D12, so MJP was right about that.

Moreover it is also specified so for the DXGI_SWAP_EFFECT enumeration: https://msdn.microsoft.com/en-us/library/windows/desktop/bb173077(v=vs.85).aspx. Thank you for your help.

This topic is closed to new replies.

Advertisement