Menggunakan DXCore untuk menghitung adaptor

DXCore adalah API enumerasi adaptor untuk perangkat DirectX, sehingga beberapa fasilitasnya tumpang tindih dengan DXGI.

DXCore memungkinkan paparan jenis perangkat baru ke mode pengguna, seperti MCDM (Model Driver Komputasi Microsoft), untuk digunakan dengan Direct3D 12, DirectML, dan Windows Machine Learning. DXCore, tidak seperti DXGI, tidak memberikan informasi apa pun tentang teknologi atau properti terkait tampilan

Di beberapa bagian berikutnya, kita akan melihat fitur utama DXCore dengan beberapa contoh kode (ditulis dalam C++/WinRT). Contoh kode yang ditunjukkan di bawah ini diekstrak dari daftar kode sumber lengkap yang dapat Anda temukan dalam topik Aplikasi Minimal DXCore.

Membuat pabrik adaptor

Anda memulai enumerasi adaptor DXCore dengan membuat objek pabrik adaptor, yang diwakili oleh antarmuka IDXCoreAdapterFactory . Untuk membuat pabrik, sertakan dxcore.h file header, dan panggil fungsi bebas DXCoreCreateAdapterFactory .

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

Mengambil daftar adaptor

Tidak seperti DXGI, pabrik adaptor DXCore yang baru dibuat tidak secara otomatis membuat rekam jepret dari status adaptor sistem. Sebagai gantinya, DXCore membuat rekam jepret tersebut saat Anda secara eksplisit mengambil objek daftar adaptor, yang diwakili oleh antarmuka IDXCoreAdapterList .

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

Pilih adaptor yang sesuai dari daftar

Bagian ini menunjukkan bagaimana, mengingat objek daftar adaptor, Anda dapat menemukan adaptor perangkat keras pertama dalam daftar.

Metode IDXCoreAdapterList::GetAdapterCount memberi tahu Anda jumlah elemen dalam daftar, dan IDXCoreAdapterList::GetAdapter mengambil adaptor tertentu menurut indeks.

Anda kemudian dapat mengkueri properti adaptor tersebut, dengan mengikuti langkah-langkah ini.

  • Pertama, untuk mengonfirmasi bahwa valid untuk mengambil nilai properti tertentu untuk adaptor ini pada versi sistem operasi ini, Anda memanggil IDXCoreAdapter::IsPropertySupported. Berikan nilai enumerasi DXCoreAdapterProperty untuk mengidentifikasi properti mana yang Anda kueri.
  • Secara opsional konfirmasi ukuran nilai properti dengan panggilan ke IDXCoreAdapter::GetPropertySize. Untuk properti seperti DXCoreAdapterProperty::IsHardware, yang merupakan Boolean sederhana, langkah ini tidak diperlukan.
  • Dan, akhirnya, ambil nilai properti dengan memanggil 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;
    }
}

Pilih adaptor pilihan dengan mengurutkan daftar adaptor

Anda dapat mengurutkan daftar adaptor DXCore dengan memanggil metode IDXCoreAdapterList::Sort .

Enumerasi DXCoreAdapterPreference menentukan nilai yang mewakili kriteria pengurutan. Teruskan array nilai tersebut ke Urutkan, lalu baca adaptor pertama dalam daftar yang diurutkan yang dihasilkan.

Untuk menentukan apakah jenis pengurutan akan dipahami oleh Sort, pertama-tama panggil 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;
}

Mengkueri dan mengatur status adaptor (properti)

Anda dapat mengambil dan mengatur status item status adaptor tertentu dengan memanggil metode IDXCoreAdapter::QueryState dan 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));
}

Dalam praktiknya, sebelum memanggil QueryState dan SetState, Anda harus memanggil IsQueryStateSupported untuk mengonfirmasi bahwa mengkueri jenis status tersedia untuk adaptor dan sistem operasi (OS) ini.

Kesegaran daftar adaptor

Jika daftar adaptor menjadi basi karena kondisi sistem yang berubah, daftar adaptor akan ditandai dengan demikian. Anda dapat menentukan kesegaran daftar adaptor dengan melakukan polling metode IDXCoreAdapterList::IsStale .

Namun, Anda dapat berlangganan pemberitahuan untuk kondisi seperti kedaluarsa. Untuk melakukannya, lewati DXCoreNotificationType::AdapterListStale ke IDXCoreAdapterFactory::RegisterEventNotification, dan simpan cookie yang dikembalikan dengan aman untuk digunakan nanti.

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

Anda kemudian dapat membuat objek daftar adaptor baru saat ini dari objek pabrik yang sudah Anda miliki. Menangani kondisi ini sangat penting bagi kemampuan Anda untuk merespons peristiwa dengan lancar seperti kedatangan dan penghapusan adaptor (baik itu GPU, atau adaptor komputasi khusus), dan untuk memindahkan beban kerja dengan tepat sebagai respons.

Sebelum Anda menghancurkan objek daftar adaptor, Anda harus menggunakan nilai cookie untuk membatalkan pendaftaran objek tersebut dari pemberitahuan dengan memanggil IDXCoreAdapterFactory::UnregisterEventNotification. Jika Anda tidak membatalkan pendaftaran, maka pengecualian fatal dimunculkan ketika situasi terdeteksi.

HRESULT hr = factory->UnregisterEventNotification(m_eventCookie);

Tampilkan informasi

Catatan

DXCore tidak menyediakan informasi tampilan apa pun. Jika perlu, Anda harus menggunakan kelas Windows Runtime DisplayMonitor untuk mengambil informasi ini. LUID adaptor menyediakan pengidentifikasi umum yang dapat Anda gunakan untuk memetakan adaptor DXCore ke informasi DisplayMonitor.DisplayAdapterId. Untuk mendapatkan LUID adaptor, teruskan metode DXCoreAdapterProperty::InstanceLuid ke metode IDXCoreAdapter::GetProperty .

Lihat juga