DXCore를 사용하여 어댑터 열거

DXCore는 DirectX 디바이스용 어댑터 열거형 API이므로 일부 기능은 DXGI의 기능과 겹칩니다.

DXCore를 사용하면 Direct3D 12, DirectMLWindows Machine Learning에서 사용할 MCDM(Microsoft Compute Driver Model)과 같은 새로운 디바이스 유형을 사용자 모드에 노출할 수 있습니다. DXCore는 DXGI와 달리 디스플레이 관련 기술 또는 속성에 대한 정보를 제공하지 않습니다.

다음 몇 섹션에서는 몇 가지 코드 예제(C++/WinRT로 작성됨)와 함께 DXCore의 기본 기능을 살펴보겠습니다. 아래에 표시된 코드 예제는 최소 DXCore 애플리케이션 항목에서 찾을 수 있는 전체 소스 코드 목록에서 추출됩니다.

어댑터 팩터리 만들기

IDXCoreAdapterFactory 인터페이스로 표시되는 어댑터 팩터리 개체를 만들어 DXCore 어댑터 열거형을 시작합니다. 팩터리를 만들려면 헤더 파일을 포함하고 dxcore.hDXCoreCreateAdapterFactory 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));
}

실제로 QueryStateSetState를 호출하기 전에 IsQueryStateSupported 를 호출하여 이 어댑터 및 OS(운영 체제)에서 상태 종류 쿼리를 사용할 수 있는지 확인해야 합니다.

어댑터 목록 새로 고침

어댑터 목록이 시스템 조건 변경으로 인해 부실해지면 다음과 같이 표시됩니다. IDXCoreAdapterList::IsStale 메서드를 폴링하여 어댑터 목록의 새로 고침을 확인할 수 있습니다.

하지만 더 편리하게 부실과 같은 조건에 대한 알림을 구독할 수 있습니다. 이렇게 하려면 DXCoreNotificationType::AdapterListStaleIDXCoreAdapterFactory::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::InstanceLuidIDXCoreAdapter::GetProperty 메서드에 전달합니다.

추가 정보