engine_vulkan: Refactor queue finding
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 8m39s
Some checks failed
Build legacy Nix package on Ubuntu / build (push) Failing after 8m39s
This commit is contained in:
parent
9ea8721346
commit
4676b1b5b8
5 changed files with 202 additions and 160 deletions
174
crates/engine_vulkan/src/queues.rs
Normal file
174
crates/engine_vulkan/src/queues.rs
Normal file
|
@ -0,0 +1,174 @@
|
|||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use engine_window::raw_handle::DisplayHandleWrapper;
|
||||
use vulkano::device::{
|
||||
QueueCreateInfo, QueueFamilyProperties, QueueFlags, physical::PhysicalDevice,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum VulkanQueueFamilyStatus {
|
||||
Unused,
|
||||
NotSupported,
|
||||
Supported(u32),
|
||||
}
|
||||
|
||||
impl VulkanQueueFamilyStatus {
|
||||
pub fn can_be_set(&self) -> bool {
|
||||
match self {
|
||||
VulkanQueueFamilyStatus::NotSupported => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a boolean to a VulkanQueueFamilyStatus as default value
|
||||
impl From<bool> for VulkanQueueFamilyStatus {
|
||||
fn from(value: bool) -> Self {
|
||||
if value {
|
||||
VulkanQueueFamilyStatus::NotSupported
|
||||
} else {
|
||||
VulkanQueueFamilyStatus::Unused
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a DisplayHandleWrapper Option to a VulkanQueueFamilyStatus as default value
|
||||
impl From<Option<&DisplayHandleWrapper>> for VulkanQueueFamilyStatus {
|
||||
fn from(value: Option<&DisplayHandleWrapper>) -> Self {
|
||||
if value.is_some() {
|
||||
VulkanQueueFamilyStatus::NotSupported
|
||||
} else {
|
||||
VulkanQueueFamilyStatus::Unused
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VulkanQueueFamilyIndices {
|
||||
pub present_queue_family_index: VulkanQueueFamilyStatus,
|
||||
pub graphics_queue_family_index: VulkanQueueFamilyStatus,
|
||||
pub compute_queue_family_index: VulkanQueueFamilyStatus,
|
||||
pub transfer_queue_family_index: VulkanQueueFamilyStatus,
|
||||
}
|
||||
|
||||
impl From<VulkanQueueFamilyIndices> for Vec<VulkanQueueFamilyStatus> {
|
||||
fn from(indices: VulkanQueueFamilyIndices) -> Self {
|
||||
vec![
|
||||
indices.present_queue_family_index,
|
||||
indices.graphics_queue_family_index,
|
||||
indices.compute_queue_family_index,
|
||||
indices.transfer_queue_family_index,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VulkanQueueFamilyIndices> for Vec<QueueCreateInfo> {
|
||||
fn from(indices: VulkanQueueFamilyIndices) -> Self {
|
||||
let mut queue_create_infos = HashMap::<u32, QueueCreateInfo>::new();
|
||||
|
||||
let statuses: Vec<VulkanQueueFamilyStatus> = indices.into();
|
||||
|
||||
for status in statuses.iter() {
|
||||
match status {
|
||||
VulkanQueueFamilyStatus::Supported(index) => {
|
||||
let entry = queue_create_infos.entry(*index).or_insert(QueueCreateInfo {
|
||||
queue_family_index: *index,
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
entry.queues.push(1.0);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
queue_create_infos
|
||||
.into_iter()
|
||||
.map(|(_, value)| value)
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a VulkanQueuesQuery to a VulkanQueuesFamilyIndices as default value
|
||||
impl<'a> From<&'a VulkanQueuesQuery<'a>> for VulkanQueueFamilyIndices {
|
||||
fn from(query: &'a VulkanQueuesQuery<'a>) -> Self {
|
||||
VulkanQueueFamilyIndices {
|
||||
present_queue_family_index: query.with_surface.into(),
|
||||
graphics_queue_family_index: query.with_graphics_queue.into(),
|
||||
compute_queue_family_index: query.with_compute_queue.into(),
|
||||
transfer_queue_family_index: query.with_transfer_queue.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VulkanQueuesQuery<'a> {
|
||||
pub with_surface: Option<&'a DisplayHandleWrapper>,
|
||||
pub with_graphics_queue: bool,
|
||||
pub with_compute_queue: bool,
|
||||
pub with_transfer_queue: bool,
|
||||
}
|
||||
|
||||
pub fn find_queues_family_indices(
|
||||
physical_device: &Arc<PhysicalDevice>,
|
||||
query: &VulkanQueuesQuery,
|
||||
) -> VulkanQueueFamilyIndices {
|
||||
let mut indices: VulkanQueueFamilyIndices = query.into();
|
||||
|
||||
for (i, queue_family_properties) in physical_device.queue_family_properties().iter().enumerate()
|
||||
{
|
||||
if indices.present_queue_family_index.can_be_set()
|
||||
&& check_presentation_support(
|
||||
physical_device,
|
||||
i as u32,
|
||||
&query.with_surface.as_ref().unwrap(),
|
||||
)
|
||||
{
|
||||
indices.present_queue_family_index = VulkanQueueFamilyStatus::Supported(i as u32);
|
||||
}
|
||||
|
||||
if indices.graphics_queue_family_index.can_be_set()
|
||||
&& check_queue_support(queue_family_properties, QueueFlags::GRAPHICS)
|
||||
{
|
||||
indices.graphics_queue_family_index = VulkanQueueFamilyStatus::Supported(i as u32);
|
||||
}
|
||||
|
||||
if indices.compute_queue_family_index.can_be_set()
|
||||
&& check_queue_support(queue_family_properties, QueueFlags::COMPUTE)
|
||||
{
|
||||
indices.compute_queue_family_index = VulkanQueueFamilyStatus::Supported(i as u32);
|
||||
}
|
||||
|
||||
if indices.transfer_queue_family_index.can_be_set()
|
||||
&& check_queue_support(queue_family_properties, QueueFlags::TRANSFER)
|
||||
{
|
||||
indices.transfer_queue_family_index = VulkanQueueFamilyStatus::Supported(i as u32);
|
||||
}
|
||||
|
||||
if !indices.present_queue_family_index.can_be_set()
|
||||
&& !indices.graphics_queue_family_index.can_be_set()
|
||||
&& !indices.compute_queue_family_index.can_be_set()
|
||||
&& !indices.transfer_queue_family_index.can_be_set()
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return indices;
|
||||
}
|
||||
|
||||
fn check_presentation_support(
|
||||
physical_device: &Arc<PhysicalDevice>,
|
||||
queue_family_index: u32,
|
||||
surface: &DisplayHandleWrapper,
|
||||
) -> bool {
|
||||
physical_device
|
||||
.presentation_support(queue_family_index, &surface.0)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn check_queue_support(
|
||||
queue_family_property: &QueueFamilyProperties,
|
||||
queue_flags: QueueFlags,
|
||||
) -> bool {
|
||||
queue_family_property.queue_flags.intersects(queue_flags)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue