Enforce a consistent comment width (#2444)

* Enforce comment width

* `cargo +nightly fmt`

* Finishing touches
This commit is contained in:
marc0246 2024-01-05 09:14:49 +01:00 committed by GitHub
parent e7f37adfa9
commit 00b65b1299
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
62 changed files with 634 additions and 583 deletions

View File

@ -1,2 +1,4 @@
imports_granularity = "Crate" comment_width = 99
group_imports = "One" group_imports = "One"
imports_granularity = "Crate"
wrap_comments = true

View File

@ -1,11 +1,13 @@
// Welcome to the mesh shader example! // Welcome to the mesh shader example!
// //
// This is a simple, modified version of the `instancing.rs` example that demonstrates how to use mesh shaders to // This is a simple, modified version of the `instancing.rs` example that demonstrates how to use
// generate geometry, that looks identical to the instancing example. We expect you to be familiar with both // mesh shaders to generate geometry, that looks identical to the instancing example. We expect you
// instancing and compute shaders before approaching mesh shaders, due to their high complexity. // to be familiar with both instancing and compute shaders before approaching mesh shaders, due to
// their high complexity.
// //
// This example is intentionally kept simple and does not follow the recommended pattern by which one should emit // This example is intentionally kept simple and does not follow the recommended pattern by which
// vertices and indices. This pattern should best match what the hardware likes, and thus is unique to each vendor. // one should emit vertices and indices. This pattern should best match what the hardware likes,
// and thus is unique to each vendor.
// //
// See these presentation slides for an overview of mesh shaders and best practices: // See these presentation slides for an overview of mesh shaders and best practices:
// https://vulkan.org/user/pages/09.events/vulkanised-2023/vulkanised_mesh_best_practices_2023.02.09-1.pdf // https://vulkan.org/user/pages/09.events/vulkanised-2023/vulkanised_mesh_best_practices_2023.02.09-1.pdf

View File

@ -357,8 +357,9 @@ fn main() {
.unwrap(); .unwrap();
unsafe { unsafe {
// Drawing commands are broadcast to each view in the view mask of the active renderpass which // Drawing commands are broadcast to each view in the view mask of the active renderpass
// means only a single draw call is needed to draw to multiple layers of the framebuffer. // which means only a single draw call is needed to draw to multiple layers of the
// framebuffer.
builder.draw(vertex_buffer.len() as u32, 1, 0, 0).unwrap(); builder.draw(vertex_buffer.len() as u32, 1, 0, 0).unwrap();
} }

View File

@ -313,8 +313,8 @@ fn main() -> Result<(), impl Error> {
elapsed.as_secs() as f64 + elapsed.subsec_nanos() as f64 / 1_000_000_000.0; elapsed.as_secs() as f64 + elapsed.subsec_nanos() as f64 / 1_000_000_000.0;
let rotation = Matrix3::from_angle_y(Rad(rotation as f32)); let rotation = Matrix3::from_angle_y(Rad(rotation as f32));
// note: this teapot was meant for OpenGL where the origin is at the lower left // NOTE: This teapot was meant for OpenGL where the origin is at the lower left
// instead the origin is at the upper left in Vulkan, so we reverse the Y axis // instead the origin is at the upper left in Vulkan, so we reverse the Y axis.
let aspect_ratio = let aspect_ratio =
swapchain.image_extent()[0] as f32 / swapchain.image_extent()[1] as f32; swapchain.image_extent()[0] as f32 / swapchain.image_extent()[1] as f32;
let proj = cgmath::perspective( let proj = cgmath::perspective(

View File

@ -395,21 +395,21 @@ fn main() -> Result<(), impl Error> {
PipelineShaderStageCreateInfo::new(fs), PipelineShaderStageCreateInfo::new(fs),
]; ];
// We must now create a **pipeline layout** object, which describes the locations and types of // We must now create a **pipeline layout** object, which describes the locations and types
// descriptor sets and push constants used by the shaders in the pipeline. // of descriptor sets and push constants used by the shaders in the pipeline.
// //
// Multiple pipelines can share a common layout object, which is more efficient. // Multiple pipelines can share a common layout object, which is more efficient.
// The shaders in a pipeline must use a subset of the resources described in its pipeline // The shaders in a pipeline must use a subset of the resources described in its pipeline
// layout, but the pipeline layout is allowed to contain resources that are not present in the // layout, but the pipeline layout is allowed to contain resources that are not present in
// shaders; they can be used by shaders in other pipelines that share the same layout. // the shaders; they can be used by shaders in other pipelines that share the same
// Thus, it is a good idea to design shaders so that many pipelines have common resource // layout. Thus, it is a good idea to design shaders so that many pipelines have
// locations, which allows them to share pipeline layouts. // common resource locations, which allows them to share pipeline layouts.
let layout = PipelineLayout::new( let layout = PipelineLayout::new(
device.clone(), device.clone(),
// Since we only have one pipeline in this example, and thus one pipeline layout, // Since we only have one pipeline in this example, and thus one pipeline layout,
// we automatically generate the creation info for it from the resources used in the // we automatically generate the creation info for it from the resources used in the
// shaders. In a real application, you would specify this information manually so that you // shaders. In a real application, you would specify this information manually so that
// can re-use one layout in multiple pipelines. // you can re-use one layout in multiple pipelines.
PipelineDescriptorSetLayoutCreateInfo::from_stages(&stages) PipelineDescriptorSetLayoutCreateInfo::from_stages(&stages)
.into_pipeline_layout_create_info(device.clone()) .into_pipeline_layout_create_info(device.clone())
.unwrap(), .unwrap(),
@ -448,7 +448,8 @@ fn main() -> Result<(), impl Error> {
// The default value does not perform any multisampling. // The default value does not perform any multisampling.
multisample_state: Some(MultisampleState::default()), multisample_state: Some(MultisampleState::default()),
// How pixel values are combined with the values already present in the framebuffer. // How pixel values are combined with the values already present in the framebuffer.
// The default value overwrites the old value with the new one, without any blending. // The default value overwrites the old value with the new one, without any
// blending.
color_blend_state: Some(ColorBlendState::with_attachment_states( color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.color_attachment_formats.len() as u32, subpass.color_attachment_formats.len() as u32,
ColorBlendAttachmentState::default(), ColorBlendAttachmentState::default(),

View File

@ -400,21 +400,21 @@ fn main() -> Result<(), impl Error> {
PipelineShaderStageCreateInfo::new(fs), PipelineShaderStageCreateInfo::new(fs),
]; ];
// We must now create a **pipeline layout** object, which describes the locations and types of // We must now create a **pipeline layout** object, which describes the locations and types
// descriptor sets and push constants used by the shaders in the pipeline. // of descriptor sets and push constants used by the shaders in the pipeline.
// //
// Multiple pipelines can share a common layout object, which is more efficient. // Multiple pipelines can share a common layout object, which is more efficient.
// The shaders in a pipeline must use a subset of the resources described in its pipeline // The shaders in a pipeline must use a subset of the resources described in its pipeline
// layout, but the pipeline layout is allowed to contain resources that are not present in the // layout, but the pipeline layout is allowed to contain resources that are not present in
// shaders; they can be used by shaders in other pipelines that share the same layout. // the shaders; they can be used by shaders in other pipelines that share the same
// Thus, it is a good idea to design shaders so that many pipelines have common resource // layout. Thus, it is a good idea to design shaders so that many pipelines have
// locations, which allows them to share pipeline layouts. // common resource locations, which allows them to share pipeline layouts.
let layout = PipelineLayout::new( let layout = PipelineLayout::new(
device.clone(), device.clone(),
// Since we only have one pipeline in this example, and thus one pipeline layout, // Since we only have one pipeline in this example, and thus one pipeline layout,
// we automatically generate the creation info for it from the resources used in the // we automatically generate the creation info for it from the resources used in the
// shaders. In a real application, you would specify this information manually so that you // shaders. In a real application, you would specify this information manually so that
// can re-use one layout in multiple pipelines. // you can re-use one layout in multiple pipelines.
PipelineDescriptorSetLayoutCreateInfo::from_stages(&stages) PipelineDescriptorSetLayoutCreateInfo::from_stages(&stages)
.into_pipeline_layout_create_info(device.clone()) .into_pipeline_layout_create_info(device.clone())
.unwrap(), .unwrap(),
@ -446,7 +446,8 @@ fn main() -> Result<(), impl Error> {
// The default value does not perform any multisampling. // The default value does not perform any multisampling.
multisample_state: Some(MultisampleState::default()), multisample_state: Some(MultisampleState::default()),
// How pixel values are combined with the values already present in the framebuffer. // How pixel values are combined with the values already present in the framebuffer.
// The default value overwrites the old value with the new one, without any blending. // The default value overwrites the old value with the new one, without any
// blending.
color_blend_state: Some(ColorBlendState::with_attachment_states( color_blend_state: Some(ColorBlendState::with_attachment_states(
subpass.num_color_attachments(), subpass.num_color_attachments(),
ColorBlendAttachmentState::default(), ColorBlendAttachmentState::default(),

View File

@ -1,5 +1,6 @@
//! The procedural macro for vulkano's shader system. //! The procedural macro for vulkano's shader system.
//! Manages the compile-time compilation of GLSL into SPIR-V and generation of associated Rust code. //! Manages the compile-time compilation of GLSL into SPIR-V and generation of associated Rust
//! code.
//! //!
//! # Basic usage //! # Basic usage
//! //!
@ -31,11 +32,11 @@
//! //!
//! The macro generates the following items of interest: //! The macro generates the following items of interest:
//! //!
//! - The `load` constructor. This function takes an `Arc<Device>`, constructs a //! - The `load` constructor. This function takes an `Arc<Device>`, constructs a [`ShaderModule`]
//! [`ShaderModule`] with the passed-in device and the shader data provided //! with the passed-in device and the shader data provided via the macro, and returns
//! via the macro, and returns `Result<Arc<ShaderModule>, Validated<VulkanError>>`. //! `Result<Arc<ShaderModule>, Validated<VulkanError>>`. Before doing so, it checks every
//! Before doing so, it checks every capability instruction in the shader data, //! capability instruction in the shader data, verifying that the passed-in `Device` has the
//! verifying that the passed-in `Device` has the appropriate features enabled. //! appropriate features enabled.
//! - If the `shaders` option is used, then instead of one `load` constructor, there is one for //! - If the `shaders` option is used, then instead of one `load` constructor, there is one for
//! each shader. They are named based on the provided names, `load_first`, `load_second` etc. //! each shader. They are named based on the provided names, `load_first`, `load_second` etc.
//! - A Rust struct translated from each struct contained in the shader data. By default each //! - A Rust struct translated from each struct contained in the shader data. By default each

View File

@ -10,7 +10,8 @@
//! instances of (references to) one or more bottom-level structures. A top-level structure is //! instances of (references to) one or more bottom-level structures. A top-level structure is
//! intended to contain the whole rendered scene (or the relevant parts of it), while a //! intended to contain the whole rendered scene (or the relevant parts of it), while a
//! bottom-level structure may contain individual objects within the scene. This two-level //! bottom-level structure may contain individual objects within the scene. This two-level
//! arrangement allows you to easily rearrange the scene, adding and removing parts of it as needed. //! arrangement allows you to easily rearrange the scene, adding and removing parts of it as
//! needed.
//! //!
//! # Building an acceleration structure //! # Building an acceleration structure
//! //!
@ -44,8 +45,8 @@
//! - [`AccelerationStructureBuildGeometryInfo::scratch_data`] //! - [`AccelerationStructureBuildGeometryInfo::scratch_data`]
//! - [`AccelerationStructureGeometryTrianglesData::vertex_data`] //! - [`AccelerationStructureGeometryTrianglesData::vertex_data`]
//! - [`AccelerationStructureGeometryTrianglesData::vertex_stride`] //! - [`AccelerationStructureGeometryTrianglesData::vertex_stride`]
//! - [`AccelerationStructureGeometryTrianglesData::transform_data`] //! - [`AccelerationStructureGeometryTrianglesData::transform_data`] (but the variant of `Option`
//! (but the variant of `Option` must not change) //! must not change)
//! - [`AccelerationStructureGeometryAabbsData::data`] //! - [`AccelerationStructureGeometryAabbsData::data`]
//! - [`AccelerationStructureGeometryAabbsData::stride`] //! - [`AccelerationStructureGeometryAabbsData::stride`]
//! - [`AccelerationStructureGeometryInstancesData::data`] //! - [`AccelerationStructureGeometryInstancesData::data`]
@ -75,7 +76,8 @@
//! //!
//! On the Vulkano side, you can then create a descriptor set layout using //! On the Vulkano side, you can then create a descriptor set layout using
//! [`DescriptorType::AccelerationStructure`] as a descriptor type, and write the //! [`DescriptorType::AccelerationStructure`] as a descriptor type, and write the
//! acceleration structure to a descriptor set using [`WriteDescriptorSet::acceleration_structure`]. //! acceleration structure to a descriptor set using
//! [`WriteDescriptorSet::acceleration_structure`].
//! //!
//! [`build_acceleration_structure`]: crate::command_buffer::RecordingCommandBuffer::build_acceleration_structure //! [`build_acceleration_structure`]: crate::command_buffer::RecordingCommandBuffer::build_acceleration_structure
//! [`build_acceleration_structure_indirect`]: crate::command_buffer::RecordingCommandBuffer::build_acceleration_structure_indirect //! [`build_acceleration_structure_indirect`]: crate::command_buffer::RecordingCommandBuffer::build_acceleration_structure_indirect
@ -113,8 +115,8 @@ impl AccelerationStructure {
/// ///
/// # Safety /// # Safety
/// ///
/// - `create_info.buffer` (and any subbuffer it overlaps with) must not be accessed /// - `create_info.buffer` (and any subbuffer it overlaps with) must not be accessed while it
/// while it is bound to the acceleration structure. /// is bound to the acceleration structure.
/// ///
/// [`acceleration_structure`]: crate::device::Features::acceleration_structure /// [`acceleration_structure`]: crate::device::Features::acceleration_structure
#[inline] #[inline]
@ -1625,7 +1627,8 @@ vulkan_enum! {
HostOrDevice = HOST_OR_DEVICE, HostOrDevice = HOST_OR_DEVICE,
} }
/// The minimum sizes needed for various resources during an acceleration structure build operation. /// The minimum sizes needed for various resources during an acceleration structure build
/// operation.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct AccelerationStructureBuildSizesInfo { pub struct AccelerationStructureBuildSizesInfo {
/// The minimum required size of the acceleration structure for a build or update operation. /// The minimum required size of the acceleration structure for a build or update operation.

View File

@ -275,9 +275,9 @@ where
/// return an error. Similarly if you called [`write`] on the buffer and haven't dropped the /// return an error. Similarly if you called [`write`] on the buffer and haven't dropped the
/// lock, this function will return an error as well. /// lock, this function will return an error as well.
/// ///
/// After this function successfully locks the subbuffer, any attempt to submit a command buffer /// After this function successfully locks the subbuffer, any attempt to submit a command
/// that uses it in exclusive mode will fail. You can still submit this subbuffer for /// buffer that uses it in exclusive mode will fail. You can still submit this subbuffer
/// non-exclusive accesses (ie. reads). /// for non-exclusive accesses (ie. reads).
/// ///
/// If the memory backing the buffer is not [host-coherent], then this function will lock a /// If the memory backing the buffer is not [host-coherent], then this function will lock a
/// range that is potentially larger than the subbuffer, because the range given to /// range that is potentially larger than the subbuffer, because the range given to
@ -344,8 +344,8 @@ where
// SAFETY: // SAFETY:
// - `self.mapped_slice()` didn't return an error, which means that the subbuffer falls // - `self.mapped_slice()` didn't return an error, which means that the subbuffer falls
// within the mapped range of the memory. // within the mapped range of the memory.
// - We ensure that memory mappings are always aligned to the non-coherent atom size // - We ensure that memory mappings are always aligned to the non-coherent atom size for
// for non-host-coherent memory, therefore the subbuffer's range aligned to the // non-host-coherent memory, therefore the subbuffer's range aligned to the
// non-coherent atom size must fall within the mapped range of the memory. // non-coherent atom size must fall within the mapped range of the memory.
unsafe { allocation.invalidate_range_unchecked(memory_range) } unsafe { allocation.invalidate_range_unchecked(memory_range) }
.map_err(HostAccessError::Invalidate)?; .map_err(HostAccessError::Invalidate)?;
@ -429,8 +429,8 @@ where
// SAFETY: // SAFETY:
// - `self.mapped_slice()` didn't return an error, which means that the subbuffer falls // - `self.mapped_slice()` didn't return an error, which means that the subbuffer falls
// within the mapped range of the memory. // within the mapped range of the memory.
// - We ensure that memory mappings are always aligned to the non-coherent atom size // - We ensure that memory mappings are always aligned to the non-coherent atom size for
// for non-host-coherent memory, therefore the subbuffer's range aligned to the // non-host-coherent memory, therefore the subbuffer's range aligned to the
// non-coherent atom size must fall within the mapped range of the memory. // non-coherent atom size must fall within the mapped range of the memory.
unsafe { allocation.invalidate_range_unchecked(memory_range) } unsafe { allocation.invalidate_range_unchecked(memory_range) }
.map_err(HostAccessError::Invalidate)?; .map_err(HostAccessError::Invalidate)?;

View File

@ -690,8 +690,8 @@ impl AutoSyncState {
/// through `Command::buffer(..)` or `Command::image(..)`. /// through `Command::buffer(..)` or `Command::image(..)`.
/// - `PipelineMemoryAccess` must match the way the resource has been used. /// - `PipelineMemoryAccess` must match the way the resource has been used.
/// - `start_layout` and `end_layout` designate the image layout that the image is expected to /// - `start_layout` and `end_layout` designate the image layout that the image is expected to
/// be in when the command starts, and the image layout that the image will be transitioned to /// be in when the command starts, and the image layout that the image will be transitioned
/// during the command. When it comes to buffers, you should pass `Undefined` for both. /// to during the command. When it comes to buffers, you should pass `Undefined` for both.
fn add_resources(&mut self, command_info: &CommandInfo) { fn add_resources(&mut self, command_info: &CommandInfo) {
let &CommandInfo { let &CommandInfo {
name: command_name, name: command_name,

View File

@ -8,16 +8,17 @@
//! simultaneously. //! simultaneously.
//! //!
//! Now imagine that the command buffer contains 10 draw commands instead. Contrary to the dispatch //! Now imagine that the command buffer contains 10 draw commands instead. Contrary to the dispatch
//! commands, the draw pipeline contains multiple stages: draw indirect, vertex input, vertex shader, //! commands, the draw pipeline contains multiple stages: draw indirect, vertex input, vertex
//! ..., fragment shader, late fragment test, color output. When there are multiple stages, the //! shader, ..., fragment shader, late fragment test, color output. When there are multiple stages,
//! implementations must start and end the stages in order. In other words it can start the draw //! the implementations must start and end the stages in order. In other words it can start the
//! indirect stage of all 10 commands, then start the vertex input stage of all 10 commands, and so //! draw indirect stage of all 10 commands, then start the vertex input stage of all 10 commands,
//! on. But it can't for example start the fragment shader stage of a command before starting the //! and so on. But it can't for example start the fragment shader stage of a command before
//! vertex shader stage of another command. Same thing for ending the stages in the right order. //! starting the vertex shader stage of another command. Same thing for ending the stages in the
//! right order.
//! //!
//! Depending on the type of the command, the pipeline stages are different. Compute shaders use the //! Depending on the type of the command, the pipeline stages are different. Compute shaders use
//! compute stage, while transfer commands use the transfer stage. The compute and transfer stages //! the compute stage, while transfer commands use the transfer stage. The compute and transfer
//! aren't ordered. //! stages aren't ordered.
//! //!
//! When you submit multiple command buffers to a queue, the implementation doesn't do anything in //! When you submit multiple command buffers to a queue, the implementation doesn't do anything in
//! particular and behaves as if the command buffers were appended to one another. Therefore if you //! particular and behaves as if the command buffers were appended to one another. Therefore if you
@ -32,10 +33,10 @@
//! is done by adding a pipeline barrier between the two commands. //! is done by adding a pipeline barrier between the two commands.
//! //!
//! A pipeline barriers has a source stage and a destination stage (plus various other things). //! A pipeline barriers has a source stage and a destination stage (plus various other things).
//! A barrier represents a split in the list of commands. When you add it, the stages of the commands //! A barrier represents a split in the list of commands. When you add it, the stages of the
//! before the barrier corresponding to the source stage of the barrier, must finish before the //! commands before the barrier corresponding to the source stage of the barrier, must finish
//! stages of the commands after the barrier corresponding to the destination stage of the barrier //! before the stages of the commands after the barrier corresponding to the destination stage of
//! can start. //! the barrier can start.
//! //!
//! For example if you add a barrier that transitions from the compute stage to the compute stage, //! For example if you add a barrier that transitions from the compute stage to the compute stage,
//! then the compute stage of all the commands before the barrier must end before the compute stage //! then the compute stage of all the commands before the barrier must end before the compute stage

View File

@ -42,8 +42,8 @@ impl RecordingCommandBuffer {
/// - If [`index_data`] is `Some`, then if `index_max` is the highest index value in the index /// - If [`index_data`] is `Some`, then if `index_max` is the highest index value in the index
/// buffer that is accessed, then the size of [`vertex_data`] must be at least<br/> /// buffer that is accessed, then the size of [`vertex_data`] must be at least<br/>
/// [`vertex_stride`] * ([`first_vertex`] + `index_max` + 1). /// [`vertex_stride`] * ([`first_vertex`] + `index_max` + 1).
/// - If [`transform_data`] is `Some`, then for the /// - If [`transform_data`] is `Some`, then for the 3x4 matrix in the buffer, the first three
/// 3x4 matrix in the buffer, the first three columns must be a 3x3 invertible matrix. /// columns must be a 3x3 invertible matrix.
/// ///
/// If `info.geometries` is [`AccelerationStructureGeometries::Aabbs`], then for each geometry: /// If `info.geometries` is [`AccelerationStructureGeometries::Aabbs`], then for each geometry:
/// - For each accessed [`AabbPositions`] element in /// - For each accessed [`AabbPositions`] element in
@ -54,11 +54,11 @@ impl RecordingCommandBuffer {
/// of the buffer in [`data`](AccelerationStructureGeometryInstancesData::data) must be valid, /// of the buffer in [`data`](AccelerationStructureGeometryInstancesData::data) must be valid,
/// as follows: /// as follows:
/// - Any [`AccelerationStructureInstance::acceleration_structure_reference`] address contained /// - Any [`AccelerationStructureInstance::acceleration_structure_reference`] address contained
/// in or referenced by [`data`](AccelerationStructureGeometryInstancesData::data) /// in or referenced by [`data`](AccelerationStructureGeometryInstancesData::data) must be
/// must be either 0, or a device address that was returned from calling [`device_address`] /// either 0, or a device address that was returned from calling [`device_address`] on a
/// on a bottom-level acceleration structure. /// bottom-level acceleration structure.
/// - If an [`AccelerationStructureInstance::acceleration_structure_reference`] address is /// - If an [`AccelerationStructureInstance::acceleration_structure_reference`] address is not
/// not 0, then the corresponding acceleration structure object must be kept alive and not be /// 0, then the corresponding acceleration structure object must be kept alive and not be
/// dropped while it is bound to the top-level acceleration structure. /// dropped while it is bound to the top-level acceleration structure.
/// - If [`data`](AccelerationStructureGeometryInstancesData::data) is /// - If [`data`](AccelerationStructureGeometryInstancesData::data) is
/// [`AccelerationStructureGeometryInstancesDataType::Pointers`], then the addresses in the /// [`AccelerationStructureGeometryInstancesDataType::Pointers`], then the addresses in the
@ -138,8 +138,8 @@ impl RecordingCommandBuffer {
/// - [`primitive_count`] must not be greater than the corresponding element of /// - [`primitive_count`] must not be greater than the corresponding element of
/// `max_primitive_counts`. /// `max_primitive_counts`.
/// - If `info.geometries` is [`AccelerationStructureGeometries::Instances`], then /// - If `info.geometries` is [`AccelerationStructureGeometries::Instances`], then
/// [`primitive_count`] must not be greater than the [`max_instance_count`] limit. /// [`primitive_count`] must not be greater than the [`max_instance_count`] limit. Otherwise,
/// Otherwise, it must not be greater than the [`max_primitive_count`] limit. /// it must not be greater than the [`max_primitive_count`] limit.
/// ///
/// If `info.geometries` is [`AccelerationStructureGeometries::Triangles`], then: /// If `info.geometries` is [`AccelerationStructureGeometries::Triangles`], then:
/// - [`primitive_offset`] must be a multiple of: /// - [`primitive_offset`] must be a multiple of:
@ -147,15 +147,15 @@ impl RecordingCommandBuffer {
/// - The byte size of the smallest component of [`vertex_format`] if [`index_data`] is /// - The byte size of the smallest component of [`vertex_format`] if [`index_data`] is
/// `None`. /// `None`.
/// - [`transform_offset`] must be a multiple of 16. /// - [`transform_offset`] must be a multiple of 16.
/// - The size of [`vertex_data`] must be at least<br/> /// - The size of [`vertex_data`] must be at least<br/> [`primitive_offset`] +
/// [`primitive_offset`] + ([`first_vertex`] + 3 * [`primitive_count`]) * [`vertex_stride`] /// ([`first_vertex`]
/// <br/>if [`index_data`] is `None`, and as in [`build_acceleration_structure`] if /// + 3 * [`primitive_count`]) * [`vertex_stride`] <br/>if [`index_data`] is `None`, and as
/// [`index_data`] is `Some`. /// in
/// - The size of [`index_data`] must be at least<br/> /// [`build_acceleration_structure`] if [`index_data`] is `Some`.
/// [`primitive_offset`] + 3 * [`primitive_count`] * /// - The size of [`index_data`] must be at least<br/> [`primitive_offset`] + 3 *
/// [`index_data.index_type().size()`]. /// [`primitive_count`] * [`index_data.index_type().size()`].
/// - The size of [`transform_data`] must be at least<br/> /// - The size of [`transform_data`] must be at least<br/> [`transform_offset`] +
/// [`transform_offset`] + `size_of::<TransformMatrix>()`. /// `size_of::<TransformMatrix>()`.
/// ///
/// If `info.geometries` is [`AccelerationStructureGeometries::Aabbs`], then: /// If `info.geometries` is [`AccelerationStructureGeometries::Aabbs`], then:
/// - [`primitive_offset`] must be a multiple of 8. /// - [`primitive_offset`] must be a multiple of 8.
@ -170,8 +170,7 @@ impl RecordingCommandBuffer {
/// `size_of::<AccelerationStructureInstance>()`<br/> if /// `size_of::<AccelerationStructureInstance>()`<br/> if
/// [`data`](AccelerationStructureGeometryInstancesData::data) is /// [`data`](AccelerationStructureGeometryInstancesData::data) is
/// [`AccelerationStructureGeometryInstancesDataType::Values`]. /// [`AccelerationStructureGeometryInstancesDataType::Values`].
/// - [`primitive_offset`] + [`primitive_count`] * /// - [`primitive_offset`] + [`primitive_count`] * `size_of::<DeviceSize>()`<br/> if
/// `size_of::<DeviceSize>()`<br/> if
/// [`data`](AccelerationStructureGeometryInstancesData::data) is /// [`data`](AccelerationStructureGeometryInstancesData::data) is
/// [`AccelerationStructureGeometryInstancesDataType::Pointers`]. /// [`AccelerationStructureGeometryInstancesDataType::Pointers`].
/// ///
@ -354,8 +353,8 @@ impl RecordingCommandBuffer {
/// ///
/// - `info.src` must have been built when this command is executed. /// - `info.src` must have been built when this command is executed.
/// - `info.dst` must be large enough to hold the serialized form of `info.src`. This can be /// - `info.dst` must be large enough to hold the serialized form of `info.src`. This can be
/// queried using [`write_acceleration_structures_properties`] with a query pool whose type is /// queried using [`write_acceleration_structures_properties`] with a query pool whose type
/// [`QueryType::AccelerationStructureSerializationSize`]. /// is [`QueryType::AccelerationStructureSerializationSize`].
/// ///
/// [`write_acceleration_structures_properties`]: Self::write_acceleration_structures_properties /// [`write_acceleration_structures_properties`]: Self::write_acceleration_structures_properties
#[inline] #[inline]
@ -440,8 +439,8 @@ impl RecordingCommandBuffer {
/// - `info.src` must contain data previously serialized using /// - `info.src` must contain data previously serialized using
/// [`copy_acceleration_structure_to_memory`], and must have a format compatible with the /// [`copy_acceleration_structure_to_memory`], and must have a format compatible with the
/// device (as queried by [`Device::acceleration_structure_is_compatible`]). /// device (as queried by [`Device::acceleration_structure_is_compatible`]).
/// - `info.dst.size()` must be at least the size that the structure in `info.src` had /// - `info.dst.size()` must be at least the size that the structure in `info.src` had before
/// before it was serialized. /// it was serialized.
/// ///
/// [`copy_acceleration_structure_to_memory`]: Self::copy_acceleration_structure_to_memory /// [`copy_acceleration_structure_to_memory`]: Self::copy_acceleration_structure_to_memory
/// [`Device::acceleration_structure_is_compatible`]: crate::device::Device::acceleration_structure_is_compatible /// [`Device::acceleration_structure_is_compatible`]: crate::device::Device::acceleration_structure_is_compatible
@ -528,8 +527,8 @@ impl RecordingCommandBuffer {
/// ///
/// - All elements of `acceleration_structures` must have been built when this command is /// - All elements of `acceleration_structures` must have been built when this command is
/// executed. /// executed.
/// - If `query_pool.query_type()` is [`QueryType::AccelerationStructureCompactedSize`], /// - If `query_pool.query_type()` is [`QueryType::AccelerationStructureCompactedSize`], all
/// all elements of `acceleration_structures` must have been built with /// elements of `acceleration_structures` must have been built with
/// [`BuildAccelerationStructureFlags::ALLOW_COMPACTION`]. /// [`BuildAccelerationStructureFlags::ALLOW_COMPACTION`].
/// - The queries must be unavailable, ensured by calling [`reset_query_pool`]. /// - The queries must be unavailable, ensured by calling [`reset_query_pool`].
/// ///

View File

@ -1085,7 +1085,8 @@ impl RawRecordingCommandBuffer {
break; break;
} }
// push the minimum of the whole remaining data, and the part until the end of this range // push the minimum of the whole remaining data, and the part until the end of this
// range
let push_size = let push_size =
remaining_size.min(range.offset as usize + range.size as usize - current_offset); remaining_size.min(range.offset as usize + range.size as usize - current_offset);
current_offset += push_size; current_offset += push_size;
@ -1140,7 +1141,8 @@ impl RawRecordingCommandBuffer {
break; break;
} }
// push the minimum of the whole remaining data, and the part until the end of this range // push the minimum of the whole remaining data, and the part until the end of this
// range
let push_size = remaining_size.min(range.offset + range.size - current_offset); let push_size = remaining_size.min(range.offset + range.size - current_offset);
let data_offset = (current_offset - offset) as usize; let data_offset = (current_offset - offset) as usize;
debug_assert!(data_offset < size as usize); debug_assert!(data_offset < size as usize);

View File

@ -25,8 +25,7 @@ impl RecordingCommandBuffer {
/// ///
/// # Panics /// # Panics
/// ///
/// - Panics if `src_buffer` or `dst_buffer` were not created from the same device /// - Panics if `src_buffer` or `dst_buffer` were not created from the same device as `self`.
/// as `self`.
pub fn copy_buffer( pub fn copy_buffer(
&mut self, &mut self,
copy_buffer_info: impl Into<CopyBufferInfo>, copy_buffer_info: impl Into<CopyBufferInfo>,
@ -125,8 +124,7 @@ impl RecordingCommandBuffer {
/// ///
/// # Panics /// # Panics
/// ///
/// - Panics if `src_image` or `dst_image` were not created from the same device /// - Panics if `src_image` or `dst_image` were not created from the same device as `self`.
/// as `self`.
pub fn copy_image( pub fn copy_image(
&mut self, &mut self,
copy_image_info: CopyImageInfo, copy_image_info: CopyImageInfo,
@ -501,8 +499,7 @@ impl RecordingCommandBuffer {
/// ///
/// # Panics /// # Panics
/// ///
/// - Panics if `src_image` or `dst_image` were not created from the same device /// - Panics if `src_image` or `dst_image` were not created from the same device as `self`.
/// as `self`.
pub fn resolve_image( pub fn resolve_image(
&mut self, &mut self,
resolve_image_info: ResolveImageInfo, resolve_image_info: ResolveImageInfo,
@ -5233,7 +5230,8 @@ pub struct BlitImageInfo {
/// ///
/// The default value is a single region, covering the first mip level, and the smallest of the /// The default value is a single region, covering the first mip level, and the smallest of the
/// array layers of the two images. The whole extent of each image is covered, scaling if /// array layers of the two images. The whole extent of each image is covered, scaling if
/// necessary. All aspects of each image are selected, or `plane0` if the image is multi-planar. /// necessary. All aspects of each image are selected, or `plane0` if the image is
/// multi-planar.
pub regions: SmallVec<[ImageBlit; 1]>, pub regions: SmallVec<[ImageBlit; 1]>,
/// The filter to use for sampling `src_image` when the `src_extent` and /// The filter to use for sampling `src_image` when the `src_extent` and

View File

@ -214,10 +214,10 @@ impl RecordingCommandBuffer {
/// and `first_instance` as 0. /// and `first_instance` as 0.
/// ///
/// A primitive shading graphics pipeline must have been bound using /// A primitive shading graphics pipeline must have been bound using
/// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). Any resources used by the graphics /// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). Any resources used by the
/// pipeline, such as descriptor sets, vertex buffers and dynamic state, must have been set /// graphics pipeline, such as descriptor sets, vertex buffers and dynamic state, must have
/// beforehand. If the bound graphics pipeline uses vertex buffers, then the provided vertex and /// been set beforehand. If the bound graphics pipeline uses vertex buffers, then the
/// instance ranges must be in range of the bound vertex buffers. /// provided vertex and instance ranges must be in range of the bound vertex buffers.
/// ///
/// # Safety /// # Safety
/// ///
@ -404,17 +404,16 @@ impl RecordingCommandBuffer {
/// enabled. /// enabled.
/// ///
/// A primitive shading graphics pipeline must have been bound using /// A primitive shading graphics pipeline must have been bound using
/// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). Any resources used by the graphics /// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). Any resources used by the
/// pipeline, such as descriptor sets, vertex buffers and dynamic state, must have been set /// graphics pipeline, such as descriptor sets, vertex buffers and dynamic state, must have
/// beforehand. If the bound graphics pipeline uses vertex buffers, then the vertex and instance /// been set beforehand. If the bound graphics pipeline uses vertex buffers, then the
/// ranges of each `DrawIndirectCommand` in the indirect buffer must be in range of the bound /// vertex and instance ranges of each `DrawIndirectCommand` in the indirect buffer must be
/// vertex buffers. /// in range of the bound vertex buffers.
/// ///
/// # Safety /// # Safety
/// ///
/// - The general [shader safety requirements](crate::shader#safety) apply. /// - The general [shader safety requirements](crate::shader#safety) apply.
/// - The [safety requirements for `DrawIndirectCommand`](DrawIndirectCommand#safety) /// - The [safety requirements for `DrawIndirectCommand`](DrawIndirectCommand#safety) apply.
/// apply.
pub unsafe fn draw_indirect( pub unsafe fn draw_indirect(
&mut self, &mut self,
indirect_buffer: Subbuffer<[DrawIndirectCommand]>, indirect_buffer: Subbuffer<[DrawIndirectCommand]>,
@ -512,17 +511,16 @@ impl RecordingCommandBuffer {
/// [`max_draw_indirect_count`](Properties::max_draw_indirect_count) limit. /// [`max_draw_indirect_count`](Properties::max_draw_indirect_count) limit.
/// ///
/// A primitive shading graphics pipeline must have been bound using /// A primitive shading graphics pipeline must have been bound using
/// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). Any resources used by the graphics /// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). Any resources used by the
/// pipeline, such as descriptor sets, vertex buffers and dynamic state, must have been set /// graphics pipeline, such as descriptor sets, vertex buffers and dynamic state, must have
/// beforehand. If the bound graphics pipeline uses vertex buffers, then the vertex and instance /// been set beforehand. If the bound graphics pipeline uses vertex buffers, then the
/// ranges of each `DrawIndirectCommand` in the indirect buffer must be in range of the bound /// vertex and instance ranges of each `DrawIndirectCommand` in the indirect buffer must be
/// vertex buffers. /// in range of the bound vertex buffers.
/// ///
/// # Safety /// # Safety
/// ///
/// - The general [shader safety requirements](crate::shader#safety) apply. /// - The general [shader safety requirements](crate::shader#safety) apply.
/// - The [safety requirements for `DrawIndirectCommand`](DrawIndirectCommand#safety) /// - The [safety requirements for `DrawIndirectCommand`](DrawIndirectCommand#safety) apply.
/// apply.
/// - The count stored in `count_buffer` must not be greater than the /// - The count stored in `count_buffer` must not be greater than the
/// [`max_draw_indirect_count`](Properties::max_draw_indirect_count) device limit. /// [`max_draw_indirect_count`](Properties::max_draw_indirect_count) device limit.
/// - The count stored in `count_buffer` must fall within the range of `indirect_buffer`. /// - The count stored in `count_buffer` must fall within the range of `indirect_buffer`.
@ -652,11 +650,11 @@ impl RecordingCommandBuffer {
/// range of the bound index buffer. /// range of the bound index buffer.
/// ///
/// A primitive shading graphics pipeline must have been bound using /// A primitive shading graphics pipeline must have been bound using
/// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). Any resources used by the graphics /// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). Any resources used by the
/// pipeline, such as descriptor sets, vertex buffers and dynamic state, must have been set /// graphics pipeline, such as descriptor sets, vertex buffers and dynamic state, must have
/// beforehand. If the bound graphics pipeline uses vertex buffers, then the provided instance /// been set beforehand. If the bound graphics pipeline uses vertex buffers, then the
/// range must be in range of the bound vertex buffers. The vertex indices in the index buffer /// provided instance range must be in range of the bound vertex buffers. The vertex
/// must be in range of the bound vertex buffers. /// indices in the index buffer must be in range of the bound vertex buffers.
/// ///
/// # Safety /// # Safety
/// ///
@ -891,17 +889,17 @@ impl RecordingCommandBuffer {
/// buffer. /// buffer.
/// ///
/// A primitive shading graphics pipeline must have been bound using /// A primitive shading graphics pipeline must have been bound using
/// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). Any resources used by the graphics /// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). Any resources used by the
/// pipeline, such as descriptor sets, vertex buffers and dynamic state, must have been set /// graphics pipeline, such as descriptor sets, vertex buffers and dynamic state, must have
/// beforehand. If the bound graphics pipeline uses vertex buffers, then the instance ranges of /// been set beforehand. If the bound graphics pipeline uses vertex buffers, then the
/// each `DrawIndexedIndirectCommand` in the indirect buffer must be in range of the bound /// instance ranges of each `DrawIndexedIndirectCommand` in the indirect buffer must be in
/// vertex buffers. /// range of the bound vertex buffers.
/// ///
/// # Safety /// # Safety
/// ///
/// - The general [shader safety requirements](crate::shader#safety) apply. /// - The general [shader safety requirements](crate::shader#safety) apply.
/// - The [safety requirements for `DrawIndexedIndirectCommand`](DrawIndexedIndirectCommand#safety) /// - The [safety requirements for
/// apply. /// `DrawIndexedIndirectCommand`](DrawIndexedIndirectCommand#safety) apply.
pub unsafe fn draw_indexed_indirect( pub unsafe fn draw_indexed_indirect(
&mut self, &mut self,
indirect_buffer: Subbuffer<[DrawIndexedIndirectCommand]>, indirect_buffer: Subbuffer<[DrawIndexedIndirectCommand]>,
@ -1013,17 +1011,17 @@ impl RecordingCommandBuffer {
/// buffer. /// buffer.
/// ///
/// A primitive shading graphics pipeline must have been bound using /// A primitive shading graphics pipeline must have been bound using
/// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). Any resources used by the graphics /// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). Any resources used by the
/// pipeline, such as descriptor sets, vertex buffers and dynamic state, must have been set /// graphics pipeline, such as descriptor sets, vertex buffers and dynamic state, must have
/// beforehand. If the bound graphics pipeline uses vertex buffers, then the instance ranges of /// been set beforehand. If the bound graphics pipeline uses vertex buffers, then the
/// each `DrawIndexedIndirectCommand` in the indirect buffer must be in range of the bound /// instance ranges of each `DrawIndexedIndirectCommand` in the indirect buffer must be in
/// vertex buffers. /// range of the bound vertex buffers.
/// ///
/// # Safety /// # Safety
/// ///
/// - The general [shader safety requirements](crate::shader#safety) apply. /// - The general [shader safety requirements](crate::shader#safety) apply.
/// - The [safety requirements for `DrawIndexedIndirectCommand`](DrawIndexedIndirectCommand#safety) /// - The [safety requirements for
/// apply. /// `DrawIndexedIndirectCommand`](DrawIndexedIndirectCommand#safety) apply.
/// - The count stored in `count_buffer` must not be greater than the /// - The count stored in `count_buffer` must not be greater than the
/// [`max_draw_indirect_count`](Properties::max_draw_indirect_count) device limit. /// [`max_draw_indirect_count`](Properties::max_draw_indirect_count) device limit.
/// - The count stored in `count_buffer` must fall within the range of `indirect_buffer`. /// - The count stored in `count_buffer` must fall within the range of `indirect_buffer`.
@ -1152,7 +1150,8 @@ impl RecordingCommandBuffer {
/// ///
/// A mesh shading graphics pipeline must have been bound using /// A mesh shading graphics pipeline must have been bound using
/// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). Any resources used by the /// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). Any resources used by the
/// graphics pipeline, such as descriptor sets and dynamic state, must have been set beforehand. /// graphics pipeline, such as descriptor sets and dynamic state, must have been set
/// beforehand.
/// ///
/// # Safety /// # Safety
/// ///
@ -1336,16 +1335,17 @@ impl RecordingCommandBuffer {
/// Perform multiple draw operations using a mesh shading graphics pipeline. /// Perform multiple draw operations using a mesh shading graphics pipeline.
/// ///
/// One draw is performed for each [`DrawMeshTasksIndirectCommand`] struct in `indirect_buffer`. /// One draw is performed for each [`DrawMeshTasksIndirectCommand`] struct in
/// The maximum number of draw commands in the buffer is limited by the /// `indirect_buffer`. The maximum number of draw commands in the buffer is limited by the
/// [`max_draw_indirect_count`](Properties::max_draw_indirect_count) limit. /// [`max_draw_indirect_count`](Properties::max_draw_indirect_count) limit.
/// This limit is 1 unless the /// This limit is 1 unless the
/// [`multi_draw_indirect`](Features::multi_draw_indirect) feature has been /// [`multi_draw_indirect`](Features::multi_draw_indirect) feature has been
/// enabled. /// enabled.
/// ///
/// A mesh shading graphics pipeline must have been bound using /// A mesh shading graphics pipeline must have been bound using
/// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). Any resources used by the graphics /// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). Any resources used by the
/// pipeline, such as descriptor sets and dynamic state, must have been set beforehand. /// graphics pipeline, such as descriptor sets and dynamic state, must have been set
/// beforehand.
/// ///
/// # Safety /// # Safety
/// ///
@ -1458,8 +1458,9 @@ impl RecordingCommandBuffer {
/// [`max_draw_indirect_count`](Properties::max_draw_indirect_count) limit. /// [`max_draw_indirect_count`](Properties::max_draw_indirect_count) limit.
/// ///
/// A mesh shading graphics pipeline must have been bound using /// A mesh shading graphics pipeline must have been bound using
/// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). Any resources used by the graphics /// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). Any resources used by the
/// pipeline, such as descriptor sets and dynamic state, must have been set beforehand. /// graphics pipeline, such as descriptor sets and dynamic state, must have been set
/// beforehand.
/// ///
/// # Safety /// # Safety
/// ///
@ -1886,11 +1887,11 @@ impl RecordingCommandBuffer {
})); }));
} }
// - If the Sampled Type of the OpTypeImage does not match the numeric format of the // - If the Sampled Type of the OpTypeImage does not match the numeric format of
// image, as shown in the SPIR-V Sampled Type column of the // the image, as shown in the SPIR-V Sampled Type column of the Interpretation
// Interpretation of Numeric Format table. // of Numeric Format table.
// - If the signedness of any read or sample operation does not match the signedness of // - If the signedness of any read or sample operation does not match the
// the images format. // signedness of the images format.
if let Some(shader_numeric_type) = binding_reqs.image_scalar_type { if let Some(shader_numeric_type) = binding_reqs.image_scalar_type {
let aspects = image_view.subresource_range().aspects; let aspects = image_view.subresource_range().aspects;
let view_numeric_type = NumericType::from( let view_numeric_type = NumericType::from(
@ -1955,10 +1956,11 @@ impl RecordingCommandBuffer {
})); }));
} }
// - OpImageFetch, OpImageSparseFetch, OpImage*Gather, and OpImageSparse*Gather must not // - OpImageFetch, OpImageSparseFetch, OpImage*Gather, and
// be used with a sampler that enables sampler YCBCR conversion. // OpImageSparse*Gather must not be used with a sampler that enables
// - The ConstOffset and Offset operands must not be used with a sampler that enables
// sampler YCBCR conversion. // sampler YCBCR conversion.
// - The ConstOffset and Offset operands must not be used with a sampler
// that enables sampler YCBCR conversion.
if desc_reqs.sampler_no_ycbcr_conversion if desc_reqs.sampler_no_ycbcr_conversion
&& sampler.sampler_ycbcr_conversion().is_some() && sampler.sampler_ycbcr_conversion().is_some()
{ {
@ -1983,8 +1985,8 @@ impl RecordingCommandBuffer {
*/ */
if desc_reqs.sampler_compare && sampler.compare().is_none() { if desc_reqs.sampler_compare && sampler.compare().is_none() {
// - The SPIR-V instruction is one of the OpImage*Dref* instructions and the sampler // - The SPIR-V instruction is one of the OpImage*Dref* instructions and
// compareEnable is VK_FALSE // the sampler compareEnable is VK_FALSE
return Err(Box::new(ValidationError { return Err(Box::new(ValidationError {
problem: format!( problem: format!(
"the currently bound pipeline accesses the sampler bound to \ "the currently bound pipeline accesses the sampler bound to \
@ -1998,8 +2000,8 @@ impl RecordingCommandBuffer {
..Default::default() ..Default::default()
})); }));
} else if !desc_reqs.sampler_compare && sampler.compare().is_some() { } else if !desc_reqs.sampler_compare && sampler.compare().is_some() {
// - The SPIR-V instruction is not one of the OpImage*Dref* instructions and the sampler // - The SPIR-V instruction is not one of the OpImage*Dref* instructions
// compareEnable is VK_TRUE // and the sampler compareEnable is VK_TRUE
return Err(Box::new(ValidationError { return Err(Box::new(ValidationError {
problem: format!( problem: format!(
"the currently bound pipeline accesses the sampler bound to \ "the currently bound pipeline accesses the sampler bound to \
@ -2908,7 +2910,8 @@ impl RecordingCommandBuffer {
} }
} }
// DynamicState::RayTracingPipelineStackSize => unreachable!( // DynamicState::RayTracingPipelineStackSize => unreachable!(
// "RayTracingPipelineStackSize dynamic state should not occur on a graphics pipeline" // "RayTracingPipelineStackSize dynamic state should not occur on a graphics \
// pipeline",
// ), // ),
// DynamicState::SampleLocations => todo!(), // DynamicState::SampleLocations => todo!(),
DynamicState::Scissor => { DynamicState::Scissor => {
@ -3188,12 +3191,14 @@ impl RecordingCommandBuffer {
} }
// TODO: VUID-vkCmdDrawIndexed-primitiveFragmentShadingRateWithMultipleViewports-04552 // TODO: VUID-vkCmdDrawIndexed-primitiveFragmentShadingRateWithMultipleViewports-04552
// If the primitiveFragmentShadingRateWithMultipleViewports limit is not supported, // If the primitiveFragmentShadingRateWithMultipleViewports limit is not
// the bound graphics pipeline was created with the // supported, the bound graphics pipeline was created with
// VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT dynamic state enabled, and any of the // the VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT dynamic
// shader stages of the bound graphics pipeline write to the PrimitiveShadingRateKHR // state enabled, and any of the shader stages of the bound
// built-in, then vkCmdSetViewportWithCountEXT must have been called in the current // graphics pipeline write to the PrimitiveShadingRateKHR
// command buffer prior to this drawing command, and the viewportCount parameter of // built-in, then vkCmdSetViewportWithCountEXT must have been called in the
// current command buffer prior to this drawing command, and
// the viewportCount parameter of
// vkCmdSetViewportWithCountEXT must be 1 // vkCmdSetViewportWithCountEXT must be 1
} }
} }

View File

@ -67,8 +67,10 @@ impl RecordingCommandBuffer {
// TODO: // TODO:
// VUID-vkCmdBeginRenderPass2-framebuffer-02533 // VUID-vkCmdBeginRenderPass2-framebuffer-02533
// For any attachment in framebuffer that is used by renderPass and is bound to memory locations that are also bound to another attachment used by renderPass, and if at least one of those uses causes either // For any attachment in framebuffer that is used by renderPass and is bound to memory
// attachment to be written to, both attachments must have had the VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT set // locations that are also bound to another attachment used by renderPass, and if at least
// one of those uses causes either attachment to be written to, both attachments
// must have had the VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT set
Ok(()) Ok(())
} }
@ -638,7 +640,8 @@ impl RecordingCommandBuffer {
/// `rects` specify the regions to clear. /// `rects` specify the regions to clear.
/// ///
/// A graphics pipeline must have been bound using /// A graphics pipeline must have been bound using
/// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). And the command must be inside render pass. /// [`bind_pipeline_graphics`](Self::bind_pipeline_graphics). And the command must be inside
/// render pass.
/// ///
/// If the render pass instance this is recorded in uses multiview, /// If the render pass instance this is recorded in uses multiview,
/// then `ClearRect.base_array_layer` must be zero and `ClearRect.layer_count` must be one. /// then `ClearRect.base_array_layer` must be zero and `ClearRect.layer_count` must be one.
@ -1223,8 +1226,10 @@ impl RawRecordingCommandBuffer {
// TODO: // TODO:
// VUID-vkCmdBeginRenderPass2-framebuffer-02533 // VUID-vkCmdBeginRenderPass2-framebuffer-02533
// For any attachment in framebuffer that is used by renderPass and is bound to memory locations that are also bound to another attachment used by renderPass, and if at least one of those uses causes either // For any attachment in framebuffer that is used by renderPass and is bound to memory
// attachment to be written to, both attachments must have had the VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT set // locations that are also bound to another attachment used by renderPass, and if at least
// one of those uses causes either attachment to be written to, both attachments
// must have had the VK_ATTACHMENT_DESCRIPTION_MAY_ALIAS_BIT set
Ok(()) Ok(())
} }
@ -1825,7 +1830,8 @@ pub struct RenderPassBeginInfo {
/// The size of the area that will be rendered to. /// The size of the area that will be rendered to.
/// ///
/// `render_area_offset + render_area_extent` must not be greater than [`framebuffer.extent()`]. /// `render_area_offset + render_area_extent` must not be greater than
/// [`framebuffer.extent()`].
/// ///
/// The default value is [`framebuffer.extent()`]. /// The default value is [`framebuffer.extent()`].
pub render_area_extent: [u32; 2], pub render_area_extent: [u32; 2],

View File

@ -22,8 +22,8 @@
//! //!
//! There are two levels of command buffers: //! There are two levels of command buffers:
//! //!
//! - A primary command buffer can be executed on a queue, and is the main command buffer level. //! - A primary command buffer can be executed on a queue, and is the main command buffer level. It
//! It cannot be executed within another command buffer. //! cannot be executed within another command buffer.
//! - A secondary command buffer can only be executed within a primary command buffer, not directly //! - A secondary command buffer can only be executed within a primary command buffer, not directly
//! on a queue. //! on a queue.
//! //!
@ -155,15 +155,15 @@ pub struct DispatchIndirectCommand {
/// ///
/// # Safety /// # Safety
/// ///
/// - Every vertex number within the specified range must fall within the range of /// - Every vertex number within the specified range must fall within the range of the bound
/// the bound vertex-rate vertex buffers. /// vertex-rate vertex buffers.
/// - Every instance number within the specified range must fall within the range of /// - Every instance number within the specified range must fall within the range of the bound
/// the bound instance-rate vertex buffers. /// instance-rate vertex buffers.
/// - If the [`draw_indirect_first_instance`](Features::draw_indirect_first_instance) feature /// - If the [`draw_indirect_first_instance`](Features::draw_indirect_first_instance) feature is
/// is not enabled, then `first_instance` must be `0`. /// not enabled, then `first_instance` must be `0`.
/// - If an [instance divisor](VertexInputRate::Instance) other than 1 is used, and /// - If an [instance divisor](VertexInputRate::Instance) other than 1 is used, and the
/// the [`supports_non_zero_first_instance`](Properties::supports_non_zero_first_instance) /// [`supports_non_zero_first_instance`](Properties::supports_non_zero_first_instance) device
/// device property is `false`, then `first_instance` must be `0`. /// property is `false`, then `first_instance` must be `0`.
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug, Default, Zeroable, Pod, PartialEq, Eq)] #[derive(Clone, Copy, Debug, Default, Zeroable, Pod, PartialEq, Eq)]
pub struct DrawIndirectCommand { pub struct DrawIndirectCommand {
@ -178,18 +178,18 @@ pub struct DrawIndirectCommand {
/// ///
/// # Safety /// # Safety
/// ///
/// - If the graphics pipeline **does not** include a task shader, then the /// - If the graphics pipeline **does not** include a task shader, then the `group_count_x`,
/// `group_count_x`, `group_count_y` and `group_count_z` values must not be greater than the /// `group_count_y` and `group_count_z` values must not be greater than the respective elements
/// respective elements of the /// of the [`max_mesh_work_group_count`](Properties::max_mesh_work_group_count) device limit, and
/// [`max_mesh_work_group_count`](Properties::max_mesh_work_group_count) device limit, /// the product of these three values must not be greater than the
/// and the product of these three values must not be greater than the /// [`max_mesh_work_group_total_count`](Properties::max_mesh_work_group_total_count) device
/// [`max_mesh_work_group_total_count`](Properties::max_mesh_work_group_total_count) device limit. /// limit.
/// - If the graphics pipeline **does** include a task shader, then the /// - If the graphics pipeline **does** include a task shader, then the `group_count_x`,
/// `group_count_x`, `group_count_y` and `group_count_z` values must not be greater than the /// `group_count_y` and `group_count_z` values must not be greater than the respective elements
/// respective elements of the /// of the [`max_task_work_group_count`](Properties::max_task_work_group_count) device limit, and
/// [`max_task_work_group_count`](Properties::max_task_work_group_count) device limit, /// the product of these three values must not be greater than the
/// and the product of these three values must not be greater than the /// [`max_task_work_group_total_count`](Properties::max_task_work_group_total_count) device
/// [`max_task_work_group_total_count`](Properties::max_task_work_group_total_count) device limit. /// limit.
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug, Default, Zeroable, Pod, PartialEq, Eq)] #[derive(Clone, Copy, Debug, Default, Zeroable, Pod, PartialEq, Eq)]
pub struct DrawMeshTasksIndirectCommand { pub struct DrawMeshTasksIndirectCommand {
@ -204,18 +204,18 @@ pub struct DrawMeshTasksIndirectCommand {
/// # Safety /// # Safety
/// ///
/// - Every index within the specified range must fall within the range of the bound index buffer. /// - Every index within the specified range must fall within the range of the bound index buffer.
/// - Every vertex number that is retrieved from the index buffer must fall within the range of /// - Every vertex number that is retrieved from the index buffer must fall within the range of the
/// the bound vertex-rate vertex buffers. /// bound vertex-rate vertex buffers.
/// - Every vertex number that is retrieved from the index buffer, if it is not the special /// - Every vertex number that is retrieved from the index buffer, if it is not the special
/// primitive restart value, must be no greater than the /// primitive restart value, must be no greater than the
/// [`max_draw_indexed_index_value`](Properties::max_draw_indexed_index_value) device limit. /// [`max_draw_indexed_index_value`](Properties::max_draw_indexed_index_value) device limit.
/// - Every instance number within the specified range must fall within the range of /// - Every instance number within the specified range must fall within the range of the bound
/// the bound instance-rate vertex buffers. /// instance-rate vertex buffers.
/// - If the [`draw_indirect_first_instance`](Features::draw_indirect_first_instance) feature /// - If the [`draw_indirect_first_instance`](Features::draw_indirect_first_instance) feature is
/// is not enabled, then `first_instance` must be `0`. /// not enabled, then `first_instance` must be `0`.
/// - If an [instance divisor](VertexInputRate::Instance) other than 1 is used, and /// - If an [instance divisor](VertexInputRate::Instance) other than 1 is used, and the
/// the [`supports_non_zero_first_instance`](Properties::supports_non_zero_first_instance) /// [`supports_non_zero_first_instance`](Properties::supports_non_zero_first_instance) device
/// device property is `false`, then `first_instance` must be `0`. /// property is `false`, then `first_instance` must be `0`.
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug, Default, Zeroable, Pod, PartialEq, Eq)] #[derive(Clone, Copy, Debug, Default, Zeroable, Pod, PartialEq, Eq)]
pub struct DrawIndexedIndirectCommand { pub struct DrawIndexedIndirectCommand {
@ -747,8 +747,9 @@ pub enum CommandBufferUsage {
/// optimizations. /// optimizations.
OneTimeSubmit = ash::vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT.as_raw(), OneTimeSubmit = ash::vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT.as_raw(),
/// The command buffer can be used multiple times, but must not execute or record more than once /// The command buffer can be used multiple times, but must not execute or record more than
/// simultaneously. In other words, it is as if executing the command buffer borrows it mutably. /// once simultaneously. In other words, it is as if executing the command buffer borrows
/// it mutably.
MultipleSubmit = 0, MultipleSubmit = 0,
/// The command buffer can be executed multiple times in parallel on different queues. /// The command buffer can be executed multiple times in parallel on different queues.
@ -907,10 +908,10 @@ pub struct SemaphoreSubmitInfo {
/// If `semaphore.semaphore_type()` is [`SemaphoreType::Timeline`], specifies the value that /// If `semaphore.semaphore_type()` is [`SemaphoreType::Timeline`], specifies the value that
/// will be used for the semaphore operation: /// will be used for the semaphore operation:
/// - If it's a signal operation, then the semaphore's value will be set to this value /// - If it's a signal operation, then the semaphore's value will be set to this value when it
/// when it is signaled. /// is signaled.
/// - If it's a wait operation, then the semaphore will wait until its value is greater than /// - If it's a wait operation, then the semaphore will wait until its value is greater than or
/// or equal to this value. /// equal to this value.
/// ///
/// If `semaphore.semaphore_type()` is [`SemaphoreType::Binary`], then this must be `0`. /// If `semaphore.semaphore_type()` is [`SemaphoreType::Binary`], then this must be `0`.
/// ///
@ -921,9 +922,9 @@ pub struct SemaphoreSubmitInfo {
/// scope: stages of queue operations following the wait operation that can start executing /// scope: stages of queue operations following the wait operation that can start executing
/// after the semaphore is signalled. /// after the semaphore is signalled.
/// ///
/// For a semaphore signal operation, specifies the pipeline stages in the first synchronization /// For a semaphore signal operation, specifies the pipeline stages in the first
/// scope: stages of queue operations preceding the signal operation that must complete before /// synchronization scope: stages of queue operations preceding the signal operation that
/// the semaphore is signalled. /// must complete before the semaphore is signalled.
/// If this value does not equal [`ALL_COMMANDS`], then the [`synchronization2`] feature must /// If this value does not equal [`ALL_COMMANDS`], then the [`synchronization2`] feature must
/// be enabled on the device. /// be enabled on the device.
/// ///

View File

@ -183,14 +183,13 @@ impl DescriptorPool {
/// ///
/// # Safety /// # Safety
/// ///
/// - When the pool is dropped, the returned descriptor sets must not be in use by either /// - When the pool is dropped, the returned descriptor sets must not be in use by either the
/// the host or device. /// host or device.
/// - If the device API version is less than 1.1, and the [`khr_maintenance1`] extension is not /// - If the device API version is less than 1.1, and the [`khr_maintenance1`] extension is not
/// enabled on the device, then /// enabled on the device, then the length of `allocate_infos` must not be greater than the
/// the length of `allocate_infos` must not be greater than the number of descriptor sets /// number of descriptor sets remaining in the pool, and the total number of descriptors of
/// remaining in the pool, and /// each type being allocated must not be greater than the number of descriptors of that type
/// the total number of descriptors of each type being allocated must not be greater than the /// remaining in the pool.
/// number of descriptors of that type remaining in the pool.
/// ///
/// [`khr_maintenance1`]: crate::device::DeviceExtensions::khr_maintenance1 /// [`khr_maintenance1`]: crate::device::DeviceExtensions::khr_maintenance1
#[inline] #[inline]
@ -339,8 +338,8 @@ impl DescriptorPool {
/// ///
/// # Safety /// # Safety
/// ///
/// - All elements of `descriptor_sets` must have been allocated from `self`, /// - All elements of `descriptor_sets` must have been allocated from `self`, and not freed
/// and not freed previously. /// previously.
/// - All elements of `descriptor_sets` must not be in use by the host or device. /// - All elements of `descriptor_sets` must not be in use by the host or device.
#[inline] #[inline]
pub unsafe fn free_descriptor_sets( pub unsafe fn free_descriptor_sets(

View File

@ -28,8 +28,8 @@ use std::{ops::Range, ptr, sync::Arc};
/// provided for each resource type: /// provided for each resource type:
/// - The basic constructor variant writes a single element to array index 0. It is intended for /// - The basic constructor variant writes a single element to array index 0. It is intended for
/// non-arrayed bindings, where `descriptor_count` in the descriptor set layout is 1. /// non-arrayed bindings, where `descriptor_count` in the descriptor set layout is 1.
/// - The `_array` variant writes several elements and allows specifying the target array index. /// - The `_array` variant writes several elements and allows specifying the target array index. At
/// At least one element must be provided; a panic results if the provided iterator is empty. /// least one element must be provided; a panic results if the provided iterator is empty.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct WriteDescriptorSet { pub struct WriteDescriptorSet {
binding: u32, binding: u32,
@ -44,8 +44,8 @@ impl WriteDescriptorSet {
/// immutable samplers in the layout. The Vulkan spec requires these elements to be explicitly /// immutable samplers in the layout. The Vulkan spec requires these elements to be explicitly
/// written, but since there is no data to write, a dummy write is provided instead. /// written, but since there is no data to write, a dummy write is provided instead.
/// ///
/// For regular descriptor sets, the data for such descriptors is automatically valid, and dummy /// For regular descriptor sets, the data for such descriptors is automatically valid, and
/// writes are not allowed. /// dummy writes are not allowed.
#[inline] #[inline]
pub fn none(binding: u32) -> Self { pub fn none(binding: u32) -> Self {
Self::none_array(binding, 0, 1) Self::none_array(binding, 0, 1)

View File

@ -1240,7 +1240,8 @@ pub struct DeviceCreateInfo {
/// If the [`khr_portability_subset`](DeviceExtensions::khr_portability_subset) extension is /// If the [`khr_portability_subset`](DeviceExtensions::khr_portability_subset) extension is
/// available, it will be enabled automatically, so you do not have to do this yourself. /// available, it will be enabled automatically, so you do not have to do this yourself.
/// You are responsible for ensuring that your program can work correctly on such devices. /// You are responsible for ensuring that your program can work correctly on such devices.
/// See [the documentation of the `instance` module](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag) /// See [the documentation of the `instance`
/// module](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag)
/// for more information. /// for more information.
/// ///
/// The default value is [`DeviceExtensions::empty()`]. /// The default value is [`DeviceExtensions::empty()`].
@ -1648,9 +1649,9 @@ pub struct QueueCreateInfo {
/// The queues to create for the given queue family, each with a relative priority. /// The queues to create for the given queue family, each with a relative priority.
/// ///
/// The relative priority value is an arbitrary number between 0.0 and 1.0. Giving a queue a /// The relative priority value is an arbitrary number between 0.0 and 1.0. Giving a queue a
/// higher priority is a hint to the driver that the queue should be given more processing time. /// higher priority is a hint to the driver that the queue should be given more processing
/// As this is only a hint, different drivers may handle this value differently and there are no /// time. As this is only a hint, different drivers may handle this value differently and
/// guarantees about its behavior. /// there are no guarantees about its behavior.
/// ///
/// The default value is a single queue with a priority of 0.5. /// The default value is a single queue with a priority of 0.5.
pub queues: Vec<f32>, pub queues: Vec<f32>,

View File

@ -2286,8 +2286,8 @@ impl PhysicalDevice {
}) })
} }
/// Returns the combinations of format and color space that are supported by the physical device /// Returns the combinations of format and color space that are supported by the physical
/// for the given surface. /// device for the given surface.
/// ///
/// The results of this function are cached, so that future calls with the same arguments /// The results of this function are cached, so that future calls with the same arguments
/// do not need to make a call to the Vulkan API again. /// do not need to make a call to the Vulkan API again.
@ -3073,8 +3073,8 @@ impl PhysicalDevice {
) != 0 ) != 0
} }
/// Queries whether the physical device supports presenting to Win32 surfaces from queues of the /// Queries whether the physical device supports presenting to Win32 surfaces from queues of
/// given queue family. /// the given queue family.
#[inline] #[inline]
pub fn win32_presentation_support( pub fn win32_presentation_support(
&self, &self,

View File

@ -453,7 +453,8 @@ impl<'a> QueueGuard<'a> {
/// - The semaphore must be kept alive while the command is being executed. /// - The semaphore must be kept alive while the command is being executed.
/// - The semaphore must be already in the signaled state, or there must be a previously /// - The semaphore must be already in the signaled state, or there must be a previously
/// submitted operation that will signal it. /// submitted operation that will signal it.
/// - When the wait operation is executed, no other queue must be waiting on the same semaphore. /// - When the wait operation is executed, no other queue must be waiting on the same
/// semaphore.
/// ///
/// For every element of `present_info.swapchain_infos`: /// For every element of `present_info.swapchain_infos`:
/// - `swapchain` must be kept alive while the command is being executed. /// - `swapchain` must be kept alive while the command is being executed.
@ -461,8 +462,8 @@ impl<'a> QueueGuard<'a> {
/// operation must happen-after the acquire operation. /// operation must happen-after the acquire operation.
/// - The swapchain image indicated by `swapchain` and `image_index` must be in the /// - The swapchain image indicated by `swapchain` and `image_index` must be in the
/// [`ImageLayout::PresentSrc`] layout when the presentation operation is executed. /// [`ImageLayout::PresentSrc`] layout when the presentation operation is executed.
/// - The swapchain image indicated by `swapchain` and `image_index` must not be accessed /// - The swapchain image indicated by `swapchain` and `image_index` must not be accessed after
/// after this function is called, until it is acquired again. /// this function is called, until it is acquired again.
/// - If `present_id` is `Some`, then it must be greater than any present ID previously used /// - If `present_id` is `Some`, then it must be greater than any present ID previously used
/// for the same swapchain. /// for the same swapchain.
/// ///
@ -709,8 +710,8 @@ impl<'a> QueueGuard<'a> {
/// - If the command buffer's `usage` is [`CommandBufferUsage::MultipleSubmit`], then it must /// - If the command buffer's `usage` is [`CommandBufferUsage::MultipleSubmit`], then it must
/// not be currently submitted and not yet completed. /// not be currently submitted and not yet completed.
/// - If a recorded command performs a queue family transfer acquire operation, then a /// - If a recorded command performs a queue family transfer acquire operation, then a
/// corresponding queue family transfer release operation with matching parameters must /// corresponding queue family transfer release operation with matching parameters must have
/// have been previously submitted, and must happen-before it. /// been previously submitted, and must happen-before it.
/// - If a recorded command references an [`Event`], then that `Event` must not be referenced /// - If a recorded command references an [`Event`], then that `Event` must not be referenced
/// by a command that is currently executing on another queue. /// by a command that is currently executing on another queue.
/// ///
@ -1350,7 +1351,8 @@ pub struct QueueFamilyProperties {
/// If timestamps are not supported, this is `None`. /// If timestamps are not supported, this is `None`.
pub timestamp_valid_bits: Option<u32>, pub timestamp_valid_bits: Option<u32>,
/// The minimum granularity supported for image transfers, in terms of `[width, height, depth]`. /// The minimum granularity supported for image transfers, in terms of `[width, height,
/// depth]`.
pub min_image_transfer_granularity: [u32; 3], pub min_image_transfer_granularity: [u32; 3],
} }

View File

@ -13,14 +13,14 @@
//! # Creating surfaces that render directly to a display //! # Creating surfaces that render directly to a display
//! //!
//! - Choose the `Display` that you want to render to. //! - Choose the `Display` that you want to render to.
//! - Get display plane properties with [`PhysicalDevice::display_plane_properties`], //! - Get display plane properties with [`PhysicalDevice::display_plane_properties`], and choose a
//! and choose a display plane index that is supported with the chosen display. //! display plane index that is supported with the chosen display.
//! - Choose a `DisplayMode`, which is the combination of a display, a resolution and a refresh //! - Choose a `DisplayMode`, which is the combination of a display, a resolution and a refresh
//! rate. You can enumerate the modes available on a display with //! rate. You can enumerate the modes available on a display with
//! [`Display::display_mode_properties`], or create your own mode. //! [`Display::display_mode_properties`], or create your own mode. A display can show multiple
//! A display can show multiple planes in a stacking fashion. //! planes in a stacking fashion.
//! - Create a `Surface` object with `Surface::from_display_plane`, //! - Create a `Surface` object with `Surface::from_display_plane`, and pass the chosen
//! and pass the chosen `DisplayMode` and display plane index. //! `DisplayMode` and display plane index.
use crate::{ use crate::{
cache::{OnceCache, WeakArcOnceCache}, cache::{OnceCache, WeakArcOnceCache},
@ -125,7 +125,8 @@ impl Display {
self.plane_reorder_possible self.plane_reorder_possible
} }
/// Returns whether the content of the display is buffered internally, and therefore persistent. /// Returns whether the content of the display is buffered internally, and therefore
/// persistent.
#[inline] #[inline]
pub fn persistent_content(&self) -> bool { pub fn persistent_content(&self) -> bool {
self.persistent_content self.persistent_content

View File

@ -1,16 +1,16 @@
//! All the formats supported by Vulkan. //! All the formats supported by Vulkan.
//! //!
//! A format is mostly used to describe the texel data of an image. However, formats also show up in //! A format is mostly used to describe the texel data of an image. However, formats also show up
//! a few other places, most notably to describe the format of vertex buffers. //! in a few other places, most notably to describe the format of vertex buffers.
//! //!
//! # Format support //! # Format support
//! //!
//! Not all formats are supported by every device. Those that devices do support may only be //! Not all formats are supported by every device. Those that devices do support may only be
//! supported for certain use cases. It is an error to use a format where it is not supported, but //! supported for certain use cases. It is an error to use a format where it is not supported, but
//! you can query a device beforehand for its support by calling `format_properties` on the physical //! you can query a device beforehand for its support by calling `format_properties` on the
//! device. You can use this to select a usable format from one or more suitable alternatives. //! physical device. You can use this to select a usable format from one or more suitable
//! Some formats are required to be always supported for a particular usage. These are listed in the //! alternatives. Some formats are required to be always supported for a particular usage. These
//! [tables in the Vulkan specification](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap43.html#features-required-format-support). //! are listed in the [tables in the Vulkan specification](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap43.html#features-required-format-support).
//! //!
//! # Special format types //! # Special format types
//! //!
@ -27,8 +27,8 @@
//! //!
//! Depth/stencil formats deviate from the others in a few more ways. Their data representation is //! Depth/stencil formats deviate from the others in a few more ways. Their data representation is
//! considered opaque, meaning that they do not have a fixed layout in memory nor a fixed size per //! considered opaque, meaning that they do not have a fixed layout in memory nor a fixed size per
//! texel. They also have special limitations in several operations such as copying; a depth/stencil //! texel. They also have special limitations in several operations such as copying; a
//! format is not compatible with any other format, only with itself. //! depth/stencil format is not compatible with any other format, only with itself.
//! //!
//! ## Block-compressed formats //! ## Block-compressed formats
//! //!
@ -59,10 +59,10 @@
//! requires it. //! requires it.
//! //!
//! Many YCbCr formats make use of **chroma subsampling**. This is a technique whereby the two //! Many YCbCr formats make use of **chroma subsampling**. This is a technique whereby the two
//! chroma components are encoded using a lower resolution than the luma component. The human eye is //! chroma components are encoded using a lower resolution than the luma component. The human eye
//! less sensitive to color detail than to detail in brightness, so this allows more detail to be //! is less sensitive to color detail than to detail in brightness, so this allows more detail to
//! encoded in less data. Chroma subsampling is indicated with one of three numbered suffixes in a //! be encoded in less data. Chroma subsampling is indicated with one of three numbered suffixes in
//! format name: //! a format name:
//! - `444` indicates a YCbCr format without chroma subsampling. All components have the same //! - `444` indicates a YCbCr format without chroma subsampling. All components have the same
//! resolution. //! resolution.
//! - `422` indicates horizontal chroma subsampling. The horizontal resolution of the chroma //! - `422` indicates horizontal chroma subsampling. The horizontal resolution of the chroma
@ -74,9 +74,9 @@
//! of storing the components of a single texel together in memory, the components are separated //! of storing the components of a single texel together in memory, the components are separated
//! into *planes*, which act like independent images. In 3-plane formats, the planes hold the Y, //! into *planes*, which act like independent images. In 3-plane formats, the planes hold the Y,
//! Cb and Cr components respectively, while in 2-plane formats, Cb and Cr are combined into a //! Cb and Cr components respectively, while in 2-plane formats, Cb and Cr are combined into a
//! two-component plane. Where chroma subsampling is applied, plane 0 has the full resolution, while //! two-component plane. Where chroma subsampling is applied, plane 0 has the full resolution,
//! planes 1 and 2 have reduced resolution. Effectively, they are standalone images with half the //! while planes 1 and 2 have reduced resolution. Effectively, they are standalone images with half
//! resolution of the original. //! the resolution of the original.
//! //!
//! The texels of multi-planar images cannot be accessed individually, for example to copy or blit, //! The texels of multi-planar images cannot be accessed individually, for example to copy or blit,
//! since the components of each texel are split across the planes. Instead, you must access each //! since the components of each texel are split across the planes. Instead, you must access each
@ -276,8 +276,8 @@ pub enum NumericFormat {
SSCALED, SSCALED,
/// Unsigned integer that is converted to a floating-point value directly. /// Unsigned integer that is converted to a floating-point value directly.
USCALED, USCALED,
/// Unsigned integer where R, G, B components represent a normalized floating-point value in the /// Unsigned integer where R, G, B components represent a normalized floating-point value in
/// sRGB color space, while the A component is a simple normalized value as in `UNORM`. /// the sRGB color space, while the A component is a simple normalized value as in `UNORM`.
SRGB, SRGB,
} }

View File

@ -1327,8 +1327,7 @@ pub fn max_mip_levels(extent: [u32; 3]) -> u32 {
/// ///
/// # Panics /// # Panics
/// ///
/// - In debug mode, panics if `extent` contains 0. /// - In debug mode, panics if `extent` contains 0. In release, returns an unspecified value.
/// In release, returns an unspecified value.
#[inline] #[inline]
pub fn mip_level_extent(extent: [u32; 3], level: u32) -> Option<[u32; 3]> { pub fn mip_level_extent(extent: [u32; 3], level: u32) -> Option<[u32; 3]> {
if level == 0 { if level == 0 {

View File

@ -19,8 +19,8 @@
//! //!
//! It is possible to provide a *bias* to the base LOD value, which is simply added to it. //! It is possible to provide a *bias* to the base LOD value, which is simply added to it.
//! An LOD bias can be provided both in the sampler object and as part of the sampling operation in //! An LOD bias can be provided both in the sampler object and as part of the sampling operation in
//! the shader, and are combined by addition to produce the final bias value, which is then added to //! the shader, and are combined by addition to produce the final bias value, which is then added
//! the base LOD. //! to the base LOD.
//! //!
//! Once LOD bias has been applied, the resulting value may be *clamped* to a minimum and maximum //! Once LOD bias has been applied, the resulting value may be *clamped* to a minimum and maximum
//! value to provide the final LOD. A maximum may be specified by the sampler, while a minimum //! value to provide the final LOD. A maximum may be specified by the sampler, while a minimum
@ -629,7 +629,8 @@ pub struct SamplerCreateInfo {
/// [`max_sampler_lod_bias`](crate::device::Properties::max_sampler_lod_bias) limit of the /// [`max_sampler_lod_bias`](crate::device::Properties::max_sampler_lod_bias) limit of the
/// device. /// device.
/// ///
/// On [portability subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag) /// On [portability
/// subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag)
/// devices, if `mip_lod_bias` is not `0.0`, the /// devices, if `mip_lod_bias` is not `0.0`, the
/// [`sampler_mip_lod_bias`](crate::device::Features::sampler_mip_lod_bias) /// [`sampler_mip_lod_bias`](crate::device::Features::sampler_mip_lod_bias)
/// feature must be enabled on the device. /// feature must be enabled on the device.
@ -640,8 +641,8 @@ pub struct SamplerCreateInfo {
/// Whether anisotropic texel filtering is enabled (`Some`), and the maximum anisotropy value /// Whether anisotropic texel filtering is enabled (`Some`), and the maximum anisotropy value
/// to use if it is enabled. /// to use if it is enabled.
/// ///
/// Anisotropic filtering is a special filtering mode that takes into account the differences in /// Anisotropic filtering is a special filtering mode that takes into account the differences
/// scaling between the horizontal and vertical framebuffer axes. /// in scaling between the horizontal and vertical framebuffer axes.
/// ///
/// If set to `Some`, the [`sampler_anisotropy`](crate::device::Features::sampler_anisotropy) /// If set to `Some`, the [`sampler_anisotropy`](crate::device::Features::sampler_anisotropy)
/// feature must be enabled on the device, the provided maximum value must not exceed the /// feature must be enabled on the device, the provided maximum value must not exceed the
@ -657,15 +658,16 @@ pub struct SamplerCreateInfo {
/// Depth comparison is an alternative mode for samplers that can be used in combination with /// Depth comparison is an alternative mode for samplers that can be used in combination with
/// image views specifying the depth aspect. Instead of returning a value that is sampled from /// image views specifying the depth aspect. Instead of returning a value that is sampled from
/// the image directly, a comparison operation is applied between the sampled value and a /// the image directly, a comparison operation is applied between the sampled value and a
/// reference value that is specified as part of the operation. The result is binary: 1.0 if the /// reference value that is specified as part of the operation. The result is binary: 1.0 if
/// operation returns `true`, 0.0 if it returns `false`. /// the operation returns `true`, 0.0 if it returns `false`.
/// ///
/// If set to `Some`, the `reduction_mode` must be set to /// If set to `Some`, the `reduction_mode` must be set to
/// [`WeightedAverage`](SamplerReductionMode::WeightedAverage). /// [`WeightedAverage`](SamplerReductionMode::WeightedAverage).
/// ///
/// On [portability subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag) /// On [portability
/// devices, if the sampler is going to be used as a mutable sampler (written to descriptor sets /// subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag)
/// rather than being an immutable part of a descriptor set layout), the /// devices, if the sampler is going to be used as a mutable sampler (written to descriptor
/// sets rather than being an immutable part of a descriptor set layout), the
/// [`mutable_comparison_samplers`](crate::device::Features::mutable_comparison_samplers) /// [`mutable_comparison_samplers`](crate::device::Features::mutable_comparison_samplers)
/// feature must be enabled on the device. /// feature must be enabled on the device.
/// ///

View File

@ -374,8 +374,8 @@ pub struct SamplerYcbcrConversionCreateInfo {
/// The format must support YCbCr conversions, meaning that its `FormatFeatures` must support /// The format must support YCbCr conversions, meaning that its `FormatFeatures` must support
/// at least one of `cosited_chroma_samples` or `midpoint_chroma_samples`. /// at least one of `cosited_chroma_samples` or `midpoint_chroma_samples`.
/// ///
/// If this is set to a format that has chroma subsampling (contains `422` or `420` in the name) /// If this is set to a format that has chroma subsampling (contains `422` or `420` in the
/// then `component_mapping` is restricted as follows: /// name) then `component_mapping` is restricted as follows:
/// - `g` must be identity swizzled. /// - `g` must be identity swizzled.
/// - `a` must be identity swizzled or `Zero` or `One`. /// - `a` must be identity swizzled or `Zero` or `One`.
/// - `r` and `b` must be identity swizzled or mapped to each other. /// - `r` and `b` must be identity swizzled or mapped to each other.
@ -419,8 +419,8 @@ pub struct SamplerYcbcrConversionCreateInfo {
/// The default value is [`CositedEven`](ChromaLocation::CositedEven) for both axes. /// The default value is [`CositedEven`](ChromaLocation::CositedEven) for both axes.
pub chroma_offset: [ChromaLocation; 2], pub chroma_offset: [ChromaLocation; 2],
/// For formats with chroma subsampling, specifies the filter used for reconstructing the chroma /// For formats with chroma subsampling, specifies the filter used for reconstructing the
/// components to full resolution. /// chroma components to full resolution.
/// ///
/// The `Cubic` filter is not supported. If `Linear` is used, the format must support it. /// The `Cubic` filter is not supported. If `Linear` is used, the format must support it.
/// ///

View File

@ -705,14 +705,14 @@ impl RawImage {
/// Binds device memory to this image. /// Binds device memory to this image.
/// ///
/// - If `self.flags()` does not contain `ImageCreateFlags::DISJOINT`, /// - If `self.flags()` does not contain `ImageCreateFlags::DISJOINT`, then `allocations` must
/// then `allocations` must contain exactly one element. /// contain exactly one element.
/// - If `self.flags()` contains `ImageCreateFlags::DISJOINT`, and /// - If `self.flags()` contains `ImageCreateFlags::DISJOINT`, and `self.tiling()` is
/// `self.tiling()` is `ImageTiling::Linear` or `ImageTiling::Optimal`, then /// `ImageTiling::Linear` or `ImageTiling::Optimal`, then `allocations` must contain exactly
/// `allocations` must contain exactly `self.format().unwrap().planes().len()` elements. /// `self.format().unwrap().planes().len()` elements.
/// - If `self.flags()` contains `ImageCreateFlags::DISJOINT`, and /// - If `self.flags()` contains `ImageCreateFlags::DISJOINT`, and `self.tiling()` is
/// `self.tiling()` is `ImageTiling::DrmFormatModifier`, then /// `ImageTiling::DrmFormatModifier`, then `allocations` must contain exactly
/// `allocations` must contain exactly `self.drm_format_modifier().unwrap().1` elements. /// `self.drm_format_modifier().unwrap().1` elements.
/// ///
/// # Safety /// # Safety
/// ///
@ -1106,14 +1106,14 @@ impl RawImage {
/// # Safety /// # Safety
/// ///
/// - If `self.flags()` does not contain `ImageCreateFlags::DISJOINT`, /// - If `self.flags()` does not contain `ImageCreateFlags::DISJOINT`, then `allocations` must
/// then `allocations` must contain exactly one element. /// contain exactly one element.
/// - If `self.flags()` contains `ImageCreateFlags::DISJOINT`, and /// - If `self.flags()` contains `ImageCreateFlags::DISJOINT`, and `self.tiling()` is
/// `self.tiling()` is `ImageTiling::Linear` or `ImageTiling::Optimal`, then /// `ImageTiling::Linear` or `ImageTiling::Optimal`, then `allocations` must contain exactly
/// `allocations` must contain exactly `self.format().unwrap().planes().len()` elements. /// `self.format().unwrap().planes().len()` elements.
/// - If `self.flags()` contains `ImageCreateFlags::DISJOINT`, and /// - If `self.flags()` contains `ImageCreateFlags::DISJOINT`, and `self.tiling()` is
/// `self.tiling()` is `ImageTiling::DrmFormatModifier`, then /// `ImageTiling::DrmFormatModifier`, then `allocations` must contain exactly
/// `allocations` must contain exactly `self.drm_format_modifier().unwrap().1` elements. /// `self.drm_format_modifier().unwrap().1` elements.
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
pub unsafe fn bind_memory_unchecked( pub unsafe fn bind_memory_unchecked(
self, self,
@ -1723,11 +1723,12 @@ pub struct ImageCreateInfo {
/// The formats that an image view can have when it is created from this image. /// The formats that an image view can have when it is created from this image.
/// ///
/// If the list is not empty, and `flags` does not contain [`ImageCreateFlags::MUTABLE_FORMAT`], /// If the list is not empty, and `flags` does not contain
/// then the list must contain at most one element, otherwise any number of elements are /// [`ImageCreateFlags::MUTABLE_FORMAT`], then the list must contain at most one element,
/// allowed. The view formats must be compatible with `format`. If `flags` also contains /// otherwise any number of elements are allowed. The view formats must be compatible with
/// [`ImageCreateFlags::BLOCK_TEXEL_VIEW_COMPATIBLE`], then the view formats can also be /// `format`. If `flags` also contains [`ImageCreateFlags::BLOCK_TEXEL_VIEW_COMPATIBLE`],
/// uncompressed formats that are merely size-compatible with `format`. /// then the view formats can also be uncompressed formats that are merely size-compatible
/// with `format`.
/// ///
/// If the list is empty, then depending on `flags`, a view must have the same format as /// If the list is empty, then depending on `flags`, a view must have the same format as
/// `format`, can have any compatible format, or additionally any uncompressed size-compatible /// `format`, can have any compatible format, or additionally any uncompressed size-compatible
@ -1752,7 +1753,8 @@ pub struct ImageCreateInfo {
/// The number of array layers to create the image with. /// The number of array layers to create the image with.
/// ///
/// On [portability subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag) /// On [portability
/// subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag)
/// devices, if `samples` is not [`SampleCount::Sample1`] and `array_layers` is not 1, /// devices, if `samples` is not [`SampleCount::Sample1`] and `array_layers` is not 1,
/// the [`multisample_array_image`](crate::device::Features::multisample_array_image) /// the [`multisample_array_image`](crate::device::Features::multisample_array_image)
/// feature must be enabled on the device. /// feature must be enabled on the device.
@ -1767,7 +1769,8 @@ pub struct ImageCreateInfo {
/// The number of samples per texel that the image should use. /// The number of samples per texel that the image should use.
/// ///
/// On [portability subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag) /// On [portability
/// subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag)
/// devices, if `samples` is not [`SampleCount::Sample1`] and `array_layers` is not 1, /// devices, if `samples` is not [`SampleCount::Sample1`] and `array_layers` is not 1,
/// the [`multisample_array_image`](crate::device::Features::multisample_array_image) /// the [`multisample_array_image`](crate::device::Features::multisample_array_image)
/// feature must be enabled on the device. /// feature must be enabled on the device.

View File

@ -818,7 +818,8 @@ pub struct ImageViewCreateInfo {
/// If this is set to a format that is different from the image, the image must be created with /// If this is set to a format that is different from the image, the image must be created with
/// the `mutable_format` flag. /// the `mutable_format` flag.
/// ///
/// On [portability subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag) /// On [portability
/// subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag)
/// devices, if `format` does not have the same number of components and bits per component as /// devices, if `format` does not have the same number of components and bits per component as
/// the parent image's format, the /// the parent image's format, the
/// [`image_view_format_reinterpretation`](crate::device::Features::image_view_format_reinterpretation) /// [`image_view_format_reinterpretation`](crate::device::Features::image_view_format_reinterpretation)
@ -829,7 +830,8 @@ pub struct ImageViewCreateInfo {
/// How to map components of each pixel. /// How to map components of each pixel.
/// ///
/// On [portability subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag) /// On [portability
/// subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag)
/// devices, if `component_mapping` is not the identity mapping, the /// devices, if `component_mapping` is not the identity mapping, the
/// [`image_view_format_swizzle`](crate::device::Features::image_view_format_swizzle) /// [`image_view_format_swizzle`](crate::device::Features::image_view_format_swizzle)
/// feature must be enabled on the device. /// feature must be enabled on the device.

View File

@ -392,7 +392,8 @@ pub struct DebugUtilsMessengerCallbackLabel<'a> {
/// The name of the label. /// The name of the label.
pub label_name: &'a str, pub label_name: &'a str,
/// An RGBA color value that is associated with the label, with values in the range `0.0..=1.0`. /// An RGBA color value that is associated with the label, with values in the range
/// `0.0..=1.0`.
pub color: &'a [f32; 4], pub color: &'a [f32; 4],
} }
@ -507,7 +508,8 @@ pub struct DebugUtilsLabel {
/// The default value is empty. /// The default value is empty.
pub label_name: String, pub label_name: String,
/// An RGBA color value that is associated with the label, with values in the range `0.0..=1.0`. /// An RGBA color value that is associated with the label, with values in the range
/// `0.0..=1.0`.
/// ///
/// If set to `[0.0; 4]`, the value is ignored. /// If set to `[0.0; 4]`, the value is ignored.
/// ///

View File

@ -152,10 +152,10 @@ include!(concat!(env!("OUT_DIR"), "/instance_extensions.rs"));
/// functions, even though they could theoretically support a higher version. You can think of it /// functions, even though they could theoretically support a higher version. You can think of it
/// as a promise never to use any functionality from a higher version. /// as a promise never to use any functionality from a higher version.
/// ///
/// The maximum API version is not a _minimum_, so it is possible to set it to a higher version than /// The maximum API version is not a _minimum_, so it is possible to set it to a higher version
/// what the instance or device inherently support. The final API version that you are able to use /// than what the instance or device inherently support. The final API version that you are able to
/// on an instance or device is the lower of the supported API version and the chosen maximum API /// use on an instance or device is the lower of the supported API version and the chosen maximum
/// version of the `Instance`. /// API version of the `Instance`.
/// ///
/// Due to a quirk in how the Vulkan 1.0 specification was written, if the instance only /// Due to a quirk in how the Vulkan 1.0 specification was written, if the instance only
/// supports Vulkan 1.0, then it is not possible to specify a maximum API version higher than 1.0. /// supports Vulkan 1.0, then it is not possible to specify a maximum API version higher than 1.0.

View File

@ -27,25 +27,25 @@
//! is suitable for your program. A [`PhysicalDevice`] represents a Vulkan-capable device that //! is suitable for your program. A [`PhysicalDevice`] represents a Vulkan-capable device that
//! is available on the system, such as a graphics card, a software implementation, etc. //! is available on the system, such as a graphics card, a software implementation, etc.
//! //!
//! 6. Create a [`Device`] and accompanying [`Queue`]s from the selected `PhysicalDevice`. //! 6. Create a [`Device`] and accompanying [`Queue`]s from the selected `PhysicalDevice`. The
//! The `Device` is the most important object of Vulkan, and you need one to create almost //! `Device` is the most important object of Vulkan, and you need one to create almost every
//! every other object. `Queue`s are created together with the `Device`, and are used to submit //! other object. `Queue`s are created together with the `Device`, and are used to submit work
//! work to the device to make it do something. //! to the device to make it do something.
//! //!
//! 7. If you created a `Surface` earlier, create a [`Swapchain`]. This object contains special //! 7. If you created a `Surface` earlier, create a [`Swapchain`]. This object contains special
//! images that correspond to the contents of the surface. Whenever you want to //! images that correspond to the contents of the surface. Whenever you want to change the
//! change the contents (show something new to the user), you must first *acquire* one of these //! contents (show something new to the user), you must first *acquire* one of these images from
//! images from the swapchain, fill it with the new contents (by rendering, copying or any //! the swapchain, fill it with the new contents (by rendering, copying or any other means), and
//! other means), and then *present* it back to the swapchain. //! then *present* it back to the swapchain. A swapchain can become outdated if the properties
//! A swapchain can become outdated if the properties of the surface change, such as when //! of the surface change, such as when the size of the window changes. It then becomes
//! 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*](crate::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
//! *transfer* operations. To do any of these things, you will need to create several other objects, //! *transfer* operations. To do any of these things, you will need to create several other
//! depending on your specific needs. This includes: //! objects, depending on your specific needs. This includes:
//! //!
//! - [*Buffers*] store general-purpose data on memory accessible by the device. This can include //! - [*Buffers*] store general-purpose data on memory accessible by the device. This can include
//! mesh data (vertices, texture coordinates etc.), lighting information, matrices, and anything //! mesh data (vertices, texture coordinates etc.), lighting information, matrices, and anything
@ -55,8 +55,7 @@
//! as textures, depth/stencil buffers, framebuffers and as part of a swapchain. //! as textures, depth/stencil buffers, framebuffers and as part of a swapchain.
//! //!
//! - [*Pipelines*] describe operations on the device. They include one or more [*shader*]s, small //! - [*Pipelines*] describe operations on the device. They include one or more [*shader*]s, small
//! programs that the device will execute as part of a pipeline. //! programs that the device will execute as part of a pipeline. Pipelines come in several types:
//! Pipelines come in several types:
//! - A [`ComputePipeline`] describes how *dispatch* commands are to be performed. //! - A [`ComputePipeline`] describes how *dispatch* commands are to be performed.
//! - A [`GraphicsPipeline`] describes how *draw* commands are to be performed. //! - A [`GraphicsPipeline`] describes how *draw* commands are to be performed.
//! //!
@ -65,11 +64,11 @@
//! more of these layouts in turn forms a [`PipelineLayout`], which is used when creating a //! more of these layouts in turn forms a [`PipelineLayout`], which is used when creating a
//! pipeline object. //! pipeline object.
//! //!
//! - For more complex, multi-stage draw operations, you can create a [`RenderPass`] object. //! - For more complex, multi-stage draw operations, you can create a [`RenderPass`] object. This
//! This object describes the stages, known as subpasses, that draw operations consist of, //! object describes the stages, known as subpasses, that draw operations consist of, how they
//! how they interact with one another, and which types of images are available in each subpass. //! interact with one another, and which types of images are available in each subpass. You must
//! You must also create a [`Framebuffer`], which contains the image objects that are to be used //! also create a [`Framebuffer`], which contains the image objects that are to be used in a
//! in a render pass. //! render pass.
//! //!
//! # `_unchecked` functions //! # `_unchecked` functions
//! //!

View File

@ -349,7 +349,6 @@ impl DynamicLibraryLoader {
/// # Safety /// # Safety
/// ///
/// - The dynamic library must be a valid Vulkan implementation. /// - The dynamic library must be a valid Vulkan implementation.
///
pub unsafe fn new(path: impl AsRef<Path>) -> Result<DynamicLibraryLoader, LoadingError> { pub unsafe fn new(path: impl AsRef<Path>) -> Result<DynamicLibraryLoader, LoadingError> {
let vk_lib = Library::new(path.as_ref()).map_err(LoadingError::LibraryLoadFailure)?; let vk_lib = Library::new(path.as_ref()).map_err(LoadingError::LibraryLoadFailure)?;

View File

@ -154,7 +154,7 @@
//! Now if we free B and D, since these are done out of order, we will be left with holes between //! Now if we free B and D, since these are done out of order, we will be left with holes between
//! the other allocations, and we won't be able to fit allocation E anywhere: //! the other allocations, and we won't be able to fit allocation E anywhere:
//! //!
//! ```plain //! ```plain
//! +-----+-------------------+-------+-----------+-- - - --+ +-------------------------+ //! +-----+-------------------+-------+-----------+-- - - --+ +-------------------------+
//! | | | | | | ? | | //! | | | | | | ? | |
//! | A | | C | | ••• | <== | E | //! | A | | C | | ••• | <== | E |

View File

@ -57,8 +57,8 @@ use std::{
/// this trait, but if you **must**: /// this trait, but if you **must**:
/// ///
/// - `allocate` must return a memory block that is in bounds of the region. /// - `allocate` must return a memory block that is in bounds of the region.
/// - `allocate` must return a memory block that doesn't alias any other currently allocated /// - `allocate` must return a memory block that doesn't alias any other currently allocated memory
/// memory blocks: /// blocks:
/// - Two currently allocated memory blocks must not share any memory locations, meaning that the /// - Two currently allocated memory blocks must not share any memory locations, meaning that the
/// intersection of the byte ranges of the two memory blocks must be empty. /// intersection of the byte ranges of the two memory blocks must be empty.
/// - Two neighboring currently allocated memory blocks must not share any [page] whose size is /// - Two neighboring currently allocated memory blocks must not share any [page] whose size is

View File

@ -1151,15 +1151,15 @@ pub enum MemoryImportInfo {
/// ///
/// - `handle` must be a valid Windows handle. /// - `handle` must be a valid Windows handle.
/// - Vulkan will not take ownership of `handle`. /// - Vulkan will not take ownership of `handle`.
/// - If `handle_type` is [`ExternalMemoryHandleType::OpaqueWin32`], it owns a reference /// - If `handle_type` is [`ExternalMemoryHandleType::OpaqueWin32`], it owns a reference to the
/// to the underlying resource and must eventually be closed by the caller. /// underlying resource and must eventually be closed by the caller.
/// - If `handle_type` is [`ExternalMemoryHandleType::OpaqueWin32Kmt`], it does not own a /// - If `handle_type` is [`ExternalMemoryHandleType::OpaqueWin32Kmt`], it does not own a
/// reference to the underlying resource. /// reference to the underlying resource.
/// - `handle` must be created by the Vulkan API. /// - `handle` must be created by the Vulkan API.
/// - [`MemoryAllocateInfo::allocation_size`] and [`MemoryAllocateInfo::memory_type_index`] /// - [`MemoryAllocateInfo::allocation_size`] and [`MemoryAllocateInfo::memory_type_index`]
/// must match those of the original memory allocation. /// must match those of the original memory allocation.
/// - If the original memory allocation used [`MemoryAllocateInfo::dedicated_allocation`], /// - If the original memory allocation used [`MemoryAllocateInfo::dedicated_allocation`], the
/// the imported one must also use it, and the associated buffer or image must be defined /// imported one must also use it, and the associated buffer or image must be defined
/// identically to the original. /// identically to the original.
Win32 { Win32 {
handle_type: ExternalMemoryHandleType, handle_type: ExternalMemoryHandleType,
@ -1889,7 +1889,8 @@ impl MappedDeviceMemory {
/// # Safety /// # Safety
/// ///
/// - If there are memory writes by the GPU that have not been propagated into the CPU cache, /// - If there are memory writes by the GPU that have not been propagated into the CPU cache,
/// then there must not be any references in Rust code to the specified `range` of the memory. /// then there must not be any references in Rust code to the specified `range` of the
/// memory.
/// ///
/// # Panics /// # Panics
/// ///
@ -1942,8 +1943,8 @@ impl MappedDeviceMemory {
/// ///
/// # Safety /// # Safety
/// ///
/// - There must be no operations pending or executing in a GPU queue, that access the specified /// - There must be no operations pending or executing in a GPU queue, that access the
/// `range` of the memory. /// specified `range` of the memory.
/// ///
/// # Panics /// # Panics
/// ///
@ -1992,8 +1993,8 @@ impl MappedDeviceMemory {
/// ///
/// # Safety /// # Safety
/// ///
/// - While the returned reference exists, there must not be any mutable references in Rust code /// - While the returned reference exists, there must not be any mutable references in Rust
/// to the same memory. /// code to the same memory.
/// - While the returned reference exists, there must be no operations pending or executing in /// - While the returned reference exists, there must be no operations pending or executing in
/// a GPU queue, that write to the same memory. /// a GPU queue, that write to the same memory.
/// ///

View File

@ -805,7 +805,8 @@ pub struct SparseBufferMemoryBind {
pub memory: Option<(Arc<DeviceMemory>, DeviceSize)>, pub memory: Option<(Arc<DeviceMemory>, DeviceSize)>,
} }
/// Parameters for a single sparse bind operation on parts of an image with an opaque memory layout. /// Parameters for a single sparse bind operation on parts of an image with an opaque memory
/// layout.
/// ///
/// This type of sparse bind should be used for mip tail regions, the metadata aspect, and for the /// This type of sparse bind should be used for mip tail regions, the metadata aspect, and for the
/// normal regions of images that do not have the `sparse_residency` flag set. /// normal regions of images that do not have the `sparse_residency` flag set.

View File

@ -9,8 +9,9 @@
//! 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 the data //! of [`get_data`](crate::pipeline::cache::PipelineCache::get_data) for example of how to store
//! on the disk, and [`new`](crate::pipeline::cache::PipelineCache::new) for how to reload it. //! the data on the disk, and [`new`](crate::pipeline::cache::PipelineCache::new) for how to reload
//! it.
use crate::{ use crate::{
device::{Device, DeviceOwned}, device::{Device, DeviceOwned},
@ -236,7 +237,6 @@ impl PipelineCache {
/// Merges other pipeline caches into this one. /// Merges other pipeline caches into this one.
/// ///
/// It is `self` that is modified here. The pipeline caches passed as parameter are untouched. /// It is `self` that is modified here. The pipeline caches passed as parameter are untouched.
///
// FIXME: vkMergePipelineCaches is not thread safe for the destination cache // FIXME: vkMergePipelineCaches is not thread safe for the destination cache
// TODO: write example // TODO: write example
pub fn merge<'a>( pub fn merge<'a>(

View File

@ -7,11 +7,11 @@
//! of pipeline. While it theoretically possible to perform graphics operations entirely in a //! of pipeline. While it theoretically possible to perform graphics operations entirely in a
//! compute pipeline, a graphics pipeline is better suited to that task. //! compute pipeline, a graphics pipeline is better suited to that task.
//! //!
//! A compute pipeline is relatively simple to create, requiring only a pipeline layout and a single //! A compute pipeline is relatively simple to create, requiring only a pipeline layout and a
//! shader, the *compute shader*. The compute shader is the actual program that performs the work. //! single shader, the *compute shader*. The compute shader is the actual program that performs the
//! Once created, you can execute a compute pipeline by *binding* it in a command buffer, binding //! work. Once created, you can execute a compute pipeline by *binding* it in a command buffer,
//! any descriptor sets and/or push constants that the pipeline needs, and then issuing a `dispatch` //! binding any descriptor sets and/or push constants that the pipeline needs, and then issuing a
//! command on the command buffer. //! `dispatch` command on the command buffer.
use super::{PipelineCreateFlags, PipelineShaderStageCreateInfo}; use super::{PipelineCreateFlags, PipelineShaderStageCreateInfo};
use crate::{ use crate::{

View File

@ -41,8 +41,8 @@ pub struct ColorBlendState {
/// The default value is `None`. /// The default value is `None`.
pub logic_op: Option<LogicOp>, pub logic_op: Option<LogicOp>,
/// Sets the blend and output state for each color attachment. The number of elements must match /// Sets the blend and output state for each color attachment. The number of elements must
/// the number of color attachments in the subpass. /// match the number of color attachments in the subpass.
/// ///
/// If there are multiple elements, and the `blend` and `color_write_mask` members of each /// If there are multiple elements, and the `blend` and `color_write_mask` members of each
/// element differ, then the [`independent_blend`](crate::device::Features::independent_blend) /// element differ, then the [`independent_blend`](crate::device::Features::independent_blend)

View File

@ -75,8 +75,8 @@ impl DepthStencilState {
Self::default() Self::default()
} }
/// Creates a `DepthStencilState` with a `Less` depth test, `depth_write` set to true, and other /// Creates a `DepthStencilState` with a `Less` depth test, `depth_write` set to true, and
/// tests disabled. /// other tests disabled.
#[inline] #[inline]
#[deprecated(since = "0.34.0", note = "use `DepthState::simple` instead")] #[deprecated(since = "0.34.0", note = "use `DepthState::simple` instead")]
pub fn simple_depth_test() -> Self { pub fn simple_depth_test() -> Self {
@ -301,7 +301,8 @@ pub struct StencilOpState {
/// considered to pass if the `compare_op` between the stencil buffer value and this reference /// considered to pass if the `compare_op` between the stencil buffer value and this reference
/// value yields true. /// value yields true.
/// ///
/// On [portability subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag) /// On [portability
/// subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag)
/// devices, if culling is disabled, and the `reference` values of the front and back face /// devices, if culling is disabled, and the `reference` values of the front and back face
/// are not equal, then the /// are not equal, then the
/// [`separate_stencil_mask_ref`](crate::device::Features::separate_stencil_mask_ref) /// [`separate_stencil_mask_ref`](crate::device::Features::separate_stencil_mask_ref)

View File

@ -12,10 +12,9 @@
//! Due to the parallel nature of a GPU, no strict ordering guarantees may exist. //! Due to the parallel nature of a GPU, no strict ordering guarantees may exist.
//! //!
//! Graphics pipelines come in two different forms: //! Graphics pipelines come in two different forms:
//! - *Primitive shading* graphics pipelines, which contain a vertex shader, vertex input and //! - *Primitive shading* graphics pipelines, which contain a vertex shader, vertex input and input
//! input assembly state, and optionally tessellation shaders and/or a geometry shader. //! assembly state, and optionally tessellation shaders and/or a geometry shader.
//! - *Mesh shading* graphics pipelines, which contain a mesh shader, and optionally a //! - *Mesh shading* graphics pipelines, which contain a mesh shader, and optionally a task shader.
//! task shader.
//! //!
//! These types differ in the operations that are performed in the first half of the pipeline, //! These types differ in the operations that are performed in the first half of the pipeline,
//! but share a common second half. The type of a graphics pipeline is determined by whether //! but share a common second half. The type of a graphics pipeline is determined by whether
@ -39,8 +38,8 @@
//! 1. (Optional) Task shader invocations: the task shader is run once for each workgroup in the //! 1. (Optional) Task shader invocations: the task shader is run once for each workgroup in the
//! draw command. The task shader then spawns one or more mesh shader invocations. //! draw command. The task shader then spawns one or more mesh shader invocations.
//! 2. Mesh shader invocations: the mesh shader is run, either once each time it is spawned by a //! 2. Mesh shader invocations: the mesh shader is run, either once each time it is spawned by a
//! task shader, or if there is no task shader, once for each workgroup in the draw command. //! task shader, or if there is no task shader, once for each workgroup in the draw command. The
//! The mesh shader outputs a list of primitives (triangles etc). //! mesh shader outputs a list of primitives (triangles etc).
//! //!
//! Mesh shading pipelines do not receive any vertex input; their input data is supplied entirely //! Mesh shading pipelines do not receive any vertex input; their input data is supplied entirely
//! from resources bound via descriptor sets, in combination with the x, y and z coordinates of //! from resources bound via descriptor sets, in combination with the x, y and z coordinates of
@ -54,8 +53,8 @@
//! - Clipping primitives to the view frustum and user-defined clipping planes. //! - Clipping primitives to the view frustum and user-defined clipping planes.
//! - Perspective division. //! - Perspective division.
//! - Viewport mapping. //! - Viewport mapping.
//! 2. Rasterization: converting primitives into a two-dimensional representation. Primitives may be //! 2. Rasterization: converting primitives into a two-dimensional representation. Primitives may
//! discarded depending on their orientation, and are then converted into a collection of //! be discarded depending on their orientation, and are then converted into a collection of
//! fragments that are processed further. //! fragments that are processed further.
//! 3. Fragment operations. These include invocations of the fragment shader, which generates the //! 3. Fragment operations. These include invocations of the fragment shader, which generates the
//! values to be written to the color attachment. Various testing and discarding operations can //! values to be written to the color attachment. Various testing and discarding operations can
@ -73,8 +72,8 @@
//! //!
//! # Using a graphics pipeline //! # Using a graphics pipeline
//! //!
//! Once a graphics pipeline has been created, you can execute it by first *binding* it in a command //! Once a graphics pipeline has been created, you can execute it by first *binding* it in a
//! buffer, binding the necessary vertex buffers, binding any descriptor sets, setting push //! command buffer, binding the necessary vertex buffers, binding any descriptor sets, setting push
//! constants, and setting any dynamic state that the pipeline may need. Then you issue a `draw` //! constants, and setting any dynamic state that the pipeline may need. Then you issue a `draw`
//! command. //! command.
@ -1093,7 +1092,8 @@ impl GraphicsPipeline {
input_assembly_state, input_assembly_state,
tessellation_state, tessellation_state,
viewport_state, viewport_state,
rasterization_state: rasterization_state.unwrap(), // Can be None for pipeline libraries, but we don't support that yet // Can be None for pipeline libraries, but we don't support that yet
rasterization_state: rasterization_state.unwrap(),
multisample_state, multisample_state,
depth_stencil_state, depth_stencil_state,
color_blend_state, color_blend_state,

View File

@ -10,9 +10,9 @@ use crate::{
/// State of the multisampling. /// State of the multisampling.
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct MultisampleState { pub struct MultisampleState {
/// The number of rasterization samples to take per pixel. The GPU will pick this many different /// The number of rasterization samples to take per pixel. The GPU will pick this many
/// locations within each pixel and assign to each of these locations a different depth value. /// different locations within each pixel and assign to each of these locations a different
/// The depth and stencil test will then be run for each sample. /// depth value. The depth and stencil test will then be run for each sample.
/// ///
/// The default value is [`SampleCount::Sample1`]. /// The default value is [`SampleCount::Sample1`].
pub rasterization_samples: SampleCount, pub rasterization_samples: SampleCount,
@ -21,9 +21,9 @@ pub struct MultisampleState {
/// fragment shader. /// fragment shader.
/// ///
/// If the value is 1.0, then all sub-pixel samples will run /// If the value is 1.0, then all sub-pixel samples will run
/// through the shader and get a different value. If the value is 0.5, about half of the samples /// through the shader and get a different value. If the value is 0.5, about half of the
/// will run through the shader and the other half will get their values from the ones which /// samples will run through the shader and the other half will get their values from the
/// went through the shader. /// ones which went through the shader.
/// ///
/// If set to `Some`, the [`sample_rate_shading`](crate::device::Features::sample_rate_shading) /// If set to `Some`, the [`sample_rate_shading`](crate::device::Features::sample_rate_shading)
/// feature must be enabled on the device. /// feature must be enabled on the device.
@ -39,9 +39,9 @@ pub struct MultisampleState {
/// Controls whether the alpha value of the fragment will be used in an implementation-defined /// Controls whether the alpha value of the fragment will be used in an implementation-defined
/// way to determine which samples get disabled or not. For example if the alpha value is 0.5, /// way to determine which samples get disabled or not. For example if the alpha value is 0.5,
/// then about half of the samples will be discarded. If you render to a multisample image, this /// then about half of the samples will be discarded. If you render to a multisample image,
/// means that the color will end up being mixed with whatever color was underneath, which gives /// this means that the color will end up being mixed with whatever color was underneath,
/// the same effect as alpha blending. /// which gives the same effect as alpha blending.
/// ///
/// The default value is `false`. /// The default value is `false`.
pub alpha_to_coverage_enable: bool, pub alpha_to_coverage_enable: bool,

View File

@ -15,23 +15,23 @@
//! components in a location, even if not all bits are actually used. //! components in a location, even if not all bits are actually used.
//! //!
//! A variable may take up fewer than four components. For example, a single `float` takes up only //! A variable may take up fewer than four components. For example, a single `float` takes up only
//! one component, a `vec2` takes up two, and so on. Using the `component` layout qualifier in GLSL, //! one component, a `vec2` takes up two, and so on. Using the `component` layout qualifier in
//! it is possible to fit multiple variables into a single four-component location slot, as long //! GLSL, it is possible to fit multiple variables into a single four-component location slot, as
//! as the components of each variable don't overlap. //! long as the components of each variable don't overlap.
//! //!
//! If the input variable is an array, then it takes up a series of consecutive locations. Each //! If the input variable is an array, then it takes up a series of consecutive locations. Each
//! element of the array always starts at a new location, regardless of whether there is still room //! element of the array always starts at a new location, regardless of whether there is still room
//! in the previous one. So, for example, an array of three `vec2` takes three locations, since //! in the previous one. So, for example, an array of three `vec2` takes three locations, since
//! `vec2` alone needs one location. An array can be decorated with the `component` qualifier as //! `vec2` alone needs one location. An array can be decorated with the `component` qualifier as
//! well; this is equivalent to applying the qualifier to every element of the array. If elements do //! well; this is equivalent to applying the qualifier to every element of the array. If elements
//! not use all components in their locations, those free components can be filled with additional //! do not use all components in their locations, those free components can be filled with
//! variables, just like for non-array types. //! additional variables, just like for non-array types.
//! //!
//! Matrices are laid out as if they were an array of column vectors. Thus, a `mat4x3` is laid out //! Matrices are laid out as if they were an array of column vectors. Thus, a `mat4x3` is laid out
//! as an array of four `vec3`s, `mat2x4` as two `vec4`s. As with individual vectors, each column of //! as an array of four `vec3`s, `mat2x4` as two `vec4`s. As with individual vectors, each column
//! the matrix uses up as many components of its location as there are rows in the matrix, and the //! of the matrix uses up as many components of its location as there are rows in the matrix, and
//! remaining components are available for additional variables as described above. However, it is //! the remaining components are available for additional variables as described above. However, it
//! not possible to use the `component` qualifier on a matrix. //! is not possible to use the `component` qualifier on a matrix.
//! //!
//! If a 64-bit value is to be passed to a shader, it will take up two adjacent components. Vectors //! If a 64-bit value is to be passed to a shader, it will take up two adjacent components. Vectors
//! of 64-bit values are correspondingly twice as large: `dvec2` takes up all four components of a //! of 64-bit values are correspondingly twice as large: `dvec2` takes up all four components of a
@ -41,8 +41,8 @@
//! //!
//! # Input attributes //! # Input attributes
//! //!
//! An input attribute is a mapping between data in a vertex buffer and the locations and components //! An input attribute is a mapping between data in a vertex buffer and the locations and
//! of the vertex shader. //! components of the vertex shader.
//! //!
//! Input attributes are assigned on a per-location basis; it is not possible to assign attributes //! Input attributes are assigned on a per-location basis; it is not possible to assign attributes
//! to individual components. Instead, each attribute specifies up to four values to be read from //! to individual components. Instead, each attribute specifies up to four values to be read from
@ -603,7 +603,8 @@ pub struct VertexInputAttributeDescription {
/// Number of bytes between the start of a vertex buffer element and the location of attribute. /// Number of bytes between the start of a vertex buffer element and the location of attribute.
/// ///
/// On [portability subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag) /// On [portability
/// subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag)
/// devices, if the sum of `offset + format.block_size()` is greater than the `stride` of /// devices, if the sum of `offset + format.block_size()` is greater than the `stride` of
/// `binding`, the /// `binding`, the
/// [`vertex_attribute_access_beyond_stride`](crate::device::Features::vertex_attribute_access_beyond_stride) /// [`vertex_attribute_access_beyond_stride`](crate::device::Features::vertex_attribute_access_beyond_stride)

View File

@ -29,15 +29,14 @@
//! Vulkan allows four different setups: //! Vulkan allows four different setups:
//! //!
//! - The state of both the viewports and scissor boxes is known at pipeline creation. //! - The state of both the viewports and scissor boxes is known at pipeline creation.
//! - The state of viewports is known at pipeline creation, but the state of scissor boxes is //! - The state of viewports is known at pipeline creation, but the state of scissor boxes is only
//! only known when submitting the draw command. //! known when submitting the draw command.
//! - The state of scissor boxes is known at pipeline creation, but the state of viewports is //! - The state of scissor boxes is known at pipeline creation, but the state of viewports is only
//! only known when submitting the draw command. //! known when submitting the draw command.
//! - The state of both the viewports and scissor boxes is only known when submitting the //! - The state of both the viewports and scissor boxes is only known when submitting the draw
//! draw command. //! command.
//! //!
//! In all cases the number of viewports and scissor boxes must be the same. //! In all cases the number of viewports and scissor boxes must be the same.
//!
use crate::{device::Device, Requires, RequiresAllOf, RequiresOneOf, ValidationError, Version}; use crate::{device::Device, Requires, RequiresAllOf, RequiresOneOf, ValidationError, Version};
use smallvec::{smallvec, SmallVec}; use smallvec::{smallvec, SmallVec};

View File

@ -41,9 +41,9 @@
//! //!
//! - An incompatible definition of `Pc` invalidates all bound descriptor sets. //! - An incompatible definition of `Pc` invalidates all bound descriptor sets.
//! - An incompatible definition of `DsN` invalidates all bound descriptor sets *N* and higher. //! - An incompatible definition of `DsN` invalidates all bound descriptor sets *N* and higher.
//! - If *N* is the highest set being assigned in a bind command, and it and all lower sets //! - If *N* is the highest set being assigned in a bind command, and it and all lower sets have
//! have compatible definitions, including the push constants, then descriptor sets above *N* //! compatible definitions, including the push constants, then descriptor sets above *N* remain
//! remain valid. //! valid.
//! //!
//! [`RecordingCommandBuffer`] keeps track of this state and will automatically remove descriptor //! [`RecordingCommandBuffer`] keeps track of this state and will automatically remove descriptor
//! sets that have been invalidated by incompatible layouts in subsequent binding commands. //! sets that have been invalidated by incompatible layouts in subsequent binding commands.

View File

@ -163,7 +163,8 @@ impl QueryPool {
/// enough to hold the data. /// enough to hold the data.
/// ///
/// `true` is returned if every result was available and written to the buffer. `false` /// `true` is returned if every result was available and written to the buffer. `false`
/// is returned if some results were not yet available; these will not be written to the buffer. /// is returned if some results were not yet available; these will not be written to the
/// buffer.
/// ///
/// See also [`copy_query_pool_results`]. /// See also [`copy_query_pool_results`].
/// ///

View File

@ -1,9 +1,7 @@
// Most of the code in this module comes from the rangemap crate, which is licensed under either of // Most of the code in this module comes from the rangemap crate, which is licensed under either of
// - Apache License, Version 2.0 // - Apache License, Version 2.0 (https://github.com/jeffparsons/rangemap/blob/master/LICENSE-APACHE
// (https://github.com/jeffparsons/rangemap/blob/master/LICENSE-APACHE or // or http://www.apache.org/licenses/LICENSE-2.0)
// http://www.apache.org/licenses/LICENSE-2.0) // - MIT (https://github.com/jeffparsons/rangemap/blob/master/LICENSE-MIT or http://opensource.org/licenses/MIT)
// - MIT (https://github.com/jeffparsons/rangemap/blob/master/LICENSE-MIT or
// http://opensource.org/licenses/MIT)
// at your option. // at your option.
// //
// The following changes were made: // The following changes were made:
@ -892,9 +890,7 @@ mod tests {
assert_eq!(range_map.to_vec(), vec![]); assert_eq!(range_map.to_vec(), vec![]);
} }
/// // impl Debug
/// impl Debug
///
#[test] #[test]
fn map_debug_repr_looks_right() { fn map_debug_repr_looks_right() {

View File

@ -29,7 +29,8 @@ impl<T: Ord + Copy> RangeSet<T> {
/// Inserts the elements of `range` into the set. /// Inserts the elements of `range` into the set.
pub fn insert(&mut self, elements: Range<T>) { pub fn insert(&mut self, elements: Range<T>) {
// Find the first range that is not less than `elements`, and the first range that is greater. // Find the first range that is not less than `elements`, and the first range that is
// greater.
let index_start = self let index_start = self
.0 .0
.iter() .iter()

View File

@ -6,8 +6,8 @@
//! //!
//! - A *render pass* describes the overall process of drawing a frame. It is subdivided into one //! - A *render pass* describes the overall process of drawing a frame. It is subdivided into one
//! or more subpasses. //! or more subpasses.
//! - A *framebuffer* contains the list of image views that are attached during the drawing of //! - A *framebuffer* contains the list of image views that are attached during the drawing of each
//! each subpass. //! subpass.
//! //!
//! Render passes are typically created at initialization only (for example during a loading //! Render passes are typically created at initialization only (for example during a loading
//! screen) because they can be costly, while framebuffers can be created and destroyed either at //! screen) because they can be costly, while framebuffers can be created and destroyed either at
@ -47,8 +47,8 @@ mod framebuffer;
/// A render pass in Vulkan is made up of three parts: /// A render pass in Vulkan is made up of three parts:
/// - A list of attachments, which are image views that are inputs, outputs or intermediate stages /// - A list of attachments, which are image views that are inputs, outputs or intermediate stages
/// in the rendering process. /// in the rendering process.
/// - One or more subpasses, which are the steps in which the rendering process, takes place, /// - One or more subpasses, which are the steps in which the rendering process, takes place, and
/// and the attachments that are used for each step. /// the attachments that are used for each step.
/// - Dependencies, which describe how the input and output data of each subpass is to be passed /// - Dependencies, which describe how the input and output data of each subpass is to be passed
/// from one subpass to the next. /// from one subpass to the next.
/// ///
@ -2141,9 +2141,9 @@ vulkan_bitflags! {
/// Describes one of the subpasses of a render pass. /// Describes one of the subpasses of a render pass.
/// ///
/// A subpass can use zero or more attachments of various types. Attachment types of which there can /// A subpass can use zero or more attachments of various types. Attachment types of which there
/// be multiple are listed in a `Vec` in this structure. The index in these `Vec`s corresponds to /// can be multiple are listed in a `Vec` in this structure. The index in these `Vec`s corresponds
/// the index used for that attachment type in the shader. /// to the index used for that attachment type in the shader.
/// ///
/// If a particular index is not used in the shader, it can be set to `None` in this structure. /// If a particular index is not used in the shader, it can be set to `None` in this structure.
/// This is useful if an unused index needs to be skipped but a higher index needs to be specified. /// This is useful if an unused index needs to be skipped but a higher index needs to be specified.
@ -2158,9 +2158,9 @@ pub struct SubpassDescription {
/// The default value is empty. /// The default value is empty.
pub flags: SubpassDescriptionFlags, pub flags: SubpassDescriptionFlags,
/// If not `0`, enables multiview rendering, and specifies the view indices that are rendered to /// If not `0`, enables multiview rendering, and specifies the view indices that are rendered
/// in this subpass. The value is a bitmask, so that that for example `0b11` will draw to the /// to in this subpass. The value is a bitmask, so that that for example `0b11` will draw
/// first two views and `0b101` will draw to the first and third view. /// to the first two views and `0b101` will draw to the first and third view.
/// ///
/// If set to a nonzero value, it must be nonzero for all subpasses in the render pass, and the /// If set to a nonzero value, it must be nonzero for all subpasses in the render pass, and the
/// [`multiview`](crate::device::Features::multiview) feature must be enabled on the device. /// [`multiview`](crate::device::Features::multiview) feature must be enabled on the device.
@ -2168,16 +2168,18 @@ pub struct SubpassDescription {
/// The default value is `0`. /// The default value is `0`.
pub view_mask: u32, pub view_mask: u32,
/// The attachments of the render pass that are to be used as input attachments in this subpass. /// The attachments of the render pass that are to be used as input attachments in this
/// subpass.
/// ///
/// If an attachment is used here for the first time in this render pass, and it's is not also /// If an attachment is used here for the first time in this render pass, and it's is not also
/// used as a color or depth/stencil attachment in this subpass, then the attachment's `load_op` /// used as a color or depth/stencil attachment in this subpass, then the attachment's
/// must not be [`AttachmentLoadOp::Clear`]. /// `load_op` must not be [`AttachmentLoadOp::Clear`].
/// ///
/// The default value is empty. /// The default value is empty.
pub input_attachments: Vec<Option<AttachmentReference>>, pub input_attachments: Vec<Option<AttachmentReference>>,
/// The attachments of the render pass that are to be used as color attachments in this subpass. /// The attachments of the render pass that are to be used as color attachments in this
/// subpass.
/// ///
/// The number of color attachments must be less than the /// The number of color attachments must be less than the
/// [`max_color_attachments`](crate::device::Properties::max_color_attachments) limit of the /// [`max_color_attachments`](crate::device::Properties::max_color_attachments) limit of the
@ -3203,9 +3205,9 @@ impl AttachmentReference {
/// then `by_region` must be activated. /// then `by_region` must be activated.
/// ///
/// If `src_subpass` or `dst_subpass` are set to `None`, this specifies an external /// If `src_subpass` or `dst_subpass` are set to `None`, this specifies an external
/// dependency. An external dependency specifies a dependency on commands that were submitted before /// dependency. An external dependency specifies a dependency on commands that were submitted
/// the render pass instance began (for `src_subpass`), or on commands that will be submitted /// before the render pass instance began (for `src_subpass`), or on commands that will be
/// after the render pass instance ends (for `dst_subpass`). The values must not both be /// submitted after the render pass instance ends (for `dst_subpass`). The values must not both be
/// `None`. /// `None`.
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct SubpassDependency { pub struct SubpassDependency {
@ -3249,10 +3251,9 @@ pub struct SubpassDependency {
/// Dependency flags that modify behavior of the subpass dependency. /// Dependency flags that modify behavior of the subpass dependency.
/// ///
/// If a `src_subpass` equals `dst_subpass`, then: /// If a `src_subpass` equals `dst_subpass`, then:
/// - If `src_stages` and `dst_stages` both contain framebuffer-space stages, /// - If `src_stages` and `dst_stages` both contain framebuffer-space stages, this must include
/// this must include [`BY_REGION`]. /// [`BY_REGION`].
/// - If the subpass's `view_mask` has more than one view, /// - If the subpass's `view_mask` has more than one view, this must include [`VIEW_LOCAL`].
/// this must include [`VIEW_LOCAL`].
/// ///
/// The default value is [`DependencyFlags::empty()`]. /// The default value is [`DependencyFlags::empty()`].
/// ///

View File

@ -25,15 +25,15 @@
//! ## Layout of data //! ## Layout of data
//! //!
//! When buffers, push constants or other user-provided data are accessed in shaders, //! When buffers, push constants or other user-provided data are accessed in shaders,
//! the shader expects the values inside to be laid out in a specific way. For every uniform buffer, //! the shader expects the values inside to be laid out in a specific way. For every uniform
//! storage buffer or push constant block, the SPIR-V specification requires the SPIR-V code to //! buffer, storage buffer or push constant block, the SPIR-V specification requires the SPIR-V
//! provide the `Offset` decoration for every member of a struct, indicating where it is placed //! code to provide the `Offset` decoration for every member of a struct, indicating where it is
//! relative to the start of the struct. If there are arrays or matrices among the variables, the //! placed relative to the start of the struct. If there are arrays or matrices among the
//! SPIR-V code must also provide an `ArrayStride` or `MatrixStride` decoration for them, //! variables, the SPIR-V code must also provide an `ArrayStride` or `MatrixStride` decoration for
//! indicating the number of bytes between the start of each element in the array or column in the //! them, indicating the number of bytes between the start of each element in the array or column
//! matrix. When providing data to shaders, you must make sure that your data is placed at the //! in the matrix. When providing data to shaders, you must make sure that your data is placed at
//! locations indicated within the SPIR-V code, or the shader will read the wrong data and produce //! the locations indicated within the SPIR-V code, or the shader will read the wrong data and
//! nonsense. //! produce nonsense.
//! //!
//! GLSL does not require you to give explicit offsets and/or strides to your variables (although //! GLSL does not require you to give explicit offsets and/or strides to your variables (although
//! it has the option to provide them if you wish). Instead, the shader compiler automatically //! it has the option to provide them if you wish). Instead, the shader compiler automatically
@ -63,12 +63,12 @@
//! [`#[repr(C)]`](https://doc.rust-lang.org/nomicon/other-reprs.html#reprc) attribute. //! [`#[repr(C)]`](https://doc.rust-lang.org/nomicon/other-reprs.html#reprc) attribute.
//! The shader compiler does not use this alignment by default, so you must use the GLSL //! The shader compiler does not use this alignment by default, so you must use the GLSL
//! qualifier. You must also enable the [`scalar_block_layout`] feature in Vulkan. //! qualifier. You must also enable the [`scalar_block_layout`] feature in Vulkan.
//! - **Base alignment**, also known as **std430** (GLSL qualifier: `layout(std430)`). //! - **Base alignment**, also known as **std430** (GLSL qualifier: `layout(std430)`). The shader
//! The shader compiler uses this alignment by default for all shader data except uniform buffers. //! compiler uses this alignment by default for all shader data except uniform buffers. If you
//! If you use the base alignment for a uniform buffer, you must also enable the //! use the base alignment for a uniform buffer, you must also enable the
//! [`uniform_buffer_standard_layout`] feature in Vulkan. //! [`uniform_buffer_standard_layout`] feature in Vulkan.
//! - **Extended alignment**, also known as **std140** (GLSL qualifier: `layout(std140)`). //! - **Extended alignment**, also known as **std140** (GLSL qualifier: `layout(std140)`). The
//! The shader compiler uses this alignment by default for uniform buffers. //! shader compiler uses this alignment by default for uniform buffers.
//! //!
//! Each alignment type is a subset of the ones above it, so if something adheres to the extended //! Each alignment type is a subset of the ones above it, so if something adheres to the extended
//! alignment rules, it also follows the rules for the base and scalar alignments. //! alignment rules, it also follows the rules for the base and scalar alignments.
@ -140,105 +140,112 @@
//! //!
//! ## Buffers //! ## Buffers
//! //!
//! - If the [`robust_buffer_access`](Features::robust_buffer_access) feature is not enabled //! - If the [`robust_buffer_access`](Features::robust_buffer_access) feature is not enabled on the
//! on the device, then the shader must not access any values outside the range of the buffer, //! device, then the shader must not access any values outside the range of the buffer, as
//! as specified when writing the descriptor set. //! specified when writing the descriptor set. <sup>[\[06935\]] [\[06936\]]</sup>
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-uniformBuffers-06935) //! - If any `PhysicalStorageBuffer` pointers to device memory are dereferenced in the shader, then
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-storageBuffers-06936) //! they must point to valid buffer memory of the correct type.
//! - If any `PhysicalStorageBuffer` pointers to device memory are dereferenced in the shader,
//! then they must point to valid buffer memory of the correct type.
//! //!
//! ## Image views and buffer views //! ## Image views and buffer views
//! //!
//! - The [`view_type`](ImageView::view_type) of the bound image view //! - The [`view_type`](ImageView::view_type) of the bound image view must match the `Dim` operand
//! must match the `Dim` operand of the `OpImageType`. //! of the `OpImageType`. <sup>[\[07752\]]</sup>
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-viewType-07752) //! - The numeric type of the [`format`](ImageView::format) of the bound image view must match the
//! - The numeric type of the [`format`](ImageView::format) of the bound image view //! `Sampled Type` operand of the `OpImageType`. <sup>[\[07753\]]</sup>
//! must match the `Sampled Type` operand of the `OpImageType`. //! - For every `OpImageWrite` instruction, the type of the `Texel` operand must have at least as
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-format-07753) //! many components as the format of the bound image view or buffer view. If the bound image
//! - For every `OpImageWrite` instruction, the type of the `Texel` operand must have at least //! view's format is [`Format::A8_UNORM`], then the type of the `Texel` operand must have four
//! as many components as the format of the bound image view or buffer view. //! components. <sup>[\[04469\]] [\[08795\]] [\[08796\]]</sup>
//! If the bound image view's format is [`Format::A8_UNORM`], then the type of the `Texel` //! - The `Sampled Type` operand of the `OpTypeImage` declaration must have a `Width` of 64, if and
//! operand must have four components. //! only if the format of the bound image view or buffer view also has a 64-bit component.
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-OpImageWrite-04469) //! Otherwise, it must have a `Width` of 32. <sup>[\[04470\]] [\[04471\]] [\[04472\]]
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-OpImageWrite-08795) //! [\[04473\]]</sup>
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-OpImageWrite-08796)
//! - The `Sampled Type` operand of the `OpTypeImage` declaration must have a `Width` of 64,
//! if and only if the format of the bound image view or buffer view also has a 64-bit component.
//! Otherwise, it must have a `Width` of 32.
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-SampledType-04470)
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-SampledType-04471)
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-SampledType-04472)
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-SampledType-04473)
//! - For a storage image/texel buffer declared with `OpTypeImage` with an `Unknown` format: //! - For a storage image/texel buffer declared with `OpTypeImage` with an `Unknown` format:
//! - If it is written to in the shader, the format of the bound image view or buffer view must //! - If it is written to in the shader, the format of the bound image view or buffer view must
//! have the [`FormatFeatures::STORAGE_WRITE_WITHOUT_FORMAT`] format feature. //! have the [`FormatFeatures::STORAGE_WRITE_WITHOUT_FORMAT`] format feature. <sup>[\[07027\]]
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-OpTypeImage-07027) //! [\[07029\]]</sup>
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-OpTypeImage-07029)
//! - If it is read from in the shader, the format of the bound image view or buffer view must //! - If it is read from in the shader, the format of the bound image view or buffer view must
//! have the [`FormatFeatures::STORAGE_READ_WITHOUT_FORMAT`] format feature. //! have the [`FormatFeatures::STORAGE_READ_WITHOUT_FORMAT`] format feature. <sup>[\[07028\]]
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-OpTypeImage-07028) //! [\[07030\]]</sup>
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-OpTypeImage-07030)
//! - If atomic operations are used on a storage image/texel buffer: //! - If atomic operations are used on a storage image/texel buffer:
//! - The bound image view's format must have the [`FormatFeatures::STORAGE_IMAGE_ATOMIC`] //! - The bound image view's format must have the [`FormatFeatures::STORAGE_IMAGE_ATOMIC`] format
//! format feature. //! feature. <sup>[\[02691\]]</sup>
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-None-02691) //! - The bound buffer view's format must have the
//! - The bound buffer view's format must have the [`FormatFeatures::STORAGE_TEXEL_BUFFER_ATOMIC`] //! [`FormatFeatures::STORAGE_TEXEL_BUFFER_ATOMIC`] format feature. <sup>[\[07888\]]</sup>
//! format feature.
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-None-07888)
//! //!
//! ## Image sampling //! ## Image sampling
//! //!
//! If the bound sampler uses [`Filter::Linear`] or [`SamplerMipmapMode::Linear`]: //! If the bound sampler uses [`Filter::Linear`] or [`SamplerMipmapMode::Linear`]:
//! - The bound image view's format must have the [`FormatFeatures::SAMPLED_IMAGE_FILTER_LINEAR`] //! - The bound image view's format must have the [`FormatFeatures::SAMPLED_IMAGE_FILTER_LINEAR`]
//! format feature. //! format feature. <sup>[\[04553\]] [\[04770\]]</sup>
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-magFilter-04553)
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-mipmapMode-04770)
//! //!
//! If the bound sampler uses [`Filter::Cubic`]: //! If the bound sampler uses [`Filter::Cubic`]:
//! - The bound image view's format must have the [`FormatFeatures::SAMPLED_IMAGE_FILTER_CUBIC`] //! - The bound image view's format must have the [`FormatFeatures::SAMPLED_IMAGE_FILTER_CUBIC`]
//! format feature. //! format feature. <sup>[\[02692\]]</sup>
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-None-02692)
//! - The bound image view's type and format must support cubic filtering, as indicated in //! - The bound image view's type and format must support cubic filtering, as indicated in
//! [`ImageFormatProperties::filter_cubic`] returned from //! [`ImageFormatProperties::filter_cubic`] returned from
//! [`PhysicalDevice::image_format_properties`]. //! [`PhysicalDevice::image_format_properties`]. <sup>[\[02694\]]</sup>
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-filterCubic-02694)
//! - If the sampler's reduction mode is [`SamplerReductionMode::Min`] or //! - If the sampler's reduction mode is [`SamplerReductionMode::Min`] or
//! [`SamplerReductionMode::Max`], the image view type and format must support cubic minmax //! [`SamplerReductionMode::Max`], the image view type and format must support cubic minmax
//! filtering, as indicated in [`ImageFormatProperties::filter_cubic_minmax`] returned from //! filtering, as indicated in [`ImageFormatProperties::filter_cubic_minmax`] returned from
//! [`PhysicalDevice::image_format_properties`]. //! [`PhysicalDevice::image_format_properties`]. <sup>[\[02695\]]</sup>
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-filterCubicMinmax-02695)
//! //!
//! If the bound sampler uses [depth comparison](SamplerCreateInfo::compare): //! If the bound sampler uses [depth comparison](SamplerCreateInfo::compare):
//! - The bound image view's format must have the [`FormatFeatures::SAMPLED_IMAGE_DEPTH_COMPARISON`] //! - The bound image view's format must have the
//! format feature. //! [`FormatFeatures::SAMPLED_IMAGE_DEPTH_COMPARISON`] format feature. <sup>[\[06479\]]</sup>
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-None-06479)
//! //!
//! If the bound sampler uses [unnormalized coordinates](SamplerCreateInfo::unnormalized_coordinates): //! If the bound sampler uses [unnormalized
//! - The bound image view must have a type of [`ImageViewType::Dim1d`] or [`ImageViewType::Dim2d`]. //! coordinates](SamplerCreateInfo::unnormalized_coordinates):
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-None-08609) //! - The bound image view must have a type of [`ImageViewType::Dim1d`] or
//! [`ImageViewType::Dim2d`]. <sup>[\[08609\]]</sup>
//! - The sampler must not be used in any `OpImageSample*` or `OpImageSparseSample*` instructions, //! - The sampler must not be used in any `OpImageSample*` or `OpImageSparseSample*` instructions,
//! that contain `ImplicitLod`, `Dref` or `Proj` in their name. //! that contain `ImplicitLod`, `Dref` or `Proj` in their name. <sup>[\[08610\]]</sup>
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-None-08610)
//! - The sampler must not be used in any `OpImageSample*` or `OpImageSparseSample*` instructions, //! - The sampler must not be used in any `OpImageSample*` or `OpImageSparseSample*` instructions,
//! that include an LOD bias or offset operand. //! that include an LOD bias or offset operand. <sup>[\[08611\]]</sup>
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-None-08611)
//! //!
//! If the bound sampler has a [sampler YCbCr conversion](crate::image::sampler::ycbcr): //! If the bound sampler has a [sampler YCbCr conversion](crate::image::sampler::ycbcr):
//! - The sampler must only be used in `OpImageSample*` or `OpImageSparseSample*` instructions. //! - The sampler must only be used in `OpImageSample*` or `OpImageSparseSample*` instructions.
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-None-06550) //! <sup>[\[06550\]]</sup>
//! - The sampler must not be used with the `ConstOffset` or `Offset` image operands. //! - The sampler must not be used with the `ConstOffset` or `Offset` image operands.
//! [\[spec\]](https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-ConstOffset-06551) //! <sup>[\[06551\]]</sup>
//! //!
//! ## Acceleration structures //! ## Acceleration structures
//! //!
//! - In any top-level acceleration structure, the pointers that refer to the contained //! - In any top-level acceleration structure, the pointers that refer to the contained
//! bottom-level acceleration structure instances must point to valid acceleration structures. //! bottom-level acceleration structure instances must point to valid acceleration structures.
//! //!
//! [alignment rules]: <https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap15.html#interfaces-resources-layout> //! [alignment rules]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap15.html#interfaces-resources-layout
//! [`GL_EXT_scalar_block_layout`]: <https://github.com/KhronosGroup/GLSL/blob/master/extensions/ext/GL_EXT_scalar_block_layout.txt> //! [`GL_EXT_scalar_block_layout`]: https://github.com/KhronosGroup/GLSL/blob/master/extensions/ext/GL_EXT_scalar_block_layout.txt
//! [`scalar_block_layout`]: crate::device::Features::scalar_block_layout //! [`scalar_block_layout`]: crate::device::Features::scalar_block_layout
//! [`uniform_buffer_standard_layout`]: crate::device::Features::uniform_buffer_standard_layout //! [`uniform_buffer_standard_layout`]: crate::device::Features::uniform_buffer_standard_layout
//! [\[06935\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-uniformBuffers-06935
//! [\[06936\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-storageBuffers-06936
//! [\[07752\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-viewType-07752
//! [\[07753\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-format-07753
//! [\[04469\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-OpImageWrite-04469
//! [\[08795\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-OpImageWrite-08795
//! [\[08796\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-OpImageWrite-08796
//! [\[04470\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-SampledType-04470
//! [\[04471\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-SampledType-04471
//! [\[04472\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-SampledType-04472
//! [\[04473\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-SampledType-04473
//! [\[07027\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-OpTypeImage-07027
//! [\[07029\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-OpTypeImage-07029
//! [\[07028\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-OpTypeImage-07028
//! [\[07030\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-OpTypeImage-07030
//! [\[02691\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-None-02691
//! [\[07888\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-None-07888
//! [\[04553\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-magFilter-04553
//! [\[04770\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-mipmapMode-04770
//! [\[02692\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-None-02692
//! [\[02694\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-filterCubic-02694
//! [\[02695\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-filterCubicMinmax-02695
//! [\[06479\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-None-06479
//! [\[08609\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-None-08609
//! [\[08610\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-None-08610
//! [\[08611\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-None-08611
//! [\[06550\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-None-06550
//! [\[06551\]]: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdDispatch-ConstOffset-06551
use self::spirv::{Id, Instruction}; use self::spirv::{Id, Instruction};
#[cfg(doc)] #[cfg(doc)]
@ -905,9 +912,9 @@ impl SpecializedShaderModule {
self.spirv.as_ref().unwrap_or(&self.base_module.spirv) self.spirv.as_ref().unwrap_or(&self.base_module.spirv)
} }
/// Returns information about the entry point with the provided name. Returns `None` if no entry /// Returns information about the entry point with the provided name. Returns `None` if no
/// point with that name exists in the shader module or if multiple entry points with the same /// entry point with that name exists in the shader module or if multiple entry points with
/// name exist. /// the same name exist.
#[inline] #[inline]
pub fn entry_point(self: &Arc<Self>, name: &str) -> Option<EntryPoint> { pub fn entry_point(self: &Arc<Self>, name: &str) -> Option<EntryPoint> {
self.single_entry_point_filter(|info| info.name == name) self.single_entry_point_filter(|info| info.name == name)

View File

@ -719,9 +719,9 @@ struct InstructionReader<'a> {
} }
impl<'a> InstructionReader<'a> { impl<'a> InstructionReader<'a> {
/// Constructs a new reader from a slice of words for a single instruction, including the opcode /// Constructs a new reader from a slice of words for a single instruction, including the
/// word. `instruction` is the number of the instruction currently being read, and is used for /// opcode word. `instruction` is the number of the instruction currently being read, and
/// error reporting. /// is used for error reporting.
fn new(words: &'a [u32], instruction: usize) -> Self { fn new(words: &'a [u32], instruction: usize) -> Self {
debug_assert!(!words.is_empty()); debug_assert!(!words.is_empty());
Self { Self {

View File

@ -521,7 +521,8 @@ fn evaluate_spec_constant_op(
} }
} }
// Evaluate a SpecConstantInstruction that does calculations on scalars or paired vector components. // Evaluate a SpecConstantInstruction that does calculations on scalars or paired vector
// components.
fn evaluate_spec_constant_calculation_op( fn evaluate_spec_constant_calculation_op(
instruction: &SpecConstantInstruction, instruction: &SpecConstantInstruction,
constants: &HashMap<Id, Constant>, constants: &HashMap<Id, Constant>,

View File

@ -2,8 +2,8 @@
//! //!
//! Before you can draw on the screen or a window, you have to create two objects: //! Before you can draw on the screen or a window, you have to create two objects:
//! //!
//! - Create a `Surface` object that represents the location where the image will show up (either //! - Create a `Surface` object that represents the location where the image will show up (either a
//! a window or a monitor). //! window or a monitor).
//! - Create a `Swapchain` that uses that `Surface`. //! - Create a `Swapchain` that uses that `Surface`.
//! //!
//! Creating a surface can be done with only an `Instance` object. However creating a swapchain //! Creating a surface can be done with only an `Instance` object. However creating a swapchain
@ -219,8 +219,8 @@
//! - Call `swapchain::acquire_next_image`. This function will return the index of the image //! - Call `swapchain::acquire_next_image`. This function will return the index of the image
//! (within the list returned by `Swapchain::new`) that is available to draw, plus a future //! (within the list returned by `Swapchain::new`) that is available to draw, plus a future
//! representing the moment when the GPU will gain access to that image. //! representing the moment when the GPU will gain access to that image.
//! - Draw on that image just like you would draw to any other image (see the documentation of //! - Draw on that image just like you would draw to any other image (see the documentation of the
//! the `pipeline` module). You need to chain the draw after the future that was returned by //! `pipeline` module). You need to chain the draw after the future that was returned by
//! `acquire_next_image`. //! `acquire_next_image`.
//! - Call `Swapchain::present` with the same index and by chaining the futures, in order to tell //! - Call `Swapchain::present` with the same index and by chaining the futures, in order to tell
//! the implementation that you are finished drawing to the image and that it can queue a //! the implementation that you are finished drawing to the image and that it can queue a
@ -402,7 +402,6 @@ impl Swapchain {
/// ///
/// - Panics if the device and the surface don't belong to the same instance. /// - Panics if the device and the surface don't belong to the same instance.
/// - Panics if `create_info.usage` is empty. /// - Panics if `create_info.usage` is empty.
///
// TODO: isn't it unsafe to take the surface through an Arc when it comes to vulkano-win? // TODO: isn't it unsafe to take the surface through an Arc when it comes to vulkano-win?
#[inline] #[inline]
pub fn new( pub fn new(
@ -1154,8 +1153,8 @@ impl Swapchain {
/// ///
/// - `handle` and `image_handles` must be valid Vulkan object handles created from `device`. /// - `handle` and `image_handles` must be valid Vulkan object handles created from `device`.
/// - `handle` must not be retired. /// - `handle` must not be retired.
/// - `image_handles` must be swapchain images owned by `handle`, /// - `image_handles` must be swapchain images owned by `handle`, in the same order as they
/// in the same order as they were returned by `vkGetSwapchainImagesKHR`. /// were returned by `vkGetSwapchainImagesKHR`.
/// - `surface` and `create_info` must match the info used to create the object. /// - `surface` and `create_info` must match the info used to create the object.
pub unsafe fn from_handle( pub unsafe fn from_handle(
device: Arc<Device>, device: Arc<Device>,
@ -1614,8 +1613,8 @@ impl Swapchain {
/// ///
/// The swapchain must have been created with [`FullScreenExclusive::ApplicationControlled`], /// The swapchain must have been created with [`FullScreenExclusive::ApplicationControlled`],
/// and must not already hold full-screen exclusivity. Full-screen exclusivity is held until /// and must not already hold full-screen exclusivity. Full-screen exclusivity is held until
/// either the `release_full_screen_exclusive` is called, or if any of the the other `Swapchain` /// either the `release_full_screen_exclusive` is called, or if any of the the other
/// functions return `FullScreenExclusiveLost`. /// `Swapchain` functions return `FullScreenExclusiveLost`.
#[inline] #[inline]
pub fn acquire_full_screen_exclusive_mode(&self) -> Result<(), Validated<VulkanError>> { pub fn acquire_full_screen_exclusive_mode(&self) -> Result<(), Validated<VulkanError>> {
self.validate_acquire_full_screen_exclusive_mode()?; self.validate_acquire_full_screen_exclusive_mode()?;
@ -1819,7 +1818,8 @@ pub struct SwapchainCreateInfo {
/// The default value is `Format::UNDEFINED`. /// The default value is `Format::UNDEFINED`.
pub image_format: Format, pub image_format: Format,
/// The formats that an image view can have when it is created from one of the swapchain images. /// The formats that an image view can have when it is created from one of the swapchain
/// images.
/// ///
/// If the list is not empty, and `flags` does not contain /// If the list is not empty, and `flags` does not contain
/// [`SwapchainCreateFlags::MUTABLE_FORMAT`], then the list must contain at most one element, /// [`SwapchainCreateFlags::MUTABLE_FORMAT`], then the list must contain at most one element,
@ -1895,9 +1895,10 @@ pub struct SwapchainCreateInfo {
/// The default value is empty. /// The default value is empty.
pub present_modes: SmallVec<[PresentMode; PresentMode::COUNT]>, pub present_modes: SmallVec<[PresentMode; PresentMode::COUNT]>,
/// Whether the implementation is allowed to discard rendering operations that affect regions of /// Whether the implementation is allowed to discard rendering operations that affect regions
/// the surface which aren't visible. This is important to take into account if your fragment /// of the surface which aren't visible. This is important to take into account if your
/// shader has side-effects or if you want to read back the content of the image afterwards. /// fragment shader has side-effects or if you want to read back the content of the image
/// afterwards.
/// ///
/// The default value is `true`. /// The default value is `true`.
pub clipped: bool, pub clipped: bool,

View File

@ -167,8 +167,8 @@ impl Surface {
/// ///
/// - `handle` must be a valid Vulkan object handle created from `instance`. /// - `handle` must be a valid Vulkan object handle created from `instance`.
/// - `handle` must have been created using the function specified by `api`. /// - `handle` must have been created using the function specified by `api`.
/// - The window object that `handle` was created from must outlive the created `Surface`. /// - The window object that `handle` was created from must outlive the created `Surface`. The
/// The `object` parameter can be used to ensure this. /// `object` parameter can be used to ensure this.
pub unsafe fn from_handle( pub unsafe fn from_handle(
instance: Arc<Instance>, instance: Arc<Instance>,
handle: ash::vk::SurfaceKHR, handle: ash::vk::SurfaceKHR,
@ -191,8 +191,9 @@ impl Surface {
/// Creates a `Surface` with no backing window or display. /// Creates a `Surface` with no backing window or display.
/// ///
/// Presenting to a headless surface does nothing, so this is mostly useless in itself. However, /// Presenting to a headless surface does nothing, so this is mostly useless in itself.
/// it may be useful for testing, and it is available for future extensions to layer on top of. /// However, it may be useful for testing, and it is available for future extensions to
/// layer on top of.
pub fn headless( pub fn headless(
instance: Arc<Instance>, instance: Arc<Instance>,
object: Option<Arc<dyn Any + Send + Sync>>, object: Option<Arc<dyn Any + Send + Sync>>,
@ -434,8 +435,8 @@ impl Surface {
/// # Safety /// # Safety
/// ///
/// - `window` must be a valid Android `ANativeWindow` handle. /// - `window` must be a valid Android `ANativeWindow` handle.
/// - The object referred to by `window` must outlive the created `Surface`. /// - The object referred to by `window` must outlive the created `Surface`. The `object`
/// The `object` parameter can be used to ensure this. /// parameter can be used to ensure this.
pub unsafe fn from_android( pub unsafe fn from_android(
instance: Arc<Instance>, instance: Arc<Instance>,
window: *mut ash::vk::ANativeWindow, window: *mut ash::vk::ANativeWindow,
@ -505,8 +506,8 @@ impl Surface {
/// ///
/// - `dfb` must be a valid DirectFB `IDirectFB` handle. /// - `dfb` must be a valid DirectFB `IDirectFB` handle.
/// - `surface` must be a valid DirectFB `IDirectFBSurface` handle. /// - `surface` must be a valid DirectFB `IDirectFBSurface` handle.
/// - The object referred to by `dfb` and `surface` must outlive the created `Surface`. /// - The object referred to by `dfb` and `surface` must outlive the created `Surface`. The
/// The `object` parameter can be used to ensure this. /// `object` parameter can be used to ensure this.
pub unsafe fn from_directfb( pub unsafe fn from_directfb(
instance: Arc<Instance>, instance: Arc<Instance>,
dfb: *mut ash::vk::IDirectFB, dfb: *mut ash::vk::IDirectFB,
@ -584,8 +585,8 @@ impl Surface {
/// # Safety /// # Safety
/// ///
/// - `image_pipe_handle` must be a valid Fuchsia `zx_handle_t` handle. /// - `image_pipe_handle` must be a valid Fuchsia `zx_handle_t` handle.
/// - The object referred to by `image_pipe_handle` must outlive the created `Surface`. /// - The object referred to by `image_pipe_handle` must outlive the created `Surface`. The
/// The `object` parameter can be used to ensure this. /// `object` parameter can be used to ensure this.
pub unsafe fn from_fuchsia_image_pipe( pub unsafe fn from_fuchsia_image_pipe(
instance: Arc<Instance>, instance: Arc<Instance>,
image_pipe_handle: ash::vk::zx_handle_t, image_pipe_handle: ash::vk::zx_handle_t,
@ -659,8 +660,8 @@ impl Surface {
/// # Safety /// # Safety
/// ///
/// - `stream_descriptor` must be a valid Google Games Platform `GgpStreamDescriptor` handle. /// - `stream_descriptor` must be a valid Google Games Platform `GgpStreamDescriptor` handle.
/// - The object referred to by `stream_descriptor` must outlive the created `Surface`. /// - The object referred to by `stream_descriptor` must outlive the created `Surface`. The
/// The `object` parameter can be used to ensure this. /// `object` parameter can be used to ensure this.
pub unsafe fn from_ggp_stream_descriptor( pub unsafe fn from_ggp_stream_descriptor(
instance: Arc<Instance>, instance: Arc<Instance>,
stream_descriptor: ash::vk::GgpStreamDescriptor, stream_descriptor: ash::vk::GgpStreamDescriptor,
@ -734,8 +735,8 @@ impl Surface {
/// # Safety /// # Safety
/// ///
/// - `metal_layer` must be a valid `IOSMetalLayer` handle. /// - `metal_layer` must be a valid `IOSMetalLayer` handle.
/// - The object referred to by `metal_layer` must outlive the created `Surface`. /// - The object referred to by `metal_layer` must outlive the created `Surface`. The `object`
/// The `object` parameter can be used to ensure this. /// parameter can be used to ensure this.
/// - The `UIView` must be backed by a `CALayer` instance of type `CAMetalLayer`. /// - The `UIView` must be backed by a `CALayer` instance of type `CAMetalLayer`.
pub unsafe fn from_ios( pub unsafe fn from_ios(
instance: Arc<Instance>, instance: Arc<Instance>,
@ -808,8 +809,8 @@ impl Surface {
/// # Safety /// # Safety
/// ///
/// - `view` must be a valid `CAMetalLayer` or `NSView` handle. /// - `view` must be a valid `CAMetalLayer` or `NSView` handle.
/// - The object referred to by `view` must outlive the created `Surface`. /// - The object referred to by `view` must outlive the created `Surface`. The `object`
/// The `object` parameter can be used to ensure this. /// parameter can be used to ensure this.
/// - The `NSView` must be backed by a `CALayer` instance of type `CAMetalLayer`. /// - The `NSView` must be backed by a `CALayer` instance of type `CAMetalLayer`.
pub unsafe fn from_mac_os( pub unsafe fn from_mac_os(
instance: Arc<Instance>, instance: Arc<Instance>,
@ -882,8 +883,8 @@ impl Surface {
/// # Safety /// # Safety
/// ///
/// - `layer` must be a valid Metal `CAMetalLayer` handle. /// - `layer` must be a valid Metal `CAMetalLayer` handle.
/// - The object referred to by `layer` must outlive the created `Surface`. /// - The object referred to by `layer` must outlive the created `Surface`. The `object`
/// The `object` parameter can be used to ensure this. /// parameter can be used to ensure this.
pub unsafe fn from_metal( pub unsafe fn from_metal(
instance: Arc<Instance>, instance: Arc<Instance>,
layer: *const ash::vk::CAMetalLayer, layer: *const ash::vk::CAMetalLayer,
@ -950,8 +951,8 @@ impl Surface {
/// ///
/// - `context` must be a valid QNX Screen `_screen_context` handle. /// - `context` must be a valid QNX Screen `_screen_context` handle.
/// - `window` must be a valid QNX Screen `_screen_window` handle. /// - `window` must be a valid QNX Screen `_screen_window` handle.
/// - The object referred to by `window` must outlive the created `Surface`. /// - The object referred to by `window` must outlive the created `Surface`. The `object`
/// The `object` parameter can be used to ensure this. /// parameter can be used to ensure this.
pub unsafe fn from_qnx_screen( pub unsafe fn from_qnx_screen(
instance: Arc<Instance>, instance: Arc<Instance>,
context: *mut ash::vk::_screen_context, context: *mut ash::vk::_screen_context,
@ -1029,8 +1030,8 @@ impl Surface {
/// # Safety /// # Safety
/// ///
/// - `window` must be a valid `nn::vi::NativeWindowHandle` handle. /// - `window` must be a valid `nn::vi::NativeWindowHandle` handle.
/// - The object referred to by `window` must outlive the created `Surface`. /// - The object referred to by `window` must outlive the created `Surface`. The `object`
/// The `object` parameter can be used to ensure this. /// parameter can be used to ensure this.
pub unsafe fn from_vi( pub unsafe fn from_vi(
instance: Arc<Instance>, instance: Arc<Instance>,
window: *mut c_void, window: *mut c_void,
@ -1184,8 +1185,8 @@ impl Surface {
/// ///
/// - `hinstance` must be a valid Win32 `HINSTANCE` handle. /// - `hinstance` must be a valid Win32 `HINSTANCE` handle.
/// - `hwnd` must be a valid Win32 `HWND` handle. /// - `hwnd` must be a valid Win32 `HWND` handle.
/// - The objects referred to by `hwnd` and `hinstance` must outlive the created `Surface`. /// - The objects referred to by `hwnd` and `hinstance` must outlive the created `Surface`. The
/// The `object` parameter can be used to ensure this. /// `object` parameter can be used to ensure this.
pub unsafe fn from_win32( pub unsafe fn from_win32(
instance: Arc<Instance>, instance: Arc<Instance>,
hinstance: ash::vk::HINSTANCE, hinstance: ash::vk::HINSTANCE,
@ -1348,8 +1349,8 @@ impl Surface {
/// ///
/// - `display` must be a valid Xlib `Display` handle. /// - `display` must be a valid Xlib `Display` handle.
/// - `window` must be a valid Xlib `Window` handle. /// - `window` must be a valid Xlib `Window` handle.
/// - The objects referred to by `display` and `window` must outlive the created `Surface`. /// - The objects referred to by `display` and `window` must outlive the created `Surface`. The
/// The `object` parameter can be used to ensure this. /// `object` parameter can be used to ensure this.
pub unsafe fn from_xlib( pub unsafe fn from_xlib(
instance: Arc<Instance>, instance: Arc<Instance>,
display: *mut ash::vk::Display, display: *mut ash::vk::Display,
@ -2136,7 +2137,8 @@ vulkan_enum! {
]), ]),
} }
/// Parameters for [`PhysicalDevice::surface_capabilities`] and [`PhysicalDevice::surface_formats`]. /// Parameters for [`PhysicalDevice::surface_capabilities`] and
/// [`PhysicalDevice::surface_formats`].
/// ///
/// [`PhysicalDevice::surface_capabilities`]: crate::device::physical::PhysicalDevice::surface_capabilities /// [`PhysicalDevice::surface_capabilities`]: crate::device::physical::PhysicalDevice::surface_capabilities
/// [`PhysicalDevice::surface_formats`]: crate::device::physical::PhysicalDevice::surface_formats /// [`PhysicalDevice::surface_formats`]: crate::device::physical::PhysicalDevice::surface_formats

View File

@ -42,7 +42,8 @@ pub struct Event {
impl Event { impl Event {
/// Creates a new `Event`. /// Creates a new `Event`.
/// ///
/// On [portability subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag) /// On [portability
/// subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag)
/// devices, the /// devices, the
/// [`events`](crate::device::Features::events) /// [`events`](crate::device::Features::events)
/// feature must be enabled on the device. /// feature must be enabled on the device.

View File

@ -45,7 +45,8 @@ use std::{
time::Duration, time::Duration,
}; };
/// A two-state synchronization primitive that is signalled by the device and waited on by the host. /// A two-state synchronization primitive that is signalled by the device and waited on by the
/// host.
#[derive(Debug)] #[derive(Debug)]
pub struct Fence { pub struct Fence {
handle: ash::vk::Fence, handle: ash::vk::Fence,
@ -616,9 +617,9 @@ impl Fence {
/// # Safety /// # Safety
/// ///
/// - The fence must not be in use by the device. /// - The fence must not be in use by the device.
/// - If in `import_fence_fd_info`, `handle_type` is `ExternalHandleType::OpaqueFd`, /// - If in `import_fence_fd_info`, `handle_type` is `ExternalHandleType::OpaqueFd`, then
/// then `file` must represent a fence that was exported from Vulkan or a compatible API, /// `file` must represent a fence that was exported from Vulkan or a compatible API, with a
/// with a driver and device UUID equal to those of the device that owns `self`. /// driver and device UUID equal to those of the device that owns `self`.
#[inline] #[inline]
pub unsafe fn import_fd( pub unsafe fn import_fd(
&self, &self,
@ -765,8 +766,8 @@ impl Fence {
// Shared by Fence and FenceSignalFuture // Shared by Fence and FenceSignalFuture
pub(crate) fn poll_impl(&self, cx: &mut Context<'_>) -> Poll<Result<(), VulkanError>> { pub(crate) fn poll_impl(&self, cx: &mut Context<'_>) -> Poll<Result<(), VulkanError>> {
// Vulkan only allows polling of the fence status, so we have to use a spin future. // Vulkan only allows polling of the fence status, so we have to use a spin future.
// This is still better than blocking in async applications, since a smart-enough async engine // This is still better than blocking in async applications, since a smart-enough async
// can choose to run some other tasks between probing this one. // engine can choose to run some other tasks between probing this one.
// Check if we are done without blocking // Check if we are done without blocking
match self.is_signaled() { match self.is_signaled() {

View File

@ -59,8 +59,8 @@ pub enum FenceSignalFutureBehavior {
/// Contrary to most other future types, it is possible to block the current thread until the event /// Contrary to most other future types, it is possible to block the current thread until the event
/// happens. This is done by calling the `wait()` function. /// happens. This is done by calling the `wait()` function.
/// ///
/// This can also be done through Rust's Async system by simply `.await`ing this object. Note though /// This can also be done through Rust's Async system by simply `.await`ing this object. Note
/// that (due to the Vulkan API fence design) this will spin to check the fence, rather than /// though that (due to the Vulkan API fence design) this will spin to check the fence, rather than
/// blocking in the driver. Therefore if you have a long-running task, blocking may be less /// blocking in the driver. Therefore if you have a long-running task, blocking may be less
/// CPU intense (depending on the driver's implementation). /// CPU intense (depending on the driver's implementation).
/// ///

View File

@ -67,8 +67,9 @@ where
let first = self.first.build_submission()?; let first = self.first.build_submission()?;
let second = self.second.build_submission()?; let second = self.second.build_submission()?;
// In some cases below we have to submit previous command buffers already, this s done by flushing previous. // In some cases below we have to submit previous command buffers already, this s done by
// Since the implementation should remember being flushed it's safe to call build_submission multiple times // flushing previous. Since the implementation should remember being flushed it's
// safe to call build_submission multiple times
Ok(match (first, second) { Ok(match (first, second) {
(SubmitAnyBuilder::Empty, b) => b, (SubmitAnyBuilder::Empty, b) => b,
(a, SubmitAnyBuilder::Empty) => a, (a, SubmitAnyBuilder::Empty) => a,

View File

@ -171,7 +171,8 @@ where
.map(|r| r.map(|_| ())) .map(|r| r.map(|_| ()))
.fold(Ok(()), Result::and)?; .fold(Ok(()), Result::and)?;
// FIXME: problematic because if we return an error and flush() is called again, then we'll submit the present twice // FIXME: problematic because if we return an error and flush() is called again,
// then we'll submit the present twice
queue_submit( queue_submit(
&queue, &queue,
SubmitInfo { SubmitInfo {

View File

@ -3065,7 +3065,8 @@ impl ImageMemoryBarrier {
queue_family_ownership_transfer: None, queue_family_ownership_transfer: None,
image, image,
subresource_range: ImageSubresourceRange { subresource_range: ImageSubresourceRange {
aspects: ImageAspects::empty(), // Can't use image format aspects because `color` can't be specified with `planeN`. // Can't use image format aspects because `color` can't be specified with `planeN`.
aspects: ImageAspects::empty(),
mip_levels: 0..0, mip_levels: 0..0,
array_layers: 0..0, array_layers: 0..0,
}, },
@ -3538,13 +3539,16 @@ impl ImageMemoryBarrier {
} }
// VUID-VkImageMemoryBarrier2-synchronization2-07793 // VUID-VkImageMemoryBarrier2-synchronization2-07793
// If the synchronization2 feature is not enabled, oldLayout must not be VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR or VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR // If the synchronization2 feature is not enabled, oldLayout must not be
// VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR or VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR
// VUID-VkImageMemoryBarrier2-synchronization2-07794 // VUID-VkImageMemoryBarrier2-synchronization2-07794
// If the synchronization2 feature is not enabled, newLayout must not be VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR or VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR // If the synchronization2 feature is not enabled, newLayout must not be
// VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR or VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR
// VUID-VkImageMemoryBarrier2-attachmentFeedbackLoopLayout-07313 // VUID-VkImageMemoryBarrier2-attachmentFeedbackLoopLayout-07313
// If the attachmentFeedbackLoopLayout feature is not enabled, newLayout must not be VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT // If the attachmentFeedbackLoopLayout feature is not enabled, newLayout must not be
// VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT
subresource_range subresource_range
.validate(device) .validate(device)

View File

@ -28,10 +28,10 @@
//! Both the device and the host can perform the same two operations on a timeline semaphore: //! Both the device and the host can perform the same two operations on a timeline semaphore:
//! - A **semaphore signal operation** will set the semaphore counter value to a specified value. //! - A **semaphore signal operation** will set the semaphore counter value to a specified value.
//! - A **semaphore wait operation** will block execution of the operation it is associated with, //! - A **semaphore wait operation** will block execution of the operation it is associated with,
//! as long as the semaphore's counter value is less than a specified threshold value. //! as long as the semaphore's counter value is less than a specified threshold value. Once the
//! Once the semaphore's counter value is equal to or greater than the threshold, execution //! semaphore's counter value is equal to or greater than the threshold, execution continues.
//! continues. Unlike with binary semaphores, waiting does not alter the state of a timeline //! Unlike with binary semaphores, waiting does not alter the state of a timeline semaphore, so
//! semaphore, so multiple operations can wait for the same semaphore value. //! multiple operations can wait for the same semaphore value.
//! //!
//! Additionally, the host can query the current counter value of a timeline semaphore. //! Additionally, the host can query the current counter value of a timeline semaphore.
//! //!
@ -43,14 +43,13 @@
//! //!
//! For binary semaphores: //! For binary semaphores:
//! - When a semaphore signal operation is executed, the semaphore must be in the unsignaled state. //! - When a semaphore signal operation is executed, the semaphore must be in the unsignaled state.
//! In other words, the same semaphore cannot be signalled by multiple commands; //! In other words, the same semaphore cannot be signalled by multiple commands; there must
//! there must always be a wait operation in between them. //! always be a wait operation in between them.
//! - There must never be more than one semaphore wait operation executing on the same semaphore //! - There must never be more than one semaphore wait operation executing on the same semaphore at
//! at the same time. //! the same time.
//! - When a semaphore wait operation is queued as part of a command, //! - When a semaphore wait operation is queued as part of a command, the semaphore must already be
//! the semaphore must already be in the signaled state, or //! in the signaled state, or the signal operation that it waits for must have been queued
//! the signal operation that it waits for must have been queued previously //! previously (as part of a previous command, or an earlier batch within the same command).
//! (as part of a previous command, or an earlier batch within the same command).
//! //!
//! For timeline semaphores: //! For timeline semaphores:
//! - When a semaphore signal operation is executed, the new counter value of the semaphore must be //! - When a semaphore signal operation is executed, the new counter value of the semaphore must be
@ -299,8 +298,8 @@ impl Semaphore {
/// ///
/// # Safety /// # Safety
/// ///
/// - The safety requirements for semaphores, as detailed in the module documentation, /// - The safety requirements for semaphores, as detailed in the module documentation, must be
/// must be followed. /// followed.
#[inline] #[inline]
pub unsafe fn signal( pub unsafe fn signal(
&self, &self,
@ -856,10 +855,9 @@ impl Semaphore {
/// # Safety /// # Safety
/// ///
/// - The semaphore must not be in use by the device. /// - The semaphore must not be in use by the device.
/// - If in `import_semaphore_fd_info`, `handle_type` is `ExternalHandleType::OpaqueFd`, /// - If in `import_semaphore_fd_info`, `handle_type` is `ExternalHandleType::OpaqueFd`, then
/// then `file` must represent a binary semaphore that was exported from Vulkan or a /// `file` must represent a binary semaphore that was exported from Vulkan or a compatible
/// compatible API, with a driver and device UUID equal to those of the device that owns /// API, with a driver and device UUID equal to those of the device that owns `self`.
/// `self`.
#[inline] #[inline]
pub unsafe fn import_fd( pub unsafe fn import_fd(
&self, &self,