1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
// Generated by `scripts/generate_vk.js`

use utils::c_bindings::*;
use utils::vk_traits::*;
use utils::vk_ptr::*;
use utils::vk_convert::*;
use std::os::raw::c_char;
use std::ptr;
use std::mem;
use std::cmp;
use vk::*;

pub type RawVkInstance = u64;

#[derive(Debug, Copy, Clone)]
pub struct VkInstance {
    _handle: RawVkInstance,
    _parent_instance: RawVkInstance,
    _parent_device: RawVkDevice,
    _fn_table: *mut VkInstanceFunctionTable
}

impl VkRawType<VkInstance> for RawVkInstance {
    fn vk_to_wrapped(src: &RawVkInstance) -> VkInstance {
        VkInstance {
            _handle: *src,
            _parent_instance: 0,
            _parent_device: 0,
            _fn_table: ptr::null_mut()
        }
    }
}

impl VkWrappedType<RawVkInstance> for VkInstance {
    fn vk_to_raw(src: &VkInstance, dst: &mut RawVkInstance) {
        *dst = src._handle
    }
}

impl Default for VkInstance {
    fn default() -> VkInstance {
        VkInstance {
            _handle: 0,
            _parent_instance: 0,
            _parent_device: 0,
            _fn_table: ptr::null_mut()
        }
    }
}

impl VkSetup for VkInstance {
    fn vk_setup(&mut self, fn_table: *mut VkInstanceFunctionTable, instance: RawVkInstance, device: RawVkDevice) {
        self._parent_instance = instance;
        self._parent_device = device;
        self._fn_table = fn_table;
    }
}

impl VkInstance {
    pub fn create_surface<F : Fn(u64, *const c_void, *mut u64) -> i32>(&self, create_fn: F) -> Result<khr::VkSurface, VkResult> {
        unsafe {
            let raw_surface = &mut mem::uninitialized() as *mut khr::RawVkSurface;
            let vk_result = create_fn(self._handle, ptr::null(), raw_surface);
            if vk_result != 0 { return Err(RawVkResult::vk_to_wrapped(&vk_result)) }
            let mut surface = new_vk_value(raw_surface);
            let fn_table = self._fn_table;
            let parent_instance = self._parent_instance;
            let parent_device = self._parent_device;
            VkSetup::vk_setup(&mut surface, fn_table, parent_instance, parent_device);
            Ok(surface)
        }
    }
}

impl VkInstance {
    
    pub fn handle(&self) -> u64 {
        self._handle
    }
    
    pub fn destroy(&self) {
        unsafe {
            ((&*self._fn_table).vkDestroyInstance)(self._handle, ptr::null());
            Box::from_raw(self._fn_table);
        }
    }
    
    pub fn enumerate_physical_devices(&self) -> Result<Vec<VkPhysicalDevice>, VkResult> {
        unsafe {
            let mut raw_physical_devices : *mut RawVkPhysicalDevice = ptr::null_mut();
            let raw_physical_device_count = &mut mem::uninitialized() as *mut u32;
            let vk_result = ((&*self._fn_table).vkEnumeratePhysicalDevices)(self._handle, raw_physical_device_count, raw_physical_devices);
            if vk_result != 0 { return Err(RawVkResult::vk_to_wrapped(&vk_result)) }
            raw_physical_devices = malloc((*raw_physical_device_count as usize) * mem::size_of::<RawVkPhysicalDevice>()) as *mut RawVkPhysicalDevice;
            
            let vk_result = ((&*self._fn_table).vkEnumeratePhysicalDevices)(self._handle, raw_physical_device_count, raw_physical_devices);
            if vk_result != 0 { return Err(RawVkResult::vk_to_wrapped(&vk_result)) }
            
            let mut physical_devices = new_vk_array(*raw_physical_device_count, raw_physical_devices);
            for elt in &mut physical_devices { VkSetup::vk_setup(elt, self._fn_table, self._parent_instance, self._parent_device); }
            free_ptr(raw_physical_devices);
            Ok(physical_devices)
        }
    }
    
    pub fn enumerate_physical_device_groups(&self) -> Result<Vec<VkPhysicalDeviceGroupProperties>, VkResult> {
        unsafe {
            let mut raw_physical_device_group_properties : *mut RawVkPhysicalDeviceGroupProperties = ptr::null_mut();
            let raw_physical_device_group_count = &mut mem::uninitialized() as *mut u32;
            let vk_result = ((&*self._fn_table).vkEnumeratePhysicalDeviceGroups)(self._handle, raw_physical_device_group_count, raw_physical_device_group_properties);
            if vk_result != 0 { return Err(RawVkResult::vk_to_wrapped(&vk_result)) }
            raw_physical_device_group_properties = malloc((*raw_physical_device_group_count as usize) * mem::size_of::<RawVkPhysicalDeviceGroupProperties>()) as *mut RawVkPhysicalDeviceGroupProperties;
            
            let vk_result = ((&*self._fn_table).vkEnumeratePhysicalDeviceGroups)(self._handle, raw_physical_device_group_count, raw_physical_device_group_properties);
            if vk_result != 0 { return Err(RawVkResult::vk_to_wrapped(&vk_result)) }
            
            let mut physical_device_group_properties = new_vk_array(*raw_physical_device_group_count, raw_physical_device_group_properties);
            for elt in &mut physical_device_group_properties { VkSetup::vk_setup(elt, self._fn_table, self._parent_instance, self._parent_device); }
            free_vk_ptr_array(*raw_physical_device_group_count as usize, raw_physical_device_group_properties);
            Ok(physical_device_group_properties)
        }
    }
    
