使用 DXCore 來列舉介面卡
DXCore 是 DirectX 裝置的介面卡列舉 API,因此其部分設施會與 DXGI的裝置重迭。
DXCore 可讓新的裝置類型暴露在使用者模式,例如 MCDM (Microsoft Compute Driver Model) ,以搭配 Direct3D 12、 DirectML和 Windows 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會依索引擷取特定配接器。
接著,您可以遵循下列步驟來查詢該配接器的屬性。
- 首先,若要確認此作業系統版本上擷取此介面卡的指定屬性值是有效的,請呼叫 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));
}
在實務上,在呼叫 QueryState 和 SetState之前,您應該呼叫 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 方法。
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應