From 62884d16ddf51c30ba014233d57d8022958e2ddd Mon Sep 17 00:00:00 2001 From: Zakarum Date: Tue, 9 Apr 2024 21:33:17 +0200 Subject: [PATCH 1/2] Update ash to 0.38 --- ash/Cargo.toml | 4 ++-- ash/src/lib.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ash/Cargo.toml b/ash/Cargo.toml index 2aba337..ed1ef68 100644 --- a/ash/Cargo.toml +++ b/ash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gpu-descriptor-ash" -version = "0.2.0" +version = "0.3.0" authors = ["Zakarum "] edition = "2018" description = "gpu-descriptor integration with ash" @@ -14,5 +14,5 @@ readme = "../README.md" [dependencies] gpu-descriptor-types = { path = "../types", version = "0.1" } tracing = { version = "0.1", optional = true, default-features = false } -ash = { version = "0.37", default-features = false } +ash = { version = "0.38", default-features = false } smallvec = "1.0" diff --git a/ash/src/lib.rs b/ash/src/lib.rs index 0173f66..7f61013 100644 --- a/ash/src/lib.rs +++ b/ash/src/lib.rs @@ -30,7 +30,7 @@ impl DescriptorDevice Result { - let mut array = [vk::DescriptorPoolSize::builder().build(); 13]; + let mut array = [vk::DescriptorPoolSize::default(); 13]; let mut len = 0; if descriptor_count.sampler != 0 { @@ -124,7 +124,7 @@ impl DescriptorDevice = layouts.copied().collect(); match self.device.allocate_descriptor_sets( - &vk::DescriptorSetAllocateInfo::builder() + &vk::DescriptorSetAllocateInfo::default() .set_layouts(&set_layouts) .descriptor_pool(*pool), ) { From 9f2fb9546591322e7b77ee1e79385e01effd85e4 Mon Sep 17 00:00:00 2001 From: Zakarum Date: Tue, 9 Apr 2024 21:55:44 +0200 Subject: [PATCH 2/2] Fix clippy issues --- ash/Cargo.toml | 2 +- erupt/Cargo.toml | 4 ++-- gpu-descriptor/Cargo.toml | 4 ++-- gpu-descriptor/src/allocator.rs | 37 +++++++++++++++++++++++++-------- types/Cargo.toml | 2 +- types/src/device.rs | 24 ++++++++++++++++++++- types/src/types.rs | 19 +++++++++++++++++ 7 files changed, 76 insertions(+), 16 deletions(-) diff --git a/ash/Cargo.toml b/ash/Cargo.toml index ed1ef68..433a9f8 100644 --- a/ash/Cargo.toml +++ b/ash/Cargo.toml @@ -12,7 +12,7 @@ repository = "https://github.com/zakarumych/gpu-descriptor" readme = "../README.md" [dependencies] -gpu-descriptor-types = { path = "../types", version = "0.1" } +gpu-descriptor-types = { path = "../types", version = "0.2" } tracing = { version = "0.1", optional = true, default-features = false } ash = { version = "0.38", default-features = false } smallvec = "1.0" diff --git a/erupt/Cargo.toml b/erupt/Cargo.toml index 6a1a8c3..0de44c9 100644 --- a/erupt/Cargo.toml +++ b/erupt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gpu-descriptor-erupt" -version = "0.4.0" +version = "0.5.0" authors = ["Zakarum "] edition = "2018" description = "gpu-descriptor integration with erupt" @@ -12,7 +12,7 @@ repository = "https://github.com/zakarumych/gpu-descriptor" readme = "../README.md" [dependencies] -gpu-descriptor-types = { path = "../types", version = "0.1" } +gpu-descriptor-types = { path = "../types", version = "0.2" } tracing = { version = "0.1", optional = true, default-features = false } erupt = { version = "0.23", default-features = false } smallvec = "1.0" diff --git a/gpu-descriptor/Cargo.toml b/gpu-descriptor/Cargo.toml index f4b2641..1bba419 100644 --- a/gpu-descriptor/Cargo.toml +++ b/gpu-descriptor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gpu-descriptor" -version = "0.2.4" +version = "0.3.0" authors = ["Zakarum "] edition = "2018" description = "Implementation agnostic descriptor allocator for Vulkan like APIs" @@ -16,7 +16,7 @@ std = [] default = ["std"] [dependencies] -gpu-descriptor-types = { path = "../types", version = "0.1" } +gpu-descriptor-types = { path = "../types", version = "0.2" } tracing = { version = "0.1", optional = true, default-features = false } bitflags = { version = "2.4", default-features = false } serde = { version = "1.0", optional = true, default-features = false, features = [ diff --git a/gpu-descriptor/src/allocator.rs b/gpu-descriptor/src/allocator.rs index f922530..96fc073 100644 --- a/gpu-descriptor/src/allocator.rs +++ b/gpu-descriptor/src/allocator.rs @@ -108,7 +108,7 @@ struct DescriptorPool

