ferroui_vulkan/i_vulkan_device.rs
1use crate::unmanaged_interop::{VulkanDeviceApi, VulkanInstanceApi};
2use crate::IVulkanRenderTarget;
3use ash::vk;
4use ferroui_base::platform::surfaces::IPlatformRenderSurface;
5use ferroui_base::platform::{IOptionalFeatureProvider, IPlatformGraphicsContext};
6use ferroui_base::reactive::IDisposable;
7use std::rc::Rc;
8use std::sync::Arc;
9
10/// A Vulkan device with the queue the framework renders with.
11///
12/// A device is shared by threads (an application may hand one device to the
13/// platform graphics, which every render thread then uses), so it is held in
14/// an `Arc`; its queue is only used while the device is locked.
15pub trait IVulkanDevice: IOptionalFeatureProvider + Send + Sync {
16 /// The `VkDevice`.
17 fn handle(&self) -> isize;
18
19 /// The `VkPhysicalDevice` the device was created for.
20 fn physical_device_handle(&self) -> isize;
21
22 /// The `VkQueue` commands are submitted to. Only valid while the device
23 /// is locked by the calling thread.
24 fn main_queue_handle(&self) -> isize;
25
26 /// The index of the queue family of the main queue.
27 fn graphics_queue_family_index(&self) -> u32;
28
29 /// The instance the device belongs to.
30 fn instance(&self) -> Arc<dyn IVulkanInstance>;
31
32 /// Whether the device was lost.
33 fn is_lost(&self) -> bool;
34
35 /// Takes the device for the calling thread until the result is
36 /// disposed. A thread may lock a device it has locked already.
37 fn lock(&self) -> Rc<dyn IDisposable>;
38
39 /// The names of the device extensions that were enabled.
40 fn enabled_extensions(&self) -> Vec<String>;
41
42 /// Destroys the device.
43 fn dispose(&self);
44}
45
46/// A Vulkan instance and the way to its entry points.
47pub trait IVulkanInstance: Send + Sync {
48 /// The `VkInstance`.
49 fn handle(&self) -> isize;
50
51 /// The address of an instance-level entry point (`vkGetInstanceProcAddr`);
52 /// zero when the instance does not have it.
53 fn get_instance_proc_address(&self, instance: isize, name: &str) -> isize;
54
55 /// The address of a device-level entry point (`vkGetDeviceProcAddr`);
56 /// zero when the device does not have it.
57 fn get_device_proc_address(&self, device: isize, name: &str) -> isize;
58
59 /// The names of the instance extensions that were enabled.
60 fn enabled_extensions(&self) -> Vec<String>;
61}
62
63/// A platform graphics context that renders with Vulkan.
64///
65/// A graphics context that is a Vulkan context announces it through its
66/// optional features: `try_get_feature(TypeId::of::<dyn
67/// IVulkanPlatformGraphicsContext>())` returns an `Rc<dyn
68/// IVulkanPlatformGraphicsContext>`.
69///
70/// The contract is implemented by this crate only: the members after
71/// [`instance`](Self::instance) up to
72/// [`graphics_queue_family_index`](Self::graphics_queue_family_index) are
73/// what the objects of the crate (images, command buffers, the swap chain)
74/// read of their context.
75pub trait IVulkanPlatformGraphicsContext: IPlatformGraphicsContext {
76 /// The device of the context.
77 fn device(&self) -> Arc<dyn IVulkanDevice>;
78
79 /// The instance of the device.
80 fn instance(&self) -> Arc<dyn IVulkanInstance>;
81
82 /// The instance-level entry points.
83 fn instance_api(&self) -> &VulkanInstanceApi;
84
85 /// The device-level entry points.
86 fn device_api(&self) -> &VulkanDeviceApi;
87
88 /// The device as a typed handle.
89 fn device_handle(&self) -> vk::Device;
90
91 /// The physical device as a typed handle.
92 fn physical_device_handle(&self) -> vk::PhysicalDevice;
93
94 /// The instance as a typed handle.
95 fn instance_handle(&self) -> vk::Instance;
96
97 /// The main queue as a typed handle. Only valid while the device is
98 /// locked by the calling thread.
99 fn main_queue_handle(&self) -> vk::Queue;
100
101 /// The index of the queue family of the main queue.
102 fn graphics_queue_family_index(&self) -> u32;
103
104 /// Creates a render target for the first of the surfaces the context
105 /// can render to.
106 ///
107 /// # Panics
108 /// Panics when none of the surfaces is suitable, and when the swap chain
109 /// of the surface cannot be created.
110 fn create_render_target(&self, surfaces: &[Arc<dyn IPlatformRenderSurface>]) -> Rc<dyn IVulkanRenderTarget>;
111}