WIP setup "window surface", "presentation queue"
TODO: "swap chain" https://vulkan-tutorial.com/en/Drawing_a_triangle/Presentation/Swap_chain
This commit is contained in:
parent
62c01acc7a
commit
5e9b12a0a2
1 changed files with 101 additions and 62 deletions
163
src/main.rs
163
src/main.rs
|
@ -15,6 +15,7 @@ mod ffi {
|
|||
}
|
||||
}
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::ffi::{CStr, CString};
|
||||
|
||||
const WINDOW_WIDTH: i32 = 800;
|
||||
|
@ -123,61 +124,15 @@ fn create_debug_messenger_create_info() -> ffi::VkDebugUtilsMessengerCreateInfoE
|
|||
}
|
||||
}
|
||||
|
||||
fn is_device_suitable(dev: ffi::VkPhysicalDevice) -> bool {
|
||||
let mut dev_props: ffi::VkPhysicalDeviceProperties = unsafe { std::mem::zeroed() };
|
||||
unsafe {
|
||||
ffi::vkGetPhysicalDeviceProperties(dev, std::ptr::addr_of_mut!(dev_props));
|
||||
}
|
||||
|
||||
let mut dev_feat: ffi::VkPhysicalDeviceFeatures = unsafe { std::mem::zeroed() };
|
||||
unsafe {
|
||||
ffi::vkGetPhysicalDeviceFeatures(dev, std::ptr::addr_of_mut!(dev_feat));
|
||||
}
|
||||
|
||||
// dev_props.deviceType == ffi::VkPhysicalDeviceType_VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
|
||||
// && dev_feat.geometryShader != 0
|
||||
|
||||
// Use previous checks for specifics, but for now, accept GPUs that support "graphics family".
|
||||
find_queue_families(dev).graphics_family.is_some()
|
||||
}
|
||||
|
||||
struct QueueFamilyIndices {
|
||||
graphics_family: Option<u32>,
|
||||
present_family: Option<u32>,
|
||||
}
|
||||
|
||||
fn find_queue_families(dev: ffi::VkPhysicalDevice) -> QueueFamilyIndices {
|
||||
let mut queue_fam = QueueFamilyIndices {
|
||||
graphics_family: None,
|
||||
};
|
||||
|
||||
let mut queue_family_count: u32 = 0;
|
||||
unsafe {
|
||||
ffi::vkGetPhysicalDeviceQueueFamilyProperties(
|
||||
dev,
|
||||
std::ptr::addr_of_mut!(queue_family_count),
|
||||
std::ptr::null_mut(),
|
||||
);
|
||||
impl QueueFamilyIndices {
|
||||
fn is_complete(&self) -> bool {
|
||||
self.graphics_family.is_some() && self.present_family.is_some()
|
||||
}
|
||||
|
||||
let mut queue_family_props: Vec<ffi::VkQueueFamilyProperties> =
|
||||
Vec::with_capacity(queue_family_count as usize);
|
||||
queue_family_props.resize(queue_family_count as usize, unsafe { std::mem::zeroed() });
|
||||
unsafe {
|
||||
ffi::vkGetPhysicalDeviceQueueFamilyProperties(
|
||||
dev,
|
||||
std::ptr::addr_of_mut!(queue_family_count),
|
||||
queue_family_props.as_mut_ptr(),
|
||||
);
|
||||
}
|
||||
|
||||
for (idx, queue_family_prop) in queue_family_props.iter().enumerate() {
|
||||
if queue_family_prop.queueFlags & ffi::VkQueueFlagBits_VK_QUEUE_GRAPHICS_BIT != 0 {
|
||||
queue_fam.graphics_family = Some(idx as u32);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
queue_fam
|
||||
}
|
||||
|
||||
struct VulkanApp {
|
||||
|
@ -188,6 +143,7 @@ struct VulkanApp {
|
|||
physical_device: ffi::VkPhysicalDevice,
|
||||
device: ffi::VkDevice,
|
||||
graphics_queue: ffi::VkQueue,
|
||||
present_queue: ffi::VkQueue,
|
||||
}
|
||||
|
||||
impl VulkanApp {
|
||||
|
@ -200,6 +156,7 @@ impl VulkanApp {
|
|||
physical_device: std::ptr::null_mut(),
|
||||
device: std::ptr::null_mut(),
|
||||
graphics_queue: std::ptr::null_mut(),
|
||||
present_queue: std::ptr::null_mut(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,7 +317,7 @@ impl VulkanApp {
|
|||
}
|
||||
|
||||
for phys_dev in phys_dev_handles_vec {
|
||||
if is_device_suitable(phys_dev) {
|
||||
if self.is_device_suitable(phys_dev) {
|
||||
self.physical_device = phys_dev;
|
||||
break;
|
||||
}
|
||||
|
@ -376,25 +333,32 @@ impl VulkanApp {
|
|||
panic!("\"physical_device\" must be set before calling \"create_logical_device\"!");
|
||||
}
|
||||
|
||||
let indices = find_queue_families(self.physical_device);
|
||||
let indices = self.find_queue_families(self.physical_device);
|
||||
|
||||
let mut dev_queue_create_info: ffi::VkDeviceQueueCreateInfo = unsafe { std::mem::zeroed() };
|
||||
dev_queue_create_info.sType =
|
||||
ffi::VkStructureType_VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||
dev_queue_create_info.queueFamilyIndex = indices
|
||||
.graphics_family
|
||||
.expect("\"physical_device\" must support graphics!");
|
||||
dev_queue_create_info.queueCount = 1;
|
||||
let mut dev_queue_create_infos: Vec<ffi::VkDeviceQueueCreateInfo> = Vec::new();
|
||||
let mut unique_queue_families: HashSet<u32> = HashSet::new();
|
||||
unique_queue_families.insert(indices.graphics_family.unwrap());
|
||||
unique_queue_families.insert(indices.present_family.unwrap());
|
||||
|
||||
let queue_priority: f32 = 1.0;
|
||||
dev_queue_create_info.pQueuePriorities = std::ptr::addr_of!(queue_priority);
|
||||
|
||||
for queue_family in unique_queue_families {
|
||||
let mut dev_queue_create_info: ffi::VkDeviceQueueCreateInfo =
|
||||
unsafe { std::mem::zeroed() };
|
||||
dev_queue_create_info.sType =
|
||||
ffi::VkStructureType_VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||
dev_queue_create_info.queueFamilyIndex = queue_family;
|
||||
dev_queue_create_info.queueCount = 1;
|
||||
dev_queue_create_info.pQueuePriorities = std::ptr::addr_of!(queue_priority);
|
||||
dev_queue_create_infos.push(dev_queue_create_info);
|
||||
}
|
||||
|
||||
let mut phys_dev_feat: ffi::VkPhysicalDeviceFeatures = unsafe { std::mem::zeroed() };
|
||||
|
||||
let mut dev_create_info: ffi::VkDeviceCreateInfo = unsafe { std::mem::zeroed() };
|
||||
dev_create_info.sType = ffi::VkStructureType_VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||
dev_create_info.pQueueCreateInfos = std::ptr::addr_of!(dev_queue_create_info);
|
||||
dev_create_info.queueCreateInfoCount = 1;
|
||||
dev_create_info.pQueueCreateInfos = dev_queue_create_infos.as_ptr();
|
||||
dev_create_info.queueCreateInfoCount = dev_queue_create_infos.len() as u32;
|
||||
dev_create_info.pEnabledFeatures = std::ptr::addr_of!(phys_dev_feat);
|
||||
|
||||
dev_create_info.enabledExtensionCount = 0;
|
||||
|
@ -424,6 +388,12 @@ impl VulkanApp {
|
|||
0,
|
||||
std::ptr::addr_of_mut!(self.graphics_queue),
|
||||
);
|
||||
ffi::vkGetDeviceQueue(
|
||||
self.device,
|
||||
indices.present_family.unwrap(),
|
||||
0,
|
||||
std::ptr::addr_of_mut!(self.present_queue),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -459,6 +429,75 @@ impl VulkanApp {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_queue_families(&self, dev: ffi::VkPhysicalDevice) -> QueueFamilyIndices {
|
||||
let mut queue_fam = QueueFamilyIndices {
|
||||
graphics_family: None,
|
||||
present_family: None,
|
||||
};
|
||||
|
||||
let mut queue_family_count: u32 = 0;
|
||||
unsafe {
|
||||
ffi::vkGetPhysicalDeviceQueueFamilyProperties(
|
||||
dev,
|
||||
std::ptr::addr_of_mut!(queue_family_count),
|
||||
std::ptr::null_mut(),
|
||||
);
|
||||
}
|
||||
|
||||
let mut queue_family_props: Vec<ffi::VkQueueFamilyProperties> =
|
||||
Vec::with_capacity(queue_family_count as usize);
|
||||
queue_family_props.resize(queue_family_count as usize, unsafe { std::mem::zeroed() });
|
||||
unsafe {
|
||||
ffi::vkGetPhysicalDeviceQueueFamilyProperties(
|
||||
dev,
|
||||
std::ptr::addr_of_mut!(queue_family_count),
|
||||
queue_family_props.as_mut_ptr(),
|
||||
);
|
||||
}
|
||||
|
||||
for (idx, queue_family_prop) in queue_family_props.iter().enumerate() {
|
||||
let mut present_support: ffi::VkBool32 = ffi::VK_FALSE;
|
||||
unsafe {
|
||||
ffi::vkGetPhysicalDeviceSurfaceSupportKHR(
|
||||
dev,
|
||||
idx as u32,
|
||||
self.surface,
|
||||
std::ptr::addr_of_mut!(present_support),
|
||||
);
|
||||
}
|
||||
if present_support != ffi::VK_FALSE {
|
||||
queue_fam.present_family = Some(idx as u32);
|
||||
}
|
||||
if queue_family_prop.queueFlags & ffi::VkQueueFlagBits_VK_QUEUE_GRAPHICS_BIT != 0 {
|
||||
queue_fam.graphics_family = Some(idx as u32);
|
||||
}
|
||||
|
||||
if queue_fam.is_complete() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
queue_fam
|
||||
}
|
||||
|
||||
fn is_device_suitable(&self, dev: ffi::VkPhysicalDevice) -> bool {
|
||||
let mut dev_props: ffi::VkPhysicalDeviceProperties = unsafe { std::mem::zeroed() };
|
||||
unsafe {
|
||||
ffi::vkGetPhysicalDeviceProperties(dev, std::ptr::addr_of_mut!(dev_props));
|
||||
}
|
||||
|
||||
let mut dev_feat: ffi::VkPhysicalDeviceFeatures = unsafe { std::mem::zeroed() };
|
||||
unsafe {
|
||||
ffi::vkGetPhysicalDeviceFeatures(dev, std::ptr::addr_of_mut!(dev_feat));
|
||||
}
|
||||
|
||||
// dev_props.deviceType == ffi::VkPhysicalDeviceType_VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
|
||||
// && dev_feat.geometryShader != 0
|
||||
|
||||
// Use previous checks for specifics, but for now, accept GPUs with required support.
|
||||
self.find_queue_families(dev).is_complete()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for VulkanApp {
|
||||
|
|
Loading…
Reference in a new issue