CheckMultisampleQualityLevels(...) 表示该卡不支持 MSAA(例如我的 GeForce GTX 780 不支持)?
CheckMultisampleQualityLevels(...) says the card does not support MSAA (which is not true for e.g. my GeForce GTX 780)?
我使用 CheckMultisampleQualityLevels(...)
在我的硬件上建立 MSAA 支持。我按照这个顺序做:
D3D11CreateDevice(...)
给我 device
device->CheckMultisampleQualityLevels(...)
- 将结果传递给
DXGI_SWAP_CHAIN_DESC.SampleDesc
CreateSwapChain(...)
给定 DXGI_SWAP_CHAIN_DESC
问题是,CheckMultisampleQualityLevels(...)
总是给我 0
for pNumQualityLevels
。而且我确定我的显卡支持某些 MSAA(我已经在 GeForce gtx 780 和其他显卡上测试了该程序,结果相同)。
我错过了什么吗?我应该在 before CheckMultisampleQualityLevels(...)
之前调用其他东西吗?
代码:
创建设备:
UINT createDeviceFlags = 0;
#ifdef DEBUG_DIRECTX
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
D3D_DRIVER_TYPE driverTypes[] = {
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
std::string driverTypesNames[] = {
"D3D_DRIVER_TYPE_HARDWARE",
"D3D_DRIVER_TYPE_WARP",
"D3D_DRIVER_TYPE_REFERENCE",
};
UINT numDriverTypes = ARRAYSIZE(driverTypes);
D3D_FEATURE_LEVEL featureLevels[] = {
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
};
std::string featureLevelsNames[] = {
"D3D_FEATURE_LEVEL_11_0",
"D3D_FEATURE_LEVEL_10_1",
"D3D_FEATURE_LEVEL_10_0",
};
UINT numFeatureLevels = ARRAYSIZE(featureLevels);
D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0;
for(UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++){
driverType = driverTypes[driverTypeIndex];
result = D3D11CreateDevice(NULL, driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &device, &g_featureLevel, &context);
if(SUCCEEDED(result)){
LOG(logDEBUG1, "Driver type: " << driverTypesNames[driverTypeIndex] << ".", MOD_GRAPHIC);
break;
}
}
ERROR_HANDLE(SUCCEEDED(result), L"Could not create device (DirectX 11).", MOD_GRAPHIC);
检查多样本质量水平(基于vertexwahn.de article):
sampleCountOut = 1;
maxQualityLevelOut = 0;
for(UINT sampleCount = 1; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount++){
UINT maxQualityLevel = 0;
HRESULT hr = device->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, sampleCount, &maxQualityLevel);
if(maxQualityLevel > 0){
maxQualityLevel--;
}
ERROR_HANDLE(hr == S_OK, L"CheckMultisampleQualityLevels failed.", MOD_GRAPHIC);
if(maxQualityLevel > 0){
LOG(logDEBUG1, "MSAA " << sampleCount << "X supported with " << maxQualityLevel << " quality levels.", MOD_GRAPHIC);
sampleCountOut = sampleCount;
maxQualityLevelOut = maxQualityLevel;
}
}
交换链:
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferDesc.Width = width;
sd.BufferDesc.Height = height;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = *hwnd;
sd.SampleDesc.Count = sampleCount;
sd.SampleDesc.Quality = maxQualityLevel;
sd.Windowed = false;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // allow full-screen switchin
//based on
IDXGIDevice * dxgiDevice = 0;
HRESULT hr = device->QueryInterface(__uuidof(IDXGIDevice), (void **)& dxgiDevice);
ERROR_HANDLE(SUCCEEDED(hr), L"Query for IDXGIDevice failed.", MOD_GRAPHIC);
IDXGIAdapter * dxgiAdapter = 0;
hr = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void **)& dxgiAdapter);
ERROR_HANDLE(SUCCEEDED(hr), L"Could not get IDXGIAdapter.", MOD_GRAPHIC);
IDXGIFactory * dxgiFactory = 0;
hr = dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void **)& dxgiFactory);
ERROR_HANDLE(SUCCEEDED(hr), L"Could not get IDXGIFactory.", MOD_GRAPHIC);
// This system only has DirectX 11.0 installed (let's assume it)
result = dxgiFactory->CreateSwapChain(device, &sd, &swapChain);
LOG(logDEBUG1, "This system only has DirectX 11.0 installed. CreateSwapChain(...) used.", MOD_GRAPHIC);
ERROR_HANDLE(result == S_OK, L"Could not swap chain.", MOD_GRAPHIC);
我的 ERROR_HANDLE(...)
宏从不触发(第一个参数在所有情况下都为真)。日志说我使用 D3D_DRIVER_TYPE_HARDWARE
作为驱动程序类型。
DirectX 调试器说(这是一些问题,但我不认为这是 CheckMultisampleQualityLevels(...)
给我错误结果的原因):
DXGI WARNING: IDXGISwapChain::Present: Fullscreen presentation inefficiencies incurred due to application not using IDXGISwapChain::ResizeBuffers appropriately, specifying a DXGI_MODE_DESC not available in IDXGIOutput::GetDisplayModeList, or not using DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH.DXGI_SWAP_CHAIN_DESC::BufferDesc = { 1600, 900, { 60, 1 }, R8G8B8A8_UNORM, 0, 0 }; DXGI_SWAP_CHAIN_DESC::SampleDesc = { 8, 0 }; DXGI_SWAP_CHAIN_DESC::Flags = 0x2; [ MISCELLANEOUS WARNING #98: ]
您的代码先从 maxQualityLevels 中减去 1,然后再检查它是否大于零。初始值为 1 表示以质量级别 0 创建目标是有效的。
假设您希望它跨供应商工作,您只需要检查它是否 > 0,然后创建质量 = 0 的表面。
质量级别 > 0 是特定于供应商的,对于不同的 GPU 可能意味着任意数量的东西。 Nvidia 的 CSAA 和 AMD 的 EQAA 都可以通过非零质量级别获得,但您需要查看他们自己的文档才能弄清楚每个质量级别的实际含义。它们在功能上也与传统 MSAA 略有不同。 "Quality" 有点误导,因为数字越大并不一定意味着质量越高,称它为 "Mode"
会更合适
同时查看:
http://www.nvidia.com/object/coverage-sampled-aa.html
和
我使用 CheckMultisampleQualityLevels(...)
在我的硬件上建立 MSAA 支持。我按照这个顺序做:
D3D11CreateDevice(...)
给我device
device->CheckMultisampleQualityLevels(...)
- 将结果传递给
DXGI_SWAP_CHAIN_DESC.SampleDesc
CreateSwapChain(...)
给定DXGI_SWAP_CHAIN_DESC
问题是,CheckMultisampleQualityLevels(...)
总是给我 0
for pNumQualityLevels
。而且我确定我的显卡支持某些 MSAA(我已经在 GeForce gtx 780 和其他显卡上测试了该程序,结果相同)。
我错过了什么吗?我应该在 before CheckMultisampleQualityLevels(...)
之前调用其他东西吗?
代码:
创建设备:
UINT createDeviceFlags = 0;
#ifdef DEBUG_DIRECTX
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
D3D_DRIVER_TYPE driverTypes[] = {
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
std::string driverTypesNames[] = {
"D3D_DRIVER_TYPE_HARDWARE",
"D3D_DRIVER_TYPE_WARP",
"D3D_DRIVER_TYPE_REFERENCE",
};
UINT numDriverTypes = ARRAYSIZE(driverTypes);
D3D_FEATURE_LEVEL featureLevels[] = {
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
};
std::string featureLevelsNames[] = {
"D3D_FEATURE_LEVEL_11_0",
"D3D_FEATURE_LEVEL_10_1",
"D3D_FEATURE_LEVEL_10_0",
};
UINT numFeatureLevels = ARRAYSIZE(featureLevels);
D3D_FEATURE_LEVEL g_featureLevel = D3D_FEATURE_LEVEL_11_0;
for(UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++){
driverType = driverTypes[driverTypeIndex];
result = D3D11CreateDevice(NULL, driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels, D3D11_SDK_VERSION, &device, &g_featureLevel, &context);
if(SUCCEEDED(result)){
LOG(logDEBUG1, "Driver type: " << driverTypesNames[driverTypeIndex] << ".", MOD_GRAPHIC);
break;
}
}
ERROR_HANDLE(SUCCEEDED(result), L"Could not create device (DirectX 11).", MOD_GRAPHIC);
检查多样本质量水平(基于vertexwahn.de article):
sampleCountOut = 1;
maxQualityLevelOut = 0;
for(UINT sampleCount = 1; sampleCount <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; sampleCount++){
UINT maxQualityLevel = 0;
HRESULT hr = device->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, sampleCount, &maxQualityLevel);
if(maxQualityLevel > 0){
maxQualityLevel--;
}
ERROR_HANDLE(hr == S_OK, L"CheckMultisampleQualityLevels failed.", MOD_GRAPHIC);
if(maxQualityLevel > 0){
LOG(logDEBUG1, "MSAA " << sampleCount << "X supported with " << maxQualityLevel << " quality levels.", MOD_GRAPHIC);
sampleCountOut = sampleCount;
maxQualityLevelOut = maxQualityLevel;
}
}
交换链:
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferDesc.Width = width;
sd.BufferDesc.Height = height;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = *hwnd;
sd.SampleDesc.Count = sampleCount;
sd.SampleDesc.Quality = maxQualityLevel;
sd.Windowed = false;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // allow full-screen switchin
//based on
IDXGIDevice * dxgiDevice = 0;
HRESULT hr = device->QueryInterface(__uuidof(IDXGIDevice), (void **)& dxgiDevice);
ERROR_HANDLE(SUCCEEDED(hr), L"Query for IDXGIDevice failed.", MOD_GRAPHIC);
IDXGIAdapter * dxgiAdapter = 0;
hr = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void **)& dxgiAdapter);
ERROR_HANDLE(SUCCEEDED(hr), L"Could not get IDXGIAdapter.", MOD_GRAPHIC);
IDXGIFactory * dxgiFactory = 0;
hr = dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void **)& dxgiFactory);
ERROR_HANDLE(SUCCEEDED(hr), L"Could not get IDXGIFactory.", MOD_GRAPHIC);
// This system only has DirectX 11.0 installed (let's assume it)
result = dxgiFactory->CreateSwapChain(device, &sd, &swapChain);
LOG(logDEBUG1, "This system only has DirectX 11.0 installed. CreateSwapChain(...) used.", MOD_GRAPHIC);
ERROR_HANDLE(result == S_OK, L"Could not swap chain.", MOD_GRAPHIC);
我的 ERROR_HANDLE(...)
宏从不触发(第一个参数在所有情况下都为真)。日志说我使用 D3D_DRIVER_TYPE_HARDWARE
作为驱动程序类型。
DirectX 调试器说(这是一些问题,但我不认为这是 CheckMultisampleQualityLevels(...)
给我错误结果的原因):
DXGI WARNING: IDXGISwapChain::Present: Fullscreen presentation inefficiencies incurred due to application not using IDXGISwapChain::ResizeBuffers appropriately, specifying a DXGI_MODE_DESC not available in IDXGIOutput::GetDisplayModeList, or not using DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH.DXGI_SWAP_CHAIN_DESC::BufferDesc = { 1600, 900, { 60, 1 }, R8G8B8A8_UNORM, 0, 0 }; DXGI_SWAP_CHAIN_DESC::SampleDesc = { 8, 0 }; DXGI_SWAP_CHAIN_DESC::Flags = 0x2; [ MISCELLANEOUS WARNING #98: ]
您的代码先从 maxQualityLevels 中减去 1,然后再检查它是否大于零。初始值为 1 表示以质量级别 0 创建目标是有效的。
假设您希望它跨供应商工作,您只需要检查它是否 > 0,然后创建质量 = 0 的表面。
质量级别 > 0 是特定于供应商的,对于不同的 GPU 可能意味着任意数量的东西。 Nvidia 的 CSAA 和 AMD 的 EQAA 都可以通过非零质量级别获得,但您需要查看他们自己的文档才能弄清楚每个质量级别的实际含义。它们在功能上也与传统 MSAA 略有不同。 "Quality" 有点误导,因为数字越大并不一定意味着质量越高,称它为 "Mode"
会更合适同时查看:
http://www.nvidia.com/object/coverage-sampled-aa.html
和