DXCore를 사용하여 어댑터 열거
DXCore는 DirectX 디바이스용 어댑터 열거형 API이므로 일부 기능은 DXGI의 기능과 겹칩니다.
DXCore를 사용하면 Direct3D 12, DirectML 및 Windows Machine Learning에서 사용할 MCDM(Microsoft Compute Driver Model)과 같은 새로운 디바이스 유형을 사용자 모드에 노출할 수 있습니다. DXCore는 DXGI와 달리 디스플레이 관련 기술 또는 속성에 대한 정보를 제공하지 않습니다.
다음 몇 섹션에서는 몇 가지 코드 예제(C++/WinRT로 작성됨)와 함께 DXCore의 기본 기능을 살펴보겠습니다. 아래에 표시된 코드 예제는 최소 DXCore 애플리케이션 항목에서 찾을 수 있는 전체 소스 코드 목록에서 추출됩니다.
어댑터 팩터리 만들기
IDXCoreAdapterFactory 인터페이스로 표시되는 어댑터 팩터리 개체를 만들어 DXCore 어댑터 열거형을 시작합니다. 팩터리를 만들려면 헤더 파일을 포함하고 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 열거형은 정렬 조건을 나타내는 값을 정의합니다. 이러한 값의 배열을 정렬에 전달한 다음 결과 정렬된 목록에서 첫 번째 어댑터를 읽습니다.
정렬 형식을 정렬로 이해할지 여부를 확인하려면 먼저 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에 전달하고 나중에 사용할 수 있도록 반환된 쿠키를 안전하게 저장합니다.
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을 호출하여 알림에서 해당 개체의 등록을 취소하려면 쿠키 값을 사용해야 합니다. 등록을 취소하지 않으면 상황이 감지되면 치명적인 예외가 발생합니다.
HRESULT hr = factory->UnregisterEventNotification(m_eventCookie);
정보 표시
참고
DXCore 자체는 표시 정보를 제공하지 않습니다. 필요한 경우 Windows 런타임 DisplayMonitor 클래스를 사용하여 이 정보를 검색해야 합니다. 어댑터의 LUID 는 DXCore 어댑터를 DisplayMonitor.DisplayAdapterId 정보에 매핑하는 데 사용할 수 있는 일반적인 식별자를 제공합니다. 어댑터의 LUID를 가져오려면 DXCoreAdapterProperty::InstanceLuid 를 IDXCoreAdapter::GetProperty 메서드에 전달합니다.
추가 정보
피드백
https://aka.ms/ContentUserFeedback을 참조하세요.
출시 예정: 2024년 내내 콘텐츠 피드백 메커니즘인 GitHub 문제를 단계적으로 폐지하고 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은다음에 대한 사용자 의견 제출 및 보기