я использую CheckMultisampleQualityLevels(...)
установить поддержку MSAA на моем оборудовании. Я делаю это в таком порядке:
D3D11CreateDevice(...)
дает мне device
device->CheckMultisampleQualityLevels(...)
DXGI_SWAP_CHAIN_DESC.SampleDesc
CreateSwapChain(...)
с учетом DXGI_SWAP_CHAIN_DESC
Проблема в, CheckMultisampleQualityLevels(...)
всегда дает мне 0
за pNumQualityLevels
, И я уверен, что моя графическая карта поддерживает некоторые MSAA (я тестировал программу на GeForce GTX 780 и других с тем же результатом).
Я что-то пропустил? Должен ли я позвонить что-то еще до 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):
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 http://stackoverflow.com/questions/27270504/directx-creating-the-swapchain
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 ПРЕДУПРЕЖДЕНИЕ: IDXGISwapChain :: Present: Fullscreen презентационные неэффективностью, понесенные в связи с применением не используя IDXGISwapChain :: ResizeBuffers соответственно, указав DXGI_MODE_DESC не доступны в IDXGIOutput :: GetDisplayModeList или не используя 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; [РАЗНОЕ ПРЕДУПРЕЖДЕНИЕ № 98:]
Ваш код вычитает 1 из maxQualityLevels, прежде чем проверять, является ли он больше нуля. Первоначальное значение 1 предполагает, что можно создать цель на уровне качества 0.
Предполагая, что вы хотите, чтобы это работало между поставщиками, вам действительно нужно проверить, чтобы оно было> 0, а затем просто создать поверхность с качеством = 0.
Уровни качества> 0 зависят от поставщика и могут означать любое количество разных графических процессоров. CSAA от Nvidia и EQAA от AMD доступны с ненулевыми уровнями качества, но вам нужно взглянуть на их собственную документацию, чтобы понять, что на самом деле означает каждый уровень качества. Они также функционально немного отличаются от традиционных MSAA. «Качество» немного вводит в заблуждение в том смысле, что большее число не обязательно означает лучшее качество, более уместно назвать его «Режим»
Смотрите оба:
http://www.nvidia.com/object/coverage-sampled-aa.html
а также