Code cleanup (#2497)

* refactoring

* fmt

* Update vulkano/src/command_buffer/commands/query.rs

Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com>

* Update vulkano/src/buffer/subbuffer.rs

Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com>

* Update vulkano/src/buffer/mod.rs

Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com>

* Update vulkano/src/swapchain/mod.rs

Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com>

* Update vulkano/src/sync/fence.rs

Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com>

* Update vulkano/src/sync/semaphore.rs

Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com>

* Update vulkano/src/sync/pipeline.rs

Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com>

* Update vulkano/src/descriptor_set/mod.rs

Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com>

* Update vulkano/src/image/mod.rs

Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com>

* review fixes

* post merge fixes

* fmt

---------

Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com>
This commit is contained in:
maratik123 2024-03-13 19:37:28 +03:00 committed by GitHub
parent 25a1184c75
commit f911996534
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
60 changed files with 583 additions and 506 deletions

View File

@ -139,7 +139,7 @@ fn main() {
}) })
.expect("no device available"); .expect("no device available");
let (_device, mut _queues) = Device::new( let (_device, _queues) = Device::new(
physical_device, physical_device,
DeviceCreateInfo { DeviceCreateInfo {
enabled_extensions: device_extensions, enabled_extensions: device_extensions,

View File

@ -455,11 +455,11 @@ mod linux {
} }
Err(VulkanError::OutOfDate) => { Err(VulkanError::OutOfDate) => {
recreate_swapchain = true; recreate_swapchain = true;
previous_frame_end = Some(vulkano::sync::now(device.clone()).boxed()); previous_frame_end = Some(now(device.clone()).boxed());
} }
Err(e) => { Err(e) => {
println!("failed to flush future: {e}"); println!("failed to flush future: {e}");
previous_frame_end = Some(vulkano::sync::now(device.clone()).boxed()); previous_frame_end = Some(now(device.clone()).boxed());
} }
}; };
} }

View File

