1#[allow(unused)]
11
12mod native;
13pub mod vk {
14 pub use native::VkPhysicalDeviceProperties as PhysicalDeviceProperties;
15 pub use native::VkQueueFamilyProperties as QueueFamilyProperties;
16 pub use native::VkPhysicalDeviceFeatures as PhysicalDeviceFeatures;
17
18 use crate::*;
19
20 pub struct Instance {
21 __instance: native::VkInstance,
22 __validation: native::VkDebugUtilsMessengerEXT,
23 }
24
25 impl Drop for Instance {
26 fn drop(&mut self) {
28 unsafe {
29 if cfg!(debug_assertions) {
30 assert!(!self.__validation.is_null());
31
32 let vk_destroy_debug_utils_messenger_ext:
33 unsafe extern "system" fn(
34 native::VkInstance,
35 native::VkDebugUtilsMessengerEXT,
36 *const ::std::ffi::c_void)
37 = std::mem::transmute(native::vkGetInstanceProcAddr
38 (self.__instance,
39 std::ffi::CString::new("vkDestroyDebugUtilsMessengerEXT")
40 .unwrap()
41 .to_owned()
42 .as_ptr()));
43
44 vk_destroy_debug_utils_messenger_ext(self.__instance, self.__validation, std::ptr::null());
45 }
46 native::vkDestroyInstance(self.__instance, std::ptr::null());
47 }
48 }
49 }
50
51
52 pub struct PhysicalDevice {
56 __physical_device: native::VkPhysicalDevice,
57 }
58
59
60 pub trait InstanceMethods {
61 fn enumerate_physical_devices(&self) -> Vec<PhysicalDevice>;
64 }
65
66 impl InstanceMethods for Instance {
67 fn enumerate_physical_devices(&self) -> Vec<PhysicalDevice> {
68 unsafe {
69 let mut num_devices: u32 = 0;
70 native::vkEnumeratePhysicalDevices(self.__instance, &mut num_devices, std::ptr::null_mut());
71 assert!(num_devices > 0);
72
73 let mut physical_devices: Vec<native::VkPhysicalDevice> = Vec::with_capacity(num_devices as usize);
74 native::vkEnumeratePhysicalDevices(self.__instance, &mut num_devices, physical_devices.as_mut_ptr());
75 physical_devices.set_len(num_devices as usize);
76
77 let mut devices: Vec<PhysicalDevice> = Vec::with_capacity(num_devices as usize);
78
79 for i in 0..num_devices {
80 dbg!(physical_devices[i as usize]);
81 let device = PhysicalDevice { __physical_device: physical_devices[i as usize] };
82 assert!(!device.__physical_device.is_null());
83 devices.push(device);
84 }
85
86 return devices;
87 }
88 }
89 }
90
91 pub trait PhysicalDeviceMethods {
92 fn get_properties(&self) -> native::VkPhysicalDeviceProperties;
96 fn get_queue_family_properties(&self) -> Vec<native::VkQueueFamilyProperties>;
100 fn get_features(&self) -> native::VkPhysicalDeviceFeatures;
104 }
105
106 impl PhysicalDeviceMethods for PhysicalDevice {
107 fn get_properties(&self) -> native::VkPhysicalDeviceProperties {
108 unsafe {
109 let mut properties: native::VkPhysicalDeviceProperties = std::mem::zeroed();
110 native::vkGetPhysicalDeviceProperties(self.__physical_device, &mut properties);
111 return properties;
112 }
113 }
114 fn get_queue_family_properties(&self) -> Vec<native::VkQueueFamilyProperties> {
115 unsafe {
116 let mut num_queue_families: u32 = 0;
117 native::vkGetPhysicalDeviceQueueFamilyProperties(self.__physical_device, &mut num_queue_families, std::ptr::null_mut());
118 assert!(num_queue_families > 0);
119
120 let mut queue_families: Vec<native::VkQueueFamilyProperties> = Vec::with_capacity(num_queue_families as usize);
121 native::vkGetPhysicalDeviceQueueFamilyProperties(self.__physical_device, &mut num_queue_families, queue_families.as_mut_ptr());
122 queue_families.set_len(num_queue_families as usize);
123
124 return queue_families;
125 }
126 }
127 fn get_features(&self) -> native::VkPhysicalDeviceFeatures {
128 unsafe {
129 let mut features: native::VkPhysicalDeviceFeatures = std::mem::zeroed();
130 native::vkGetPhysicalDeviceFeatures(self.__physical_device, &mut features);
131 return features;
132 }
133 }
134 }
135
136 pub fn make_version(major: u32, minor: u32, patch: u32) -> u32 {
139 return (patch<<0) | (minor<<12) | (major<<22) | (0<<29);
140 }
141
142 #[cfg(debug_assertions)]
143 extern "C" fn debug_callback(
144 _message_severity: native::VkDebugUtilsMessageSeverityFlagBitsEXT,
145 _message_types: native::VkDebugUtilsMessageTypeFlagsEXT,
146 _callback_data: *const native::VkDebugUtilsMessengerCallbackDataEXT,
147 _user_data: *mut ::std::os::raw::c_void,
148 ) -> native::VkBool32 {
149 unsafe {
150 let message = std::ffi::CStr::from_ptr((*_callback_data).pMessage);
151 if (_message_severity &
152 (native::VkDebugUtilsMessageSeverityFlagBitsEXT_VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT
153 |native::VkDebugUtilsMessageSeverityFlagBitsEXT_VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT))
154 != 0 {
155 panic!("Failed validating, message from layer: {:?}", message);
156 }
157 println!("{}", format!("Validation layer debug: {}", message.to_str().unwrap()));
158 }
159 return native::VK_TRUE;
160 }
161
162 #[cfg(debug_assertions)]
163 fn setup_validation_layer(instance: native::VkInstance) -> native::VkDebugUtilsMessengerEXT {
164 let debug_utils_create_info = native::VkDebugUtilsMessengerCreateInfoEXT {
165 sType: native::VkStructureType_VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
166 pNext: std::ptr::null(),
167 flags: 0,
168 messageSeverity:
169 native::VkDebugUtilsMessageSeverityFlagBitsEXT_VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT |
170 native::VkDebugUtilsMessageSeverityFlagBitsEXT_VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
171 native::VkDebugUtilsMessageSeverityFlagBitsEXT_VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
172 native::VkDebugUtilsMessageSeverityFlagBitsEXT_VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
173 messageType:
174 native::VkDebugUtilsMessageTypeFlagBitsEXT_VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
175 native::VkDebugUtilsMessageTypeFlagBitsEXT_VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
176 native::VkDebugUtilsMessageTypeFlagBitsEXT_VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
177 pfnUserCallback: Some(debug_callback),
178 pUserData: std::ptr::null_mut(),
179 };
180 unsafe {
181 let vk_create_debug_utils_messenger_ext:
182 unsafe extern "system" fn(
183 native::VkInstance,
184 *const native::VkDebugUtilsMessengerCreateInfoEXT,
185 *const ::std::ffi::c_void,
186 *mut native::VkDebugUtilsMessengerEXT)
187 -> native::VkResult
188 = std::mem::transmute(native::vkGetInstanceProcAddr
189 (instance,
190 std::ffi::CString::new("vkCreateDebugUtilsMessengerEXT")
191 .unwrap()
192 .to_owned()
193 .as_ptr()));
194 let mut out: native::VkDebugUtilsMessengerEXT = std::mem::zeroed();
195 vk_create_debug_utils_messenger_ext(instance, &debug_utils_create_info, std::ptr::null(), &mut out);
196 return out;
197 }
198 }
199
200
201 pub fn create_instance() -> Instance {
209 let enabled_layers: Vec<&str> =
210 vec!["VK_LAYER_KHRONOS_validation\0"];
211 let layer_count = enabled_layers.len();
212 let enabled_layers: *const *const i8 = Box::into_raw(enabled_layers.into_boxed_slice()).cast_const() as *const *const i8;
213
214 let enabled_exts: Vec<&str> =
215 vec!["VK_EXT_debug_utils\0"];
216 let ext_count = enabled_exts.len();
217 let enabled_exts: *const *const i8 = Box::into_raw(enabled_exts.into_boxed_slice()).cast_const() as *const *const i8;
218
219 let application_info = native::VkApplicationInfo {
220 sType: native::VkStructureType_VK_STRUCTURE_TYPE_APPLICATION_INFO,
221 pNext: std::ptr::null(),
222 pApplicationName: c"vulk".as_ptr(),
223 applicationVersion: make_version(0, 1, 0),
224 pEngineName: c"vulk".as_ptr(),
225 engineVersion: make_version(0, 1, 0),
226 apiVersion: make_version(1, 3, 0),
227 };
228 let instance_info = native::VkInstanceCreateInfo {
229 sType: native::VkStructureType_VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
230 pNext: std::ptr::null(),
231 flags: 0,
232 pApplicationInfo: &application_info,
233 enabledLayerCount: if cfg!(debug_assertions) { layer_count as u32 } else { 0 },
234 ppEnabledLayerNames: if cfg!(debug_assertions) { enabled_layers } else { std::ptr::null() },
235 enabledExtensionCount: if cfg!(debug_assertions) { ext_count as u32 } else { 0 },
236 ppEnabledExtensionNames: if cfg!(debug_assertions) { enabled_exts } else { std::ptr::null() },
237 };
238
239 unsafe {
240 let mut instance: native::VkInstance = { std::mem::zeroed() };
241 native::vkCreateInstance(&instance_info, std::ptr::null(), &mut instance);
242 assert!(!instance.is_null());
243 #[cfg(debug_assertions)] {
244 let validation = setup_validation_layer(instance);
245 return Instance { __instance: instance, __validation: validation};
246 }
247 #[cfg(not(debug_assertions))]
248 {
249 return Instance { __instance: instance, __validation: std::ptr::null_mut()};
250 }
251 }
252 }
253
254}