ferroui_vulkan/unmanaged_interop/
vulkan_instance_api.rs1use super::vulkan_global_api::{proc_loader, read_into_vec};
2use crate::IVulkanInstance;
3use ash::vk;
4use std::ffi::CStr;
5use std::ptr;
6use std::sync::Arc;
7
8pub struct VulkanInstanceApi {
16 instance: Arc<dyn IVulkanInstance>,
17 fp: ash::InstanceFnV1_0,
18 fp_1_1: ash::InstanceFnV1_1,
19 device_fp: ash::DeviceFnV1_0,
22 surface: ash::khr::surface::InstanceFn,
23 debug_utils: ash::ext::debug_utils::InstanceFn,
24}
25
26impl VulkanInstanceApi {
27 pub fn new(instance: Arc<dyn IVulkanInstance>) -> Self {
31 let handle = instance.handle();
32 let lookup = |name: &str| instance.get_instance_proc_address(handle, name);
33 let fp = ash::InstanceFnV1_0::load(proc_loader(lookup));
34 let fp_1_1 = ash::InstanceFnV1_1::load(proc_loader(lookup));
35 let device_fp = ash::DeviceFnV1_0::load(proc_loader(lookup));
36 let surface = ash::khr::surface::InstanceFn::load(proc_loader(lookup));
37 let debug_utils = ash::ext::debug_utils::InstanceFn::load(proc_loader(lookup));
38 Self { instance, fp, fp_1_1, device_fp, surface, debug_utils }
39 }
40
41 pub fn instance(&self) -> &Arc<dyn IVulkanInstance> {
43 &self.instance
44 }
45
46 pub fn create_debug_utils_messenger_ext(
48 &self,
49 instance: vk::Instance,
50 create_info: &vk::DebugUtilsMessengerCreateInfoEXT<'_>,
51 ) -> Result<vk::DebugUtilsMessengerEXT, vk::Result> {
52 let mut messenger = vk::DebugUtilsMessengerEXT::null();
53 let result = unsafe {
56 (self.debug_utils.create_debug_utils_messenger_ext)(instance, create_info, ptr::null(), &mut messenger)
57 };
58 match result {
59 vk::Result::SUCCESS => Ok(messenger),
60 error => Err(error),
61 }
62 }
63
64 pub fn enumerate_physical_devices(&self, instance: vk::Instance) -> Result<Vec<vk::PhysicalDevice>, vk::Result> {
66 read_into_vec(|count, data| unsafe { (self.fp.enumerate_physical_devices)(instance, count, data) })
69 }
70
71 pub fn get_physical_device_properties(&self, physical_device: vk::PhysicalDevice) -> vk::PhysicalDeviceProperties {
73 let mut properties = vk::PhysicalDeviceProperties::default();
74 unsafe { (self.fp.get_physical_device_properties)(physical_device, &mut properties) };
76 properties
77 }
78
79 pub fn enumerate_device_extension_properties(
81 &self,
82 physical_device: vk::PhysicalDevice,
83 ) -> Result<Vec<vk::ExtensionProperties>, vk::Result> {
84 read_into_vec(|count, data| unsafe {
86 (self.fp.enumerate_device_extension_properties)(physical_device, ptr::null(), count, data)
87 })
88 }
89
90 pub fn get_physical_device_surface_support_khr(
93 &self,
94 physical_device: vk::PhysicalDevice,
95 queue_family_index: u32,
96 surface: vk::SurfaceKHR,
97 ) -> Result<bool, vk::Result> {
98 let mut supported = vk::FALSE;
99 let result = unsafe {
101 (self.surface.get_physical_device_surface_support_khr)(
102 physical_device,
103 queue_family_index,
104 surface,
105 &mut supported,
106 )
107 };
108 match result {
109 vk::Result::SUCCESS => Ok(supported != vk::FALSE),
110 error => Err(error),
111 }
112 }
113
114 pub fn get_physical_device_queue_family_properties(
116 &self,
117 physical_device: vk::PhysicalDevice,
118 ) -> Vec<vk::QueueFamilyProperties> {
119 read_into_vec(|count, data| unsafe {
121 (self.fp.get_physical_device_queue_family_properties)(physical_device, count, data);
122 vk::Result::SUCCESS
123 })
124 .unwrap_or_default()
125 }
126
127 pub fn create_device(
129 &self,
130 physical_device: vk::PhysicalDevice,
131 create_info: &vk::DeviceCreateInfo<'_>,
132 ) -> Result<vk::Device, vk::Result> {
133 let mut device = vk::Device::null();
134 let result = unsafe { (self.fp.create_device)(physical_device, create_info, ptr::null(), &mut device) };
137 match result {
138 vk::Result::SUCCESS => Ok(device),
139 error => Err(error),
140 }
141 }
142
143 pub fn destroy_device(&self, device: vk::Device) {
146 unsafe { (self.device_fp.destroy_device)(device, ptr::null()) };
148 }
149
150 pub fn get_device_queue(&self, device: vk::Device, queue_family_index: u32, queue_index: u32) -> vk::Queue {
152 let mut queue = vk::Queue::null();
153 unsafe { (self.device_fp.get_device_queue)(device, queue_family_index, queue_index, &mut queue) };
155 queue
156 }
157
158 pub fn get_device_proc_addr(&self, device: vk::Device, name: &CStr) -> isize {
161 let address = unsafe { (self.fp.get_device_proc_addr)(device, name.as_ptr()) };
163 address.map_or(0, |address| address as usize as isize)
164 }
165
166 pub fn destroy_surface_khr(&self, instance: vk::Instance, surface: vk::SurfaceKHR) {
168 unsafe { (self.surface.destroy_surface_khr)(instance, surface, ptr::null()) };
170 }
171
172 pub fn get_physical_device_surface_formats_khr(
174 &self,
175 physical_device: vk::PhysicalDevice,
176 surface: vk::SurfaceKHR,
177 ) -> Result<Vec<vk::SurfaceFormatKHR>, vk::Result> {
178 read_into_vec(|count, data| unsafe {
180 (self.surface.get_physical_device_surface_formats_khr)(physical_device, surface, count, data)
181 })
182 }
183
184 pub fn get_physical_device_memory_properties(
186 &self,
187 physical_device: vk::PhysicalDevice,
188 ) -> vk::PhysicalDeviceMemoryProperties {
189 let mut properties = vk::PhysicalDeviceMemoryProperties::default();
190 unsafe { (self.fp.get_physical_device_memory_properties)(physical_device, &mut properties) };
192 properties
193 }
194
195 pub fn get_physical_device_surface_capabilities_khr(
197 &self,
198 physical_device: vk::PhysicalDevice,
199 surface: vk::SurfaceKHR,
200 ) -> Result<vk::SurfaceCapabilitiesKHR, vk::Result> {
201 let mut capabilities = vk::SurfaceCapabilitiesKHR::default();
202 let result = unsafe {
204 (self.surface.get_physical_device_surface_capabilities_khr)(physical_device, surface, &mut capabilities)
205 };
206 match result {
207 vk::Result::SUCCESS => Ok(capabilities),
208 error => Err(error),
209 }
210 }
211
212 pub fn get_physical_device_surface_present_modes_khr(
214 &self,
215 physical_device: vk::PhysicalDevice,
216 surface: vk::SurfaceKHR,
217 ) -> Result<Vec<vk::PresentModeKHR>, vk::Result> {
218 read_into_vec(|count, data| unsafe {
220 (self.surface.get_physical_device_surface_present_modes_khr)(physical_device, surface, count, data)
221 })
222 }
223
224 pub fn get_physical_device_properties2(
227 &self,
228 physical_device: vk::PhysicalDevice,
229 properties: &mut vk::PhysicalDeviceProperties2<'_>,
230 ) {
231 unsafe { (self.fp_1_1.get_physical_device_properties2)(physical_device, properties) };
234 }
235}