レイトレ日記 2022/07/27

今日は,ノートPCでの起動チェックを行いました。
で,早速DirectX周りでハマりました。

まず,当たり前ですがSwapChainの解像度がサポートされているものしか対応しないので,デスクトップと同じ解像度を指定したら,SwapChainが作成できなくて起動できないという問題にあたりました。
結局,画像出力用のレンダーターゲットを1つ用意して,そちらは高解像度にしてリードバックして,CPUからPNGに書き出し。SwapChainの方は,縮小して表示することにしました。

次のハマりポイントですが,EnumOutputs()がエラーを返すというのでハマりました。どうやらIDXGIAdapterの中には,EnumOutputs()の0番が失敗するものがいるようです。で,それを採用するように軽く実装したら,今度はAdapterが変わってDXRのチェックに通らないみたいなことが発生しました。結局,EnumOutputs()用にAdapterは別のものにするという対応で,ようやくサポート解像度がとれるようになりました。本当,こういうところがDirectXは面倒くさくて嫌いです。
コードは下記のような感じになりました。

    // DXGIアダプター生成.
    {
        RefPtr<IDXGIAdapter1> pAdapter;
        for(auto adapterId=0;
            DXGI_ERROR_NOT_FOUND != m_pFactory->EnumAdapterByGpuPreference(adapterId, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, IID_PPV_ARGS(pAdapter.GetAddress()));
            adapterId++)
        {
            DXGI_ADAPTER_DESC1 desc;
            auto hr = pAdapter->GetDesc1(&desc);
            if (FAILED(hr))
            { continue; }

            hr = D3D12CreateDevice(pAdapter.GetPtr(), D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), nullptr);
            if (SUCCEEDED(hr))
            {
                if (m_pAdapter.GetPtr() == nullptr)
                {
                    m_pAdapter = pAdapter.GetPtr();
                    m_pAdapter->AddRef();
                }

                RefPtr<IDXGIOutput> pOutput;
                hr = pAdapter->EnumOutputs(0, pOutput.GetAddress());
                if (FAILED(hr))
                { continue; }

                hr = pOutput->QueryInterface(IID_PPV_ARGS(m_pOutput.GetAddress()));
                if (SUCCEEDED(hr))
                { break; }
            }
        }
    }

これで,一応ノートPCでプログラムが起動するようになりました。
今週末が,レギュレーションテストなので,明日はテスト用のアセット生成などをして本番と同じフローになるように大枠だけは整えたいなと思っています。