2015年9月25日金曜日

DXGIFactoryの生成または取得方法

生成または取得する方法がいくつかあるのでまとめておきます.

#include <Windows.h>
#include <tchar.h>
#include <wrl/client.h>
#include <d3d11_3.h>
#include <dxgi1_4.h>

#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "dxgi.lib")

using namespace Microsoft::WRL;
using namespace std;

int WINAPI wWinMain(
    HINSTANCE hInstance,
    HINSTANCE,
    LPWSTR lpCmdLine,
    int nCmdShow
)
{
    HRESULT hr = S_OK;

    // CreateDXGIFactoryによるDXGIFactoryの生成
    {
        ComPtr<idxgifactory> pFactory;
        hr = CreateDXGIFactory(
            IID_PPV_ARGS(pFactory.GetAddressOf())
        );
        if(FAILED(hr)) { return 0; }

        // インターフェースがサポートされていない,と失敗する
        // ComPtr<idxgifactory1> pFactory1;
        // hr = pFactory.As(&pFactory1);
        // if(FAILED(hr)) { return 0; }
    }

    // CreateDXGIFactory1によるDXGIFactory1の生成 (Windows 7以降)
    {
        ComPtr<idxgifactory1> pFactory1;
        hr = CreateDXGIFactory1(
            IID_PPV_ARGS(pFactory1.GetAddressOf())
        );
        if(FAILED(hr)) { return 0; }

        ComPtr<idxgifactory> pFactory;
        hr = pFactory1.As(&pFactory);
        if(FAILED(hr)) { return 0; }

        ComPtr<idxgifactory3> pFactory3;
        hr = pFactory1.As(&pFactory3);
        if(FAILED(hr)) { return 0; }

        ComPtr<idxgifactory4> pFactory4;
        hr = pFactory1.As(&pFactory4);
        if(FAILED(hr)) { return 0; }
    }

    // CreateDXGIFactory2によるDXGIFactory2の生成 (Windows 8.1以降)
    {
        ComPtr<idxgifactory2> pFactory2;
        ULONG creationFlag = 0;
#ifdef _DEBUG
        creationFlag |= DXGI_CREATE_FACTORY_DEBUG;
#endif

        hr = CreateDXGIFactory2(
            creationFlag,
            IID_PPV_ARGS(pFactory2.GetAddressOf())
        );
        if(FAILED(hr)) { return 0; }

        ComPtr<idxgifactory> pFactory;
        hr = pFactory2.As(&pFactory);
        if(FAILED(hr)) { return 0; }

        ComPtr<idxgifactory1> pFactory1;
        hr = pFactory2.As(&pFactory1);
        if(FAILED(hr)) { return 0; }

        ComPtr<idxgifactory3> pFactory3;
        hr = pFactory2.As(&pFactory3);
        if(FAILED(hr)) { return 0; }

        ComPtr<idxgifactory4> pFactory4;
        hr = pFactory2.As(&pFactory4);
        if(FAILED(hr)) { return 0; }
    }

    // D3D機能レベルの一覧を用意
    D3D_FEATURE_LEVEL featureLevels[] =
    {
        D3D_FEATURE_LEVEL_12_1,
        D3D_FEATURE_LEVEL_12_0,
        D3D_FEATURE_LEVEL_11_1,
        D3D_FEATURE_LEVEL_11_0,
        D3D_FEATURE_LEVEL_10_1,
        D3D_FEATURE_LEVEL_10_0,
        D3D_FEATURE_LEVEL_9_3,
        D3D_FEATURE_LEVEL_9_2,
        D3D_FEATURE_LEVEL_9_1,
    };
    D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_9_1;
    UINT deviceCreationFlag = 0;

    // D3D11デバイスおよびイメディエイトコンテキストの生成
    ComPtr<id3d11device> pDevice;
    ComPtr<id3d11devicecontext> pImmediateContext;
    hr = D3D11CreateDevice(
        nullptr,
        D3D_DRIVER_TYPE_HARDWARE,
        nullptr,
        deviceCreationFlag,
        featureLevels,
        _countof(featureLevels),
        D3D11_SDK_VERSION,
        pDevice.GetAddressOf(),
        &featureLevel,
        pImmediateContext.GetAddressOf()
    );
    if(FAILED(hr)) { return 0; }

    ComPtr<idxgidevice> pDXGIDevice;
    hr = pDevice.As(&pDXGIDevice);
    if(FAILED(hr)) { return 0; }

    // D3D11DeviceからDXGIDeviceを取得し,
    // DXGIDeviceからDXGIAdapterを取得し,
    // DXGIAdapterの親であるDXGIFactoryを取得する.
    // そこからIDXGIFactory1,2,3,4を取得する.
    {
        ComPtr<idxgiadapter> pDXGIAdapter;
        hr = pDXGIDevice->GetAdapter(
            pDXGIAdapter.GetAddressOf()
        );
        if(FAILED(hr)) { return 0; }

        ComPtr<idxgifactory> pFactory;
        hr = pDXGIAdapter->GetParent(
            IID_PPV_ARGS(pFactory.GetAddressOf())
        );
        if(FAILED(hr)) { return 0; }

        ComPtr<idxgifactory1> pFactory1;
        hr = pFactory.As(&pFactory1);
        if(FAILED(hr)) { return 0; }なn

        ComPtr<idxgifactory2> pFactory2;
        hr = pFactory.As(&pFactory2);
        if(FAILED(hr)) { return 0; }

        ComPtr<idxgifactory3> pFactory3;
        hr = pFactory.As(&pFactory3);
        if(FAILED(hr)) { return 0; }

        ComPtr<idxgifactory4> pFactory4;
        hr = pFactory.As(&pFactory4);
        if(FAILED(hr)) { return 0; }
    }

    return 0;
}

CreateDXGIFactoryでDXGIFactoryを生成した場合,以降のIDXGIFactory1,2,3,4のインターフェースをサポートしたオブジェクトにはならないようです.

ところで,D3D11DeviceからDXGIDeviceを取得できるって,どこかに関係の説明があるんでしょうか?
MSDNにサンプルがあったのでこうできるというのは分かったんですが,その関係性が書いてあるドキュメントが見つけられないんですよね.

2015/09/26 追記

IDXGIDeviceのドキュメントが2つあって,
こちらには情報が載っていなくて,
こちらには載っていました.
何なんだろう.

0 件のコメント:

コメントを投稿