gfx_hal/
adapter.rs

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
11use crate::{
12    buffer, device, display, external_memory, format, image, memory,
13    queue::{QueueGroup, QueuePriority},
14    Backend, Features, PhysicalDeviceProperties,
15};
16
17use 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))]
22pub 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))]
33pub 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))]
43pub 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)]
56pub 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.
64pub 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    /// ```
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.
103    fn format_properties(&self, format: Option<format::Format>) -> format::Properties;
104
105    /// Fetch details for a particular image format.
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.
116    fn memory_properties(&self) -> MemoryProperties;
117
118    /// Get external buffer properties. The parameters specify how the buffer is going to used.
119    /// # Arguments
120    ///
121    /// * `usage` - the usage of the buffer.
122    /// * `sparse` - the sparse flags of the buffer.
123    /// * `memory_type` - the external memory type for the buffer.
124    fn external_buffer_properties(
125        &self,
126        usage: buffer::Usage,
127        sparse: memory::SparseFlags,
128        memory_type: external_memory::ExternalMemoryType,
129    ) -> external_memory::ExternalMemoryProperties;
130
131    /// Get external image properties. The parameters specify how the image is going to used.
132    /// # Arguments
133    ///
134    /// * `format` - the format of the image.
135    /// * `dimensions` - the dimensions of the image.
136    /// * `tiling` - the tiling mode of the image.
137    /// * `usage` - the usage of the image.
138    /// * `view_caps` - the view capabilities of the image.
139    /// * `external_memory_type` - the external memory type for the image.
140    /// # Errors
141    ///
142    /// - Returns `OutOfMemory` if the implementation goes out of memory during the operation.
143    /// - Returns `FormatNotSupported` if the implementation does not support the requested image format.
144    ///
145    fn external_image_properties(
146        &self,
147        format: format::Format,
148        dimensions: u8,
149        tiling: image::Tiling,
150        usage: image::Usage,
151        view_caps: image::ViewCapabilities,
152        external_memory_type: external_memory::ExternalMemoryType,
153    ) -> Result<external_memory::ExternalMemoryProperties, external_memory::ExternalImagePropertiesError>;
154
155    /// Returns the features of this `PhysicalDevice`. This usually depends on the graphics API being
156    /// used, as well as the actual platform underneath.
157    fn features(&self) -> Features;
158
159    /// Returns the properties of this `PhysicalDevice`. Similarly to `Features`, they
160    // depend on the platform, but unlike features, these are immutable and can't be switched on.
161    fn properties(&self) -> PhysicalDeviceProperties;
162
163    /// Check cache compatibility with the `PhysicalDevice`.
164    fn is_valid_cache(&self, _cache: &[u8]) -> bool {
165        false
166    }
167
168    /// Enumerate active displays [surface][display::Display] from display.
169    /// Please notice that, even if a system has displays attached, they could be not returned because they are managed by some other components.
170    /// This function only return the display that are available to be managed by the current application.
171    /// Since, generally, while compositor are running they take the control of every display connected, it could be better to run the application directly from the tty to avoid the return of an empty list.
172    /// # Arguments
173    ///
174    /// * `adapter` - the [adapter][crate::adapter::Adapter] from which the displays will be enumerated.
175    unsafe fn enumerate_displays(&self) -> Vec<display::Display<B>>;
176
177    /// Enumerate compatibles planes with the provided display.
178    /// # Arguments
179    ///
180    /// * `display` - display on which the the compatible planes will be listed.
181    unsafe fn enumerate_compatible_planes(
182        &self,
183        display: &display::Display<B>,
184    ) -> Vec<display::Plane>;
185
186    /// Create a new display mode from a display, a resolution, a refresh_rate and the plane index.
187    /// If the builtin display modes does not satisfy the requirements, this function will try to create a new one.
188    /// # Arguments
189    ///
190    /// * `display` - display on which the display mode will be created.
191    /// * `resolution` - the desired resolution.
192    /// * `refresh_rate` - the desired refresh_rate.
193    unsafe fn create_display_mode(
194        &self,
195        display: &display::Display<B>,
196        resolution: (u32, u32),
197        refresh_rate: u32,
198    ) -> Result<display::DisplayMode<B>, display::DisplayModeError>;
199
200    /// Create a display plane from a display, a resolution, a refresh_rate and a plane.
201    /// If the builtin display modes does not satisfy the requirements, this function will try to create a new one.
202    /// # Arguments
203    ///
204    /// * `display` - display on which the display plane will be created.
205    /// * `plane` - the plane on which the surface will be rendered on.
206    /// * `resolution` - the desired resolution.
207    /// * `refresh_rate` - the desired refresh_rate.
208    unsafe fn create_display_plane<'a>(
209        &self,
210        display: &'a display::DisplayMode<B>,
211        plane: &'a display::Plane,
212    ) -> Result<display::DisplayPlane<'a, B>, device::OutOfMemory>;
213}
214
215/// The type of a physical graphics device
216#[derive(Clone, PartialEq, Eq, Debug)]
217#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
218pub enum DeviceType {
219    /// Other
220    Other = 0,
221    /// Integrated
222    IntegratedGpu = 1,
223    /// Discrete
224    DiscreteGpu = 2,
225    /// Virtual / Hosted
226    VirtualGpu = 3,
227    /// CPU / Software Rendering
228    Cpu = 4,
229}
230
231/// Metadata about a backend [adapter][Adapter].
232#[derive(Clone, Debug, Eq, PartialEq)]
233#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
234pub struct AdapterInfo {
235    /// Adapter name
236    pub name: String,
237    /// PCI ID of the device vendor
238    pub vendor: usize,
239    /// PCI ID of the device
240    pub device: usize,
241    /// Type of device
242    pub device_type: DeviceType,
243}
244
245/// Information about a graphics device, supported by the backend.
246///
247/// The list of available adapters is obtained by calling
248/// [`Instance::enumerate_adapters`][crate::Instance::enumerate_adapters].
249///
250/// To create a [`Gpu`][Gpu] from this type you can use the [`open`](PhysicalDevice::open)
251/// method on its [`physical_device`][Adapter::physical_device] field.
252#[derive(Debug)]
253pub struct Adapter<B: Backend> {
254    /// General information about this adapter.
255    pub info: AdapterInfo,
256    /// Actual [physical device][PhysicalDevice].
257    pub physical_device: B::PhysicalDevice,
258    /// [Queue families][crate::queue::family::QueueFamily] supported by this adapter.
259    pub queue_families: Vec<B::QueueFamily>,
260}