使用 MSAA 创建交换链失败
Creating a swap chain with MSAA fails
当我尝试设置支持 MSAA 的交换链时,出现 DXGI_ERROR_INVALID_CALL
错误 - 这是创建交换链的代码:
// Describe and create the swap chain.
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
swapChainDesc.BufferCount = frameCount_;
swapChainDesc.Width = static_cast<UINT>(rsd.width);
swapChainDesc.Height = static_cast<UINT>(rsd.height);
swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
if (rsd.enableMSAA) {
swapChainDesc.SampleDesc = findBestMSAASetttings(swapChainDesc.Format);
}
ComPtr<IDXGISwapChain1> swapChain;
HRESULT hr = factory_->CreateSwapChainForHwnd(commandQueue_.Get(), // Swap chain needs the queue so that it can force a flush on it.
hWnd, &swapChainDesc, nullptr, nullptr, &swapChain);
查找最佳可用 MSAA 设置的方法如下所示:
DXGI_SAMPLE_DESC D3D12RenderSystem::findBestMSAASetttings(DXGI_FORMAT format)
{
HRESULT hr = S_FALSE;
// The default sampler mode, with no anti-aliasing, has a count of 1 and a quality level of 0.
UINT maxQualityLevel = 0;
UINT respectiveSampleCount = 1;
// If anti-aliasing is activated the best possible sample and quality level is chosen.
// Find highest available sample count and quality level
for (UINT sampleCount = 1; sampleCount <= D3D12_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount++) {
D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msaaQualityDesc{};
msaaQualityDesc.SampleCount = sampleCount;
msaaQualityDesc.Format = format; // DXGI_FORMAT_R8G8B8A8_UNORM;
msaaQualityDesc.Flags = D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE;
msaaQualityDesc.NumQualityLevels = 0;
hr = device_->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &msaaQualityDesc, sizeof(msaaQualityDesc));
if (hr != S_OK) {
BLUE_LOG(error) << "CheckMultisampleQualityLevels failed.";
}
if (msaaQualityDesc.NumQualityLevels > 0) {
BLUE_LOG(trace) << "MSAA with sampleCount " << msaaQualityDesc.SampleCount << " and qualtiy level " << msaaQualityDesc.NumQualityLevels << " supported.";
if (maxQualityLevel <= msaaQualityDesc.NumQualityLevels) {
maxQualityLevel = msaaQualityDesc.NumQualityLevels;
respectiveSampleCount = sampleCount;
}
}
}
BLUE_ASSERT(hr == S_OK, "find best MSAA setting failed.")
DXGI_SAMPLE_DESC sd;
sd.Count = respectiveSampleCount;
sd.Quality = maxQualityLevel;
return sd;
}
当 rsd.enableMSAA
为 false
时一切正常。
我的设备是这样创建的(我使用的是 warp 适配器,因为我没有硬件支持):
throwIfFailed(factory_->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter)));
throwIfFailed(D3D12CreateDevice(warpAdapter.Get(), featureLevel_, IID_PPV_ARGS(&device_)));
我的日志说:
trace | D3D12RenderSystem::findBestMSAASetttings | MSAA with sampleCount 1 and qualtiy level 1 supported.
trace | D3D12RenderSystem::findBestMSAASetttings | MSAA with sampleCount 2 and qualtiy level 1 supported.
trace | D3D12RenderSystem::findBestMSAASetttings | MSAA with sampleCount 4 and qualtiy level 1 supported.
trace | D3D12RenderSystem::findBestMSAASetttings | MSAA with sampleCount 8 and qualtiy level 1 supported.
trace | D3D12RenderSystem::findBestMSAASetttings | MSAA with sampleCount 16 and qualtiy level 1 supported.
https://github.com/Microsoft/DirectXTK12/wiki/Simple-rendering 说:
Direct3D 12 don't support creating MSAA swap chains--attempts to
create a swap chain with SampleDesc.Count > 1 will fail. Instead, you
create your own MSAA render target and explicitly resolve to the DXGI
back-buffer for presentation as shown here.
当我尝试设置支持 MSAA 的交换链时,出现 DXGI_ERROR_INVALID_CALL
错误 - 这是创建交换链的代码:
// Describe and create the swap chain.
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
swapChainDesc.BufferCount = frameCount_;
swapChainDesc.Width = static_cast<UINT>(rsd.width);
swapChainDesc.Height = static_cast<UINT>(rsd.height);
swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
if (rsd.enableMSAA) {
swapChainDesc.SampleDesc = findBestMSAASetttings(swapChainDesc.Format);
}
ComPtr<IDXGISwapChain1> swapChain;
HRESULT hr = factory_->CreateSwapChainForHwnd(commandQueue_.Get(), // Swap chain needs the queue so that it can force a flush on it.
hWnd, &swapChainDesc, nullptr, nullptr, &swapChain);
查找最佳可用 MSAA 设置的方法如下所示:
DXGI_SAMPLE_DESC D3D12RenderSystem::findBestMSAASetttings(DXGI_FORMAT format)
{
HRESULT hr = S_FALSE;
// The default sampler mode, with no anti-aliasing, has a count of 1 and a quality level of 0.
UINT maxQualityLevel = 0;
UINT respectiveSampleCount = 1;
// If anti-aliasing is activated the best possible sample and quality level is chosen.
// Find highest available sample count and quality level
for (UINT sampleCount = 1; sampleCount <= D3D12_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount++) {
D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msaaQualityDesc{};
msaaQualityDesc.SampleCount = sampleCount;
msaaQualityDesc.Format = format; // DXGI_FORMAT_R8G8B8A8_UNORM;
msaaQualityDesc.Flags = D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE;
msaaQualityDesc.NumQualityLevels = 0;
hr = device_->CheckFeatureSupport(D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS, &msaaQualityDesc, sizeof(msaaQualityDesc));
if (hr != S_OK) {
BLUE_LOG(error) << "CheckMultisampleQualityLevels failed.";
}
if (msaaQualityDesc.NumQualityLevels > 0) {
BLUE_LOG(trace) << "MSAA with sampleCount " << msaaQualityDesc.SampleCount << " and qualtiy level " << msaaQualityDesc.NumQualityLevels << " supported.";
if (maxQualityLevel <= msaaQualityDesc.NumQualityLevels) {
maxQualityLevel = msaaQualityDesc.NumQualityLevels;
respectiveSampleCount = sampleCount;
}
}
}
BLUE_ASSERT(hr == S_OK, "find best MSAA setting failed.")
DXGI_SAMPLE_DESC sd;
sd.Count = respectiveSampleCount;
sd.Quality = maxQualityLevel;
return sd;
}
当 rsd.enableMSAA
为 false
时一切正常。
我的设备是这样创建的(我使用的是 warp 适配器,因为我没有硬件支持):
throwIfFailed(factory_->EnumWarpAdapter(IID_PPV_ARGS(&warpAdapter)));
throwIfFailed(D3D12CreateDevice(warpAdapter.Get(), featureLevel_, IID_PPV_ARGS(&device_)));
我的日志说:
trace | D3D12RenderSystem::findBestMSAASetttings | MSAA with sampleCount 1 and qualtiy level 1 supported.
trace | D3D12RenderSystem::findBestMSAASetttings | MSAA with sampleCount 2 and qualtiy level 1 supported.
trace | D3D12RenderSystem::findBestMSAASetttings | MSAA with sampleCount 4 and qualtiy level 1 supported.
trace | D3D12RenderSystem::findBestMSAASetttings | MSAA with sampleCount 8 and qualtiy level 1 supported.
trace | D3D12RenderSystem::findBestMSAASetttings | MSAA with sampleCount 16 and qualtiy level 1 supported.
https://github.com/Microsoft/DirectXTK12/wiki/Simple-rendering 说:
Direct3D 12 don't support creating MSAA swap chains--attempts to create a swap chain with SampleDesc.Count > 1 will fail. Instead, you create your own MSAA render target and explicitly resolve to the DXGI back-buffer for presentation as shown here.