DXCore を使用したアダプターの列挙

DXCore は DirectX デバイス用のアダプター列挙 API であるため、その機能の一部は DXGI の機能と重複しています。

DXCore を使用すると、新しいデバイスの種類を MCDM (Microsoft Compute Driver Model) などのユーザー モードに公開して、Direct3D 12DirectMLWindows Machine Learning で使用できます。 DXCore は、DXGI とは異なり、ディスプレイ関連のテクノロジまたはプロパティに関する情報を提供しません

次のいくつかのセクションでは、DXCore のメイン機能と、いくつかのコード例 (C++/WinRT で記述) について説明します。 以下に示すコード例は、 トピック「最小限の DXCore アプリケーション」で確認できる完全なソース コードリストから抽出されています。

アダプター ファクトリを作成する

DXCore アダプター列挙を開始するには、 IDXCoreAdapterFactory インターフェイスで表されるアダプター ファクトリ オブジェクトを作成します。 ファクトリを作成するには、ヘッダー ファイルを dxcore.h 含め、 DXCoreCreateAdapterFactory free 関数を呼び出します。

#include <dxcore.h>
...
winrt::com_ptr<IDXCoreAdapterFactory> adapterFactory;
winrt::check_hresult(::DXCoreCreateAdapterFactory(adapterFactory.put()));

アダプターの一覧を取得する

DXGI とは異なり、新しく作成された DXCore アダプター ファクトリは、システムのアダプター状態のスナップショットを自動的に作成しません。 代わりに、DXCore は、IDXCoreAdapterList インターフェイスによって表されるアダプター リスト オブジェクトを明示的に取得するときに、そのスナップショットを作成します。

winrt::com_ptr<IDXCoreAdapterList> d3D12CoreComputeAdapters;
GUID attributes[]{ DXCORE_ADAPTER_ATTRIBUTE_D3D12_CORE_COMPUTE };
winrt::check_hresult(
    adapterFactory->CreateAdapterList(_countof(attributes),
        attributes,
        d3D12CoreComputeAdapters.put()));

一覧から適切なアダプターを選択します

このセクションでは、アダプター リスト オブジェクトを指定すると、一覧で最初のハードウェア アダプターを見つける方法を示します。

IDXCoreAdapterList::GetAdapterCount メソッドはリスト内の要素の数を示し、IDXCoreAdapterList::GetAdapter はインデックスによって特定のアダプターを取得します。

その後、次の手順に従って、そのアダプターのプロパティに対してクエリを実行できます。

  • 最初に、このオペレーティング システムのバージョンでこのアダプターの特定のプロパティの値を取得することが有効であることを確認するには、 IDXCoreAdapter::IsPropertySupported を呼び出します。 DXCoreAdapterProperty 列挙の値を渡して、クエリを実行するプロパティを識別します。
  • 必要に応じて、 IDXCoreAdapter::GetPropertySize の呼び出しでプロパティ値のサイズを確認します。 単純なブール値である DXCoreAdapterProperty::IsHardware などのプロパティの場合、この手順は必要ありません。
  • 最後に、 IDXCoreAdapter::GetProperty を呼び出してプロパティの値を取得します。
winrt::com_ptr<IDXCoreAdapter> preferredAdapter;

const uint32_t count{ d3D12CoreComputeAdapters->GetAdapterCount() };

for (uint32_t i = 0; i < count; ++i)
{
    winrt::com_ptr<IDXCoreAdapter> candidateAdapter;
    winrt::check_hresult(
        d3D12CoreComputeAdapters->GetAdapter(i, candidateAdapter.put()));

    bool isHardware{ false };
    winrt::check_hresult(candidateAdapter->GetProperty(
        DXCoreAdapterProperty::IsHardware,
        &isHardware));

    if (isHardware)
    {
        // Choose the first hardware adapter, and stop looping.
        preferredAdapter = candidateAdapter;
        break;
    }

    // Otherwise, ensure that (as long as there are *any* adapters) we'll
    // at least choose one.
    if (!preferredAdapter)
    {
        preferredAdapter = candidateAdapter;
    }
}

アダプターの一覧を並べ替えて優先アダプターを選択する

IDXCoreAdapterList::Sort メソッドを呼び出すことで、DXCore アダプター リストを並べ替えることができます。

DXCoreAdapterPreference 列挙は、並べ替え条件を表す値を定義します。 これらの値の配列を Sort に渡し、結果の 並べ替えられた一覧の最初のアダプターを読み取ります。

並べ替えの種類が Sort で認識されるかどうかを判断するには、まず IDXCoreAdapterList::IsAdapterPreferenceSupported を呼び出します。

