1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
use {
    super::{Device, DriverConfig, Instance, Surface},
    crate::ptr::Shared,
    archery::SharedPointerKind,
    ash::vk,
    std::{fmt::Debug, ops::Deref},
};

#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub struct QueueFamily {
    pub idx: u32,
    pub props: QueueFamilyProperties,
}

#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
pub struct QueueFamilyProperties {
    pub queue_flags: vk::QueueFlags,
    pub queue_count: u32,
    pub timestamp_valid_bits: u32,
    pub min_image_transfer_granularity: [u32; 3],
}

#[derive(Clone)]
pub struct PhysicalDevice {
    pub mem_props: vk::PhysicalDeviceMemoryProperties,
    physical_device: vk::PhysicalDevice,
    pub props: vk::PhysicalDeviceProperties,
    queue_families: Vec<QueueFamily>,
}

impl PhysicalDevice {
    pub fn new(
        physical_device: vk::PhysicalDevice,
        mem_props: vk::PhysicalDeviceMemoryProperties,
        props: vk::PhysicalDeviceProperties,
        queue_families: Vec<QueueFamily>,
    ) -> Self {
        Self {
            mem_props,
            physical_device,
            props,
            queue_families,
        }
    }

    pub fn has_presentation_support<P>(
        this: &Self,
        instance: &Shared<Instance, P>,
        surface: &Surface<P>,
    ) -> bool
    where
        P: SharedPointerKind,
    {
        if let Ok(device) = Device::create(
            instance,
            this.clone(),
            DriverConfig::new().presentation(true).build().unwrap(),
        ) {
            this.queue_families
                .iter()
                .enumerate()
                .any(|(queue_idx, info)| unsafe {
                    info.props.queue_flags.contains(vk::QueueFlags::GRAPHICS)
                        && device
                            .surface_ext
                            .get_physical_device_surface_support(
                                this.physical_device,
                                queue_idx as _,
                                **surface,
                            )
                            .ok()
                            .unwrap_or_default()
                })
        } else {
            false
        }
    }

    pub fn has_ray_tracing_support(_this: &Self) -> bool {
        // TODO!
        false
    }

    pub fn queue_families(this: &Self) -> impl Iterator<Item = QueueFamily> + '_ {
        this.queue_families.iter().copied()
    }
}

impl Debug for PhysicalDevice {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "PhysicalDevice {{ {:#?} }}", self.props)
    }
}

impl Deref for PhysicalDevice {
    type Target = vk::PhysicalDevice;

    fn deref(&self) -> &Self::Target {
        &self.physical_device
    }
}