1 //! Physical graphics devices. 2 //! 3 //! The [`PhysicalDevice`][PhysicalDevice] trait specifies the API a backend 4 //! must provide for dealing with and querying a physical device, such as 5 //! a particular GPU. 6 //! 7 //! An [adapter][Adapter] is a struct containing a physical device and metadata 8 //! for a particular GPU, generally created from an [instance][crate::Instance] 9 //! of that [backend][crate::Backend]. 10 11 use crate::{ 12 device, format, image, memory, 13 queue::{QueueGroup, QueuePriority}, 14 Backend, Features, PhysicalDeviceProperties, 15 }; 16 17 use std::{any::Any, fmt}; 18 19 /// A description for a single type of memory in a heap. 20 #[derive(Copy, Clone, Debug, PartialEq, Eq)] 21 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 22 pub struct MemoryType { 23 /// Properties of the associated memory, such as synchronization 24 /// properties or whether it's on the CPU or GPU. 25 pub properties: memory::Properties, 26 /// Index to the underlying memory heap in `Gpu::memory_heaps` 27 pub heap_index: usize, 28 } 29 30 /// A description for a memory heap. 31 #[derive(Copy, Clone, Debug, PartialEq, Eq)] 32 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 33 pub struct MemoryHeap { 34 /// Total size of the heap. 35 pub size: u64, 36 /// Heap flags. 37 pub flags: memory::HeapFlags, 38 } 39 40 /// Types of memory supported by this adapter and available memory. 41 #[derive(Clone, Debug, Eq, PartialEq)] 42 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 43 pub struct MemoryProperties { 44 /// Each memory type is associated with one heap of `memory_heaps`. 45 /// Multiple types can point to the same heap. 46 pub memory_types: Vec<MemoryType>, 47 /// Memory heaps with their size in bytes. 48 pub memory_heaps: Vec<MemoryHeap>, 49 } 50 51 /// Represents a combination of a [logical device][crate::device::Device] and the 52 /// [hardware queues][QueueGroup] it provides. 53 /// 54 /// This structure is typically created from an [adapter][crate::adapter::Adapter]. 55 #[derive(Debug)] 56 pub struct Gpu<B: Backend> { 57 /// [Logical device][crate::device::Device] for a given backend. 58 pub device: B::Device, 59 /// The [command queues][crate::queue::Queue] that the device provides. 60 pub queue_groups: Vec<QueueGroup<B>>, 61 } 62 63 /// Represents a physical device (such as a GPU) capable of supporting the given backend. 64 pub trait PhysicalDevice<B: Backend>: fmt::Debug + Any + Send + Sync { 65 /// Create a new [logical device][crate::device::Device] with the requested features. 66 /// If `requested_features` is [empty][crate::Features::empty], then only 67 /// the core features are supported. 68 /// 69 /// # Arguments 70 /// 71 /// * `families` - which [queue families][crate::queue::family::QueueFamily] 72 /// to create queues from. The implementation may allocate more processing time to 73 /// the queues with higher [priority][QueuePriority]. 74 /// * `requested_features` - device features to enable. Must be a subset of 75 /// the [features][PhysicalDevice::features] supported by this device. 76 /// 77 /// # Errors 78 /// 79 /// - Returns `TooManyObjects` if the implementation can't create a new logical device. 80 /// - Returns `MissingFeature` if the implementation does not support a requested feature. 81 /// 82 /// # Examples 83 /// 84 /// ```no_run 85 /// # extern crate gfx_backend_empty as empty; 86 /// # extern crate gfx_hal; 87 /// # fn main() { 88 /// use gfx_hal::{adapter::PhysicalDevice, Features}; 89 /// 90 /// # let physical_device: empty::PhysicalDevice = return; 91 /// # let family: empty::QueueFamily = return; 92 /// # unsafe { 93 /// let gpu = physical_device.open(&[(&family, &[1.0; 1])], Features::empty()); 94 /// # }} 95 /// ``` open( &self, families: &[(&B::QueueFamily, &[QueuePriority])], requested_features: Features, ) -> Result<Gpu<B>, device::CreationError>96 unsafe fn open( 97 &self, 98 families: &[(&B::QueueFamily, &[QueuePriority])], 99 requested_features: Features, 100 ) -> Result<Gpu<B>, device::CreationError>; 101 102 /// Fetch details for a particular format. format_properties(&self, format: Option<format::Format>) -> format::Properties103 fn format_properties(&self, format: Option<format::Format>) -> format::Properties; 104 105 /// Fetch details for a particular image format. image_format_properties( &self, format: format::Format, dimensions: u8, tiling: image::Tiling, usage: image::Usage, view_caps: image::ViewCapabilities, ) -> Option<image::FormatProperties>106 fn image_format_properties( 107 &self, 108 format: format::Format, 109 dimensions: u8, 110 tiling: image::Tiling, 111 usage: image::Usage, 112 view_caps: image::ViewCapabilities, 113 ) -> Option<image::FormatProperties>; 114 115 /// Fetch details for the memory regions provided by the device. memory_properties(&self) -> MemoryProperties116 fn memory_properties(&self) -> MemoryProperties; 117 118 /// Returns the features of this `PhysicalDevice`. This usually depends on the graphics API being 119 /// used, as well as the actual platform underneath. features(&self) -> Features120 fn features(&self) -> Features; 121 122 /// Returns the properties of this `PhysicalDevice`. Similarly to `Features`, they 123 // depend on the platform, but unlike features, these are immutable and can't be switched on. properties(&self) -> PhysicalDeviceProperties124 fn properties(&self) -> PhysicalDeviceProperties; 125 126 /// Check cache compatibility with the `PhysicalDevice`. is_valid_cache(&self, _cache: &[u8]) -> bool127 fn is_valid_cache(&self, _cache: &[u8]) -> bool { 128 false 129 } 130 } 131 132 /// The type of a physical graphics device 133 #[derive(Clone, PartialEq, Eq, Debug)] 134 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 135 pub enum DeviceType { 136 /// Other 137 Other = 0, 138 /// Integrated 139 IntegratedGpu = 1, 140 /// Discrete 141 DiscreteGpu = 2, 142 /// Virtual / Hosted 143 VirtualGpu = 3, 144 /// CPU / Software Rendering 145 Cpu = 4, 146 } 147 148 /// Metadata about a backend [adapter][Adapter]. 149 #[derive(Clone, Debug, Eq, PartialEq)] 150 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] 151 pub struct AdapterInfo { 152 /// Adapter name 153 pub name: String, 154 /// PCI ID of the device vendor 155 pub vendor: usize, 156 /// PCI ID of the device 157 pub device: usize, 158 /// Type of device 159 pub device_type: DeviceType, 160 } 161 162 /// Information about a graphics device, supported by the backend. 163 /// 164 /// The list of available adapters is obtained by calling 165 /// [`Instance::enumerate_adapters`][crate::Instance::enumerate_adapters]. 166 /// 167 /// To create a [`Gpu`][Gpu] from this type you can use the [`open`](PhysicalDevice::open) 168 /// method on its [`physical_device`][Adapter::physical_device] field. 169 #[derive(Debug)] 170 pub struct Adapter<B: Backend> { 171 /// General information about this adapter. 172 pub info: AdapterInfo, 173 /// Actual [physical device][PhysicalDevice]. 174 pub physical_device: B::PhysicalDevice, 175 /// [Queue families][crate::queue::family::QueueFamily] supported by this adapter. 176 pub queue_families: Vec<B::QueueFamily>, 177 } 178