vulkan_lib/vulkan-rs/src/queue.rs

254 lines
6.9 KiB
Rust
Raw Normal View History

2023-01-14 12:03:01 +00:00
use crate::prelude::*;
use anyhow::Result;
use std::{
slice,
sync::{Arc, Mutex},
time::Duration,
};
pub struct QueueRequestInfo {
pub queue_create_info: VkDeviceQueueCreateInfo,
pub queue_family_index: u32,
pub queue_index: u32,
}
#[derive(Debug)]
pub struct Queue {
device: Arc<Device>,
queue: VkQueue,
family_index: u32,
queue_index: u32,
}
impl Queue {
pub fn create_presentable_request_info(
physical_device: &Arc<PhysicalDevice>,
surface: &Arc<Surface>,
queue_type: impl Into<VkQueueFlagBits>,
) -> Result<QueueRequestInfo> {
let index =
Self::find_presentable_queue_index(physical_device, surface, queue_type.into())?;
let priorities = &[0.0f32];
Ok(QueueRequestInfo {
queue_create_info: VkDeviceQueueCreateInfo::new(0, index, priorities),
queue_family_index: index,
queue_index: 0,
})
}
pub fn create_non_presentable_request_info(
physical_device: &Arc<PhysicalDevice>,
queue_type: impl Into<VkQueueFlagBits>,
) -> Result<QueueRequestInfo> {
let index = Self::find_non_presentable_queue_index(physical_device, queue_type.into())?;
let priorities = &[0.0f32];
Ok(QueueRequestInfo {
queue_create_info: VkDeviceQueueCreateInfo::new(0, index, priorities),
queue_family_index: index,
queue_index: 0,
})
}
pub fn new(
device: Arc<Device>,
queue: VkQueue,
family_index: u32,
queue_index: u32,
) -> Arc<Mutex<Queue>> {
Arc::new(Mutex::new(Queue {
device,
queue,
family_index,
queue_index,
}))
}
pub fn family_index(&self) -> u32 {
self.family_index
}
pub fn queue_index(&self) -> u32 {
self.queue_index
}
/// really expensiv call, since its locks the queue until it is idle
pub fn submit(&self, fence: Option<&Arc<Fence>>, submits: &[SubmitInfo]) -> Result<()> {
let submit_infos: Vec<VkSubmitInfo> = submits.iter().map(|s| s.as_vk_submit()).collect();
let fence = match fence {
Some(fence) => fence.vk_handle(),
None => VkFence::NULL_HANDLE,
};
self.device
.queue_submit(self.queue, submit_infos.as_slice(), fence)
}
pub fn minimal_submit(
&self,
time_out: Duration,
command_buffers: &[Arc<CommandBuffer>],
) -> Result<()> {
let mut submit = SubmitInfo::default();
for command_buffer in command_buffers.iter() {
submit = submit.add_command_buffer(command_buffer);
}
let fence = Fence::builder().build(self.device.clone())?;
self.submit(Some(&fence), slice::from_ref(&submit))?;
// make sure command_buffer is ready
self.device.wait_for_fences(&[&fence], true, time_out)?;
Ok(())
}
pub fn present(
&self,
swapchains: &[&Arc<Swapchain>],
image_indices: &[u32],
wait_semaphores: &[&Arc<Semaphore>],
) -> Result<OutOfDate<()>> {
let wait_semaphores: Vec<VkSemaphore> =
wait_semaphores.iter().map(|sem| sem.vk_handle()).collect();
let swapchains: Vec<VkSwapchainKHR> = swapchains
.iter()
.map(|swapchain| swapchain.vk_handle())
.collect();
let present_info = VkPresentInfoKHR::new(
wait_semaphores.as_slice(),
swapchains.as_slice(),
image_indices,
&mut [],
);
self.device.queue_present(self.queue, &present_info)
}
pub fn wait_idle(&self) -> Result<()> {
self.device.queue_wait_idle(self.queue)
}
}
impl VulkanDevice for Queue {
fn device(&self) -> &Arc<Device> {
&self.device
}
}
impl_vk_handle!(Queue, VkQueue, queue);
impl Queue {
fn find_presentable_queue_index(
physical_device: &Arc<PhysicalDevice>,
surface: &Arc<Surface>,
flags: VkQueueFlagBits,
) -> Result<u32> {
let surface = surface.vk_handle();
let vk_physical_device = physical_device.vk_handle();
let queue_family_properties = physical_device
.instance()
.physical_device_queue_family_properties(vk_physical_device);
for (i, queue) in queue_family_properties.iter().enumerate() {
if (queue.queueFlagBits & flags) == flags {
let presentable = physical_device.instance().physical_device_surface_support(
vk_physical_device,
i as u32,
surface,
)?;
if presentable {
return Ok(i as u32);
}
}
}
Err(anyhow::Error::msg("Requested queue could not be found"))
}
fn find_non_presentable_queue_index(
physical_device: &Arc<PhysicalDevice>,
flags: VkQueueFlagBits,
) -> Result<u32> {
let vk_physical_device = physical_device.vk_handle();
let queue_family_properties = physical_device
.instance()
.physical_device_queue_family_properties(vk_physical_device);
for (i, queue) in queue_family_properties.iter().enumerate() {
if (queue.queueFlagBits & flags) == flags {
return Ok(i as u32);
}
}
Err(anyhow::Error::msg("Requested queue could not be found"))
}
}
#[derive(Default)]
pub struct SubmitInfo {
wait_semaphores: Vec<VkSemaphore>,
wait_stages: Vec<VkPipelineStageFlagBits>,
command_buffers: Vec<VkCommandBuffer>,
signal_semaphores: Vec<VkSemaphore>,
}
impl SubmitInfo {
2023-12-04 11:41:10 +00:00
pub fn add_wait_semaphore(
self,
wait_semaphore: impl VkHandle<VkSemaphore>,
wait_stage: impl Into<VkPipelineStageFlagBits>,
) -> Self {
self.add_wait_semaphore_vk(wait_semaphore.vk_handle(), wait_stage)
}
pub fn add_wait_semaphore_vk(
mut self,
wait_semaphore: VkSemaphore,
wait_stage: impl Into<VkPipelineStageFlagBits>,
) -> Self {
2023-12-04 10:09:57 +00:00
self.wait_semaphores.push(wait_semaphore);
2023-01-14 12:03:01 +00:00
self.wait_stages.push(wait_stage.into());
self
}
pub fn add_command_buffer(mut self, command_buffer: impl VkHandle<VkCommandBuffer>) -> Self {
self.command_buffers.push(command_buffer.vk_handle());
self
}
2023-12-04 11:41:10 +00:00
pub fn add_signal_semaphore(self, signal_semaphore: impl VkHandle<VkSemaphore>) -> Self {
self.add_signal_semaphore_vk(signal_semaphore.vk_handle())
2023-01-14 12:03:01 +00:00
}
2023-12-04 10:09:57 +00:00
pub fn add_signal_semaphore_vk(mut self, signal_semaphore: VkSemaphore) -> Self {
self.signal_semaphores.push(signal_semaphore);
self
}
2023-01-14 12:03:01 +00:00
pub fn as_vk_submit(&self) -> VkSubmitInfo {
VkSubmitInfo::new(
self.wait_semaphores.as_slice(),
self.wait_stages.as_slice(),
self.command_buffers.as_slice(),
self.signal_semaphores.as_slice(),
)
}
}