@ -362,7 +362,7 @@ impl InputState {
} }
/// Update toggle julia state (if right mouse is clicked) /// Update toggle julia state (if right mouse is clicked)
fn on_mouse_click_event(&mut self, state: ElementState, mouse_btn: winit::event::MouseButton) { fn on_mouse_click_event(&mut self, state: ElementState, mouse_btn: MouseButton) {
if mouse_btn == MouseButton::Right { if mouse_btn == MouseButton::Right {
self.toggle_c = state_is_pressed(state) self.toggle_c = state_is_pressed(state)
} }

View File

@ -1,5 +1,5 @@
use glam::f32::Vec2; use glam::f32::Vec2;
use rand::Rng; use rand::random;
use std::sync::Arc; use std::sync::Arc;
use vulkano::{ use vulkano::{
buffer::{Buffer, BufferCreateInfo, BufferUsage, Subbuffer}, buffer::{Buffer, BufferCreateInfo, BufferUsage, Subbuffer},
@ -103,10 +103,10 @@ impl FractalComputePipeline {
pub fn randomize_palette(&mut self) { pub fn randomize_palette(&mut self) {
let mut colors = vec![]; let mut colors = vec![];
for _ in 0..self.palette_size { for _ in 0..self.palette_size {
let r = rand::thread_rng().gen::<f32>(); let r = random::<f32>();
let g = rand::thread_rng().gen::<f32>(); let g = random::<f32>();
let b = rand::thread_rng().gen::<f32>(); let b = random::<f32>();
let a = rand::thread_rng().gen::<f32>(); let a = random::<f32>();
colors.push([r, g, b, a]); colors.push([r, g, b, a]);
} }
self.palette = Buffer::from_iter( self.palette = Buffer::from_iter(

View File

@ -35,7 +35,7 @@ pub struct VulkanoWindowRenderer {
recreate_swapchain: bool, recreate_swapchain: bool,
previous_frame_end: Option<Box<dyn GpuFuture>>, previous_frame_end: Option<Box<dyn GpuFuture>>,
image_index: u32, image_index: u32,
present_mode: vulkano::swapchain::PresentMode, present_mode: PresentMode,
} }
impl VulkanoWindowRenderer { impl VulkanoWindowRenderer {
@ -44,7 +44,7 @@ impl VulkanoWindowRenderer {
/// [`SwapchainCreateInfo`] parameters. /// [`SwapchainCreateInfo`] parameters.
pub fn new( pub fn new(
vulkano_context: &VulkanoContext, vulkano_context: &VulkanoContext,
window: winit::window::Window, window: Window,
descriptor: &WindowDescriptor, descriptor: &WindowDescriptor,
swapchain_create_info_modify: fn(&mut SwapchainCreateInfo), swapchain_create_info_modify: fn(&mut SwapchainCreateInfo),
) -> VulkanoWindowRenderer { ) -> VulkanoWindowRenderer {
@ -315,10 +315,7 @@ impl VulkanoWindowRenderer {
match future.map_err(Validated::unwrap) { match future.map_err(Validated::unwrap) {
Ok(mut future) => { Ok(mut future) => {
if wait_future { if wait_future {
match future.wait(None) { future.wait(None).unwrap_or_else(|e| println!("{e}"))
Ok(x) => x,
Err(e) => println!("{e}"),
}
// wait allows you to organize resource waiting yourself. // wait allows you to organize resource waiting yourself.
} else { } else {
future.cleanup_finished(); future.cleanup_finished();

View File

@ -37,8 +37,8 @@ use winit::{
/// ``` /// ```
#[derive(Default)] #[derive(Default)]
pub struct VulkanoWindows { pub struct VulkanoWindows {
windows: HashMap<winit::window::WindowId, VulkanoWindowRenderer>, windows: HashMap<WindowId, VulkanoWindowRenderer>,
primary: Option<winit::window::WindowId>, primary: Option<WindowId>,
} }
impl VulkanoWindows { impl VulkanoWindows {
@ -50,7 +50,7 @@ impl VulkanoWindows {
vulkano_context: &VulkanoContext, vulkano_context: &VulkanoContext,
window_descriptor: &WindowDescriptor, window_descriptor: &WindowDescriptor,
swapchain_create_info_modify: fn(&mut SwapchainCreateInfo), swapchain_create_info_modify: fn(&mut SwapchainCreateInfo),
) -> winit::window::WindowId { ) -> WindowId {
let mut winit_window_builder = winit::window::WindowBuilder::new(); let mut winit_window_builder = winit::window::WindowBuilder::new();
winit_window_builder = match window_descriptor.mode { winit_window_builder = match window_descriptor.mode {
@ -96,12 +96,10 @@ impl VulkanoWindows {
} }
} }
if let Some(sf) = scale_factor_override { if let Some(sf) = scale_factor_override {
winit_window_builder.with_inner_size(
winit::dpi::LogicalSize::new(*width, *height).to_physical::<f64>(*sf),
)
} else {
winit_window_builder winit_window_builder
.with_inner_size(winit::dpi::LogicalSize::new(*width, *height)) .with_inner_size(LogicalSize::new(*width, *height).to_physical::<f64>(*sf))
} else {
winit_window_builder.with_inner_size(LogicalSize::new(*width, *height))
} }
} }
.with_resizable(window_descriptor.resizable) .with_resizable(window_descriptor.resizable)
@ -193,34 +191,31 @@ impl VulkanoWindows {
/// Get a mutable reference to the renderer by winit window id. /// Get a mutable reference to the renderer by winit window id.
#[inline] #[inline]
pub fn get_renderer_mut( pub fn get_renderer_mut(&mut self, id: WindowId) -> Option<&mut VulkanoWindowRenderer> {
&mut self,
id: winit::window::WindowId,
) -> Option<&mut VulkanoWindowRenderer> {
self.windows.get_mut(&id) self.windows.get_mut(&id)
} }
/// Get a reference to the renderer by winit window id. /// Get a reference to the renderer by winit window id.
#[inline] #[inline]
pub fn get_renderer(&self, id: winit::window::WindowId) -> Option<&VulkanoWindowRenderer> { pub fn get_renderer(&self, id: WindowId) -> Option<&VulkanoWindowRenderer> {
self.windows.get(&id) self.windows.get(&id)
} }
/// Get a reference to the winit window by winit window id. /// Get a reference to the winit window by winit window id.
#[inline] #[inline]
pub fn get_window(&self, id: winit::window::WindowId) -> Option<&winit::window::Window> { pub fn get_window(&self, id: WindowId) -> Option<&winit::window::Window> {
self.windows.get(&id).map(|v_window| v_window.window()) self.windows.get(&id).map(|v_window| v_window.window())
} }
/// Return primary window id. /// Return primary window id.
#[inline] #[inline]
pub fn primary_window_id(&self) -> Option<winit::window::WindowId> { pub fn primary_window_id(&self) -> Option<WindowId> {
self.primary self.primary
} }
/// Remove renderer by window id. /// Remove renderer by window id.
#[inline] #[inline]
pub fn remove_renderer(&mut self, id: winit::window::WindowId) { pub fn remove_renderer(&mut self, id: WindowId) {
self.windows.remove(&id); self.windows.remove(&id);
if let Some(primary) = self.primary { if let Some(primary) = self.primary {
if primary == id { if primary == id {

View File

@ -108,29 +108,33 @@ fn device_extensions_output(members: &[ExtensionsMember]) -> TokenStream {
instance_extensions, instance_extensions,
device_features: _, device_features: _,
}| { }| {
let condition_items = (api_version.iter().map(|version| { let condition_items = api_version
let version = format_ident!("V{}_{}", version.0, version.1); .iter()
quote! { api_version >= crate::Version::#version } .map(|version| {
})) let version = format_ident!("V{}_{}", version.0, version.1);
.chain(instance_extensions.iter().map(|ext_name| { quote! { api_version >= crate::Version::#version }
let ident = format_ident!("{}", ext_name); })
quote! { instance_extensions.#ident } .chain(instance_extensions.iter().map(|ext_name| {
})); let ident = format_ident!("{}", ext_name);
let requires_one_of_items = (api_version.iter().map(|(major, minor)| { quote! { instance_extensions.#ident }
let version = format_ident!("V{}_{}", major, minor); }));
quote! { let requires_one_of_items = api_version
crate::RequiresAllOf(&[ .iter()
crate::Requires::APIVersion(crate::Version::#version), .map(|(major, minor)| {
]), let version = format_ident!("V{}_{}", major, minor);
} quote! {
})) crate::RequiresAllOf(&[
.chain(instance_extensions.iter().map(|ext_name| { crate::Requires::APIVersion(crate::Version::#version),
quote! { ]),
crate::RequiresAllOf(&[ }
crate::Requires::InstanceExtension(#ext_name), })
]), .chain(instance_extensions.iter().map(|ext_name| {
} quote! {
})); crate::RequiresAllOf(&[
crate::Requires::InstanceExtension(#ext_name),
]),
}
}));
let problem = format!("contains `{}`", name_string); let problem = format!("contains `{}`", name_string);
quote! { quote! {
@ -173,7 +177,7 @@ fn device_extensions_output(members: &[ExtensionsMember]) -> TokenStream {
name: _, name: _,
requires_all_of, requires_all_of,
.. ..
}| (!requires_all_of.is_empty()), }| !requires_all_of.is_empty(),
) )
.map( .map(
|ExtensionsMember { |ExtensionsMember {
@ -191,7 +195,7 @@ fn device_extensions_output(members: &[ExtensionsMember]) -> TokenStream {
device_extensions, device_extensions,
instance_extensions: _, instance_extensions: _,
device_features: _, device_features: _,
}| (!device_extensions.is_empty()), }| !device_extensions.is_empty(),
) )
.map( .map(
|RequiresOneOf { |RequiresOneOf {
@ -364,7 +368,7 @@ fn instance_extensions_output(members: &[ExtensionsMember]) -> TokenStream {
name: _, name: _,
requires_all_of, requires_all_of,
.. ..
}| (!requires_all_of.is_empty()), }| !requires_all_of.is_empty(),
) )
.map( .map(
|ExtensionsMember { |ExtensionsMember {
@ -382,7 +386,7 @@ fn instance_extensions_output(members: &[ExtensionsMember]) -> TokenStream {
device_extensions: _, device_extensions: _,
instance_extensions, instance_extensions,
device_features: _, device_features: _,
}| (!instance_extensions.is_empty()), }| !instance_extensions.is_empty(),
) )
.map( .map(
|RequiresOneOf { |RequiresOneOf {

View File

@ -179,7 +179,7 @@ fn formats_output(members: &[FormatMember]) -> TokenStream {
.filter( .filter(
|&FormatMember { |&FormatMember {
texels_per_block, .. texels_per_block, ..
}| (*texels_per_block != 1), }| *texels_per_block != 1,
) )
.map( .map(
|FormatMember { |FormatMember {
@ -257,7 +257,7 @@ fn formats_output(members: &[FormatMember]) -> TokenStream {
type_cgmath, type_cgmath,
.. ..
}| { }| {
(type_cgmath.as_ref().or(type_std_array.as_ref())).map(|ty| { type_cgmath.as_ref().or(type_std_array.as_ref()).map(|ty| {
quote! { (cgmath, #name) => { #ty }; } quote! { (cgmath, #name) => { #ty }; }
}) })
}, },
@ -269,7 +269,7 @@ fn formats_output(members: &[FormatMember]) -> TokenStream {
type_glam, type_glam,
.. ..
}| { }| {
(type_glam.as_ref().or(type_std_array.as_ref())).map(|ty| { type_glam.as_ref().or(type_std_array.as_ref()).map(|ty| {
quote! { (glam, #name) => { #ty }; } quote! { (glam, #name) => { #ty }; }
}) })
}, },
@ -281,9 +281,12 @@ fn formats_output(members: &[FormatMember]) -> TokenStream {
type_nalgebra, type_nalgebra,
.. ..
}| { }| {
(type_nalgebra.as_ref().or(type_std_array.as_ref())).map(|ty| { type_nalgebra
quote! { (nalgebra, #name) => { #ty }; } .as_ref()
}) .or(type_std_array.as_ref())
.map(|ty| {
quote! { (nalgebra, #name) => { #ty }; }
})
}, },
); );
@ -300,41 +303,45 @@ fn formats_output(members: &[FormatMember]) -> TokenStream {
instance_extensions, instance_extensions,
device_features: _, device_features: _,
}| { }| {
let condition_items = (api_version.iter().map(|(major, minor)| { let condition_items = api_version
let version = format_ident!("V{}_{}", major, minor); .iter()
quote! { device_api_version >= crate::Version::#version } .map(|(major, minor)| {
})) let version = format_ident!("V{}_{}", major, minor);
.chain(device_extensions.iter().map(|ext_name| { quote! { device_api_version >= crate::Version::#version }
let ident = format_ident!("{}", ext_name); })
quote! { device_extensions.#ident } .chain(device_extensions.iter().map(|ext_name| {
})) let ident = format_ident!("{}", ext_name);
.chain(instance_extensions.iter().map(|ext_name| { quote! { device_extensions.#ident }
let ident = format_ident!("{}", ext_name); }))
quote! { instance_extensions.#ident } .chain(instance_extensions.iter().map(|ext_name| {
})); let ident = format_ident!("{}", ext_name);
quote! { instance_extensions.#ident }
}));
let required_for = format!("is `Format::{}`", name); let required_for = format!("is `Format::{}`", name);
let requires_one_of_items = (api_version.iter().map(|(major, minor)| { let requires_one_of_items = api_version
let version = format_ident!("V{}_{}", major, minor); .iter()
quote! { .map(|(major, minor)| {
crate::RequiresAllOf(&[ let version = format_ident!("V{}_{}", major, minor);
crate::Requires::APIVersion(crate::Version::#version), quote! {
]), crate::RequiresAllOf(&[
} crate::Requires::APIVersion(crate::Version::#version),
})) ]),
.chain(device_extensions.iter().map(|ext_name| { }
quote! { })
crate::RequiresAllOf(&[ .chain(device_extensions.iter().map(|ext_name| {
crate::Requires::DeviceExtension(#ext_name), quote! {
]), crate::RequiresAllOf(&[
} crate::Requires::DeviceExtension(#ext_name),
})) ]),
.chain(instance_extensions.iter().map(|ext_name| { }
quote! { }))
crate::RequiresAllOf(&[ .chain(instance_extensions.iter().map(|ext_name| {
crate::Requires::InstanceExtension(#ext_name), quote! {
]), crate::RequiresAllOf(&[
} crate::Requires::InstanceExtension(#ext_name),
})); ]),
}
}));
quote! { quote! {
if !(#(#condition_items)||*) { if !(#(#condition_items)||*) {

View File

@ -66,7 +66,7 @@ fn write_file(file: impl AsRef<Path>, source: impl AsRef<str>, content: impl Dis
) )
.unwrap(); .unwrap();
std::mem::drop(writer); // Ensure that the file is fully written drop(writer); // Ensure that the file is fully written
Command::new("rustfmt").arg(&path).status().ok(); Command::new("rustfmt").arg(&path).status().ok();
} }
@ -221,7 +221,7 @@ impl<'r> VkRegistryData<'r> {
features: &IndexMap<&'a str, &'a Feature>, features: &IndexMap<&'a str, &'a Feature>,
extensions: &IndexMap<&'a str, &'a Extension>, extensions: &IndexMap<&'a str, &'a Extension>,
) -> Vec<&'a str> { ) -> Vec<&'a str> {
(registry registry
.0 .0
.iter() .iter()
.filter_map(|child| match child { .filter_map(|child| match child {
@ -244,36 +244,38 @@ impl<'r> VkRegistryData<'r> {
})), })),
_ => None, _ => None,
}) })
.flatten()) .flatten()
.chain( .chain(
(features.values().map(|feature| feature.children.iter())) features
.chain( .values()
extensions .map(|feature| feature.children.iter())
.values() .chain(
.map(|extension| extension.children.iter()), extensions
) .values()
.flatten() .map(|extension| extension.children.iter()),
.filter_map(|child| { )
if let ExtensionChild::Require { items, .. } = child { .flatten()
return Some(items.iter().filter_map(|item| match item { .filter_map(|child| {
InterfaceItem::Enum(Enum { if let ExtensionChild::Require { items, .. } = child {
name, return Some(items.iter().filter_map(|item| match item {
spec: InterfaceItem::Enum(Enum {
EnumSpec::Offset { name,
extends, spec:
dir: false, EnumSpec::Offset {
.. extends,
}, dir: false,
.. ..
}) if extends == "VkResult" => Some(name.as_str()), },
_ => None, ..
})); }) if extends == "VkResult" => Some(name.as_str()),
} _ => None,
None }));
}) }
.flatten(), None
) })
.collect() .flatten(),
)
.collect()
} }
fn get_extensions(registry: &Registry) -> IndexMap<&str, &Extension> { fn get_extensions(registry: &Registry) -> IndexMap<&str, &Extension> {

View File

@ -100,40 +100,44 @@ fn spirv_reqs_output(members: &[SpirvReqsMember], is_extension: bool) -> TokenSt
ref device_features, ref device_features,
} = requires_one_of; } = requires_one_of;
let condition_items = (api_version.iter().map(|version| { let condition_items = api_version
let version = format_ident!("V{}_{}", version.0, version.1); .iter()
quote! { api_version >= crate::Version::#version } .map(|version| {
})) let version = format_ident!("V{}_{}", version.0, version.1);
.chain(device_extensions.iter().map(|name| { quote! { api_version >= crate::Version::#version }
let ident = format_ident!("{}", name); })
quote! { device_extensions.#ident } .chain(device_extensions.iter().map(|name| {
})) let ident = format_ident!("{}", name);
.chain(device_features.iter().map(|name| { quote! { device_extensions.#ident }
let ident = format_ident!("{}", name); }))
quote! { device_features.#ident } .chain(device_features.iter().map(|name| {
})); let ident = format_ident!("{}", name);
let requires_one_of_items = (api_version.iter().map(|(major, minor)| { quote! { device_features.#ident }
let version = format_ident!("V{}_{}", major, minor); }));
quote! { let requires_one_of_items = api_version
crate::RequiresAllOf(&[ .iter()
crate::Requires::APIVersion(crate::Version::#version), .map(|(major, minor)| {
]), let version = format_ident!("V{}_{}", major, minor);
} quote! {
})) crate::RequiresAllOf(&[
.chain(device_extensions.iter().map(|name| { crate::Requires::APIVersion(crate::Version::#version),
quote! { ]),
crate::RequiresAllOf(&[ }
crate::Requires::DeviceExtension(#name), })
]), .chain(device_extensions.iter().map(|name| {
} quote! {
})) crate::RequiresAllOf(&[
.chain(device_features.iter().map(|name| { crate::Requires::DeviceExtension(#name),
quote! { ]),
crate::RequiresAllOf(&[ }
crate::Requires::DeviceFeature(#name), }))
]), .chain(device_features.iter().map(|name| {
} quote! {
})); crate::RequiresAllOf(&[
crate::Requires::DeviceFeature(#name),
]),
}
}));
let problem = format!("uses the SPIR-V {} `{}`", item_type, name); let problem = format!("uses the SPIR-V {} `{}`", item_type, name);
quote! { quote! {

View File

@ -65,9 +65,8 @@
//! See also [the `shader` module documentation] for information about how buffer contents need to //! See also [the `shader` module documentation] for information about how buffer contents need to
//! be laid out in accordance with the shader interface. //! be laid out in accordance with the shader interface.
//! //!
//! [`RawBuffer`]: self::sys::RawBuffer //! [`SubbufferAllocator`]: allocator::SubbufferAllocator
//! [`SubbufferAllocator`]: self::allocator::SubbufferAllocator //! [the `view` module]: view
//! [the `view` module]: self::view
//! [the `shader` module documentation]: crate::shader //! [the `shader` module documentation]: crate::shader
pub use self::{subbuffer::*, sys::*, usage::*}; pub use self::{subbuffer::*, sys::*, usage::*};
@ -865,8 +864,6 @@ vulkan_bitflags! {
} }
/// The buffer configuration to query in [`PhysicalDevice::external_buffer_properties`]. /// The buffer configuration to query in [`PhysicalDevice::external_buffer_properties`].
///
/// [`PhysicalDevice::external_buffer_properties`]: crate::device::physical::PhysicalDevice::external_buffer_properties
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ExternalBufferInfo { pub struct ExternalBufferInfo {
/// The flags that will be used. /// The flags that will be used.

View File

@ -115,8 +115,8 @@ impl<T: ?Sized> Subbuffer<T> {
/// ///
/// See [`MappingState::slice`] for the safety invariants of the returned pointer. /// See [`MappingState::slice`] for the safety invariants of the returned pointer.
/// ///
/// [`DeviceMemory::map`]: crate::memory::DeviceMemory::map /// [`DeviceMemory::map`]: memory::DeviceMemory::map
/// [`MappingState::slice`]: crate::memory::MappingState::slice /// [`MappingState::slice`]: memory::MappingState::slice
pub fn mapped_slice(&self) -> Result<NonNull<[u8]>, HostAccessError> { pub fn mapped_slice(&self) -> Result<NonNull<[u8]>, HostAccessError> {
match self.buffer().memory() { match self.buffer().memory() {
BufferMemory::Normal(allocation) => { BufferMemory::Normal(allocation) => {
@ -167,8 +167,8 @@ impl<T: ?Sized> Subbuffer<T> {
#[inline(always)] #[inline(always)]
unsafe fn reinterpret_unchecked_ref_inner<U: ?Sized>(&self) -> &Subbuffer<U> { unsafe fn reinterpret_unchecked_ref_inner<U: ?Sized>(&self) -> &Subbuffer<U> {
assert!(size_of::<Subbuffer<T>>() == size_of::<Subbuffer<U>>()); assert_eq!(size_of::<Subbuffer<T>>(), size_of::<Subbuffer<U>>());
assert!(align_of::<Subbuffer<T>>() == align_of::<Subbuffer<U>>()); assert_eq!(align_of::<Subbuffer<T>>(), align_of::<Subbuffer<U>>());
// SAFETY: All `Subbuffer`s share the same layout. // SAFETY: All `Subbuffer`s share the same layout.
mem::transmute::<&Subbuffer<T>, &Subbuffer<U>>(self) mem::transmute::<&Subbuffer<T>, &Subbuffer<U>>(self)
@ -261,10 +261,13 @@ where
assert!(is_aligned(self.memory_offset(), new_layout.alignment())); assert!(is_aligned(self.memory_offset(), new_layout.alignment()));
if new_layout.is_sized() { if new_layout.is_sized() {
assert!(self.size == new_layout.unwrap_sized().size()); assert_eq!(self.size, new_layout.unwrap_sized().size());
} else { } else {
assert!(self.size > new_layout.head_size()); assert!(self.size > new_layout.head_size());
assert!((self.size - new_layout.head_size()) % new_layout.element_size().unwrap() == 0); assert_eq!(
(self.size - new_layout.head_size()) % new_layout.element_size().unwrap(),
0,
);
assert!(is_aligned(self.size(), new_layout.alignment())); assert!(is_aligned(self.size(), new_layout.alignment()));
} }
} }
@ -293,8 +296,8 @@ where
/// If the memory backing the buffer is not managed by vulkano, (i.e. this buffer was created /// If the memory backing the buffer is not managed by vulkano, (i.e. this buffer was created
/// from [`RawBuffer::assume_bound`]), then it can't be read from using this function. /// from [`RawBuffer::assume_bound`]), then it can't be read from using this function.
/// ///
/// [host-coherent]: crate::memory::MemoryPropertyFlags::HOST_COHERENT /// [host-coherent]: memory::MemoryPropertyFlags::HOST_COHERENT
/// [`invalidate_range`]: crate::memory::ResourceMemory::invalidate_range /// [`invalidate_range`]: memory::ResourceMemory::invalidate_range
/// [`non_coherent_atom_size`]: crate::device::DeviceProperties::non_coherent_atom_size /// [`non_coherent_atom_size`]: crate::device::DeviceProperties::non_coherent_atom_size
/// [`write`]: Self::write /// [`write`]: Self::write
/// [`SubbufferAllocator`]: super::allocator::SubbufferAllocator /// [`SubbufferAllocator`]: super::allocator::SubbufferAllocator
@ -386,8 +389,8 @@ where
/// If the memory backing the buffer is not managed by vulkano, (i.e. this buffer was created /// If the memory backing the buffer is not managed by vulkano, (i.e. this buffer was created
/// from [`RawBuffer::assume_bound`]), then it can't be written to using this function. /// from [`RawBuffer::assume_bound`]), then it can't be written to using this function.
/// ///
/// [host-coherent]: crate::memory::MemoryPropertyFlags::HOST_COHERENT /// [host-coherent]: memory::MemoryPropertyFlags::HOST_COHERENT
/// [`flush_range`]: crate::memory::ResourceMemory::flush_range /// [`flush_range`]: memory::ResourceMemory::flush_range
/// [`non_coherent_atom_size`]: crate::device::DeviceProperties::non_coherent_atom_size /// [`non_coherent_atom_size`]: crate::device::DeviceProperties::non_coherent_atom_size
/// [`read`]: Self::read /// [`read`]: Self::read
/// [`SubbufferAllocator`]: super::allocator::SubbufferAllocator /// [`SubbufferAllocator`]: super::allocator::SubbufferAllocator
@ -505,7 +508,7 @@ impl<T> Subbuffer<[T]> {
self.offset += start * size_of::<T>() as DeviceSize; self.offset += start * size_of::<T>() as DeviceSize;
self.size = (end - start) * size_of::<T>() as DeviceSize; self.size = (end - start) * size_of::<T>() as DeviceSize;
assert!(self.size != 0); assert_ne!(self.size, 0);
self self
} }
@ -1231,14 +1234,14 @@ mod tests {
{ {
let (left, right) = buffer.clone().split_at(2); let (left, right) = buffer.clone().split_at(2);
assert!(left.len() == 2); assert_eq!(left.len(), 2);
assert!(right.len() == 4); assert_eq!(right.len(), 4);
} }
{ {
let (left, right) = buffer.clone().split_at(5); let (left, right) = buffer.clone().split_at(5);
assert!(left.len() == 5); assert_eq!(left.len(), 5);
assert!(right.len() == 1); assert_eq!(right.len(), 1);
} }
{ {

View File

@ -1375,7 +1375,9 @@ impl RenderPassState {
RenderPassState { RenderPassState {
contents: SubpassContents::Inline, contents: SubpassContents::Inline,
render_area_offset: [0, 0], render_area_offset: [0, 0],
render_area_extent: (info.framebuffer.as_ref()) render_area_extent: info
.framebuffer
.as_ref()
// Still not exact, but it's a better upper bound. // Still not exact, but it's a better upper bound.
.map_or([u32::MAX, u32::MAX], |framebuffer| framebuffer.extent()), .map_or([u32::MAX, u32::MAX], |framebuffer| framebuffer.extent()),
@ -1452,10 +1454,12 @@ impl RenderPassStateAttachments {
let fb_attachments = framebuffer.attachments(); let fb_attachments = framebuffer.attachments();
Self { Self {
color_attachments: (subpass_desc.color_attachments.iter()) color_attachments: subpass_desc
.color_attachments
.iter()
.zip(subpass_desc.color_resolve_attachments.iter()) .zip(subpass_desc.color_resolve_attachments.iter())
.map(|(color_attachment, color_resolve_attachment)| { .map(|(color_attachment, color_resolve_attachment)| {
(color_attachment.as_ref()).map(|color_attachment| { color_attachment.as_ref().map(|color_attachment| {
RenderPassStateAttachmentInfo { RenderPassStateAttachmentInfo {
image_view: fb_attachments[color_attachment.attachment as usize] image_view: fb_attachments[color_attachment.attachment as usize]
.clone(), .clone(),
@ -1472,9 +1476,12 @@ impl RenderPassStateAttachments {
}) })
}) })
.collect(), .collect(),
depth_attachment: (subpass_desc.depth_stencil_attachment.as_ref()) depth_attachment: subpass_desc
.depth_stencil_attachment
.as_ref()
.filter(|depth_stencil_attachment| { .filter(|depth_stencil_attachment| {
(rp_attachments[depth_stencil_attachment.attachment as usize].format) rp_attachments[depth_stencil_attachment.attachment as usize]
.format
.aspects() .aspects()
.intersects(ImageAspects::DEPTH) .intersects(ImageAspects::DEPTH)
}) })
@ -1491,9 +1498,12 @@ impl RenderPassStateAttachments {
}, },
), ),
}), }),
stencil_attachment: (subpass_desc.depth_stencil_attachment.as_ref()) stencil_attachment: subpass_desc
.depth_stencil_attachment
.as_ref()
.filter(|depth_stencil_attachment| { .filter(|depth_stencil_attachment| {
(rp_attachments[depth_stencil_attachment.attachment as usize].format) rp_attachments[depth_stencil_attachment.attachment as usize]
.format
.aspects() .aspects()
.intersects(ImageAspects::STENCIL) .intersects(ImageAspects::STENCIL)
}) })
@ -1519,21 +1529,25 @@ impl RenderPassStateAttachments {
pub(in crate::command_buffer) fn from_rendering_info(info: &RenderingInfo) -> Self { pub(in crate::command_buffer) fn from_rendering_info(info: &RenderingInfo) -> Self {
Self { Self {
color_attachments: (info.color_attachments.iter()) color_attachments: info
.color_attachments
.iter()
.map(|atch_info| { .map(|atch_info| {
(atch_info.as_ref()).map(|atch_info| RenderPassStateAttachmentInfo { atch_info
image_view: atch_info.image_view.clone(), .as_ref()
_image_layout: atch_info.image_layout, .map(|atch_info| RenderPassStateAttachmentInfo {
_resolve_info: atch_info.resolve_info.as_ref().map(|resolve_atch_info| { image_view: atch_info.image_view.clone(),
RenderPassStateAttachmentResolveInfo { _image_layout: atch_info.image_layout,
_image_view: resolve_atch_info.image_view.clone(), _resolve_info: atch_info.resolve_info.as_ref().map(
_image_layout: resolve_atch_info.image_layout, |resolve_atch_info| RenderPassStateAttachmentResolveInfo {
} _image_view: resolve_atch_info.image_view.clone(),
}), _image_layout: resolve_atch_info.image_layout,
}) },
),
})
}) })
.collect(), .collect(),
depth_attachment: (info.depth_attachment.as_ref()).map(|atch_info| { depth_attachment: info.depth_attachment.as_ref().map(|atch_info| {
RenderPassStateAttachmentInfo { RenderPassStateAttachmentInfo {
image_view: atch_info.image_view.clone(), image_view: atch_info.image_view.clone(),
_image_layout: atch_info.image_layout, _image_layout: atch_info.image_layout,
@ -1545,7 +1559,7 @@ impl RenderPassStateAttachments {
}), }),
} }
}), }),
stencil_attachment: (info.stencil_attachment.as_ref()).map(|atch_info| { stencil_attachment: info.stencil_attachment.as_ref().map(|atch_info| {
RenderPassStateAttachmentInfo { RenderPassStateAttachmentInfo {
image_view: atch_info.image_view.clone(), image_view: atch_info.image_view.clone(),
_image_layout: atch_info.image_layout, _image_layout: atch_info.image_layout,

View File

@ -523,7 +523,7 @@ mod tests {
// primaries is an error. // primaries is an error.
assert!(builder.execute_commands(secondary.clone()).is_err()); assert!(builder.execute_commands(secondary.clone()).is_err());
std::mem::drop(cb1); drop(cb1);
// Now that the first cb is dropped, we should be able to record. // Now that the first cb is dropped, we should be able to record.
builder.execute_commands(secondary).unwrap(); builder.execute_commands(secondary).unwrap();

View File

@ -74,8 +74,7 @@ impl RecordingCommandBuffer {
/// [`AabbPositions`]: crate::acceleration_structure::AabbPositions /// [`AabbPositions`]: crate::acceleration_structure::AabbPositions
/// [`AccelerationStructureInstance::acceleration_structure_reference`]: crate::acceleration_structure::AccelerationStructureInstance::acceleration_structure_reference /// [`AccelerationStructureInstance::acceleration_structure_reference`]: crate::acceleration_structure::AccelerationStructureInstance::acceleration_structure_reference
/// [`AccelerationStructureGeometryInstancesData::data`]: crate::acceleration_structure::AccelerationStructureGeometryInstancesData::data /// [`AccelerationStructureGeometryInstancesData::data`]: crate::acceleration_structure::AccelerationStructureGeometryInstancesData::data
/// [`device_address`]: crate::acceleration_structure::AccelerationStructure::device_address /// [`device_address`]: AccelerationStructure::device_address
/// [`AccelerationStructureGeometryInstancesDataType::Pointers`]: crate::acceleration_structure::AccelerationStructureGeometryInstancesDataType::Pointers
#[inline] #[inline]
pub unsafe fn build_acceleration_structure( pub unsafe fn build_acceleration_structure(
&mut self, &mut self,

View File

@ -1699,7 +1699,10 @@ impl RecordingCommandBuffer {
let check_buffer_view = let check_buffer_view =
|set_num: u32, binding_num: u32, index: u32, buffer_view: &Arc<BufferView>| { |set_num: u32, binding_num: u32, index: u32, buffer_view: &Arc<BufferView>| {
for desc_reqs in (binding_reqs.descriptors.get(&Some(index)).into_iter()) for desc_reqs in binding_reqs
.descriptors
.get(&Some(index))
.into_iter()
.chain(binding_reqs.descriptors.get(&None)) .chain(binding_reqs.descriptors.get(&None))
{ {
if layout_binding.descriptor_type == DescriptorType::StorageTexelBuffer { if layout_binding.descriptor_type == DescriptorType::StorageTexelBuffer {
@ -1750,7 +1753,10 @@ impl RecordingCommandBuffer {
let check_image_view_common = let check_image_view_common =
|set_num: u32, binding_num: u32, index: u32, image_view: &Arc<ImageView>| { |set_num: u32, binding_num: u32, index: u32, image_view: &Arc<ImageView>| {
for desc_reqs in (binding_reqs.descriptors.get(&Some(index)).into_iter()) for desc_reqs in binding_reqs
.descriptors
.get(&Some(index))
.into_iter()
.chain(binding_reqs.descriptors.get(&None)) .chain(binding_reqs.descriptors.get(&None))
{ {
if desc_reqs.storage_image_atomic if desc_reqs.storage_image_atomic
@ -1936,7 +1942,10 @@ impl RecordingCommandBuffer {
let check_sampler_common = let check_sampler_common =
|set_num: u32, binding_num: u32, index: u32, sampler: &Arc<Sampler>| { |set_num: u32, binding_num: u32, index: u32, sampler: &Arc<Sampler>| {
for desc_reqs in (binding_reqs.descriptors.get(&Some(index)).into_iter()) for desc_reqs in binding_reqs
.descriptors
.get(&Some(index))
.into_iter()
.chain(binding_reqs.descriptors.get(&None)) .chain(binding_reqs.descriptors.get(&None))
{ {
if desc_reqs.sampler_no_unnormalized_coordinates if desc_reqs.sampler_no_unnormalized_coordinates
@ -2062,7 +2071,10 @@ impl RecordingCommandBuffer {
|set_num: u32, binding_num: u32, index: u32, sampler: &Arc<Sampler>| { |set_num: u32, binding_num: u32, index: u32, sampler: &Arc<Sampler>| {
check_sampler_common(set_num, binding_num, index, sampler)?; check_sampler_common(set_num, binding_num, index, sampler)?;
for desc_reqs in (binding_reqs.descriptors.get(&Some(index)).into_iter()) for desc_reqs in binding_reqs
.descriptors
.get(&Some(index))
.into_iter()
.chain(binding_reqs.descriptors.get(&None)) .chain(binding_reqs.descriptors.get(&None))
{ {
// Check sampler-image compatibility. Only done for separate samplers; // Check sampler-image compatibility. Only done for separate samplers;

View File

@ -251,9 +251,8 @@ impl RecordingCommandBuffer {
/// ///
/// See also [`get_results`]. /// See also [`get_results`].
/// ///
/// [`query_pool.ty().result_len()`]: crate::query::QueryPool::result_len /// [`query_pool.ty().result_len()`]: QueryPool::result_len
/// [`QueryResultFlags::WITH_AVAILABILITY`]: crate::query::QueryResultFlags::WITH_AVAILABILITY /// [`get_results`]: QueryPool::get_results
/// [`get_results`]: crate::query::QueryPool::get_results
pub fn copy_query_pool_results<T>( pub fn copy_query_pool_results<T>(
&mut self, &mut self,
query_pool: Arc<QueryPool>, query_pool: Arc<QueryPool>,

View File

@ -1095,7 +1095,9 @@ impl RawRecordingCommandBuffer {
_ne: _, _ne: _,
} = subpass_desc; } = subpass_desc;
for atch_ref in (input_attachments.iter().flatten()) for atch_ref in input_attachments
.iter()
.flatten()
.chain(color_attachments.iter().flatten()) .chain(color_attachments.iter().flatten())
.chain(color_resolve_attachments.iter().flatten()) .chain(color_resolve_attachments.iter().flatten())
.chain(depth_stencil_attachment.iter()) .chain(depth_stencil_attachment.iter())
@ -2182,7 +2184,9 @@ impl RenderingInfo {
} }
} }
for image_view in (color_attachments.iter().flatten()) for image_view in color_attachments
.iter()
.flatten()
.chain(depth_attachment.iter()) .chain(depth_attachment.iter())
.chain(stencil_attachment.iter()) .chain(stencil_attachment.iter())
.flat_map(|attachment_info| { .flat_map(|attachment_info| {
@ -3132,7 +3136,7 @@ impl RenderingAttachmentResolveInfo {
/// Clear attachment type, used in [`clear_attachments`] command. /// Clear attachment type, used in [`clear_attachments`] command.
/// ///
/// [`clear_attachments`]: crate::command_buffer::RecordingCommandBuffer::clear_attachments /// [`clear_attachments`]: RecordingCommandBuffer::clear_attachments
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub enum ClearAttachment { pub enum ClearAttachment {
/// Clear the color attachment at the specified index, with the specified clear value. /// Clear the color attachment at the specified index, with the specified clear value.
@ -3218,7 +3222,7 @@ impl From<ClearAttachment> for ash::vk::ClearAttachment {
/// Specifies the clear region for the [`clear_attachments`] command. /// Specifies the clear region for the [`clear_attachments`] command.
/// ///
/// [`clear_attachments`]: crate::command_buffer::RecordingCommandBuffer::clear_attachments /// [`clear_attachments`]: RecordingCommandBuffer::clear_attachments
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct ClearRect { pub struct ClearRect {
/// The rectangle offset. /// The rectangle offset.

View File

@ -188,12 +188,14 @@ impl RecordingCommandBuffer {
})); }));
} }
for (color_attachment_index, image_view, inherited_format) in (attachments for (color_attachment_index, image_view, inherited_format) in attachments
.color_attachments .color_attachments
.iter()) .iter()
.zip(inheritance_info.color_attachment_formats.iter().copied()) .zip(inheritance_info.color_attachment_formats.iter().copied())
.enumerate() .enumerate()
.filter_map(|(i, (a, f))| a.as_ref().map(|a| (i as u32, &a.image_view, f))) .filter_map(|(i, (a, f))| {
a.as_ref().map(|a| (i as u32, &a.image_view, f))
})
{ {
let required_format = image_view.format(); let required_format = image_view.format();

View File

@ -1139,7 +1139,9 @@ impl RawRecordingCommandBuffer {
buffer_memory_barriers_vk, buffer_memory_barriers_vk,
image_memory_barriers_vk, image_memory_barriers_vk,
}, },
) in (dependency_infos_vk.iter_mut()).zip(per_dependency_info_vk.iter_mut()) ) in dependency_infos_vk
.iter_mut()
.zip(per_dependency_info_vk.iter_mut())
{ {
*dependency_info_vk = ash::vk::DependencyInfo { *dependency_info_vk = ash::vk::DependencyInfo {
memory_barrier_count: memory_barriers_vk.len() as u32, memory_barrier_count: memory_barriers_vk.len() as u32,

View File

@ -88,8 +88,8 @@
//! let future = cb.execute(queue.clone()); //! let future = cb.execute(queue.clone());
//! ``` //! ```
//! //!
//! [`StandardCommandBufferAllocator`]: self::allocator::StandardCommandBufferAllocator //! [`StandardCommandBufferAllocator`]: allocator::StandardCommandBufferAllocator
//! [`CommandBufferAllocator`]: self::allocator::CommandBufferAllocator //! [`CommandBufferAllocator`]: allocator::CommandBufferAllocator
//! [inherit]: CommandBufferInheritanceInfo //! [inherit]: CommandBufferInheritanceInfo
//! [`end`]: RecordingCommandBuffer::end //! [`end`]: RecordingCommandBuffer::end
//! [`GpuFuture`]: crate::sync::GpuFuture //! [`GpuFuture`]: crate::sync::GpuFuture

View File

@ -99,7 +99,7 @@ impl CommandBuffer {
assert_eq!(self.device().handle(), future.device().handle()); assert_eq!(self.device().handle(), future.device().handle());
if !future.queue_change_allowed() { if !future.queue_change_allowed() {
assert!(future.queue().unwrap() == queue); assert_eq!(future.queue().unwrap(), queue);
} }
Ok(CommandBufferExecFuture { Ok(CommandBufferExecFuture {

View File

@ -172,8 +172,6 @@ impl AllocationHandle {
/// ///
/// This allocator only needs to lock when a thread first allocates or when a thread that /// This allocator only needs to lock when a thread first allocates or when a thread that
/// previously allocated exits. In all other cases, allocation is lock-free. /// previously allocated exits. In all other cases, allocation is lock-free.
///
/// [`DescriptorPool`]: crate::descriptor_set::pool::DescriptorPool
#[derive(Debug)] #[derive(Debug)]
pub struct StandardDescriptorSetAllocator { pub struct StandardDescriptorSetAllocator {
device: InstanceOwnedDebugWrapper<Arc<Device>>, device: InstanceOwnedDebugWrapper<Arc<Device>>,
@ -340,7 +338,7 @@ impl FixedEntry {
.descriptor_counts() .descriptor_counts()
.iter() .iter()
.map(|(&ty, &count)| { .map(|(&ty, &count)| {
assert!(ty != DescriptorType::InlineUniformBlock); assert_ne!(ty, DescriptorType::InlineUniformBlock);
(ty, count * create_info.set_count as u32) (ty, count * create_info.set_count as u32)
}) })
.collect(), .collect(),
@ -425,7 +423,7 @@ impl VariableEntry {
.descriptor_counts() .descriptor_counts()
.iter() .iter()
.map(|(&ty, &count)| { .map(|(&ty, &count)| {
assert!(ty != DescriptorType::InlineUniformBlock); assert_ne!(ty, DescriptorType::InlineUniformBlock);
(ty, count * create_info.set_count as u32) (ty, count * create_info.set_count as u32)
}) })
.collect(), .collect(),

View File

@ -63,9 +63,6 @@
//! - The [`DescriptorSetsCollection`] trait is implemented on collections of descriptor sets. It //! - The [`DescriptorSetsCollection`] trait is implemented on collections of descriptor sets. It
//! is what you pass to the bind function. //! is what you pass to the bind function.
//! //!
//! [`DescriptorPool`]: pool::DescriptorPool
//! [`RawDescriptorSet`]: sys::RawDescriptorSet
//! [`DescriptorSetAllocator`]: allocator::DescriptorSetAllocator
//! [`StandardDescriptorSetAllocator`]: allocator::StandardDescriptorSetAllocator //! [`StandardDescriptorSetAllocator`]: allocator::StandardDescriptorSetAllocator
pub(crate) use self::update::DescriptorWriteInfo; pub(crate) use self::update::DescriptorWriteInfo;

View File

@ -56,7 +56,7 @@ impl WriteDescriptorSet {
/// See [`none`](Self::none) for more information. /// See [`none`](Self::none) for more information.
#[inline] #[inline]
pub fn none_array(binding: u32, first_array_element: u32, num_elements: u32) -> Self { pub fn none_array(binding: u32, first_array_element: u32, num_elements: u32) -> Self {
assert!(num_elements != 0); assert_ne!(num_elements, 0);
Self { Self {
binding, binding,
first_array_element, first_array_element,

View File

@ -547,8 +547,8 @@ impl Device {
/// Returns the Vulkan version supported by the device. /// Returns the Vulkan version supported by the device.
/// ///
/// This is the lower of the /// This is the lower of the
/// [physical device's supported version](crate::device::physical::PhysicalDevice::api_version) /// [physical device's supported version](PhysicalDevice::api_version)
/// and the instance's [`max_api_version`](crate::instance::Instance::max_api_version). /// and the instance's [`max_api_version`](Instance::max_api_version).
#[inline] #[inline]
pub fn api_version(&self) -> Version { pub fn api_version(&self) -> Version {
self.api_version self.api_version
@ -1566,7 +1566,7 @@ impl Device {
object: &T, object: &T,
object_name: Option<&str>, object_name: Option<&str>,
) -> Result<(), VulkanError> { ) -> Result<(), VulkanError> {
assert!(object.device().handle() == self.handle()); assert_eq!(object.device().handle(), self.handle());
let object_name_vk = object_name.map(|object_name| CString::new(object_name).unwrap()); let object_name_vk = object_name.map(|object_name| CString::new(object_name).unwrap());
let info = ash::vk::DebugUtilsObjectNameInfoEXT { let info = ash::vk::DebugUtilsObjectNameInfoEXT {
@ -1750,7 +1750,7 @@ pub struct DeviceCreateInfo {
/// ///
/// The default value is `0`. /// The default value is `0`.
/// ///
/// [private data slots]: self::private_data /// [private data slots]: private_data
/// [`ext_private_data`]: DeviceExtensions::ext_private_data /// [`ext_private_data`]: DeviceExtensions::ext_private_data
pub private_data_slot_request_count: u32, pub private_data_slot_request_count: u32,
@ -2357,7 +2357,7 @@ mod tests {
let queue_family_properties = let queue_family_properties =
&physical_device.queue_family_properties()[queue_family_index as usize]; &physical_device.queue_family_properties()[queue_family_index as usize];
let queues = (0..queue_family_properties.queue_count + 1) let queues = (0..queue_family_properties.queue_count + 1)
.map(|_| (0.5)) .map(|_| 0.5)
.collect(); .collect();
if Device::new( if Device::new(

View File

@ -488,8 +488,8 @@ impl PhysicalDevice {
/// Returns the properties of displays attached to the physical device. /// Returns the properties of displays attached to the physical device.
#[inline] #[inline]
pub fn display_properties<'a>( pub fn display_properties(
self: &'a Arc<Self>, self: &Arc<Self>,
) -> Result<Vec<Arc<Display>>, Validated<VulkanError>> { ) -> Result<Vec<Arc<Display>>, Validated<VulkanError>> {
self.validate_display_properties()?; self.validate_display_properties()?;
@ -510,8 +510,8 @@ impl PhysicalDevice {
} }
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn display_properties_unchecked<'a>( pub unsafe fn display_properties_unchecked(
self: &'a Arc<Self>, self: &Arc<Self>,
) -> Result<Vec<Arc<Display>>, VulkanError> { ) -> Result<Vec<Arc<Display>>, VulkanError> {
let fns = self.instance.fns(); let fns = self.instance.fns();
@ -2543,7 +2543,11 @@ impl PhysicalDevice {
Ok(surface_format2s_vk Ok(surface_format2s_vk
.into_iter() .into_iter()
.filter_map(|surface_format2| { .filter_map(|surface_format2| {
(surface_format2.surface_format.format.try_into().ok()) surface_format2
.surface_format
.format
.try_into()
.ok()
.zip(surface_format2.surface_format.color_space.try_into().ok()) .zip(surface_format2.surface_format.color_space.try_into().ok())
}) })
.collect()) .collect())
@ -2580,7 +2584,10 @@ impl PhysicalDevice {
Ok(surface_formats Ok(surface_formats
.into_iter() .into_iter()
.filter_map(|surface_format| { .filter_map(|surface_format| {
(surface_format.format.try_into().ok()) surface_format
.format
.try_into()
.ok()
.zip(surface_format.color_space.try_into().ok()) .zip(surface_format.color_space.try_into().ok())
}) })
.collect()) .collect())

View File

@ -425,10 +425,10 @@ impl<'a> QueueGuard<'a> {
image_binds_vk, image_binds_vk,
signal_semaphores_vk, signal_semaphores_vk,
}, },
) in (bind_infos_vk.iter_mut()).zip(per_bind_vk.iter_mut()) ) in bind_infos_vk.iter_mut().zip(per_bind_vk.iter_mut())
{ {
for (buffer_bind_infos_vk, buffer_binds_vk) in for (buffer_bind_infos_vk, buffer_binds_vk) in
(buffer_bind_infos_vk.iter_mut()).zip(buffer_binds_vk.iter()) buffer_bind_infos_vk.iter_mut().zip(buffer_binds_vk.iter())
{ {
*buffer_bind_infos_vk = ash::vk::SparseBufferMemoryBindInfo { *buffer_bind_infos_vk = ash::vk::SparseBufferMemoryBindInfo {
bind_count: buffer_binds_vk.len() as u32, bind_count: buffer_binds_vk.len() as u32,
@ -437,8 +437,9 @@ impl<'a> QueueGuard<'a> {
}; };
} }
for (image_opaque_bind_infos_vk, image_opaque_binds_vk) in for (image_opaque_bind_infos_vk, image_opaque_binds_vk) in image_opaque_bind_infos_vk
(image_opaque_bind_infos_vk.iter_mut()).zip(image_opaque_binds_vk.iter()) .iter_mut()
.zip(image_opaque_binds_vk.iter())
{ {
*image_opaque_bind_infos_vk = ash::vk::SparseImageOpaqueMemoryBindInfo { *image_opaque_bind_infos_vk = ash::vk::SparseImageOpaqueMemoryBindInfo {
bind_count: image_opaque_binds_vk.len() as u32, bind_count: image_opaque_binds_vk.len() as u32,
@ -448,7 +449,7 @@ impl<'a> QueueGuard<'a> {
} }
for (image_bind_infos_vk, image_binds_vk) in for (image_bind_infos_vk, image_binds_vk) in
(image_bind_infos_vk.iter_mut()).zip(image_binds_vk.iter()) image_bind_infos_vk.iter_mut().zip(image_binds_vk.iter())
{ {
*image_bind_infos_vk = ash::vk::SparseImageMemoryBindInfo { *image_bind_infos_vk = ash::vk::SparseImageMemoryBindInfo {
bind_count: image_binds_vk.len() as u32, bind_count: image_binds_vk.len() as u32,
@ -686,7 +687,7 @@ impl<'a> QueueGuard<'a> {
if has_present_regions { if has_present_regions {
for (present_regions_vk, rectangles_vk) in for (present_regions_vk, rectangles_vk) in
(present_regions_vk.iter_mut()).zip(rectangles_vk.iter()) present_regions_vk.iter_mut().zip(rectangles_vk.iter())
{ {
*present_regions_vk = ash::vk::PresentRegionKHR { *present_regions_vk = ash::vk::PresentRegionKHR {
rectangle_count: rectangles_vk.len() as u32, rectangle_count: rectangles_vk.len() as u32,
@ -1005,7 +1006,7 @@ impl<'a> QueueGuard<'a> {
command_buffer_infos_vk, command_buffer_infos_vk,
signal_semaphore_infos_vk, signal_semaphore_infos_vk,
}, },
) in (submit_info_vk.iter_mut()).zip(per_submit_vk.iter_mut()) ) in submit_info_vk.iter_mut().zip(per_submit_vk.iter_mut())
{ {
*submit_info_vk = ash::vk::SubmitInfo2 { *submit_info_vk = ash::vk::SubmitInfo2 {
wait_semaphore_info_count: wait_semaphore_infos_vk.len() as u32, wait_semaphore_info_count: wait_semaphore_infos_vk.len() as u32,
@ -1163,7 +1164,7 @@ impl<'a> QueueGuard<'a> {
signal_semaphores_vk, signal_semaphores_vk,
signal_semaphore_values_vk, signal_semaphore_values_vk,
}, },
) in (submit_info_vk.iter_mut()).zip(per_submit_vk.iter_mut()) ) in submit_info_vk.iter_mut().zip(per_submit_vk.iter_mut())
{ {
*submit_info_vk = ash::vk::SubmitInfo { *submit_info_vk = ash::vk::SubmitInfo {
wait_semaphore_count: wait_semaphores_vk.len() as u32, wait_semaphore_count: wait_semaphores_vk.len() as u32,

View File

@ -43,7 +43,7 @@
//! You can [create a `ResourceMemory` from `DeviceMemory`] if you want to bind its own block of //! You can [create a `ResourceMemory` from `DeviceMemory`] if you want to bind its own block of
//! memory to an image. //! memory to an image.
//! //!
//! [`ImageView`]: crate::image::view::ImageView //! [`ImageView`]: view::ImageView
//! [create an `Image` directly]: Image::new //! [create an `Image` directly]: Image::new
//! [create a `RawImage`]: RawImage::new //! [create a `RawImage`]: RawImage::new
//! [bind memory to it]: RawImage::bind_memory //! [bind memory to it]: RawImage::bind_memory
@ -893,7 +893,7 @@ impl SubresourceRangeIterator {
.collect::<SmallVec<[usize; 4]>>() .collect::<SmallVec<[usize; 4]>>()
.into_iter() .into_iter()
.peekable(); .peekable();
assert!(aspect_nums.len() != 0); assert_ne!(aspect_nums.len(), 0);
let current_aspect_num = aspect_nums.next(); let current_aspect_num = aspect_nums.next();
let current_mip_level = subresource_range.mip_levels.start; let current_mip_level = subresource_range.mip_levels.start;
@ -1032,9 +1032,6 @@ vulkan_bitflags! {
/// For 2D images, whether an image view of type [`ImageViewType::Cube`] or /// For 2D images, whether an image view of type [`ImageViewType::Cube`] or
/// [`ImageViewType::CubeArray`] can be created from the image. /// [`ImageViewType::CubeArray`] can be created from the image.
///
/// [`ImageViewType::Cube`]: crate::image::view::ImageViewType::Cube
/// [`ImageViewType::CubeArray`]: crate::image::view::ImageViewType::CubeArray
CUBE_COMPATIBLE = CUBE_COMPATIBLE, CUBE_COMPATIBLE = CUBE_COMPATIBLE,
/* TODO: enable /* TODO: enable
@ -1063,8 +1060,6 @@ vulkan_bitflags! {
/// On [portability subset] devices, the [`image_view2_d_on3_d_image`] feature must be enabled /// On [portability subset] devices, the [`image_view2_d_on3_d_image`] feature must be enabled
/// on the device. /// on the device.
/// ///
/// [`ImageViewType::Dim2d`]: crate::image::view::ImageViewType::Dim2d
/// [`ImageViewType::Dim2dArray`]: crate::image::view::ImageViewType::Dim2dArray
/// [`DIM2D_VIEW_COMPATIBLE`]: ImageCreateFlags::DIM2D_VIEW_COMPATIBLE /// [`DIM2D_VIEW_COMPATIBLE`]: ImageCreateFlags::DIM2D_VIEW_COMPATIBLE
/// [portability subset]: crate::instance#portability-subset-devices-and-the-enumerate_portability-flag /// [portability subset]: crate::instance#portability-subset-devices-and-the-enumerate_portability-flag
/// [`image_view2_d_on3_d_image`]: crate::device::DeviceFeatures::image_view2_d_on3_d_image /// [`image_view2_d_on3_d_image`]: crate::device::DeviceFeatures::image_view2_d_on3_d_image
@ -1146,7 +1141,6 @@ vulkan_bitflags! {
/// - [`image2_d_view_of3_d`] for storage images. /// - [`image2_d_view_of3_d`] for storage images.
/// - [`sampler2_d_view_of3_d`] for sampled images. /// - [`sampler2_d_view_of3_d`] for sampled images.
/// ///
/// [`ImageViewType::Dim2d`]: crate::image::view::ImageViewType::Dim2d
/// [`DIM2D_ARRAY_COMPATIBLE`]: ImageCreateFlags::DIM2D_ARRAY_COMPATIBLE /// [`DIM2D_ARRAY_COMPATIBLE`]: ImageCreateFlags::DIM2D_ARRAY_COMPATIBLE
/// [`image2_d_view_of3_d`]: crate::device::DeviceFeatures::image2_d_view_of3_d /// [`image2_d_view_of3_d`]: crate::device::DeviceFeatures::image2_d_view_of3_d
/// [`sampler2_d_view_of3_d`]: crate::device::DeviceFeatures::sampler2_d_view_of3_d /// [`sampler2_d_view_of3_d`]: crate::device::DeviceFeatures::sampler2_d_view_of3_d
@ -1641,7 +1635,7 @@ pub struct SubresourceLayout {
} }
/// The image configuration to query in /// The image configuration to query in
/// [`PhysicalDevice::image_format_properties`](crate::device::physical::PhysicalDevice::image_format_properties). /// [`PhysicalDevice::image_format_properties`].
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ImageFormatInfo { pub struct ImageFormatInfo {
/// The `flags` that the image will have. /// The `flags` that the image will have.
@ -1983,7 +1977,7 @@ impl ImageFormatInfo {
} }
/// The image's DRM format modifier configuration to query in /// The image's DRM format modifier configuration to query in
/// [`PhysicalDevice::image_format_properties`](crate::device::physical::PhysicalDevice::image_format_properties). /// [`PhysicalDevice::image_format_properties`].
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ImageDrmFormatModifierInfo { pub struct ImageDrmFormatModifierInfo {
/// The DRM format modifier to query. /// The DRM format modifier to query.
@ -2095,13 +2089,13 @@ pub struct ImageFormatProperties {
pub external_memory_properties: ExternalMemoryProperties, pub external_memory_properties: ExternalMemoryProperties,
/// When querying with an image view type, whether such image views support sampling with /// When querying with an image view type, whether such image views support sampling with
/// a [`Cubic`](crate::image::sampler::Filter::Cubic) `mag_filter` or `min_filter`. /// a [`Cubic`](sampler::Filter::Cubic) `mag_filter` or `min_filter`.
pub filter_cubic: bool, pub filter_cubic: bool,
/// When querying with an image view type, whether such image views support sampling with /// When querying with an image view type, whether such image views support sampling with
/// a [`Cubic`](crate::image::sampler::Filter::Cubic) `mag_filter` or `min_filter`, and with a /// a [`Cubic`](sampler::Filter::Cubic) `mag_filter` or `min_filter`, and with a
/// [`Min`](crate::image::sampler::SamplerReductionMode::Min) or /// [`Min`](sampler::SamplerReductionMode::Min) or
/// [`Max`](crate::image::sampler::SamplerReductionMode::Max) `reduction_mode`. /// [`Max`](sampler::SamplerReductionMode::Max) `reduction_mode`.
pub filter_cubic_minmax: bool, pub filter_cubic_minmax: bool,
} }
@ -2126,7 +2120,7 @@ impl From<ash::vk::ImageFormatProperties> for ImageFormatProperties {
} }
/// The image configuration to query in /// The image configuration to query in
/// [`PhysicalDevice::sparse_image_format_properties`](crate::device::physical::PhysicalDevice::sparse_image_format_properties). /// [`PhysicalDevice::sparse_image_format_properties`].
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct SparseImageFormatInfo { pub struct SparseImageFormatInfo {
/// The `format` that the image will have. /// The `format` that the image will have.

View File

@ -708,8 +708,8 @@ pub struct SamplerCreateInfo {
/// - Anisotropy and depth comparison must be disabled. /// - Anisotropy and depth comparison must be disabled.
/// ///
/// Some restrictions also apply to the image view being sampled: /// Some restrictions also apply to the image view being sampled:
/// - The view type must be [`Dim1d`](crate::image::view::ImageViewType::Dim1d) or /// - The view type must be [`Dim1d`](ImageViewType::Dim1d) or [`Dim2d`](ImageViewType::Dim2d).
/// [`Dim2d`](crate::image::view::ImageViewType::Dim2d). Arrayed types are not allowed. /// Arrayed types are not allowed.
/// - It must have a single mipmap level. /// - It must have a single mipmap level.
/// ///
/// Finally, restrictions apply to the sampling operations that can be used in a shader: /// Finally, restrictions apply to the sampling operations that can be used in a shader:
@ -1323,7 +1323,7 @@ vulkan_enum! {
/// ///
/// The [`ext_filter_cubic`](crate::device::DeviceExtensions::ext_filter_cubic) extension must /// The [`ext_filter_cubic`](crate::device::DeviceExtensions::ext_filter_cubic) extension must
/// be enabled on the device, and anisotropy must be disabled. Sampled image views must have /// be enabled on the device, and anisotropy must be disabled. Sampled image views must have
/// a type of [`Dim2d`](crate::image::view::ImageViewType::Dim2d). /// a type of [`Dim2d`](ImageViewType::Dim2d).
Cubic = CUBIC_EXT Cubic = CUBIC_EXT
RequiresOneOf([ RequiresOneOf([
RequiresAllOf([DeviceExtension(ext_filter_cubic)]), RequiresAllOf([DeviceExtension(ext_filter_cubic)]),

View File

@ -1196,7 +1196,7 @@ impl RawImage {
}); });
}; };
for (info_vk, plane_info_vk) in (infos_vk.iter_mut()).zip(plane_infos_vk.iter_mut()) { for (info_vk, plane_info_vk) in infos_vk.iter_mut().zip(plane_infos_vk.iter_mut()) {
info_vk.p_next = plane_info_vk as *mut _ as *mut _; info_vk.p_next = plane_info_vk as *mut _ as *mut _;
} }

View File

@ -142,9 +142,9 @@ include!(concat!(env!("OUT_DIR"), "/instance_extensions.rs"));
/// to use when used on a particular instance or device. It is possible for the instance and the /// to use when used on a particular instance or device. It is possible for the instance and the
/// device to support different versions. The supported version for an instance can be queried /// device to support different versions. The supported version for an instance can be queried
/// before creation with /// before creation with
/// [`VulkanLibrary::api_version`](crate::VulkanLibrary::api_version), /// [`VulkanLibrary::api_version`],
/// while for a device it can be retrieved with /// while for a device it can be retrieved with
/// [`PhysicalDevice::api_version`](crate::device::physical::PhysicalDevice::api_version). /// [`PhysicalDevice::api_version`].
/// ///
/// When creating an `Instance`, you have to specify a maximum API version that you will use. /// When creating an `Instance`, you have to specify a maximum API version that you will use.
/// This restricts the API version that is available for the instance and any devices created from /// This restricts the API version that is available for the instance and any devices created from
@ -210,7 +210,7 @@ include!(concat!(env!("OUT_DIR"), "/instance_extensions.rs"));
/// ///
/// When creating an `Instance`, you have the possibility to pass a list of **layers** that will /// When creating an `Instance`, you have the possibility to pass a list of **layers** that will
/// be activated on the newly-created instance. The list of available layers can be retrieved by /// be activated on the newly-created instance. The list of available layers can be retrieved by
/// calling the [`layer_properties`](crate::VulkanLibrary::layer_properties) method of /// calling the [`layer_properties`](VulkanLibrary::layer_properties) method of
/// `VulkanLibrary`. /// `VulkanLibrary`.
/// ///
/// A layer is a component that will hook and potentially modify the Vulkan function calls. /// A layer is a component that will hook and potentially modify the Vulkan function calls.
@ -592,7 +592,7 @@ impl Instance {
/// Returns the Vulkan version supported by the instance. /// Returns the Vulkan version supported by the instance.
/// ///
/// This is the lower of the /// This is the lower of the
/// [driver's supported version](crate::VulkanLibrary::api_version) and /// [driver's supported version](VulkanLibrary::api_version) and
/// [`max_api_version`](Instance::max_api_version). /// [`max_api_version`](Instance::max_api_version).
#[inline] #[inline]
pub fn api_version(&self) -> Version { pub fn api_version(&self) -> Version {
@ -952,7 +952,7 @@ pub struct InstanceCreateInfo {
/// to use during the creation and destruction of the instance. /// to use during the creation and destruction of the instance.
/// ///
/// The debug messengers are not used at any other time, /// The debug messengers are not used at any other time,
/// [`DebugUtilsMessenger`](crate::instance::debug::DebugUtilsMessenger) should be used for /// [`DebugUtilsMessenger`](debug::DebugUtilsMessenger) should be used for
/// that. /// that.
/// ///
/// If this is not empty, the `ext_debug_utils` extension must be set in `enabled_extensions`. /// If this is not empty, the `ext_debug_utils` extension must be set in `enabled_extensions`.

View File

@ -40,7 +40,7 @@
//! of the surface change, such as when the size of the window changes. It then becomes //! of the surface change, such as when the size of the window changes. It then becomes
//! necessary to create a new swapchain. //! necessary to create a new swapchain.
//! //!
//! 8. Record a [*command buffer*](crate::command_buffer), containing commands that the device must //! 8. Record a [*command buffer*](command_buffer), containing commands that the device must
//! execute. Then build the command buffer and submit it to a `Queue`. //! execute. Then build the command buffer and submit it to a `Queue`.
//! //!
//! Many different operations can be recorded to a command buffer, such as *draw*, *compute* and //! Many different operations can be recorded to a command buffer, such as *draw*, *compute* and
@ -97,27 +97,26 @@
//! | `document_unchecked` | Include `_unchecked` functions in the generated documentation. | //! | `document_unchecked` | Include `_unchecked` functions in the generated documentation. |
//! | `serde` | Enables (de)serialization of certain types using [`serde`]. | //! | `serde` | Enables (de)serialization of certain types using [`serde`]. |
//! //!
//! [`VulkanLibrary`]: crate::VulkanLibrary //! [`Instance`]: instance::Instance
//! [`Instance`]: crate::instance::Instance //! [`Surface`]: swapchain::Surface
//! [`Surface`]: crate::swapchain::Surface
//! [`vulkano-win`]: https://crates.io/crates/vulkano-win //! [`vulkano-win`]: https://crates.io/crates/vulkano-win
//! [Enumerate the physical devices]: crate::instance::Instance::enumerate_physical_devices //! [Enumerate the physical devices]: instance::Instance::enumerate_physical_devices
//! [`PhysicalDevice`]: crate::device::physical::PhysicalDevice //! [`PhysicalDevice`]: device::physical::PhysicalDevice
//! [`Device`]: crate::device::Device //! [`Device`]: device::Device
//! [`Queue`]: crate::device::Queue //! [`Queue`]: device::Queue
//! [`Swapchain`]: crate::swapchain::Swapchain //! [`Swapchain`]: swapchain::Swapchain
//! [*command buffer*]: crate::command_buffer //! [*command buffer*]: command_buffer
//! [*Buffers*]: crate::buffer //! [*Buffers*]: buffer
//! [*Images*]: crate::image //! [*Images*]: image
//! [*Pipelines*]: crate::pipeline //! [*Pipelines*]: pipeline
//! [*shader*]: crate::shader //! [*shader*]: shader
//! [`ComputePipeline`]: crate::pipeline::ComputePipeline //! [`ComputePipeline`]: pipeline::ComputePipeline
//! [`GraphicsPipeline`]: crate::pipeline::GraphicsPipeline //! [`GraphicsPipeline`]: pipeline::GraphicsPipeline
//! [*Descriptor sets*]: crate::descriptor_set //! [*Descriptor sets*]: descriptor_set
//! [`DescriptorSetLayout`]: crate::descriptor_set::layout //! [`DescriptorSetLayout`]: descriptor_set::layout
//! [`PipelineLayout`]: crate::pipeline::layout //! [`PipelineLayout`]: pipeline::layout
//! [`RenderPass`]: crate::render_pass::RenderPass //! [`RenderPass`]: render_pass::RenderPass
//! [`Framebuffer`]: crate::render_pass::Framebuffer //! [`Framebuffer`]: render_pass::Framebuffer
//! [`vulkano-macros`]: vulkano_macros //! [`vulkano-macros`]: vulkano_macros
//! [`serde`]: https://crates.io/crates/serde //! [`serde`]: https://crates.io/crates/serde
@ -252,7 +251,7 @@ unsafe impl<T: ?Sized> SafeDeref for Box<T> {}
/// Gives access to the internal identifier of an object. /// Gives access to the internal identifier of an object.
pub unsafe trait VulkanObject { pub unsafe trait VulkanObject {
/// The type of the object. /// The type of the object.
type Handle: ash::vk::Handle; type Handle: Handle;
/// Returns the raw Vulkan handle of the object. /// Returns the raw Vulkan handle of the object.
fn handle(&self) -> Self::Handle; fn handle(&self) -> Self::Handle;

View File

@ -204,7 +204,6 @@
//! [buffer-image granularity]: crate::device::DeviceProperties::buffer_image_granularity //! [buffer-image granularity]: crate::device::DeviceProperties::buffer_image_granularity
//! [cyclic references]: Arc#breaking-cycles-with-weak //! [cyclic references]: Arc#breaking-cycles-with-weak
//! [`Rc`]: std::rc::Rc //! [`Rc`]: std::rc::Rc
//! [`mem::forget`]: std::mem::forget
//! [region]: Suballocator#regions //! [region]: Suballocator#regions
mod layout; mod layout;

View File

@ -372,13 +372,13 @@ mod tests {
assert!(allocator assert!(allocator
.allocate(DUMMY_LAYOUT, AllocationType::Unknown, DeviceAlignment::MIN) .allocate(DUMMY_LAYOUT, AllocationType::Unknown, DeviceAlignment::MIN)
.is_err()); .is_err());
assert!(allocator.free_size() == 0); assert_eq!(allocator.free_size(), 0);
for alloc in allocs { for alloc in allocs {
unsafe { allocator.deallocate(alloc) }; unsafe { allocator.deallocate(alloc) };
} }
assert!(allocator.free_size() == REGION_SIZE); assert_eq!(allocator.free_size(), REGION_SIZE);
let alloc = allocator let alloc = allocator
.allocate( .allocate(
DeviceLayout::from_size_alignment(REGION_SIZE, 1).unwrap(), DeviceLayout::from_size_alignment(REGION_SIZE, 1).unwrap(),
@ -408,7 +408,7 @@ mod tests {
assert!(allocator assert!(allocator
.allocate(LAYOUT, AllocationType::Unknown, DeviceAlignment::MIN) .allocate(LAYOUT, AllocationType::Unknown, DeviceAlignment::MIN)
.is_err()); .is_err());
assert!(allocator.free_size() == REGION_SIZE - 10); assert_eq!(allocator.free_size(), REGION_SIZE - 10);
for alloc in allocs.drain(..) { for alloc in allocs.drain(..) {
unsafe { allocator.deallocate(alloc) }; unsafe { allocator.deallocate(alloc) };
@ -443,7 +443,7 @@ mod tests {
assert!(allocator assert!(allocator
.allocate(DUMMY_LAYOUT, AllocationType::Linear, GRANULARITY) .allocate(DUMMY_LAYOUT, AllocationType::Linear, GRANULARITY)
.is_err()); .is_err());
assert!(allocator.free_size() == 0); assert_eq!(allocator.free_size(), 0);
for alloc in linear_allocs.drain(..) { for alloc in linear_allocs.drain(..) {
unsafe { allocator.deallocate(alloc) }; unsafe { allocator.deallocate(alloc) };
@ -498,7 +498,7 @@ mod tests {
assert!(allocator assert!(allocator
.allocate(DUMMY_LAYOUT, AllocationType::Unknown, DeviceAlignment::MIN) .allocate(DUMMY_LAYOUT, AllocationType::Unknown, DeviceAlignment::MIN)
.is_err()); .is_err());
assert!(allocator.free_size() == 0); assert_eq!(allocator.free_size(), 0);
for alloc in allocs.drain(..) { for alloc in allocs.drain(..) {
unsafe { allocator.deallocate(alloc) }; unsafe { allocator.deallocate(alloc) };
@ -528,7 +528,7 @@ mod tests {
assert!(allocator assert!(allocator
.allocate(DUMMY_LAYOUT, AllocationType::Unknown, DeviceAlignment::MIN) .allocate(DUMMY_LAYOUT, AllocationType::Unknown, DeviceAlignment::MIN)
.is_err()); .is_err());
assert!(allocator.free_size() == 0); assert_eq!(allocator.free_size(), 0);
unsafe { allocator.deallocate(alloc) }; unsafe { allocator.deallocate(alloc) };
for alloc in allocs.drain(..) { for alloc in allocs.drain(..) {
@ -552,7 +552,10 @@ mod tests {
assert!(allocator assert!(allocator
.allocate(layout, AllocationType::Unknown, DeviceAlignment::MIN) .allocate(layout, AllocationType::Unknown, DeviceAlignment::MIN)
.is_err()); .is_err());
assert!(allocator.free_size() == REGION_SIZE - BuddyAllocator::MIN_NODE_SIZE); assert_eq!(
allocator.free_size(),
REGION_SIZE - BuddyAllocator::MIN_NODE_SIZE,
);
unsafe { allocator.deallocate(alloc) }; unsafe { allocator.deallocate(alloc) };
} }
@ -576,9 +579,9 @@ mod tests {
assert!(allocator assert!(allocator
.allocate(layout_a, AllocationType::Unknown, DeviceAlignment::MIN) .allocate(layout_a, AllocationType::Unknown, DeviceAlignment::MIN)
.is_err()); .is_err());
assert!( assert_eq!(
allocator.free_size() allocator.free_size(),
== REGION_SIZE - allocations_a * BuddyAllocator::MIN_NODE_SIZE REGION_SIZE - allocations_a * BuddyAllocator::MIN_NODE_SIZE,
); );
for _ in 0..allocations_b { for _ in 0..allocations_b {
@ -592,7 +595,7 @@ mod tests {
assert!(allocator assert!(allocator
.allocate(DUMMY_LAYOUT, AllocationType::Unknown, DeviceAlignment::MIN) .allocate(DUMMY_LAYOUT, AllocationType::Unknown, DeviceAlignment::MIN)
.is_err()); .is_err());
assert!(allocator.free_size() == 0); assert_eq!(allocator.free_size(), 0);
for alloc in allocs { for alloc in allocs {
unsafe { allocator.deallocate(alloc) }; unsafe { allocator.deallocate(alloc) };
@ -623,7 +626,7 @@ mod tests {
assert!(allocator assert!(allocator
.allocate(DUMMY_LAYOUT, AllocationType::Linear, GRANULARITY) .allocate(DUMMY_LAYOUT, AllocationType::Linear, GRANULARITY)
.is_err()); .is_err());
assert!(allocator.free_size() == 0); assert_eq!(allocator.free_size(), 0);
for alloc in allocs { for alloc in allocs {
unsafe { allocator.deallocate(alloc) }; unsafe { allocator.deallocate(alloc) };
@ -640,7 +643,7 @@ mod tests {
assert!(allocator assert!(allocator
.allocate(DUMMY_LAYOUT, AllocationType::Linear, GRANULARITY) .allocate(DUMMY_LAYOUT, AllocationType::Linear, GRANULARITY)
.is_err()); .is_err());
assert!(allocator.free_size() == 0); assert_eq!(allocator.free_size(), 0);
unsafe { allocator.deallocate(alloc1) }; unsafe { allocator.deallocate(alloc1) };
unsafe { allocator.deallocate(alloc2) }; unsafe { allocator.deallocate(alloc2) };
} }
@ -673,10 +676,10 @@ mod tests {
assert!(allocator assert!(allocator
.allocate(layout, AllocationType::Unknown, DeviceAlignment::MIN) .allocate(layout, AllocationType::Unknown, DeviceAlignment::MIN)
.is_err()); .is_err());
assert!(allocator.free_size() == 0); assert_eq!(allocator.free_size(), 0);
allocator.reset(); allocator.reset();
assert!(allocator.free_size() == REGION_SIZE); assert_eq!(allocator.free_size(), REGION_SIZE);
} }
#[test] #[test]
@ -706,7 +709,7 @@ mod tests {
assert!(allocator assert!(allocator
.allocate(DUMMY_LAYOUT, AllocationType::Linear, GRANULARITY) .allocate(DUMMY_LAYOUT, AllocationType::Linear, GRANULARITY)
.is_err()); .is_err());
assert!(allocator.free_size() == 0); assert_eq!(allocator.free_size(), 0);
allocator.reset(); allocator.reset();
@ -727,9 +730,9 @@ mod tests {
assert!(allocator assert!(allocator
.allocate(DUMMY_LAYOUT, AllocationType::Linear, GRANULARITY) .allocate(DUMMY_LAYOUT, AllocationType::Linear, GRANULARITY)
.is_err()); .is_err());
assert!(allocator.free_size() == GRANULARITY.as_devicesize() - 1); assert_eq!(allocator.free_size(), GRANULARITY.as_devicesize() - 1);
allocator.reset(); allocator.reset();
assert!(allocator.free_size() == REGION_SIZE); assert_eq!(allocator.free_size(), REGION_SIZE);
} }
} }

View File

@ -589,7 +589,7 @@ impl DeviceMemory {
/// cache, then there must not be any references in Rust code to any portion of the specified /// cache, then there must not be any references in Rust code to any portion of the specified
/// `memory_range`. /// `memory_range`.
/// ///
/// [host-coherent]: crate::memory::MemoryPropertyFlags::HOST_COHERENT /// [host-coherent]: MemoryPropertyFlags::HOST_COHERENT
/// [`map`]: Self::map /// [`map`]: Self::map
/// [`non_coherent_atom_size`]: crate::device::DeviceProperties::non_coherent_atom_size /// [`non_coherent_atom_size`]: crate::device::DeviceProperties::non_coherent_atom_size
#[inline] #[inline]
@ -644,7 +644,7 @@ impl DeviceMemory {
/// - There must be no operations pending or executing in a device queue, that access the /// - There must be no operations pending or executing in a device queue, that access the
/// specified `memory_range`. /// specified `memory_range`.
/// ///
/// [host-coherent]: crate::memory::MemoryPropertyFlags::HOST_COHERENT /// [host-coherent]: MemoryPropertyFlags::HOST_COHERENT
/// [`map`]: Self::map /// [`map`]: Self::map
/// [`non_coherent_atom_size`]: crate::device::DeviceProperties::non_coherent_atom_size /// [`non_coherent_atom_size`]: crate::device::DeviceProperties::non_coherent_atom_size
#[inline] #[inline]
@ -711,7 +711,7 @@ impl DeviceMemory {
/// `self` must have been allocated from a memory type that has the [`LAZILY_ALLOCATED`] flag /// `self` must have been allocated from a memory type that has the [`LAZILY_ALLOCATED`] flag
/// set. /// set.
/// ///
/// [`LAZILY_ALLOCATED`]: crate::memory::MemoryPropertyFlags::LAZILY_ALLOCATED /// [`LAZILY_ALLOCATED`]: MemoryPropertyFlags::LAZILY_ALLOCATED
#[inline] #[inline]
pub fn commitment(&self) -> Result<DeviceSize, Box<ValidationError>> { pub fn commitment(&self) -> Result<DeviceSize, Box<ValidationError>> {
self.validate_commitment()?; self.validate_commitment()?;

View File

@ -121,7 +121,7 @@ mod device_memory;
/// block of `DeviceMemory` to a resource, or can't go through an allocator, you can use [the /// block of `DeviceMemory` to a resource, or can't go through an allocator, you can use [the
/// dedicated constructor]. /// dedicated constructor].
/// ///
/// [memory allocator]: allocator::MemoryAllocator /// [memory allocator]: MemoryAllocator
/// [the dedicated constructor]: Self::new_dedicated /// [the dedicated constructor]: Self::new_dedicated
#[derive(Debug)] #[derive(Debug)]
pub struct ResourceMemory { pub struct ResourceMemory {
@ -251,8 +251,6 @@ impl ResourceMemory {
/// range of the memory mapping given to [`DeviceMemory::map`]. /// range of the memory mapping given to [`DeviceMemory::map`].
/// ///
/// See [`MappingState::slice`] for the safety invariants of the returned pointer. /// See [`MappingState::slice`] for the safety invariants of the returned pointer.
///
/// [`MappingState::slice`]: crate::memory::MappingState::slice
#[inline] #[inline]
pub fn mapped_slice( pub fn mapped_slice(
&self, &self,
@ -277,7 +275,7 @@ impl ResourceMemory {
&self, &self,
range: impl RangeBounds<DeviceSize>, range: impl RangeBounds<DeviceSize>,
) -> Result<NonNull<[u8]>, HostAccessError> { ) -> Result<NonNull<[u8]>, HostAccessError> {
let mut range = self::range_unchecked(range, ..self.size()); let mut range = range_unchecked(range, ..self.size());
range.start += self.offset(); range.start += self.offset();
range.end += self.offset(); range.end += self.offset();
@ -306,7 +304,7 @@ impl ResourceMemory {
/// cache, then there must not be any references in Rust code to any portion of the specified /// cache, then there must not be any references in Rust code to any portion of the specified
/// `memory_range`. /// `memory_range`.
/// ///
/// [host-coherent]: crate::memory::MemoryPropertyFlags::HOST_COHERENT /// [host-coherent]: MemoryPropertyFlags::HOST_COHERENT
/// [`non_coherent_atom_size`]: crate::device::DeviceProperties::non_coherent_atom_size /// [`non_coherent_atom_size`]: crate::device::DeviceProperties::non_coherent_atom_size
#[inline] #[inline]
pub unsafe fn invalidate_range( pub unsafe fn invalidate_range(
@ -340,7 +338,7 @@ impl ResourceMemory {
/// - There must be no operations pending or executing in a device queue, that access any /// - There must be no operations pending or executing in a device queue, that access any
/// portion of the specified `memory_range`. /// portion of the specified `memory_range`.
/// ///
/// [host-coherent]: crate::memory::MemoryPropertyFlags::HOST_COHERENT /// [host-coherent]: MemoryPropertyFlags::HOST_COHERENT
/// [`non_coherent_atom_size`]: crate::device::DeviceProperties::non_coherent_atom_size /// [`non_coherent_atom_size`]: crate::device::DeviceProperties::non_coherent_atom_size
#[inline] #[inline]
pub unsafe fn flush_range( pub unsafe fn flush_range(
@ -538,8 +536,8 @@ vulkan_bitflags! {
/// Host access to the memory does not require calling [`invalidate_range`] to make device /// Host access to the memory does not require calling [`invalidate_range`] to make device
/// writes visible to the host, nor [`flush_range`] to flush host writes back to the device. /// writes visible to the host, nor [`flush_range`] to flush host writes back to the device.
/// ///
/// [`invalidate_range`]: MappedDeviceMemory::invalidate_range /// [`invalidate_range`]: DeviceMemory::invalidate_range
/// [`flush_range`]: MappedDeviceMemory::flush_range /// [`flush_range`]: DeviceMemory::flush_range
HOST_COHERENT = HOST_COHERENT, HOST_COHERENT = HOST_COHERENT,
/// The memory is cached by the host. /// The memory is cached by the host.

View File

@ -9,8 +9,8 @@
//! doesn't exist. //! doesn't exist.
//! //!
//! Once that is done, you can extract the data from the cache and store it. See the documentation //! Once that is done, you can extract the data from the cache and store it. See the documentation
//! of [`get_data`](crate::pipeline::cache::PipelineCache::get_data) for example of how to store //! of [`get_data`](PipelineCache::get_data) for example of how to store
//! the data on the disk, and [`new`](crate::pipeline::cache::PipelineCache::new) for how to reload //! the data on the disk, and [`new`](PipelineCache::new) for how to reload
//! it. //! it.
use crate::{ use crate::{

View File

@ -306,7 +306,7 @@ impl GraphicsPipeline {
specialization_data_vk, specialization_data_vk,
required_subgroup_size_create_info, required_subgroup_size_create_info,
}, },
) in (stages_vk.iter_mut()).zip(per_stage_vk.iter_mut()) ) in stages_vk.iter_mut().zip(per_stage_vk.iter_mut())
{ {
*stage_vk = ash::vk::PipelineShaderStageCreateInfo { *stage_vk = ash::vk::PipelineShaderStageCreateInfo {
p_next: required_subgroup_size_create_info.as_ref().map_or( p_next: required_subgroup_size_create_info.as_ref().map_or(

View File

@ -85,19 +85,25 @@ impl PipelineRenderingCreateInfo {
Self { Self {
view_mask: subpass_desc.view_mask, view_mask: subpass_desc.view_mask,
color_attachment_formats: (subpass_desc.color_attachments.iter()) color_attachment_formats: subpass_desc
.color_attachments
.iter()
.map(|color_attachment| { .map(|color_attachment| {
color_attachment.as_ref().map(|color_attachment| { color_attachment.as_ref().map(|color_attachment| {
rp_attachments[color_attachment.attachment as usize].format rp_attachments[color_attachment.attachment as usize].format
}) })
}) })
.collect(), .collect(),
depth_attachment_format: (subpass_desc.depth_stencil_attachment.as_ref()) depth_attachment_format: subpass_desc
.depth_stencil_attachment
.as_ref()
.map(|depth_stencil_attachment| { .map(|depth_stencil_attachment| {
rp_attachments[depth_stencil_attachment.attachment as usize].format rp_attachments[depth_stencil_attachment.attachment as usize].format
}) })
.filter(|format| format.aspects().intersects(ImageAspects::DEPTH)), .filter(|format| format.aspects().intersects(ImageAspects::DEPTH)),
stencil_attachment_format: (subpass_desc.depth_stencil_attachment.as_ref()) stencil_attachment_format: subpass_desc
.depth_stencil_attachment
.as_ref()
.map(|depth_stencil_attachment| { .map(|depth_stencil_attachment| {
rp_attachments[depth_stencil_attachment.attachment as usize].format rp_attachments[depth_stencil_attachment.attachment as usize].format
}) })
@ -109,16 +115,22 @@ impl PipelineRenderingCreateInfo {
pub(crate) fn from_rendering_info(info: &RenderingInfo) -> Self { pub(crate) fn from_rendering_info(info: &RenderingInfo) -> Self {
Self { Self {
view_mask: info.view_mask, view_mask: info.view_mask,
color_attachment_formats: (info.color_attachments.iter()) color_attachment_formats: info
.color_attachments
.iter()
.map(|atch_info| { .map(|atch_info| {
atch_info atch_info
.as_ref() .as_ref()
.map(|atch_info| atch_info.image_view.format()) .map(|atch_info| atch_info.image_view.format())
}) })
.collect(), .collect(),
depth_attachment_format: (info.depth_attachment.as_ref()) depth_attachment_format: info
.depth_attachment
.as_ref()
.map(|atch_info| atch_info.image_view.format()), .map(|atch_info| atch_info.image_view.format()),
stencil_attachment_format: (info.stencil_attachment.as_ref()) stencil_attachment_format: info
.stencil_attachment
.as_ref()
.map(|atch_info| atch_info.image_view.format()), .map(|atch_info| atch_info.image_view.format()),
_ne: crate::NonExhaustive(()), _ne: crate::NonExhaustive(()),
} }

View File

@ -23,8 +23,14 @@ impl<T: ?Sized> VertexBuffersCollection for Subbuffer<T> {
impl<T: ?Sized> VertexBuffersCollection for Vec<Subbuffer<T>> { impl<T: ?Sized> VertexBuffersCollection for Vec<Subbuffer<T>> {
fn into_vec(self) -> Vec<Subbuffer<[u8]>> { fn into_vec(self) -> Vec<Subbuffer<[u8]>> {
assert!(mem::size_of::<Subbuffer<T>>() == mem::size_of::<Subbuffer<[u8]>>()); assert_eq!(
assert!(mem::align_of::<Subbuffer<T>>() == mem::align_of::<Subbuffer<[u8]>>()); mem::size_of::<Subbuffer<T>>(),
mem::size_of::<Subbuffer<[u8]>>(),
);
assert_eq!(
mem::align_of::<Subbuffer<T>>(),
mem::align_of::<Subbuffer<[u8]>>(),
);
// SAFETY: All `Subbuffer`s share the same layout. // SAFETY: All `Subbuffer`s share the same layout.
unsafe { mem::transmute::<Vec<Subbuffer<T>>, Vec<Subbuffer<[u8]>>>(self) } unsafe { mem::transmute::<Vec<Subbuffer<T>>, Vec<Subbuffer<[u8]>>>(self) }

View File

@ -334,30 +334,32 @@ impl VertexInputState {
vuids: RequiredVertexInputsVUIDs, vuids: RequiredVertexInputsVUIDs,
) -> Result<(), Box<ValidationError>> { ) -> Result<(), Box<ValidationError>> {
for (&location, location_info) in vertex_shader_inputs { for (&location, location_info) in vertex_shader_inputs {
let (is_previous, attribute_desc) = let (is_previous, attribute_desc) = self
(self.attributes.get(&location).map(|d| (false, d))) .attributes
.or_else(|| { .get(&location)
// If the previous location has at least three 64-bit components, .map(|d| (false, d))
// then it extends into the current location, so try that instead. .or_else(|| {
location.checked_sub(1).and_then(|location| { // If the previous location has at least three 64-bit components,
self.attributes // then it extends into the current location, so try that instead.
.get(&location) location.checked_sub(1).and_then(|location| {
.filter(|attribute_desc| attribute_desc.format.locations() == 2) self.attributes
.map(|d| (true, d)) .get(&location)
}) .filter(|attribute_desc| attribute_desc.format.locations() == 2)
.map(|d| (true, d))
}) })
.ok_or_else(|| { })
Box::new(ValidationError { .ok_or_else(|| {
problem: format!( Box::new(ValidationError {
"the vertex shader has an input variable with location {0}, but \ problem: format!(
the vertex input attributes do not contain {0}", "the vertex shader has an input variable with location {0}, but \
location, the vertex input attributes do not contain {0}",
) location,
.into(), )
vuids: vuids.not_present, .into(),
..Default::default() vuids: vuids.not_present,
}) ..Default::default()
})?; })
})?;
let attribute_numeric_type = attribute_desc let attribute_numeric_type = attribute_desc
.format .format

View File

@ -154,7 +154,8 @@ impl ViewportState {
// VUID-VkPipelineViewportStateCreateInfo-x-02821 // VUID-VkPipelineViewportStateCreateInfo-x-02821
// Ensured by the use of an unsigned integer. // Ensured by the use of an unsigned integer.
if (i32::try_from(offset[0]).ok()) if i32::try_from(offset[0])
.ok()
.zip(i32::try_from(extent[0]).ok()) .zip(i32::try_from(extent[0]).ok())
.and_then(|(o, e)| o.checked_add(e)) .and_then(|(o, e)| o.checked_add(e))
.is_none() .is_none()
@ -167,7 +168,8 @@ impl ViewportState {
})); }));
} }
if (i32::try_from(offset[1]).ok()) if i32::try_from(offset[1])
.ok()
.zip(i32::try_from(extent[1]).ok()) .zip(i32::try_from(extent[1]).ok())
.and_then(|(o, e)| o.checked_add(e)) .and_then(|(o, e)| o.checked_add(e))
.is_none() .is_none()

View File

@ -336,7 +336,7 @@ vulkan_enum! {
DepthBias = DEPTH_BIAS, DepthBias = DEPTH_BIAS,
/// The value of /// The value of
/// [`ColorBlendState::blend_constants`](crate::pipeline::graphics::color_blend::ColorBlendState::blend_constants). /// [`ColorBlendState::blend_constants`](graphics::color_blend::ColorBlendState::blend_constants).
/// ///
/// Set with /// Set with
/// [`set_blend_constants`](crate::command_buffer::RecordingCommandBuffer::set_blend_constants). /// [`set_blend_constants`](crate::command_buffer::RecordingCommandBuffer::set_blend_constants).
@ -374,7 +374,7 @@ vulkan_enum! {
StencilReference = STENCIL_REFERENCE, StencilReference = STENCIL_REFERENCE,
/// The value of /// The value of
/// [`RasterizationState::cull_mode`](crate::pipeline::graphics::rasterization::RasterizationState::cull_mode). /// [`RasterizationState::cull_mode`](graphics::rasterization::RasterizationState::cull_mode).
/// ///
/// Set with /// Set with
/// [`set_cull_mode`](crate::command_buffer::RecordingCommandBuffer::set_cull_mode). /// [`set_cull_mode`](crate::command_buffer::RecordingCommandBuffer::set_cull_mode).
@ -385,7 +385,7 @@ vulkan_enum! {
]), ]),
/// The value of /// The value of
/// [`RasterizationState::front_face`](crate::pipeline::graphics::rasterization::RasterizationState::front_face). /// [`RasterizationState::front_face`](graphics::rasterization::RasterizationState::front_face).
/// ///
/// Set with /// Set with
/// [`set_front_face`](crate::command_buffer::RecordingCommandBuffer::set_front_face). /// [`set_front_face`](crate::command_buffer::RecordingCommandBuffer::set_front_face).
@ -396,7 +396,7 @@ vulkan_enum! {
]), ]),
/// The value of /// The value of
/// [`InputAssemblyState::topology`](crate::pipeline::graphics::input_assembly::InputAssemblyState::topology). /// [`InputAssemblyState::topology`](graphics::input_assembly::InputAssemblyState::topology).
/// ///
/// Set with /// Set with
/// [`set_primitive_topology`](crate::command_buffer::RecordingCommandBuffer::set_primitive_topology). /// [`set_primitive_topology`](crate::command_buffer::RecordingCommandBuffer::set_primitive_topology).
@ -526,7 +526,7 @@ vulkan_enum! {
]), ]),
/// The value of /// The value of
/// [`InputAssemblyState::primitive_restart_enable`](crate::pipeline::graphics::input_assembly::InputAssemblyState::primitive_restart_enable). /// [`InputAssemblyState::primitive_restart_enable`](graphics::input_assembly::InputAssemblyState::primitive_restart_enable).
/// ///
/// Set with /// Set with
/// [`set_primitive_restart_enable`](crate::command_buffer::RecordingCommandBuffer::set_primitive_restart_enable). /// [`set_primitive_restart_enable`](crate::command_buffer::RecordingCommandBuffer::set_primitive_restart_enable).
@ -616,7 +616,7 @@ vulkan_enum! {
]), ]),
/// The value of /// The value of
/// [`TessellationState::patch_control_points`](crate::pipeline::graphics::tessellation::TessellationState::patch_control_points). /// [`TessellationState::patch_control_points`](graphics::tessellation::TessellationState::patch_control_points).
/// ///
/// Set with /// Set with
/// [`set_patch_control_points`](crate::command_buffer::RecordingCommandBuffer::set_patch_control_points). /// [`set_patch_control_points`](crate::command_buffer::RecordingCommandBuffer::set_patch_control_points).
@ -626,7 +626,7 @@ vulkan_enum! {
]), ]),
/// The value of /// The value of
/// [`ColorBlendState::logic_op`](crate::pipeline::graphics::color_blend::ColorBlendState::logic_op). /// [`ColorBlendState::logic_op`](graphics::color_blend::ColorBlendState::logic_op).
/// ///
/// Set with /// Set with
/// [`set_logic_op`](crate::command_buffer::RecordingCommandBuffer::set_logic_op). /// [`set_logic_op`](crate::command_buffer::RecordingCommandBuffer::set_logic_op).

View File

@ -388,7 +388,9 @@ fn are_interface_types_compatible(
}, },
) => { ) => {
out_member_types.len() == in_member_types.len() out_member_types.len() == in_member_types.len()
&& (out_member_types.iter().zip(out_id_info.members())) && out_member_types
.iter()
.zip(out_id_info.members())
.zip(in_member_types.iter().zip(in_id_info.members())) .zip(in_member_types.iter().zip(in_id_info.members()))
.all( .all(
|( |(

View File

@ -340,71 +340,72 @@ impl PipelineShaderStageCreateInfo {
} }
} }
let local_size = (spirv let local_size =
.decorations() spirv
.iter() .decorations()
.find_map(|instruction| match *instruction {
Instruction::Decorate {
target,
decoration:
Decoration::BuiltIn {
built_in: BuiltIn::WorkgroupSize,
},
} => {
let constituents: &[Id; 3] = match *spirv.id(target).instruction() {
Instruction::ConstantComposite {
ref constituents, ..
} => constituents.as_slice().try_into().unwrap(),
_ => unreachable!(),
};
let local_size = constituents.map(|id| match *spirv.id(id).instruction() {
Instruction::Constant { ref value, .. } => {
assert!(value.len() == 1);
value[0]
}
_ => unreachable!(),
});
Some(local_size)
}
_ => None,
}))
.or_else(|| {
entry_point_function
.execution_modes()
.iter() .iter()
.find_map(|instruction| match *instruction { .find_map(|instruction| match *instruction {
Instruction::ExecutionMode { Instruction::Decorate {
mode: target,
ExecutionMode::LocalSize { decoration:
x_size, Decoration::BuiltIn {
y_size, built_in: BuiltIn::WorkgroupSize,
z_size,
}, },
.. } => {
} => Some([x_size, y_size, z_size]), let constituents: &[Id; 3] = match *spirv.id(target).instruction() {
Instruction::ExecutionModeId { Instruction::ConstantComposite {
mode: ref constituents, ..
ExecutionMode::LocalSizeId { } => constituents.as_slice().try_into().unwrap(),
x_size, _ => unreachable!(),
y_size, };
z_size,
}, let local_size = constituents.map(|id| match *spirv.id(id).instruction() {
..
} => Some([x_size, y_size, z_size].map(
|id| match *spirv.id(id).instruction() {
Instruction::Constant { ref value, .. } => { Instruction::Constant { ref value, .. } => {
assert!(value.len() == 1); assert!(value.len() == 1);
value[0] value[0]
} }
_ => unreachable!(), _ => unreachable!(),
}, });
)),
Some(local_size)
}
_ => None, _ => None,
}) })
}) .or_else(|| {
.unwrap_or_default(); entry_point_function
.execution_modes()
.iter()
.find_map(|instruction| match *instruction {
Instruction::ExecutionMode {
mode:
ExecutionMode::LocalSize {
x_size,
y_size,
z_size,
},
..
} => Some([x_size, y_size, z_size]),
Instruction::ExecutionModeId {
mode:
ExecutionMode::LocalSizeId {
x_size,
y_size,
z_size,
},
..
} => Some([x_size, y_size, z_size].map(|id| {
match *spirv.id(id).instruction() {
Instruction::Constant { ref value, .. } => {
assert_eq!(value.len(), 1);
value[0]
}
_ => unreachable!(),
}
})),
_ => None,
})
})
.unwrap_or_default();
let workgroup_size = local_size let workgroup_size = local_size
.into_iter() .into_iter()
.try_fold(1, u32::checked_mul) .try_fold(1, u32::checked_mul)

View File

@ -1944,15 +1944,18 @@ impl<'a> RuntimeValidator<'a> {
for instruction in self.spirv.function(function).instructions() { for instruction in self.spirv.function(function).instructions() {
if let Some(pointer) = instruction.atomic_pointer_id() { if let Some(pointer) = instruction.atomic_pointer_id() {
let (storage_class, ty) = let (storage_class, ty) = match self
match (self.spirv.id(pointer).instruction().result_type_id()) .spirv
.map(|id| self.spirv.id(id).instruction()) .id(pointer)
{ .instruction()
Some(&Instruction::TypePointer { .result_type_id()
storage_class, ty, .. .map(|id| self.spirv.id(id).instruction())
}) => (storage_class, ty), {
_ => unreachable!(), Some(&Instruction::TypePointer {
}; storage_class, ty, ..
}) => (storage_class, ty),
_ => unreachable!(),
};
match *self.spirv.id(ty).instruction() { match *self.spirv.id(ty).instruction() {
Instruction::TypeInt { width: 64, .. } => match storage_class { Instruction::TypeInt { width: 64, .. } => match storage_class {
@ -2462,9 +2465,10 @@ impl<'a> RuntimeValidator<'a> {
if instruction.is_image_gather() { if instruction.is_image_gather() {
if let Some(image_operands) = instruction.image_operands() { if let Some(image_operands) = instruction.image_operands() {
if let Some(components) = if let Some(components) = image_operands
(image_operands.const_offset.or(image_operands.offset)) .const_offset
.and_then(|offset| get_constant_maybe_composite(self.spirv, offset)) .or(image_operands.offset)
.and_then(|offset| get_constant_maybe_composite(self.spirv, offset))
{ {
for offset in components { for offset in components {
if offset < properties.min_texel_gather_offset as u64 { if offset < properties.min_texel_gather_offset as u64 {
@ -2528,7 +2532,8 @@ impl<'a> RuntimeValidator<'a> {
if instruction.is_image_sample() || instruction.is_image_fetch() { if instruction.is_image_sample() || instruction.is_image_fetch() {
if let Some(image_operands) = instruction.image_operands() { if let Some(image_operands) = instruction.image_operands() {
if let Some(components) = (image_operands.const_offset) if let Some(components) = image_operands
.const_offset
.and_then(|offset| get_constant_maybe_composite(self.spirv, offset)) .and_then(|offset| get_constant_maybe_composite(self.spirv, offset))
{ {
for offset in components { for offset in components {

View File

@ -651,7 +651,7 @@ vulkan_bitflags! {
#[inline] #[inline]
pub const fn is_primitive_shading_graphics(self) -> bool { pub const fn is_primitive_shading_graphics(self) -> bool {
self.intersects( self.intersects(
(QueryPipelineStatisticFlags::INPUT_ASSEMBLY_VERTICES) QueryPipelineStatisticFlags::INPUT_ASSEMBLY_VERTICES
.union(QueryPipelineStatisticFlags::INPUT_ASSEMBLY_PRIMITIVES) .union(QueryPipelineStatisticFlags::INPUT_ASSEMBLY_PRIMITIVES)
.union(QueryPipelineStatisticFlags::VERTEX_SHADER_INVOCATIONS) .union(QueryPipelineStatisticFlags::VERTEX_SHADER_INVOCATIONS)
.union(QueryPipelineStatisticFlags::GEOMETRY_SHADER_INVOCATIONS) .union(QueryPipelineStatisticFlags::GEOMETRY_SHADER_INVOCATIONS)
@ -668,7 +668,7 @@ vulkan_bitflags! {
#[inline] #[inline]
pub const fn is_mesh_shading_graphics(self) -> bool { pub const fn is_mesh_shading_graphics(self) -> bool {
self.intersects( self.intersects(
(QueryPipelineStatisticFlags::TASK_SHADER_INVOCATIONS) QueryPipelineStatisticFlags::TASK_SHADER_INVOCATIONS
.union(QueryPipelineStatisticFlags::MESH_SHADER_INVOCATIONS), .union(QueryPipelineStatisticFlags::MESH_SHADER_INVOCATIONS),
) )
} }

View File

@ -547,7 +547,9 @@ impl FramebufferCreateInfo {
match image_view.view_type() { match image_view.view_type() {
ImageViewType::Dim2d | ImageViewType::Dim2dArray => { ImageViewType::Dim2d | ImageViewType::Dim2dArray => {
if image_view.image().image_type() == ImageType::Dim3d if image_view.image().image_type() == ImageType::Dim3d
&& (image_view.format().aspects()) && image_view
.format()
.aspects()
.intersects(ImageAspects::DEPTH | ImageAspects::STENCIL) .intersects(ImageAspects::DEPTH | ImageAspects::STENCIL)
{ {
return Err(Box::new(ValidationError { return Err(Box::new(ValidationError {

View File

@ -480,7 +480,8 @@ impl RenderPass {
return false; return false;
} }
if !(subpasses1.iter()) if !subpasses1
.iter()
.zip(subpasses2.iter()) .zip(subpasses2.iter())
.all(|(subpass1, subpass2)| { .all(|(subpass1, subpass2)| {
let SubpassDescription { let SubpassDescription {
@ -697,7 +698,10 @@ impl Subpass {
let subpass_desc = self.subpass_desc(); let subpass_desc = self.subpass_desc();
// TODO: chain input attachments as well? // TODO: chain input attachments as well?
(subpass_desc.color_attachments.iter().flatten()) subpass_desc
.color_attachments
.iter()
.flatten()
.chain(subpass_desc.depth_stencil_attachment.iter()) .chain(subpass_desc.depth_stencil_attachment.iter())
.filter_map(|attachment_ref| { .filter_map(|attachment_ref| {
self.render_pass self.render_pass
@ -3261,8 +3265,8 @@ pub struct SubpassDependency {
/// ///
/// The default value is [`DependencyFlags::empty()`]. /// The default value is [`DependencyFlags::empty()`].
/// ///
/// [`BY_REGION`]: crate::sync::DependencyFlags::BY_REGION /// [`BY_REGION`]: DependencyFlags::BY_REGION
/// [`VIEW_LOCAL`]: crate::sync::DependencyFlags::VIEW_LOCAL /// [`VIEW_LOCAL`]: DependencyFlags::VIEW_LOCAL
pub dependency_flags: DependencyFlags, pub dependency_flags: DependencyFlags,
/// If multiview rendering is being used (the subpasses have a nonzero `view_mask`), and /// If multiview rendering is being used (the subpasses have a nonzero `view_mask`), and
@ -3276,7 +3280,7 @@ pub struct SubpassDependency {
/// ///
/// The default value is `0`. /// The default value is `0`.
/// ///
/// [`VIEW_LOCAL`]: crate::sync::DependencyFlags::VIEW_LOCAL /// [`VIEW_LOCAL`]: DependencyFlags::VIEW_LOCAL
pub view_offset: i32, pub view_offset: i32,
pub _ne: crate::NonExhaustive, pub _ne: crate::NonExhaustive,

View File

@ -667,8 +667,8 @@ fn descriptor_binding_requirements_of(spirv: &Spirv, variable_id: Id) -> Descrip
image_format, image_format,
.. ..
} => { } => {
assert!( assert_ne!(
sampled != 0, sampled, 0,
"Vulkan requires that variables of type OpTypeImage have a Sampled operand of \ "Vulkan requires that variables of type OpTypeImage have a Sampled operand of \
1 or 2", 1 or 2",
); );
@ -678,7 +678,7 @@ fn descriptor_binding_requirements_of(spirv: &Spirv, variable_id: Id) -> Descrip
Instruction::TypeInt { Instruction::TypeInt {
width, signedness, .. width, signedness, ..
} => { } => {
assert!(width == 32); // TODO: 64-bit components assert_eq!(width, 32); // TODO: 64-bit components
match signedness { match signedness {
0 => NumericType::Uint, 0 => NumericType::Uint,
1 => NumericType::Int, 1 => NumericType::Int,
@ -686,7 +686,7 @@ fn descriptor_binding_requirements_of(spirv: &Spirv, variable_id: Id) -> Descrip
} }
} }
Instruction::TypeFloat { width, .. } => { Instruction::TypeFloat { width, .. } => {
assert!(width == 32); // TODO: 64-bit components assert_eq!(width, 32); // TODO: 64-bit components
NumericType::Float NumericType::Float
} }
_ => unreachable!(), _ => unreachable!(),
@ -698,8 +698,8 @@ fn descriptor_binding_requirements_of(spirv: &Spirv, variable_id: Id) -> Descrip
reqs.image_format.is_none(), reqs.image_format.is_none(),
"If Dim is SubpassData, Image Format must be Unknown", "If Dim is SubpassData, Image Format must be Unknown",
); );
assert!(sampled == 2, "If Dim is SubpassData, Sampled must be 2"); assert_eq!(sampled, 2, "If Dim is SubpassData, Sampled must be 2");
assert!(arrayed == 0, "If Dim is SubpassData, Arrayed must be 0"); assert_eq!(arrayed, 0, "If Dim is SubpassData, Arrayed must be 0");
reqs.descriptor_types = vec![DescriptorType::InputAttachment]; reqs.descriptor_types = vec![DescriptorType::InputAttachment];
} }
@ -991,9 +991,9 @@ pub(super) fn specialization_constants(spirv: &Spirv) -> HashMap<u32, Specializa
width, signedness, .. width, signedness, ..
} => { } => {
if width == 64 { if width == 64 {
assert!(value.len() == 2); assert_eq!(value.len(), 2);
} else { } else {
assert!(value.len() == 1); assert_eq!(value.len(), 1);
} }
match (signedness, width) { match (signedness, width) {
@ -1014,9 +1014,9 @@ pub(super) fn specialization_constants(spirv: &Spirv) -> HashMap<u32, Specializa
} }
Instruction::TypeFloat { width, .. } => { Instruction::TypeFloat { width, .. } => {
if width == 64 { if width == 64 {
assert!(value.len() == 2); assert_eq!(value.len(), 2);
} else { } else {
assert!(value.len() == 1); assert_eq!(value.len(), 1);
} }
match width { match width {
@ -1049,7 +1049,7 @@ pub(crate) fn size_of_type(spirv: &Spirv, id: Id) -> Option<DeviceSize> {
Instruction::TypeVoid { .. } => Some(0), Instruction::TypeVoid { .. } => Some(0),
Instruction::TypeBool { .. } => Some(4), Instruction::TypeBool { .. } => Some(4),
Instruction::TypeInt { width, .. } | Instruction::TypeFloat { width, .. } => { Instruction::TypeInt { width, .. } | Instruction::TypeFloat { width, .. } => {
assert!(width % 8 == 0); assert_eq!(width % 8, 0);
Some(width as DeviceSize / 8) Some(width as DeviceSize / 8)
} }
Instruction::TypePointer { Instruction::TypePointer {

View File

@ -298,7 +298,9 @@ impl Spirv {
} => { } => {
let decorations = &decoration_groups[&decoration_group]; let decorations = &decoration_groups[&decoration_group];
(targets.iter().copied()) targets
.iter()
.copied()
.flat_map(|target| { .flat_map(|target| {
decorations decorations
.iter() .iter()
@ -335,7 +337,9 @@ impl Spirv {
} => { } => {
let decorations = &decoration_groups[&decoration_group]; let decorations = &decoration_groups[&decoration_group];
(targets.iter().copied()) targets
.iter()
.copied()
.flat_map(|target| { .flat_map(|target| {
decorations decorations
.iter() .iter()

View File

@ -165,9 +165,9 @@ pub(super) fn replace_specialization_instructions(
width, signedness, .. width, signedness, ..
} => { } => {
if width == 64 { if width == 64 {
assert!(value.len() == 2); assert_eq!(value.len(), 2);
} else { } else {
assert!(value.len() == 1); assert_eq!(value.len(), 1);
} }
match (signedness, width) { match (signedness, width) {
@ -186,9 +186,9 @@ pub(super) fn replace_specialization_instructions(
} }
Instruction::TypeFloat { width, .. } => { Instruction::TypeFloat { width, .. } => {
if width == 64 { if width == 64 {
assert!(value.len() == 2); assert_eq!(value.len(), 2);
} else { } else {
assert!(value.len() == 1); assert_eq!(value.len(), 1);
} }
match width { match width {
@ -408,7 +408,9 @@ fn evaluate_spec_constant_op(
let new_result_ids = std::iter::once(result_id).chain(new_ids.clone()); let new_result_ids = std::iter::once(result_id).chain(new_ids.clone());
let new_constituent_ids = new_ids.chain(std::iter::once(object)); let new_constituent_ids = new_ids.chain(std::iter::once(object));
let mut new_instructions: SmallVec<_> = (indexes.iter().copied()) let mut new_instructions: SmallVec<_> = indexes
.iter()
.copied()
.zip(new_result_ids.zip(new_constituent_ids)) .zip(new_result_ids.zip(new_constituent_ids))
.map(|(index, (new_result_id, new_constituent_id))| { .map(|(index, (new_result_id, new_constituent_id))| {
let constant = &constants[&old_constituent_id]; let constant = &constants[&old_constituent_id];
@ -448,19 +450,20 @@ fn evaluate_spec_constant_op(
assert_eq!(conditions.len(), object_1.len()); assert_eq!(conditions.len(), object_1.len());
assert_eq!(conditions.len(), object_2.len()); assert_eq!(conditions.len(), object_2.len());
let constituents: SmallVec<[Id; 4]> = let constituents: SmallVec<[Id; 4]> = conditions
(conditions.iter().map(|c| constants[c].value.as_scalar())) .iter()
.zip(object_1.iter().zip(object_2.iter())) .map(|c| constants[c].value.as_scalar())
.map( .zip(object_1.iter().zip(object_2.iter()))
|(condition, (&object_1, &object_2))| { .map(
if condition != 0 { |(condition, (&object_1, &object_2))| {
object_1 if condition != 0 {
} else { object_1
object_2 } else {
} object_2
}, }
) },
.collect(); )
.collect();
smallvec![Instruction::ConstantComposite { smallvec![Instruction::ConstantComposite {
result_type_id, result_type_id,
@ -547,7 +550,8 @@ fn evaluate_spec_constant_calculation_op(
} }
(ConstantValue::Composite(constituents1), ConstantValue::Composite(constituents2)) => { (ConstantValue::Composite(constituents1), ConstantValue::Composite(constituents2)) => {
assert_eq!(constituents1.len(), constituents2.len()); assert_eq!(constituents1.len(), constituents2.len());
(constituents1.iter()) constituents1
.iter()
.zip(constituents2.iter()) .zip(constituents2.iter())
.map(|(constituent1, constituent2)| { .map(|(constituent1, constituent2)| {
let operand1 = constants[constituent1].value.as_scalar(); let operand1 = constants[constituent1].value.as_scalar();

View File

@ -162,7 +162,7 @@
//! # } //! # }
//! ``` //! ```
//! //!
//! Then, call [`Swapchain::new`](crate::swapchain::Swapchain::new). //! Then, call [`Swapchain::new`].
//! //!
//! ```no_run //! ```no_run
//! # use std::{error::Error, sync::Arc}; //! # use std::{error::Error, sync::Arc};
@ -578,7 +578,9 @@ impl Swapchain {
.surface_capabilities_unchecked( .surface_capabilities_unchecked(
surface, surface,
SurfaceInfo { SurfaceInfo {
present_mode: (device.enabled_extensions().ext_swapchain_maintenance1) present_mode: device
.enabled_extensions()
.ext_swapchain_maintenance1
.then_some(present_mode), .then_some(present_mode),
full_screen_exclusive, full_screen_exclusive,
win32_monitor: win32_monitor win32_monitor: win32_monitor
@ -601,7 +603,9 @@ impl Swapchain {
.surface_formats_unchecked( .surface_formats_unchecked(
surface, surface,
SurfaceInfo { SurfaceInfo {
present_mode: (device.enabled_extensions().ext_swapchain_maintenance1) present_mode: device
.enabled_extensions()
.ext_swapchain_maintenance1
.then_some(present_mode), .then_some(present_mode),
full_screen_exclusive, full_screen_exclusive,
win32_monitor: win32_monitor.filter(|_| { win32_monitor: win32_monitor.filter(|_| {

View File

@ -1809,7 +1809,7 @@ vulkan_enum! {
/// Only `Fifo` is guaranteed to be supported on every device. For the others, you must call /// Only `Fifo` is guaranteed to be supported on every device. For the others, you must call
/// [`surface_present_modes`] to see if they are supported. /// [`surface_present_modes`] to see if they are supported.
/// ///
/// [`surface_present_modes`]: crate::device::physical::PhysicalDevice::surface_present_modes /// [`surface_present_modes`]: PhysicalDevice::surface_present_modes
PresentMode = PresentModeKHR(i32); PresentMode = PresentModeKHR(i32);
/// The presentation engine holds only the currently displayed image. When presenting an image, /// The presentation engine holds only the currently displayed image. When presenting an image,
@ -2139,9 +2139,6 @@ vulkan_enum! {
/// Parameters for [`PhysicalDevice::surface_capabilities`] and /// Parameters for [`PhysicalDevice::surface_capabilities`] and
/// [`PhysicalDevice::surface_formats`]. /// [`PhysicalDevice::surface_formats`].
///
/// [`PhysicalDevice::surface_capabilities`]: crate::device::physical::PhysicalDevice::surface_capabilities
/// [`PhysicalDevice::surface_formats`]: crate::device::physical::PhysicalDevice::surface_formats
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct SurfaceInfo { pub struct SurfaceInfo {
/// If this is `Some`, the /// If this is `Some`, the

View File

@ -1169,7 +1169,7 @@ impl ImportFenceWin32HandleInfo {
} }
/// The fence configuration to query in /// The fence configuration to query in
/// [`PhysicalDevice::external_fence_properties`](crate::device::physical::PhysicalDevice::external_fence_properties). /// [`PhysicalDevice::external_fence_properties`].
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ExternalFenceInfo { pub struct ExternalFenceInfo {
/// The external handle type that will be used with the fence. /// The external handle type that will be used with the fence.

View File

@ -18,7 +18,7 @@ where
assert_eq!(first.device().handle(), second.device().handle()); assert_eq!(first.device().handle(), second.device().handle());
if !first.queue_change_allowed() && !second.queue_change_allowed() { if !first.queue_change_allowed() && !second.queue_change_allowed() {
assert!(first.queue().unwrap() == second.queue().unwrap()); assert_eq!(first.queue().unwrap(), second.queue().unwrap());
} }
JoinFuture { first, second } JoinFuture { first, second }

View File

@ -2,7 +2,7 @@
//! //!
//! Whenever you ask the GPU to start an operation by using a function of the vulkano library (for //! Whenever you ask the GPU to start an operation by using a function of the vulkano library (for
//! example executing a command buffer), this function will return a *future*. A future is an //! example executing a command buffer), this function will return a *future*. A future is an
//! object that implements [the `GpuFuture` trait](crate::sync::GpuFuture) and that represents the //! object that implements [the `GpuFuture` trait](GpuFuture) and that represents the
//! point in time when this operation is over. //! point in time when this operation is over.
//! //!
//! No function in vulkano immediately sends an operation to the GPU (with the exception of some //! No function in vulkano immediately sends an operation to the GPU (with the exception of some

View File

@ -125,23 +125,19 @@ vulkan_bitflags_enum! {
} }
if self.contains_flags2() { if self.contains_flags2() {
if (self - PipelineStages::from(QueueFlags::GRAPHICS)).is_empty() { return if (self - PipelineStages::from(QueueFlags::GRAPHICS)).is_empty() {
return PipelineStages::ALL_GRAPHICS; PipelineStages::ALL_GRAPHICS
} else { } else {
return PipelineStages::ALL_COMMANDS; PipelineStages::ALL_COMMANDS
} };
} }
} }
if self.validate_device(device).is_err() { match self.validate_device(device) {
if (self - PipelineStages::from(QueueFlags::GRAPHICS)).is_empty() { Ok(_) => self,
return PipelineStages::ALL_GRAPHICS; Err(_) if (self - PipelineStages::from(QueueFlags::GRAPHICS)).is_empty() => PipelineStages::ALL_GRAPHICS,
} else { Err(_) => PipelineStages::ALL_COMMANDS,
return PipelineStages::ALL_COMMANDS;
}
} }
self
} }
}, },
@ -4082,7 +4078,6 @@ impl ImageMemoryBarrier {
/// mentioned parameters do not match. /// mentioned parameters do not match.
/// ///
/// [`Instance`]: crate::instance::Instance /// [`Instance`]: crate::instance::Instance
/// [`Device`]: crate::device::Device
/// [`device_uuid`]: crate::device::DeviceProperties::device_uuid /// [`device_uuid`]: crate::device::DeviceProperties::device_uuid
/// [`driver_uuid`]: crate::device::DeviceProperties::driver_uuid /// [`driver_uuid`]: crate::device::DeviceProperties::driver_uuid
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]

View File

@ -1843,7 +1843,7 @@ impl ImportSemaphoreZirconHandleInfo {
} }
/// The semaphore configuration to query in /// The semaphore configuration to query in
/// [`PhysicalDevice::external_semaphore_properties`](crate::device::physical::PhysicalDevice::external_semaphore_properties). /// [`PhysicalDevice::external_semaphore_properties`].
#[derive(Clone, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ExternalSemaphoreInfo { pub struct ExternalSemaphoreInfo {
/// The external handle type that will be used with the semaphore. /// The external handle type that will be used with the semaphore.