使用 DXCore 來列舉介面卡

DXCore 是 DirectX 裝置的介面卡列舉 API,因此其部分設施會與 DXGI的裝置重迭。

DXCore 可讓新的裝置類型暴露在使用者模式,例如 MCDM (Microsoft Compute Driver Model) ,以搭配 Direct3D 12DirectMLWindows Machine Learning使用。 DXCore 與 DXGI 不同,不會提供有關顯示相關技術或屬性的任何資訊

在接下來的幾節中,我們將探討 DXCore 的主要功能,其中包含一些以 C++/WinRT) 撰寫的程式碼範例 (。 以下所示的程式碼範例會從您可以在 最小 DXCore 應用程式主題中找到的完整源代碼清單擷取。

建立配接器處理站

您可以建立由 IDXCoreAdapterFactory 介面表示的配接器處理站物件來開始 DXCore 配接器列舉。 若要建立處理站,請包含 dxcore.h 標頭檔,並呼叫 DXCoreCreateAdapterFactory 免費函式。

#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會依索引擷取特定配接器。

接著,您可以遵循下列步驟來查詢該配接器的屬性。

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::QueryStateIDXCoreAdapter::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)
{
    ...
}

然後,您可以從您已經擁有的 Factory 物件產生新的目前配接器清單物件。 處理這些條件對於您能夠順暢地回應介面卡抵達和移除等事件, (GPU 或特製化計算配接器) ,以及適當地轉移回應中的工作負載的能力非常重要。

在終結配接器清單物件之前,您必須呼叫 IDXCoreAdapterFactory::UnregisterEventNotification,以使用 Cookie 值從通知取消註冊該物件。 如果您未取消註冊,則會在偵測到情況時引發嚴重例外狀況。

HRESULT hr = factory->UnregisterEventNotification(m_eventCookie);

顯示資訊

注意

DXCore 本身不會提供任何顯示資訊。 如有必要,您應該使用 Windows 執行階段DisplayMonitor類別來擷取此資訊。 配接器的 LUID 提供通用識別碼,可讓您用來將 DXCore 配接器對應至 DisplayMonitor.DisplayAdapterId 資訊。 若要取得配接器的 LUID,請將 DXCoreAdapterProperty::InstanceLuid 傳遞至 IDXCoreAdapter::GetProperty 方法。

另請參閱