CheckMultisampleQualityLevels(...)表示该卡不支持MSAA(例如我的GeForce GTX 780不支持)?

时间:2015-06-20 18:27:20

标签: c++ directx directx-11 msaa

我使用CheckMultisampleQualityLevels(...)在我的硬件上建立MSAA支持。我是按照这个顺序做的:

  1. D3D11CreateDevice(...)给了我device
  2. device->CheckMultisampleQualityLevels(...)
  3. 将结果传递给DXGI_SWAP_CHAIN_DESC.SampleDesc
  4. 给定CreateSwapChain(...)
  5. 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 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 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 ::目前:由于应用程序未正确使用IDXGISwapChain :: ResizeBuffers而导致全屏显示效率低下,指定IDXGIOutput :: GetDisplayModeList中不可用的DXGI_MODE_DESC,或者未使用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 个答案:

答案 0 :(得分:1)

您的代码在检查是否大于零之前从maxQualityLevels中减去1。初始值为1表示在质量等级0创建目标是有效的。

假设您希望这适用于供应商,您只需要检查它是否为&gt; 0,然后在Quality = 0处创建表面。

质量水平&gt; 0是供应商特定的,可以表示不同GPU的任意数量的东西。 Nvidia的CSAA和AMD的EQAA都可以通过非零质量水平获得,但您需要查看自己的文档,以确定每个质量水平的实际含义。它们在功能上与传统的MSAA略有不同。 “质量”有点误导,因为更多的数字并不一定意味着更高的质量,把它称为“模式”更合适

见两者:

http://www.nvidia.com/object/coverage-sampled-aa.html

http://developer.amd.com/wordpress/media/2012/10/EQAA%2520Modes%2520for%2520AMD%2520HD%25206900%2520Series%2520Cards.pdf