dxwr 0.4.3

Direct3D12 and DXGI wrapper library
Documentation
use super::utility::dxgi_factory;
use std::sync::Arc;
use windows::Win32::Foundation::LUID;
use windows::Win32::Graphics::Dxgi::*;
use windows::core::Interface;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct AdapterId {
    pub vendor_id: u32,
    pub device_id: u32,
    pub sub_sys_id: u32,
    pub revision: u32,
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct AdapterMemoryInfo {
    pub dedicate_video_memory: usize,
    pub dedicate_system_memory: usize,
    pub shared_system_memory: usize,
}

#[derive(Clone, Debug)]
pub struct Adapter {
    handle: IDXGIAdapter4,
    desc: Arc<DXGI_ADAPTER_DESC3>,
}

impl Adapter {
    #[inline]
    pub fn description(&self) -> String {
        let len = self
            .desc
            .Description
            .iter()
            .position(|d| *d == 0)
            .unwrap_or(self.desc.Description.len());
        String::from_utf16_lossy(&self.desc.Description[..len])
    }

    #[inline]
    pub fn id(&self) -> AdapterId {
        AdapterId {
            vendor_id: self.desc.VendorId,
            device_id: self.desc.DeviceId,
            sub_sys_id: self.desc.SubSysId,
            revision: self.desc.Revision,
        }
    }

    #[inline]
    pub fn memory_info(&self) -> AdapterMemoryInfo {
        AdapterMemoryInfo {
            dedicate_video_memory: self.desc.DedicatedVideoMemory,
            dedicate_system_memory: self.desc.DedicatedSystemMemory,
            shared_system_memory: self.desc.SharedSystemMemory,
        }
    }

    #[inline]
    pub fn flags(&self) -> DXGI_ADAPTER_FLAG3 {
        self.desc.Flags
    }

    #[inline]
    pub fn luid(&self) -> LUID {
        self.desc.AdapterLuid
    }

    #[inline]
    pub fn graphics_preemption_granularity(&self) -> DXGI_GRAPHICS_PREEMPTION_GRANULARITY {
        self.desc.GraphicsPreemptionGranularity
    }

    #[inline]
    pub fn compute_preemption_granularity(&self) -> DXGI_COMPUTE_PREEMPTION_GRANULARITY {
        self.desc.ComputePreemptionGranularity
    }

    #[inline]
    pub fn handle(&self) -> &IDXGIAdapter4 {
        &self.handle
    }
}

pub fn enum_adapters() -> windows::core::Result<Vec<Adapter>> {
    let factory = dxgi_factory();
    let mut adapters = vec![];
    let mut index = 0;
    unsafe {
        loop {
            let ret = factory.EnumAdapters1(index);
            match ret {
                Ok(adapter) => {
                    let handle = adapter.cast::<IDXGIAdapter4>().unwrap();
                    let desc = handle.GetDesc3()?;
                    adapters.push(Adapter {
                        handle,
                        desc: Arc::new(desc),
                    });
                    index += 1;
                }
                Err(e) if e.code() == DXGI_ERROR_NOT_FOUND => break,
                Err(e) => return Err(e),
            }
        }
    }
    Ok(adapters)
}

#[inline]
pub fn enum_warp_adapter() -> windows::core::Result<Adapter> {
    let factory = dxgi_factory();
    let handle: IDXGIAdapter4 = unsafe { factory.EnumWarpAdapter()? };
    let desc = unsafe { handle.GetDesc3()? };
    Ok(Adapter {
        handle,
        desc: Arc::new(desc),
    })
}