    pub fn create_display_plane_surface(&self, create_info: &khr::VkDisplaySurfaceCreateInfo) -> Result<khr::VkSurface, VkResult> {
        unsafe {
            let raw_create_info = new_ptr_vk_value(create_info);
            let raw_surface = &mut mem::uninitialized() as *mut khr::RawVkSurface;
            
            let vk_result = ((&*self._fn_table).vkCreateDisplayPlaneSurfaceKHR)(self._handle, raw_create_info, ptr::null(), raw_surface);
            if vk_result != 0 { return Err(RawVkResult::vk_to_wrapped(&vk_result)) }
            
            let mut surface = new_vk_value(raw_surface);
            let fn_table = self._fn_table;
            let parent_instance = self._parent_instance;
            let parent_device = self._parent_device;
            VkSetup::vk_setup(&mut surface, fn_table, parent_instance, parent_device);
            free_vk_ptr(raw_create_info);
            Ok(surface)
        }
    }
    
    pub fn create_debug_report_callback(&self, create_info: &ext::VkDebugReportCallbackCreateInfo) -> Result<ext::VkDebugReportCallback, VkResult> {
        unsafe {
            let raw_create_info = new_ptr_vk_value(create_info);
            let raw_callback = &mut mem::uninitialized() as *mut ext::RawVkDebugReportCallback;
            
            let vk_result = ((&*self._fn_table).vkCreateDebugReportCallbackEXT)(self._handle, raw_create_info, ptr::null(), raw_callback);
            if vk_result != 0 { return Err(RawVkResult::vk_to_wrapped(&vk_result)) }
            
            let mut callback = new_vk_value(raw_callback);
            let fn_table = self._fn_table;
            let parent_instance = self._parent_instance;
            let parent_device = self._parent_device;
            VkSetup::vk_setup(&mut callback, fn_table, parent_instance, parent_device);
            free_vk_ptr(raw_create_info);
            Ok(callback)
        }
    }
    
    pub fn debug_report_message(&self, flags: ext::VkDebugReportFlags, object_type: ext::VkDebugReportObjectType, object: usize, location: usize, message_code: isize, layer_prefix: &str, message: &str) {
        unsafe {
            let raw_flags = vk_to_raw_value(&flags);
            let raw_object_type = vk_to_raw_value(&object_type);
            let raw_object = vk_to_raw_value(&object);
            let raw_location = location;
            let raw_message_code = vk_to_raw_value(&message_code);
            let raw_layer_prefix = new_ptr_string(layer_prefix);
            let raw_message = new_ptr_string(message);
            ((&*self._fn_table).vkDebugReportMessageEXT)(self._handle, raw_flags, raw_object_type, raw_object, raw_location, raw_message_code, raw_layer_prefix, raw_message);
            free_ptr(raw_layer_prefix);
            free_ptr(raw_message);
        }
    }
    
    pub fn create_debug_utils_messenger(&self, create_info: &ext::VkDebugUtilsMessengerCreateInfo) -> Result<ext::VkDebugUtilsMessenger, VkResult> {
        unsafe {
            let raw_create_info = new_ptr_vk_value(create_info);
            let raw_messenger = &mut mem::uninitialized() as *mut ext::RawVkDebugUtilsMessenger;
            
            let vk_result = ((&*self._fn_table).vkCreateDebugUtilsMessengerEXT)(self._handle, raw_create_info, ptr::null(), raw_messenger);
            if vk_result != 0 { return Err(RawVkResult::vk_to_wrapped(&vk_result)) }
            
            let mut messenger = new_vk_value(raw_messenger);
            let fn_table = self._fn_table;
            let parent_instance = self._parent_instance;
            let parent_device = self._parent_device;
            VkSetup::vk_setup(&mut messenger, fn_table, parent_instance, parent_device);
            free_vk_ptr(raw_create_info);
            Ok(messenger)
        }
    }
    
    pub fn submit_debug_utils_message(&self, message_severity: ext::VkDebugUtilsMessageSeverityFlags, message_types: ext::VkDebugUtilsMessageTypeFlags, callback_data: &ext::VkDebugUtilsMessengerCallbackData) {
        unsafe {
            let raw_message_severity = vk_to_raw_value(&message_severity);
            let raw_message_types = vk_to_raw_value(&message_types);
            let raw_callback_data = new_ptr_vk_value(callback_data);
            ((&*self._fn_table).vkSubmitDebugUtilsMessageEXT)(self._handle, raw_message_severity, raw_message_types, raw_callback_data);
            free_vk_ptr(raw_callback_data);
        }
    }
}