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/game",
"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]

View file

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

View file

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

View file

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

View file

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

View file

@ -1,4 +1,5 @@
use bitflags::bitflags;
use core::fmt;
use parking_lot::Mutex;
use raw_window_handle::RawDisplayHandle;
use std::{collections::HashMap, ops::Deref, sync::Arc};
@ -36,7 +37,7 @@ impl Queue {
F: FnOnce(&Queue) -> R,
{
let _lock = self.inner.lock.lock();
f(&self)
f(self)
}
}
@ -51,20 +52,58 @@ impl QueueInner {
pub fn raw(&self) -> vk::Queue {
self.raw
}
pub fn family_index(&self) -> u32 {
pub fn family_index(&self) -> QueueFamilyIndex {
self.family.index
}
}
#[derive(Debug, Clone, Copy)]
pub struct QueueFamily {
pub index: u32,
pub index: QueueFamilyIndex,
pub count: u32,
pub flags: QueueFlags,
pub granularity: TransferGranuality,
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! {
#[derive(Debug, Clone, Copy)]
pub struct QueueFlags: u16 {
@ -143,8 +182,11 @@ impl DeviceQueues {
&self.transfer
}
pub fn family_indices(&self, flags: crate::device::QueueFlags) -> ArrayVec<[u32; 4]> {
let mut indices = array_vec!([u32; 4]);
pub fn family_indices(
&self,
flags: crate::device::QueueFlags,
) -> ArrayVec<[QueueFamilyIndex; 4]> {
let mut indices = array_vec!([QueueFamilyIndex; 4]);
use crate::device::QueueFlags as QF;
if flags.intersects(QF::GRAPHICS | QF::PRESENT) {
indices.push(self.graphics.family.index);
@ -160,7 +202,7 @@ impl DeviceQueues {
indices
}
pub fn swapchain_family_indices(&self) -> &[u32] {
pub fn swapchain_family_indices(&self) -> &[QueueFamilyIndex] {
core::slice::from_ref(&self.graphics.family.index)
}
@ -203,13 +245,13 @@ impl DeviceQueueInfos {
.into_iter()
.map(|(index, count)| {
vk::DeviceQueueCreateInfo::default()
.queue_family_index(index)
.queue_family_index(index.index())
.queue_priorities(&Self::PRIORITIES[..count as usize])
})
.collect()
}
fn queue_family_indices(&self) -> HashMap<u32, u32> {
fn queue_family_indices(&self) -> HashMap<QueueFamilyIndex, u32> {
let mut families = HashMap::new();
families.insert(self.graphics.index, 1);
@ -231,12 +273,12 @@ impl DeviceQueueInfos {
.map(|(queue_family_index, count)| {
let queues = (0..count)
.map(|queue_index| unsafe {
dev.get_device_queue(queue_family_index, queue_index)
dev.get_device_queue(queue_family_index.index(), queue_index)
})
.collect();
(queue_family_index, queues)
})
.collect::<HashMap<u32, Vec<vk::Queue>>>();
.collect::<HashMap<QueueFamilyIndex, Vec<vk::Queue>>>();
let graphics = Queue::from_vk_queue(
queues.get_mut(&self.graphics.index).unwrap().pop().unwrap(),
@ -285,15 +327,14 @@ impl DeviceQueueInfos {
.enumerate()
.map(|(index, props)| {
let mut flags = QueueFlags::from_vk_flags(props.queue_flags);
if let Some(display_handle) = display_handle {
if instance.query_presentation_support(pdev.pdev, index as u32, display_handle)
{
flags |= QueueFlags::PRESENT;
}
if let Some(display_handle) = display_handle
&& instance.query_presentation_support(pdev.pdev, index as u32, display_handle)
{
flags |= QueueFlags::PRESENT;
}
QueueFamily {
index: index as u32,
index: QueueFamilyIndex(index as u32),
count: props.queue_count,
flags,
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 gpu_allocator::vulkan::AllocationScheme;
use renderer_device::queue::QueueFamilyIndices;
use crate::{
Device,
@ -132,7 +133,7 @@ impl Buffer {
let create_info = vk::BufferCreateInfo::default()
.size(desc.size)
.usage(desc.usage)
.queue_family_indices(&queue_families)
.queue_family_indices(queue_families.as_u32_slice())
.sharing_mode(sharing_mode);
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 gpu_allocator::vulkan::{AllocationCreateDesc, AllocationScheme};
use parking_lot::Mutex;
use renderer_device::queue::QueueFamilyIndices;
#[derive(Clone)]
pub struct ImageDesc {
@ -316,7 +317,7 @@ impl Image {
.tiling(*tiling)
.usage(*usage)
.sharing_mode(sharing_mode)
.queue_family_indices(&queue_families)
.queue_family_indices(queue_families.as_u32_slice())
.array_layers(*array_layers)
.mip_levels(*mip_levels);