{ struct DescriptorBucket

{ offset: u64, pools: VecDeque>, - total: u64, + total: u32, update_after_bind: bool, size: DescriptorTotalCount, } @@ -159,7 +159,7 @@ impl

DescriptorBucket

{ fn new_pool_size(&self, minimal_set_count: u32) -> (DescriptorTotalCount, u32) { let mut max_sets = MIN_SETS // at least MIN_SETS .max(minimal_set_count) // at least enough for allocation - .max(self.total.min(MAX_SETS as u64) as u32) // at least as much as was allocated so far capped to MAX_SETS + .max(self.total.min(MAX_SETS)) // at least as much as was allocated so far capped to MAX_SETS .checked_next_power_of_two() // rounded up to nearest 2^N .unwrap_or(i32::MAX as u32); @@ -260,7 +260,7 @@ impl

DescriptorBucket

{ count -= allocate; pool.available -= allocate; pool.allocated += allocate; - self.total += u64::from(allocate); + self.total += allocate; if count == 0 { return Ok(()); @@ -329,7 +329,7 @@ impl

DescriptorBucket

{ allocated: allocate, available: max_sets - allocate, }); - self.total += allocate as u64; + self.total += allocate; } Ok(()) @@ -357,7 +357,7 @@ impl

DescriptorBucket

{ pool.available += count; pool.allocated -= count; - self.total -= u64::from(count); + self.total -= count; #[cfg(feature = "tracing")] tracing::trace!("Freed {} from descriptor bucket", count); @@ -396,10 +396,11 @@ impl

DescriptorBucket

{ #[derive(Debug)] pub struct DescriptorAllocator { buckets: HashMap<(DescriptorTotalCount, bool), DescriptorBucket

>, - total: u64, sets_cache: Vec>, raw_sets_cache: Vec, max_update_after_bind_descriptors_in_all_pools: u32, + current_update_after_bind_descriptors_in_all_pools: u32, + total: u32, } impl Drop for DescriptorAllocator { @@ -422,6 +423,7 @@ impl DescriptorAllocator { sets_cache: Vec::new(), raw_sets_cache: Vec::new(), max_update_after_bind_descriptors_in_all_pools, + current_update_after_bind_descriptors_in_all_pools: 0, } } @@ -450,8 +452,18 @@ impl DescriptorAllocator { return Ok(Vec::new()); } + let descriptor_count = count * layout_descriptor_count.total(); + let update_after_bind = flags.contains(DescriptorSetLayoutCreateFlags::UPDATE_AFTER_BIND); + if update_after_bind + && self.max_update_after_bind_descriptors_in_all_pools + - self.current_update_after_bind_descriptors_in_all_pools + < descriptor_count + { + return Err(AllocationError::Fragmentation); + } + #[cfg(feature = "tracing")] tracing::trace!( "Allocating {} sets with layout {:?} @ {:?}", @@ -465,7 +477,14 @@ impl DescriptorAllocator { .entry((*layout_descriptor_count, update_after_bind)) .or_insert_with(|| DescriptorBucket::new(update_after_bind, *layout_descriptor_count)); match bucket.allocate(device, layout, count, &mut self.sets_cache) { - Ok(()) => Ok(core::mem::replace(&mut self.sets_cache, Vec::new())), + Ok(()) => { + self.total += descriptor_count; + if update_after_bind { + self.current_update_after_bind_descriptors_in_all_pools += descriptor_count; + } + + Ok(core::mem::take(&mut self.sets_cache)) + } Err(err) => { debug_assert!(self.raw_sets_cache.is_empty()); @@ -519,7 +538,7 @@ impl DescriptorAllocator { .get_mut(&last_key) .expect("Set must be allocated from this allocator"); - debug_assert!(u64::try_from(self.raw_sets_cache.len()) + debug_assert!(u32::try_from(self.raw_sets_cache.len()) .ok() .map_or(false, |count| count <= bucket.total)); @@ -537,7 +556,7 @@ impl DescriptorAllocator { .get_mut(&last_key) .expect("Set must be allocated from this allocator"); - debug_assert!(u64::try_from(self.raw_sets_cache.len()) + debug_assert!(u32::try_from(self.raw_sets_cache.len()) .ok() .map_or(false, |count| count <= bucket.total)); diff --git a/types/Cargo.toml b/types/Cargo.toml index 25475e6..93bfcc8 100644 --- a/types/Cargo.toml +++ b/types/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "gpu-descriptor-types" -version = "0.1.2" +version = "0.2.0" authors = ["Zakarum "] edition = "2018" description = "Core types of gpu-descriptor crate" diff --git a/types/src/device.rs b/types/src/device.rs index 4542afc..a73a58a 100644 --- a/types/src/device.rs +++ b/types/src/device.rs @@ -31,6 +31,12 @@ pub enum DeviceAllocationError { /// Abstract device that can create pools of type `P` and allocate sets `S` with layout `L`. pub trait DescriptorDevice { + /// Creates a new descriptor pool. + /// + /// # Safety + /// + /// Actually safe. + /// TODO: Remove `unsafe` with next breaking change. unsafe fn create_descriptor_pool( &self, descriptor_count: &DescriptorTotalCount, @@ -38,8 +44,19 @@ pub trait DescriptorDevice { flags: DescriptorPoolCreateFlags, ) -> Result; + /// Destroys descriptor pool. + /// + /// # Safety + /// + /// Pool must be created from this device. + /// All descriptor sets allocated from this pool become invalid. unsafe fn destroy_descriptor_pool(&self, pool: P); + /// Allocates descriptor sets. + /// + /// # Safety + /// + /// Pool must be created from this device. unsafe fn alloc_descriptor_sets<'a>( &self, pool: &mut P, @@ -49,5 +66,10 @@ pub trait DescriptorDevice { where L: 'a; - unsafe fn dealloc_descriptor_sets<'a>(&self, pool: &mut P, sets: impl Iterator); + /// Deallocates descriptor sets. + /// + /// # Safety + /// + /// Sets must be allocated from specified pool and not deallocated before. + unsafe fn dealloc_descriptor_sets(&self, pool: &mut P, sets: impl Iterator); } diff --git a/types/src/types.rs b/types/src/types.rs index 018a24b..73b28dc 100644 --- a/types/src/types.rs +++ b/types/src/types.rs @@ -32,3 +32,22 @@ pub struct DescriptorTotalCount { pub inline_uniform_block_bytes: u32, pub inline_uniform_block_bindings: u32, } + +impl DescriptorTotalCount { + pub fn total(&self) -> u32 { + self.sampler + + self.combined_image_sampler + + self.sampled_image + + self.storage_image + + self.uniform_texel_buffer + + self.storage_texel_buffer + + self.uniform_buffer + + self.storage_buffer + + self.uniform_buffer_dynamic + + self.storage_buffer_dynamic + + self.input_attachment + + self.acceleration_structure + + self.inline_uniform_block_bytes + + self.inline_uniform_block_bindings + } +}