winrt::com_ptr<IDXCoreAdapter> TryFindHardwareHighPerformanceGraphicsAdapter()
{
    // You begin DXCore adapter enumeration by creating an adapter factory.
    winrt::com_ptr<IDXCoreAdapterFactory> adapterFactory;
    winrt::check_hresult(::DXCoreCreateAdapterFactory(adapterFactory.put()));

    // From the factory, retrieve a list of all the Direct3D 12 Graphics adapters.
    winrt::com_ptr<IDXCoreAdapterList> d3D12GraphicsAdapters;
    GUID attributes[]{ DXCORE_ADAPTER_ATTRIBUTE_D3D12_GRAPHICS };
    winrt::check_hresult(
        adapterFactory->CreateAdapterList(_countof(attributes),
            attributes,
            d3D12GraphicsAdapters.put()));

    DXCoreAdapterPreference sortPreferences[]{
        DXCoreAdapterPreference::Hardware, DXCoreAdapterPreference::HighPerformance };

    // Ask the OS to sort for the highest performance hardware adapter.
    winrt::check_hresult(d3D12GraphicsAdapters->Sort(_countof(sortPreferences), sortPreferences));

    winrt::com_ptr<IDXCoreAdapter> preferredAdapter;

    if (d3D12GraphicsAdapters->GetAdapterCount() > 0)
    {
        winrt::check_hresult(d3D12GraphicsAdapters->GetAdapter(0, preferredAdapter.put()));
    }

    return preferredAdapter;
}

アダプターの状態のクエリと設定 (プロパティ)

IDXCoreAdapter::QueryState メソッドと IDXCoreAdapter::SetState メソッドを呼び出すことで、アダプターの指定された状態項目の状態を取得および設定できます。

void SetDesiredMemoryReservation(winrt::com_ptr<IDXCoreAdapter> const& adapter, uint64_t reservation)
{
    DXCoreAdapterMemoryBudgetNodeSegmentGroup nodeSegmentGroup{};
    nodeSegmentGroup.nodeIndex = 0;
    nodeSegmentGroup.segmentGroup = DXCoreSegmentGroup::Local;

    DXCoreAdapterMemoryBudget memoryBudget{};
    winrt::check_hresult(adapter->QueryState(
        DXCoreAdapterState::AdapterMemoryBudget,
        &nodeSegmentGroup,
        &memoryBudget));

    // Clamp the reservation to what's available.
    reservation = std::min<uint64_t>(reservation, memoryBudget.availableForReservation);

    winrt::check_hresult(adapter->SetState(
        DXCoreAdapterState::AdapterMemoryBudget,
        &nodeSegmentGroup,
        &reservation));
}

実際には、 QueryStateSetState を呼び出す前に 、IsQueryStateSupported を呼び出して、このアダプターとオペレーティング システム (OS) で状態の種類のクエリを実行できるかどうかを確認する必要があります。

アダプターの一覧の鮮度

システムの状態の変更によりアダプター リストが古くなった場合は、そのようにマークされます。 IDXCoreAdapterList::IsStale メソッドをポーリングすることで、アダプター リストの鮮度を確認できます。

ただし、より便利に、古さなどの条件の通知をサブスクライブできます。 これを行うには、 DXCoreNotificationType::AdapterListStaleを IDXCoreAdapterFactory::RegisterEventNotification に渡し、後で使用するために返された Cookie を安全に格納します。

uint32_t m_eventCookie = 0;
...
winrt::check_hresult(factory->RegisterEventNotification(
    m_adapters.get(),
    DXCoreNotificationType::AdapterListStale,
    OnAdapterListStale,
    this,
    &m_eventCookie));
...
static void WINAPI OnAdapterListStale(
    DXCoreNotificationType notificationType,
    IUnknown* staleObject,
    void* context)
{
    ...
}

その後、既にあるファクトリ オブジェクトから、新しい現在のアダプター リスト オブジェクトを生成できます。 これらの条件の処理は、アダプターの到着や削除などのイベント (GPU、特殊なコンピューティング アダプターのいずれであっても) にシームレスに対応し、それに応じてワークロードを適切にシフトする能力にとって重要です。

アダプター リスト オブジェクトを破棄する前に、 IDXCoreAdapterFactory::UnregisterEventNotification を呼び出して、Cookie 値を使用してそのオブジェクトを通知から登録解除する必要があります。 登録を解除しない場合、状況が検出されると致命的な例外が発生します。

HRESULT hr = factory->UnregisterEventNotification(m_eventCookie);

情報を表示する

注意

DXCore 自体は表示情報を提供しません。 必要に応じて、Windows ランタイム DisplayMonitor クラスを使用してこの情報を取得する必要があります。 アダプターの LUID は、DXCore アダプターを DisplayMonitor.DisplayAdapterId 情報にマップするために使用できる共通識別子を提供します。 アダプターの LUID を取得するには、 DXCoreAdapterProperty::InstanceLuidを IDXCoreAdapter::GetProperty メソッドに渡します。

関連項目