newtype queue family index

This commit is contained in:
janis 2026-10-24 21:37:07 +02:00
parent 885f3ca492
commit f9c18bcd3c
Signed by: janis
SSH key fingerprint: SHA256:bB1qbbqmDXZNT0KKD5c2Dfjg53JGhj7B3CFcLIzSqq8
10 changed files with 89 additions and 37 deletions

View file

@ -12,7 +12,7 @@ members = [
"crates/window", "crates/window",
"crates/game", "crates/game",
"crates/text", "crates/text",
"crates/bevy_vulkan_render", "crates/renderer_device", "crates/renderer_resources", "crates/bevy_vulkan_render", "crates/renderer_device", "crates/renderer_resources", "crates/renderer_rendergraph",
] ]
[dependencies] [dependencies]

View file

@ -32,7 +32,7 @@ impl Drop for SingleUseCommandPool {
impl SingleUseCommandPool { impl SingleUseCommandPool {
pub fn new(device: Device, queue: Queue) -> VkResult<Arc<Self>> { pub fn new(device: Device, queue: Queue) -> VkResult<Arc<Self>> {
let pool_info = vk::CommandPoolCreateInfo::default() let pool_info = vk::CommandPoolCreateInfo::default()
.queue_family_index(queue.family_index()) .queue_family_index(queue.family_index().index())
.flags(vk::CommandPoolCreateFlags::TRANSIENT); .flags(vk::CommandPoolCreateFlags::TRANSIENT);
let pool = unsafe { device.dev().create_command_pool(&pool_info, None)? }; let pool = unsafe { device.dev().create_command_pool(&pool_info, None)? };
@ -193,9 +193,11 @@ impl DeviceOwned<vk::CommandBuffer> for SingleUseCommand {
impl Drop for SingleUseCommand { impl Drop for SingleUseCommand {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
self.pool self.pool.pool.with_locked(|&pool| {
.pool self.device()
.with_locked(|&pool| self.device().dev().free_command_buffers(pool, &[self.handle()])) .dev()
.free_command_buffers(pool, &[self.handle()])
})
} }
} }
} }
@ -660,6 +662,7 @@ mod command_pools {
use arrayvec::ArrayVec; use arrayvec::ArrayVec;
use ash::{prelude::VkResult, vk}; use ash::{prelude::VkResult, vk};
use parking_lot::Mutex; use parking_lot::Mutex;
use renderer_device::queue::QueueFamilyIndex;
use smol::future::FutureExt; use smol::future::FutureExt;
use thread_local::ThreadLocal; use thread_local::ThreadLocal;
@ -682,7 +685,7 @@ mod command_pools {
pub struct CommandPool { pub struct CommandPool {
inner: DeviceObject<vk::CommandPool>, inner: DeviceObject<vk::CommandPool>,
family: u32, family: QueueFamilyIndex,
free_list: Mutex<Cell<(Vec<vk::CommandBufferLevel>, Vec<vk::CommandBuffer>)>>, free_list: Mutex<Cell<(Vec<vk::CommandBufferLevel>, Vec<vk::CommandBuffer>)>>,
} }
@ -701,12 +704,12 @@ mod command_pools {
impl CommandPool { impl CommandPool {
pub fn new( pub fn new(
dev: Device, dev: Device,
family: u32, family: QueueFamilyIndex,
flags: vk::CommandPoolCreateFlags, flags: vk::CommandPoolCreateFlags,
name: Option<Cow<'static, str>>, name: Option<Cow<'static, str>>,
) -> Result<CommandPool, vk::Result> { ) -> Result<CommandPool, vk::Result> {
let pool_info = vk::CommandPoolCreateInfo::default() let pool_info = vk::CommandPoolCreateInfo::default()
.queue_family_index(family) .queue_family_index(family.index())
.flags(flags); .flags(flags);
let pool = unsafe { dev.dev().create_command_pool(&pool_info, None)? }; let pool = unsafe { dev.dev().create_command_pool(&pool_info, None)? };
@ -824,7 +827,7 @@ mod command_pools {
} }
} }
fn find_or_default(&mut self, dev: &Device, family: u32) -> Arc<CommandPool> { fn find_or_default(&mut self, dev: &Device, family: QueueFamilyIndex) -> Arc<CommandPool> {
match self match self
.per_family_pools .per_family_pools
.binary_search_by_key(&family, |entry| entry.0) .binary_search_by_key(&family, |entry| entry.0)
@ -858,7 +861,7 @@ mod command_pools {
#[derive(Debug)] #[derive(Debug)]
struct CommandPoolsShard { struct CommandPoolsShard {
per_family_pools: ArrayVec<(u32, Arc<CommandPool>), 8>, per_family_pools: ArrayVec<(QueueFamilyIndex, Arc<CommandPool>), 8>,
} }
pub struct CommandPools { pub struct CommandPools {
@ -867,7 +870,7 @@ mod command_pools {
} }
impl CommandPools { impl CommandPools {
pub fn get_for_family(&self, family: u32) -> Arc<CommandPool> { pub fn get_for_family(&self, family: QueueFamilyIndex) -> Arc<CommandPool> {
let shard = self let shard = self
.shards .shards
.get_or(|| core::cell::Cell::new(CommandPoolsShard::new()).into()); .get_or(|| core::cell::Cell::new(CommandPoolsShard::new()).into());
@ -881,7 +884,7 @@ mod command_pools {
pub fn allocate_buffer( pub fn allocate_buffer(
&self, &self,
family: u32, family: QueueFamilyIndex,
name: Option<Cow<'static, str>>, name: Option<Cow<'static, str>>,
level: vk::CommandBufferLevel, level: vk::CommandBufferLevel,
flags: vk::CommandBufferUsageFlags, flags: vk::CommandBufferUsageFlags,

View file

@ -80,11 +80,7 @@ impl<'r> GraphBuilder<'r> {
mod api_demo { mod api_demo {
use crate::{ use crate::{EguiState, pipeline::Pipeline, render_graph::commands};
EguiState,
pipeline::Pipeline,
render_graph::{commands, resources::TextureRegion},
};
use super::*; use super::*;
use ash::vk::{self, BufferUsageFlags}; use ash::vk::{self, BufferUsageFlags};

View file

@ -2,7 +2,7 @@ use std::ops::Deref;
use ash::vk; use ash::vk;
use crate::{images::MipRange, render_graph::recorder::SideEffectMap2}; use crate::images::MipRange;
pub trait Resource: Sized { pub trait Resource: Sized {
fn id(&self) -> ResourceId; fn id(&self) -> ResourceId;

View file

@ -15,6 +15,7 @@ use ash::{
}; };
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use raw_window_handle::{RawDisplayHandle, RawWindowHandle}; use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
use renderer_device::queue::QueueFamilyIndices;
use crate::{ use crate::{
Instance, PhysicalDeviceInfo, Result, SurfaceCapabilities, Instance, PhysicalDeviceInfo, Result, SurfaceCapabilities,
@ -433,7 +434,7 @@ impl Swapchain {
} else { } else {
vk::SharingMode::CONCURRENT vk::SharingMode::CONCURRENT
}) })
.queue_family_indices(queue_families) .queue_family_indices(queue_families.as_u32_slice())
.pre_transform(vk::SurfaceTransformFlagsKHR::IDENTITY) .pre_transform(vk::SurfaceTransformFlagsKHR::IDENTITY)
.composite_alpha(config.composite_alpha_mode) .composite_alpha(config.composite_alpha_mode)
.old_swapchain(old_swapchain) .old_swapchain(old_swapchain)

View file

@ -1,4 +1,5 @@
use bitflags::bitflags; use bitflags::bitflags;
use core::fmt;
use parking_lot::Mutex; use parking_lot::Mutex;
use raw_window_handle::RawDisplayHandle; use raw_window_handle::RawDisplayHandle;
use std::{collections::HashMap, ops::Deref, sync::Arc}; use std::{collections::HashMap, ops::Deref, sync::Arc};
@ -36,7 +37,7 @@ impl Queue {
F: FnOnce(&Queue) -> R, F: FnOnce(&Queue) -> R,
{ {
let _lock = self.inner.lock.lock(); let _lock = self.inner.lock.lock();
f(&self) f(self)
} }
} }
@ -51,20 +52,58 @@ impl QueueInner {
pub fn raw(&self) -> vk::Queue { pub fn raw(&self) -> vk::Queue {
self.raw self.raw
} }
pub fn family_index(&self) -> u32 { pub fn family_index(&self) -> QueueFamilyIndex {
self.family.index self.family.index
} }
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct QueueFamily { pub struct QueueFamily {
pub index: u32, pub index: QueueFamilyIndex,
pub count: u32, pub count: u32,
pub flags: QueueFlags, pub flags: QueueFlags,
pub granularity: TransferGranuality, pub granularity: TransferGranuality,
pub timestamp_valid_bits: u32, pub timestamp_valid_bits: u32,
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(transparent)]
pub struct QueueFamilyIndex(u32);
pub trait QueueFamilyIndices {
fn as_u32_slice(&self) -> &[u32];
}
impl QueueFamilyIndices for [QueueFamilyIndex] {
fn as_u32_slice(&self) -> &[u32] {
// SAFETY: QueueFamilyIndex is repr(transparent) over u32
unsafe { std::slice::from_raw_parts(self.as_ptr() as *const u32, self.len()) }
}
}
impl Default for QueueFamilyIndex {
fn default() -> Self {
Self::INVALID
}
}
impl fmt::Display for QueueFamilyIndex {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "q{}", self.0)
}
}
impl QueueFamilyIndex {
const INVALID: QueueFamilyIndex = QueueFamilyIndex(u32::MAX);
pub fn new(index: u32) -> Self {
Self(index)
}
pub fn index(&self) -> u32 {
self.0
}
}
bitflags! { bitflags! {
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct QueueFlags: u16 { pub struct QueueFlags: u16 {
@ -143,8 +182,11 @@ impl DeviceQueues {
&self.transfer &self.transfer
} }
pub fn family_indices(&self, flags: crate::device::QueueFlags) -> ArrayVec<[u32; 4]> { pub fn family_indices(
let mut indices = array_vec!([u32; 4]); &self,
flags: crate::device::QueueFlags,
) -> ArrayVec<[QueueFamilyIndex; 4]> {
let mut indices = array_vec!([QueueFamilyIndex; 4]);
use crate::device::QueueFlags as QF; use crate::device::QueueFlags as QF;
if flags.intersects(QF::GRAPHICS | QF::PRESENT) { if flags.intersects(QF::GRAPHICS | QF::PRESENT) {
indices.push(self.graphics.family.index); indices.push(self.graphics.family.index);
@ -160,7 +202,7 @@ impl DeviceQueues {
indices indices
} }
pub fn swapchain_family_indices(&self) -> &[u32] { pub fn swapchain_family_indices(&self) -> &[QueueFamilyIndex] {
core::slice::from_ref(&self.graphics.family.index) core::slice::from_ref(&self.graphics.family.index)
} }
@ -203,13 +245,13 @@ impl DeviceQueueInfos {
.into_iter() .into_iter()
.map(|(index, count)| { .map(|(index, count)| {
vk::DeviceQueueCreateInfo::default() vk::DeviceQueueCreateInfo::default()
.queue_family_index(index) .queue_family_index(index.index())
.queue_priorities(&Self::PRIORITIES[..count as usize]) .queue_priorities(&Self::PRIORITIES[..count as usize])
}) })
.collect() .collect()
} }
fn queue_family_indices(&self) -> HashMap<u32, u32> { fn queue_family_indices(&self) -> HashMap<QueueFamilyIndex, u32> {
let mut families = HashMap::new(); let mut families = HashMap::new();
families.insert(self.graphics.index, 1); families.insert(self.graphics.index, 1);
@ -231,12 +273,12 @@ impl DeviceQueueInfos {
.map(|(queue_family_index, count)| { .map(|(queue_family_index, count)| {
let queues = (0..count) let queues = (0..count)
.map(|queue_index| unsafe { .map(|queue_index| unsafe {
dev.get_device_queue(queue_family_index, queue_index) dev.get_device_queue(queue_family_index.index(), queue_index)
}) })
.collect(); .collect();
(queue_family_index, queues) (queue_family_index, queues)
}) })
.collect::<HashMap<u32, Vec<vk::Queue>>>(); .collect::<HashMap<QueueFamilyIndex, Vec<vk::Queue>>>();
let graphics = Queue::from_vk_queue( let graphics = Queue::from_vk_queue(
queues.get_mut(&self.graphics.index).unwrap().pop().unwrap(), queues.get_mut(&self.graphics.index).unwrap().pop().unwrap(),
@ -285,15 +327,14 @@ impl DeviceQueueInfos {
.enumerate() .enumerate()
.map(|(index, props)| { .map(|(index, props)| {
let mut flags = QueueFlags::from_vk_flags(props.queue_flags); let mut flags = QueueFlags::from_vk_flags(props.queue_flags);
if let Some(display_handle) = display_handle { if let Some(display_handle) = display_handle
if instance.query_presentation_support(pdev.pdev, index as u32, display_handle) && instance.query_presentation_support(pdev.pdev, index as u32, display_handle)
{ {
flags |= QueueFlags::PRESENT; flags |= QueueFlags::PRESENT;
}
} }
QueueFamily { QueueFamily {
index: index as u32, index: QueueFamilyIndex(index as u32),
count: props.queue_count, count: props.queue_count,
flags, flags,
granularity: TransferGranuality::from_vk_granularity( granularity: TransferGranuality::from_vk_granularity(

View file

@ -0,0 +1,6 @@
[package]
name = "renderer_rendergraph"
version = "0.1.0"
edition = "2024"
[dependencies]

View file

@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

View file

@ -2,6 +2,7 @@ use std::borrow::Cow;
use ash::vk; use ash::vk;
use gpu_allocator::vulkan::AllocationScheme; use gpu_allocator::vulkan::AllocationScheme;
use renderer_device::queue::QueueFamilyIndices;
use crate::{ use crate::{
Device, Device,
@ -132,7 +133,7 @@ impl Buffer {
let create_info = vk::BufferCreateInfo::default() let create_info = vk::BufferCreateInfo::default()
.size(desc.size) .size(desc.size)
.usage(desc.usage) .usage(desc.usage)
.queue_family_indices(&queue_families) .queue_family_indices(queue_families.as_u32_slice())
.sharing_mode(sharing_mode); .sharing_mode(sharing_mode);
let buffer = unsafe { device.dev().create_buffer(&create_info, None)? }; let buffer = unsafe { device.dev().create_buffer(&create_info, None)? };

View file

@ -15,6 +15,7 @@ use ash::vk::{self, Handle};
use ash_formats::FormatExt; use ash_formats::FormatExt;
use gpu_allocator::vulkan::{AllocationCreateDesc, AllocationScheme}; use gpu_allocator::vulkan::{AllocationCreateDesc, AllocationScheme};
use parking_lot::Mutex; use parking_lot::Mutex;
use renderer_device::queue::QueueFamilyIndices;
#[derive(Clone)] #[derive(Clone)]
pub struct ImageDesc { pub struct ImageDesc {
@ -316,7 +317,7 @@ impl Image {
.tiling(*tiling) .tiling(*tiling)
.usage(*usage) .usage(*usage)
.sharing_mode(sharing_mode) .sharing_mode(sharing_mode)
.queue_family_indices(&queue_families) .queue_family_indices(queue_families.as_u32_slice())
.array_layers(*array_layers) .array_layers(*array_layers)
.mip_levels(*mip_levels); .mip_levels(*mip_levels);